Version 2.0.0-dev.21.0
Merge commit '402e69b53d59083d34d7538126837c4381aa0c4a' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1c96bf6..a579da2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,9 +8,25 @@
This allows libraries with no library declarations (and therefore no name)
to have parts, and it allows tools to easily find the library of a part
file.
+* Added support for starting `async` functions synchronously. All tools (VM,
+ dart2js, DDC) have now a flag `--sync-async` to enable this behavior.
+ Currently this behavior is opt-in. It will become the default.
#### Strong Mode
+* Future flattening is now done only as specified in the Dart 2.0 spec, rather
+than more broadly. This means that the following code will now have an error on
+the assignment to `y`.
+
+ ```dart
+ test() {
+ Future<int> f;
+ var x = f.then<Future<List<int>>>((x) => []);
+ Future<List<int>> y = x;
+ }
+ ```
+
+
### Core library changes
* `dart:async`
@@ -51,6 +67,7 @@
`MINUTES_PER_DAY` to `minutesPerDay`, and
`ZERO` to `zero`.
* Added `Provisional` annotation to `dart:core`.
+ * Added static `escape` function to `RegExp` class.
* `dart:convert`
* `Utf8Decoder` when compiled with dart2js uses the browser's `TextDecoder` in
diff --git a/DEPS b/DEPS
index dca297c..b14f921 100644
--- a/DEPS
+++ b/DEPS
@@ -36,6 +36,7 @@
"fuchsia_git": "https://fuchsia.googlesource.com",
"co19_rev": "@dec2b67aaab3bb7339b9764049707e71e601da3d",
+ "co19_2_rev": "@d8cdc47f759b0e89a517403ffa13eccd874bbbc0",
# As Flutter does, we pull buildtools, including the clang toolchain, from
# Fuchsia. This revision should be kept up to date with the revision pulled
@@ -50,7 +51,7 @@
# Revisions of /third_party/* dependencies.
"args_tag": "@0.13.7",
- "async_tag": "@2.0.2",
+ "async_tag": "@corelib_2_2_1",
"barback-0.13.0_rev": "@34853",
"barback-0.14.0_rev": "@36398",
"barback-0.14.1_rev": "@38525",
@@ -87,7 +88,7 @@
"func_rev": "@25eec48146a58967d75330075ab376b3838b18a8",
"glob_tag": "@1.1.5",
"html_tag" : "@0.13.2+2",
- "http_io_tag": "@bea7f236fbd62f6e1b47d4806a889f628c58d114",
+ "http_io_tag": "@35dc43c9144cf7ed4236843dacd62ebaf89df21a",
"http_multi_server_tag" : "@2.0.4",
"http_parser_tag" : "@3.1.1",
"http_retry_tag": "@0.1.0",
@@ -102,7 +103,7 @@
"logging_tag": "@0.11.3+1",
"markdown_tag": "@1.0.0",
"matcher_tag": "@0.12.1+4",
- "mime_tag": "@0.9.4",
+ "mime_tag": "@0.9.6",
"mockito_tag": "@2.0.2",
"mustache4dart_tag" : "@v2.1.0",
"oauth2_tag": "@1.1.0",
@@ -139,9 +140,9 @@
"tuple_tag": "@v1.0.1",
"typed_data_tag": "@1.1.3",
"usage_tag": "@3.3.0",
- "utf_tag": "@0.9.0+3",
- "watcher_tag": "@0.9.7+4",
- "web_socket_channel_tag": "@1.0.6",
+ "utf_tag": "@0.9.0+4",
+ "watcher_tag": "@0.9.7+7",
+ "web_socket_channel_tag": "@corelib_2_2_1",
"WebCore_rev": "@3c45690813c112373757bbef53de1602a62af609",
"yaml_tag": "@2.1.13",
"zlib_rev": "@c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
@@ -158,6 +159,10 @@
Var("dart_root") + "/tests/co19/src":
Var("dart_git") + "co19.git" + Var("co19_rev"),
+Var("dart_root") + "/tests/co19_2/src":
+ Var("chromium_git") + "/external/github.com/dart-lang/co19.git" +
+ Var("co19_2_rev"),
+
Var("dart_root") + "/third_party/zlib":
Var("chromium_git") + "/chromium/src/third_party/zlib.git" +
Var("zlib_rev"),
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 6923a31..210a22d 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- 1.18.4
+ 1.18.5
</h1>
<p>
This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
index 1027255..30c42f7 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol_dart.dart
@@ -129,12 +129,15 @@
element.parameters.isEmpty) {
return null;
}
- parameters = element.parameters;
+ parameters = element.parameters.toList();
} else if (element is engine.FunctionTypeAliasElement) {
- parameters = element.parameters;
+ parameters = element.parameters.toList();
} else {
return null;
}
+
+ parameters.sort(_preferRequiredParams);
+
StringBuffer sb = new StringBuffer();
String closeOptionalString = '';
for (engine.ParameterElement parameter in parameters) {
@@ -214,3 +217,15 @@
}
return false;
}
+
+// Sort @required named parameters before optional ones.
+int _preferRequiredParams(
+ engine.ParameterElement e1, engine.ParameterElement e2) {
+ int rank1 = e1.isRequired
+ ? 0
+ : e1.parameterKind != engine.ParameterKind.NAMED ? -1 : 1;
+ int rank2 = e2.isRequired
+ ? 0
+ : e2.parameterKind != engine.ParameterKind.NAMED ? -1 : 1;
+ return rank1 - rank2;
+}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 369bb62..0ce8a02 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -108,7 +108,7 @@
* The version of the analysis server. The value should be replaced
* automatically during the build.
*/
- static final String VERSION = '1.18.4';
+ static final String VERSION = '1.18.5';
/**
* The options of this server instance.
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index c1fd4e5..7e96426 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -177,6 +177,7 @@
try {
AssistProcessor processor = new AssistProcessor(dartAssistContext);
List<Assist> assists = await processor.compute();
+ assists.sort(Assist.SORT_BY_RELEVANCE);
for (Assist assist in assists) {
changes.add(assist.change);
}
diff --git a/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart b/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
index 5abb20f..819655d 100644
--- a/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
+++ b/pkg/analysis_server/lib/src/flutter/flutter_outline_computer.dart
@@ -138,12 +138,39 @@
variableName = node.name;
}
+ String label;
+ if (kind == protocol.FlutterOutlineKind.GENERIC) {
+ label = _getShortLabel(node);
+ }
+
return new protocol.FlutterOutline(kind, node.offset, node.length,
- className: className, variableName: variableName);
+ className: className, variableName: variableName, label: label);
}
return null;
}
+
+ String _getShortLabel(AstNode node) {
+ if (node is MethodInvocation) {
+ var buffer = new StringBuffer();
+
+ if (node.target != null) {
+ buffer.write(_getShortLabel(node.target));
+ buffer.write('.');
+ }
+
+ buffer.write(node.methodName.name);
+
+ if (node.argumentList == null || node.argumentList.arguments.isEmpty) {
+ buffer.write('()');
+ } else {
+ buffer.write('(…)');
+ }
+
+ return buffer.toString();
+ }
+ return node.toString();
+ }
}
class _FlutterOutlineBuilder extends GeneralizingAstVisitor<void> {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 7cba458..d33a4eb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -92,8 +92,6 @@
new LocalLibraryContributor(),
new LocalReferenceContributor(),
new NamedConstructorContributor(),
- // Revisit this contributor and these tests
- // once DartChangeBuilder API has solidified.
// new OverrideContributor(),
new StaticMemberContributor(),
new TypeMemberContributor(),
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index 492567f..c13b677 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -12,9 +12,11 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/range_factory.dart';
/**
* A completion contributor used to suggest replacing partial identifiers inside
@@ -48,7 +50,7 @@
// Gracefully degrade if the overridden element has not been resolved.
if (element.returnType != null) {
CompletionSuggestion suggestion =
- _buildSuggestion(request, targetId, element);
+ await _buildSuggestion(request, targetId, element);
if (suggestion != null) {
suggestions.add(suggestion);
}
@@ -58,33 +60,29 @@
}
/**
- * Return a template for an override of the given [element] in the given
- * [source]. If selected, the template will replace [targetId].
+ * Return a template for an override of the given [element]. If selected, the
+ * template will replace [targetId].
*/
- String _buildRepacementText(Source source, SimpleIdentifier targetId,
- CompilationUnit unit, ExecutableElement element) {
- // AnalysisContext context = element.context;
- // Inject partially resolved unit for use by change builder
- // DartChangeBuilder builder = new DartChangeBuilder(context, unit);
- // builder.addFileEdit(source, context.getModificationStamp(source),
- // (DartFileEditBuilder builder) {
- // builder.addReplacement(targetId.offset, targetId.length,
- // (DartEditBuilder builder) {
- // builder.writeOverrideOfInheritedMember(element);
- // });
- // });
- // return builder.sourceChange.edits[0].edits[0].replacement.trim();
- return '';
+ Future<String> _buildReplacementText(AnalysisResult result,
+ SimpleIdentifier targetId, ExecutableElement element) async {
+ DartChangeBuilder builder =
+ new DartChangeBuilder(result.driver.currentSession);
+ await builder.addFileEdit(result.path, (DartFileEditBuilder builder) {
+ builder.addReplacement(range.node(targetId), (DartEditBuilder builder) {
+ builder.writeOverrideOfInheritedMember(element);
+ });
+ });
+ return builder.sourceChange.edits[0].edits[0].replacement.trim();
}
/**
* Build a suggestion to replace [targetId] in the given [unit]
* with an override of the given [element].
*/
- CompletionSuggestion _buildSuggestion(DartCompletionRequest request,
- SimpleIdentifier targetId, ExecutableElement element) {
- String completion = _buildRepacementText(
- request.source, targetId, request.target.unit, element);
+ Future<CompletionSuggestion> _buildSuggestion(DartCompletionRequest request,
+ SimpleIdentifier targetId, ExecutableElement element) async {
+ String completion =
+ await _buildReplacementText(request.result, targetId, element);
if (completion == null || completion.length == 0) {
return null;
}
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 013e7ce..5bb126d 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -47,6 +47,8 @@
"Convert into line documentation comment");
static const CONVERT_FLUTTER_CHILD =
const AssistKind('CONVERT_FLUTTER_CHILD', 30, "Convert to children:");
+ static const CONVERT_INTO_ASYNC_BODY = const AssistKind(
+ 'CONVERT_INTO_ASYNC_BODY', 30, "Convert into async function body");
static const CONVERT_INTO_BLOCK_BODY = const AssistKind(
'CONVERT_INTO_BLOCK_BODY', 30, "Convert into block body");
static const CONVERT_INTO_EXPRESSION_BODY = const AssistKind(
@@ -93,6 +95,10 @@
const AssistKind("REPARENT_FLUTTER_LIST", 30, "Wrap with new widget");
static const REPARENT_FLUTTER_WIDGET =
const AssistKind("REPARENT_FLUTTER_WIDGET", 30, "Wrap with new widget");
+ static const REPARENT_FLUTTER_WIDGET_CENTER =
+ const AssistKind("REPARENT_FLUTTER_WIDGET_CENTER", 29, "Center widget");
+ static const REPARENT_FLUTTER_WIDGET_PADDING = const AssistKind(
+ "REPARENT_FLUTTER_WIDGET_CENTER", 29, "Add widget padding");
static const REMOVE_TYPE_ANNOTATION =
const AssistKind('REMOVE_TYPE_ANNOTATION', 29, "Remove type annotation");
static const REPLACE_CONDITIONAL_WITH_IF_ELSE = const AssistKind(
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 16e29bf..1238735 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -125,6 +125,7 @@
await _addProposal_convertIntoGetter();
await _addProposal_convertDocumentationIntoBlock();
await _addProposal_convertDocumentationIntoLine();
+ await _addProposal_convertToAsyncFunctionBody();
await _addProposal_convertToBlockFunctionBody();
await _addProposal_convertToExpressionFunctionBody();
await _addProposal_convertFlutterChild();
@@ -159,6 +160,8 @@
}
FunctionBody getEnclosingFunctionBody() {
+ // TODO(brianwilkerson) Determine whether there is a reason why this method
+ // isn't just "return node.getAncestor((node) => node is FunctionBody);"
{
FunctionExpression function =
node.getAncestor((node) => node is FunctionExpression);
@@ -674,6 +677,37 @@
_addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_PART_OF_TO_URI);
}
+ Future<Null> _addProposal_convertToAsyncFunctionBody() async {
+ FunctionBody body = getEnclosingFunctionBody();
+ if (body == null || body.isAsynchronous || body.isGenerator) {
+ _coverageMarker();
+ return;
+ }
+
+ // Function bodies can be quite large, e.g. Flutter build() methods.
+ // It is surprising to see this Quick Assist deep in a function body.
+ if (body is BlockFunctionBody &&
+ selectionOffset > body.block.beginToken.end) {
+ return;
+ }
+ if (body is ExpressionFunctionBody &&
+ selectionOffset > body.beginToken.end) {
+ return;
+ }
+
+ AstNode parent = body.parent;
+ if (parent is ConstructorDeclaration) {
+ return;
+ }
+
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.convertFunctionFromSyncToAsync(body, typeProvider);
+ });
+ _addAssistFromBuilder(
+ changeBuilder, DartAssistKind.CONVERT_INTO_ASYNC_BODY);
+ }
+
Future<Null> _addProposal_convertToBlockFunctionBody() async {
FunctionBody body = getEnclosingFunctionBody();
// prepare expression body
@@ -1831,6 +1865,23 @@
}
Future<Null> _addProposal_reparentFlutterWidget() async {
+ await _addProposal_reparentFlutterWidgetImpl();
+ await _addProposal_reparentFlutterWidgetImpl(
+ kind: DartAssistKind.REPARENT_FLUTTER_WIDGET_CENTER,
+ parentLibraryUri: 'package:flutter/widgets.dart',
+ parentClassName: 'Center');
+ await _addProposal_reparentFlutterWidgetImpl(
+ kind: DartAssistKind.REPARENT_FLUTTER_WIDGET_PADDING,
+ parentLibraryUri: 'package:flutter/widgets.dart',
+ parentClassName: 'Padding',
+ leadingLines: ['padding: const EdgeInsets.all(8.0),']);
+ }
+
+ Future<Null> _addProposal_reparentFlutterWidgetImpl(
+ {AssistKind kind: DartAssistKind.REPARENT_FLUTTER_WIDGET,
+ String parentLibraryUri,
+ String parentClassName,
+ List<String> leadingLines: const []}) async {
InstanceCreationExpression newExpr = flutter.identifyNewExpression(node);
if (newExpr == null || !flutter.isWidgetCreation(newExpr)) {
_coverageMarker();
@@ -1838,36 +1889,56 @@
}
String newExprSrc = utils.getNodeText(newExpr);
+ // If the wrapper class is specified, find its element.
+ ClassElement parentClassElement;
+ if (parentLibraryUri != null && parentClassName != null) {
+ var parentLibrary = await session.getLibraryByUri(parentLibraryUri);
+ var element = parentLibrary.exportNamespace.get(parentClassName);
+ if (element is ClassElement) {
+ parentClassElement = element;
+ } else {
+ return;
+ }
+ }
+
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
builder.addReplacement(range.node(newExpr), (DartEditBuilder builder) {
builder.write('new ');
- builder.addSimpleLinkedEdit('WIDGET', 'widget');
+ if (parentClassElement == null) {
+ builder.addSimpleLinkedEdit('WIDGET', 'widget');
+ } else {
+ builder.writeType(parentClassElement.type);
+ }
builder.write('(');
- if (newExprSrc.contains(eol)) {
- int newlineIdx = newExprSrc.lastIndexOf(eol);
- int eolLen = eol.length;
- if (newlineIdx == newExprSrc.length - eolLen) {
- newlineIdx -= eolLen;
- }
- String indentOld =
- utils.getLinePrefix(newExpr.offset + eolLen + newlineIdx);
+ if (newExprSrc.contains(eol) || leadingLines.isNotEmpty) {
+ String indentOld = utils.getLinePrefix(newExpr.offset);
String indentNew = '$indentOld${utils.getIndent(1)}';
+
+ for (var leadingLine in leadingLines) {
+ builder.write(eol);
+ builder.write(indentNew);
+ builder.write(leadingLine);
+ }
+
builder.write(eol);
builder.write(indentNew);
newExprSrc = newExprSrc.replaceAll(
new RegExp("^$indentOld", multiLine: true), indentNew);
newExprSrc += ",$eol$indentOld";
}
- builder.addSimpleLinkedEdit('CHILD', 'child');
+ if (parentClassElement == null) {
+ builder.addSimpleLinkedEdit('CHILD', 'child');
+ } else {
+ builder.write('child');
+ }
builder.write(': ');
builder.write(newExprSrc);
builder.write(')');
builder.selectHere();
});
});
- _addAssistFromBuilder(
- changeBuilder, DartAssistKind.REPARENT_FLUTTER_WIDGET);
+ _addAssistFromBuilder(changeBuilder, kind);
}
Future<Null> _addProposal_replaceConditionalWithIfElse() async {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index bfcd0dc..ab6d4ac 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -78,6 +78,7 @@
errorCode.name == LintNames.avoid_init_to_null ||
errorCode.name == LintNames.prefer_collection_literals ||
errorCode.name == LintNames.prefer_conditional_assignment ||
+ errorCode.name == LintNames.prefer_const_declarations ||
errorCode.name == LintNames.unnecessary_brace_in_string_interp ||
errorCode.name == LintNames.unnecessary_lambdas ||
errorCode.name == LintNames.unnecessary_this));
@@ -205,6 +206,8 @@
const FixKind('REMOVE_UNUSED_IMPORT', 50, "Remove unused import");
static const REPLACE_BOOLEAN_WITH_BOOL = const FixKind(
'REPLACE_BOOLEAN_WITH_BOOL', 50, "Replace 'boolean' with 'bool'");
+ static const REPLACE_FINAL_WITH_CONST = const FixKind(
+ 'REPLACE_FINAL_WITH_CONST', 50, "Replace 'final' with 'const'");
static const REPLACE_VAR_WITH_DYNAMIC = const FixKind(
'REPLACE_VAR_WITH_DYNAMIC', 50, "Replace 'var' with 'dynamic'");
static const REPLACE_RETURN_TYPE_FUTURE = const FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 853962e..fcba496 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -444,6 +444,9 @@
if (name == LintNames.prefer_conditional_assignment) {
await _addFix_replaceWithConditionalAssignment();
}
+ if (errorCode.name == LintNames.prefer_const_declarations) {
+ await _addFix_replaceFinalWithConst();
+ }
if (name == LintNames.prefer_is_not_empty) {
await _addFix_isNotEmpty();
}
@@ -1578,7 +1581,8 @@
}
// name
builder.write(element.displayName);
- builder.writeTypeParameters(element.typeParameters);
+ builder.writeTypeParameters(element.typeParameters,
+ methodBeingCopied: element);
// parameters + body
if (isGetter) {
builder.write(' => null;');
@@ -2199,6 +2203,17 @@
_addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_IMPORT);
}
+ Future<Null> _addFix_replaceFinalWithConst() async {
+ if (node is VariableDeclarationList) {
+ DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+ await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+ builder.addSimpleReplacement(
+ range.token((node as VariableDeclarationList).keyword), 'const');
+ });
+ _addFixFromBuilder(changeBuilder, DartFixKind.REPLACE_FINAL_WITH_CONST);
+ }
+ }
+
Future<Null> _addFix_replaceVarWithDynamic() async {
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
@@ -3250,6 +3265,7 @@
static const String prefer_collection_literals = 'prefer_collection_literals';
static const String prefer_conditional_assignment =
'prefer_conditional_assignment';
+ static const String prefer_const_declarations = 'prefer_const_declarations';
static const String prefer_is_not_empty = 'prefer_is_not_empty';
static const String type_init_formals = 'type_init_formals';
static const String unnecessary_brace_in_string_interp =
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index 59153af..60c9475 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -450,8 +450,7 @@
return node.constKeyword != null;
}
if (node is InstanceCreationExpression) {
- InstanceCreationExpression creation = node;
- return creation.isConst;
+ return node.isConst;
}
if (node is ArgumentList ||
node is ConditionalExpression ||
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 934dc07..069e2b0 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -21,6 +21,7 @@
import 'package:front_end/src/base/performance_logger.dart';
import 'mock_sdk.dart';
+import 'src/utilities/flutter_util.dart';
/**
* Finds an [Element] with the given [name].
@@ -55,6 +56,11 @@
AnalysisDriver get driver => _driver;
+ void addFlutterPackage() {
+ Folder libFolder = configureFlutterPackage(resourceProvider);
+ packageMap['flutter'] = [libFolder];
+ }
+
Source addMetaPackageSource() => addPackageSource('meta', 'meta.dart', r'''
library meta;
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index 9a1717a..3e486d5 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -168,6 +168,56 @@
expect(element.flags, Element.FLAG_CONST);
}
+ test_fromElement_CONSTRUCTOR_required_parameters_1() async {
+ addMetaPackageSource();
+ engine.Source source = addSource('/test.dart', '''
+import 'package:meta/meta.dart';
+class A {
+ const A.myConstructor(int a, {int b, @required int c});
+}''');
+
+ engine.CompilationUnit unit = await resolveLibraryUnit(source);
+ engine.ConstructorElement engineElement =
+ findElementInUnit(unit, 'myConstructor');
+ // create notification Element
+ Element element = convertElement(engineElement);
+ expect(element.parameters, '(int a, {int c, int b})');
+ }
+
+ // Verify parameter re-ordering for required params
+ test_fromElement_CONSTRUCTOR_required_parameters_2() async {
+ addMetaPackageSource();
+ engine.Source source = addSource('/test.dart', '''
+import 'package:meta/meta.dart';
+class A {
+ const A.myConstructor(int a, {int b, @required int d, @required int c});
+}''');
+
+ engine.CompilationUnit unit = await resolveLibraryUnit(source);
+ engine.ConstructorElement engineElement =
+ findElementInUnit(unit, 'myConstructor');
+ // create notification Element
+ Element element = convertElement(engineElement);
+ expect(element.parameters, '(int a, {int d, int c, int b})');
+ }
+
+ // Verify parameter re-ordering for required params
+ test_fromElement_CONSTRUCTOR_required_parameters_3() async {
+ addMetaPackageSource();
+ engine.Source source = addSource('/test.dart', '''
+import 'package:meta/meta.dart';
+class A {
+ const A.myConstructor(int a, {int b, @required int d, @required int c, int a});
+}''');
+
+ engine.CompilationUnit unit = await resolveLibraryUnit(source);
+ engine.ConstructorElement engineElement =
+ findElementInUnit(unit, 'myConstructor');
+ // create notification Element
+ Element element = convertElement(engineElement);
+ expect(element.parameters, '(int a, {int d, int c, int b, int a})');
+ }
+
void test_fromElement_dynamic() {
var engineElement = engine.DynamicElementImpl.instance;
// create notification Element
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 3cf0ef7..05c1b3d 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -8,7 +8,6 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../src/utilities/flutter_util.dart';
import 'completion_contributor_util.dart';
main() {
@@ -252,12 +251,10 @@
}
test_ArgumentList_Flutter_InstanceCreationExpression_0() async {
- configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() => new Row(
^
@@ -275,12 +272,10 @@
}
test_ArgumentList_Flutter_InstanceCreationExpression_01() async {
- configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() => new Scaffold(
appBar: new AppBar(
@@ -291,20 +286,18 @@
await computeSuggestions();
- assertSuggest('color: ,',
+ assertSuggest('backgroundColor: ,',
csKind: CompletionSuggestionKind.NAMED_ARGUMENT,
relevance: DART_RELEVANCE_NAMED_PARAMETER,
defaultArgListString: null, // No default values.
- selectionOffset: 7);
+ selectionOffset: 17);
}
test_ArgumentList_Flutter_InstanceCreationExpression_1() async {
- configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() => new Row(
key: null,
@@ -323,12 +316,10 @@
}
test_ArgumentList_Flutter_InstanceCreationExpression_2() async {
- configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() => new Row(
^
@@ -349,17 +340,18 @@
test_ArgumentList_Flutter_InstanceCreationExpression_children_dynamic() async {
// Ensure we don't generate unneeded <dynamic> param if a future API doesn't
// type it's children.
- configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code +
- '\nclass DynamicRow extends Widget { DynamicRow({List children: null}){}}'
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() => new Container(
child: new DynamicRow(^);
);
+
+class DynamicRow extends Widget {
+ DynamicRow({List children: null});
+}
''');
await computeSuggestions();
@@ -374,17 +366,18 @@
test_ArgumentList_Flutter_InstanceCreationExpression_children_Map() async {
// Ensure we don't generate Map params for a future API
- configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code +
- '\nclass MapRow extends Widget { MapRow({Map<Object,Object> children: null}){}}'
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() => new Container(
child: new MapRow(^);
);
+
+class MapRow extends Widget {
+ MapRow({Map<Object, Object> children: null});
+}
''');
await computeSuggestions();
@@ -397,18 +390,18 @@
}
test_ArgumentList_Flutter_InstanceCreationExpression_slivers() async {
- configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code +
- '\nclass CustomScrollView extends Widget { CustomScrollView('
- '\n{List<Widget> slivers}){}}'
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() => new CustomScrollView(
^
);
+
+class CustomScrollView extends Widget {
+ CustomScrollView({List<Widget> slivers});
+}
''');
await computeSuggestions();
@@ -423,16 +416,15 @@
test_ArgumentList_Flutter_MethodExpression_children() async {
// Ensure we don't generate params for a method call
- configureFlutterPkg({
- 'src/widgets/framework.dart':
- flutter_framework_code + '\nfoo({String children})'
- });
+ addFlutterPackage();
addTestSource('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
main() {
foo(^);
+
+foo({String children}) {}
''');
await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index f368461..14f2fca 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -9,8 +9,6 @@
import 'package:analysis_server/src/services/completion/completion_performance.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
show DartCompletionRequestImpl;
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/generated/parser.dart' as analyzer;
import 'package:analyzer/src/generated/source.dart';
@@ -18,7 +16,6 @@
import 'package:test/test.dart';
import '../../../abstract_context.dart';
-import '../../../src/utilities/flutter_util.dart';
int suggestionComparator(CompletionSuggestion s1, CompletionSuggestion s2) {
String c1 = s1.completion.toLowerCase();
@@ -497,30 +494,6 @@
expect(suggestions, isNotNull, reason: 'expected suggestions');
}
- /**
- * Configures the [SourceFactory] to have the `flutter` package in
- * `/packages/flutter/lib` folder.
- */
- void configureFlutterPkg(Map<String, String> pathToCode) {
- pathToCode.forEach((path, code) {
- newFile('$flutterPkgLibPath/$path', content: code);
- });
- // configure SourceFactory
- Folder myPkgFolder = getFolder(flutterPkgLibPath);
- UriResolver pkgResolver = new PackageMapUriResolver(resourceProvider, {
- 'flutter': [myPkgFolder]
- });
- SourceFactory sourceFactory = new SourceFactory(
- [new DartUriResolver(sdk), pkgResolver, resourceResolver]);
- driver.configure(sourceFactory: sourceFactory);
- // force 'flutter' resolution
- addSource(
- '/tmp/other.dart',
- pathToCode.keys
- .map((path) => "import 'package:flutter/$path';")
- .join('\n'));
- }
-
DartCompletionContributor createContributor();
void failedCompletion(String message,
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index e0d356c..25178e7 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -11,10 +11,7 @@
import 'completion_contributor_util.dart';
main() {
- // Revisit this contributor and these tests
- // once DartChangeBuilder API has solidified.
- // initializeTestEnvironment();
- // defineReflectiveTests(InheritedContributorTest);
+ defineReflectiveTests(OverrideContributorTest);
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index a307b98..09ec41d 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -11,8 +11,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/element/ast_provider.dart';
@@ -25,7 +23,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../abstract_single_unit.dart';
-import '../../src/utilities/flutter_util.dart';
main() {
defineReflectiveSuite(() {
@@ -917,11 +914,9 @@
}
test_convertFlutterChild_OK_multiLine() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -938,7 +933,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -959,11 +954,9 @@
test_convertFlutterChild_OK_newlineChild() async {
// This case could occur with deeply nested constructors, common in Flutter.
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -981,7 +974,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -1001,11 +994,9 @@
}
test_convertFlutterChild_OK_singleLine() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -1019,7 +1010,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -1061,6 +1052,119 @@
''');
}
+ test_convertToAsyncBody_BAD_async() async {
+ await resolveTestUnit('''
+import 'dart:async';
+Future<String> f() async => '';
+''');
+ await assertNoAssistAt('=>', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
+ }
+
+ test_convertToAsyncBody_BAD_asyncStar() async {
+ await resolveTestUnit('''
+import 'dart:async';
+Stream<String> f() async* {}
+''');
+ await assertNoAssistAt('{}', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
+ }
+
+ test_convertToAsyncBody_BAD_constructor() async {
+ await resolveTestUnit('''
+class C {
+ C() {}
+}
+''');
+ await assertNoAssistAt('{}', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
+ }
+
+ test_convertToAsyncBody_BAD_inBody_block() async {
+ await resolveTestUnit('''
+class C {
+ void foo() {
+ print(42);
+ }
+}
+''');
+ await assertNoAssistAt('print', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
+ }
+
+ test_convertToAsyncBody_BAD_inBody_expression() async {
+ await resolveTestUnit('''
+class C {
+ void foo() => print(42);
+}
+''');
+ await assertNoAssistAt('print', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
+ }
+
+ test_convertToAsyncBody_BAD_syncStar() async {
+ await resolveTestUnit('''
+Iterable<String> f() sync* {}
+''');
+ await assertNoAssistAt('{}', DartAssistKind.CONVERT_INTO_ASYNC_BODY);
+ }
+
+ test_convertToAsyncBody_OK_closure() async {
+ await resolveTestUnit('''
+main() {
+ f(() => 123);
+}
+f(g) {}
+''');
+ await assertHasAssistAt('=>', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
+main() {
+ f(() async => 123);
+}
+f(g) {}
+''');
+ }
+
+ test_convertToAsyncBody_OK_function() async {
+ // TODO(brianwilkerson) Remove the "class C {}" when the bug in the builder
+ // is fixed that causes the import to be incorrectly inserted when the first
+ // character in the file is also being modified.
+ await resolveTestUnit('''
+class C {}
+String f() => '';
+''');
+ await assertHasAssistAt('=>', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
+import 'dart:async';
+
+class C {}
+Future<String> f() async => '';
+''');
+ }
+
+ test_convertToAsyncBody_OK_method() async {
+ await resolveTestUnit('''
+class C {
+ int m() { return 0; }
+}
+''');
+ await assertHasAssistAt(
+ '{ return', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
+import 'dart:async';
+
+class C {
+ Future<int> m() async { return 0; }
+}
+''');
+ }
+
+ test_convertToAsyncBody_OK_method_noReturnType() async {
+ await resolveTestUnit('''
+class C {
+ m() { return 0; }
+}
+''');
+ await assertHasAssistAt(
+ '{ return', DartAssistKind.CONVERT_INTO_ASYNC_BODY, '''
+class C {
+ m() async { return 0; }
+}
+''');
+ }
+
test_convertToBlockBody_BAD_inExpression() async {
await resolveTestUnit('''
main() => 123;
@@ -3347,11 +3451,9 @@
}
test_moveFlutterWidgetDown_OK() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -3372,7 +3474,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.MOVE_FLUTTER_WIDGET_DOWN, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -3394,11 +3496,9 @@
}
test_moveFlutterWidgetUp_OK() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -3419,7 +3519,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.MOVE_FLUTTER_WIDGET_UP, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
// start
@@ -3568,11 +3668,9 @@
test_reparentFlutterList_BAD_multiLine() async {
verifyNoTestUnitErrors = false;
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -3592,11 +3690,9 @@
}
test_reparentFlutterList_BAD_singleLine() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
var obj;
@@ -3611,11 +3707,9 @@
}
test_reparentFlutterList_OK_multiLine() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -3632,7 +3726,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_LIST, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -3654,9 +3748,7 @@
}
test_reparentFlutterWidget_BAD_minimal() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
/*caret*/x(){}
''');
@@ -3665,11 +3757,9 @@
}
test_reparentFlutterWidget_BAD_singleLine() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
var obj;
@@ -3684,11 +3774,9 @@
}
test_reparentFlutterWidget_OK_multiLines() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
return new Container(
@@ -3708,7 +3796,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
return new Container(
@@ -3731,11 +3819,9 @@
}
test_reparentFlutterWidget_OK_multiLines_eol2() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';\r
+import 'package:flutter/widgets.dart';
class FakeFlutter {\r
main() {\r
return new Container(\r
@@ -3755,7 +3841,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, '''
-import 'package:flutter/src/widgets/framework.dart';\r
+import 'package:flutter/widgets.dart';
class FakeFlutter {\r
main() {\r
return new Container(\r
@@ -3778,11 +3864,9 @@
}
test_reparentFlutterWidget_OK_singleLine1() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
// start
@@ -3793,7 +3877,7 @@
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
// start
@@ -3805,27 +3889,66 @@
}
test_reparentFlutterWidget_OK_singleLine2() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
-// start
return new ClipRect./*caret*/rect();
-// end
}
}
''');
_setCaretLocation();
await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
class FakeFlutter {
main() {
-// start
return new widget(child: new ClipRect./*caret*/rect());
-// end
+ }
+}
+''');
+ }
+
+ test_reparentFlutterWidgetCenter_OK() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Container();
+ }
+}
+''');
+ _setCaretLocation();
+ await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET_CENTER, '''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Center(child: new Container());
+ }
+}
+''');
+ }
+
+ test_reparentFlutterWidgetPadding_OK() async {
+ addFlutterPackage();
+ await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Container();
+ }
+}
+''');
+ _setCaretLocation();
+ await assertHasAssist(DartAssistKind.REPARENT_FLUTTER_WIDGET_PADDING, '''
+import 'package:flutter/widgets.dart';
+class FakeFlutter {
+ main() {
+ return /*caret*/new Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: new Container(),
+ );
}
}
''');
@@ -4390,30 +4513,6 @@
return await processor.compute();
}
- /**
- * Configures the [SourceFactory] to have the `flutter` package in
- * `/packages/flutter/lib` folder.
- */
- void _configureFlutterPkg(Map<String, String> pathToCode) {
- pathToCode.forEach((path, code) {
- newFile('$flutterPkgLibPath/$path', content: code);
- });
- // configure SourceFactory
- Folder myPkgFolder = getFolder(flutterPkgLibPath);
- UriResolver pkgResolver = new PackageMapUriResolver(resourceProvider, {
- 'flutter': [myPkgFolder]
- });
- SourceFactory sourceFactory = new SourceFactory(
- [new DartUriResolver(sdk), pkgResolver, resourceResolver]);
- driver.configure(sourceFactory: sourceFactory);
- // force 'flutter' resolution
- addSource(
- '/tmp/other.dart',
- pathToCode.keys
- .map((path) => "import 'package:flutter/$path';")
- .join('\n'));
- }
-
List<Position> _findResultPositions(List<String> searchStrings) {
List<Position> positions = <Position>[];
for (String search in searchStrings) {
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 5a13acd..a38a0d0 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -26,7 +26,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../abstract_single_unit.dart';
-import '../../src/utilities/flutter_util.dart';
main() {
defineReflectiveSuite(() {
@@ -211,6 +210,190 @@
@reflectiveTest
class FixProcessorTest extends BaseFixProcessorTest {
+ test_addAsync_asyncFor() async {
+ await resolveTestUnit('''
+import 'dart:async';
+void main(Stream<String> names) {
+ await for (String name in names) {
+ print(name);
+ }
+}
+''');
+ await assertHasFix(DartFixKind.ADD_ASYNC, '''
+import 'dart:async';
+Future main(Stream<String> names) async {
+ await for (String name in names) {
+ print(name);
+ }
+}
+''');
+ }
+
+ test_addAsync_BAD_nullFunctionBody() async {
+ await resolveTestUnit('''
+var F = await;
+''');
+ await assertNoFix(DartFixKind.ADD_ASYNC);
+ }
+
+ test_addAsync_blockFunctionBody() async {
+ await resolveTestUnit('''
+foo() {}
+main() {
+ await foo();
+}
+''');
+ List<AnalysisError> errors = await _computeErrors();
+ expect(errors, hasLength(2));
+ errors.sort((a, b) => a.message.compareTo(b.message));
+ // No fix for ";".
+ {
+ AnalysisError error = errors[0];
+ expect(error.message, "Expected to find ';'.");
+ List<Fix> fixes = await _computeFixes(error);
+ expect(fixes, isEmpty);
+ }
+ // Has fix for "await".
+ {
+ AnalysisError error = errors[1];
+ expect(error.message, startsWith("Undefined name 'await' in function"));
+ List<Fix> fixes = await _computeFixes(error);
+ // has exactly one fix
+ expect(fixes, hasLength(1));
+ Fix fix = fixes[0];
+ expect(fix.kind, DartFixKind.ADD_ASYNC);
+ // apply to "file"
+ List<SourceFileEdit> fileEdits = fix.change.edits;
+ expect(fileEdits, hasLength(1));
+ resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits);
+ // verify
+ expect(resultCode, '''
+foo() {}
+main() async {
+ await foo();
+}
+''');
+ }
+ }
+
+ test_addAsync_closure() async {
+ errorFilter = (AnalysisError error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
+ };
+ await resolveTestUnit('''
+import 'dart:async';
+
+void takeFutureCallback(Future callback()) {}
+
+void doStuff() => takeFutureCallback(() => await 1);
+''');
+ await assertHasFix(DartFixKind.ADD_ASYNC, '''
+import 'dart:async';
+
+void takeFutureCallback(Future callback()) {}
+
+void doStuff() => takeFutureCallback(() async => await 1);
+''');
+ }
+
+ test_addAsync_expressionFunctionBody() async {
+ errorFilter = (AnalysisError error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
+ };
+ await resolveTestUnit('''
+foo() {}
+main() => await foo();
+''');
+ await assertHasFix(DartFixKind.ADD_ASYNC, '''
+foo() {}
+main() async => await foo();
+''');
+ }
+
+ test_addAsync_returnFuture() async {
+ errorFilter = (AnalysisError error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
+ };
+ await resolveTestUnit('''
+foo() {}
+int main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix(DartFixKind.ADD_ASYNC, '''
+import 'dart:async';
+
+foo() {}
+Future<int> main() async {
+ await foo();
+ return 42;
+}
+''');
+ }
+
+ test_addAsync_returnFuture_alreadyFuture() async {
+ errorFilter = (AnalysisError error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
+ };
+ await resolveTestUnit('''
+import 'dart:async';
+foo() {}
+Future<int> main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix(DartFixKind.ADD_ASYNC, '''
+import 'dart:async';
+foo() {}
+Future<int> main() async {
+ await foo();
+ return 42;
+}
+''');
+ }
+
+ test_addAsync_returnFuture_dynamic() async {
+ errorFilter = (AnalysisError error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
+ };
+ await resolveTestUnit('''
+foo() {}
+dynamic main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix(DartFixKind.ADD_ASYNC, '''
+foo() {}
+dynamic main() async {
+ await foo();
+ return 42;
+}
+''');
+ }
+
+ test_addAsync_returnFuture_noType() async {
+ errorFilter = (AnalysisError error) {
+ return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
+ };
+ await resolveTestUnit('''
+foo() {}
+main() {
+ await foo();
+ return 42;
+}
+''');
+ await assertHasFix(DartFixKind.ADD_ASYNC, '''
+foo() {}
+main() async {
+ await foo();
+ return 42;
+}
+''');
+ }
+
test_addFieldFormalParameters_hasRequiredParameter() async {
await resolveTestUnit('''
class Test {
@@ -415,13 +598,11 @@
}
test_addMissingRequiredArg_cons_flutter_children() async {
- addPackageSource(
- 'flutter', 'src/widgets/framework.dart', flutter_framework_code);
-
+ addFlutterPackage();
_addMetaPackageSource();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
class MyWidget extends Widget {
@@ -436,7 +617,7 @@
await assertHasFix(
DartFixKind.ADD_MISSING_REQUIRED_ARGUMENT,
'''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
import 'package:meta/meta.dart';
class MyWidget extends Widget {
@@ -767,170 +948,6 @@
''');
}
- test_addSync_asyncFor() async {
- await resolveTestUnit('''
-import 'dart:async';
-void main(Stream<String> names) {
- await for (String name in names) {
- print(name);
- }
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import 'dart:async';
-Future main(Stream<String> names) async {
- await for (String name in names) {
- print(name);
- }
-}
-''');
- }
-
- test_addSync_BAD_nullFunctionBody() async {
- await resolveTestUnit('''
-var F = await;
-''');
- await assertNoFix(DartFixKind.ADD_ASYNC);
- }
-
- test_addSync_blockFunctionBody() async {
- await resolveTestUnit('''
-foo() {}
-main() {
- await foo();
-}
-''');
- List<AnalysisError> errors = await _computeErrors();
- expect(errors, hasLength(2));
- errors.sort((a, b) => a.message.compareTo(b.message));
- // No fix for ";".
- {
- AnalysisError error = errors[0];
- expect(error.message, "Expected to find ';'.");
- List<Fix> fixes = await _computeFixes(error);
- expect(fixes, isEmpty);
- }
- // Has fix for "await".
- {
- AnalysisError error = errors[1];
- expect(error.message, startsWith("Undefined name 'await' in function"));
- List<Fix> fixes = await _computeFixes(error);
- // has exactly one fix
- expect(fixes, hasLength(1));
- Fix fix = fixes[0];
- expect(fix.kind, DartFixKind.ADD_ASYNC);
- // apply to "file"
- List<SourceFileEdit> fileEdits = fix.change.edits;
- expect(fileEdits, hasLength(1));
- resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits);
- // verify
- expect(resultCode, '''
-foo() {}
-main() async {
- await foo();
-}
-''');
- }
- }
-
- test_addSync_expressionFunctionBody() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
- };
- await resolveTestUnit('''
-foo() {}
-main() => await foo();
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-foo() {}
-main() async => await foo();
-''');
- }
-
- test_addSync_returnFuture() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
- };
- await resolveTestUnit('''
-foo() {}
-int main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import 'dart:async';
-
-foo() {}
-Future<int> main() async {
- await foo();
- return 42;
-}
-''');
- }
-
- test_addSync_returnFuture_alreadyFuture() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
- };
- await resolveTestUnit('''
-import 'dart:async';
-foo() {}
-Future<int> main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-import 'dart:async';
-foo() {}
-Future<int> main() async {
- await foo();
- return 42;
-}
-''');
- }
-
- test_addSync_returnFuture_dynamic() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
- };
- await resolveTestUnit('''
-foo() {}
-dynamic main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-foo() {}
-dynamic main() async {
- await foo();
- return 42;
-}
-''');
- }
-
- test_addSync_returnFuture_noType() async {
- errorFilter = (AnalysisError error) {
- return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER_AWAIT;
- };
- await resolveTestUnit('''
-foo() {}
-main() {
- await foo();
- return 42;
-}
-''');
- await assertHasFix(DartFixKind.ADD_ASYNC, '''
-foo() {}
-main() async {
- await foo();
- return 42;
-}
-''');
- }
-
test_boolean() async {
await resolveTestUnit('''
main() {
@@ -2685,7 +2702,6 @@
''');
}
- @failingTest
test_createMissingOverrides_functionTypedParameter() async {
await resolveTestUnit('''
abstract class A {
@@ -2970,6 +2986,30 @@
''');
}
+ test_createMissingOverrides_method_generic_withBounds() async {
+ // https://github.com/dart-lang/sdk/issues/31199
+ await resolveTestUnit('''
+abstract class A<K, V> {
+ List<T> foo<T extends V>(K key);
+}
+
+class B<K, V> implements A<K, V> {
+}
+''');
+ await assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+abstract class A<K, V> {
+ List<T> foo<T extends V>(K key);
+}
+
+class B<K, V> implements A<K, V> {
+ @override
+ List<T> foo<T extends V>(K key) {
+ // TODO: implement foo
+ }
+}
+''');
+ }
+
test_createMissingOverrides_method_notEmptyClassBody() async {
await resolveTestUnit('''
abstract class A {
@@ -5351,11 +5391,9 @@
}
test_undefinedParameter_convertFlutterChild_invalidList() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -5372,11 +5410,9 @@
}
test_undefinedParameter_convertFlutterChild_OK_hasList() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -5390,7 +5426,7 @@
}
''');
await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -5406,11 +5442,9 @@
}
test_undefinedParameter_convertFlutterChild_OK_hasTypedList() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -5424,7 +5458,7 @@
}
''');
await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/widgets.dart';
build() {
return new Container(
child: new Row(
@@ -5440,11 +5474,9 @@
}
test_undefinedParameter_convertFlutterChild_OK_multiLine() async {
- _configureFlutterPkg({
- 'src/widgets/framework.dart': flutter_framework_code,
- });
+ addFlutterPackage();
await resolveTestUnit('''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
body: new Row(
@@ -5457,7 +5489,7 @@
}
''');
await assertHasFix(DartFixKind.CONVERT_FLUTTER_CHILD, '''
-import 'package:flutter/src/widgets/framework.dart';
+import 'package:flutter/material.dart';
build() {
return new Scaffold(
body: new Row(
@@ -5595,30 +5627,6 @@
}
''');
}
-
- /**
- * Configures the [SourceFactory] to have the `flutter` package in
- * `/packages/flutter/lib` folder.
- */
- void _configureFlutterPkg(Map<String, String> pathToCode) {
- pathToCode.forEach((path, code) {
- newFile('$flutterPkgLibPath/$path', content: code);
- });
- // configure SourceFactory
- Folder myPkgFolder = getFolder(flutterPkgLibPath);
- UriResolver pkgResolver = new PackageMapUriResolver(resourceProvider, {
- 'flutter': [myPkgFolder]
- });
- SourceFactory sourceFactory = new SourceFactory(
- [new DartUriResolver(sdk), pkgResolver, resourceResolver]);
- driver.configure(sourceFactory: sourceFactory);
- // force 'flutter' resolution
- addSource(
- '/tmp/other.dart',
- pathToCode.keys
- .map((path) => "import 'package:flutter/$path';")
- .join('\n'));
- }
}
@reflectiveTest
@@ -6426,6 +6434,19 @@
''');
}
+ test_replaceFinalWithConst_method() async {
+ String src = '''
+/*LINT*/final int a = 1;
+''';
+ await findLint(src, LintNames.prefer_const_declarations);
+
+ await applyFix(DartFixKind.REPLACE_FINAL_WITH_CONST);
+
+ verifyResult('''
+const int a = 1;
+''');
+ }
+
test_replaceWithConditionalAssignment_withCodeBeforeAndAfter() async {
String src = '''
class Person {
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index 18eb7d2..6cbfdff 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -126,6 +126,31 @@
assertRefactoringStatusOK(status);
}
+ test_checkFinalConditions_OK_noShadow_nullVisibleRange() async {
+ await indexTestUnit('''
+class A {
+ int foo;
+
+ A(this.foo);
+}
+
+class B {
+ int bar; // declaration
+
+ B(this.bar);
+
+ void referenceField() {
+ bar;
+ }
+}
+''');
+ createRenameRefactoringAtString('bar; // declaration');
+ // check status
+ refactoring.newName = 'foo';
+ RefactoringStatus status = await refactoring.checkFinalConditions();
+ assertRefactoringStatusOK(status);
+ }
+
test_checkFinalConditions_publicToPrivate_usedInOtherLibrary() async {
await indexTestUnit('''
class A {
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index 80085b4..1da0f30 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
@@ -516,6 +516,30 @@
''');
}
+ test_createChange_FunctionTypeAliasElement() async {
+ await indexTestUnit('''
+typedef void F();
+void foo<T>() {}
+void main() {
+ foo<F>();
+}
+''');
+ // configure refactoring
+ createRenameRefactoringAtString('F()');
+ expect(refactoring.refactoringName, 'Rename Function Type Alias');
+ expect(refactoring.elementKindName, 'function type alias');
+ expect(refactoring.oldName, 'F');
+ refactoring.newName = 'G';
+ // validate change
+ return assertSuccessfulRefactoring('''
+typedef void G();
+void foo<T>() {}
+void main() {
+ foo<G>();
+}
+''');
+ }
+
test_createChange_PropertyAccessorElement_getter_declaration() async {
await _test_createChange_PropertyAccessorElement("test {}");
}
diff --git a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
index 53d69f8..45a6435 100644
--- a/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
+++ b/pkg/analysis_server/test/src/flutter/flutter_outline_computer_test.dart
@@ -206,6 +206,62 @@
}
}
+ test_genericLabel_invocation() async {
+ FlutterOutline unitOutline = await _computeOutline(r'''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return new Row(children: [
+ createText(0),
+ createEmptyText(),
+ WidgetFactory.createMyText(),
+ ]);
+ }
+ Text createEmptyText() {
+ return new Text('');
+ }
+ Text createText(int index) {
+ return new Text('index: $index');
+ }
+}
+
+class WidgetFactory {
+ static Text createMyText() => new Text('');
+}
+''');
+ var myWidget = unitOutline.children[0];
+ var build = myWidget.children[0];
+ expect(build.children, hasLength(1));
+
+ var row = build.children[0];
+ expect(row.kind, FlutterOutlineKind.NEW_INSTANCE);
+ expect(row.className, 'Row');
+ expect(row.children, hasLength(3));
+
+ {
+ var text = row.children[0];
+ expect(text.kind, FlutterOutlineKind.GENERIC);
+ expect(text.className, 'Text');
+ expect(text.label, 'createText(…)');
+ }
+
+ {
+ var text = row.children[1];
+ expect(text.kind, FlutterOutlineKind.GENERIC);
+ expect(text.className, 'Text');
+ expect(text.label, 'createEmptyText()');
+ }
+
+ {
+ var text = row.children[2];
+ expect(text.kind, FlutterOutlineKind.GENERIC);
+ expect(text.className, 'Text');
+ expect(text.label, 'WidgetFactory.createMyText()');
+ }
+ }
+
test_parentAssociationLabel() async {
newFile('/a.dart', content: r'''
import 'package:flutter/widgets.dart';
diff --git a/pkg/analysis_server/test/src/utilities/flutter_util.dart b/pkg/analysis_server/test/src/utilities/flutter_util.dart
index 6d1cd55..6a3167c 100644
--- a/pkg/analysis_server/test/src/utilities/flutter_util.dart
+++ b/pkg/analysis_server/test/src/utilities/flutter_util.dart
@@ -7,25 +7,6 @@
String flutterPkgLibPath = '/packages/flutter/lib';
-String get flutter_framework_code => '''
-class Widget {}
-class RenderObjectWidget extends Widget {}
-class StatelessWidget extends Widget {}
-abstract class StatefulWidget extends Widget { }
-class SingleChildRenderObjectWidget extends RenderObjectWidget {}
-class Transform extends SingleChildRenderObjectWidget {}
-class ClipRect extends SingleChildRenderObjectWidget { ClipRect.rect(){} }
-class AspectRatio extends SingleChildRenderObjectWidget {}
-class Container extends StatelessWidget { Container({child: null, width: null, height: null}){}}
-class Center extends StatelessWidget { Center({child: null, key: null}){}}
-class DefaultTextStyle extends StatelessWidget { DefaultTextStyle({child: null}){}}
-class Row extends Widget { Row({List<Widget> children: null, key: null}){}}
-class GestureDetector extends SingleChildRenderObjectWidget { GestureDetector({child: null, onTap: null}){}}
-class AppBar extends StatefulWidget implements PreferredSizeWidget { AppBar(title: null, color: null, key: null) }
-class Scaffold extends Widget { Scaffold({body: null, PreferredSizeWidget appBar: null}){}}
-class PreferredSizeWidget implements Widget {}
-''';
-
/**
* Add some Flutter libraries and types to the given [provider] and return
* the `lib` folder.
@@ -37,12 +18,15 @@
Folder newFolder(String path) =>
provider.newFolder(provider.convertPath(path));
- newFile('/flutter/lib/material.dart', r'''
+ newFile('$flutterPkgLibPath/material.dart', r'''
export 'widgets.dart';
+export 'src/material/app_bar.dart';
+export 'src/material/gesture_detector.dart';
export 'src/material/icons.dart';
+export 'src/material/scaffold.dart';
''');
- newFile('/flutter/lib/widgets.dart', r'''
+ newFile('$flutterPkgLibPath/widgets.dart', r'''
export 'src/widgets/basic.dart';
export 'src/widgets/center.dart';
export 'src/widgets/container.dart';
@@ -52,7 +36,19 @@
''');
void createSrcMaterial() {
- newFile('/flutter/lib/src/material/icons.dart', r'''
+ newFile('$flutterPkgLibPath/src/material/app_bar.dart', r'''
+import 'package:flutter/widgets.dart';
+
+class AppBar extends StatefulWidget {
+ AppBar({
+ Key key,
+ title,
+ backgroundColor,
+ });
+}
+''');
+
+ newFile('$flutterPkgLibPath/src/material/icons.dart', r'''
import 'package:flutter/widgets.dart';
class Icons {
@@ -63,11 +59,76 @@
Icons._();
}
''');
+
+ newFile('$flutterPkgLibPath/src/material/scaffold.dart', r'''
+import 'package:flutter/widgets.dart';
+
+class Scaffold extends StatefulWidget {
+ const Scaffold({
+ Key key,
+ Widget body,
+ });
+}
+''');
+
+ newFile('$flutterPkgLibPath/src/material/gesture_detector.dart', r'''
+import 'package:flutter/widgets.dart';
+
+class GestureDetector extends StatelessWidget {
+ GestureDetector({
+ Key key,
+ Widget child,
+ onTap,
+ });
+''');
+ }
+
+ void createRendering() {
+ newFile('$flutterPkgLibPath/rendering.dart', r'''
+export 'painting.dart';
+''');
+ }
+
+ void createPainting() {
+ newFile('$flutterPkgLibPath/painting.dart', r'''
+export 'src/painting/edge_insets.dart';
+''');
+
+ newFile('$flutterPkgLibPath/src/painting/edge_insets.dart', r'''
+abstract class EdgeInsetsGeometry {
+ const EdgeInsetsGeometry();
+}
+
+class EdgeInsets extends EdgeInsetsGeometry {
+ const EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom);
+
+ const EdgeInsets.all(double value)
+ : left = value, top = value, right = value, bottom = value;
+
+ const EdgeInsets.only({
+ this.left: 0.0,
+ this.top: 0.0,
+ this.right: 0.0,
+ this.bottom: 0.0
+ });
+
+ const EdgeInsets.symmetric({ double vertical: 0.0,
+ double horizontal: 0.0 })
+ : left = horizontal, top = vertical, right = horizontal, bottom = vertical;
+}
+''');
}
void createSrcWidgets() {
- newFile('/flutter/lib/src/widgets/basic.dart', r'''
+ newFile('$flutterPkgLibPath/src/widgets/basic.dart', r'''
import 'framework.dart';
+import 'rendering.dart';
+
+export 'painting.dart';
+
+class Center extends StatelessWidget {
+ const Center({Widget child, Key key});
+}
class Column extends Flex {
Column({
@@ -89,9 +150,47 @@
List<Widget> children: const <Widget>[],
});
}
+
+class ClipRect extends SingleChildRenderObjectWidget {
+ const ClipRect({Key key, Widget child}) :
+ super(key: key, child: child);
+
+ /// Does not actually exist in Flutter.
+ const ClipRect.rect({Key key, Widget child}) :
+ super(key: key, child: child);
+}
+
+class Transform extends SingleChildRenderObjectWidget {
+ const Transform({
+ Key key,
+ @required transform,
+ origin,
+ alignment,
+ transformHitTests: true,
+ Widget child,
+ });
+}
+
+class AspectRatio extends SingleChildRenderObjectWidget {
+ const AspectRatio({
+ Key key,
+ @required aspectRatio,
+ Widget child,
+ });
+}
+
+class Padding extends SingleChildRenderObjectWidget {
+ final EdgeInsetsGeometry padding;
+
+ const Padding({
+ Key key,
+ this.padding,
+ Widget child,
+ });
+}
''');
- newFile('/flutter/lib/src/widgets/container.dart', r'''
+ newFile('$flutterPkgLibPath/src/widgets/container.dart', r'''
import 'framework.dart';
class Container extends StatelessWidget {
@@ -109,7 +208,7 @@
}
''');
- newFile('/flutter/lib/src/widgets/framework.dart', r'''
+ newFile('$flutterPkgLibPath/src/widgets/framework.dart', r'''
typedef void VoidCallback();
abstract class BuildContext {
@@ -161,9 +260,19 @@
const Widget({this.key});
}
+
+abstract class SingleChildRenderObjectWidget extends RenderObjectWidget {
+ final Widget child;
+
+ const SingleChildRenderObjectWidget({Key key, this.child}) : super(key: key);
+}
+
+abstract class RenderObjectWidget extends Widget {
+ const RenderObjectWidget({Key key}) : super(key: key);
+}
''');
- newFile('/flutter/lib/src/widgets/icon.dart', r'''
+ newFile('$flutterPkgLibPath/src/widgets/icon.dart', r'''
import 'framework.dart';
class Icon extends StatelessWidget {
@@ -185,9 +294,13 @@
}
''');
- newFile('/flutter/lib/src/widgets/text.dart', r'''
+ newFile('$flutterPkgLibPath/src/widgets/text.dart', r'''
import 'framework.dart';
+class DefaultTextStyle extends StatelessWidget {
+ DefaultTextStyle({Widget child});
+}
+
class Text extends StatelessWidget {
final String data;
const Text(
@@ -197,18 +310,12 @@
: super(key: key);
}
''');
-
- newFile('/flutter/lib/src/widgets/center.dart', r'''
-import 'framework.dart';
-
-class Center extends StatelessWidget {
- const Center({Widget child, Key key});
-}
-''');
}
- createSrcMaterial();
+ createPainting();
+ createRendering();
createSrcWidgets();
+ createSrcMaterial();
- return newFolder('/flutter/lib');
+ return newFolder(flutterPkgLibPath);
}
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 17bd6ac..3459953 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
<body>
<h1>Analysis Server API Specification</h1>
<h1 style="color:#999999">Version
- <version>1.18.4</version>
+ <version>1.18.5</version>
</h1>
<p>
This document contains a specification of the API provided by the
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f39f2a5..1cf5070 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.31.0+1
+
+* Update SDK constraint to require Dart v2-dev release.
+
+## 0.31.0
+
+* **NOTE** This release was pulled from the package site due to an invalid SDK
+ constraint that was fixed in `0.31.0+1`.
+
+* A number of updates, including support for the new Function syntax.
+
## 0.30.0-alpha.0
* Changed the API for creating BazelWorkspace. It should now be constructed using BazelWorkspace.find(). Note that this might return `null` in the event that the given path is not part of a BazelWorkspace.
* Added an AST structure to support asserts in constructor initializers (AssertInitializer). AstVisitor classes must now implement visitAssertInitializer().
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index ba811b3d..e49bab4 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -4195,9 +4195,11 @@
* An instance creation expression.
*
* newExpression ::=
- * ('new' | 'const') [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
+ * ('new' | 'const')? [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
*
* Clients may not extend, implement or mix-in this class.
+ *
+ * 'new' | 'const' are only optional if the previewDart2 option is enabled.
*/
abstract class InstanceCreationExpression extends Expression
implements ConstructorReferenceNode {
@@ -4223,7 +4225,9 @@
/**
* Return `true` if this creation expression is used to invoke a constant
- * constructor.
+ * constructor, either because the keyword `const` was explicitly provided or
+ * because no keyword was provided and this expression is in a constant
+ * context.
*/
bool get isConst;
@@ -6609,6 +6613,13 @@
void set constKeyword(Token token);
/**
+ * Return `true` if this literal is a constant expression, either because the
+ * keyword `const` was explicitly provided or because no keyword was provided
+ * and this expression is in a constant context.
+ */
+ bool get isConst;
+
+ /**
* Return the type argument associated with this literal, or `null` if no type
* arguments were declared.
*/
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 4ccf24f..65314c8 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -147,6 +147,7 @@
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_FACTORY,
CompileTimeErrorCode.INSTANCE_MEMBER_ACCESS_FROM_STATIC,
CompileTimeErrorCode.INSTANTIATE_ENUM,
+ CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE,
CompileTimeErrorCode.INVALID_ANNOTATION,
CompileTimeErrorCode.INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY,
CompileTimeErrorCode.INVALID_CONSTANT,
@@ -567,7 +568,6 @@
StaticWarningCode.IMPORT_DUPLICATED_LIBRARY_NAMED,
StaticWarningCode.IMPORT_OF_NON_LIBRARY,
StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE,
StaticWarningCode.INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE,
StaticWarningCode.INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE,
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 8b78044..2efe773 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -157,9 +157,10 @@
AnalysisContext buildContext(String path) {
InternalAnalysisContext context =
AnalysisEngine.instance.createAnalysisContext();
- AnalysisOptions options = getAnalysisOptions(path);
+ AnalysisOptionsImpl options = getAnalysisOptions(path);
context.contentCache = contentCache;
context.sourceFactory = createSourceFactory(path, options);
+ options.previewDart2 = previewDart2;
context.analysisOptions = options;
context.name = path;
//_processAnalysisOptions(context, optionMap);
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 6050b2fb..b444188 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -323,6 +323,7 @@
}
this._options.strongMode = options.strongMode;
this._options.useFastaParser = options.useFastaParser;
+ this._options.previewDart2 = options.previewDart2;
this._options.trackCacheDependencies = options.trackCacheDependencies;
this._options.disableCacheFlushing = options.disableCacheFlushing;
this._options.patchPaths = options.patchPaths;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index d4f4af8..0bb7bbe 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -598,6 +598,7 @@
bool useFasta = analysisOptions.useFastaParser;
Parser parser = new Parser(source, errorListener, useFasta: useFasta);
+ parser.enableOptionalNewAndConst = analysisOptions.previewDart2;
parser.parseGenericMethodComments = analysisOptions.strongMode;
CompilationUnit unit = parser.parseCompilationUnit(token);
unit.lineInfo = lineInfo;
@@ -785,7 +786,7 @@
// We are given all required unlinked and linked summaries for it.
if (externalSummaries != null) {
String uriStr = uri.toString();
- if (externalSummaries.hasUnlinkedUnit(uriStr)) {
+ if (externalSummaries.hasLinkedLibrary(uriStr)) {
file = new FileState._external(this, uri);
_uriToFile[uri] = file;
return file;
diff --git a/pkg/analyzer/lib/src/dart/analysis/index.dart b/pkg/analyzer/lib/src/dart/analysis/index.dart
index 17edccb..66337bb 100644
--- a/pkg/analyzer/lib/src/dart/analysis/index.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/index.dart
@@ -612,6 +612,7 @@
: IndexRelationKind.IS_INVOKED_BY;
recordRelation(element, kind, name, isQualified);
node.target?.accept(this);
+ node.typeArguments?.accept(this);
node.argumentList?.accept(this);
}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index fbc951e..5c10748 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -4113,6 +4113,61 @@
return DynamicTypeImpl.instance;
}
+ /**
+ * An expression _e_ is said to _occur in a constant context_,
+ * * if _e_ is an element of a constant list literal, or a key or value of an
+ * entry of a constant map literal.
+ * * if _e_ is an actual argument of a constant object expression or of a
+ * metadata annotation.
+ * * if _e_ is the initializing expression of a constant variable declaration.
+ * * if _e_ is a switch case expression.
+ * * if _e_ is an immediate subexpression of an expression _e1_ which occurs
+ * in a constant context, unless _e1_ is a `throw` expression or a function
+ * literal.
+ *
+ * This roughly means that everything which is inside a syntactically constant
+ * expression is in a constant context. A `throw` expression is currently not
+ * allowed in a constant expression, but extensions affecting that status may
+ * be considered. A similar situation arises for function literals.
+ *
+ * Note that the default value of an optional formal parameter is _not_ a
+ * constant context. This choice reserves some freedom to modify the semantics
+ * of default values.
+ */
+ bool get inConstantContext {
+ AstNode child = this;
+ while (child is Expression ||
+ child is ArgumentList ||
+ child is MapLiteralEntry) {
+ AstNode parent = child.parent;
+ if (parent is TypedLiteralImpl && parent.constKeyword != null) {
+ // Inside an explicitly `const` list or map literal.
+ return true;
+ } else if (parent is InstanceCreationExpression) {
+ if (parent.keyword?.keyword == Keyword.CONST) {
+ // Inside an explicitly `const` instance creation expression.
+ return true;
+ } else if (parent.keyword?.keyword == Keyword.NEW) {
+ // Inside an explicitly non-`const` instance creation expression.
+ return false;
+ }
+ } else if (parent is Annotation) {
+ // Inside an annotation.
+ return true;
+ } else if (parent is VariableDeclaration) {
+ AstNode grandParent = parent.parent;
+ // Inside the initializer for a `const` variable declaration.
+ return grandParent is VariableDeclarationList &&
+ grandParent.keyword?.keyword == Keyword.CONST;
+ } else if (parent is SwitchCase) {
+ // Inside a switch case.
+ return true;
+ }
+ child = parent;
+ }
+ return false;
+ }
+
@override
bool get isAssignable => false;
@@ -6367,7 +6422,9 @@
* An instance creation expression.
*
* newExpression ::=
- * ('new' | 'const') [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
+ * ('new' | 'const')? [TypeName] ('.' [SimpleIdentifier])? [ArgumentList]
+ *
+ * 'new' | 'const' are only optional if the previewDart2 option is enabled.
*/
class InstanceCreationExpressionImpl extends ExpressionImpl
implements InstanceCreationExpression {
@@ -6434,7 +6491,20 @@
Token get endToken => _argumentList.endToken;
@override
- bool get isConst => keyword?.keyword == Keyword.CONST;
+ bool get isConst {
+ if (!isImplicit) {
+ return keyword.keyword == Keyword.CONST;
+ } else {
+ return inConstantContext;
+ }
+ }
+
+ /**
+ * Return `true` if this is an implicit constructor invocations.
+ *
+ * This can only be `true` when the previewDart2 option is enabled.
+ */
+ bool get isImplicit => keyword == null;
@override
int get precedence => 16;
@@ -10649,6 +10719,11 @@
}
@override
+ bool get isConst {
+ return constKeyword != null || inConstantContext;
+ }
+
+ @override
TypeArgumentList get typeArguments => _typeArguments;
@override
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 96d278c..d0a69b7 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -7290,7 +7290,9 @@
Object visitDefaultFormalParameter(DefaultFormalParameter node) {
_visitNode(node.parameter);
if (node.separator != null) {
- _writer.print(" ");
+ if (node.separator.lexeme != ":") {
+ _writer.print(" ");
+ }
_writer.print(node.separator.lexeme);
_visitNodeWithPrefix(" ", node.defaultValue);
}
@@ -8603,7 +8605,9 @@
Object visitDefaultFormalParameter(DefaultFormalParameter node) {
safelyVisitNode(node.parameter);
if (node.separator != null) {
- sink.write(" ");
+ if (node.separator.lexeme != ":") {
+ sink.write(" ");
+ }
sink.write(node.separator.lexeme);
safelyVisitNodeWithPrefix(" ", node.defaultValue);
}
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 992a468..79a8383 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.dart.constant.evaluation;
-
import 'dart:collection';
import 'package:analyzer/context/declared_variables.dart';
@@ -752,6 +750,22 @@
reportLocalErrorForRecordedExternalErrors();
return result;
}
+ } else if (initializer is AssertInitializer) {
+ Expression condition = initializer.condition;
+ if (condition == null) {
+ errorReporter.reportErrorForNode(
+ CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+ node);
+ }
+ DartObjectImpl evaluationResult = condition.accept(initializerVisitor);
+ if (evaluationResult == null ||
+ !evaluationResult.isBool ||
+ evaluationResult.toBoolValue() != true) {
+ errorReporter.reportErrorForNode(
+ CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
+ node);
+ return null;
+ }
}
}
// Evaluate explicit or implicit call to super().
@@ -1241,30 +1255,24 @@
@override
DartObjectImpl visitBinaryExpression(BinaryExpression node) {
- DartObjectImpl leftResult = node.leftOperand.accept(this);
- DartObjectImpl rightResult = node.rightOperand.accept(this);
TokenType operatorType = node.operator.type;
- // 'null' is almost never good operand
- if (operatorType != TokenType.BANG_EQ &&
- operatorType != TokenType.EQ_EQ &&
- operatorType != TokenType.QUESTION_QUESTION) {
- if (leftResult != null && leftResult.isNull ||
- rightResult != null && rightResult.isNull) {
- _error(node, CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
- return null;
- }
+ DartObjectImpl leftResult = node.leftOperand.accept(this);
+ // evaluate lazy operators
+ if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
+ return _dartObjectComputer.logicalAnd(
+ node, leftResult, () => node.rightOperand.accept(this));
+ } else if (operatorType == TokenType.BAR_BAR) {
+ return _dartObjectComputer.logicalOr(
+ node, leftResult, () => node.rightOperand.accept(this));
}
- // evaluate operator
+ // evaluate eager operators
+ DartObjectImpl rightResult = node.rightOperand.accept(this);
if (operatorType == TokenType.AMPERSAND) {
return _dartObjectComputer.bitAnd(node, leftResult, rightResult);
- } else if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
- return _dartObjectComputer.logicalAnd(node, leftResult, rightResult);
} else if (operatorType == TokenType.BANG_EQ) {
return _dartObjectComputer.notEqual(node, leftResult, rightResult);
} else if (operatorType == TokenType.BAR) {
return _dartObjectComputer.bitOr(node, leftResult, rightResult);
- } else if (operatorType == TokenType.BAR_BAR) {
- return _dartObjectComputer.logicalOr(node, leftResult, rightResult);
} else if (operatorType == TokenType.CARET) {
return _dartObjectComputer.bitXor(node, leftResult, rightResult);
} else if (operatorType == TokenType.EQ_EQ) {
@@ -1880,10 +1888,10 @@
}
DartObjectImpl logicalAnd(BinaryExpression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperand) {
- if (leftOperand != null && rightOperand != null) {
+ DartObjectImpl rightOperandComputer()) {
+ if (leftOperand != null) {
try {
- return leftOperand.logicalAnd(_typeProvider, rightOperand);
+ return leftOperand.logicalAnd(_typeProvider, rightOperandComputer);
} on EvaluationException catch (exception) {
_errorReporter.reportErrorForNode(exception.errorCode, node);
}
@@ -1903,10 +1911,10 @@
}
DartObjectImpl logicalOr(BinaryExpression node, DartObjectImpl leftOperand,
- DartObjectImpl rightOperand) {
- if (leftOperand != null && rightOperand != null) {
+ DartObjectImpl rightOperandComputer()) {
+ if (leftOperand != null) {
try {
- return leftOperand.logicalOr(_typeProvider, rightOperand);
+ return leftOperand.logicalOr(_typeProvider, rightOperandComputer);
} on EvaluationException catch (exception) {
_errorReporter.reportErrorForNode(exception.errorCode, node);
}
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index b097c0e..e4bcf2a 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -8,8 +8,10 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
+import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart'
@@ -37,7 +39,9 @@
* constants to be evaluated.
*/
class ConstantAstCloner extends AstCloner {
- ConstantAstCloner() : super(true);
+ final bool previewDart2;
+
+ ConstantAstCloner(this.previewDart2) : super(true);
@override
Annotation visitAnnotation(Annotation node) {
@@ -65,11 +69,32 @@
InstanceCreationExpression node) {
InstanceCreationExpression expression =
super.visitInstanceCreationExpression(node);
+ if (previewDart2 && node.keyword == null && node.isConst) {
+ expression.keyword = new KeywordToken(Keyword.CONST, node.offset);
+ }
expression.staticElement = node.staticElement;
return expression;
}
@override
+ ListLiteral visitListLiteral(ListLiteral node) {
+ ListLiteral literal = super.visitListLiteral(node);
+ if (previewDart2 && node.constKeyword == null && node.isConst) {
+ literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
+ }
+ return literal;
+ }
+
+ @override
+ MapLiteral visitMapLiteral(MapLiteral node) {
+ MapLiteral literal = super.visitMapLiteral(node);
+ if (previewDart2 && node.constKeyword == null && node.isConst) {
+ literal.constKeyword = new KeywordToken(Keyword.CONST, node.offset);
+ }
+ return literal;
+ }
+
+ @override
RedirectingConstructorInvocation visitRedirectingConstructorInvocation(
RedirectingConstructorInvocation node) {
RedirectingConstructorInvocation invocation =
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 91d79cf..ea4f84d 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -100,12 +100,13 @@
}
@override
- BoolState logicalAnd(InstanceState rightOperand) {
- assertBool(rightOperand);
- if (value == null) {
- return UNKNOWN_VALUE;
+ BoolState logicalAnd(InstanceState rightOperandComputer()) {
+ if (value == false) {
+ return FALSE_STATE;
}
- return value ? rightOperand.convertToBool() : FALSE_STATE;
+ InstanceState rightOperand = rightOperandComputer();
+ assertBool(rightOperand);
+ return value == null ? UNKNOWN_VALUE : rightOperand.convertToBool();
}
@override
@@ -117,12 +118,13 @@
}
@override
- BoolState logicalOr(InstanceState rightOperand) {
- assertBool(rightOperand);
- if (value == null) {
- return UNKNOWN_VALUE;
+ BoolState logicalOr(InstanceState rightOperandComputer()) {
+ if (value == true) {
+ return TRUE_STATE;
}
- return value ? TRUE_STATE : rightOperand.convertToBool();
+ InstanceState rightOperand = rightOperandComputer();
+ assertBool(rightOperand);
+ return value == null ? UNKNOWN_VALUE : rightOperand.convertToBool();
}
@override
@@ -493,9 +495,9 @@
* object of this kind.
*/
DartObjectImpl logicalAnd(
- TypeProvider typeProvider, DartObjectImpl rightOperand) =>
- new DartObjectImpl(
- typeProvider.boolType, _state.logicalAnd(rightOperand._state));
+ TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
+ new DartObjectImpl(typeProvider.boolType,
+ _state.logicalAnd(() => rightOperandComputer()?._state));
/**
* Return the result of invoking the '!' operator on this object. The
@@ -516,9 +518,9 @@
* object of this kind.
*/
DartObjectImpl logicalOr(
- TypeProvider typeProvider, DartObjectImpl rightOperand) =>
- new DartObjectImpl(
- typeProvider.boolType, _state.logicalOr(rightOperand._state));
+ TypeProvider typeProvider, DartObjectImpl rightOperandComputer()) =>
+ new DartObjectImpl(typeProvider.boolType,
+ _state.logicalOr(() => rightOperandComputer()?._state));
/**
* Return the result of invoking the '-' operator on this object with the
@@ -1198,8 +1200,8 @@
}
@override
- BoolState logicalAnd(InstanceState rightOperand) {
- assertBool(rightOperand);
+ BoolState logicalAnd(InstanceState rightOperandComputer()) {
+ assertBool(rightOperandComputer());
return BoolState.UNKNOWN_VALUE;
}
@@ -1207,7 +1209,8 @@
BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
@override
- BoolState logicalOr(InstanceState rightOperand) {
+ BoolState logicalOr(InstanceState rightOperandComputer()) {
+ InstanceState rightOperand = rightOperandComputer();
assertBool(rightOperand);
return rightOperand.convertToBool();
}
@@ -1485,7 +1488,8 @@
}
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1560,7 +1564,8 @@
IntState bitAnd(InstanceState rightOperand) {
assertIntOrNull(this);
assertIntOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1571,7 +1576,8 @@
*/
IntState bitNot() {
assertIntOrNull(this);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1584,7 +1590,8 @@
IntState bitOr(InstanceState rightOperand) {
assertIntOrNull(this);
assertIntOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1597,7 +1604,8 @@
IntState bitXor(InstanceState rightOperand) {
assertIntOrNull(this);
assertIntOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1609,7 +1617,8 @@
*/
StringState concatenate(InstanceState rightOperand) {
assertString(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1638,7 +1647,8 @@
NumState divide(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1660,7 +1670,8 @@
BoolState greaterThan(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1673,7 +1684,8 @@
BoolState greaterThanOrEqual(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1686,7 +1698,8 @@
IntState integerDivide(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1705,7 +1718,8 @@
BoolState lessThan(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1718,7 +1732,8 @@
BoolState lessThanOrEqual(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1728,10 +1743,14 @@
* Throws an [EvaluationException] if the operator is not appropriate for an
* object of this kind.
*/
- BoolState logicalAnd(InstanceState rightOperand) {
+ BoolState logicalAnd(InstanceState rightOperandComputer()) {
assertBool(this);
+ if (convertToBool() == BoolState.FALSE_STATE) {
+ return this;
+ }
+ InstanceState rightOperand = rightOperandComputer();
assertBool(rightOperand);
- return BoolState.FALSE_STATE;
+ return rightOperand.convertToBool();
}
/**
@@ -1752,8 +1771,12 @@
* Throws an [EvaluationException] if the operator is not appropriate for an
* object of this kind.
*/
- BoolState logicalOr(InstanceState rightOperand) {
+ BoolState logicalOr(InstanceState rightOperandComputer()) {
assertBool(this);
+ if (convertToBool() == BoolState.TRUE_STATE) {
+ return this;
+ }
+ InstanceState rightOperand = rightOperandComputer();
assertBool(rightOperand);
return rightOperand.convertToBool();
}
@@ -1768,7 +1791,8 @@
NumState minus(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1779,7 +1803,8 @@
*/
NumState negated() {
assertNumOrNull(this);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1792,7 +1817,8 @@
NumState remainder(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1805,7 +1831,8 @@
IntState shiftLeft(InstanceState rightOperand) {
assertIntOrNull(this);
assertIntOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1818,7 +1845,8 @@
IntState shiftRight(InstanceState rightOperand) {
assertIntOrNull(this);
assertIntOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1829,7 +1857,8 @@
*/
IntState stringLength() {
assertString(this);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
/**
@@ -1842,7 +1871,8 @@
NumState times(InstanceState rightOperand) {
assertNumOrNull(this);
assertNumOrNull(rightOperand);
- throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
+ throw new EvaluationException(
+ CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
}
}
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 744a53d..67fe7c13 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -2127,33 +2127,6 @@
return this;
}
- if (isDartAsyncFuture && newTypeArguments.isNotEmpty) {
- //
- // In strong mode interpret Future< T > as Future< flatten(T) >
- //
- // For example, Future<Future<T>> will flatten to Future<T>.
- //
- // In the Dart 3rd edition spec, this flatten operation is used for
- // `async` and `await`. In strong mode, we extend it to all Future<T>
- // instantiations. This allows typing of Future-related operations
- // in dart:async in a way that matches their runtime behavior and provides
- // precise return types for users of these APIs.
- //
- // For example:
- //
- // abstract class Future<T> {
- // Future<S> then<S>(S onValue(T value), ...);
- // }
- //
- // Given a call where S <: Future<R> for some R, we will need to flatten
- // the return type so it is Future< flatten(S) >, yielding Future<R>.
- //
- if (element.library.context.analysisOptions.strongMode) {
- TypeImpl t = newTypeArguments[0];
- newTypeArguments[0] = t.flattenFutures(new StrongTypeSystemImpl(null));
- }
- }
-
InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
newType.typeArguments = newTypeArguments;
return newType;
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 29d2e48..dc4b398 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -1407,6 +1407,13 @@
"Enums can't be instantiated.",
"Try using one of the defined constants.");
+ static const CompileTimeErrorCode INTEGER_LITERAL_OUT_OF_RANGE =
+ const CompileTimeErrorCode(
+ 'INTEGER_LITERAL_OUT_OF_RANGE',
+ "The integer literal {0} can't be represented in 64 bits.",
+ "Try using the BigInt class if you need an integer larger than "
+ "9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.");
+
/**
* 15 Metadata: Metadata consists of a series of annotations, each of which
* begin with the character @, followed by a constant expression that must be
@@ -2813,13 +2820,13 @@
"Try changing the condition.");
/**
- * 13.15 Assert: It is a static type warning if the type of <i>e</i> may not
- * be assigned to either bool or () → bool
+ * 17.17 Assert: It is a static type warning if the type of <i>e</i> may not
+ * be assigned to bool.
*/
static const StaticTypeWarningCode NON_BOOL_EXPRESSION =
const StaticTypeWarningCode(
'NON_BOOL_EXPRESSION',
- "Assertions must be on either a 'bool' or '() -> bool'.",
+ "The expression in an assert must be of type 'bool'.",
"Try changing the expression.");
/**
@@ -3803,22 +3810,6 @@
"inconsistency.");
/**
- * 7.1 Instance Methods: It is a static warning if a class <i>C</i> declares
- * an instance method named <i>n</i> and an accessible static member named
- * <i>n</i> is declared in a superclass of <i>C</i>.
- *
- * Parameters:
- * 0: the name of the member with the name conflict
- * 1: the name of the enclosing class that has the static member
- */
- static const StaticWarningCode
- INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC =
- const StaticWarningCode(
- 'INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC',
- "'{0}' collides with a static member in the superclass '{1}'.",
- "Try renaming either the method or the inherited member.");
-
- /**
* 7.2 Getters: It is a static warning if a getter <i>m1</i> overrides a
* getter <i>m2</i> and the type of <i>m1</i> is not a subtype of the type of
* <i>m2</i>.
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 1a944e0..9b0220a 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -50,6 +50,10 @@
errorReporter?.reportErrorForOffset(
ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, offset, length);
return;
+ case "BREAK_OUTSIDE_OF_LOOP":
+ errorReporter?.reportErrorForOffset(
+ ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, offset, length);
+ return;
case "BUILT_IN_IDENTIFIER_AS_TYPE":
String name = stringOrTokenLexeme();
errorReporter?.reportErrorForOffset(
@@ -95,6 +99,14 @@
errorReporter?.reportErrorForOffset(
CompileTimeErrorCode.CONST_NOT_INITIALIZED, offset, length, [name]);
return;
+ case "CONTINUE_OUTSIDE_OF_LOOP":
+ errorReporter?.reportErrorForOffset(
+ ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, offset, length);
+ return;
+ case "CONTINUE_WITHOUT_LABEL_IN_CASE":
+ errorReporter?.reportErrorForOffset(
+ ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, offset, length);
+ return;
case "COVARIANT_AFTER_FINAL":
errorReporter?.reportErrorForOffset(
ParserErrorCode.COVARIANT_AFTER_FINAL, offset, length);
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index 8416c84..b3774e2 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -737,7 +737,7 @@
/// Otherwise return the given [member].
static Member _getRealTarget(Member member) {
if (member is Procedure && member.isForwardingStub) {
- return member.forwardingStubInterfaceTarget.node;
+ return member.forwardingStubInterfaceTarget;
}
return member;
}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index abf9bae..cc8dc80 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -7,6 +7,7 @@
import 'dart:collection';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/ast_factory.dart';
import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
@@ -19,12 +20,15 @@
IdentifierImpl,
PrefixedIdentifierImpl,
SimpleIdentifierImpl;
+import 'package:analyzer/src/dart/ast/ast_factory.dart';
import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/task/strong/checker.dart';
/**
@@ -129,6 +133,11 @@
TypePromotionManager _promoteManager;
/**
+ * Gets an instance of [AstFactory] based on the standard AST implementation.
+ */
+ AstFactory _astFactory;
+
+ /**
* Initialize a newly created visitor to work for the given [_resolver] to
* resolve the nodes in a compilation unit.
*/
@@ -141,6 +150,7 @@
_typeType = _resolver.typeProvider.typeType;
_subtypeManager = new SubtypeManager();
_promoteManager = _resolver.promoteManager;
+ _astFactory = new AstFactoryImpl();
}
/**
@@ -615,9 +625,23 @@
}
Element staticElement;
Element propagatedElement;
+ bool previewDart2 = _definingLibrary.context.analysisOptions.previewDart2;
if (target == null) {
staticElement = _resolveInvokedElement(methodName);
propagatedElement = null;
+
+ if (previewDart2 &&
+ staticElement != null &&
+ staticElement is ClassElement) {
+ // cases: C() or C<>()
+ InstanceCreationExpression instanceCreationExpression =
+ _handleImplicitConstructorCase(node, staticElement);
+ if (instanceCreationExpression != null) {
+ // If a non-null is returned, the node was created, replaced, so we
+ // can return here.
+ return null;
+ }
+ }
} else if (methodName.name == FunctionElement.LOAD_LIBRARY_NAME &&
_isDeferredPrefix(target)) {
if (node.operator.type == TokenType.QUESTION_PERIOD) {
@@ -641,6 +665,29 @@
//
bool isConditional = node.operator.type == TokenType.QUESTION_PERIOD;
ClassElement typeReference = getTypeReference(target);
+
+ if (previewDart2) {
+ InstanceCreationExpression instanceCreationExpression;
+ if ((target is SimpleIdentifier &&
+ target.staticElement is PrefixElement) ||
+ (target is PrefixedIdentifier &&
+ target.prefix.staticElement is PrefixElement)) {
+ // case: p.C(), p.C<>() or p.C.n()
+ instanceCreationExpression =
+ _handlePrefixedImplicitConstructorCase(node, target);
+ } else if (typeReference is ClassElement) {
+ // case: C.n()
+ instanceCreationExpression =
+ _handleImplicitConstructorCase(node, typeReference);
+ }
+
+ if (instanceCreationExpression != null) {
+ // If a non-null is returned, the node was created, replaced, so we
+ // can return here.
+ return null;
+ }
+ }
+
if (typeReference != null) {
if (node.isCascaded) {
typeReference = _typeType.element;
@@ -1567,6 +1614,187 @@
}
/**
+ * Return the newly created and replaced [InstanceCreationExpression], or
+ * `null` if this is not an implicit constructor case.
+ *
+ * This method covers the "ClassName()" and "ClassName.namedConstructor()"
+ * cases for the prefixed cases, i.e. "libraryPrefix.ClassName()" and
+ * "libraryPrefix.ClassName.namedConstructor()" see
+ * [_handlePrefixedImplicitConstructorCase].
+ */
+ InstanceCreationExpression _handleImplicitConstructorCase(
+ MethodInvocation node, ClassElement classElement) {
+ // If target == null, then this is the unnamed constructor, A(), case,
+ // otherwise it is the named constructor A.name() case.
+ Expression target = node.realTarget;
+ bool isNamedConstructorCase = target != null;
+
+ // If we are in the named constructor case, verify that the target is a
+ // SimpleIdentifier and that the operator is '.'
+ SimpleIdentifier targetSimpleId;
+ if (isNamedConstructorCase) {
+ if (target is SimpleIdentifier &&
+ node.operator.type == TokenType.PERIOD) {
+ targetSimpleId = target;
+ } else {
+ // Return null as this is not an implicit constructor case.
+ return null;
+ }
+ }
+
+ // Before any ASTs are created, look up ConstructorElement to see if we
+ // should construct an [InstanceCreationExpression] to replace this
+ // [MethodInvocation].
+ InterfaceType classType = classElement.type;
+ if (node.typeArguments != null) {
+ int parameterCount = classType.typeParameters.length;
+ int argumentCount = node.typeArguments.length;
+ if (parameterCount == argumentCount) {
+ // TODO(brianwilkerson) More gracefully handle the case where the counts
+ // are different.
+ List<DartType> typeArguments = node.typeArguments.arguments
+ .map((TypeAnnotation type) => type.type)
+ .toList();
+ classType = classType.instantiate(typeArguments);
+ }
+ } else {
+ int parameterCount = classType.typeParameters.length;
+ if (parameterCount > 0) {
+ List<DartType> typeArguments =
+ new List<DartType>.filled(parameterCount, _dynamicType);
+ classType = classType.instantiate(typeArguments);
+ }
+ }
+ ConstructorElement constructorElt;
+ if (isNamedConstructorCase) {
+ constructorElt =
+ classType.lookUpConstructor(node.methodName.name, _definingLibrary);
+ } else {
+ constructorElt = classType.lookUpConstructor(null, _definingLibrary);
+ }
+ // If the constructor was not looked up, return `null` so resulting
+ // resolution, such as error messages, will proceed as a [MethodInvocation].
+ if (constructorElt == null) {
+ return null;
+ }
+
+ // Create the Constructor name, in each case: A[.named]()
+ TypeName typeName;
+ ConstructorName constructorName;
+ if (isNamedConstructorCase) {
+ // A.named()
+ typeName = _astFactory.typeName(targetSimpleId, node.typeArguments);
+ typeName.type = classType;
+ constructorName =
+ _astFactory.constructorName(typeName, node.operator, node.methodName);
+ } else {
+ // A()
+ typeName = _astFactory.typeName(node.methodName, node.typeArguments);
+ typeName.type = classType;
+ constructorName = _astFactory.constructorName(typeName, null, null);
+ }
+ InstanceCreationExpression instanceCreationExpression = _astFactory
+ .instanceCreationExpression(null, constructorName, node.argumentList);
+
+ if (isNamedConstructorCase) {
+ constructorName.name.staticElement = constructorElt;
+ }
+ constructorName.staticElement = constructorElt;
+ instanceCreationExpression.staticElement = constructorElt;
+ instanceCreationExpression.staticType = classType;
+
+ // Finally, do the node replacement, true is returned iff the replacement
+ // was successful, only return the new node if it was successful.
+ if (NodeReplacer.replace(node, instanceCreationExpression)) {
+ return instanceCreationExpression;
+ }
+ return null;
+ }
+
+ /**
+ * Return the newly created and replaced [InstanceCreationExpression], or
+ * `null` if this is not an implicit constructor case.
+ *
+ * This method covers the "libraryPrefix.ClassName()" and
+ * "libraryPrefix.ClassName.namedConstructor()" cases for the non-prefixed
+ * cases, i.e. "ClassName()" and "ClassName.namedConstructor()" see
+ * [_handleImplicitConstructorCase].
+ */
+ InstanceCreationExpression _handlePrefixedImplicitConstructorCase(
+ MethodInvocation node, Identifier libraryPrefixId) {
+ bool isNamedConstructorCase = libraryPrefixId is PrefixedIdentifier;
+ ClassElement classElement;
+ if (isNamedConstructorCase) {
+ var elt = (libraryPrefixId as PrefixedIdentifier).staticElement;
+ if (elt is ClassElement) {
+ classElement = elt;
+ }
+ } else {
+ LibraryElementImpl libraryElementImpl = _getImportedLibrary(node.target);
+ classElement = libraryElementImpl.getType(node.methodName.name);
+ }
+
+ // Before any ASTs are created, look up ConstructorElement to see if we
+ // should construct an [InstanceCreationExpression] to replace this
+ // [MethodInvocation].
+ if (classElement == null) {
+ return null;
+ }
+ ConstructorElement constructorElt;
+ if (isNamedConstructorCase) {
+ constructorElt = classElement.type
+ .lookUpConstructor(node.methodName.name, _definingLibrary);
+ } else {
+ constructorElt =
+ classElement.type.lookUpConstructor(null, _definingLibrary);
+ }
+ // If the constructor was not looked up, return `null` so resulting
+ // resolution, such as error messages, will proceed as a [MethodInvocation].
+ if (constructorElt == null) {
+ return null;
+ }
+
+ // Create the Constructor name, in each case: A[.named]()
+ TypeName typeName;
+ ConstructorName constructorName;
+ if (isNamedConstructorCase) {
+ // p.A.n()
+ // libraryPrefixId is a PrefixedIdentifier in this case
+ typeName = _astFactory.typeName(libraryPrefixId, node.typeArguments);
+ typeName.type = classElement.type;
+ constructorName =
+ _astFactory.constructorName(typeName, node.operator, node.methodName);
+ } else {
+ // p.A()
+ // libraryPrefixId is a SimpleIdentifier in this case
+ PrefixedIdentifier prefixedIdentifier = _astFactory.prefixedIdentifier(
+ libraryPrefixId,
+ TokenFactory.tokenFromType(TokenType.PERIOD),
+ node.methodName);
+ typeName = _astFactory.typeName(prefixedIdentifier, node.typeArguments);
+ typeName.type = classElement.type;
+ constructorName = _astFactory.constructorName(typeName, null, null);
+ }
+ InstanceCreationExpression instanceCreationExpression = _astFactory
+ .instanceCreationExpression(null, constructorName, node.argumentList);
+
+ if (isNamedConstructorCase) {
+ constructorName.name.staticElement = constructorElt;
+ }
+ constructorName.staticElement = constructorElt;
+ instanceCreationExpression.staticElement = constructorElt;
+ instanceCreationExpression.staticType = classElement.type;
+
+ // Finally, do the node replacement, true is returned iff the replacement
+ // was successful, only return the new node if it was successful.
+ if (NodeReplacer.replace(node, instanceCreationExpression)) {
+ return instanceCreationExpression;
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Return `true` if the given [element] is or inherits from a class marked
* with `@proxy`.
*
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 75a93ec..e0802f5 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1297,6 +1297,11 @@
bool get preserveComments;
/**
+ * Return `true` if analyzer should enable the use of Dart 2.0 features.
+ */
+ bool get previewDart2;
+
+ /**
* Return the opaque signature of the options.
*
* The length of the list is guaranteed to equal [signatureLength].
@@ -1466,6 +1471,9 @@
bool useFastaParser = false;
@override
+ bool previewDart2 = false;
+
+ @override
bool disableCacheFlushing = false;
/**
@@ -1522,6 +1530,7 @@
preserveComments = options.preserveComments;
strongMode = options.strongMode;
useFastaParser = options.useFastaParser;
+ previewDart2 = options.previewDart2;
if (options is AnalysisOptionsImpl) {
declarationCasts = options.declarationCasts;
strongModeHints = options.strongModeHints;
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 4158b0d..f7d851f 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.generated.error_verifier;
-
import 'dart:collection';
import "dart:math" as math;
@@ -16,6 +14,7 @@
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -917,6 +916,12 @@
}
@override
+ Object visitIntegerLiteral(IntegerLiteral node) {
+ _checkForOutOfRange(node);
+ return super.visitIntegerLiteral(node);
+ }
+
+ @override
Object visitIsExpression(IsExpression node) {
_checkForTypeAnnotationDeferredClass(node.type);
return super.visitIsExpression(node);
@@ -1720,8 +1725,7 @@
* overriding. The [parameters] is the parameters of the executable element.
* The [errorNameTarget] is the node to report problems on.
*
- * See [StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC],
- * [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED],
+ * See [CompileTimeErrorCode.INVALID_OVERRIDE_REQUIRED],
* [CompileTimeErrorCode.INVALID_OVERRIDE_POSITIONAL],
* [CompileTimeErrorCode.INVALID_OVERRIDE_NAMED],
* [StaticWarningCode.INVALID_GETTER_OVERRIDE_RETURN_TYPE],
@@ -2087,10 +2091,6 @@
//
List<ExecutableElement> overriddenExecutables = _inheritanceManager
.lookupOverrides(_enclosingClass, executableElement.name);
- if (_checkForInstanceMethodNameCollidesWithSuperclassStatic(
- executableElement, errorNameTarget)) {
- return;
- }
for (ExecutableElement overriddenElement in overriddenExecutables) {
if (_checkForAllInvalidOverrideErrorCodes(executableElement,
overriddenElement, parameters, parameterLocations, errorNameTarget)) {
@@ -3270,10 +3270,17 @@
if (type.element.isAbstract) {
ConstructorElement element = expression.staticElement;
if (element != null && !element.isFactory) {
- if (expression.isConst) {
+ bool isImplicit =
+ (expression as InstanceCreationExpressionImpl).isImplicit;
+ if (!isImplicit) {
_errorReporter.reportErrorForNode(
- StaticWarningCode.CONST_WITH_ABSTRACT_CLASS, typeName);
+ expression.isConst
+ ? StaticWarningCode.CONST_WITH_ABSTRACT_CLASS
+ : StaticWarningCode.NEW_WITH_ABSTRACT_CLASS,
+ typeName);
} else {
+ // TODO(brianwilkerson/jwren) Create a new different StaticWarningCode
+ // which does not call out the new keyword so explicitly.
_errorReporter.reportErrorForNode(
StaticWarningCode.NEW_WITH_ABSTRACT_CLASS, typeName);
}
@@ -4340,81 +4347,6 @@
}
/**
- * Check whether the given [executableElement] collides with the name of a
- * static method in one of its superclasses, and reports the appropriate
- * warning if it does. The [errorNameTarget] is the node to report problems
- * on.
- *
- * See [StaticTypeWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC].
- */
- bool _checkForInstanceMethodNameCollidesWithSuperclassStatic(
- ExecutableElement executableElement, SimpleIdentifier errorNameTarget) {
- String executableElementName = executableElement.name;
- if (executableElement is! PropertyAccessorElement &&
- !executableElement.isOperator) {
- HashSet<ClassElement> visitedClasses = new HashSet<ClassElement>();
- InterfaceType superclassType = _enclosingClass.supertype;
- ClassElement superclassElement = superclassType?.element;
- bool executableElementPrivate =
- Identifier.isPrivateName(executableElementName);
- while (superclassElement != null &&
- !visitedClasses.contains(superclassElement)) {
- visitedClasses.add(superclassElement);
- LibraryElement superclassLibrary = superclassElement.library;
- // Check fields.
- FieldElement fieldElt =
- superclassElement.getField(executableElementName);
- if (fieldElt != null) {
- // Ignore if private in a different library - cannot collide.
- if (executableElementPrivate &&
- _currentLibrary != superclassLibrary) {
- continue;
- }
- // instance vs. static
- if (fieldElt.isStatic) {
- _errorReporter.reportErrorForNode(
- StaticWarningCode
- .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
- errorNameTarget,
- [executableElementName, fieldElt.enclosingElement.displayName]);
- return true;
- }
- }
- // Check methods.
- List<MethodElement> methodElements = superclassElement.methods;
- int length = methodElements.length;
- for (int i = 0; i < length; i++) {
- MethodElement methodElement = methodElements[i];
- // We need the same name.
- if (methodElement.name != executableElementName) {
- continue;
- }
- // Ignore if private in a different library - cannot collide.
- if (executableElementPrivate &&
- _currentLibrary != superclassLibrary) {
- continue;
- }
- // instance vs. static
- if (methodElement.isStatic) {
- _errorReporter.reportErrorForNode(
- StaticWarningCode
- .INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC,
- errorNameTarget,
- [
- executableElementName,
- methodElement.enclosingElement.displayName
- ]);
- return true;
- }
- }
- superclassType = superclassElement.supertype;
- superclassElement = superclassType?.element;
- }
- }
- return false;
- }
-
- /**
* Verify that an 'int' can be assigned to the parameter corresponding to the
* given [argument]. This is used for prefix and postfix expressions where
* the argument value is implicit.
@@ -5244,11 +5176,8 @@
StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression);
}
} else if (type is FunctionType) {
- if (type.typeArguments.length == 0 &&
- !_typeSystem.isAssignableTo(type.returnType, _boolType)) {
- _errorReporter.reportErrorForNode(
- StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression);
- }
+ _errorReporter.reportErrorForNode(
+ StaticTypeWarningCode.NON_BOOL_EXPRESSION, expression);
}
}
@@ -5360,6 +5289,20 @@
}
}
+ void _checkForOutOfRange(IntegerLiteral node) {
+ String lexeme = node.literal.lexeme;
+ AstNode parent = node.parent;
+ bool isNegated =
+ parent is PrefixExpression && parent.operator.type == TokenType.MINUS;
+ if (!IntegerLiteralImpl.isValidLiteral(lexeme, isNegated)) {
+ if (isNegated) {
+ lexeme = '-$lexeme';
+ }
+ _errorReporter.reportErrorForNode(
+ CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE, node, [lexeme]);
+ }
+ }
+
/**
* Check that the given named optional [parameter] does not begin with '_'.
*
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index d03c13e..01ac085 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -210,6 +210,12 @@
bool _enableNnbd = false;
/**
+ * A flag indicating whether the parser should parse instance creation
+ * expressions that lack either the `new` or `const` keyword.
+ */
+ bool _enableOptionalNewAndConst = false;
+
+ /**
* A flag indicating whether the parser is to allow URI's in part-of
* directives.
*/
@@ -329,6 +335,20 @@
}
/**
+ * Return `true` if the parser should parse instance creation expressions that
+ * lack either the `new` or `const` keyword.
+ */
+ bool get enableOptionalNewAndConst => _enableOptionalNewAndConst;
+
+ /**
+ * Set whether the parser should parse instance creation expressions that lack
+ * either the `new` or `const` keyword.
+ */
+ void set enableOptionalNewAndConst(bool enable) {
+ _enableOptionalNewAndConst = enable;
+ }
+
+ /**
* Return `true` if the parser is to allow URI's in part-of directives.
*/
bool get enableUriInPartOf => _enableUriInPartOf;
@@ -4464,6 +4484,16 @@
operand = astFactory.functionExpressionInvocation(
operand, typeArguments, argumentList);
}
+ } else if (enableOptionalNewAndConst &&
+ operand is Identifier &&
+ _isLikelyNamedInstanceCreation()) {
+ TypeArgumentList typeArguments = _parseOptionalTypeArguments();
+ Token period = _expect(TokenType.PERIOD);
+ SimpleIdentifier name = parseSimpleIdentifier();
+ ArgumentList argumentList = parseArgumentList();
+ TypeName typeName = astFactory.typeName(operand, typeArguments);
+ operand = astFactory.instanceCreationExpression(null,
+ astFactory.constructorName(typeName, period, name), argumentList);
} else {
operand = parseAssignableSelector(operand, true);
}
@@ -6253,6 +6283,24 @@
}
/**
+ * Return `true` if it looks like we have found the invocation of a named
+ * constructor following the name of the type:
+ * ```
+ * typeArguments? '.' identifier '('
+ * ```
+ */
+ bool _isLikelyNamedInstanceCreation() {
+ Token token = skipTypeArgumentList(_currentToken);
+ if (token != null && _tokenMatches(token, TokenType.PERIOD)) {
+ token = skipSimpleIdentifier(token.next);
+ if (token != null && _tokenMatches(token, TokenType.OPEN_PAREN)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Given that we have just found bracketed text within the given [comment],
* look to see whether that text is (a) followed by a parenthesized link
* address, (b) followed by a colon, or (c) followed by optional whitespace
@@ -7810,6 +7858,7 @@
Parser parser = new Parser(_source, listener);
parser._currentToken = _cloneTokens(startToken);
parser._enableNnbd = _enableNnbd;
+ parser._enableOptionalNewAndConst = _enableOptionalNewAndConst;
parser._inAsync = _inAsync;
parser._inGenerator = _inGenerator;
parser._inInitializer = _inInitializer;
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index 98b88b7..4e03662 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -4,22 +4,6 @@
part of analyzer.parser;
-class _Builder implements Builder {
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class _KernelLibraryBuilder implements KernelLibraryBuilder {
- @override
- final uri;
-
- _KernelLibraryBuilder(this.uri);
-
- @override
- Uri get fileUri => uri;
-
- noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
/**
* Proxy implementation of the analyzer parser, implemented in terms of the
* Fasta parser.
@@ -57,6 +41,17 @@
}
@override
+ bool get enableOptionalNewAndConst => false;
+
+ @override
+ void set enableOptionalNewAndConst(bool enable) {}
+
+ @override
+ void set parseFunctionBodies(bool parseFunctionBodies) {
+ // ignored
+ }
+
+ @override
bool get parseGenericMethodComments => astBuilder.parseGenericMethodComments;
@override
@@ -65,9 +60,7 @@
}
@override
- void set parseFunctionBodies(bool parseFunctionBodies) {
- // ignored
- }
+ Expression parseAdditiveExpression() => parseExpression2();
@override
Annotation parseAnnotation() {
@@ -91,9 +84,6 @@
parseExpression2();
@override
- Expression parseAdditiveExpression() => parseExpression2();
-
- @override
Expression parseBitwiseAndExpression() => parseExpression2();
@override
@@ -337,6 +327,22 @@
Expression parseUnaryExpression() => parseExpression2();
}
+class _Builder implements Builder {
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class _KernelLibraryBuilder implements KernelLibraryBuilder {
+ @override
+ final uri;
+
+ _KernelLibraryBuilder(this.uri);
+
+ @override
+ Uri get fileUri => uri;
+
+ noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
/**
* Replacement parser based on Fasta.
*/
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 29b0f99..21e168c 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1075,6 +1075,7 @@
DartType futureArgument = returnTypeType.typeArguments[0];
if (futureArgument.isDynamic ||
futureArgument.isDartCoreNull ||
+ futureArgument.isVoid ||
futureArgument.isObject) {
return;
}
@@ -5196,8 +5197,7 @@
// Analyzer ignores annotations on "part of" directives.
assert(parent is PartOfDirective);
} else {
- elementAnnotationImpl.annotationAst =
- new ConstantAstCloner().cloneNode(node);
+ elementAnnotationImpl.annotationAst = _createCloner().cloneNode(node);
}
return null;
}
@@ -5550,7 +5550,7 @@
}
ConstructorElementImpl constructor = node.element;
constructor.constantInitializers =
- new ConstantAstCloner().cloneNodeList(node.initializers);
+ _createCloner().cloneNodeList(node.initializers);
return null;
}
@@ -5617,7 +5617,7 @@
// during constant evaluation.
if (!_hasSerializedConstantInitializer(element)) {
(element as ConstVariableElement).constantInitializer =
- new ConstantAstCloner().cloneNode(node.defaultValue);
+ _createCloner().cloneNode(node.defaultValue);
}
return null;
}
@@ -6256,7 +6256,7 @@
// evaluate the const constructor).
if (element is ConstVariableElement) {
(element as ConstVariableElement).constantInitializer =
- new ConstantAstCloner().cloneNode(node.initializer);
+ _createCloner().cloneNode(node.initializer);
}
return null;
}
@@ -6407,6 +6407,15 @@
}
/**
+ * Return a newly created cloner that can be used to clone constant
+ * expressions.
+ */
+ ConstantAstCloner _createCloner() {
+ return new ConstantAstCloner(
+ definingLibrary.context.analysisOptions.previewDart2);
+ }
+
+ /**
* Creates a union of `T | Future<T>`, unless `T` is already a
* future-union, in which case it simply returns `T`.
*/
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 486e00c..543f95c 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -614,9 +614,6 @@
ElementFactory.methodElement(">", _boolType, [_numType]),
ElementFactory.methodElement(">=", _boolType, [_numType]),
ElementFactory.methodElement("==", _boolType, [_objectType]),
- ElementFactory.methodElement("isNaN", _boolType),
- ElementFactory.methodElement("isNegative", _boolType),
- ElementFactory.methodElement("isInfinite", _boolType),
ElementFactory.methodElement("abs", _numType),
ElementFactory.methodElement("floor", _numType),
ElementFactory.methodElement("ceil", _numType),
@@ -631,6 +628,11 @@
.methodElement("toStringAsPrecision", _stringType, [_intType]),
ElementFactory.methodElement("toRadixString", _stringType, [_intType])
];
+ numElement.accessors = [
+ ElementFactory.getterElement('isInfinite', false, _boolType),
+ ElementFactory.getterElement('isNaN', false, _boolType),
+ ElementFactory.getterElement('isNegative', false, _boolType),
+ ];
intElement.methods = <MethodElement>[
ElementFactory.methodElement("&", _intType, [_intType]),
ElementFactory.methodElement("|", _intType, [_intType]),
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index c586717..1b88697 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -475,6 +475,14 @@
}
/**
+ * Return `true` if the store contains the linked summary for the library
+ * with the given absolute [uri].
+ */
+ bool hasLinkedLibrary(String uri) {
+ return linkedMap.containsKey(uri);
+ }
+
+ /**
* Return `true` if the store contains the unlinked summary for the unit
* with the given absolute [uri].
*/
diff --git a/pkg/analyzer/lib/src/summary/summary_file_builder.dart b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
index 7cabe97..3028abf 100644
--- a/pkg/analyzer/lib/src/summary/summary_file_builder.dart
+++ b/pkg/analyzer/lib/src/summary/summary_file_builder.dart
@@ -140,6 +140,7 @@
LineInfo lineInfo = new LineInfo(scanner.lineStarts);
Parser parser = new Parser(source, errorListener,
useFasta: context.analysisOptions.useFastaParser);
+ parser.enableOptionalNewAndConst = context.analysisOptions.previewDart2;
parser.parseGenericMethodComments = strong;
CompilationUnit unit = parser.parseCompilationUnit(token);
unit.lineInfo = lineInfo;
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 98aaf75..c95f382 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -3769,6 +3769,7 @@
parser.parseFunctionBodies =
options.analyzeFunctionBodiesPredicate(_source);
parser.parseGenericMethodComments = options.strongMode;
+ parser.enableOptionalNewAndConst = options.previewDart2;
parser.enableUriInPartOf = options.enableUriInPartOf;
CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
unit.lineInfo = lineInfo;
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index b38c3ad..aed9461 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -48,6 +48,7 @@
'enableInitializingFormalAccess';
static const String enableStrictCallChecks = 'enableStrictCallChecks';
static const String enableSuperMixins = 'enableSuperMixins';
+ static const String enablePreviewDart2 = 'enablePreviewDart2';
static const String errors = 'errors';
static const String exclude = 'exclude';
@@ -88,7 +89,8 @@
enableAsync,
enableGenericMethods,
enableStrictCallChecks,
- enableSuperMixins
+ enableSuperMixins,
+ enablePreviewDart2
];
}
@@ -578,6 +580,8 @@
options.enableStrictCallChecks = boolValue;
} else if (feature == AnalyzerOptions.enableSuperMixins) {
options.enableSuperMixins = boolValue;
+ } else if (feature == AnalyzerOptions.enablePreviewDart2) {
+ options.previewDart2 = boolValue;
}
}
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 19fb41c..7c25bb8 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,21 +1,21 @@
name: analyzer
-version: 0.31.0-alpha.2
+version: 0.31.0+1
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
environment:
- sdk: '>=1.20.0 <2.0.0'
+ sdk: '>=2.0.0-dev <2.0.0'
dependencies:
args: '>=0.12.1 <2.0.0'
charcode: ^1.1.0
collection: ^1.10.1
convert: ^2.0.0
crypto: '>=1.1.1 <3.0.0'
- front_end: 0.1.0-alpha.7
+ front_end: 0.1.0-alpha.8
glob: ^1.0.3
html: '>=0.12.0 <1.14.0'
isolate: '>=0.2.2 <2.0.0'
- kernel: 0.3.0-alpha.4
+ kernel: 0.3.0-alpha.5
meta: ^1.0.2
package_config: '>=0.1.5 <2.0.0'
path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_kernel_test.dart
index 1a4f23f..7ffdcb3 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_kernel_test.dart
@@ -23,6 +23,13 @@
@failingTest
@override
+ test_assertion_throws() async {
+ // Not yet generating errors in kernel mode.
+ await super.test_assertion_throws();
+ }
+
+ @failingTest
+ @override
test_fieldFormalParameterAssignableToField_fieldType_unresolved_null() async {
// Expected 1 errors of type StaticWarningCode.UNDEFINED_CLASS, found 0
await super
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 37920c3..746ca53 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -23,6 +23,19 @@
AnalysisOptions get defaultAnalysisOptions =>
new AnalysisOptionsImpl()..strongMode = true;
+ test_assertion_throws() async {
+ Source source = addSource(r'''
+class A {
+ const A(int x, int y) : assert(x < y);
+}
+var v = const A(3, 2);
+''');
+ await computeAnalysisResult(source);
+ assertErrors(
+ source, [CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION]);
+ verify([source]);
+ }
+
test_fieldFormalParameterAssignableToField_extends() async {
// According to checked-mode type checking rules, a value of type B is
// assignable to a field of type A, because B extends A (and hence is a
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index 42274d3..c78e97e 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -1340,6 +1340,20 @@
@override
@failingTest
+ test_integerLiteralOutOfRange_negative() async {
+ // Expected 1 errors of type CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE, found 0
+ await super.test_integerLiteralOutOfRange_negative();
+ }
+
+ @override
+ @failingTest
+ test_integerLiteralOutOfRange_positive() async {
+ // Expected 1 errors of type CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE, found 0
+ await super.test_integerLiteralOutOfRange_positive();
+ }
+
+ @override
+ @failingTest
test_invalidAnnotation_getter() async {
// Expected 1 errors of type CompileTimeErrorCode.INVALID_ANNOTATION, found 0
await super.test_invalidAnnotation_getter();
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 8551fdc..3079a45 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -1180,11 +1180,21 @@
test_constEvalTypeBool_binary_leftTrue() async {
Source source = addSource("const C = (true || 0);");
await computeAnalysisResult(source);
- assertErrors(source, [
- CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL,
- StaticTypeWarningCode.NON_BOOL_OPERAND,
- HintCode.DEAD_CODE
- ]);
+ assertErrors(
+ source, [StaticTypeWarningCode.NON_BOOL_OPERAND, HintCode.DEAD_CODE]);
+ verify([source]);
+ }
+
+ test_constEvalTypeBool_logicalOr_trueLeftOperand() async {
+ Source source = addSource(r'''
+class C {
+ final int x;
+ const C({this.x}) : assert(x == null || x >= 0);
+}
+const c = const C();
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
verify([source]);
}
@@ -3210,6 +3220,18 @@
verify([source]);
}
+ test_integerLiteralOutOfRange_negative() async {
+ Source source = addSource('int x = -9223372036854775809;');
+ await computeAnalysisResult(source);
+ assertErrors(source, [CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE]);
+ }
+
+ test_integerLiteralOutOfRange_positive() async {
+ Source source = addSource('int x = 9223372036854775808;');
+ await computeAnalysisResult(source);
+ assertErrors(source, [CompileTimeErrorCode.INTEGER_LITERAL_OUT_OF_RANGE]);
+ }
+
test_invalidAnnotation_getter() async {
Source source = addSource(r'''
get V => 0;
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index c267a84..f94b026 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -25,13 +25,6 @@
@reflectiveTest
class ConstantEvaluatorTest extends ResolverTestCase {
- void fail_constructor() {
- EvaluationResult result = _getExpressionValue("?");
- expect(result.isValid, isTrue);
- DartObject value = result.value;
- expect(value, null);
- }
-
void fail_identifier_class() {
EvaluationResult result = _getExpressionValue("?");
expect(result.isValid, isTrue);
@@ -132,6 +125,88 @@
_assertValue3(74 ^ 42, "74 ^ 42");
}
+ void test_constructorInvocation_assert_false() {
+ EvaluationResult result = _getExpressionValue("const C(0)", context: '''
+class C {
+ const C(int x) : assert(x > 0);
+}
+''');
+ expect(result.isValid, isFalse);
+ }
+
+ test_constructorInvocation_assert_inherited() async {
+ EvaluationResult result =
+ _getExpressionValue("const Center(name: 'v')", context: '''
+class Align {
+ final double widthFactor;
+ const Align({String name, this.widthFactor})
+ assert(widthFactor == null || widthFactor >= 0.0);
+}
+class Center extends Align {
+ const Center({String name})
+ : super(name: name);
+}
+''');
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, isNotNull);
+ expect(value.type.name, 'Center');
+ DartObject superclassFields = value.getField(GenericState.SUPERCLASS_FIELD);
+ DartObject widthFactor = superclassFields.getField('widthFactor');
+ expect(widthFactor, isNotNull);
+ expect(widthFactor.isNull, isTrue);
+ }
+
+ void test_constructorInvocation_assert_true() {
+ EvaluationResult result = _getExpressionValue("const C(3)", context: '''
+class C {
+ const C(int x) : assert(x > 0);
+}
+''');
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, isNotNull);
+ expect(value.type.name, 'C');
+ }
+
+ void test_constructorInvocation_fieldInitializer() {
+ EvaluationResult result = _getExpressionValue("const C(2)", context: '''
+class C {
+ final int x;
+ const C(this.x);
+}
+''');
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, isNotNull);
+ expect(value.type.name, 'C');
+ DartObject x = value.getField('x');
+ expect(x, isNotNull);
+ expect(x.type.name, 'int');
+ expect(x.toIntValue(), 2);
+ }
+
+ void test_constructorInvocation_noArgs() {
+ EvaluationResult result =
+ _getExpressionValue("const C()", context: 'class C {}');
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, isNotNull);
+ expect(value.type.name, 'C');
+ }
+
+ void test_constructorInvocation_simpleArgs() {
+ EvaluationResult result = _getExpressionValue("const C(1)", context: '''
+class C {
+ const C(int x);
+}
+''');
+ expect(result.isValid, isTrue);
+ DartObject value = result.value;
+ expect(value, isNotNull);
+ expect(value.type.name, 'C');
+ }
+
void test_divide_double_double() {
_assertValue2(3.2 / 2.3, "3.2 / 2.3");
}
@@ -388,14 +463,13 @@
expect(value.toStringValue(), expectedValue);
}
- EvaluationResult _getExpressionValue(String contents) {
- Source source = addSource("var x = $contents;");
+ EvaluationResult _getExpressionValue(String contents, {String context: ''}) {
+ Source source = addSource("var x = $contents;$context");
LibraryElement library = resolve2(source);
CompilationUnit unit =
analysisContext.resolveCompilationUnit(source, library);
expect(unit, isNotNull);
NodeList<CompilationUnitMember> declarations = unit.declarations;
- expect(declarations, hasLength(1));
CompilationUnitMember declaration = declarations[0];
EngineTestCase.assertInstanceOf((obj) => obj is TopLevelVariableDeclaration,
TopLevelVariableDeclaration, declaration);
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index b9454b3..aaf88b9 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -33,6 +33,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(ElementResolverCodeTest);
defineReflectiveTests(ElementResolverTest);
+ defineReflectiveTests(PreviewDart2Test);
});
}
@@ -1296,3 +1297,249 @@
}
}
}
+
+@reflectiveTest
+class PreviewDart2Test extends ResolverTestCase {
+ @override
+ void setUp() {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl()
+ ..previewDart2 = true;
+ resetWith(options: options);
+ }
+
+ /**
+ * Tests and verifies that even with a explicit 'new' keyword, the
+ * construction of the InstanceCreationExpression node with types and elements
+ * is all correct.
+ */
+ test_visitMethodInvocations_explicit() async {
+ String code = '''
+class A {
+ A() {}
+}
+main() {
+ var v = new A(); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode constructorName = findMarkedIdentifier(code, unit, "(); // marker");
+ InstanceCreationExpression instanceCreationExpression =
+ constructorName.parent.parent.parent;
+ expect(instanceCreationExpression, isNotNull);
+ expect(instanceCreationExpression.constructorName.type.type, isNotNull);
+ expect(instanceCreationExpression.constructorName.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticType, isNotNull);
+ // unnamed constructor:
+ expect(instanceCreationExpression.constructorName.name, isNull);
+ }
+
+ /**
+ * Test that the call to a constructor with an implicit unnamed constructor is
+ * re-written as an InstanceCreationExpression AST node from a
+ * MethodInvocation.
+ *
+ * C()
+ */
+ test_visitMethodInvocations_implicit() async {
+ String code = '''
+class A {
+ A() {}
+}
+main() {
+ var v = A(); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode constructorName = findMarkedIdentifier(code, unit, "(); // marker");
+ InstanceCreationExpression instanceCreationExpression =
+ constructorName.parent.parent.parent;
+ expect(instanceCreationExpression, isNotNull);
+ expect(instanceCreationExpression.constructorName.type.type, isNotNull);
+ expect(instanceCreationExpression.constructorName.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticType, isNotNull);
+ // unnamed constructor:
+ expect(instanceCreationExpression.constructorName.name, isNull);
+ }
+
+ /**
+ * Test that the call to a constructor with an implicit named constructor is
+ * re-written as an InstanceCreationExpression AST node from a
+ * MethodInvocation.
+ *
+ * C.n()
+ */
+ test_visitMethodInvocations_implicit_named() async {
+ String code = '''
+class A {
+ A.named() {}
+}
+main() {
+ var v = A.named(); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode constructorName = findMarkedIdentifier(code, unit, "(); // marker");
+ InstanceCreationExpression instanceCreationExpression =
+ constructorName.parent.parent;
+ expect(instanceCreationExpression, isNotNull);
+ expect(instanceCreationExpression.constructorName.type.type, isNotNull);
+ expect(instanceCreationExpression.constructorName.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticType, isNotNull);
+ // named constructor:
+ expect(instanceCreationExpression.constructorName.name.staticElement,
+ isNotNull);
+ }
+
+ /**
+ * Test that the call to a constructor with a prefixed implicit constructor is
+ * re-written as an InstanceCreationExpression AST node from a
+ * MethodInvocation.
+ *
+ * p.C()
+ */
+ test_visitMethodInvocations_implicit_prefixed() async {
+ addNamedSource("/fileOne.dart", r'''
+class A {
+ A() {}
+}
+''');
+ String code = '''
+import 'fileOne.dart' as one;
+
+main() {
+ var v = one.A(); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode constructorName = findMarkedIdentifier(code, unit, "(); // marker");
+ InstanceCreationExpression instanceCreationExpression =
+ constructorName.parent.parent.parent.parent;
+ expect(instanceCreationExpression, isNotNull);
+ expect(instanceCreationExpression.constructorName.type.type, isNotNull);
+ expect(instanceCreationExpression.constructorName.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticType, isNotNull);
+ // unnamed constructor:
+ expect(instanceCreationExpression.constructorName.name, isNull);
+ }
+
+ /**
+ * Test that the call to a constructor with a prefixed implicit named constructor is
+ * re-written as an InstanceCreationExpression AST node from a
+ * MethodInvocation.
+ *
+ * p.C.n()
+ */
+ test_visitMethodInvocations_implicit_prefixed_named() async {
+ addNamedSource("/fileOne.dart", r'''
+class A {
+ A.named() {}
+}
+''');
+ String code = '''
+import 'fileOne.dart' as one;
+main() {
+ var v = one.A.named(); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode constructorName = findMarkedIdentifier(code, unit, "(); // marker");
+ InstanceCreationExpression instanceCreationExpression =
+ constructorName.parent.parent;
+ expect(instanceCreationExpression, isNotNull);
+ expect(instanceCreationExpression.constructorName.type.type, isNotNull);
+ expect(instanceCreationExpression.constructorName.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticType, isNotNull);
+ // named constructor:
+ expect(instanceCreationExpression.constructorName.name.staticElement,
+ isNotNull);
+ }
+
+ /**
+ * Test that the call to a constructor with a prefixed implicit constructor is
+ * re-written as an InstanceCreationExpression AST node from a
+ * MethodInvocation.
+ *
+ * p.C<>()
+ */
+ test_visitMethodInvocations_implicit_prefixed_typeArgs() async {
+ addNamedSource("/fileOne.dart", r'''
+class A<T> {
+ final T x;
+ A(this.x) {}
+}
+''');
+ String code = '''
+import 'fileOne.dart' as one;
+
+main() {
+ var v = one.A<int>(42); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode constructorName =
+ findMarkedIdentifier(code, unit, "<int>(42); // marker");
+ InstanceCreationExpression instanceCreationExpression =
+ constructorName.parent.parent.parent.parent;
+ expect(instanceCreationExpression, isNotNull);
+ expect(instanceCreationExpression.constructorName.type.type, isNotNull);
+ expect(instanceCreationExpression.constructorName.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticType, isNotNull);
+ // unnamed constructor:
+ expect(instanceCreationExpression.constructorName.name, isNull);
+ }
+
+ /**
+ * Test that the call to a constructor with an implicit unnamed constructor is
+ * re-written as an InstanceCreationExpression AST node from a
+ * MethodInvocation.
+ *
+ * C<>()
+ */
+ test_visitMethodInvocations_implicit_typeArgs() async {
+ String code = '''
+class A<T> {
+ final T x;
+ A(this.x) {}
+}
+main() {
+ var v = A<int>(42); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode constructorName =
+ findMarkedIdentifier(code, unit, "<int>(42); // marker");
+ InstanceCreationExpression instanceCreationExpression =
+ constructorName.parent.parent.parent;
+ expect(instanceCreationExpression, isNotNull);
+ expect(instanceCreationExpression.constructorName.type.type, isNotNull);
+ expect(instanceCreationExpression.constructorName.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticElement, isNotNull);
+ expect(instanceCreationExpression.staticType, isNotNull);
+ // unnamed constructor:
+ expect(instanceCreationExpression.constructorName.name, isNull);
+ }
+
+ /**
+ * Test that the call to a static method will not be re-written as a
+ * InstanceCreationExpression AST node.
+ */
+ test_visitMethodInvocations_not_implicit_constructor() async {
+ String code = '''
+class A {
+ static staticMethod() {}
+}
+main() {
+ A.staticMethod(); // marker
+}
+ ''';
+ CompilationUnit unit = await resolveSource(code);
+ AstNode node = findMarkedIdentifier(code, unit, "(); // marker");
+ assert(node.parent is MethodInvocation);
+ }
+}
diff --git a/pkg/analyzer/test/generated/hint_code_kernel_test.dart b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
index 530eb78..76f0dc1 100644
--- a/pkg/analyzer/test/generated/hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
@@ -490,4 +490,10 @@
test_importDeferredLibraryWithLoadFunction() async {
await super.test_importDeferredLibraryWithLoadFunction();
}
+
+ @failingTest
+ @override
+ test_no_missingReturn_async_futureOrVoid() async {
+ await super.test_no_missingReturn_async_futureOrVoid();
+ }
}
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index dae6056..5e8fcea 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -2253,6 +2253,26 @@
verify([source]);
}
+ test_no_missingReturn_async_futureVoid() async {
+ Source source = addSource('''
+import 'dart:async';
+Future<void> f() async {}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ test_no_missingReturn_async_futureOrVoid() async {
+ Source source = addSource('''
+import 'dart:async';
+FutureOr<void> f(Future f) async {}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_missingReturn_factory() async {
Source source = addSource(r'''
class A {
diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
index 9c424a9..e7bf2d5 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
@@ -142,6 +142,13 @@
@override
@failingTest
+ @potentialAnalyzerProblem
+ test_constDeferredClass_new() async {
+ return super.test_constDeferredClass_new();
+ }
+
+ @override
+ @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/28434')
test_constructorDeclaration_scope_signature() async {
return super.test_constructorDeclaration_scope_signature();
@@ -191,6 +198,13 @@
@override
@failingTest
+ @potentialAnalyzerProblem
+ test_integerLiteralOutOfRange_negative_valid() async {
+ return super.test_integerLiteralOutOfRange_negative_valid();
+ }
+
+ @override
+ @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/31641')
test_invalidAnnotation_constantVariable_field() async {
return super.test_invalidAnnotation_constantVariable_field();
@@ -240,36 +254,12 @@
@override
@failingTest
- @FastaProblem('https://github.com/dart-lang/sdk/issues/30834')
- test_memberWithClassName_setter() async {
- return super.test_memberWithClassName_setter();
- }
-
- @override
- @failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/28434')
test_methodDeclaration_scope_signature() async {
return super.test_methodDeclaration_scope_signature();
}
@override
- test_nativeConstConstructor() async {
- return super.test_nativeConstConstructor();
- }
-
- @override
- test_nativeFunctionBodyInNonSDKCode_function() async {
- return super.test_nativeFunctionBodyInNonSDKCode_function();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_nonBoolExpression_functionType() async {
- return super.test_nonBoolExpression_functionType();
- }
-
- @override
@failingTest
@FastaProblem('https://github.com/dart-lang/sdk/issues/31628')
test_nonConstCaseExpression_constField() async {
@@ -338,19 +328,4 @@
test_undefinedIdentifier_synthetic_whenMethodName() async {
return super.test_undefinedIdentifier_synthetic_whenMethodName();
}
-
- @override
- test_uriDoesNotExist_dll() async {
- return super.test_uriDoesNotExist_dll();
- }
-
- @override
- test_uriDoesNotExist_dylib() async {
- return super.test_uriDoesNotExist_dylib();
- }
-
- @override
- test_uriDoesNotExist_so() async {
- return super.test_uriDoesNotExist_so();
- }
}
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index cfb31c2..cb9fca4 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1169,18 +1169,6 @@
verify([source]);
}
- test_forEach_genericFunctionType() async {
- Source source = addSource(r'''
-main() {
- for (Null Function<T>(T, Null) e in []) {
- e;
- }
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
test_caseBlockNotTerminated() async {
Source source = addSource(r'''
f(int p) {
@@ -2410,6 +2398,18 @@
verify([source]);
}
+ test_forEach_genericFunctionType() async {
+ Source source = addSource(r'''
+main() {
+ for (Null Function<T>(T, Null) e in []) {
+ e;
+ }
+}''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_functionDeclaration_scope_returnType() async {
Source source = addSource("int f(int) { return 0; }");
await computeAnalysisResult(source);
@@ -3105,6 +3105,36 @@
verify([source]);
}
+ test_integerLiteralOutOfRange_negative_leadingZeros() async {
+ Source source = addSource('int x = -000923372036854775809;');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ }
+
+ test_integerLiteralOutOfRange_negative_valid() async {
+ Source source = addSource('int x = -9223372036854775808;');
+ await computeAnalysisResult(source);
+ assertErrors(source);
+ }
+
+ test_integerLiteralOutOfRange_positive_leadingZeros() async {
+ Source source = addSource('int x = 000923372036854775808;');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ }
+
+ test_integerLiteralOutOfRange_positive_valid() async {
+ Source source = addSource('int x = 9223372036854775807;');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ }
+
+ test_integerLiteralOutOfRange_positive_zero() async {
+ Source source = addSource('int x = 0;');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ }
+
test_invalidAnnotation_constantVariable_field() async {
Source source = addSource(r'''
@A.C
@@ -4370,17 +4400,6 @@
verify([source]);
}
- test_nonBoolExpression_functionType() async {
- Source source = addSource(r'''
-bool makeAssertion() => true;
-f() {
- assert(makeAssertion);
-}''');
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
test_nonBoolExpression_interfaceType() async {
Source source = addSource(r'''
f() {
@@ -5413,6 +5432,13 @@
verify([source]);
}
+ test_typeArgument_boundToFunctionType() async {
+ Source source = addSource("class A<T extends void Function<T>(T)>{}");
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_typeArgumentNotMatchingBounds_const() async {
Source source = addSource(r'''
class A {}
@@ -6399,13 +6425,6 @@
verify([source]);
}
- test_typeArgument_boundToFunctionType() async {
- Source source = addSource("class A<T extends void Function<T>(T)>{}");
- await computeAnalysisResult(source);
- assertNoErrors(source);
- verify([source]);
- }
-
Future<Null> _check_wrongNumberOfParametersForOperator(
String name, String parameters) async {
Source source = addSource("""
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index bd0444f..cce7def 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -115,22 +115,6 @@
with ErrorParserTestMixin {
@override
@failingTest
- void test_breakOutsideOfLoop_breakInIfStatement() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, found 0
- super.test_breakOutsideOfLoop_breakInIfStatement();
- }
-
- @override
- @failingTest
- void test_breakOutsideOfLoop_functionExpression_inALoop() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, found 0
- super.test_breakOutsideOfLoop_functionExpression_inALoop();
- }
-
- @override
- @failingTest
void test_constConstructorWithBody() {
// TODO(brianwilkerson) Wrong errors:
// Expected 1 errors of type ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, found 0
@@ -165,30 +149,6 @@
@override
@failingTest
- void test_continueOutsideOfLoop_continueInIfStatement() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, found 0
- super.test_continueOutsideOfLoop_continueInIfStatement();
- }
-
- @override
- @failingTest
- void test_continueOutsideOfLoop_functionExpression_inALoop() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, found 0
- super.test_continueOutsideOfLoop_functionExpression_inALoop();
- }
-
- @override
- @failingTest
- void test_continueWithoutLabelInCase_error() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, found 0
- super.test_continueWithoutLabelInCase_error();
- }
-
- @override
- @failingTest
void test_duplicateLabelInSwitchStatement() {
// TODO(brianwilkerson) Wrong errors:
// Expected 1 errors of type ParserErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT, found 0
@@ -1381,17 +1341,6 @@
@override
@failingTest
- void test_typedef_namedFunction() {
- // TODO(brianwilkerson) Wrong errors:
- // Expected 1 errors of type ParserErrorCode.MISSING_TYPEDEF_PARAMETERS, found 0;
- // 1 errors of type ParserErrorCode.MISSING_IDENTIFIER, found 0;
- // 1 errors of type ParserErrorCode.UNEXPECTED_TOKEN, found 0;
- // 1 errors of type ParserErrorCode.EXPECTED_EXECUTABLE, found 0
- super.test_typedef_namedFunction();
- }
-
- @override
- @failingTest
void test_unexpectedToken_endOfFieldDeclarationStatement() {
// TODO(brianwilkerson) Wrong errors:
// Expected 1 errors of type ParserErrorCode.UNEXPECTED_TOKEN, found 0
@@ -1654,6 +1603,10 @@
}
}
+ set enableOptionalNewAndConst(bool enable) {
+ // ignored
+ }
+
@override
set enableUriInPartOf(bool value) {
if (value == false) {
@@ -1769,19 +1722,10 @@
@override
CompilationUnit parseCompilationUnit(String content,
{List<ErrorCode> codes, List<ExpectedError> errors}) {
- // Scan tokens
- var source = new StringSource(content, 'parser_test_StringSource.dart');
GatheringErrorListener listener =
new GatheringErrorListener(checkRanges: true);
- var scanner = new Scanner.fasta(source, listener);
- scanner.scanGenericMethodComments = enableGenericMethodComments;
- _fastaTokens = scanner.tokenize();
- // Run parser
- analyzer.Parser parser =
- new analyzer.Parser(source, listener, useFasta: true);
- CompilationUnit unit = parser.parseCompilationUnit(_fastaTokens);
- expect(unit, isNotNull);
+ CompilationUnit unit = parseCompilationUnit2(content, listener);
// Assert and return result
if (codes != null) {
@@ -1795,6 +1739,22 @@
return unit;
}
+ CompilationUnit parseCompilationUnit2(
+ String content, GatheringErrorListener listener) {
+ // Scan tokens
+ var source = new StringSource(content, 'parser_test_StringSource.dart');
+ var scanner = new Scanner.fasta(source, listener);
+ scanner.scanGenericMethodComments = enableGenericMethodComments;
+ _fastaTokens = scanner.tokenize();
+
+ // Run parser
+ analyzer.Parser parser =
+ new analyzer.Parser(source, listener, useFasta: true);
+ CompilationUnit unit = parser.parseCompilationUnit(_fastaTokens);
+ expect(unit, isNotNull);
+ return unit;
+ }
+
@override
ConditionalExpression parseConditionalExpression(String code) {
return _parseExpression(code);
@@ -2492,6 +2452,18 @@
with SimpleParserTestMixin {
@override
@failingTest
+ void test_parseInstanceCreation_noKeyword_noPrefix() {
+ super.test_parseInstanceCreation_noKeyword_noPrefix();
+ }
+
+ @override
+ @failingTest
+ void test_parseInstanceCreation_noKeyword_prefix() {
+ super.test_parseInstanceCreation_noKeyword_prefix();
+ }
+
+ @override
+ @failingTest
void test_parseTypeParameterList_single() {
// TODO(brianwilkerson) Does not use all tokens.
super.test_parseTypeParameterList_single();
@@ -2505,30 +2477,6 @@
class StatementParserTest_Fasta extends FastaParserTestCase
with StatementParserTestMixin {
@override
- @failingTest
- void test_parseBreakStatement_noLabel() {
- // TODO(brianwilkerson)
- // Expected 1 errors of type ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, found 0
- super.test_parseBreakStatement_noLabel();
- }
-
- @override
- @failingTest
- void test_parseContinueStatement_label() {
- // TODO(brianwilkerson)
- // Expected 1 errors of type ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, found 0
- super.test_parseContinueStatement_label();
- }
-
- @override
- @failingTest
- void test_parseContinueStatement_noLabel() {
- // TODO(brianwilkerson)
- // Expected 1 errors of type ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, found 0
- super.test_parseContinueStatement_noLabel();
- }
-
- @override
void test_parseFunctionDeclarationStatement_typeParameterComments() {
// Ignored: Fasta does not support the generic comment syntax.
}
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 4a8c1d4b..857d40e 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -55,6 +55,12 @@
void set enableNnbd(bool value);
/**
+ * Set a flag indicating whether the parser should parse instance creation
+ * expressions that lack either the `new` or `const` keyword.
+ */
+ void set enableOptionalNewAndConst(bool value);
+
+ /**
* Set a flag indicating whether the parser is to parse part-of directives
* that specify a URI rather than a library name.
*/
@@ -2463,7 +2469,7 @@
IfStatement statement = parseStatement('if (x) {break;}');
expectNotNullIfNoErrors(statement);
listener.assertErrors(
- [expectedError(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, 8, 6)]);
+ [expectedError(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, 8, 5)]);
}
void test_breakOutsideOfLoop_breakInSwitchStatement() {
@@ -2481,7 +2487,7 @@
void test_breakOutsideOfLoop_functionExpression_inALoop() {
parseStatement("for(; x;) {() {break;};}");
listener.assertErrors(
- [expectedError(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, 15, 6)]);
+ [expectedError(ParserErrorCode.BREAK_OUTSIDE_OF_LOOP, 15, 5)]);
}
void test_breakOutsideOfLoop_functionExpression_withALoop() {
@@ -2616,7 +2622,7 @@
IfStatement statement = parseStatement('if (x) {continue;}');
expectNotNullIfNoErrors(statement);
listener.assertErrors(
- [expectedError(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, 8, 9)]);
+ [expectedError(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, 8, 8)]);
}
void test_continueOutsideOfLoop_continueInSwitchStatement() {
@@ -2635,7 +2641,7 @@
void test_continueOutsideOfLoop_functionExpression_inALoop() {
parseStatement("for(; x;) {() {continue;};}");
listener.assertErrors(
- [expectedError(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, 15, 9)]);
+ [expectedError(ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, 15, 8)]);
}
void test_continueOutsideOfLoop_functionExpression_withALoop() {
@@ -2647,7 +2653,7 @@
parseStatement('switch (x) {case 1: continue;}');
expectNotNullIfNoErrors(statement);
listener.assertErrors(
- [expectedError(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, 20, 9)]);
+ [expectedError(ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE, 20, 8)]);
}
void test_continueWithoutLabelInCase_noError() {
@@ -2687,6 +2693,15 @@
[expectedError(ParserErrorCode.COVARIANT_AND_STATIC, 10, 6)]);
}
+ void test_covariantAndType_local() {
+ // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
+ // this would be a better error message.
+ parseStatement("covariant int x;");
+ listener.assertErrors(usingFastaParser
+ ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 9)]
+ : [expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 9)]);
+ }
+
void test_covariantConstructor() {
createParser('class C { covariant C(); }');
ClassDeclaration member = parseFullCompilationUnitMember();
@@ -2701,15 +2716,6 @@
]);
}
- void test_covariantAndType_local() {
- // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
- // this would be a better error message.
- parseStatement("covariant int x;");
- listener.assertErrors(usingFastaParser
- ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 9)]
- : [expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 9)]);
- }
-
void test_covariantMember_getter_noReturnType() {
createParser('static covariant get x => 0;');
ClassMember member = parser.parseClassMember('C');
@@ -2952,7 +2958,9 @@
CompilationUnit unit = parseCompilationUnit('heart 2 heart',
errors: usingFastaParser
? [
- expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 0, 5),
+ expectedError(
+ ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 0, 5),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 6, 1),
expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 6, 1),
expectedError(
ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 8, 5),
@@ -2971,9 +2979,11 @@
CompilationUnit unit = parseCompilationUnit('void 2 void',
errors: usingFastaParser
? [
- expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 0, 4),
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 5, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 5, 1),
expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 5, 1),
- expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 7, 4),
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 0),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 0),
]
: [
expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 6, 1),
@@ -3145,13 +3155,6 @@
errors: [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 4)]);
}
- void test_exportDirectiveAfterPartDirective() {
- parseCompilationUnit("part 'a.dart'; export 'b.dart';", errors: [
- expectedError(
- ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, 15, 6)
- ]);
- }
-
void test_exportAsType() {
parseCompilationUnit('export<dynamic> foo;',
errors: usingFastaParser
@@ -3172,6 +3175,13 @@
: []);
}
+ void test_exportDirectiveAfterPartDirective() {
+ parseCompilationUnit("part 'a.dart'; export 'b.dart';", errors: [
+ expectedError(
+ ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE, 15, 6)
+ ]);
+ }
+
void test_externalAfterConst() {
createParser('const external C();');
ClassMember member = parser.parseClassMember('C');
@@ -3549,6 +3559,31 @@
]);
}
+ void test_genericFunctionType_asIdentifier() {
+ createParser('final int Function = 0;');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ expectNotNullIfNoErrors(unit);
+ listener.assertErrors([]);
+ }
+
+ void test_genericFunctionType_asIdentifier2() {
+ if (usingFastaParser) {
+ createParser('int Function() {}');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ expectNotNullIfNoErrors(unit);
+ listener.assertErrors([]);
+ }
+ }
+
+ void test_genericFunctionType_asIdentifier3() {
+ if (usingFastaParser) {
+ createParser('int Function() => 0;');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ expectNotNullIfNoErrors(unit);
+ listener.assertErrors([]);
+ }
+ }
+
void test_genericFunctionType_extraLessThan() {
createParser('''
class Wrong<T> {
@@ -3818,6 +3853,16 @@
listener.assertErrors([expectedError(ParserErrorCode.INVALID_SYNC, 0, 4)]);
}
+ void test_invalidTopLevelSetter() {
+ parseCompilationUnit("var set foo; main(){}", errors: [
+ expectedError(ParserErrorCode.VAR_RETURN_TYPE, 0, 3),
+ usingFastaParser
+ ? expectedError(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 8, 3)
+ : expectedError(ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 11, 1),
+ expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 11, 1)
+ ]);
+ }
+
void test_invalidTopLevelVar() {
parseCompilationUnit("var Function(var arg);", errors: [
expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 21, 2),
@@ -3825,18 +3870,6 @@
]);
}
- void test_invalidTopLevelSetter() {
- parseCompilationUnit("var set foo; main(){}",
- errors: usingFastaParser
- ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 4, 3)]
- : [
- expectedError(ParserErrorCode.VAR_RETURN_TYPE, 0, 3),
- expectedError(
- ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 11, 1),
- expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 11, 1)
- ]);
- }
-
void test_invalidTypedef() {
parseCompilationUnit("typedef var Function(var arg);",
errors: usingFastaParser
@@ -4990,19 +5023,19 @@
expect(function.functionExpression.parameters, isNull);
}
+ void test_topLevelFactory_withFunction() {
+ parseCompilationUnit('factory Function() x = null;', errors: [
+ expectedError(ParserErrorCode.FACTORY_TOP_LEVEL_DECLARATION, 0, 7)
+ ]);
+ }
+
void test_topLevelOperator_withFunction() {
- createParser('operator Function() x = null;');
- CompilationUnitMember member = parseFullCompilationUnitMember();
- expectNotNullIfNoErrors(member);
- if (usingFastaParser) {
- listener.assertErrors([
- expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 0, 8),
- expectedError(ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 20, 1)
- ]);
- } else {
- // Should be generating an error here.
- listener.assertErrorsWithCodes([]);
- }
+ parseCompilationUnit('operator Function() x = null;',
+ errors: usingFastaParser
+ ? [expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 0, 8)]
+ : [
+ // Should be generating an error here.
+ ]);
}
void test_topLevelOperator_withoutOperator() {
@@ -5015,44 +5048,18 @@
}
void test_topLevelOperator_withoutType() {
- createParser('operator +(bool x, bool y) => x | y;');
- CompilationUnitMember member = parseFullCompilationUnitMember();
- expectNotNullIfNoErrors(member);
- if (usingFastaParser) {
- listener.assertErrors(usingFastaParser
- ? [expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 0, 8)]
- : [
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, 0, 0),
- expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 0, 8)
- ]);
- } else {
- listener.assertErrorsWithCodes([ParserErrorCode.TOP_LEVEL_OPERATOR]);
- }
+ parseCompilationUnit('operator +(bool x, bool y) => x | y;',
+ errors: [expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 0, 8)]);
}
void test_topLevelOperator_withType() {
- createParser('bool operator +(bool x, bool y) => x | y;');
- CompilationUnitMember member = parseFullCompilationUnitMember();
- expectNotNullIfNoErrors(member);
- listener.assertErrors(
- [expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 5, 8)]);
+ parseCompilationUnit('bool operator +(bool x, bool y) => x | y;',
+ errors: [expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 5, 8)]);
}
void test_topLevelOperator_withVoid() {
- createParser('void operator +(bool x, bool y) => x | y;');
- CompilationUnitMember member = parseFullCompilationUnitMember();
- expectNotNullIfNoErrors(member);
- if (usingFastaParser) {
- listener.assertErrors(usingFastaParser
- ? [expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 5, 8)]
- : [
- expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 0),
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, 0, 0),
- expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 5, 8)
- ]);
- } else {
- listener.assertErrorsWithCodes([ParserErrorCode.TOP_LEVEL_OPERATOR]);
- }
+ parseCompilationUnit('void operator +(bool x, bool y) => x | y;',
+ errors: [expectedError(ParserErrorCode.TOP_LEVEL_OPERATOR, 5, 8)]);
}
void test_topLevelVariable_withMetadata() {
@@ -5083,12 +5090,18 @@
void test_typedef_namedFunction() {
// TODO(brianwilkerson) Improve recovery for this case.
- parseCompilationUnit('typedef void Function();', codes: [
- ParserErrorCode.UNEXPECTED_TOKEN,
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_EXECUTABLE,
- ParserErrorCode.MISSING_TYPEDEF_PARAMETERS
- ]);
+ parseCompilationUnit('typedef void Function();',
+ codes: usingFastaParser
+ ? [
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.MISSING_TYPEDEF_PARAMETERS
+ ]
+ : [
+ ParserErrorCode.UNEXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_EXECUTABLE,
+ ParserErrorCode.MISSING_TYPEDEF_PARAMETERS
+ ]);
}
void test_typedefInClass_withoutReturnType() {
@@ -9307,6 +9320,12 @@
bool enableNnbd = false;
/**
+ * A flag indicating whether the parser should parse instance creation
+ * expressions that lack either the `new` or `const` keyword.
+ */
+ bool enableOptionalNewAndConst = false;
+
+ /**
* A flag indicating whether the parser is to parse part-of directives that
* specify a URI rather than a library name.
*/
@@ -9359,6 +9378,7 @@
parser.parseGenericMethodComments = enableGenericMethodComments;
parser.parseFunctionBodies = parseFunctionBodies;
parser.enableNnbd = enableNnbd;
+ parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
parser.enableUriInPartOf = enableUriInPartOf;
parser.currentToken = tokenStream;
}
@@ -9469,6 +9489,7 @@
listener.setLineInfo(testSource, scanner.lineStarts);
Token token = scanner.tokenize();
Parser parser = new Parser(testSource, listener);
+ parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
CompilationUnit unit = parser.parseCompilationUnit(token);
expect(unit, isNotNull);
if (codes != null) {
@@ -9490,6 +9511,7 @@
Scanner scanner = new Scanner(null, new CharSequenceReader(code), listener);
Token token = scanner.tokenize();
Parser parser = new Parser(null, listener);
+ parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
CompilationUnit unit = parser.parseCompilationUnit(token);
unit.lineInfo = new LineInfo(scanner.lineStarts);
return unit;
@@ -9818,6 +9840,7 @@
Token token = scanner.tokenize();
Parser parser = new Parser(testSource, listener);
parser.parseGenericMethodComments = enableGenericMethodComments;
+ parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
Statement statement = parser.parseStatement(token);
expect(statement, isNotNull);
return statement;
@@ -9843,6 +9866,7 @@
listener.setLineInfo(testSource, scanner.lineStarts);
Token token = scanner.tokenize();
Parser parser = new Parser(testSource, listener);
+ parser.enableOptionalNewAndConst = enableOptionalNewAndConst;
List<Statement> statements = parser.parseStatements(token);
expect(statements, hasLength(expectedCount));
listener.assertErrorsWithCodes(errorCodes);
@@ -11020,7 +11044,9 @@
// TODO(brianwilkerson) We could do better with this.
parseCompilationUnit("do() {}",
codes: usingFastaParser
- ? [ParserErrorCode.UNEXPECTED_TOKEN]
+ // fasta reports ExpectedIdentifier
+ // which gets mapped to MISSING_IDENTIFIER
+ ? [ParserErrorCode.MISSING_IDENTIFIER]
: [
ParserErrorCode.EXPECTED_EXECUTABLE,
ParserErrorCode.UNEXPECTED_TOKEN
@@ -11198,30 +11224,26 @@
VariableDeclaration variable = variables[0];
expect(variableList.type.toString(), expectedTypeName);
expect(variable.name.name, expectedName);
- expect(declaration.semicolon.lexeme, expectedSemicolon);
+ if (expectedSemicolon.isEmpty) {
+ expect(declaration.semicolon.isSynthetic, isTrue);
+ } else {
+ expect(declaration.semicolon.lexeme, expectedSemicolon);
+ }
}
// Fasta considers the `n` an extraneous modifier
// and parses this as a single top level declaration.
// TODO(danrubel): A better recovery
// would be to insert a synthetic comma after the `n`.
- CompilationUnit unit = parseCompilationUnit('String n x = "";',
- codes: usingFastaParser
- ? [ParserErrorCode.UNEXPECTED_TOKEN]
- : [
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
- ]);
+ CompilationUnit unit = parseCompilationUnit('String n x = "";', codes: [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE
+ ]);
expect(unit, isNotNull);
NodeList<CompilationUnitMember> declarations = unit.declarations;
- if (usingFastaParser) {
- expect(declarations, hasLength(1));
- verify(declarations[0], 'n', 'x', ';');
- } else {
- expect(declarations, hasLength(2));
- verify(declarations[0], 'String', 'n', '');
- verify(declarations[1], 'null', 'x', ';');
- }
+ expect(declarations, hasLength(2));
+ verify(declarations[0], 'String', 'n', '');
+ verify(declarations[1], 'null', 'x', ';');
}
void test_multiplicativeExpression_missing_LHS() {
@@ -11308,8 +11330,10 @@
? [
expectedError(ParserErrorCode.EXPECTED_STRING_LITERAL, 7, 4),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 4),
- expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 7, 4),
- expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 1),
+ expectedError(
+ ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 7, 4),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1),
+ expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 11, 1),
expectedError(
ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 12, 2)
]
@@ -13386,17 +13410,47 @@
expect(clause.implementsKeyword, isNotNull);
}
+ void test_parseInstanceCreation_noKeyword_noPrefix() {
+ enableOptionalNewAndConst = true;
+ createParser('f() => C<E>.n();');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ expect(unit, isNotNull);
+ FunctionDeclaration f = unit.declarations[0];
+ ExpressionFunctionBody body = f.functionExpression.body;
+ expect(body.expression, new isInstanceOf<InstanceCreationExpression>());
+ InstanceCreationExpression creation = body.expression;
+ expect(creation.keyword, isNull);
+ ConstructorName constructorName = creation.constructorName;
+ expect(constructorName.type.toSource(), 'C<E>');
+ expect(constructorName.period, isNotNull);
+ expect(constructorName.name, isNotNull);
+ expect(creation.argumentList, isNotNull);
+ }
+
+ void test_parseInstanceCreation_noKeyword_prefix() {
+ enableOptionalNewAndConst = true;
+ createParser('f() => p.C<E>.n();');
+ CompilationUnit unit = parser.parseCompilationUnit2();
+ expect(unit, isNotNull);
+ FunctionDeclaration f = unit.declarations[0];
+ ExpressionFunctionBody body = f.functionExpression.body;
+ expect(body.expression, new isInstanceOf<InstanceCreationExpression>());
+ InstanceCreationExpression creation = body.expression;
+ expect(creation.keyword, isNull);
+ ConstructorName constructorName = creation.constructorName;
+ expect(constructorName.type.toSource(), 'p.C<E>');
+ expect(constructorName.period, isNotNull);
+ expect(constructorName.name, isNotNull);
+ expect(creation.argumentList, isNotNull);
+ }
+
void test_parseLibraryIdentifier_invalid() {
parseCompilationUnit('library <myLibId>;',
errors: usingFastaParser
? [
expectedError(
- ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 0, 7),
- expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 1),
- expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 8, 1),
- expectedError(
- ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE, 9, 7),
- expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 16, 1),
+ ParserErrorCode.MISSING_FUNCTION_PARAMETERS, 0, 7),
+ expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 17, 1),
]
: [expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 8, 1)]);
}
@@ -14055,6 +14109,22 @@
expect(forStatement.body, isNotNull);
}
+ void test_parseForStatement_each_genericFunctionType() {
+ var forStatement =
+ parseStatement('for (void Function<T>(T) element in list) {}')
+ as ForEachStatement;
+ assertNoErrors();
+ expect(forStatement.awaitKeyword, isNull);
+ expect(forStatement.forKeyword, isNotNull);
+ expect(forStatement.leftParenthesis, isNotNull);
+ expect(forStatement.loopVariable, isNotNull);
+ expect(forStatement.identifier, isNull);
+ expect(forStatement.inKeyword, isNotNull);
+ expect(forStatement.iterable, isNotNull);
+ expect(forStatement.rightParenthesis, isNotNull);
+ expect(forStatement.body, isNotNull);
+ }
+
void test_parseForStatement_each_identifier() {
var forStatement =
parseStatement('for (element in list) {}') as ForEachStatement;
@@ -14116,22 +14186,6 @@
expect(forStatement.body, isNotNull);
}
- void test_parseForStatement_each_genericFunctionType() {
- var forStatement =
- parseStatement('for (void Function<T>(T) element in list) {}')
- as ForEachStatement;
- assertNoErrors();
- expect(forStatement.awaitKeyword, isNull);
- expect(forStatement.forKeyword, isNotNull);
- expect(forStatement.leftParenthesis, isNotNull);
- expect(forStatement.loopVariable, isNotNull);
- expect(forStatement.identifier, isNull);
- expect(forStatement.inKeyword, isNotNull);
- expect(forStatement.iterable, isNotNull);
- expect(forStatement.rightParenthesis, isNotNull);
- expect(forStatement.body, isNotNull);
- }
-
void test_parseForStatement_loop_c() {
var forStatement = parseStatement('for (; i < count;) {}') as ForStatement;
assertNoErrors();
@@ -15455,7 +15509,6 @@
}
void test_parseCompilationUnit_builtIn_asFunctionName_withTypeParameter() {
- // Fasta correctly parses these, while analyzer does not.
if (usingFastaParser) {
for (Keyword keyword in Keyword.values) {
if (keyword.isBuiltIn) {
@@ -15466,6 +15519,15 @@
}
}
+ void test_parseCompilationUnit_builtIn_asGetter() {
+ for (Keyword keyword in Keyword.values) {
+ if (keyword.isBuiltIn) {
+ String lexeme = keyword.lexeme;
+ parseCompilationUnit('get $lexeme => 0;');
+ }
+ }
+ }
+
void test_parseCompilationUnit_directives_multiple() {
createParser("library l;\npart 'a.dart';");
CompilationUnit unit = parser.parseCompilationUnit2();
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
index d48655d..689dda8 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
@@ -366,9 +366,16 @@
@override
@failingTest
- test_nonBoolExpression_functionType() async {
+ test_nonBoolExpression_functionType_bool() async {
// Expected 1 errors of type StaticTypeWarningCode.NON_BOOL_EXPRESSION, found 0
- await super.test_nonBoolExpression_functionType();
+ await super.test_nonBoolExpression_functionType_bool();
+ }
+
+ @override
+ @failingTest
+ test_nonBoolExpression_functionType_int() async {
+ // Expected 1 errors of type StaticTypeWarningCode.NON_BOOL_EXPRESSION, found 0
+ await super.test_nonBoolExpression_functionType_int();
}
@override
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 2e1a353..b7c8fd2 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -854,7 +854,18 @@
}''', [StaticTypeWarningCode.NON_BOOL_CONDITION]);
}
- test_nonBoolExpression_functionType() async {
+ test_nonBoolExpression_functionType_bool() async {
+ Source source = addSource(r'''
+bool makeAssertion() => true;
+f() {
+ assert(makeAssertion);
+}''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [StaticTypeWarningCode.NON_BOOL_EXPRESSION]);
+ verify([source]);
+ }
+
+ test_nonBoolExpression_functionType_int() async {
await assertErrorsInCode(r'''
int makeAssertion() => 1;
f() {
diff --git a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
index 8aeb8ba..e28d5ae 100644
--- a/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_kernel_test.dart
@@ -835,70 +835,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_field() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_field();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_field2() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_field2();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_getter() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_getter();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_getter2() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_getter2();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_interface() async {
- return super
- .test_instanceMethodNameCollidesWithSuperclassStatic_interface();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_method() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_method();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_method2() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_method2();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_setter() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_setter();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_instanceMethodNameCollidesWithSuperclassStatic_setter2() async {
- return super.test_instanceMethodNameCollidesWithSuperclassStatic_setter2();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_invalidGetterOverrideReturnType() async {
return super.test_invalidGetterOverrideReturnType();
}
@@ -1660,27 +1596,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_asExpression() async {
- return super.test_typeAnnotationDeferredClass_asExpression();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_catchClause() async {
- return super.test_typeAnnotationDeferredClass_catchClause();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_fieldFormalParameter() async {
- return super.test_typeAnnotationDeferredClass_fieldFormalParameter();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_typeAnnotationDeferredClass_functionDeclaration_returnType() async {
return super
.test_typeAnnotationDeferredClass_functionDeclaration_returnType();
@@ -1689,21 +1604,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_functionTypedFormalParameter_returnType() async {
- return super
- .test_typeAnnotationDeferredClass_functionTypedFormalParameter_returnType();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_isExpression() async {
- return super.test_typeAnnotationDeferredClass_isExpression();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_typeAnnotationDeferredClass_methodDeclaration_returnType() async {
return super
.test_typeAnnotationDeferredClass_methodDeclaration_returnType();
@@ -1712,27 +1612,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_simpleFormalParameter() async {
- return super.test_typeAnnotationDeferredClass_simpleFormalParameter();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_typeArgumentList() async {
- return super.test_typeAnnotationDeferredClass_typeArgumentList();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_typeArgumentList2() async {
- return super.test_typeAnnotationDeferredClass_typeArgumentList2();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_typeAnnotationDeferredClass_typeParameter_bound() async {
return super.test_typeAnnotationDeferredClass_typeParameter_bound();
}
@@ -1740,13 +1619,6 @@
@override
@failingTest
@potentialAnalyzerProblem
- test_typeAnnotationDeferredClass_variableDeclarationList() async {
- return super.test_typeAnnotationDeferredClass_variableDeclarationList();
- }
-
- @override
- @failingTest
- @potentialAnalyzerProblem
test_typeParameterReferencedByStatic_field() async {
return super.test_typeParameterReferencedByStatic_field();
}
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index ec5d8eb..3319dcb 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -1559,153 +1559,6 @@
verify([source]);
}
- test_instanceMethodNameCollidesWithSuperclassStatic_field() async {
- Source source = addSource(r'''
-class A {
- static var n;
-}
-class B extends A {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_field2() async {
- Source source = addSource(r'''
-class A {
- static var n;
-}
-class B extends A {
-}
-class C extends B {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_getter() async {
- Source source = addSource(r'''
-class A {
- static get n {return 0;}
-}
-class B extends A {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_getter2() async {
- Source source = addSource(r'''
-class A {
- static get n {return 0;}
-}
-class B extends A {
-}
-class C extends B {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_interface() async {
- Source source = addSource(r'''
-class Base {
- static foo() {}
-}
-abstract class Ifc {
- foo();
-}
-class C extends Base implements Ifc {
- foo() {}
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_method() async {
- Source source = addSource(r'''
-class A {
- static n () {}
-}
-class B extends A {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_method2() async {
- Source source = addSource(r'''
-class A {
- static n () {}
-}
-class B extends A {
-}
-class C extends B {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_setter() async {
- Source source = addSource(r'''
-class A {
- static set n(int x) {}
-}
-class B extends A {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
- test_instanceMethodNameCollidesWithSuperclassStatic_setter2() async {
- Source source = addSource(r'''
-class A {
- static set n(int x) {}
-}
-class B extends A {
-}
-class C extends B {
- void n() {}
-}''');
- await computeAnalysisResult(source);
- assertErrors(source, [
- StaticWarningCode.INSTANCE_METHOD_NAME_COLLIDES_WITH_SUPERCLASS_STATIC
- ]);
- verify([source]);
- }
-
test_invalidGetterOverrideReturnType() async {
Source source = addSource(r'''
class A {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index e7de210..b43805a 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -390,7 +390,7 @@
}
void test_visitDefaultFormalParameter_named_value() {
- _assertCloneUnitMember('main({p : 0}) {}');
+ _assertCloneUnitMember('main({p: 0}) {}');
}
void test_visitDefaultFormalParameter_positional_noValue() {
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
index deeac1d..4e92154 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
@@ -129,6 +129,11 @@
// Skipped by design.
}
+ @override
+ test_externalSummaries_partReuse() {
+ // Skipped by design.
+ }
+
@failingTest
@potentialAnalyzerProblem
@override
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 15773b5..3af39cd 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -6806,6 +6806,53 @@
expect(result.errors, isEmpty);
}
+ test_externalSummaries_partReuse() async {
+ var a = _p('/a.dart');
+ var b = _p('/b.dart');
+ var c = _p('/c.dart');
+ provider.newFile(a, r'''
+library a;
+part 'b.dart';
+class A {}
+''');
+ provider.newFile(b, r'''
+part of a;
+class _B {}
+''');
+ provider.newFile(c, r'''
+library a;
+import 'a.dart';
+part 'b.dart';
+var a = new A();
+var b = new _B();
+''');
+
+ // Prepare the store with a.dart and everything it needs.
+ SummaryDataStore summaryStore =
+ await createAnalysisDriver().test.getSummaryStore(a);
+
+ String aUri = provider.pathContext.toUri(a).toString();
+ String bUri = provider.pathContext.toUri(b).toString();
+ // There are unlinked units for a.dart and b.dart files.
+ expect(summaryStore.hasUnlinkedUnit(aUri), isTrue);
+ expect(summaryStore.hasUnlinkedUnit(bUri), isTrue);
+ // Only a.dart is linked, because b.dart is not a library.
+ expect(summaryStore.hasLinkedLibrary(aUri), isTrue);
+ expect(summaryStore.hasLinkedLibrary(bUri), isFalse);
+
+ // Remove a.dart from the file system.
+ // Keep b.dart, because we (re)use it as a part.
+ provider.deleteFile(a);
+
+ // We don't need a.dart file when we analyze with the summary store.
+ // We can instantiate the class A the library a.dart.
+ // We can instantiate the class _A the part b.dart.
+ AnalysisDriver driver =
+ createAnalysisDriver(externalSummaries: summaryStore);
+ AnalysisResult result = await driver.getResult(c);
+ expect(result.errors, isEmpty);
+ }
+
test_generatedFile() async {
Uri uri = Uri.parse('package:aaa/foo.dart');
String templatePath = _p('/aaa/lib/foo.dart');
diff --git a/pkg/analyzer/test/src/dart/analysis/index_test.dart b/pkg/analyzer/test/src/dart/analysis/index_test.dart
index a8b1309..33f75d7 100644
--- a/pkg/analyzer/test/src/dart/analysis/index_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/index_test.dart
@@ -414,6 +414,18 @@
assertThat(element).isReferencedAt('A();', true);
}
+ test_isReferencedBy_ClassElement_invocationTypeArgument() async {
+ await _indexTestUnit('''
+class A {}
+void f<T>() {}
+main() {
+ f<A>();
+}
+''');
+ Element element = findElement('A');
+ assertThat(element)..isReferencedAt('A>();', false);
+ }
+
test_isReferencedBy_ClassTypeAlias() async {
await _indexTestUnit('''
class A {}
diff --git a/pkg/analyzer/test/src/dart/ast/ast_test.dart b/pkg/analyzer/test/src/dart/ast/ast_test.dart
index d2b842a..92d0663 100644
--- a/pkg/analyzer/test/src/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/ast_test.dart
@@ -3,185 +3,577 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../../generated/parser_test.dart';
+
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(ExpressionImplTest);
defineReflectiveTests(IntegerLiteralImplTest);
});
}
@reflectiveTest
+class ExpressionImplTest extends ParserTestCase {
+ String testSource;
+ CompilationUnitImpl testUnit;
+
+ void assertInContext(String snippet, bool isInContext) {
+ int index = testSource.indexOf(snippet);
+ expect(index >= 0, isTrue);
+ NodeLocator visitor = new NodeLocator(index);
+ AstNodeImpl node = visitor.searchWithin(testUnit);
+ expect(node, new isInstanceOf<ExpressionImpl>());
+ expect((node as ExpressionImpl).inConstantContext,
+ isInContext ? isTrue : isFalse);
+ }
+
+ void parse(String source) {
+ testSource = source;
+ testUnit = parseCompilationUnit(source);
+ }
+
+ test_inConstantContext_instanceCreation_annotation_true() {
+ parse('''
+@C(C(0))
+class C {
+ const C(_);
+}
+''');
+ assertInContext("C(0", true);
+ }
+
+ test_inConstantContext_instanceCreation_initializer_false() {
+ parse('''
+var c = C();
+class C {
+ const C();
+}
+''');
+ assertInContext("C()", false);
+ }
+
+ test_inConstantContext_instanceCreation_initializer_true() {
+ parse('''
+const c = C();
+class C {
+ const C();
+}
+''');
+ assertInContext("C()", true);
+ }
+
+ test_inConstantContext_instanceCreation_instanceCreation_false() {
+ parse('''
+f() {
+ return new C(C());
+}
+class C {
+ const C(_);
+}
+''');
+ assertInContext("C())", false);
+ }
+
+ test_inConstantContext_instanceCreation_instanceCreation_true() {
+ parse('''
+f() {
+ return new C(C());
+}
+class C {
+ const C(_);
+}
+''');
+ assertInContext("C())", false);
+ }
+
+ test_inConstantContext_instanceCreation_listLiteral_false() {
+ parse('''
+f() {
+ return [C()];
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C()]", false);
+ }
+
+ test_inConstantContext_instanceCreation_listLiteral_true() {
+ parse('''
+f() {
+ return const [C()];
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C()]", true);
+ }
+
+ test_inConstantContext_instanceCreation_mapLiteral_false() {
+ parse('''
+f() {
+ return {'a' : C()};
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C()}", false);
+ }
+
+ test_inConstantContext_instanceCreation_mapLiteral_true() {
+ parse('''
+f() {
+ return const {'a' : C()};
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C()}", true);
+ }
+
+ test_inConstantContext_instanceCreation_nestedListLiteral_false() {
+ parse('''
+f() {
+ return [[''], [C()]];
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C()]", false);
+ }
+
+ test_inConstantContext_instanceCreation_nestedListLiteral_true() {
+ parse('''
+f() {
+ return const [[''], [C()]];
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C()]", true);
+ }
+
+ test_inConstantContext_instanceCreation_nestedMapLiteral_false() {
+ parse('''
+f() {
+ return {'a' : {C() : C()}};
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C() :", false);
+ assertInContext("C()}", false);
+ }
+
+ test_inConstantContext_instanceCreation_nestedMapLiteral_true() {
+ parse('''
+f() {
+ return const {'a' : {C() : C()}};
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C() :", true);
+ assertInContext("C()}", true);
+ }
+
+ test_inConstantContext_instanceCreation_switch_true() {
+ parse('''
+f(v) {
+ switch (v) {
+ case C():
+ break;
+ }
+}
+class C {
+ const C();
+}
+''');
+ assertInContext("C()", true);
+ }
+
+ test_inConstantContext_listLiteral_annotation_true() {
+ parse('''
+@C([])
+class C {
+ const C(_);
+}
+''');
+ assertInContext("[]", true);
+ }
+
+ test_inConstantContext_listLiteral_initializer_false() {
+ parse('''
+var c = [];
+''');
+ assertInContext("[]", false);
+ }
+
+ test_inConstantContext_listLiteral_initializer_true() {
+ parse('''
+const c = [];
+''');
+ assertInContext("[]", true);
+ }
+
+ test_inConstantContext_listLiteral_instanceCreation_false() {
+ parse('''
+f() {
+ return new C([]);
+}
+class C {
+ const C(_);
+}
+''');
+ assertInContext("[]", false);
+ }
+
+ test_inConstantContext_listLiteral_instanceCreation_true() {
+ parse('''
+f() {
+ return const C([]);
+}
+class C {
+ const C(_);
+}
+''');
+ assertInContext("[]", true);
+ }
+
+ test_inConstantContext_listLiteral_listLiteral_false() {
+ parse('''
+f() {
+ return [[''], []];
+}
+''');
+ assertInContext("['']", false);
+ assertInContext("[]", false);
+ }
+
+ test_inConstantContext_listLiteral_listLiteral_true() {
+ parse('''
+f() {
+ return const [[''], []];
+}
+''');
+ assertInContext("['']", true);
+ assertInContext("[]", true);
+ }
+
+ test_inConstantContext_listLiteral_mapLiteral_false() {
+ parse('''
+f() {
+ return {'a' : [''], 'b' : []};
+}
+''');
+ assertInContext("['']", false);
+ assertInContext("[]", false);
+ }
+
+ test_inConstantContext_listLiteral_mapLiteral_true() {
+ parse('''
+f() {
+ return const {'a' : [''], 'b' : []};
+}
+''');
+ assertInContext("['']", true);
+ assertInContext("[]", true);
+ }
+
+ test_inConstantContext_listLiteral_switch_true() {
+ parse('''
+f(v) {
+ switch (v) {
+ case []:
+ break;
+ }
+}
+''');
+ assertInContext("[]", true);
+ }
+
+ test_inConstantContext_mapLiteral_annotation_true() {
+ parse('''
+@C({})
+class C {
+ const C(_);
+}
+''');
+ assertInContext("{}", true);
+ }
+
+ test_inConstantContext_mapLiteral_initializer_false() {
+ parse('''
+var c = {};
+''');
+ assertInContext("{}", false);
+ }
+
+ test_inConstantContext_mapLiteral_initializer_true() {
+ parse('''
+const c = {};
+''');
+ assertInContext("{}", true);
+ }
+
+ test_inConstantContext_mapLiteral_instanceCreation_false() {
+ parse('''
+f() {
+ return new C({});
+}
+class C {
+ const C(_);
+}
+''');
+ assertInContext("{}", false);
+ }
+
+ test_inConstantContext_mapLiteral_instanceCreation_true() {
+ parse('''
+f() {
+ return const C({});
+}
+class C {
+ const C(_);
+}
+''');
+ assertInContext("{}", true);
+ }
+
+ test_inConstantContext_mapLiteral_listLiteral_false() {
+ parse('''
+f() {
+ return [{'a' : 1}, {'b' : 2}];
+}
+''');
+ assertInContext("{'a", false);
+ assertInContext("{'b", false);
+ }
+
+ test_inConstantContext_mapLiteral_listLiteral_true() {
+ parse('''
+f() {
+ return const [{'a' : 1}, {'b' : 2}];
+}
+''');
+ assertInContext("{'a", true);
+ assertInContext("{'b", true);
+ }
+
+ test_inConstantContext_mapLiteral_mapLiteral_false() {
+ parse('''
+f() {
+ return {'a' : {'b' : 0}, 'c' : {'d' : 1}};
+}
+''');
+ assertInContext("{'b", false);
+ assertInContext("{'d", false);
+ }
+
+ test_inConstantContext_mapLiteral_mapLiteral_true() {
+ parse('''
+f() {
+ return const {'a' : {'b' : 0}, 'c' : {'d' : 1}};
+}
+''');
+ assertInContext("{'b", true);
+ assertInContext("{'d", true);
+ }
+
+ test_inConstantContext_mapLiteral_switch_true() {
+ parse('''
+f(v) {
+ switch (v) {
+ case {}:
+ break;
+ }
+}
+''');
+ assertInContext("{}", true);
+ }
+}
+
+@reflectiveTest
class IntegerLiteralImplTest {
- test_isValidLiteral_dec_negative_equalMax() async {
+ test_isValidLiteral_dec_negative_equalMax() {
expect(
IntegerLiteralImpl.isValidLiteral('9223372036854775808', true), true);
}
- test_isValidLiteral_dec_negative_fewDigits() async {
+ test_isValidLiteral_dec_negative_fewDigits() {
expect(IntegerLiteralImpl.isValidLiteral('24', true), true);
}
- test_isValidLiteral_dec_negative_leadingZeros_overMax() async {
+ test_isValidLiteral_dec_negative_leadingZeros_overMax() {
expect(IntegerLiteralImpl.isValidLiteral('009923372036854775807', true),
false);
}
- test_isValidLiteral_dec_negative_leadingZeros_underMax() async {
+ test_isValidLiteral_dec_negative_leadingZeros_underMax() {
expect(
IntegerLiteralImpl.isValidLiteral('004223372036854775807', true), true);
}
- test_isValidLiteral_dec_negative_oneOverMax() async {
+ test_isValidLiteral_dec_negative_oneOverMax() {
expect(
IntegerLiteralImpl.isValidLiteral('9223372036854775809', true), false);
}
- test_isValidLiteral_dec_negative_tooManyDigits() async {
+ test_isValidLiteral_dec_negative_tooManyDigits() {
expect(
IntegerLiteralImpl.isValidLiteral('10223372036854775808', true), false);
}
- test_isValidLiteral_dec_positive_equalMax() async {
+ test_isValidLiteral_dec_positive_equalMax() {
expect(
IntegerLiteralImpl.isValidLiteral('9223372036854775807', false), true);
}
- test_isValidLiteral_dec_positive_fewDigits() async {
+ test_isValidLiteral_dec_positive_fewDigits() {
expect(IntegerLiteralImpl.isValidLiteral('42', false), true);
}
- test_isValidLiteral_dec_positive_leadingZeros_overMax() async {
+ test_isValidLiteral_dec_positive_leadingZeros_overMax() {
expect(IntegerLiteralImpl.isValidLiteral('009923372036854775807', false),
false);
}
- test_isValidLiteral_dec_positive_leadingZeros_underMax() async {
+ test_isValidLiteral_dec_positive_leadingZeros_underMax() {
expect(IntegerLiteralImpl.isValidLiteral('004223372036854775807', false),
true);
}
- test_isValidLiteral_dec_positive_oneOverMax() async {
+ test_isValidLiteral_dec_positive_oneOverMax() {
expect(
IntegerLiteralImpl.isValidLiteral('9223372036854775808', false), false);
}
- test_isValidLiteral_dec_positive_tooManyDigits() async {
+ test_isValidLiteral_dec_positive_tooManyDigits() {
expect(IntegerLiteralImpl.isValidLiteral('10223372036854775808', false),
false);
}
- test_isValidLiteral_hex_negative_equalMax() async {
+ test_isValidLiteral_hex_negative_equalMax() {
expect(IntegerLiteralImpl.isValidLiteral('0x7FFFFFFFFFFFFFFF', true), true);
}
- test_isValidLiteral_heX_negative_equalMax() async {
+ test_isValidLiteral_heX_negative_equalMax() {
expect(IntegerLiteralImpl.isValidLiteral('0X7FFFFFFFFFFFFFFF', true), true);
}
- test_isValidLiteral_hex_negative_fewDigits() async {
+ test_isValidLiteral_hex_negative_fewDigits() {
expect(IntegerLiteralImpl.isValidLiteral('0xFF', true), true);
}
- test_isValidLiteral_heX_negative_fewDigits() async {
+ test_isValidLiteral_heX_negative_fewDigits() {
expect(IntegerLiteralImpl.isValidLiteral('0XFF', true), true);
}
- test_isValidLiteral_hex_negative_leadingZeros_overMax() async {
+ test_isValidLiteral_hex_negative_leadingZeros_overMax() {
expect(IntegerLiteralImpl.isValidLiteral('0x00FFFFFFFFFFFFFFFFF', true),
false);
}
- test_isValidLiteral_heX_negative_leadingZeros_overMax() async {
+ test_isValidLiteral_heX_negative_leadingZeros_overMax() {
expect(IntegerLiteralImpl.isValidLiteral('0X00FFFFFFFFFFFFFFFFF', true),
false);
}
- test_isValidLiteral_hex_negative_leadingZeros_underMax() async {
+ test_isValidLiteral_hex_negative_leadingZeros_underMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0x007FFFFFFFFFFFFFFF', true), true);
}
- test_isValidLiteral_heX_negative_leadingZeros_underMax() async {
+ test_isValidLiteral_heX_negative_leadingZeros_underMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0X007FFFFFFFFFFFFFFF', true), true);
}
- test_isValidLiteral_hex_negative_oneOverMax() async {
+ test_isValidLiteral_hex_negative_oneOverMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0x8000000000000000', true), false);
}
- test_isValidLiteral_heX_negative_oneOverMax() async {
+ test_isValidLiteral_heX_negative_oneOverMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0X8000000000000000', true), false);
}
- test_isValidLiteral_hex_negative_tooManyDigits() async {
+ test_isValidLiteral_hex_negative_tooManyDigits() {
expect(
IntegerLiteralImpl.isValidLiteral('0x10000000000000000', true), false);
}
- test_isValidLiteral_heX_negative_tooManyDigits() async {
+ test_isValidLiteral_heX_negative_tooManyDigits() {
expect(
IntegerLiteralImpl.isValidLiteral('0X10000000000000000', true), false);
}
- test_isValidLiteral_hex_positive_equalMax() async {
+ test_isValidLiteral_hex_positive_equalMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0x7FFFFFFFFFFFFFFF', false), true);
}
- test_isValidLiteral_heX_positive_equalMax() async {
+ test_isValidLiteral_heX_positive_equalMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0X7FFFFFFFFFFFFFFF', false), true);
}
- test_isValidLiteral_hex_positive_fewDigits() async {
+ test_isValidLiteral_hex_positive_fewDigits() {
expect(IntegerLiteralImpl.isValidLiteral('0xFF', false), true);
}
- test_isValidLiteral_heX_positive_fewDigits() async {
+ test_isValidLiteral_heX_positive_fewDigits() {
expect(IntegerLiteralImpl.isValidLiteral('0XFF', false), true);
}
- test_isValidLiteral_hex_positive_leadingZeros_overMax() async {
+ test_isValidLiteral_hex_positive_leadingZeros_overMax() {
expect(IntegerLiteralImpl.isValidLiteral('0x00FFFFFFFFFFFFFFFFF', false),
false);
}
- test_isValidLiteral_heX_positive_leadingZeros_overMax() async {
+ test_isValidLiteral_heX_positive_leadingZeros_overMax() {
expect(IntegerLiteralImpl.isValidLiteral('0X00FFFFFFFFFFFFFFFFF', false),
false);
}
- test_isValidLiteral_hex_positive_leadingZeros_underMax() async {
+ test_isValidLiteral_hex_positive_leadingZeros_underMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0x007FFFFFFFFFFFFFFF', false), true);
}
- test_isValidLiteral_heX_positive_leadingZeros_underMax() async {
+ test_isValidLiteral_heX_positive_leadingZeros_underMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0X007FFFFFFFFFFFFFFF', false), true);
}
- test_isValidLiteral_hex_positive_oneOverMax() async {
+ test_isValidLiteral_hex_positive_oneOverMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0x10000000000000000', false), false);
}
- test_isValidLiteral_heX_positive_oneOverMax() async {
+ test_isValidLiteral_heX_positive_oneOverMax() {
expect(
IntegerLiteralImpl.isValidLiteral('0X10000000000000000', false), false);
}
- test_isValidLiteral_hex_positive_tooManyDigits() async {
+ test_isValidLiteral_hex_positive_tooManyDigits() {
expect(IntegerLiteralImpl.isValidLiteral('0xFF0000000000000000', false),
false);
}
- test_isValidLiteral_heX_positive_tooManyDigits() async {
+ test_isValidLiteral_heX_positive_tooManyDigits() {
expect(IntegerLiteralImpl.isValidLiteral('0XFF0000000000000000', false),
false);
}
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index 83a8b97..72483ab 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -1828,7 +1828,7 @@
void test_visitDefaultFormalParameter_named_value() {
_assertSource(
- "p : 0",
+ "p: 0",
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter3("p"),
AstTestFactory.integer(0)));
@@ -2050,7 +2050,7 @@
void test_visitFormalParameterList_n() {
_assertSource(
- "({a : 0})",
+ "({a: 0})",
AstTestFactory.formalParameterList([
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter3("a"),
@@ -2060,7 +2060,7 @@
void test_visitFormalParameterList_nn() {
_assertSource(
- "({a : 0, b : 1})",
+ "({a: 0, b: 1})",
AstTestFactory.formalParameterList([
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter3("a"),
@@ -2103,7 +2103,7 @@
void test_visitFormalParameterList_rn() {
_assertSource(
- "(a, {b : 1})",
+ "(a, {b: 1})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.namedFormalParameter(
@@ -2114,7 +2114,7 @@
void test_visitFormalParameterList_rnn() {
_assertSource(
- "(a, {b : 1, c : 2})",
+ "(a, {b: 1, c: 2})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.namedFormalParameter(
@@ -2162,7 +2162,7 @@
void test_visitFormalParameterList_rrn() {
_assertSource(
- "(a, b, {c : 3})",
+ "(a, b, {c: 3})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.simpleFormalParameter3("b"),
@@ -2174,7 +2174,7 @@
void test_visitFormalParameterList_rrnn() {
_assertSource(
- "(a, b, {c : 3, d : 4})",
+ "(a, b, {c: 3, d: 4})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.simpleFormalParameter3("b"),
@@ -3023,7 +3023,7 @@
void test_visitNamedFormalParameter() {
_assertSource(
- "var a : 0",
+ "var a: 0",
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
AstTestFactory.integer(0)));
@@ -4204,7 +4204,7 @@
void test_visitDefaultFormalParameter_named_value() {
_assertSource(
- "p : 0",
+ "p: 0",
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter3("p"),
AstTestFactory.integer(0)));
@@ -4426,7 +4426,7 @@
void test_visitFormalParameterList_n() {
_assertSource(
- "({a : 0})",
+ "({a: 0})",
AstTestFactory.formalParameterList([
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter3("a"),
@@ -4436,7 +4436,7 @@
void test_visitFormalParameterList_nn() {
_assertSource(
- "({a : 0, b : 1})",
+ "({a: 0, b: 1})",
AstTestFactory.formalParameterList([
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter3("a"),
@@ -4479,7 +4479,7 @@
void test_visitFormalParameterList_rn() {
_assertSource(
- "(a, {b : 1})",
+ "(a, {b: 1})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.namedFormalParameter(
@@ -4490,7 +4490,7 @@
void test_visitFormalParameterList_rnn() {
_assertSource(
- "(a, {b : 1, c : 2})",
+ "(a, {b: 1, c: 2})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.namedFormalParameter(
@@ -4538,7 +4538,7 @@
void test_visitFormalParameterList_rrn() {
_assertSource(
- "(a, b, {c : 3})",
+ "(a, b, {c: 3})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.simpleFormalParameter3("b"),
@@ -4550,7 +4550,7 @@
void test_visitFormalParameterList_rrnn() {
_assertSource(
- "(a, b, {c : 3, d : 4})",
+ "(a, b, {c: 3, d: 4})",
AstTestFactory.formalParameterList([
AstTestFactory.simpleFormalParameter3("a"),
AstTestFactory.simpleFormalParameter3("b"),
@@ -5399,7 +5399,7 @@
void test_visitNamedFormalParameter() {
_assertSource(
- "var a : 0",
+ "var a: 0",
AstTestFactory.namedFormalParameter(
AstTestFactory.simpleFormalParameter(Keyword.VAR, "a"),
AstTestFactory.integer(0)));
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index 891bdd3..be13b52 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -964,16 +964,12 @@
}
void test_logicalAnd_false_null() {
- expect(() {
- _assertLogicalAnd(_boolValue(false), _boolValue(false), _nullValue());
- }, throwsEvaluationException);
+ _assertLogicalAnd(_boolValue(false), _boolValue(false), _nullValue());
}
void test_logicalAnd_false_string() {
- expect(() {
- _assertLogicalAnd(
- _boolValue(false), _boolValue(false), _stringValue("false"));
- }, throwsEvaluationException);
+ _assertLogicalAnd(
+ _boolValue(false), _boolValue(false), _stringValue("false"));
}
void test_logicalAnd_false_true() {
@@ -1097,16 +1093,11 @@
}
void test_logicalOr_true_null() {
- expect(() {
- _assertLogicalOr(_boolValue(true), _boolValue(true), _nullValue());
- }, throwsEvaluationException);
+ _assertLogicalOr(_boolValue(true), _boolValue(true), _nullValue());
}
void test_logicalOr_true_string() {
- expect(() {
- _assertLogicalOr(
- _boolValue(true), _boolValue(true), _stringValue("true"));
- }, throwsEvaluationException);
+ _assertLogicalOr(_boolValue(true), _boolValue(true), _stringValue("true"));
}
void test_logicalOr_true_true() {
@@ -1716,10 +1707,10 @@
DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
if (expected == null) {
expect(() {
- left.logicalAnd(_typeProvider, right);
+ left.logicalAnd(_typeProvider, () => right);
}, throwsEvaluationException);
} else {
- DartObjectImpl result = left.logicalAnd(_typeProvider, right);
+ DartObjectImpl result = left.logicalAnd(_typeProvider, () => right);
expect(result, isNotNull);
expect(result, expected);
}
@@ -1750,10 +1741,10 @@
DartObjectImpl expected, DartObjectImpl left, DartObjectImpl right) {
if (expected == null) {
expect(() {
- left.logicalOr(_typeProvider, right);
+ left.logicalOr(_typeProvider, () => right);
}, throwsEvaluationException);
} else {
- DartObjectImpl result = left.logicalOr(_typeProvider, right);
+ DartObjectImpl result = left.logicalOr(_typeProvider, () => right);
expect(result, isNotNull);
expect(result, expected);
}
diff --git a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
index b53098b..9701fbc 100644
--- a/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/code_order_test.dart
@@ -86,12 +86,11 @@
''');
}
- @failingTest
void test_typing_extends_identifier() {
testRecovery('''
class Foo extends CurrentlyTypingHere
class UnrelatedClass extends Bar {}
-''', [ParserErrorCode.MULTIPLE_WITH_CLAUSES], '''
+''', [ParserErrorCode.MISSING_CLASS_BODY], '''
class Foo extends CurrentlyTypingHere {}
class UnrelatedClass extends Bar {}
''');
diff --git a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
index 6e470b7..5dd8b4c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
@@ -9,6 +9,7 @@
main() {
defineReflectiveSuite(() {
+ defineReflectiveTests(AnnotationTest);
defineReflectiveTests(MiscellaneousTest);
defineReflectiveTests(ModifiersTest);
defineReflectiveTests(MultipleTypeTest);
@@ -17,6 +18,34 @@
}
/**
+ * Test how well the parser recovers when annotations are included in places
+ * where they are not allowed.
+ */
+@reflectiveTest
+class AnnotationTest extends AbstractRecoveryTest {
+ @failingTest
+ void test_typeArgument() {
+ // https://github.com/dart-lang/sdk/issues/22314
+ // Parser crashes
+ // 'package:analyzer/src/fasta/ast_builder.dart': Failed assertion:
+ // line 256 pos 12: 'token.isKeywordOrIdentifier': is not true.
+ testRecovery('''
+const annotation = null;
+class A<E> {}
+class C {
+ m() => new A<@annotation C>();
+}
+''', [ParserErrorCode.UNEXPECTED_TOKEN, ParserErrorCode.UNEXPECTED_TOKEN], '''
+const annotation = null;
+class A<E> {}
+class C {
+ m() => new A<C>();
+}
+''');
+ }
+}
+
+/**
* Test how well the parser recovers in other cases.
*/
@reflectiveTest
@@ -31,6 +60,26 @@
''');
}
+ @failingTest
+ void test_extraParenInMapLiteral() {
+ // https://github.com/dart-lang/sdk/issues/12100
+ testRecovery('''
+class C {}
+final Map v = {
+ 'a': () => new C(),
+ 'b': () => new C()),
+ 'c': () => new C(),
+};
+''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
+class C {}
+final Map v = {
+ 'a': () => new C(),
+ 'b': () => new C(),
+ 'c': () => new C(),
+};
+''');
+ }
+
void test_getter_parameters() {
testRecovery('''
int get g() => 0;
@@ -39,6 +88,14 @@
''');
}
+ void test_invalidRangeCheck() {
+ parseCompilationUnit('''
+f(x) {
+ while (1 < x < 3) {}
+}
+''', codes: [ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND]);
+ }
+
void test_multipleRedirectingInitializers() {
testRecovery('''
class A {
@@ -73,6 +130,10 @@
}
}
+/**
+ * Test how well the parser recovers when multiple type annotations are
+ * provided.
+ */
@reflectiveTest
class MultipleTypeTest extends AbstractRecoveryTest {
@failingTest
diff --git a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
index 29e2e53..7cdabed 100644
--- a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
@@ -102,15 +102,11 @@
*/
@reflectiveTest
class MissingCodeTest extends AbstractRecoveryTest {
- @failingTest
void test_ampersand() {
- // Parser crashes
testBinaryExpression('&');
}
- @failingTest
void test_ampersand_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('&');
}
@@ -131,15 +127,13 @@
''');
}
- @failingTest
void test_assignmentExpression() {
- // Parser crashes
testRecovery('''
f() {
var x;
x =
}
-''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+''', [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN], '''
f() {
var x;
x = _s_;
@@ -147,15 +141,11 @@
''');
}
- @failingTest
void test_bar() {
- // Parser crashes
testBinaryExpression('|');
}
- @failingTest
void test_bar_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('|');
}
@@ -189,83 +179,59 @@
''');
}
- @failingTest
void test_conditionalExpression_else() {
- // Parser crashes
testRecovery('''
f() => x ? y :
-''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+''', [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN], '''
f() => x ? y : _s_;
''');
}
- @failingTest
void test_conditionalExpression_then() {
- // Parser crashes
testRecovery('''
f() => x ? : z
-''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+''', [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN], '''
f() => x ? _s_ : z;
''');
}
- @failingTest
void test_equalEqual() {
- // Parser crashes
testBinaryExpression('==');
}
- @failingTest
void test_equalEqual_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('==');
}
- @failingTest
void test_greaterThan() {
- // Parser crashes
testBinaryExpression('>');
}
- @failingTest
void test_greaterThan_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('>');
}
- @failingTest
void test_greaterThanGreaterThan() {
- // Parser crashes
testBinaryExpression('>>');
}
- @failingTest
void test_greaterThanGreaterThan_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('>>');
}
- @failingTest
void test_greaterThanOrEqual() {
- // Parser crashes
testBinaryExpression('>=');
}
- @failingTest
void test_greaterThanOrEqual_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('>=');
}
- @failingTest
void test_hat() {
- // Parser crashes
testBinaryExpression('^');
}
- @failingTest
void test_hat_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('^');
}
@@ -295,75 +261,51 @@
''');
}
- @failingTest
void test_lessThan() {
- // Parser crashes
testBinaryExpression('<');
}
- @failingTest
void test_lessThan_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('<');
}
- @failingTest
void test_lessThanLessThan() {
- // Parser crashes
testBinaryExpression('<<');
}
- @failingTest
void test_lessThanLessThan_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('<<');
}
- @failingTest
void test_lessThanOrEqual() {
- // Parser crashes
testBinaryExpression('<=');
}
- @failingTest
void test_lessThanOrEqual_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('<=');
}
- @failingTest
void test_minus() {
- // Parser crashes
testBinaryExpression('-');
}
- @failingTest
void test_minus_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('-');
}
- @failingTest
void test_percent() {
- // Parser crashes
testBinaryExpression('%');
}
- @failingTest
void test_percent_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('%');
}
- @failingTest
void test_plus() {
- // Parser crashes
testBinaryExpression('+');
}
- @failingTest
void test_plus_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('+');
}
@@ -381,46 +323,56 @@
''');
}
- @failingTest
void test_slash() {
- // Parser crashes
testBinaryExpression('/');
}
- @failingTest
void test_slash_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('/');
}
- @failingTest
void test_star() {
- // Parser crashes
testBinaryExpression('*');
}
- @failingTest
void test_star_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('*');
}
- @failingTest
void test_tildeSlash() {
- // Parser crashes
testBinaryExpression('~/');
}
- @failingTest
void test_tildeSlash_super() {
- // Parser crashes
testUserDefinableOperatorWithSuper('~/');
}
+ void test_unclosedStringInterpolation() {
+ // https://github.com/dart-lang/sdk/issues/946
+ // TODO(brianwilkerson) Try to recover better. Ideally there would be a
+ // single error about an unterminated interpolation block.
+ testRecovery(r'''
+f() {
+ print("${42");
+}
+''', [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.UNTERMINATED_STRING_LITERAL,
+ ScannerErrorCode.UNTERMINATED_STRING_LITERAL
+ ], r'''
+f() {
+ print("${42}");
+}
+''');
+ }
+
void testBinaryExpression(String operator) {
testRecovery('''
f() => x $operator
-''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+''', [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN], '''
f() => x $operator _s_;
''');
}
@@ -430,7 +382,7 @@
class C {
int operator $operator(x) => super $operator
}
-''', [ParserErrorCode.MISSING_IDENTIFIER], '''
+''', [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN], '''
class C {
int operator $operator(x) => super $operator _s_;
}
@@ -609,6 +561,21 @@
''');
}
+ void test_missingComma() {
+ // https://github.com/dart-lang/sdk/issues/22074
+ testRecovery('''
+g(a, b, c) {}
+h(v1, v2, v) {
+ g(v1 == v2 || v1 == v 3, true);
+}
+''', [ParserErrorCode.EXPECTED_TOKEN], '''
+g(a, b, c) {}
+h(v1, v2, v) {
+ g(v1 == v2 || v1 == v, 3, true);
+}
+''');
+ }
+
void test_missingDefault_named_last() {
testRecovery('''
f({a: }) {}
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/break_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/break_statement_test.dart
index fc1a5c58..477bc1c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/break_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/break_statement_test.dart
@@ -16,7 +16,16 @@
'break_statement',
[
new TestDescriptor(
- 'keyword', 'break', [ParserErrorCode.EXPECTED_TOKEN], "break;",
+ 'keyword',
+ 'break',
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.BREAK_OUTSIDE_OF_LOOP
+ ],
+ "break;",
+ expectedErrorsInValidCode: [
+ ParserErrorCode.BREAK_OUTSIDE_OF_LOOP
+ ],
failing: ['labeled', 'localFunctionNonVoid']),
new TestDescriptor(
'label', 'break a', [ParserErrorCode.EXPECTED_TOKEN], "break a;"),
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index c424d5f..550eecb 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -23,7 +23,6 @@
'getter',
'setter'
];
- List<String> onlyConstAndFinal = <String>['const', 'final'];
buildTests(
'class_declaration',
[
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/continue_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/continue_statement_test.dart
index d3999b5..89a70ae 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/continue_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/continue_statement_test.dart
@@ -15,11 +15,29 @@
buildTests(
'continue_statement',
[
- new TestDescriptor('keyword', 'continue',
- [ParserErrorCode.EXPECTED_TOKEN], "continue;",
+ new TestDescriptor(
+ 'keyword',
+ 'continue',
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
+ ],
+ "continue;",
+ expectedErrorsInValidCode: [
+ ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
+ ],
failing: ['labeled', 'localFunctionNonVoid']),
- new TestDescriptor('label', 'continue a',
- [ParserErrorCode.EXPECTED_TOKEN], "continue a;"),
+ new TestDescriptor(
+ 'label',
+ 'continue a',
+ [
+ ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
+ ],
+ "continue a;",
+ expectedErrorsInValidCode: [
+ ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP
+ ]),
],
PartialCodeTest.statementSuffixes,
head: 'f() { ',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/do_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/do_statement_test.dart
index 302462e..599953c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/do_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/do_statement_test.dart
@@ -11,6 +11,8 @@
}
class DoStatementTest extends PartialCodeTest {
+ final allExceptEof =
+ PartialCodeTest.statementSuffixes.map((ts) => ts.name).toList();
buildAll() {
buildTests(
'do_statement',
@@ -70,16 +72,16 @@
[
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN
+ ScannerErrorCode.EXPECTED_TOKEN
],
"do {} while (_s_);",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'condition',
'do {} while (a',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"do {} while (a);",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor('rightParen', 'do {} while (a)',
[ParserErrorCode.EXPECTED_TOKEN], "do {} while (a);"),
],
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/export_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/export_directive_test.dart
index 8ccb281..9cd9192 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/export_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/export_directive_test.dart
@@ -26,7 +26,6 @@
'getter',
'setter'
];
- List<String> onlyConstAndFinal = <String>['const', 'final'];
buildTests(
'export_directive',
[
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
index 86240ee..d3764ef 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/import_directive_test.dart
@@ -12,7 +12,6 @@
class ImportDirectivesTest extends PartialCodeTest {
buildAll() {
- List<String> onlyConstAndFinal = <String>['const', 'final'];
buildTests(
'import_directive',
[
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart
index 7c584c8..48660aa 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/instance_creation_test.dart
@@ -29,11 +29,10 @@
'$keyword',
[
ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN,
+ ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
],
- "$keyword _s_()",
- allFailing: true),
+ "$keyword _s_()"),
new TestDescriptor(
'${keyword}_name_unnamed',
'$keyword A',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/library_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/library_directive_test.dart
index b1f0f16..cf68d9c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/library_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/library_directive_test.dart
@@ -26,7 +26,6 @@
'getter',
'setter'
];
- List<String> onlyConstAndFinal = <String>['const', 'final'];
buildTests(
'library_directive',
[
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart
index ff970df..4c2f010 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/local_variable_test.dart
@@ -209,15 +209,8 @@
],
"var a = _s_;",
failing: allExceptEof),
- new TestDescriptor(
- 'varNameEqualsExpression',
- 'var a = b',
- [
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN
- ],
- "var a = b;",
- allFailing: true),
+ new TestDescriptor('varNameEqualsExpression', 'var a = b',
+ [ParserErrorCode.EXPECTED_TOKEN], "var a = b;"),
],
PartialCodeTest.statementSuffixes,
head: 'f() { ',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_directive_test.dart
index cde7dbb..bed24e2 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_directive_test.dart
@@ -12,7 +12,6 @@
class PartDirectivesTest extends PartialCodeTest {
buildAll() {
- List<String> onlyConstAndFinal = <String>['const', 'final'];
buildTests(
'part_directive',
[
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
index 0fbbd80..7432c7f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/part_of_directive_test.dart
@@ -23,7 +23,6 @@
'getter',
'setter'
];
- List<String> onlyConstAndFinal = <String>['const', 'final'];
buildTests(
'part_of_directive',
[
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
index 35c91eb..ebb09d2 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
@@ -3,8 +3,10 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:test/test.dart';
+import '../../../../generated/test_support.dart';
import '../recovery_test_support.dart';
/**
@@ -131,9 +133,11 @@
//
StringBuffer invalid = new StringBuffer();
StringBuffer valid = new StringBuffer();
+ StringBuffer base = new StringBuffer();
if (head != null) {
invalid.write(head);
valid.write(head);
+ base.write(head);
}
invalid.write(descriptor.invalid);
valid.write(descriptor.valid);
@@ -142,12 +146,43 @@
invalid.write(suffix.text);
valid.write(' ');
valid.write(suffix.text);
+ base.write(' ');
+ base.write(suffix.text);
}
if (tail != null) {
invalid.write(tail);
valid.write(tail);
+ base.write(tail);
}
//
+ // Determine the existing errors in the code
+ // without either valid or invalid code.
+ //
+ GatheringErrorListener listener =
+ new GatheringErrorListener(checkRanges: true);
+ parseCompilationUnit2(base.toString(), listener);
+ var baseErrorCodes = <ErrorCode>[];
+ listener.errors.forEach((AnalysisError error) {
+ if (error.errorCode == ParserErrorCode.BREAK_OUTSIDE_OF_LOOP ||
+ error.errorCode == ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP ||
+ error.errorCode == ParserErrorCode.CONTINUE_WITHOUT_LABEL_IN_CASE) {
+ baseErrorCodes.add(error.errorCode);
+ }
+ });
+
+ var expectedValidCodeErrors = <ErrorCode>[];
+ expectedValidCodeErrors.addAll(baseErrorCodes);
+ if (descriptor.expectedErrorsInValidCode != null) {
+ expectedValidCodeErrors.addAll(descriptor.expectedErrorsInValidCode);
+ }
+
+ var expectedInvalidCodeErrors = <ErrorCode>[];
+ expectedInvalidCodeErrors.addAll(baseErrorCodes);
+ if (descriptor.errorCodes != null) {
+ expectedInvalidCodeErrors.addAll(descriptor.errorCodes);
+ }
+
+ //
// Run the test.
//
List<String> failing = descriptor.failing;
@@ -156,7 +191,8 @@
bool failed = false;
try {
testRecovery(
- invalid.toString(), descriptor.errorCodes, valid.toString());
+ invalid.toString(), expectedInvalidCodeErrors, valid.toString(),
+ expectedErrorsInValidCode: expectedValidCodeErrors);
failed = true;
} catch (e) {
// Expected to fail.
@@ -166,7 +202,8 @@
}
} else {
testRecovery(
- invalid.toString(), descriptor.errorCodes, valid.toString());
+ invalid.toString(), expectedInvalidCodeErrors, valid.toString(),
+ expectedErrorsInValidCode: expectedValidCodeErrors);
}
});
}
@@ -198,6 +235,11 @@
final String valid;
/**
+ * Error codes that the parser is expected to produce in the valid code.
+ */
+ final List<ErrorCode> expectedErrorsInValidCode;
+
+ /**
* A flag indicating whether all of the tests are expected to fail.
*/
final bool allFailing;
@@ -212,7 +254,7 @@
* Initialize a newly created test descriptor.
*/
TestDescriptor(this.name, this.invalid, this.errorCodes, this.valid,
- {this.allFailing: false, this.failing});
+ {this.allFailing: false, this.failing, this.expectedErrorsInValidCode});
}
/**
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/switch_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/switch_statement_test.dart
index 750f8d8..8f7502f 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/switch_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/switch_statement_test.dart
@@ -12,6 +12,8 @@
class SwitchStatementTest extends PartialCodeTest {
buildAll() {
+ final allExceptEof =
+ PartialCodeTest.statementSuffixes.map((ts) => ts.name).toList();
buildTests(
'switch_statement',
[
@@ -22,41 +24,32 @@
ParserErrorCode.EXPECTED_TOKEN,
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN,
ParserErrorCode.EXPECTED_TOKEN
],
"switch (_s_) {}",
- allFailing: true),
+ failing: ['block']),
new TestDescriptor(
'leftParen',
'switch (',
[
ParserErrorCode.MISSING_IDENTIFIER,
ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN
+ ScannerErrorCode.EXPECTED_TOKEN
],
"switch (_s_) {}",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'expression',
'switch (a',
- [
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN,
- ParserErrorCode.EXPECTED_TOKEN
- ],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"switch (a) {}",
- allFailing: true),
- new TestDescriptor(
- 'rightParen',
- 'switch (a)',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
- "switch (a) {}",
- allFailing: true),
- new TestDescriptor('leftBrace', 'switch (a) {',
+ failing: allExceptEof),
+ new TestDescriptor('rightParen', 'switch (a)',
[ParserErrorCode.EXPECTED_TOKEN], "switch (a) {}",
- allFailing: true),
+ failing: ['block']),
+ new TestDescriptor('leftBrace', 'switch (a) {',
+ [ScannerErrorCode.EXPECTED_TOKEN], "switch (a) {}",
+ failing: allExceptEof),
],
PartialCodeTest.statementSuffixes,
head: 'f() { ',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
index dc432ec..206cec2 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
@@ -90,8 +90,7 @@
"int _s_;",
allFailing: true),
new TestDescriptor(
- 'typeName', 'int a', [ParserErrorCode.EXPECTED_TOKEN], "int a;",
- allFailing: true),
+ 'typeName', 'int a', [ParserErrorCode.EXPECTED_TOKEN], "int a;"),
new TestDescriptor(
'var',
'var',
@@ -103,7 +102,7 @@
failing: allExceptEof),
new TestDescriptor(
'varName', 'var a', [ParserErrorCode.EXPECTED_TOKEN], "var a;",
- failing: allExceptEof),
+ failing: ['typedef', 'functionNonVoid', 'getter', 'setter']),
new TestDescriptor(
'varNameEquals',
'var a =',
@@ -113,15 +112,8 @@
],
"var a = _s_;",
failing: allExceptEof),
- new TestDescriptor(
- 'varNameEqualsExpression',
- 'var a = b',
- [
- ParserErrorCode.MISSING_IDENTIFIER,
- ParserErrorCode.EXPECTED_TOKEN
- ],
- "var a = b;",
- allFailing: true),
+ new TestDescriptor('varNameEqualsExpression', 'var a = b',
+ [ParserErrorCode.EXPECTED_TOKEN], "var a = b;"),
],
PartialCodeTest.declarationSuffixes);
}
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
index a6c927d..8b7046d 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
@@ -12,6 +12,8 @@
class TryStatementTest extends PartialCodeTest {
buildAll() {
+ final allExceptEof =
+ PartialCodeTest.statementSuffixes.map((ts) => ts.name).toList();
buildTests(
'try_statement',
[
@@ -37,11 +39,11 @@
'on',
'try {} on',
[
- ParserErrorCode.MISSING_IDENTIFIER,
+ ParserErrorCode.EXPECTED_TYPE_NAME,
ParserErrorCode.EXPECTED_TOKEN
],
"try {} on _s_ {}",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor('on_identifier', 'try {} on A',
[ParserErrorCode.EXPECTED_TOKEN], "try {} on A {}",
failing: ['block']),
@@ -71,9 +73,9 @@
new TestDescriptor(
'catch_identifier',
'try {} catch (e',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"try {} catch (e) {}",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'catch_identifierComma',
'try {} catch (e, ',
@@ -87,9 +89,9 @@
new TestDescriptor(
'catch_identifierCommaIdentifier',
'try {} catch (e, s',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"try {} catch (e, s) {}",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor('catch_rightParen', 'try {} catch (e, s)',
[ParserErrorCode.EXPECTED_TOKEN], "try {} catch (e, s) {}",
failing: ['block']),
@@ -119,9 +121,9 @@
new TestDescriptor(
'on_catch_identifier',
'try {} on A catch (e',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"try {} on A catch (e) {}",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'on_catch_identifierComma',
'try {} on A catch (e, ',
@@ -135,9 +137,9 @@
new TestDescriptor(
'on_catch_identifierCommaIdentifier',
'try {} on A catch (e, s',
- [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+ [ParserErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN],
"try {} on A catch (e, s) {}",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor('on_catch_rightParen', 'try {} on A catch (e, s)',
[ParserErrorCode.EXPECTED_TOKEN], "try {} on A catch (e, s) {}",
failing: ['block']),
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
index c57834a..c7aa796 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
@@ -24,7 +24,7 @@
ParserErrorCode.EXPECTED_TOKEN
],
"while (_s_)",
- failing: ['eof']),
+ failing: ['eof', 'break', 'continue']),
new TestDescriptor(
'leftParen',
'while (',
diff --git a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
index f86a63b..9a48970 100644
--- a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
@@ -9,6 +9,7 @@
import 'package:test/test.dart';
import '../../../generated/parser_fasta_test.dart';
+import '../../../generated/test_support.dart';
/**
* The base class for tests that test how well the parser recovers from various
@@ -17,15 +18,36 @@
abstract class AbstractRecoveryTest extends FastaParserTestCase {
void testRecovery(
String invalidCode, List<ErrorCode> errorCodes, String validCode,
- {CompilationUnit adjustValidUnitBeforeComparison(CompilationUnit unit)}) {
- CompilationUnit invalidUnit =
- parseCompilationUnit(invalidCode, codes: errorCodes);
+ {CompilationUnit adjustValidUnitBeforeComparison(CompilationUnit unit),
+ List<ErrorCode> expectedErrorsInValidCode}) {
+ CompilationUnit validUnit;
+
+ // Assert that the valid code is indeed valid.
+ try {
+ validUnit =
+ parseCompilationUnit(validCode, codes: expectedErrorsInValidCode);
+ } catch (e) {
+ print('*** Valid code did not parse correctly');
+ print(validCode);
+ rethrow;
+ }
+
+ // Compare the structures before asserting valid errors.
+ GatheringErrorListener listener =
+ new GatheringErrorListener(checkRanges: true);
+ CompilationUnit invalidUnit = parseCompilationUnit2(invalidCode, listener);
validateTokenStream(invalidUnit.beginToken);
- CompilationUnit validUnit = parseCompilationUnit(validCode);
if (adjustValidUnitBeforeComparison != null) {
validUnit = adjustValidUnitBeforeComparison(validUnit);
}
ResultComparator.compare(invalidUnit, validUnit);
+
+ // Assert valid errors.
+ if (errorCodes != null) {
+ listener.assertErrorsWithCodes(errorCodes);
+ } else {
+ listener.assertNoErrors();
+ }
}
void validateTokenStream(Token token) {
@@ -43,10 +65,10 @@
class ResultComparator extends AstComparator {
bool failDifferentLength(List first, List second) {
StringBuffer buffer = new StringBuffer();
- buffer.write('Expected a list of length ');
- buffer.write(second.length);
- buffer.write('; found a list of length ');
- buffer.writeln(first.length);
+ buffer.writeln('Expected a list of length ${second.length}');
+ buffer.writeln(' $second');
+ buffer.writeln('But found a list of length ${first.length}');
+ buffer.writeln(' $first');
if (first is NodeList) {
_safelyWriteNodePath(buffer, first.owner);
}
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 1204587..fb326f8 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1642,7 +1642,7 @@
Future<int> f;
var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE*/
(x) => /*error:RETURN_OF_INVALID_TYPE_FROM_CLOSURE*/[]);
- Future<List<int>> y = x;
+ Future<List<int>> y = /*error:INVALID_ASSIGNMENT*/x;
}
m2() {
Future<int> f;
diff --git a/pkg/analyzer/tool/generate_files b/pkg/analyzer/tool/generate_files
index 39bb928..0542717 100755
--- a/pkg/analyzer/tool/generate_files
+++ b/pkg/analyzer/tool/generate_files
@@ -43,5 +43,5 @@
VM_OPTIONS+=("--packages=${ROOT_DIR}/.packages")
cd "${SCRIPT_DIR}"
-"${DART}" "${VM_OPTIONS[@]}" "task_dependency_graph/generate.dart"
"${DART}" "${VM_OPTIONS[@]}" "summary/generate.dart"
+"${DART}" "${VM_OPTIONS[@]}" "task_dependency_graph/generate.dart"
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index b5bfbcd..f7ee91b 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -266,6 +266,11 @@
mode: io.FileMode.WRITE_ONLY);
}
});
+ } else {
+ // Build the graph, e.g. associate parts with libraries.
+ for (var file in uriToFileMap.values) {
+ analysisDriver.fsState.getFileForPath(file.path);
+ }
}
if (options.buildSummaryOnly) {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 9f298d5..13bcfa4 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -873,6 +873,7 @@
contextOptions.hint = !options.disableHints;
contextOptions.generateImplicitErrors = options.showPackageWarnings;
contextOptions.generateSdkErrors = options.showSdkWarnings;
+ contextOptions.previewDart2 = options.previewDart2;
if (options.useCFE) {
contextOptions.useFastaParser = true;
}
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index cd90779..cead0b7 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -50,12 +50,12 @@
Driver driver;
- /// Normalize text with bullets.
- String bulletToDash(item) => '$item'.replaceAll('•', '-');
+ bool get useCFE => false;
bool get usePreviewDart2 => false;
- bool get useCFE => false;
+ /// Normalize text with bullets.
+ String bulletToDash(item) => '$item'.replaceAll('•', '-');
/// Start a driver for the given [source], optionally providing additional
/// [args] and an [options] file path. The value of [options] defaults to an
@@ -436,6 +436,33 @@
expect(exitCode, 0);
}
+ test_onlyErrors_partFirst() async {
+ await withTempDirAsync((tempDir) async {
+ var aDart = path.join(tempDir, 'a.dart');
+ var bDart = path.join(tempDir, 'b.dart');
+
+ var aUri = 'package:aaa/a.dart';
+ var bUri = 'package:aaa/b.dart';
+
+ new File(aDart).writeAsStringSync(r'''
+library lib;
+part 'b.dart';
+class A {}
+''');
+ new File(bDart).writeAsStringSync('''
+part of lib;
+class B {}
+var a = new A();
+var b = new B();
+''');
+
+ // Analyze b.dart (part) and then a.dart (its library).
+ // No errors should be reported - the part should know its library.
+ await _doDrive(bDart, uri: bUri, additionalArgs: ['$aUri|$aDart']);
+ expect(errorSink, isEmpty);
+ });
+ }
+
Future<Null> _doDrive(String path,
{String uri,
List<String> additionalArgs: const [],
@@ -821,13 +848,6 @@
expect(driver.context.analysisOptions.useFastaParser, isFalse);
}
- @failingTest
- test_useCFE() async {
- await drive('data/options_tests_project/test_file.dart',
- args: ['--use-cfe']);
- expect(driver.context.analysisOptions.useFastaParser, isTrue);
- }
-
test_strongSdk() async {
String testDir = path.join(testDirectory, 'data', 'strong_sdk');
await drive(path.join(testDir, 'main.dart'), args: ['--strong']);
@@ -841,6 +861,13 @@
expect(outSink.toString().contains('[info]'), isFalse);
}
+ @failingTest
+ test_useCFE() async {
+ await drive('data/options_tests_project/test_file.dart',
+ args: ['--use-cfe']);
+ expect(driver.context.analysisOptions.useFastaParser, isTrue);
+ }
+
test_withFlags_overrideFatalWarning() async {
await drive('data/options_tests_project/test_file.dart',
args: ['--fatal-warnings'],
@@ -893,12 +920,12 @@
@override
@failingTest
- test_withFlags_overrideFatalWarning() =>
- super.test_withFlags_overrideFatalWarning();
+ test_previewDart2() => super.test_previewDart2();
@override
@failingTest
- test_previewDart2() => super.test_previewDart2();
+ test_withFlags_overrideFatalWarning() =>
+ super.test_withFlags_overrideFatalWarning();
}
class TestSource implements Source {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index f773143..ea4e3af 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -24,6 +24,7 @@
import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
import 'package:analyzer_plugin/utilities/range_factory.dart';
import 'package:charcode/ascii.dart';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
/**
@@ -357,6 +358,7 @@
if (isGetter) {
writeln(' => null;');
} else {
+ writeTypeParameters(member.typeParameters, methodBeingCopied: member);
List<ParameterElement> parameters = member.parameters;
writeParameters(parameters, methodBeingCopied: member);
writeln(' {');
@@ -474,9 +476,9 @@
{ExecutableElement methodBeingCopied}) {
_EnclosingElementFinder finder = new _EnclosingElementFinder();
finder.find(dartFileEditBuilder.unit, offset);
- String parameterSource = _getParameterSource(
- type, name, finder.enclosingClass, finder.enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
+ String parameterSource = _getTypeSource(
+ type, finder.enclosingClass, finder.enclosingExecutable,
+ parameterName: name, methodBeingCopied: methodBeingCopied);
write(parameterSource);
}
@@ -514,16 +516,25 @@
}
@override
- void writeTypeParameter(TypeParameterElement typeParameter) {
+ void writeTypeParameter(TypeParameterElement typeParameter,
+ {ExecutableElement methodBeingCopied}) {
write(typeParameter.name);
if (typeParameter.bound != null) {
- write(' extends ');
- writeType(typeParameter.bound);
+ _EnclosingElementFinder finder = new _EnclosingElementFinder();
+ finder.find(dartFileEditBuilder.unit, offset);
+ String bound = _getTypeSource(typeParameter.bound, finder.enclosingClass,
+ finder.enclosingExecutable,
+ methodBeingCopied: methodBeingCopied);
+ if (bound != null) {
+ write(' extends ');
+ write(bound);
+ }
}
}
@override
- void writeTypeParameters(List<TypeParameterElement> typeParameters) {
+ void writeTypeParameters(List<TypeParameterElement> typeParameters,
+ {ExecutableElement methodBeingCopied}) {
if (typeParameters.isNotEmpty) {
write('<');
bool isFirst = true;
@@ -532,7 +543,7 @@
write(', ');
}
isFirst = false;
- writeTypeParameter(typeParameter);
+ writeTypeParameter(typeParameter, methodBeingCopied: methodBeingCopied);
}
write('>');
}
@@ -755,70 +766,39 @@
}
/**
- * Return the source for the parameter with the given [type] and [name].
- */
- String _getParameterSource(DartType type, String name,
- ClassElement enclosingClass, ExecutableElement enclosingExecutable,
- {ExecutableElement methodBeingCopied}) {
- // no type
- if (type == null || type.isDynamic) {
- return name;
- }
- // function type
- if (type is FunctionType && type.element.isSynthetic) {
- FunctionType functionType = type;
- StringBuffer buffer = new StringBuffer();
- // return type
- DartType returnType = functionType.returnType;
- if (returnType != null && !returnType.isDynamic) {
- String returnTypeSource = _getTypeSource(
- returnType, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (returnTypeSource.isNotEmpty) {
- buffer.write(returnTypeSource);
- buffer.write(' ');
- }
- }
- // parameter name
- buffer.write(name);
- // parameters
- buffer.write('(');
- List<ParameterElement> fParameters = functionType.parameters;
- for (int i = 0; i < fParameters.length; i++) {
- ParameterElement fParameter = fParameters[i];
- if (i != 0) {
- buffer.write(", ");
- }
- buffer.write(_getParameterSource(fParameter.type, fParameter.name,
- enclosingClass, enclosingExecutable));
- }
- buffer.write(')');
- // done
- return buffer.toString();
- }
- // simple type
- String typeSource = _getTypeSource(
- type, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (typeSource.isNotEmpty) {
- return '$typeSource $name';
- }
- return name;
- }
-
- /**
- * Returns the source to reference [type] in this [CompilationUnit].
+ * Returns the source to reference [type] in this compilation unit.
+ *
+ * If an [enclosingClass] is provided then the reference is being generated
+ * within the class and the type parameters of the class will be considered to
+ * be visible.
+ *
+ * If an [enclosingExecutable] is provided, then the reference is being
+ * generated within the class and the type parameters of the method will be
+ * considered to be visible.
+ *
+ * If a [methodBeingCopied] is provided, then the type parameters of that
+ * method will be duplicated in the copy and will therefore be visible.
+ *
+ * If a [parameterName] is given, then the type is the type of a parameter
+ * and the parameter name will be included, either in-line in a function type
+ * or after the type source for other types.
*
* Causes any libraries whose elements are used by the generated source, to be
* imported.
*/
String _getTypeSource(DartType type, ClassElement enclosingClass,
ExecutableElement enclosingExecutable,
- {ExecutableElement methodBeingCopied, StringBuffer parametersBuffer}) {
- StringBuffer buffer = new StringBuffer();
+ {String parameterName, ExecutableElement methodBeingCopied}) {
// type parameter
- if (!_isTypeVisible(type, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied)) {
+ type = _getVisibleType(type, enclosingClass, enclosingExecutable,
+ methodBeingCopied: methodBeingCopied);
+ if (type == null ||
+ type.isDynamic ||
+ type.isBottom ||
+ type.isDartCoreNull) {
+ if (parameterName != null) {
+ return parameterName;
+ }
return 'dynamic';
}
@@ -833,43 +813,54 @@
// just a Function, not FunctionTypeAliasElement
if (type is FunctionType && element is! FunctionTypeAliasElement) {
- if (parametersBuffer == null) {
+ if (parameterName == null) {
return 'Function';
}
- parametersBuffer.write('(');
- for (ParameterElement parameter in type.parameters) {
- String parameterType = _getTypeSource(
- parameter.type, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
- if (parametersBuffer.length != 1) {
- parametersBuffer.write(', ');
- }
- parametersBuffer.write(parameterType);
- parametersBuffer.write(' ');
- parametersBuffer.write(parameter.name);
- }
- parametersBuffer.write(')');
- return _getTypeSource(
+ StringBuffer buffer = new StringBuffer();
+ String returnType = _getTypeSource(
type.returnType, enclosingClass, enclosingExecutable,
methodBeingCopied: methodBeingCopied);
- }
- // <Bottom>, Null
- if (type.isBottom || type.isDartCoreNull) {
- return 'dynamic';
+ if (returnType != null) {
+ buffer.write(returnType);
+ buffer.write(' ');
+ }
+ buffer.write(parameterName);
+ buffer.write('(');
+ int count = type.parameters.length;
+ for (int i = 0; i < count; i++) {
+ ParameterElement parameter = type.parameters[i];
+ String parameterType = _getTypeSource(
+ parameter.type, enclosingClass, enclosingExecutable,
+ parameterName: parameter.name,
+ methodBeingCopied: methodBeingCopied);
+ if (i > 0) {
+ buffer.write(', ');
+ }
+ buffer.write(parameterType);
+ }
+ buffer.write(')');
+ return buffer.toString();
}
// prepare element
if (element == null) {
String source = type.toString();
source = source.replaceAll('<dynamic>', '');
source = source.replaceAll('<dynamic, dynamic>', '');
+ if (parameterName != null) {
+ return '$source $parameterName';
+ }
return source;
}
// check if imported
+ StringBuffer buffer = new StringBuffer();
LibraryElement definingLibrary = element.library;
LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
if (definingLibrary != null && definingLibrary != importingLibrary) {
// no source, if private
if (element.isPrivate) {
+ if (parameterName != null) {
+ return parameterName;
+ }
return '';
}
// ensure import
@@ -896,8 +887,9 @@
for (DartType argument in arguments) {
hasArguments = hasArguments || !argument.isDynamic;
allArgumentsVisible = allArgumentsVisible &&
- _isTypeVisible(argument, enclosingClass, enclosingExecutable,
- methodBeingCopied: methodBeingCopied);
+ _getVisibleType(argument, enclosingClass, enclosingExecutable,
+ methodBeingCopied: methodBeingCopied) !=
+ null;
}
// append type arguments
if (hasArguments && allArgumentsVisible) {
@@ -919,6 +911,10 @@
buffer.write(">");
}
}
+ if (parameterName != null) {
+ buffer.write(' ');
+ buffer.write(parameterName);
+ }
// done
return buffer.toString();
}
@@ -963,34 +959,61 @@
}
/**
- * Checks if [type] is visible in either the [enclosingExecutable] or
- * [enclosingClass].
+ * If the given [type] is visible in either the [enclosingExecutable] or
+ * [enclosingClass], or if there is a local equivalent to the type (such as in
+ * the case of a type parameter from a superclass), then return the type that
+ * is locally visible. Otherwise, return `null`.
*/
- bool _isTypeVisible(DartType type, ClassElement enclosingClass,
+ DartType _getVisibleType(DartType type, ClassElement enclosingClass,
ExecutableElement enclosingExecutable,
{ExecutableElement methodBeingCopied}) {
if (type is TypeParameterType) {
TypeParameterElement parameterElement = type.element;
Element parameterParent = parameterElement.enclosingElement;
// TODO(brianwilkerson) This needs to compare the parameterParent with
- // each of the parents of the enclosingElement. (That means that we only
- // need the most closely enclosing element.)
- return parameterParent == enclosingExecutable ||
+ // each of the parents of the enclosingExecutable. (That means that we
+ // only need the most closely enclosing element.)
+ if (parameterParent == enclosingExecutable ||
parameterParent == enclosingClass ||
- parameterParent == methodBeingCopied;
+ parameterParent == methodBeingCopied) {
+ return type;
+ }
+ if (enclosingClass != null &&
+ methodBeingCopied != null &&
+ parameterParent is ClassElement &&
+ parameterParent == methodBeingCopied.enclosingElement) {
+ // The parameter is from the class enclosing the methodBeingCopied. That
+ // means that somewhere along the inheritance chain there must be a type
+ // argument corresponding to the type parameter (either a concrete type
+ // or a type parameter of the enclosingClass). That's the visible type
+ // that needs to be returned.
+ _InheritanceChain chain = new _InheritanceChain(
+ subtype: enclosingClass, supertype: parameterParent);
+ while (chain != null) {
+ DartType mappedType = chain.mapParameter(parameterElement);
+ if (mappedType is TypeParameterType) {
+ parameterElement = mappedType.element;
+ chain = chain.next;
+ } else {
+ return mappedType;
+ }
+ }
+ return parameterElement.type;
+ }
+ return null;
}
Element element = type.element;
if (element == null) {
- return true;
+ return type;
}
LibraryElement definingLibrary = element.library;
LibraryElement importingLibrary = dartFileEditBuilder.unit.element.library;
- if (definingLibrary != null && definingLibrary != importingLibrary) {
- if (element.isPrivate) {
- return false;
- }
+ if (definingLibrary != null &&
+ definingLibrary != importingLibrary &&
+ element.isPrivate) {
+ return null;
}
- return true;
+ return type;
}
}
@@ -1348,6 +1371,10 @@
if (node is FunctionDeclaration) {
replaceTypeWithFuture(node.returnType, typeProvider);
return;
+ } else if (node is FunctionExpression &&
+ node.parent is! FunctionDeclaration) {
+ // Closures don't have a return type.
+ return;
} else if (node is MethodDeclaration) {
replaceTypeWithFuture(node.returnType, typeProvider);
return;
@@ -1411,6 +1438,91 @@
}
}
+class _InheritanceChain {
+ final _InheritanceChain next;
+
+ final InterfaceType supertype;
+
+ /**
+ * Return the shortest inheritance chain from a [subtype] to a [supertype], or
+ * `null` if [subtype] does not inherit from [supertype].
+ */
+ factory _InheritanceChain(
+ {@required ClassElement subtype, @required ClassElement supertype}) {
+ List<_InheritanceChain> allChainsFrom(
+ _InheritanceChain next, ClassElement subtype) {
+ List<_InheritanceChain> chains = <_InheritanceChain>[];
+ InterfaceType supertypeType = subtype.supertype;
+ ClassElement supertypeElement = supertypeType.element;
+ if (supertypeElement == supertype) {
+ chains.add(new _InheritanceChain._(next, supertypeType));
+ } else if (supertypeType.isObject) {
+ // Don't add this chain and don't recurse.
+ } else {
+ chains.addAll(allChainsFrom(
+ new _InheritanceChain._(next, supertypeType), supertypeElement));
+ }
+ for (InterfaceType mixinType in subtype.mixins) {
+ ClassElement mixinElement = mixinType.element;
+ if (mixinElement == supertype) {
+ chains.add(new _InheritanceChain._(next, mixinType));
+ }
+ }
+ for (InterfaceType interfaceType in subtype.interfaces) {
+ ClassElement interfaceElement = interfaceType.element;
+ if (interfaceElement == supertype) {
+ chains.add(new _InheritanceChain._(next, interfaceType));
+ } else if (supertypeType.isObject) {
+ // Don't add this chain and don't recurse.
+ } else {
+ chains.addAll(allChainsFrom(
+ new _InheritanceChain._(next, interfaceType), interfaceElement));
+ }
+ }
+ return chains;
+ }
+
+ List<_InheritanceChain> chains = allChainsFrom(null, subtype);
+ if (chains.isEmpty) {
+ return null;
+ }
+ _InheritanceChain shortestChain = chains.removeAt(0);
+ int shortestLength = shortestChain.length;
+ for (_InheritanceChain chain in chains) {
+ int length = chain.length;
+ if (length < shortestLength) {
+ shortestChain = chain;
+ shortestLength = length;
+ }
+ }
+ return shortestChain;
+ }
+
+ /**
+ * Initialize a newly created link in an inheritance chain.
+ */
+ _InheritanceChain._(this.next, this.supertype);
+
+ /**
+ * Return the number of links in the chain starting with this link.
+ */
+ int get length {
+ if (next == null) {
+ return 1;
+ }
+ return next.length + 1;
+ }
+
+ DartType mapParameter(TypeParameterElement typeParameter) {
+ Element parameterParent = typeParameter.enclosingElement;
+ if (parameterParent is ClassElement) {
+ int index = parameterParent.typeParameters.indexOf(typeParameter);
+ return supertype.typeArguments[index];
+ }
+ return null;
+ }
+}
+
class _InsertionDescription {
final int offset;
final bool insertEmptyLineBefore;
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index b7021d6..2bc7d7d 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -238,14 +238,24 @@
/**
* Write the code to declare the given [typeParameter]. The enclosing angle
* brackets are not automatically written.
+ *
+ * If a [methodBeingCopied] is provided, then type parameters defined by that
+ * method are assumed to be part of what is being written and hence valid
+ * types.
*/
- void writeTypeParameter(TypeParameterElement typeParameter);
+ void writeTypeParameter(TypeParameterElement typeParameter,
+ {ExecutableElement methodBeingCopied});
/**
* Write the code to declare the given list of [typeParameters]. The enclosing
* angle brackets are automatically written.
+ *
+ * If a [methodBeingCopied] is provided, then type parameters defined by that
+ * method are assumed to be part of what is being written and hence valid
+ * types.
*/
- void writeTypeParameters(List<TypeParameterElement> typeParameters);
+ void writeTypeParameters(List<TypeParameterElement> typeParameters,
+ {ExecutableElement methodBeingCopied});
}
/**
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index 04a71c9..b953cf1 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -887,31 +887,85 @@
expect(group.positions, hasLength(1));
}
- test_writeOverrideOfInheritedMember() async {
- String path = provider.convertPath('/test.dart');
- String content = '''
+ test_writeOverrideOfInheritedMember_method() async {
+ await _assertWriteOverrideOfInheritedMethod('''
class A {
A add(A a) => null;
}
class B extends A {
-}''';
- addSource(path, content);
- ClassElement classA = await _getClassElement(path, 'A');
-
- DartChangeBuilderImpl builder = new DartChangeBuilder(session);
- await builder.addFileEdit(path, (FileEditBuilder builder) {
- builder.addInsertion(content.length - 1, (EditBuilder builder) {
- (builder as DartEditBuilder)
- .writeOverrideOfInheritedMember(classA.methods[0]);
- });
- });
- SourceEdit edit = getEdit(builder);
- expect(edit.replacement, equalsIgnoringWhitespace('''
+}
+''', '''
@override
A add(A a) {
// TODO: implement add
return null;
-}'''));
+}
+''');
+ }
+
+ test_writeOverrideOfInheritedMember_method_functionTypeAlias() async {
+ await _assertWriteOverrideOfInheritedMethod('''
+typedef int F(int left, int right);
+abstract class A {
+ void perform(F f);
+}
+class B extends A {
+}
+''', '''
+@override
+void perform(F f) {
+ // TODO: implement perform
+ return null;
+}
+''');
+ }
+
+ test_writeOverrideOfInheritedMember_method_functionTypedParameter() async {
+ await _assertWriteOverrideOfInheritedMethod('''
+abstract class A {
+ forEach(int f(double p1, String p2));
+}
+
+class B extends A {
+}
+''', '''
+@override
+forEach(int f(double p1, String p2)) {
+ // TODO: implement forEach
+}
+''');
+ }
+
+ test_writeOverrideOfInheritedMember_method_generic_noBounds() async {
+ await _assertWriteOverrideOfInheritedMethod('''
+abstract class A {
+ List<T> get<T>(T key);
+}
+class B implements A {
+}
+''', '''
+@override
+List<T> get<T>(T key) {
+ // TODO: implement get
+ return null;
+}
+''');
+ }
+
+ test_writeOverrideOfInheritedMember_method_generic_withBounds() async {
+ await _assertWriteOverrideOfInheritedMethod('''
+abstract class A<K1, V1> {
+ List<T> get<T extends V1>(K1 key);
+}
+class B<K2, V2> implements A<K2, V2> {
+}
+''', '''
+@override
+List<T> get<T extends V2>(K2 key) {
+ // TODO: implement get
+ return null;
+}
+''');
}
test_writeParameterMatchingArgument() async {
@@ -1330,6 +1384,28 @@
expect(resultCode, expectedCode);
}
+ /**
+ * Assuming that the [content] being edited defines a class named 'A' whose
+ * first method is the member to be overridden and ends with a class to which
+ * an inherited method is to be added, assert that the text of the overridden
+ * member matches the [expected] text (modulo white space).
+ */
+ _assertWriteOverrideOfInheritedMethod(String content, String expected) async {
+ String path = provider.convertPath('/test.dart');
+ addSource(path, content);
+ ClassElement classA = await _getClassElement(path, 'A');
+
+ DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ await builder.addFileEdit(path, (FileEditBuilder builder) {
+ builder.addInsertion(content.length - 2, (EditBuilder builder) {
+ (builder as DartEditBuilder)
+ .writeOverrideOfInheritedMember(classA.methods[0]);
+ });
+ });
+ SourceEdit edit = getEdit(builder);
+ expect(edit.replacement, equalsIgnoringWhitespace(expected));
+ }
+
Future<ClassElement> _getClassElement(String path, String name) async {
UnitElementResult result = await driver.getUnitElement(path);
return result.element.getType(name);
@@ -1350,7 +1426,27 @@
return new TestTypeProvider(context);
}
- test_convertFunctionFromSyncToAsync() async {
+ test_convertFunctionFromSyncToAsync_closure() async {
+ String path = provider.convertPath('/test.dart');
+ addSource(path, '''var f = () {}''');
+
+ CompilationUnit unit = (await driver.getResult(path))?.unit;
+ TopLevelVariableDeclaration variable = unit.declarations[0];
+ FunctionBody body =
+ (variable.variables.variables[0].initializer as FunctionExpression)
+ .body;
+
+ DartChangeBuilderImpl builder = new DartChangeBuilder(session);
+ await builder.addFileEdit(path, (FileEditBuilder builder) {
+ (builder as DartFileEditBuilder)
+ .convertFunctionFromSyncToAsync(body, typeProvider);
+ });
+ List<SourceEdit> edits = getEdits(builder);
+ expect(edits, hasLength(1));
+ expect(edits[0].replacement, equalsIgnoringWhitespace('async'));
+ }
+
+ test_convertFunctionFromSyncToAsync_topLevelFunction() async {
String path = provider.convertPath('/test.dart');
addSource(path, 'String f() {}');
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 7a6f642..7a0b6de 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -88,6 +88,11 @@
// https://gist.github.com/eernstg/4353d7b4f669745bed3a5423e04a453c.
static const String genericMethodSyntax = '--generic-method-syntax';
+ // Starts `async` functions synchronously.
+ //
+ // This is the Dart 2.0 behavior. This flag is only used during the migration.
+ static const String syncAsync = '--sync-async';
+
// Initializing-formal access is enabled by default and cannot be disabled.
// For backward compatibility the option is still accepted, but it is ignored.
static const String initializingFormalAccess = '--initializing-formal-access';
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 7163d40..67f6910 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -508,6 +508,8 @@
FunctionEntity get asyncHelperStart =>
_findAsyncHelperFunction("_asyncStart");
+ FunctionEntity get asyncHelperStartSync =>
+ _findAsyncHelperFunction("_asyncStartSync");
FunctionEntity get asyncHelperAwait =>
_findAsyncHelperFunction("_asyncAwait");
FunctionEntity get asyncHelperReturn =>
@@ -550,6 +552,12 @@
ConstructorEntity get syncCompleterConstructor =>
_env.lookupConstructor(_findAsyncHelperClass("Completer"), "sync");
+ ConstructorEntity get asyncAwaitCompleterConstructor =>
+ _env.lookupConstructor(asyncAwaitCompleter, "");
+
+ ClassEntity get asyncAwaitCompleter =>
+ _findAsyncHelperClass("_AsyncAwaitCompleter");
+
ClassEntity get asyncStarController =>
_findAsyncHelperClass("_AsyncStarStreamController");
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index b080d91..bd2e4ce 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -355,6 +355,7 @@
new OptionHandler(Flags.allowMockCompilation, passThrough),
new OptionHandler(Flags.fastStartup, passThrough),
new OptionHandler(Flags.genericMethodSyntax, ignoreOption),
+ new OptionHandler(Flags.syncAsync, passThrough),
new OptionHandler(Flags.initializingFormalAccess, ignoreOption),
new OptionHandler('${Flags.minify}|-m', implyCompilation),
new OptionHandler(Flags.preserveUris, passThrough),
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index d099669..a81a272 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -15,7 +15,8 @@
ConstantValue,
ConstructedConstantValue,
DeferredConstantValue,
- DeferredGlobalConstantValue;
+ DeferredGlobalConstantValue,
+ TypeConstantValue;
import 'elements/types.dart';
import 'elements/elements.dart'
show AstElement, ClassElement, Element, MethodElement, LocalFunctionElement;
@@ -370,6 +371,12 @@
ClassEntity cls = constant.type.element;
_updateElementRecursive(cls, oldSet, newSet, queue);
}
+ if (constant is TypeConstantValue) {
+ var type = constant.representedType;
+ if (type is TypedefType) {
+ _updateElementRecursive(type.element, oldSet, newSet, queue);
+ }
+ }
constant.getDependencies().forEach((ConstantValue dependency) {
if (dependency is DeferredConstantValue) {
/// New deferred-imports are only discovered when we are visiting the
diff --git a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
index eddc55e..7f640b3 100644
--- a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
@@ -43,7 +43,6 @@
howToFix: "Try removing '#{modifier}'.",
examples: const [
"var String foo; main(){}",
- "var set foo; main(){}",
"var final foo; main(){}",
"var var foo; main(){}",
"var const foo; main(){}",
diff --git a/pkg/compiler/lib/src/elements/resolution_types.dart b/pkg/compiler/lib/src/elements/resolution_types.dart
index 0ebbe2fb..4ecaf3b 100644
--- a/pkg/compiler/lib/src/elements/resolution_types.dart
+++ b/pkg/compiler/lib/src/elements/resolution_types.dart
@@ -627,6 +627,8 @@
*/
final List<ResolutionDartType> namedParameterTypes;
+ TypedefType get typedefType => null;
+
factory ResolutionFunctionType(FunctionTypedElement element,
[ResolutionDartType returnType = const ResolutionDynamicType(),
List<ResolutionDartType> parameterTypes = const <ResolutionDartType>[],
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 0bb9763..5ea9202 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -499,13 +499,17 @@
final List<FunctionTypeVariable> typeVariables;
+ /// The originating [TypedefType], if any.
+ final TypedefType typedefType;
+
FunctionType(
this.returnType,
this.parameterTypes,
this.optionalParameterTypes,
this.namedParameters,
this.namedParameterTypes,
- this.typeVariables);
+ this.typeVariables,
+ this.typedefType);
bool get containsTypeVariables {
return returnType.containsTypeVariables ||
@@ -573,7 +577,8 @@
newOptionalParameterTypes,
namedParameters,
newNamedParameterTypes,
- newTypeVariables);
+ newTypeVariables,
+ typedefType);
}
return this;
}
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 77856cb..a34a070 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -362,10 +362,13 @@
}
break;
case TypeUseKind.TYPE_LITERAL:
+ TypedefType typedef;
if (type.isTypedef) {
- TypedefType typedef = type;
- worldBuilder.registerTypedef(typedef.element);
+ typedef = type;
+ } else if (type is FunctionType) {
+ typedef = type.typedefType;
}
+ if (typedef != null) worldBuilder.registerTypedef(typedef.element);
break;
}
}
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 147a35e..3209051 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -700,7 +700,8 @@
NativeBasicData nativeBasicData = compiler.frontendStrategy.nativeBasicData;
RuntimeTypesNeedBuilder rtiNeedBuilder =
compiler.frontendStrategy.createRuntimeTypesNeedBuilder();
- BackendImpacts impacts = new BackendImpacts(commonElements);
+ BackendImpacts impacts =
+ new BackendImpacts(compiler.options, commonElements);
TypeVariableResolutionAnalysis typeVariableResolutionAnalysis =
new TypeVariableResolutionAnalysis(
compiler.frontendStrategy.elementEnvironment,
@@ -783,7 +784,8 @@
CompilerTask task, Compiler compiler, ClosedWorld closedWorld) {
ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
CommonElements commonElements = closedWorld.commonElements;
- BackendImpacts impacts = new BackendImpacts(commonElements);
+ BackendImpacts impacts =
+ new BackendImpacts(compiler.options, commonElements);
_typeVariableCodegenAnalysis = new TypeVariableCodegenAnalysis(
closedWorld.elementEnvironment, this, commonElements, mirrorsData);
_mirrorsCodegenAnalysis = mirrorsResolutionAnalysis.close();
@@ -981,7 +983,8 @@
emitter.createEmitter(namer, closedWorld, codegenWorldBuilder, sorter);
// TODO(johnniwinther): Share the impact object created in
// createCodegenEnqueuer.
- BackendImpacts impacts = new BackendImpacts(closedWorld.commonElements);
+ BackendImpacts impacts =
+ new BackendImpacts(compiler.options, closedWorld.commonElements);
if (compiler.options.disableRtiOptimization) {
_rtiSubstitutions = new TrivialRuntimeTypesSubstitutions(
closedWorld.elementEnvironment, closedWorld.dartTypes);
@@ -1167,13 +1170,20 @@
jsAst.Expression code,
SourceInformation bodySourceInformation,
SourceInformation exitSourceInformation) {
+ bool startAsyncSynchronously = compiler.options.startAsyncSynchronously;
+
AsyncRewriterBase rewriter = null;
jsAst.Name name = namer.methodPropertyName(element);
switch (element.asyncMarker) {
case AsyncMarker.ASYNC:
+ var startFunction = startAsyncSynchronously
+ ? commonElements.asyncHelperStartSync
+ : commonElements.asyncHelperStart;
+ var completerConstructor = startAsyncSynchronously
+ ? commonElements.asyncAwaitCompleterConstructor
+ : commonElements.syncCompleterConstructor;
rewriter = new AsyncRewriter(reporter, element,
- asyncStart:
- emitter.staticFunctionAccess(commonElements.asyncHelperStart),
+ asyncStart: emitter.staticFunctionAccess(startFunction),
asyncAwait:
emitter.staticFunctionAccess(commonElements.asyncHelperAwait),
asyncReturn:
@@ -1181,8 +1191,8 @@
asyncRethrow:
emitter.staticFunctionAccess(commonElements.asyncHelperRethrow),
wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
- completerFactory: emitter
- .staticFunctionAccess(commonElements.syncCompleterConstructor),
+ completerFactory:
+ emitter.staticFunctionAccess(completerConstructor),
safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
bodyName: namer.deriveAsyncBodyName(name));
break;
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 28360bc..3d0fd4f 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -8,6 +8,7 @@
import '../common_elements.dart' show CommonElements, ElementEnvironment;
import '../elements/types.dart' show InterfaceType;
import '../elements/entities.dart';
+import '../options.dart' show CompilerOptions;
import '../universe/selector.dart';
import '../universe/world_impact.dart'
show WorldImpact, WorldImpactBuilder, WorldImpactBuilderImpl;
@@ -88,9 +89,10 @@
/// The JavaScript backend dependencies for various features.
class BackendImpacts {
+ final CompilerOptions _options;
final CommonElements _commonElements;
- BackendImpacts(this._commonElements);
+ BackendImpacts(this._options, this._commonElements);
BackendImpact _getRuntimeTypeArgument;
@@ -126,15 +128,24 @@
BackendImpact _asyncBody;
BackendImpact get asyncBody {
- return _asyncBody ??= new BackendImpact(staticUses: [
- _commonElements.asyncHelperStart,
+ var staticUses = [
_commonElements.asyncHelperAwait,
_commonElements.asyncHelperReturn,
_commonElements.asyncHelperRethrow,
- _commonElements.syncCompleterConstructor,
_commonElements.streamIteratorConstructor,
_commonElements.wrapBody
- ]);
+ ];
+ var instantiantedClasses = <ClassEntity>[];
+ if (_options.startAsyncSynchronously) {
+ staticUses.add(_commonElements.asyncAwaitCompleterConstructor);
+ staticUses.add(_commonElements.asyncHelperStartSync);
+ instantiantedClasses.add(_commonElements.asyncAwaitCompleter);
+ } else {
+ staticUses.add(_commonElements.syncCompleterConstructor);
+ staticUses.add(_commonElements.asyncHelperStart);
+ }
+ return _asyncBody ??= new BackendImpact(
+ staticUses: staticUses, instantiatedClasses: instantiantedClasses);
}
BackendImpact _syncStarBody;
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 4cd7014..44bc1a5 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -1949,12 +1949,15 @@
}
jsAst.Comment buildGeneratedBy() {
- List<String> options = [];
- if (_closedWorld.backendUsage.isMirrorsUsed) {
- options.add('mirrors');
- }
- if (compiler.options.useContentSecurityPolicy) options.add("CSP");
- return new jsAst.Comment(generatedBy(compiler, flavor: options.join(", ")));
+ StringBuffer flavor = new StringBuffer();
+ flavor.write(compiler.options.useKernel ? 'kernel FE' : 'ast FE');
+ if (compiler.options.strongMode) flavor.write(', strong');
+ if (compiler.options.trustPrimitives) flavor.write(', trust primitives');
+ if (compiler.options.trustTypeAnnotations) flavor.write(', trust types');
+ flavor.write(', full emitter');
+ if (compiler.options.useContentSecurityPolicy) flavor.write(', CSP');
+ if (_closedWorld.backendUsage.isMirrorsUsed) flavor.write(', mirrors');
+ return new jsAst.Comment(generatedBy(compiler, flavor: '$flavor'));
}
void outputDeferredMap() {
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 86f5d3d..0509d2e 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -228,10 +228,14 @@
/// Generates a simple header that provides the compiler's build id.
js.Comment buildGeneratedBy() {
- String flavor = compiler.options.useContentSecurityPolicy
- ? 'fast startup, CSP'
- : 'fast startup';
- return new js.Comment(generatedBy(compiler, flavor: flavor));
+ StringBuffer flavor = new StringBuffer();
+ flavor.write(compiler.options.useKernel ? 'kernel FE' : 'ast FE');
+ if (compiler.options.strongMode) flavor.write(', strong');
+ if (compiler.options.trustPrimitives) flavor.write(', trust primitives');
+ if (compiler.options.trustTypeAnnotations) flavor.write(', trust types');
+ flavor.write(', fast startup emitter');
+ if (compiler.options.useContentSecurityPolicy) flavor.write(', CSP');
+ return new js.Comment(generatedBy(compiler, flavor: '$flavor'));
}
/// Writes all deferred fragment's code into files.
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
index 310092b..0e31b7c 100644
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
@@ -25,14 +25,6 @@
/// used for RTI.
Set<ClassEntity> _rtiNeededClasses;
- /// The required checks on classes.
- // TODO(johnniwinther): Currently this is wrongfully computed twice. Once
- // in [computeRequiredTypeChecks] and once in [computeRtiNeededClasses]. The
- // former is stored in [RuntimeTypeChecks] and used in the
- // [TypeRepresentationGenerator] and the latter is used to compute the
- // classes needed for RTI.
- TypeChecks _requiredChecks;
-
final CodegenWorldBuilder _codegenWorldBuilder;
final ClosedWorld _closedWorld;
@@ -57,14 +49,6 @@
return _rtiNeededClasses;
}
- TypeChecks get requiredChecks {
- assert(
- _requiredChecks != null,
- failedAt(NO_LOCATION_SPANNABLE,
- "requiredChecks has not been computed yet."));
- return _requiredChecks;
- }
-
/**
* Returns the classes with constructors used as a 'holder' in
* [emitRuntimeTypeSupport].
@@ -110,10 +94,8 @@
// 2. Add classes that are referenced by substitutions in object checks and
// their superclasses.
- _requiredChecks = rtiSubstitutions.computeChecks(
- rtiNeededClasses, rtiChecks.checkedClasses);
- Set<ClassEntity> classesUsedInSubstitutions =
- rtiSubstitutions.getClassesUsedInSubstitutions(requiredChecks);
+ Set<ClassEntity> classesUsedInSubstitutions = rtiSubstitutions
+ .getClassesUsedInSubstitutions(rtiChecks.requiredChecks);
addClassesWithSuperclasses(classesUsedInSubstitutions);
// 3. Add classes that contain checked generic function types. These are
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index df8f603..d1792a6 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -170,6 +170,10 @@
return createClass(library, cls.name, isAbstract: cls.isAbstract);
}
+ TypedefEntity convertTypedef(LibraryEntity library, IndexedTypedef typedef) {
+ return createTypedef(library, typedef.name);
+ }
+
MemberEntity convertMember(
LibraryEntity library, ClassEntity cls, IndexedMember member) {
Name memberName = new Name(member.memberName.text, library,
@@ -261,7 +265,8 @@
visitList(type.optionalParameterTypes, converter),
type.namedParameters,
visitList(type.namedParameterTypes, converter),
- type.typeVariables);
+ type.typeVariables,
+ visitTypedefType(type.typedefType, converter));
}
@override
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 17b9935..6efd179 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -88,6 +88,7 @@
Entity toBackendEntity(Entity entity) {
if (entity is ClassEntity) return map.toBackendClass(entity);
if (entity is MemberEntity) return map.toBackendMember(entity);
+ if (entity is TypedefEntity) return map.toBackendTypedef(entity);
if (entity is TypeVariableEntity) {
return map.toBackendTypeVariable(entity);
}
@@ -683,6 +684,11 @@
var args = type.typeArguments.map(_handleType).toList();
return new InterfaceType(element, args);
}
+ if (type is TypedefType) {
+ var element = toBackendEntity(type.element);
+ var args = type.typeArguments.map(_handleType).toList();
+ return new TypedefType(element, args);
+ }
// TODO(redemption): handle other types.
return type;
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 9e190de..f71d749 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -462,7 +462,7 @@
}
return new FunctionType(returnType, parameterTypes, optionalParameterTypes,
- namedParameters, namedParameterTypes, typeVariables);
+ namedParameters, namedParameterTypes, typeVariables, null);
}
@override
@@ -592,10 +592,15 @@
..sort((a, b) => a.compareTo(b));
List<DartType> namedParameterTypes =
new List.filled(namedParameters.length, dynamic);
- data.callType = new FunctionType(dynamic, requiredParameterTypes,
- optionalParameterTypes, namedParameters, namedParameterTypes,
+ data.callType = new FunctionType(
+ dynamic,
+ requiredParameterTypes,
+ optionalParameterTypes,
+ namedParameters,
+ namedParameterTypes,
// TODO(johnniwinther): Generate existential types here.
- const <FunctionTypeVariable>[]);
+ const <FunctionTypeVariable>[],
+ null);
} else {
// The function type is not valid.
data.callType = const DynamicType();
@@ -1650,6 +1655,10 @@
}
index++;
}
+
+ DartType typedefType =
+ node.typedef == null ? null : elementMap.getTypedefType(node.typedef);
+
FunctionType type = new FunctionType(
visitType(node.returnType),
visitTypes(node.positionalParameters
@@ -1660,7 +1669,8 @@
.toList()),
node.namedParameters.map((n) => n.name).toList(),
node.namedParameters.map((n) => visitType(n.type)).toList(),
- typeVariables ?? const <FunctionTypeVariable>[]);
+ typeVariables ?? const <FunctionTypeVariable>[],
+ typedefType);
for (ir.TypeParameter typeParameter in node.typeParameters) {
currentFunctionTypeParameters.remove(typeParameter);
}
@@ -1880,7 +1890,7 @@
@override
bool isNamedMixinApplication(ClassEntity cls) {
return elementMap._isMixinApplication(cls) &&
- elementMap._isUnnamedMixinApplication(cls);
+ !elementMap._isUnnamedMixinApplication(cls);
}
@override
@@ -2073,6 +2083,10 @@
return _backend._members.getEntity(member.memberIndex);
}
+ TypedefEntity toBackendTypedef(covariant IndexedTypedef typedef) {
+ return _backend._typedefs.getEntity(typedef.typedefIndex);
+ }
+
TypeVariableEntity toBackendTypeVariable(TypeVariableEntity typeVariable) {
if (typeVariable is KLocalTypeVariable) {
failedAt(
@@ -2134,6 +2148,25 @@
_classMap[env.cls] = _classes.register(newClass, data.copy(), env);
assert(newClass.classIndex == oldClass.classIndex);
}
+ for (int typedefIndex = 0;
+ typedefIndex < _elementMap._typedefs.length;
+ typedefIndex++) {
+ IndexedTypedef oldTypedef = _elementMap._typedefs.getEntity(typedefIndex);
+ TypedefData data = _elementMap._typedefs.getData(oldTypedef);
+ IndexedLibrary oldLibrary = oldTypedef.library;
+ LibraryEntity newLibrary = _libraries.getEntity(oldLibrary.libraryIndex);
+ IndexedTypedef newTypedef = convertTypedef(newLibrary, oldTypedef);
+ _typedefMap[data.node] = _typedefs.register(
+ newTypedef,
+ new TypedefData(
+ data.node,
+ newTypedef,
+ new TypedefType(
+ newTypedef,
+ new List<DartType>.filled(
+ data.node.typeParameters.length, const DynamicType()))));
+ assert(newTypedef.typedefIndex == oldTypedef.typedefIndex);
+ }
for (int memberIndex = 0;
memberIndex < _elementMap._members.length;
memberIndex++) {
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index bdcd32a..ed2fb89 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -349,8 +349,8 @@
int mixinMemberCount = 0;
if (cls.mixedInClass != null) {
- addFields(cls.mixedInClass, includeStatic: false);
- addProcedures(cls.mixedInClass, includeStatic: false);
+ addFields(cls.mixedInClass.mixin, includeStatic: false);
+ addProcedures(cls.mixedInClass.mixin, includeStatic: false);
mergeSort(members, compare: orderByFileOffset);
mixinMemberCount = members.length;
}
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 129af4d..db380bc 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -276,6 +276,9 @@
/// Strip option used by dart2dart.
final List<String> strips;
+ /// Whether to start `async` functions synchronously.
+ final bool startAsyncSynchronously;
+
/// Create an options object by parsing flags from [options].
factory CompilerOptions.parse(
{Uri entryPoint,
@@ -356,6 +359,7 @@
useMultiSourceInfo: _hasOption(options, Flags.useMultiSourceInfo),
useNewSourceInfo: _hasOption(options, Flags.useNewSourceInfo),
useStartupEmitter: _hasOption(options, Flags.fastStartup),
+ startAsyncSynchronously: _hasOption(options, Flags.syncAsync),
verbose: _hasOption(options, Flags.verbose));
}
@@ -421,6 +425,7 @@
bool useMultiSourceInfo: false,
bool useNewSourceInfo: false,
bool useStartupEmitter: false,
+ bool startAsyncSynchronously: false,
bool verbose: false}) {
// TODO(sigmund): should entrypoint be here? should we validate it is not
// null? In unittests we use the same compiler to analyze or build multiple
@@ -504,6 +509,7 @@
useMultiSourceInfo: useMultiSourceInfo,
useNewSourceInfo: useNewSourceInfo,
useStartupEmitter: useStartupEmitter,
+ startAsyncSynchronously: startAsyncSynchronously,
verbose: verbose);
}
@@ -559,6 +565,7 @@
this.useMultiSourceInfo: false,
this.useNewSourceInfo: false,
this.useStartupEmitter: false,
+ this.startAsyncSynchronously: false,
this.verbose: false})
: _shownPackageWarnings = shownPackageWarnings;
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index c2d433a..f920e3c 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -462,10 +462,7 @@
parameterNodes = parameterNodes.tail;
});
addDeferredAction(enclosingElement, () {
- // Use function.functionSignature instead of functionSignature because
- // the signature may have changed.
- // TODO(het): Fix this so we can use just 'functionSignature' here.
- function.functionSignature.forEachOptionalParameter((_parameter) {
+ functionSignature.forEachOptionalParameter((_parameter) {
ParameterElementX parameter = _parameter;
parameter.constant =
resolver.constantCompiler.compileConstant(parameter);
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 4762bc11..ed4c280 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -589,6 +589,8 @@
/// until after we finish resolving the current declaration.
bool isResolvingTypeDeclaration = false;
+ bool isPostProcessingTypeDeclaration = false;
+
/// Classes found in type annotations while resolving a type declaration.
///
/// These are stored here so that they may be resolved after the original
@@ -621,13 +623,18 @@
.removeFirst()
.ensureResolved(resolution);
}
- while (pendingClassesToBePostProcessed.isNotEmpty) {
- _postProcessClassElement(
- pendingClassesToBePostProcessed.removeFirst());
+ if (!isPostProcessingTypeDeclaration) {
+ isPostProcessingTypeDeclaration = true;
+ while (pendingClassesToBePostProcessed.isNotEmpty) {
+ _postProcessClassElement(
+ pendingClassesToBePostProcessed.removeFirst());
+ }
+ isPostProcessingTypeDeclaration = false;
}
} while (pendingClassesToBeResolved.isNotEmpty);
assert(pendingClassesToBeResolved.isEmpty);
- assert(pendingClassesToBePostProcessed.isEmpty);
+ assert(pendingClassesToBePostProcessed.isEmpty ||
+ isPostProcessingTypeDeclaration);
}
return result;
});
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 0259a5f..cd60f2f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -1232,10 +1232,6 @@
var genericCall = _callHelper('generic(#)', [genericArgs]);
- if (element.library.isDartAsync &&
- (element.name == "Future" || element.name == "_Future")) {
- genericCall = _callHelper('flattenFutures(#)', [genericCall]);
- }
var genericName = _emitTopLevelNameNoInterop(element, suffix: '\$');
return js.statement('{ # = #; # = #(); }',
[genericName, genericCall, _emitTopLevelName(element), genericName]);
@@ -2146,8 +2142,7 @@
var type = _emitAnnotatedFunctionType(
reifiedType, annotationNode?.metadata,
parameters: annotationNode?.parameters?.parameters,
- nameType: false,
- definite: true);
+ nameType: false);
var property = new JS.Property(_declareMemberName(method), type);
if (method.isStatic) {
staticMethods.add(property);
@@ -2209,8 +2204,7 @@
var type = _emitAnnotatedFunctionType(
reifiedType, annotationNode?.metadata,
parameters: annotationNode?.parameters?.parameters,
- nameType: false,
- definite: true);
+ nameType: false);
var property = new JS.Property(_declareMemberName(accessor), type);
if (isStatic) {
@@ -2266,8 +2260,7 @@
var type = _emitAnnotatedFunctionType(
ctor.type, annotationNode?.metadata,
parameters: annotationNode?.parameters?.parameters,
- nameType: false,
- definite: true);
+ nameType: false);
constructors.add(new JS.Property(memberName, type));
}
}
@@ -2459,58 +2452,60 @@
JS.Statement _initializeFields(List<VariableDeclaration> fieldDecls,
[ConstructorDeclaration ctor]) {
// Run field initializers if they can have side-effects.
- var fields = new Map<FieldElement, JS.Expression>();
- var unsetFields = new Map<FieldElement, VariableDeclaration>();
- for (var fieldNode in fieldDecls) {
- var element = fieldNode.element as FieldElement;
- if (_constants.isFieldInitConstant(fieldNode)) {
- unsetFields[element] = fieldNode;
- } else {
- fields[element] = _visitInitializer(fieldNode);
- }
+ Set<FieldElement> ctorFields;
+ if (ctor != null) {
+ ctorFields = ctor.initializers
+ .map((c) => c is ConstructorFieldInitializer
+ ? c.fieldName.staticElement as FieldElement
+ : null)
+ .toSet()
+ ..remove(null);
}
- // Initialize fields from `this.fieldName` parameters.
+ var body = <JS.Statement>[];
+ emitFieldInit(FieldElement f, Expression initializer,
+ [AstNode sourceInfo]) {
+ var access =
+ _classProperties.virtualFields[f] ?? _declareMemberName(f.getter);
+ var jsInit = _visitInitializer(initializer, f);
+ body.add(jsInit
+ .toAssignExpression(js.call('this.#', [access])
+ ..sourceInformation = sourceInfo == null ? f : null)
+ .toStatement()
+ ..sourceInformation = sourceInfo);
+ }
+
+ for (var field in fieldDecls) {
+ var f = field.element;
+ if (f.isStatic) continue;
+ var init = field.initializer;
+ if (init == null ||
+ ctorFields != null &&
+ ctorFields.contains(f) &&
+ _constants.isFieldInitConstant(field)) {
+ continue;
+ }
+ emitFieldInit(f, init);
+ }
+
+ // Run constructor field initializers such as `: foo = bar.baz`
if (ctor != null) {
for (var p in ctor.parameters.parameters) {
var element = p.element;
if (element is FieldFormalParameterElement) {
- fields[element.field] = _emitSimpleIdentifier(p.identifier);
+ emitFieldInit(element.field, p.identifier);
}
}
- // Run constructor field initializers such as `: foo = bar.baz`
for (var init in ctor.initializers) {
if (init is ConstructorFieldInitializer) {
- var element = init.fieldName.staticElement as FieldElement;
- fields[element] = _visitAndMarkExpression(init.expression);
+ emitFieldInit(init.fieldName.staticElement, init.expression, init);
} else if (init is AssertInitializer) {
- throw new UnimplementedError(
- 'Assert initializers are not implemented. '
- 'See https://github.com/dart-lang/sdk/issues/27809');
+ body.add(_emitAssert(init.condition, init.message));
}
}
}
- for (var f in fields.keys) unsetFields.remove(f);
-
- // Initialize all remaining fields
- unsetFields.forEach((element, fieldNode) {
- var value =
- _visitExpression(fieldNode.initializer) ?? new JS.LiteralNull();
- fields[element] = value..sourceInformation = fieldNode.initializer;
- });
-
- var body = <JS.Statement>[];
- fields.forEach((FieldElement e, JS.Expression initialValue) {
- JS.Expression access =
- _classProperties.virtualFields[e] ?? _declareMemberName(e.getter);
- body.add(initialValue
- .toAssignExpression(
- js.call('this.#', [access])..sourceInformation = e)
- .toStatement());
- });
-
return JS.Statement.from(body);
}
@@ -2725,8 +2720,8 @@
bool _executesAtTopLevel(AstNode node) {
var ancestor = node.getAncestor((n) =>
n is FunctionBody ||
- (n is FieldDeclaration && n.staticKeyword == null) ||
- (n is ConstructorDeclaration && n.constKeyword == null));
+ n is FieldDeclaration && n.staticKeyword == null ||
+ n is ConstructorDeclaration && n.constKeyword == null);
return ancestor == null;
}
@@ -2747,12 +2742,8 @@
JS.Expression _emitFunctionTagged(JS.Expression fn, DartType type,
{topLevel: false}) {
var lazy = topLevel && !_typeIsLoaded(type);
- var typeRep = _emitFunctionType(type, definite: true);
- if (lazy) {
- return _callHelper('lazyFn(#, () => #)', [fn, typeRep]);
- } else {
- return _callHelper('fn(#, #)', [fn, typeRep]);
- }
+ var typeRep = _emitFunctionType(type);
+ return _callHelper(lazy ? 'lazyFn(#, () => #)' : 'fn(#, #)', [fn, typeRep]);
}
/// Emits an arrow FunctionExpression node.
@@ -3214,9 +3205,7 @@
/// Emit the pieces of a function type, as an array of return type,
/// regular args, and optional/named args.
JS.Expression _emitFunctionType(FunctionType type,
- {List<FormalParameter> parameters,
- bool nameType: true,
- definite: false}) {
+ {List<FormalParameter> parameters, bool nameType: true}) {
var parameterTypes = type.normalParameterTypes;
var optionalTypes = type.optionalParameterTypes;
var namedTypes = type.namedParameterTypes;
@@ -3255,27 +3244,25 @@
typeParts = [addTypeFormalsAsParameters(typeParts)];
- helperCall = definite ? 'gFnType(#)' : 'gFnTypeFuzzy(#)';
+ helperCall = 'gFnType(#)';
// If any explicit bounds were passed, emit them.
if (typeFormals.any((t) => t.bound != null)) {
var bounds = typeFormals.map((t) => _emitType(t.type.bound)).toList();
typeParts.add(addTypeFormalsAsParameters(bounds));
}
} else {
- helperCall = definite ? 'fnType(#)' : 'fnTypeFuzzy(#)';
+ helperCall = 'fnType(#)';
}
fullType = _callHelper(helperCall, [typeParts]);
if (!nameType) return fullType;
- return _typeTable.nameType(type, fullType, definite: definite);
+ return _typeTable.nameType(type, fullType);
}
JS.Expression _emitAnnotatedFunctionType(
FunctionType type, List<Annotation> metadata,
- {List<FormalParameter> parameters,
- bool nameType: true,
- bool definite: false}) {
- var result = _emitFunctionType(type,
- parameters: parameters, nameType: nameType, definite: definite);
+ {List<FormalParameter> parameters, bool nameType: true}) {
+ var result =
+ _emitFunctionType(type, parameters: parameters, nameType: nameType);
return _emitAnnotatedResult(result, metadata);
}
@@ -3639,7 +3626,9 @@
}
if (targetType.isDartCoreFunction || targetType.isDynamic) {
// TODO(vsm): Can a call method take generic type parameters?
- return _emitDynamicInvoke(node, _visitExpression(target),
+ return _emitDynamicInvoke(
+ _visitExpression(target),
+ _emitInvokeTypeArguments(node),
_emitArgumentList(node.argumentList));
}
}
@@ -3722,6 +3711,10 @@
JS.Expression jsTarget = _emitTarget(target, element, isStatic);
if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) {
+ if (jsTarget is JS.Super) {
+ jsTarget = _emitTargetAccess(jsTarget, jsName, element);
+ return _emitDynamicInvoke(jsTarget, typeArgs, args);
+ }
if (typeArgs != null) {
return _callHelper('#(#, [#], #, #)', [
_emitDynamicOperationName('dgsend'),
@@ -3748,9 +3741,8 @@
return new JS.Call(jsTarget, args);
}
- JS.Expression _emitDynamicInvoke(
- InvocationExpression node, JS.Expression fn, List<JS.Expression> args) {
- var typeArgs = _emitInvokeTypeArguments(node);
+ JS.Expression _emitDynamicInvoke(JS.Expression fn,
+ List<JS.Expression> typeArgs, List<JS.Expression> args) {
if (typeArgs != null) {
return _callHelper('dgcall(#, [#], #)', [fn, typeArgs, args]);
} else {
@@ -3822,10 +3814,10 @@
}
var fn = _visitExpression(function);
var args = _emitArgumentList(node.argumentList);
- if (isDynamicInvoke(function)) {
- return _emitDynamicInvoke(node, fn, args);
- }
var typeArgs = _emitInvokeTypeArguments(node);
+ if (isDynamicInvoke(function)) {
+ return _emitDynamicInvoke(fn, typeArgs, args);
+ }
if (typeArgs != null) args.insertAll(0, typeArgs);
return new JS.Call(fn, args);
}
@@ -4087,9 +4079,11 @@
new JS.EmptyStatement();
@override
- JS.Statement visitAssertStatement(AssertStatement node) {
+ JS.Statement visitAssertStatement(AssertStatement node) =>
+ _emitAssert(node.condition, node.message);
+
+ JS.Statement _emitAssert(Expression condition, Expression message) {
// TODO(jmesserly): only emit in checked mode.
- var condition = node.condition;
var conditionType = condition.staticType;
var jsCondition = _visitExpression(condition);
@@ -4105,7 +4099,7 @@
return js.statement(' if (!#) #.assertFailed(#);', [
jsCondition,
_runtimeModule,
- node.message != null ? [_visitExpression(node.message)] : []
+ message != null ? [_visitExpression(message)] : []
]);
}
@@ -4217,7 +4211,8 @@
var name =
new JS.Identifier(node.name.name, type: emitTypeRef(node.element.type))
..sourceInformation = node.name;
- return new JS.VariableInitialization(name, _visitInitializer(node));
+ return new JS.VariableInitialization(
+ name, _visitInitializer(node.initializer, node.element));
}
/// Emits a list of top-level field.
@@ -4242,8 +4237,10 @@
init is InstanceCreationExpression &&
isSdkInternalRuntime(init.staticElement.library)) {
_moduleItems.add(closureAnnotate(
- js.statement('# = #;',
- [_emitTopLevelName(field.element), _visitInitializer(field)]),
+ js.statement('# = #;', [
+ _emitTopLevelName(field.element),
+ _visitInitializer(field.initializer, field.element)
+ ]),
field.element,
field));
} else {
@@ -4253,14 +4250,12 @@
return lazyFields;
}
- JS.Expression _visitInitializer(VariableDeclaration node) {
- var init = node.initializer;
+ JS.Expression _visitInitializer(Expression init, Element variable) {
// explicitly initialize to null, to avoid getting `undefined`.
// TODO(jmesserly): do this only for vars that aren't definitely assigned.
if (init == null) return new JS.LiteralNull();
- var value = _annotatedNullCheck(node.element)
- ? notNull(init)
- : _visitExpression(init);
+ var value =
+ _annotatedNullCheck(variable) ? notNull(init) : _visitExpression(init);
return value..sourceInformation = init;
}
@@ -4278,8 +4273,8 @@
accessors.add(closureAnnotate(
new JS.Method(
access,
- js.call('function() { return #; }', _visitInitializer(node))
- as JS.Fun,
+ js.call('function() { return #; }',
+ _visitInitializer(node.initializer, node.element)) as JS.Fun,
isGetter: true),
_findAccessor(element, getter: true),
node));
@@ -5595,7 +5590,7 @@
@override
JS.Expression visitListLiteral(ListLiteral node) {
var elementType = (node.staticType as InterfaceType).typeArguments[0];
- if (node.constKeyword == null) {
+ if (!node.isConst) {
return _emitList(elementType, _visitExpressionList(node.elements));
}
return _cacheConst(
@@ -5633,7 +5628,7 @@
return new JS.ArrayInitializer(entries);
}
- if (node.constKeyword == null) {
+ if (!node.isConst) {
var mapType = _emitMapImplType(node.staticType);
if (node.entries.isEmpty) {
return js.call('new #.new()', [mapType]);
diff --git a/pkg/dev_compiler/lib/src/analyzer/context.dart b/pkg/dev_compiler/lib/src/analyzer/context.dart
index 8c6e135..12fb82d 100644
--- a/pkg/dev_compiler/lib/src/analyzer/context.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/context.dart
@@ -63,7 +63,9 @@
String dartSdkSummaryPath,
List<String> summaryPaths}) {
var contextBuilderOptions = new ContextBuilderOptions()
- ..defaultOptions = (new AnalysisOptionsImpl()..strongMode = true)
+ ..defaultOptions = (new AnalysisOptionsImpl()
+ ..strongMode = true
+ ..previewDart2 = true)
..dartSdkSummaryPath = dartSdkSummaryPath;
return new AnalyzerOptions._(
@@ -76,6 +78,8 @@
{String dartSdkSummaryPath, List<String> summaryPaths}) {
var contextBuilderOptions = createContextBuilderOptions(args,
strongMode: true, trackCacheDependencies: false);
+ (contextBuilderOptions.defaultOptions as AnalysisOptionsImpl).previewDart2 =
+ true;
var dartSdkPath = args['dart-sdk'] ?? getSdkDir().path;
@@ -164,12 +168,13 @@
{ResourceProvider resourceProvider}) {
resourceProvider ??= PhysicalResourceProvider.INSTANCE;
UriResolver packageResolver() {
- ContextBuilderOptions builderOptions = new ContextBuilderOptions();
+ var builderOptions = new ContextBuilderOptions();
if (options.packageRoot != null) {
builderOptions.defaultPackagesDirectoryPath = options.packageRoot;
}
- ContextBuilder builder = new ContextBuilder(resourceProvider, null, null,
+ var builder = new ContextBuilder(resourceProvider, null, null,
options: builderOptions);
+
return new PackageMapUriResolver(resourceProvider,
builder.convertPackagesToMap(builder.createPackageMap('')));
}
diff --git a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
index 7c101ac..f497fc4 100644
--- a/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/compiler/type_utilities.dart
@@ -158,27 +158,20 @@
/// Generator variable names for hoisted types.
final _GeneratorTable _generators;
- /// Generator variable names for hoisted definite function types.
- final _GeneratorTable _definiteGenerators;
-
/// Mapping from type parameters to the types which must have their
/// cache/generator variables discharged at the binding site for the
/// type variable since the type definition depends on the type
/// parameter.
final _scopeDependencies = <TypeParameterElement, List<DartType>>{};
- TypeTable(JS.Identifier runtime)
- : _generators = new _GeneratorTable(runtime),
- _definiteGenerators = new _GeneratorTable(runtime);
+ TypeTable(JS.Identifier runtime) : _generators = new _GeneratorTable(runtime);
/// Emit a list of statements declaring the cache variables and generator
/// definitions tracked by the table. If [formals] is present, only
/// emit the definitions which depend on the formals.
List<JS.Statement> discharge([List<TypeParameterElement> formals]) {
var filter = formals?.expand((p) => _scopeDependencies[p] ?? <DartType>[]);
- var stmts = [_generators, _definiteGenerators]
- .expand((c) => c.discharge(filter))
- .toList();
+ var stmts = [_generators].expand((c) => c.discharge(filter)).toList();
formals?.forEach(_scopeDependencies.remove);
return stmts;
}
@@ -226,9 +219,8 @@
/// The boolean parameter [definite] distinguishes between definite function
/// types and other types (since the same DartType may have different
/// representations as definite and indefinite function types).
- JS.Expression nameType(DartType type, JS.Expression typeRep,
- {bool definite: false}) {
- var table = definite ? _definiteGenerators : _generators;
+ JS.Expression nameType(DartType type, JS.Expression typeRep) {
+ var table = _generators;
if (!table.isNamed(type)) {
if (recordScopeDependencies(type)) return typeRep;
}
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 42d51ee..4f1c302 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -579,10 +579,6 @@
var genericCall = _callHelper('generic(#)', [genericArgs]);
- if (getLibrary(c) == coreTypes.asyncLibrary &&
- (name == "Future" || name == "_Future")) {
- genericCall = _callHelper('flattenFutures(#)', [genericCall]);
- }
var genericName = _emitTopLevelNameNoInterop(c, suffix: '\$');
return js.statement('{ # = #; # = #(); }',
[genericName, genericCall, _emitTopLevelName(c), genericName]);
@@ -1452,7 +1448,6 @@
/// 4. initialize fields not covered in 1-3
JS.Statement _initializeFields(List<Field> fields, [Constructor ctor]) {
// Run field initializers if they can have side-effects.
-
Set<Field> ctorFields;
if (ctor != null) {
ctorFields = ctor.initializers
@@ -1462,8 +1457,7 @@
}
var body = <JS.Statement>[];
- emitFieldInit(Field f, Expression initializer,
- [TreeNode sourceInfo = null]) {
+ emitFieldInit(Field f, Expression initializer, [TreeNode sourceInfo]) {
var access = _classProperties.virtualFields[f] ?? _declareMemberName(f);
var jsInit = _visitInitializer(initializer, f.annotations);
body.add(jsInit
@@ -1482,7 +1476,7 @@
_constants.isConstant(init)) {
continue;
}
- emitFieldInit(f, f.initializer);
+ emitFieldInit(f, init);
}
// Run constructor field initializers such as `: foo = bar.baz`
@@ -1670,9 +1664,8 @@
if (member.isGetter) return [];
var enclosingClass = member.enclosingClass;
- var superMember = (member.forwardingStubSuperTarget ??
- member.forwardingStubInterfaceTarget)
- ?.asMember;
+ var superMember = member.forwardingStubSuperTarget ??
+ member.forwardingStubInterfaceTarget;
if (superMember == null) return [];
diff --git a/pkg/dev_compiler/tool/ddc b/pkg/dev_compiler/tool/ddc
index cc8f410..9846cd6 100755
--- a/pkg/dev_compiler/tool/ddc
+++ b/pkg/dev_compiler/tool/ddc
@@ -60,6 +60,12 @@
shift
fi
+SYNC_ASYNC=false
+if [ "$1" = "--sync-async" ]; then
+ SYNC_ASYNC=true
+ shift
+fi
+
BASENAME=$( basename "${1%.*}")
LIBROOT=$(cd $( dirname "${1%.*}") && pwd)
@@ -104,6 +110,7 @@
let sdk = require(\"dart_sdk\");
let main = require(\"./$BASENAME\").$BASENAME.main;
sdk.dart.ignoreWhitelistedErrors(false);
+ if ($SYNC_ASYNC) sdk.dart.setStartAsyncSynchronously();
try {
sdk._isolate_helper.startRootIsolate(main, []);
} catch(e) {
diff --git a/pkg/dev_compiler/tool/ddw b/pkg/dev_compiler/tool/ddw
index 9169c84..dfae2a2 100755
--- a/pkg/dev_compiler/tool/ddw
+++ b/pkg/dev_compiler/tool/ddw
@@ -1,7 +1,6 @@
#!/bin/bash
#
-# Compiles code with DDC and runs the resulting code in node.js with devtool,
-# an Electron-based debugger and browser environment.
+# Compiles code with DDC and runs the resulting code in node.js.
#
# The first script supplied should be the one with `main()`.
#
@@ -9,7 +8,51 @@
# inspection, modification or rerunning the code.
set -e
-DDC_PATH=$( cd $( dirname "${BASH_SOURCE[0]}" )/.. && pwd )
+function follow_links() {
+ file="$1"
+ while [ -h "$file" ]; do
+ file="$(readlink "$file")"
+ done
+ echo "$file"
+}
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+SDK_DIR="$( cd "${PROG_NAME%/*}/../../.."; pwd -P)"
+
+if [[ `uname` == 'Darwin' ]];
+then
+ OUT_DIR="$SDK_DIR"/xcodebuild
+else
+ OUT_DIR="$SDK_DIR"/out
+fi
+
+if [ -z "$DART_CONFIGURATION" ];
+then
+ DIRS=$( ls "$OUT_DIR" )
+ # list of possible configurations in decreasing desirability
+ CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
+ "ReleaseARM" "ReleaseARM64" "ReleaseARMV5TE"
+ "DebugARM" "DebugARM64" "DebugARMV5TE")
+ DART_CONFIGURATION="None"
+ for CONFIG in ${CONFIGS[*]}
+ do
+ for DIR in $DIRS;
+ do
+ if [ "$CONFIG" = "$DIR" ];
+ then
+ # choose most desirable configuration that is available and break
+ DART_CONFIGURATION="$DIR"
+ break 2
+ fi
+ done
+ done
+ if [ "$DART_CONFIGURATION" = "None" ]
+ then
+ echo "No valid dart configuration found in $OUT_DIR"
+ exit 1
+ fi
+fi
+
+GEN_DIR="$OUT_DIR"/"$DART_CONFIGURATION"/gen/utils/dartdevc
KERNEL=false
if [ "$1" = "-k" ]; then
@@ -20,21 +63,31 @@
BASENAME=$( basename "${1%.*}")
LIBROOT=$(cd $( dirname "${1%.*}") && pwd)
-# TODO(vsm): Change this to use the regular built version of the summaries
-# and the SDK.
-export NODE_PATH=$DDC_PATH/gen/sdk/common:$LIBROOT:$NODE_PATH
-
-# Build the SDK in a place where we can find it if it's not already there.
-if [ ! -e $DDC_PATH/gen/sdk/ddc_sdk.sum ]; then
- $DDC_PATH/tool/build_sdk.sh
-fi
+export NODE_PATH=$GEN_DIR/js/common:$LIBROOT:$NODE_PATH
if [ "$KERNEL" = true ]; then
- dart -c $DDC_PATH/bin/dartdevk.dart --modules=node \
- -o $BASENAME.js $*
+
+ if [ ! -e $GEN_DIR/kernel/ddc_sdk.dill ]; then
+ echo "DDC SDK must be built first, please run:"
+ echo " pushd $SDKDIR"
+ echo " ./tools/build.py -m release dartdevc_sdk_kernel_summary"
+ exit 1
+ fi
+
+ dart -c $SDK_DIR/pkg/dev_compiler/bin/dartdevk.dart --modules=node \
+ --dart-sdk-summary=$GEN_DIR/kernel/ddc_sdk.dill \
+ -o $LIBROOT/$BASENAME.js $*
else
- dart -c $DDC_PATH/bin/dartdevc.dart --modules=node --library-root=$LIBROOT \
- --dart-sdk-summary=$DDC_PATH/gen/sdk/ddc_sdk.sum \
+
+ if [ ! -e $GEN_DIR/ddc_sdk.sum ]; then
+ echo "DDC SDK must be built first, please run:"
+ echo " pushd $SDKDIR"
+ echo " ./tools/build.py -m release dartdevc_sdk"
+ exit 1
+ fi
+
+ dart -c $SDK_DIR/pkg/dev_compiler/bin/dartdevc.dart --modules=node \
+ --library-root=$LIBROOT --dart-sdk-summary=$GEN_DIR/ddc_sdk.sum \
-o $LIBROOT/$BASENAME.js $*
fi
@@ -45,7 +98,7 @@
const originalResolveFilename = Module._resolveFilename;
Module._resolveFilename = function (request, parent, isMain) {
let paths = parent.paths;
- const ddcPath = \"$DDC_PATH/gen/sdk/common\";
+ const ddcPath = \"$GEN_DIR/js/common\";
if (paths[0] != ddcPath) {
paths.splice(0, 0, ddcPath, \"$LIBROOT\");
}
@@ -53,6 +106,7 @@
};
let sdk = require(\"dart_sdk\");
let main = require(\"$BASENAME\").$BASENAME.main;
+ sdk.dart.ignoreWhitelistedErrors(false);
sdk._isolate_helper.startRootIsolate(main, []);" \
> $LIBROOT/$BASENAME.run.js
devtool $LIBROOT/$BASENAME.run.js
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
index 84479a9..1b1e938 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/js/dart2js/js_dart2js.dart
@@ -89,7 +89,6 @@
import 'dart:collection' show HashMap, ListMixin;
-import 'dart:_interceptors' as _interceptors show JSArray;
import 'dart:_js_helper' show Primitives;
import 'dart:_foreign_helper' show JS;
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
index d773cda..a4889fd 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
@@ -17,6 +17,8 @@
import 'dart:_foreign_helper' show JS, JSExportName;
+import 'dart:_runtime' as dart;
+
typedef void _Callback();
typedef void _TakeCallback(_Callback callback);
@@ -67,7 +69,7 @@
onError = zone.registerUnaryCallback(onError);
}
var asyncFuture = new _Future<T>();
- scheduleMicrotask(() {
+ var body = () {
try {
iter = JS('', '#[Symbol.iterator]()', initGenerator());
var iteratorValue = JS('', '#.next(null)', iter);
@@ -97,9 +99,20 @@
_Future._chainCoreFuture(onAwait(value), asyncFuture);
}
} catch (e, s) {
- _completeWithErrorCallback(asyncFuture, e, s);
+ if (dart.startAsyncSynchronously) {
+ scheduleMicrotask(() {
+ _completeWithErrorCallback(asyncFuture, e, s);
+ });
+ } else {
+ _completeWithErrorCallback(asyncFuture, e, s);
+ }
}
- });
+ };
+ if (dart.startAsyncSynchronously) {
+ body();
+ } else {
+ scheduleMicrotask(body);
+ }
return asyncFuture;
}
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 4531ea6..c15d282 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -16,7 +16,8 @@
NoInline,
notNull,
nullCheck,
- Primitives;
+ Primitives,
+ quoteStringForRegExp;
import 'dart:_runtime' as dart;
@@ -24,6 +25,8 @@
import 'dart:_native_typed_data' show NativeUint8List;
+import 'dart:typed_data' show Endian, Uint8List, Uint16List;
+
String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
@patch
@@ -157,6 +160,23 @@
}
@patch
+class BigInt implements Comparable<BigInt> {
+ @patch
+ static BigInt get zero => _BigIntImpl.zero;
+ @patch
+ static BigInt get one => _BigIntImpl.one;
+ @patch
+ static BigInt get two => _BigIntImpl.two;
+
+ @patch
+ static BigInt parse(String source, {int radix}) =>
+ _BigIntImpl.parse(source, radix: radix);
+
+ @patch
+ factory BigInt.from(num value) = _BigIntImpl.from;
+}
+
+@patch
class Error {
@patch
static String _objectToString(Object object) {
@@ -480,6 +500,9 @@
{bool multiLine: false, bool caseSensitive: true}) =>
new JSSyntaxRegExp(source,
multiLine: multiLine, caseSensitive: caseSensitive);
+
+ @patch
+ static String escape(String text) => quoteStringForRegExp(text);
}
// Patch for 'identical' function.
@@ -701,3 +724,2101 @@
toString() => "Error: field '$_name' is already initialized.";
}
+
+// TODO(jmesserly): The rest of this core_patch.dart source should reside in an
+// included part file instead of being inlined. However, part files are not
+// properly supported here.
+
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// part of dart.core;
+
+int _max(int a, int b) => a > b ? a : b;
+int _min(int a, int b) => a < b ? a : b;
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * Copyright (c) 2012 Adam Singer (adam@solvr.io)
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+/**
+ * An implementation for the arbitrarily large integer.
+ *
+ * The integer number is represented by a sign, an array of 16-bit unsigned
+ * integers in little endian format, and a number of used digits in that array.
+ */
+class _BigIntImpl implements BigInt {
+ // Bits per digit.
+ static const int _digitBits = 16;
+ static const int _digitBase = 1 << _digitBits;
+ static const int _digitMask = (1 << _digitBits) - 1;
+
+ static final _BigIntImpl zero = new _BigIntImpl._fromInt(0);
+ static final _BigIntImpl one = new _BigIntImpl._fromInt(1);
+ static final _BigIntImpl two = new _BigIntImpl._fromInt(2);
+
+ static final _BigIntImpl _minusOne = -one;
+ static final _BigIntImpl _bigInt10000 = new _BigIntImpl._fromInt(10000);
+
+ // Result cache for last _divRem call.
+ // Result cache for last _divRem call.
+ static Uint16List _lastDividendDigits;
+ static int _lastDividendUsed;
+ static Uint16List _lastDivisorDigits;
+ static int _lastDivisorUsed;
+ static Uint16List _lastQuoRemDigits;
+ static int _lastQuoRemUsed;
+ static int _lastRemUsed;
+ static int _lastRem_nsh;
+
+ /// Whether this bigint is negative.
+ final bool _isNegative;
+
+ /// The unsigned digits of this bigint.
+ ///
+ /// The least significant digit is in slot 0.
+ /// The list may have more digits than needed. That is, `_digits.length` may
+ /// be strictly greater than `_used`.
+ final Uint16List _digits;
+
+ /// The number of used entries in [_digits].
+ ///
+ /// To avoid reallocating [Uint16List]s, lists that are too big are not
+ /// replaced.
+ final int _used;
+
+ /**
+ * Parses [source] as a, possibly signed, integer literal and returns its
+ * value.
+ *
+ * The [source] must be a non-empty sequence of base-[radix] digits,
+ * optionally prefixed with a minus or plus sign ('-' or '+').
+ *
+ * The [radix] must be in the range 2..36. The digits used are
+ * first the decimal digits 0..9, and then the letters 'a'..'z' with
+ * values 10 through 35. Also accepts upper-case letters with the same
+ * values as the lower-case ones.
+ *
+ * If no [radix] is given then it defaults to 10. In this case, the [source]
+ * digits may also start with `0x`, in which case the number is interpreted
+ * as a hexadecimal literal, which effectively means that the `0x` is ignored
+ * and the radix is instead set to 16.
+ *
+ * For any int `n` and radix `r`, it is guaranteed that
+ * `n == int.parse(n.toRadixString(r), radix: r)`.
+ *
+ * Throws a [FormatException] if the [source] is not a valid integer literal,
+ * optionally prefixed by a sign.
+ */
+ static _BigIntImpl parse(String source, {int radix}) {
+ var result = _tryParse(source, radix: radix);
+ if (result == null) {
+ throw new FormatException("Could not parse BigInt", source);
+ }
+ return result;
+ }
+
+ /// Parses a decimal bigint literal.
+ ///
+ /// The [source] must not contain leading or trailing whitespace.
+ static _BigIntImpl _parseDecimal(String source, bool isNegative) {
+ const _0 = 48;
+
+ int part = 0;
+ _BigIntImpl result = zero;
+ // Read in the source 4 digits at a time.
+ // The first part may have a few leading virtual '0's to make the remaining
+ // parts all have exactly 4 digits.
+ int digitInPartCount = 4 - source.length.remainder(4);
+ if (digitInPartCount == 4) digitInPartCount = 0;
+ for (int i = 0; i < source.length; i++) {
+ part = part * 10 + source.codeUnitAt(i) - _0;
+ if (++digitInPartCount == 4) {
+ result = result * _bigInt10000 + new _BigIntImpl._fromInt(part);
+ part = 0;
+ digitInPartCount = 0;
+ }
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Returns the value of a given source digit.
+ ///
+ /// Source digits between "0" and "9" (inclusive) return their decimal value.
+ ///
+ /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return
+ /// 10 + their position in the ASCII alphabet.
+ ///
+ /// The incoming [codeUnit] must be an ASCII code-unit.
+ static int _codeUnitToRadixValue(int codeUnit) {
+ // We know that the characters must be ASCII as otherwise the
+ // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+ // guaranteed to be a safe operation, since it preserves digits
+ // and lower-cases ASCII letters.
+ const int _0 = 48;
+ const int _9 = 57;
+ const int _a = 97;
+ if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0;
+ codeUnit |= 0x20;
+ var result = codeUnit - _a + 10;
+ return result;
+ }
+
+ /// Parses the given [source] string, starting at [startPos], as a hex
+ /// literal.
+ ///
+ /// If [isNegative] is true, negates the result before returning it.
+ ///
+ /// The [source] (substring) must be a valid hex literal.
+ static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) {
+ int hexDigitsPerChunk = _digitBits ~/ 4;
+ int sourceLength = source.length - startPos;
+ int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
+ var digits = new Uint16List(chunkCount);
+
+ int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk;
+ int digitIndex = digits.length - 1;
+ int i = startPos;
+ int chunk = 0;
+ for (int j = 0; j < lastDigitLength; j++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (digitValue >= 16) return null;
+ chunk = chunk * 16 + digitValue;
+ }
+ digits[digitIndex--] = chunk;
+
+ while (i < source.length) {
+ chunk = 0;
+ for (int j = 0; j < 4; j++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (digitValue >= 16) return null;
+ chunk = chunk * 16 + digitValue;
+ }
+ digits[digitIndex--] = chunk;
+ }
+ if (digits.length == 1 && digits[0] == 0) return zero;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ /// Parses the given [source] as a [radix] literal.
+ ///
+ /// The [source] will be checked for invalid characters. If it is invalid,
+ /// this function returns `null`.
+ static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) {
+ var result = zero;
+ var base = new _BigIntImpl._fromInt(radix);
+ for (int i = 0; i < source.length; i++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i));
+ if (digitValue >= radix) return null;
+ result = result * base + new _BigIntImpl._fromInt(digitValue);
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Tries to parse the given [source] as a [radix] literal.
+ ///
+ /// Returns the parsed big integer, or `null` if it failed.
+ ///
+ /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
+ static _BigIntImpl _tryParse(String source, {int radix}) {
+ if (source == "") return null;
+
+ var re = new RegExp(r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$',
+ caseSensitive: false);
+ var match = re.firstMatch(source);
+ int signIndex = 1;
+ int hexIndex = 3;
+ int decimalIndex = 4;
+ int nonDecimalHexIndex = 5;
+ if (match == null) return null;
+
+ bool isNegative = match[signIndex] == "-";
+
+ String decimalMatch = match[decimalIndex];
+ String hexMatch = match[hexIndex];
+ String nonDecimalMatch = match[nonDecimalHexIndex];
+
+ if (radix == null) {
+ if (decimalMatch != null) {
+ // Cannot fail because we know that the digits are all decimal.
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (hexMatch != null) {
+ // Cannot fail because we know that the digits are all hex.
+ return _parseHex(hexMatch, 2, isNegative);
+ }
+ return null;
+ }
+
+ if (radix is! int) {
+ throw new ArgumentError.value(radix, 'radix', 'is not an integer');
+ }
+ if (radix < 2 || radix > 36) {
+ throw new RangeError.range(radix, 2, 36, 'radix');
+ }
+ if (radix == 10 && decimalMatch != null) {
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
+ return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative);
+ }
+
+ return _parseRadix(
+ decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative);
+ }
+
+ /// Finds the amount significant digits in the provided [digits] array.
+ static int _normalize(int used, Uint16List digits) {
+ while (used > 0 && digits[used - 1] == 0) used--;
+ return used;
+ }
+
+ /// Factory returning an instance initialized with the given field values.
+ /// If the [digits] array contains leading 0s, the [used] value is adjusted
+ /// accordingly. The [digits] array is not modified.
+ _BigIntImpl._(bool isNegative, int used, Uint16List digits)
+ : this._normalized(isNegative, _normalize(used, digits), digits);
+
+ _BigIntImpl._normalized(bool isNegative, this._used, this._digits)
+ : _isNegative = _used == 0 ? false : isNegative;
+
+ /// Whether this big integer is zero.
+ bool get _isZero => _used == 0;
+
+ /// Allocates an array of the given [length] and copies the [digits] in the
+ /// range [from] to [to-1], starting at index 0, followed by leading zero
+ /// digits.
+ static Uint16List _cloneDigits(
+ Uint16List digits, int from, int to, int length) {
+ var resultDigits = new Uint16List(length);
+ var n = to - from;
+ for (var i = 0; i < n; i++) {
+ resultDigits[i] = digits[from + i];
+ }
+ return resultDigits;
+ }
+
+ /// Allocates a big integer from the provided [value] number.
+ factory _BigIntImpl.from(num value) {
+ if (value == 0) return zero;
+ if (value == 1) return one;
+ if (value == 2) return two;
+
+ // Given this order dart2js will use the `_fromInt` for smaller value and
+ // then use the bit-manipulating `_fromDouble` for all other values.
+ if (value.abs() < 0x100000000)
+ return new _BigIntImpl._fromInt(value.toInt());
+ if (value is double) return new _BigIntImpl._fromDouble(value);
+ return new _BigIntImpl._fromInt(value);
+ }
+
+ factory _BigIntImpl._fromInt(int value) {
+ bool isNegative = value < 0;
+ if (isNegative) {
+ // Handle the min 64-bit value differently, since its negation is not
+ // positive.
+ // TODO(floitsch): we should use min.minValue or 0x8000000000000000 here.
+ const int minInt64 = -9223372036854775807 - 1;
+ if (value == minInt64) {
+ var digits = new Uint16List(4);
+ digits[3] = 0x8000;
+ return new _BigIntImpl._(true, digits.length, digits);
+ }
+ value = -value;
+ }
+ assert(_digitBits == 16);
+ if (value < _digitBase) {
+ var digits = new Uint16List(1);
+ digits[0] = value;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+ if (value <= 0xFFFFFFFF) {
+ var digits = new Uint16List(2);
+ digits[0] = value & _digitMask;
+ digits[1] = value >> _digitBits;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ var bits = value.bitLength;
+ var digits = new Uint16List((bits - 1) ~/ _digitBits + 1);
+ var i = 0;
+ while (value != 0) {
+ digits[i++] = value & _digitMask;
+ value = value ~/ _digitBase;
+ }
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating
+ /// garbage.
+ static final Uint8List _bitsForFromDouble = new Uint8List(8);
+
+ factory _BigIntImpl._fromDouble(double value) {
+ const int exponentBias = 1075;
+
+ if (value.isNaN || value.isInfinite) {
+ throw new ArgumentError("Value must be finite: $value");
+ }
+ bool isNegative = value < 0;
+ if (isNegative) value = -value;
+
+ value = value.floorToDouble();
+ if (value == 0) return zero;
+
+ var bits = _bitsForFromDouble;
+ for (int i = 0; i < 8; i++) {
+ bits[i] = 0;
+ }
+ bits.buffer.asByteData().setFloat64(0, value, Endian.little);
+ // The exponent is in bits 53..63.
+ var biasedExponent = (bits[7] << 4) + (bits[6] >> 4);
+ var exponent = biasedExponent - exponentBias;
+
+ assert(_digitBits == 16);
+ // The significant bits are in 0 .. 52.
+ var unshiftedDigits = new Uint16List(4);
+ unshiftedDigits[0] = (bits[1] << 8) + bits[0];
+ unshiftedDigits[1] = (bits[3] << 8) + bits[2];
+ unshiftedDigits[2] = (bits[5] << 8) + bits[4];
+ // Don't forget to add the hidden bit.
+ unshiftedDigits[3] = 0x10 | (bits[6] & 0xF);
+
+ var unshiftedBig = new _BigIntImpl._normalized(false, 4, unshiftedDigits);
+ _BigIntImpl absResult;
+ if (exponent < 0) {
+ absResult = unshiftedBig >> -exponent;
+ } else if (exponent > 0) {
+ absResult = unshiftedBig << exponent;
+ }
+ if (isNegative) return -absResult;
+ return absResult;
+ }
+
+ /**
+ * Return the negative value of this integer.
+ *
+ * The result of negating an integer always has the opposite sign, except
+ * for zero, which is its own negation.
+ */
+ _BigIntImpl operator -() {
+ if (_used == 0) return this;
+ return new _BigIntImpl._(!_isNegative, _used, _digits);
+ }
+
+ /**
+ * Returns the absolute value of this integer.
+ *
+ * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+ */
+ _BigIntImpl abs() => _isNegative ? -this : this;
+
+ /// Returns this << n *_DIGIT_BITS.
+ _BigIntImpl _dlShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used + n;
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ for (int i = used - 1; i >= 0; i--) {
+ resultDigits[i + n] = digits[i];
+ }
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ /// Same as [_dlShift] but works on the decomposed big integers.
+ ///
+ /// Returns `resultUsed`.
+ ///
+ /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`.
+ static int _dlShiftDigits(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ if (xUsed == 0) {
+ return 0;
+ }
+ if (n == 0 && identical(resultDigits, xDigits)) {
+ return xUsed;
+ }
+ final resultUsed = xUsed + n;
+ for (int i = xUsed - 1; i >= 0; i--) {
+ resultDigits[i + n] = xDigits[i];
+ }
+ for (int i = n - 1; i >= 0; i--) {
+ resultDigits[i] = 0;
+ }
+ return resultUsed;
+ }
+
+ /// Returns `this >> n*_DIGIT_BITS`.
+ _BigIntImpl _drShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used - n;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ for (var i = n; i < used; i++) {
+ resultDigits[i - n] = digits[i];
+ }
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ for (var i = 0; i < n; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Shifts the digits of [xDigits] into the right place in [resultDigits].
+ ///
+ /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)`
+ /// where `ds = ceil(n / _DIGIT_BITS)`
+ ///
+ /// Does *not* clear digits below ds.
+ static void _lsh(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << carryBitShift) - 1;
+ var carry = 0;
+ for (int i = xUsed - 1; i >= 0; i--) {
+ final digit = xDigits[i];
+ resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry;
+ carry = (digit & bitMask) << bitShift;
+ }
+ resultDigits[digitShift] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the left by [shiftAmount].
+ *
+ * Shifting to the left makes the number larger, effectively multiplying
+ * the number by `pow(2, shiftIndex)`.
+ *
+ * There is no limit on the size of the result. It may be relevant to
+ * limit intermediate values by using the "and" operator with a suitable
+ * mask.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator <<(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+ }
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _dlShift(digitShift);
+ }
+ var resultUsed = _used + digitShift + 1;
+ var resultDigits = new Uint16List(resultUsed);
+ _lsh(_digits, _used, shiftAmount, resultDigits);
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n.
+ // Returns resultUsed.
+ static int _lShiftDigits(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ if (bitShift == 0) {
+ return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits);
+ }
+ var resultUsed = xUsed + digitsShift + 1;
+ _lsh(xDigits, xUsed, n, resultDigits);
+ var i = digitsShift;
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ if (resultDigits[resultUsed - 1] == 0) {
+ resultUsed--; // Clamp result.
+ }
+ return resultUsed;
+ }
+
+ // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
+ static void _rsh(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << bitShift) - 1;
+ var carry = xDigits[digitsShift] >> bitShift;
+ final last = xUsed - digitsShift - 1;
+ for (var i = 0; i < last; i++) {
+ final digit = xDigits[i + digitsShift + 1];
+ resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry;
+ carry = digit >> bitShift;
+ }
+ resultDigits[last] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the right by [shiftAmount].
+ *
+ * Shifting to the right makes the number smaller and drops the least
+ * significant bits, effectively doing an integer division by
+ *`pow(2, shiftIndex)`.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator >>(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+ }
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _drShift(digitShift);
+ }
+ final used = _used;
+ final resultUsed = used - digitShift;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ _rsh(digits, used, shiftAmount, resultDigits);
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) {
+ return result - one;
+ }
+ for (var i = 0; i < digitShift; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Compares this to [other] taking the absolute value of both operands.
+ ///
+ /// Returns 0 if abs(this) == abs(other); a positive number if
+ /// abs(this) > abs(other); and a negative number if abs(this) < abs(other).
+ int _absCompare(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ return _compareDigits(_digits, _used, other._digits, other._used);
+ }
+
+ /**
+ * Compares this to `other`.
+ *
+ * Returns a negative number if `this` is less than `other`, zero if they are
+ * equal, and a positive number if `this` is greater than `other`.
+ */
+ int compareTo(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ var result = _absCompare(other);
+ // Use 0 - result to avoid negative zero in JavaScript.
+ return _isNegative ? 0 - result : result;
+ }
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`.
+ ///
+ /// Returns 0 if equal; a positive number if larger;
+ /// and a negative number if smaller.
+ static int _compareDigits(
+ Uint16List digits, int used, Uint16List otherDigits, int otherUsed) {
+ var result = used - otherUsed;
+ if (result == 0) {
+ for (int i = used - 1; i >= 0; i--) {
+ result = digits[i] - otherDigits[i];
+ if (result != 0) return result;
+ }
+ }
+ return result;
+ }
+
+ // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1].
+ // used >= otherUsed > 0.
+ static void _absAdd(Uint16List digits, int used, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] + otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ resultDigits[used] = carry;
+ }
+
+ // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1].
+ // used >= otherUsed > 0.
+ static void _absSub(Uint16List digits, int used, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] - otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ // Dart2js only supports unsigned shifts.
+ // Since the carry can only be -1 or 0 use this hack.
+ carry = 0 - ((carry >> _digitBits) & 1);
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ // Dart2js only supports unsigned shifts.
+ // Since the carry can only be -1 or 0 use this hack.
+ carry = 0 - ((carry >> _digitBits) & 1);
+ }
+ }
+
+ /// Returns `abs(this) + abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ if (used < otherUsed) {
+ return other._absAddSetSign(this, isNegative);
+ }
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultUsed = used + 1;
+ var resultDigits = new Uint16List(resultUsed);
+ _absAdd(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) - abs(other)` with sign set according to [isNegative].
+ ///
+ /// Requirement: `abs(this) >= abs(other)`.
+ _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) {
+ assert(_absCompare(other) >= 0);
+ var used = _used;
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ var otherUsed = other._used;
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultDigits = new Uint16List(used);
+ _absSub(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, used, resultDigits);
+ }
+
+ /// Returns `abs(this) & abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _min(_used, other._used);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ for (var i = 0; i < resultUsed; i++) {
+ resultDigits[i] = digits[i] & otherDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _used;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var m = _min(resultUsed, other._used);
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] & ~otherDigits[i];
+ }
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = digits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) | abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] | otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] ^ otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /**
+ * Bit-wise and operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with only the bits set that are set in
+ * both `this` and [other]
+ *
+ * Of both operands are negative, the result is negative, otherwise
+ * the result is non-negative.
+ */
+ _BigIntImpl operator &(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) & (-other) == ~(this-1) & ~(other-1)
+ // == ~((this-1) | (other-1))
+ // == -(((this-1) | (other-1)) + 1)
+ _BigIntImpl this1 = _absSubSetSign(one, true);
+ _BigIntImpl other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and other are negative.
+ return this1._absOrSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absAndSetSign(other, false);
+ }
+ // _isNegative != other._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // & is symmetric.
+ p = this;
+ n = other;
+ }
+ // p & (-n) == p & ~(n-1) == p &~ (n-1)
+ var n1 = n._absSubSetSign(one, false);
+ return p._absAndNotSetSign(n1, false);
+ }
+
+ /**
+ * Bit-wise or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in either
+ * of `this` and [other]
+ *
+ * If both operands are non-negative, the result is non-negative,
+ * otherwise the result us negative.
+ */
+ _BigIntImpl operator |(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) | (-other) == ~(this-1) | ~(other-1)
+ // == ~((this-1) & (other-1))
+ // == -(((this-1) & (other-1)) + 1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and a are negative.
+ return this1._absAndSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absOrSetSign(other, false);
+ }
+ // _neg != a._neg
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // | is symmetric.
+ p = this;
+ n = other;
+ }
+ // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * Bit-wise exclusive-or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in one,
+ * but not both, of `this` and [other]
+ *
+ * If the operands have the same sign, the result is non-negative,
+ * otherwise the result is negative.
+ */
+ _BigIntImpl operator ^(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ return this1._absXorSetSign(other1, false);
+ }
+ return _absXorSetSign(other, false);
+ }
+ // _isNegative != a._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // ^ is symmetric.
+ p = this;
+ n = other;
+ }
+ // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return p._absXorSetSign(n1, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * The bit-wise negate operator.
+ *
+ * Treating `this` as a sufficiently large two's component integer,
+ * the result is a number with the opposite bits set.
+ *
+ * This maps any integer `x` to `-x - 1`.
+ */
+ _BigIntImpl operator ~() {
+ if (_isNegative) {
+ // ~(-this) == ~(~(this-1)) == this-1
+ return _absSubSetSign(one, false);
+ }
+ // ~this == -this-1 == -(this+1)
+ // Result cannot be zero if this is positive.
+ return _absAddSetSign(one, true);
+ }
+
+ /// Addition operator.
+ _BigIntImpl operator +(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var isNegative = _isNegative;
+ if (isNegative == other._isNegative) {
+ // this + other == this + other
+ // (-this) + (-other) == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this + (-other) == this - other == -(this - other)
+ // (-this) + other == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Subtraction operator.
+ _BigIntImpl operator -(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var isNegative = _isNegative;
+ if (isNegative != other._isNegative) {
+ // this - (-other) == this + other
+ // (-this) - other == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this - other == this - a == -(this - other)
+ // (-this) - (-other) == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Multiplies [x] with [multiplicandDigits] and adds the result to
+ /// [accumulatorDigits].
+ ///
+ /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the
+ /// multiplicand digits.
+ ///
+ /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator
+ /// digits.
+ ///
+ /// Adds the result of the multiplicand-digits * [x] to the accumulator.
+ ///
+ /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`.
+ static void _mulAdd(int x, Uint16List multiplicandDigits, int i,
+ Uint16List accumulatorDigits, int j, int n) {
+ if (x == 0) {
+ // No-op if x is 0.
+ return;
+ }
+ int c = 0;
+ while (--n >= 0) {
+ int product = x * multiplicandDigits[i++];
+ int combined = product + accumulatorDigits[j] + c;
+ accumulatorDigits[j++] = combined & _digitMask;
+ // Note that this works with 53 bits, as the division will not lose
+ // bits.
+ c = combined ~/ _digitBase;
+ }
+ while (c != 0) {
+ int l = accumulatorDigits[j] + c;
+ accumulatorDigits[j++] = l & _digitMask;
+ c = l ~/ _digitBase;
+ }
+ }
+
+ /// Multiplication operator.
+ _BigIntImpl operator *(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var used = _used;
+ var otherUsed = other._used;
+ if (used == 0 || otherUsed == 0) {
+ return zero;
+ }
+ var resultUsed = used + otherUsed;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var i = 0;
+ while (i < otherUsed) {
+ _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used);
+ i++;
+ }
+ return new _BigIntImpl._(
+ _isNegative != other._isNegative, resultUsed, resultDigits);
+ }
+
+ // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1].
+ // Return resultUsed = xUsed + otherUsed.
+ static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ var resultUsed = xUsed + otherUsed;
+ var i = resultUsed;
+ assert(resultDigits.length >= i);
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ i = 0;
+ while (i < otherUsed) {
+ _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed);
+ i++;
+ }
+ return resultUsed;
+ }
+
+ /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`.
+ static int _estimateQuotientDigit(
+ int topDigitDivisor, Uint16List digits, int i) {
+ if (digits[i] == topDigitDivisor) return _digitMask;
+ var quotientDigit =
+ (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor;
+ if (quotientDigit > _digitMask) return _digitMask;
+ return quotientDigit;
+ }
+
+ /// Returns `trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _div(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return zero;
+ }
+ _divRem(other);
+ // Return quotient, i.e.
+ // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
+ var lastQuo_used = _lastQuoRemUsed - _lastRemUsed;
+ var quo_digits = _cloneDigits(
+ _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used);
+ var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits);
+ if ((_isNegative != other._isNegative) && (quo._used > 0)) {
+ quo = -quo;
+ }
+ return quo;
+ }
+
+ /// Returns `this - other * trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _rem(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return this;
+ }
+ _divRem(other);
+ // Return remainder, i.e.
+ // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
+ var remDigits =
+ _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed);
+ var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits);
+ if (_lastRem_nsh > 0) {
+ rem = rem >> _lastRem_nsh; // Denormalize remainder.
+ }
+ if (_isNegative && (rem._used > 0)) {
+ rem = -rem;
+ }
+ return rem;
+ }
+
+ /// Computes this ~/ other and this.remainder(other).
+ ///
+ /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and
+ /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the
+ /// quotient and the remainder.
+ ///
+ /// Caches the input to avoid doing the work again when users write
+ /// `a ~/ b` followed by a `a % b`.
+ void _divRem(_BigIntImpl other) {
+ // Check if result is already cached.
+ if ((this._used == _lastDividendUsed) &&
+ (other._used == _lastDivisorUsed) &&
+ identical(this._digits, _lastDividendDigits) &&
+ identical(other._digits, _lastDivisorDigits)) {
+ return;
+ }
+ assert(_used >= other._used);
+
+ var nsh = _digitBits - other._digits[other._used - 1].bitLength;
+ // Concatenated positive quotient and normalized positive remainder.
+ // The resultDigits can have at most one more digit than the dividend.
+ Uint16List resultDigits;
+ int resultUsed;
+ // Normalized positive divisor.
+ // The normalized divisor has the most-significant bit of it's most
+ // significant digit set.
+ // This makes estimating the quotient easier.
+ Uint16List yDigits;
+ int yUsed;
+ if (nsh > 0) {
+ yDigits = new Uint16List(other._used + 5);
+ yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits);
+ resultDigits = new Uint16List(_used + 5);
+ resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits);
+ } else {
+ yDigits = other._digits;
+ yUsed = other._used;
+ resultDigits = _cloneDigits(_digits, 0, _used, _used + 2);
+ resultUsed = _used;
+ }
+ var topDigitDivisor = yDigits[yUsed - 1];
+ var i = resultUsed;
+ var j = i - yUsed;
+ // tmpDigits is a temporary array of i (resultUsed) digits.
+ var tmpDigits = new Uint16List(i);
+ var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
+ // Explicit first division step in case normalized dividend is larger or
+ // equal to shifted normalized divisor.
+ if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
+ assert(i == resultUsed);
+ resultDigits[resultUsed++] = 1; // Quotient = 1.
+ // Subtract divisor from remainder.
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ } else {
+ // Account for possible carry in _mulAdd step.
+ resultDigits[resultUsed++] = 0;
+ }
+
+ // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
+ var nyDigits = new Uint16List(yUsed + 2);
+ nyDigits[yUsed] = 1;
+ _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits);
+ // nyDigits is read-only and has yUsed digits (possibly including several
+ // leading zeros).
+ // resultDigits is modified during iteration.
+ // resultDigits[0..yUsed-1] is the current remainder.
+ // resultDigits[yUsed..resultUsed-1] is the current quotient.
+ --i;
+
+ while (j > 0) {
+ var estimatedQuotientDigit =
+ _estimateQuotientDigit(topDigitDivisor, resultDigits, i);
+ j--;
+ _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed);
+ if (resultDigits[i] < estimatedQuotientDigit) {
+ // Reusing the already existing tmpDigits array.
+ var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ while (resultDigits[i] < --estimatedQuotientDigit) {
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ }
+ }
+ i--;
+ }
+ // Cache result.
+ _lastDividendDigits = _digits;
+ _lastDividendUsed = _used;
+ _lastDivisorDigits = other._digits;
+ _lastDivisorUsed = other._used;
+ _lastQuoRemDigits = resultDigits;
+ _lastQuoRemUsed = resultUsed;
+ _lastRemUsed = yUsed;
+ _lastRem_nsh = nsh;
+ }
+
+ int get hashCode {
+ // This is the [Jenkins hash function][1] but using masking to keep
+ // values in SMI range.
+ //
+ // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+
+ int combine(int hash, int value) {
+ hash = 0x1fffffff & (hash + value);
+ hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+ return hash ^ (hash >> 6);
+ }
+
+ int finish(int hash) {
+ hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+ hash = hash ^ (hash >> 11);
+ return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+ }
+
+ if (_isZero) return 6707; // Just a random number.
+ var hash = _isNegative ? 83585 : 429689; // Also random.
+ for (int i = 0; i < _used; i++) {
+ hash = combine(hash, _digits[i]);
+ }
+ return finish(hash);
+ }
+
+ /**
+ * Test whether this value is numerically equal to `other`.
+ *
+ * If [other] is a [_BigIntImpl] returns whether the two operands have the same
+ * value.
+ *
+ * Returns false if `other` is not a [_BigIntImpl].
+ */
+ bool operator ==(Object other) =>
+ other is _BigIntImpl && compareTo(other) == 0;
+
+ /**
+ * Returns the minimum number of bits required to store this big integer.
+ *
+ * The number of bits excludes the sign bit, which gives the natural length
+ * for non-negative (unsigned) values. Negative values are complemented to
+ * return the bit position of the first bit that differs from the sign bit.
+ *
+ * To find the number of bits needed to store the value as a signed value,
+ * add one, i.e. use `x.bitLength + 1`.
+ *
+ * ```
+ * x.bitLength == (-x-1).bitLength
+ *
+ * new BigInt.from(3).bitLength == 2; // 00000011
+ * new BigInt.from(2).bitLength == 2; // 00000010
+ * new BigInt.from(1).bitLength == 1; // 00000001
+ * new BigInt.from(0).bitLength == 0; // 00000000
+ * new BigInt.from(-1).bitLength == 0; // 11111111
+ * new BigInt.from(-2).bitLength == 1; // 11111110
+ * new BigInt.from(-3).bitLength == 2; // 11111101
+ * new BigInt.from(-4).bitLength == 2; // 11111100
+ * ```
+ */
+ int get bitLength {
+ if (_used == 0) return 0;
+ if (_isNegative) return (~this).bitLength;
+ return _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ }
+
+ /**
+ * Truncating division operator.
+ *
+ * Performs a truncating integer division, where the remainder is discarded.
+ *
+ * The remainder can be computed using the [remainder] method.
+ *
+ * Examples:
+ * ```
+ * var seven = new BigInt.from(7);
+ * var three = new BigInt.from(3);
+ * seven ~/ three; // => 2
+ * (-seven) ~/ three; // => -2
+ * seven ~/ -three; // => -2
+ * seven.remainder(three); // => 1
+ * (-seven).remainder(three); // => -1
+ * seven.remainder(-three); // => 1
+ * ```
+ */
+ _BigIntImpl operator ~/(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _div(other);
+ }
+
+ /**
+ * Returns the remainder of the truncating division of `this` by [other].
+ *
+ * The result `r` of this operation satisfies:
+ * `this == (this ~/ other) * other + r`.
+ * As a consequence the remainder `r` has the same sign as the divider `this`.
+ */
+ _BigIntImpl remainder(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _rem(other);
+ }
+
+ /// Division operator.
+ double operator /(BigInt other) => this.toDouble() / other.toDouble();
+
+ /** Relational less than operator. */
+ bool operator <(BigInt other) => compareTo(other) < 0;
+
+ /** Relational less than or equal operator. */
+ bool operator <=(BigInt other) => compareTo(other) <= 0;
+
+ /** Relational greater than operator. */
+ bool operator >(BigInt other) => compareTo(other) > 0;
+
+ /** Relational greater than or equal operator. */
+ bool operator >=(BigInt other) => compareTo(other) >= 0;
+
+ /**
+ * Euclidean modulo operator.
+ *
+ * Returns the remainder of the Euclidean division. The Euclidean division of
+ * two integers `a` and `b` yields two integers `q` and `r` such that
+ * `a == b * q + r` and `0 <= r < b.abs()`.
+ *
+ * The sign of the returned value `r` is always positive.
+ *
+ * See [remainder] for the remainder of the truncating division.
+ */
+ _BigIntImpl operator %(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ var result = _rem(other);
+ if (result._isNegative) {
+ if (other._isNegative) {
+ result = result - other;
+ } else {
+ result = result + other;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the sign of this big integer.
+ *
+ * Returns 0 for zero, -1 for values less than zero and
+ * +1 for values greater than zero.
+ */
+ int get sign {
+ if (_used == 0) return 0;
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Whether this big integer is even.
+ bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
+
+ /// Whether this big integer is odd.
+ bool get isOdd => !isEven;
+
+ /// Whether this number is negative.
+ bool get isNegative => _isNegative;
+
+ _BigIntImpl pow(int exponent) {
+ if (exponent < 0) {
+ throw new ArgumentError("Exponent must not be negative: $exponent");
+ }
+ if (exponent == 0) return one;
+
+ // Exponentiation by squaring.
+ var result = one;
+ var base = this;
+ while (exponent != 0) {
+ if ((exponent & 1) == 1) {
+ result *= base;
+ }
+ exponent >>= 1;
+ // Skip unnecessary operation.
+ if (exponent != 0) {
+ base *= base;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns this integer to the power of [exponent] modulo [modulus].
+ *
+ * The [exponent] must be non-negative and [modulus] must be
+ * positive.
+ */
+ _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) {
+ _BigIntImpl exponent = bigExponent;
+ _BigIntImpl modulus = bigModulus;
+ if (exponent._isNegative) {
+ throw new ArgumentError("exponent must be positive: $exponent");
+ }
+ if (modulus <= zero) {
+ throw new ArgumentError("modulus must be strictly positive: $modulus");
+ }
+ if (exponent._isZero) return one;
+
+ final modulusUsed = modulus._used;
+ final modulusUsed2p4 = 2 * modulusUsed + 4;
+ final exponentBitlen = exponent.bitLength;
+ if (exponentBitlen <= 0) return one;
+ _BigIntReduction z = new _BigIntClassic(modulus);
+ var resultDigits = new Uint16List(modulusUsed2p4);
+ var result2Digits = new Uint16List(modulusUsed2p4);
+ var gDigits = new Uint16List(modulusUsed);
+ var gUsed = z.convert(this, gDigits);
+ // Initialize result with g.
+ // Copy leading zero if any.
+ for (int j = gUsed - 1; j >= 0; j--) {
+ resultDigits[j] = gDigits[j];
+ }
+ var resultUsed = gUsed;
+ var result2Used;
+ for (int i = exponentBitlen - 2; i >= 0; i--) {
+ result2Used = z.sqr(resultDigits, resultUsed, result2Digits);
+ if (!(exponent & (one << i))._isZero) {
+ resultUsed =
+ z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits);
+ } else {
+ // Swap result and result2.
+ var tmpDigits = resultDigits;
+ var tmpUsed = resultUsed;
+ resultDigits = result2Digits;
+ resultUsed = result2Used;
+ result2Digits = tmpDigits;
+ result2Used = tmpUsed;
+ }
+ }
+ return z.revert(resultDigits, resultUsed);
+ }
+
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+ static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) {
+ var xDigits = x._digits;
+ var yDigits = y._digits;
+ var xUsed = x._used;
+ var yUsed = y._used;
+ var maxUsed = xUsed > yUsed ? xUsed : yUsed;
+ var unshiftedMaxUsed = maxUsed; // Keep
+ xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed);
+ yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed);
+ int shiftAmount = 0;
+ if (inv) {
+ if ((yUsed == 1) && (yDigits[0] == 1)) return one;
+ if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) {
+ throw new Exception("Not coprime");
+ }
+ } else {
+ if (x._isZero) {
+ throw new ArgumentError.value(0, "this", "must not be zero");
+ }
+ if (y._isZero) {
+ throw new ArgumentError.value(0, "other", "must not be zero");
+ }
+ if (((xUsed == 1) && (xDigits[0] == 1)) ||
+ ((yUsed == 1) && (yDigits[0] == 1))) return one;
+ while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) {
+ _rsh(xDigits, xUsed, 1, xDigits);
+ _rsh(yDigits, yUsed, 1, yDigits);
+ shiftAmount++;
+ }
+ if (shiftAmount >= _digitBits) {
+ var digitShiftAmount = shiftAmount ~/ _digitBits;
+ xUsed -= digitShiftAmount;
+ yUsed -= digitShiftAmount;
+ maxUsed -= digitShiftAmount;
+ }
+ if ((yDigits[0] & 1) == 1) {
+ // Swap x and y.
+ var tmpDigits = xDigits;
+ var tmpUsed = xUsed;
+ xDigits = yDigits;
+ xUsed = yUsed;
+ yDigits = tmpDigits;
+ yUsed = tmpUsed;
+ }
+ }
+ var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed);
+ var vDigits =
+ _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh.
+ final bool ac = (xDigits[0] & 1) == 0;
+
+ // Variables a, b, c, and d require one more digit.
+ final abcdUsed = maxUsed + 1;
+ final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd.
+ var aDigits, bDigits, cDigits, dDigits;
+ bool aIsNegative, bIsNegative, cIsNegative, dIsNegative;
+ if (ac) {
+ aDigits = new Uint16List(abcdLen);
+ aIsNegative = false;
+ aDigits[0] = 1;
+ cDigits = new Uint16List(abcdLen);
+ cIsNegative = false;
+ }
+ bDigits = new Uint16List(abcdLen);
+ bIsNegative = false;
+ dDigits = new Uint16List(abcdLen);
+ dIsNegative = false;
+ dDigits[0] = 1;
+
+ while (true) {
+ while ((uDigits[0] & 1) == 0) {
+ _rsh(uDigits, maxUsed, 1, uDigits);
+ if (ac) {
+ if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) {
+ if (aIsNegative) {
+ if ((aDigits[maxUsed] != 0) ||
+ (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) {
+ _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ } else {
+ _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits);
+ aIsNegative = false;
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ }
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(aDigits, abcdUsed, 1, aDigits);
+ } else if ((bDigits[0] & 1) == 1) {
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(bDigits, abcdUsed, 1, bDigits);
+ }
+ while ((vDigits[0] & 1) == 0) {
+ _rsh(vDigits, maxUsed, 1, vDigits);
+ if (ac) {
+ if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) {
+ if (cIsNegative) {
+ if ((cDigits[maxUsed] != 0) ||
+ (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) {
+ _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ } else {
+ _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits);
+ cIsNegative = false;
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ }
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(cDigits, abcdUsed, 1, cDigits);
+ } else if ((dDigits[0] & 1) == 1) {
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(dDigits, abcdUsed, 1, dDigits);
+ }
+ if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) {
+ _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits);
+ if (ac) {
+ if (aIsNegative == cIsNegative) {
+ var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed);
+ if (a_cmp_c > 0) {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ } else {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits);
+ aIsNegative = !aIsNegative && (a_cmp_c != 0);
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ }
+ }
+ if (bIsNegative == dIsNegative) {
+ var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed);
+ if (b_cmp_d > 0) {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ } else {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits);
+ bIsNegative = !bIsNegative && (b_cmp_d != 0);
+ }
+ } else {
+ _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ }
+ } else {
+ _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits);
+ if (ac) {
+ if (cIsNegative == aIsNegative) {
+ var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed);
+ if (c_cmp_a > 0) {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ } else {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits);
+ cIsNegative = !cIsNegative && (c_cmp_a != 0);
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ }
+ }
+ if (dIsNegative == bIsNegative) {
+ var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed);
+ if (d_cmp_b > 0) {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ } else {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits);
+ dIsNegative = !dIsNegative && (d_cmp_b != 0);
+ }
+ } else {
+ _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ }
+ }
+ // Exit loop if u == 0.
+ var i = maxUsed;
+ while ((i > 0) && (uDigits[i - 1] == 0)) --i;
+ if (i == 0) break;
+ }
+ if (!inv) {
+ if (shiftAmount > 0) {
+ maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits);
+ }
+ return new _BigIntImpl._(false, maxUsed, vDigits);
+ }
+ // No inverse if v != 1.
+ var i = maxUsed - 1;
+ while ((i > 0) && (vDigits[i] == 0)) --i;
+ if ((i != 0) || (vDigits[0] != 1)) {
+ throw new Exception("Not coprime");
+ }
+
+ if (dIsNegative) {
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = false;
+ }
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = false;
+ }
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ }
+ }
+ return new _BigIntImpl._(false, maxUsed, dDigits);
+ }
+
+ /**
+ * Returns the modular multiplicative inverse of this big integer
+ * modulo [modulus].
+ *
+ * The [modulus] must be positive.
+ *
+ * It is an error if no modular inverse exists.
+ */
+ // Returns 1/this % modulus, with modulus > 0.
+ _BigIntImpl modInverse(BigInt bigInt) {
+ _BigIntImpl modulus = bigInt;
+ if (modulus <= zero) {
+ throw new ArgumentError("Modulus must be strictly positive: $modulus");
+ }
+ if (modulus == one) return zero;
+ var tmp = this;
+ if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) {
+ tmp %= modulus;
+ }
+ return _binaryGcd(modulus, tmp, true);
+ }
+
+ /**
+ * Returns the greatest common divisor of this big integer and [other].
+ *
+ * If either number is non-zero, the result is the numerically greatest
+ * integer dividing both `this` and `other`.
+ *
+ * The greatest common divisor is independent of the order,
+ * so `x.gcd(y)` is always the same as `y.gcd(x)`.
+ *
+ * For any integer `x`, `x.gcd(x)` is `x.abs()`.
+ *
+ * If both `this` and `other` is zero, the result is also zero.
+ */
+ _BigIntImpl gcd(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return other.abs();
+ if (other._isZero) return this.abs();
+ return _binaryGcd(this, other, false);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this big integer as a
+ * non-negative number (i.e. unsigned representation). The returned value has
+ * zeros in all bit positions higher than [width].
+ *
+ * ```
+ * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit quantity:
+ *
+ * ```
+ * q = (q + 1).toUnsigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `255` and then wrap around to `0`.
+ *
+ * If the input fits in [width] bits without truncation, the result is the
+ * same as the input. The minimum width needed to avoid truncation of `x` is
+ * given by `x.bitLength`, i.e.
+ *
+ * ```
+ * x == x.toUnsigned(x.bitLength);
+ * ```
+ */
+ _BigIntImpl toUnsigned(int width) {
+ return this & ((one << width) - one);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this integer, extending the
+ * highest retained bit to the sign. This is the same as truncating the value
+ * to fit in [width] bits using an signed 2-s complement representation. The
+ * returned value has the same bit value in all positions higher than [width].
+ *
+ * ```
+ * var big15 = new BigInt.from(15);
+ * var big16 = new BigInt.from(16);
+ * var big239 = new BigInt.from(239);
+ * V--sign bit-V
+ * big16.toSigned(5) == -big16 // 00010000 -> 11110000
+ * big239.toSigned(5) == big15 // 11101111 -> 00001111
+ * ^ ^
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit signed quantity:
+ *
+ * ```
+ * q = (q + 1).toSigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+ * `127`.
+ *
+ * If the input value fits in [width] bits without truncation, the result is
+ * the same as the input. The minimum width needed to avoid truncation of `x`
+ * is `x.bitLength + 1`, i.e.
+ *
+ * ```
+ * x == x.toSigned(x.bitLength + 1);
+ * ```
+ */
+ _BigIntImpl toSigned(int width) {
+ // The value of binary number weights each bit by a power of two. The
+ // twos-complement value weights the sign bit negatively. We compute the
+ // value of the negative weighting by isolating the sign bit with the
+ // correct power of two weighting and subtracting it from the value of the
+ // lower bits.
+ var signMask = one << (width - 1);
+ return (this & (signMask - one)) - (this & signMask);
+ }
+
+ // TODO(floitsch): implement `isValidInt`.
+ // Remove the comment in [BigInt.isValidInt] when done.
+ bool get isValidInt => true;
+
+ // TODO(floitsch): implement the clamping. It behaves differently on dart2js
+ // and the VM.
+ // Remove the comment in [BigInt.isValidInt] when done.
+ int toInt() {
+ var result = 0;
+ for (int i = _used - 1; i >= 0; i--) {
+ result = result * _digitBase + _digits[i];
+ }
+ return _isNegative ? -result : result;
+ }
+
+ /**
+ * Returns this [_BigIntImpl] as a [double].
+ *
+ * If the number is not representable as a [double], an
+ * approximation is returned. For numerically large integers, the
+ * approximation may be infinite.
+ */
+ double toDouble() {
+ const int exponentBias = 1075;
+ // There are 11 bits for the exponent.
+ // 2047 (all bits set to 1) is reserved for infinity and NaN.
+ // When storing the exponent in the 11 bits, it is biased by exponentBias
+ // to support negative exponents.
+ const int maxDoubleExponent = 2046 - exponentBias;
+ if (_isZero) return 0.0;
+
+ // We fill the 53 bits little-endian.
+ var resultBits = new Uint8List(8);
+
+ var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ if (length - 53 > maxDoubleExponent) return double.INFINITY;
+
+ // The most significant bit is for the sign.
+ if (_isNegative) resultBits[7] = 0x80;
+
+ // Write the exponent into bits 1..12:
+ var biasedExponent = length - 53 + exponentBias;
+ resultBits[6] = (biasedExponent & 0xF) << 4;
+ resultBits[7] |= biasedExponent >> 4;
+
+ int cachedBits = 0;
+ int cachedBitsLength = 0;
+ int digitIndex = _used - 1;
+ int readBits(int n) {
+ // Ensure that we have enough bits in [cachedBits].
+ while (cachedBitsLength < n) {
+ int nextDigit;
+ int nextDigitLength = _digitBits; // May get updated.
+ if (digitIndex < 0) {
+ nextDigit = 0;
+ digitIndex--;
+ } else {
+ nextDigit = _digits[digitIndex];
+ if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength;
+ digitIndex--;
+ }
+ cachedBits = (cachedBits << nextDigitLength) + nextDigit;
+ cachedBitsLength += nextDigitLength;
+ }
+ // Read the top [n] bits.
+ var result = cachedBits >> (cachedBitsLength - n);
+ // Remove the bits from the cache.
+ cachedBits -= result << (cachedBitsLength - n);
+ cachedBitsLength -= n;
+ return result;
+ }
+
+ // The first leading 1 bit is implicit in the double-representation and can
+ // be discarded.
+ var leadingBits = readBits(5) & 0xF;
+ resultBits[6] |= leadingBits;
+
+ for (int i = 5; i >= 0; i--) {
+ // Get the remaining 48 bits.
+ resultBits[i] = readBits(8);
+ }
+
+ void roundUp() {
+ // Simply consists of adding 1 to the whole 64 bit "number".
+ // It will update the exponent, if necessary.
+ // It might even round up to infinity (which is what we want).
+ var carry = 1;
+ for (int i = 0; i < 8; i++) {
+ if (carry == 0) break;
+ var sum = resultBits[i] + carry;
+ resultBits[i] = sum & 0xFF;
+ carry = sum >> 8;
+ }
+ }
+
+ if (readBits(1) == 1) {
+ if (resultBits[0].isOdd) {
+ // Rounds to even all the time.
+ roundUp();
+ } else {
+ // Round up, if there is at least one other digit that is not 0.
+ if (cachedBits != 0) {
+ // There is already one in the cachedBits.
+ roundUp();
+ } else {
+ for (int i = digitIndex; digitIndex >= 0; i--) {
+ if (_digits[i] != 0) {
+ roundUp();
+ break;
+ }
+ }
+ }
+ }
+ }
+ return resultBits.buffer.asByteData().getFloat64(0, Endian.little);
+ }
+
+ /**
+ * Returns a String-representation of this integer.
+ *
+ * The returned string is parsable by [parse].
+ * For any `_BigIntImpl` `i`, it is guaranteed that
+ * `i == _BigIntImpl.parse(i.toString())`.
+ */
+ String toString() {
+ if (_used == 0) return "0";
+ if (_used == 1) {
+ if (_isNegative) return (-_digits[0]).toString();
+ return _digits[0].toString();
+ }
+
+ // Generate in chunks of 4 digits.
+ // The chunks are in reversed order.
+ var decimalDigitChunks = <String>[];
+ var rest = isNegative ? -this : this;
+ while (rest._used > 1) {
+ var digits4 = rest.remainder(_bigInt10000).toString();
+ decimalDigitChunks.add(digits4);
+ if (digits4.length == 1) decimalDigitChunks.add("000");
+ if (digits4.length == 2) decimalDigitChunks.add("00");
+ if (digits4.length == 3) decimalDigitChunks.add("0");
+ rest = rest ~/ _bigInt10000;
+ }
+ decimalDigitChunks.add(rest._digits[0].toString());
+ if (_isNegative) decimalDigitChunks.add("-");
+ return decimalDigitChunks.reversed.join();
+ }
+
+ int _toRadixCodeUnit(int digit) {
+ const int _0 = 48;
+ const int _a = 97;
+ if (digit < 10) return _0 + digit;
+ return _a + digit - 10;
+ }
+
+ /**
+ * Converts [this] to a string representation in the given [radix].
+ *
+ * In the string representation, lower-case letters are used for digits above
+ * '9', with 'a' being 10 an 'z' being 35.
+ *
+ * The [radix] argument must be an integer in the range 2 to 36.
+ */
+ String toRadixString(int radix) {
+ if (radix > 36) throw new RangeError.range(radix, 2, 36);
+
+ if (_used == 0) return "0";
+
+ if (_used == 1) {
+ var digitString = _digits[0].toRadixString(radix);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ if (radix == 16) return _toHexString();
+
+ var base = new _BigIntImpl._fromInt(radix);
+ var reversedDigitCodeUnits = <int>[];
+ var rest = this.abs();
+ while (!rest._isZero) {
+ var digit = rest.remainder(base).toInt();
+ rest = rest ~/ base;
+ reversedDigitCodeUnits.add(_toRadixCodeUnit(digit));
+ }
+ var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ String _toHexString() {
+ var chars = <int>[];
+ for (int i = 0; i < _used - 1; i++) {
+ int chunk = _digits[i];
+ for (int j = 0; j < (_digitBits ~/ 4); j++) {
+ chars.add(_toRadixCodeUnit(chunk & 0xF));
+ chunk >>= 4;
+ }
+ }
+ var msbChunk = _digits[_used - 1];
+ while (msbChunk != 0) {
+ chars.add(_toRadixCodeUnit(msbChunk & 0xF));
+ msbChunk >>= 4;
+ }
+ if (_isNegative) {
+ const _dash = 45;
+ chars.add(_dash);
+ }
+ return new String.fromCharCodes(chars.reversed);
+ }
+}
+
+// Interface for modular reduction.
+abstract class _BigIntReduction {
+ // Return the number of digits used by r_digits.
+ int convert(_BigIntImpl x, Uint16List r_digits);
+ int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+ Uint16List resultDigits);
+ int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits);
+
+ // Return x reverted to _BigIntImpl.
+ _BigIntImpl revert(Uint16List xDigits, int xUsed);
+}
+
+// Modular reduction using "classic" algorithm.
+class _BigIntClassic implements _BigIntReduction {
+ final _BigIntImpl _modulus; // Modulus.
+ final _BigIntImpl _normalizedModulus; // Normalized _modulus.
+
+ _BigIntClassic(this._modulus)
+ : _normalizedModulus = _modulus <<
+ (_BigIntImpl._digitBits -
+ _modulus._digits[_modulus._used - 1].bitLength);
+
+ int convert(_BigIntImpl x, Uint16List resultDigits) {
+ var digits;
+ var used;
+ if (x._isNegative || x.compareTo(_modulus) >= 0) {
+ var remainder = x._rem(_modulus);
+ if (x._isNegative && !remainder._isNegative && remainder._used > 0) {
+ remainder = _modulus - remainder;
+ }
+ assert(!remainder._isNegative);
+ used = remainder._used;
+ digits = remainder._digits;
+ } else {
+ used = x._used;
+ digits = x._digits;
+ }
+ var i = used; // Copy leading zero if any.
+ while (--i >= 0) {
+ resultDigits[i] = digits[i];
+ }
+ return used;
+ }
+
+ _BigIntImpl revert(Uint16List xDigits, int xUsed) {
+ return new _BigIntImpl._(false, xUsed, xDigits);
+ }
+
+ int _reduce(Uint16List xDigits, int xUsed) {
+ if (xUsed < _modulus._used) {
+ return xUsed;
+ }
+ var reverted = revert(xDigits, xUsed);
+ var rem = reverted._rem(_normalizedModulus);
+ return convert(rem, xDigits);
+ }
+
+ int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) {
+ var b = new _BigIntImpl._(false, xUsed, xDigits);
+ var b2 = b * b;
+ for (int i = 0; i < b2._used; i++) {
+ resultDigits[i] = b2._digits[i];
+ }
+ for (int i = b2._used; i < 2 * xUsed; i++) {
+ resultDigits[i] = 0;
+ }
+ return _reduce(resultDigits, 2 * xUsed);
+ }
+
+ int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+ Uint16List resultDigits) {
+ var resultUsed =
+ _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
+ return _reduce(resultDigits, resultUsed);
+ }
+}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
index 43fc543..db047d4 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
@@ -15,17 +15,72 @@
/// Returns a new type that mixes members from base and the mixin.
///
/// The mixin must be non-generic; generic mixins are handled by [genericMixin].
-mixinMembers(to, from) {
+void mixinMembers(to, from) {
JS('', '#[#] = #', to, _mixin, from);
var toProto = JS('', '#.prototype', to);
var fromProto = JS('', '#.prototype', from);
- copyProperties(toProto, fromProto);
+ _copyMembers(toProto, fromProto);
copySignature(to, from, _methodSig);
copySignature(to, from, _fieldSig);
copySignature(to, from, _getterSig);
copySignature(to, from, _setterSig);
}
+void _copyMembers(to, from) {
+ var names = getOwnNamesAndSymbols(from);
+ for (var i = 0, n = JS('int', '#.length', names); i < n; ++i) {
+ var name = JS('', '#[#]', names, i);
+ if (name == 'constructor') continue;
+ _copyMember(to, from, name);
+ }
+ return to;
+}
+
+void _copyMember(to, from, name) {
+ var desc = getOwnPropertyDescriptor(from, name);
+ if (JS('bool', '# == Symbol.iterator', name)) {
+ // On native types, Symbol.iterator may already be present.
+ // TODO(jmesserly): investigate if we still need this.
+ // If so, we need to find a better solution.
+ // See https://github.com/dart-lang/sdk/issues/28324
+ var existing = getOwnPropertyDescriptor(to, name);
+ if (existing != null) {
+ if (JS('bool', '#.writable', existing)) {
+ JS('', '#[#] = #.value', to, name, desc);
+ }
+ return;
+ }
+ }
+ var getter = JS('', '#.get', desc);
+ var setter = JS('', '#.set', desc);
+ if (getter != null) {
+ if (setter == null) {
+ var obj = JS(
+ '',
+ '#.set = { __proto__: #.__proto__, '
+ 'set [#](x) { return super[#] = x; } }',
+ desc,
+ to,
+ name,
+ name);
+ JS('', '#.set = #.set', desc, getOwnPropertyDescriptor(obj, name));
+ }
+ } else if (setter != null) {
+ if (getter == null) {
+ var obj = JS(
+ '',
+ '#.get = { __proto__: #.__proto__, '
+ 'get [#]() { return super[#]; } }',
+ desc,
+ to,
+ name,
+ name);
+ JS('', '#.get = #.get', desc, getOwnPropertyDescriptor(obj, name));
+ }
+ }
+ defineProperty(to, name, desc);
+}
+
void copySignature(to, from, signatureField) {
defineLazyField(
to,
@@ -58,24 +113,6 @@
final mixinNew = JS('', 'Symbol("dart.mixinNew")');
-/// Wrap a generic class builder function with future flattening.
-flattenFutures(builder) => JS('', '''(() => {
- function flatten(T) {
- if (!T) return $builder($dynamic);
- let futureClass = $getGenericClass($Future);
- //TODO(leafp): This only handles the direct flattening case.
- // It would probably be good to at least search up the class
- // hierarchy. If we keep doing flattening long term, we may
- // want to implement the full future flattening per spec.
- if ($getGenericClass(T) == futureClass) {
- let args = $getGenericArgs(T);
- if (args) return $builder(args[0]);
- }
- return $builder(T);
- }
- return flatten;
-})()''');
-
/// Memoize a generic type constructor function.
generic(typeConstructor, setBaseClass) => JS('', '''(() => {
let length = $typeConstructor.length;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart
index dc2d82e..d8f20d7 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/generators.dart
@@ -11,6 +11,12 @@
/// stepping stone for proposed ES7 async/await, and uses ES6 Promises.
part of dart._runtime;
+// TODO(vsm): Remove once this flag is the default.
+bool startAsyncSynchronously = false;
+void setStartAsyncSynchronously() {
+ startAsyncSynchronously = true;
+}
+
final _jsIterator = JS('', 'Symbol("_jsIterator")');
final _current = JS('', 'Symbol("_current")');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index edf399b..1d7790c 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -439,10 +439,7 @@
if (!!$isSubtype(type, $Iterable) && !!$isSubtype(actual, $Iterable) ||
!!$isSubtype(type, $Future) && !!$isSubtype(actual, $Future) ||
!!$isSubtype(type, $Map) && !!$isSubtype(actual, $Map) ||
- $_isFunctionType(type) && $_isFunctionType(actual) ||
- !!$isSubtype(type, $Stream) && !!$isSubtype(actual, $Stream) ||
- !!$isSubtype(type, $StreamSubscription) &&
- !!$isSubtype(actual, $StreamSubscription)) {
+ !!$isSubtype(type, $Stream) && !!$isSubtype(actual, $Stream)) {
console.warn('Ignoring cast fail from ' + $typeName(actual) +
' to ' + $typeName(type));
return true;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
index 6d982be..50c35e1 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
@@ -25,7 +25,8 @@
JsLinkedHashMap,
ImmutableMap,
PrivateSymbol,
- ReifyFunctionTypes;
+ ReifyFunctionTypes,
+ NoReifyGeneric;
import 'dart:_debugger' show trackCall;
export 'dart:_debugger'
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
index 8274bdd..08464ee 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
@@ -227,7 +227,8 @@
/// index path (if present) is the canonical function type.
final List _fnTypeSmallMap = JS('', '[new Map(), new Map(), new Map()]');
-_memoizeArray(map, arr, create) => JS('', '''(() => {
+@NoReifyGeneric()
+T _memoizeArray<T>(map, arr, T create()) => JS('', '''(() => {
let len = $arr.length;
$map = $_lookupNonTerminal($map, len);
for (var i = 0; i < len-1; ++i) {
@@ -239,41 +240,20 @@
return result;
})()''');
-// Map dynamic to bottom. If meta-data is present,
-// we slice off the remaining meta-data and make
-// it the second element of a packet for processing
-// later on in the constructor.
-_normalizeParameter(a) => JS('', '''(() => {
- if ($a instanceof Array) {
- let result = [];
- result.push(($a[0] == $dynamic) ? $bottom : $a[0]);
- result.push($a.slice(1));
- return result;
- }
- return ($a == $dynamic) ? $bottom : $a;
-})()''');
-
-List _canonicalizeArray(definite, array, map) => JS('', '''(() => {
- let arr = ($definite)
- ? $array
- : $array.map($_normalizeParameter);
- return $_memoizeArray($map, arr, () => arr);
-})()''');
+List _canonicalizeArray(List array, map) =>
+ _memoizeArray(map, array, () => array);
// TODO(leafp): This only canonicalizes of the names are
// emitted in a consistent order.
-_canonicalizeNamed(definite, named, map) => JS('', '''(() => {
+_canonicalizeNamed(named, map) => JS('', '''(() => {
let key = [];
let names = $getOwnPropertyNames($named);
- let r = {};
for (var i = 0; i < names.length; ++i) {
let name = names[i];
let type = $named[name];
- if (!definite) r[name] = type = $_normalizeParameter(type);
key.push(name);
key.push(type);
}
- if (!$definite) $named = r;
return $_memoizeArray($map, key, () => $named);
})()''');
@@ -287,16 +267,15 @@
// TODO(leafp): This handles some low hanging fruit, but
// really we should make all of this faster, and also
// handle more cases here.
-_createSmall(count, definite, returnType, required) => JS('', '''(() => {
- let map = $_fnTypeSmallMap[$count];
- let args = ($definite) ? $required
- : $required.map($_normalizeParameter);
- for (var i = 0; i < $count; ++i) {
- map = $_lookupNonTerminal(map, args[i]);
+FunctionType _createSmall(returnType, List required) => JS('', '''(() => {
+ let count = $required.length;
+ let map = $_fnTypeSmallMap[count];
+ for (var i = 0; i < count; ++i) {
+ map = $_lookupNonTerminal(map, $required[i]);
}
let result = map.get($returnType);
if (result !== void 0) return result;
- result = new $FunctionType.new($returnType, args, [], {});
+ result = ${new FunctionType(returnType, required, [], JS('', '{}'))};
map.set($returnType, result);
return result;
})()''');
@@ -311,14 +290,7 @@
String _stringValue;
/**
- * Construct a function type. There are two arrow constructors,
- * distinguished by the "definite" flag.
- *
- * The fuzzy arrow (definite is false) treats any arguments
- * of type dynamic as having type bottom, and will always be
- * called with a dynamic invoke.
- *
- * The definite arrow (definite is true) leaves arguments unchanged.
+ * Construct a function type.
*
* We eagerly normalize the argument types to avoid having to deal with
* this logic in multiple places.
@@ -327,28 +299,29 @@
* that all instances will share.
*
*/
- static create(definite, returnType, List args, extra) {
+ static FunctionType create(returnType, List args, extra) {
// Note that if extra is ever passed as an empty array
// or an empty map, we can end up with semantically
// identical function types that don't canonicalize
// to the same object since we won't fall into this
// fast path.
if (extra == null && JS('bool', '#.length < 3', args)) {
- return _createSmall(JS('', '#.length', args), definite, returnType, args);
+ return _createSmall(returnType, args);
}
- args = _canonicalizeArray(definite, args, _fnTypeArrayArgMap);
+ args = _canonicalizeArray(args, _fnTypeArrayArgMap);
var keys;
- var create;
+ FunctionType Function() create;
if (extra == null) {
keys = [returnType, args];
create = () => new FunctionType(returnType, args, [], JS('', '{}'));
} else if (JS('bool', '# instanceof Array', extra)) {
- var optionals = _canonicalizeArray(definite, extra, _fnTypeArrayArgMap);
+ var optionals =
+ _canonicalizeArray(JS('', '#', extra), _fnTypeArrayArgMap);
keys = [returnType, args, optionals];
create =
() => new FunctionType(returnType, args, optionals, JS('', '{}'));
} else {
- var named = _canonicalizeNamed(definite, extra, _fnTypeNamedArgMap);
+ var named = _canonicalizeNamed(extra, _fnTypeNamedArgMap);
keys = [returnType, args, named];
create = () => new FunctionType(returnType, args, [], named);
}
@@ -509,14 +482,12 @@
}
class GenericFunctionType extends AbstractFunctionType {
- final bool definite;
final _instantiateTypeParts;
final int formalCount;
final _instantiateTypeBounds;
List<TypeVariable> _typeFormals;
- GenericFunctionType(
- this.definite, instantiateTypeParts, this._instantiateTypeBounds)
+ GenericFunctionType(instantiateTypeParts, this._instantiateTypeBounds)
: _instantiateTypeParts = instantiateTypeParts,
formalCount = JS('int', '#.length', instantiateTypeParts);
@@ -555,10 +526,10 @@
}
}
- instantiate(typeArgs) {
+ FunctionType instantiate(typeArgs) {
var parts = JS('', '#.apply(null, #)', _instantiateTypeParts, typeArgs);
- return JS('', '#.create(#, #[0], #[1], #[2])', FunctionType, definite,
- parts, parts, parts);
+ return FunctionType.create(
+ JS('', '#[0]', parts), JS('', '#[1]', parts), JS('', '#[2]', parts));
}
List instantiateTypeBounds(List typeArgs) {
@@ -690,22 +661,14 @@
}
}
-typedef(name, AbstractFunctionType Function() closure) =>
+Typedef typedef(name, AbstractFunctionType Function() closure) =>
new Typedef(name, closure);
-/// Create a definite function type.
-///
-/// No substitution of dynamic for bottom occurs.
-fnType(returnType, List args, [extra = undefined]) =>
- FunctionType.create(true, returnType, args, extra);
+/// Create a function type.
+FunctionType fnType(returnType, List args, [extra = undefined]) =>
+ FunctionType.create(returnType, args, extra);
-/// Create a "fuzzy" function type.
-///
-/// If any arguments are dynamic they will be replaced with bottom.
-fnTypeFuzzy(returnType, List args, [extra = undefined]) =>
- FunctionType.create(false, returnType, args, extra);
-
-/// Creates a definite generic function type.
+/// Creates a generic function type.
///
/// A function type consists of two things: an instantiate function, and an
/// function that returns a list of upper bound constraints for each
@@ -716,10 +679,7 @@
/// For example given the type <T extends Iterable<T>>(T) -> T, we can declare
/// this type with `gFnType(T => [T, [T]], T => [Iterable$(T)])`.\
gFnType(instantiateFn, typeBounds) =>
- new GenericFunctionType(true, instantiateFn, typeBounds);
-
-gFnTypeFuzzy(instantiateFn, typeBounds) =>
- new GenericFunctionType(false, instantiateFn, typeBounds);
+ new GenericFunctionType(instantiateFn, typeBounds);
/// TODO(vsm): Remove when mirrors is deprecated.
/// This is a temporary workaround to support dart:mirrors, which doesn't
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
index 4adfd4f..2a7689e 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -95,12 +95,12 @@
static int parseInt(
@nullCheck String source, int _radix, int handleError(String source)) {
var re = JS('', r'/^\s*[+-]?((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$/i');
- var/*=JSArray<String>*/ match =
- JS('JSExtendableArray|Null', '#.exec(#)', re, source);
+ // TODO(jmesserly): this isn't reified List<String>, but it's safe to use as
+ // long as we use it locally and don't expose it to user code.
+ List<String> match = JS('', '#.exec(#)', re, source);
int digitsIndex = 1;
int hexIndex = 2;
int decimalIndex = 3;
- int nonDecimalHexIndex = 4;
if (match == null) {
// TODO(sra): It might be that the match failed due to unrecognized U+0085
// spaces. We could replace them with U+0020 spaces and try matching
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index e01387f..aac0185 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -15,9 +15,11 @@
import 'compiler_options.dart' show CompilerOptions;
abstract class IncrementalKernelGenerator {
- factory IncrementalKernelGenerator(CompilerOptions options, Uri entryPoint) {
- return new IncrementalCompiler(new CompilerContext(
- new ProcessedOptions(options, false, [entryPoint])));
+ factory IncrementalKernelGenerator(CompilerOptions options, Uri entryPoint,
+ [Uri bootstrapDill]) {
+ return new IncrementalCompiler(
+ new CompilerContext(new ProcessedOptions(options, false, [entryPoint])),
+ bootstrapDill);
}
/// Returns a component (nee program) whose libraries are the recompiled
diff --git a/pkg/front_end/lib/src/fasta/builder/load_library_builder.dart b/pkg/front_end/lib/src/fasta/builder/load_library_builder.dart
index 85234f3..c2365ca 100644
--- a/pkg/front_end/lib/src/fasta/builder/load_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/load_library_builder.dart
@@ -41,7 +41,7 @@
String prefix = expression.import.name;
tearoff = new Procedure(new Name('__loadLibrary_$prefix', parent.target),
ProcedureKind.Method, new FunctionNode(new ReturnStatement(expression)),
- fileUri: parent.target.fileUri)
+ fileUri: parent.target.fileUri, isStatic: true)
..fileOffset = charOffset;
return tearoff;
}
diff --git a/pkg/front_end/lib/src/fasta/builder_graph.dart b/pkg/front_end/lib/src/fasta/builder_graph.dart
new file mode 100644
index 0000000..9f77242
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/builder_graph.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fasta.builder_graph;
+
+import 'builder/builder.dart' show LibraryBuilder;
+
+import 'export.dart' show Export;
+
+import 'graph/graph.dart' show Graph;
+
+import 'import.dart' show Import;
+
+import 'dill/dill_library_builder.dart' show DillLibraryBuilder;
+
+import 'source/source_library_builder.dart' show SourceLibraryBuilder;
+
+class BuilderGraph implements Graph<Uri> {
+ final Map<Uri, LibraryBuilder> builders;
+
+ BuilderGraph(this.builders);
+
+ Iterable<Uri> get vertices => builders.keys;
+
+ Iterable<Uri> neighborsOf(Uri vertex) sync* {
+ LibraryBuilder library = builders[vertex];
+ if (library == null) {
+ throw "Library not found: $vertex";
+ }
+ if (library is SourceLibraryBuilder) {
+ for (Import import in library.imports) {
+ Uri uri = import.imported.uri;
+ if (builders.containsKey(uri)) {
+ yield uri;
+ }
+ }
+ for (Export export in library.exports) {
+ Uri uri = export.exported.uri;
+ if (builders.containsKey(uri)) {
+ yield uri;
+ }
+ }
+ for (SourceLibraryBuilder part in library.parts) {
+ Uri uri = part.uri;
+ if (builders.containsKey(uri)) {
+ yield uri;
+ }
+ }
+ } else if (library is DillLibraryBuilder) {
+ // Imports and exports
+ for (var dependency in library.library.dependencies) {
+ var uriString;
+ if (dependency.importedLibraryReference.node != null) {
+ uriString = '${dependency.targetLibrary.importUri}';
+ } else {
+ uriString =
+ '${dependency.importedLibraryReference.canonicalName.name}';
+ }
+ Uri uri = Uri.parse(uriString);
+ if (builders.containsKey(uri)) {
+ yield uri;
+ }
+ }
+
+ // Parts
+ for (var part in library.library.parts) {
+ Uri uri = part.fileUri;
+ if (builders.containsKey(uri)) {
+ yield uri;
+ }
+ }
+ }
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 72eb2b1..34ce204 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -226,6 +226,18 @@
message: r"""'await' can only be used in 'async' or 'async*' methods.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeBreakOutsideOfLoop = messageBreakOutsideOfLoop;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageBreakOutsideOfLoop = const MessageCode(
+ "BreakOutsideOfLoop",
+ analyzerCode: "BREAK_OUTSIDE_OF_LOOP",
+ dart2jsCode: "*ignored*",
+ message:
+ r"""A break statement can't be used outside of a loop or switch statement.""",
+ tip: r"""Try removing the break statement.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(Token token)> templateBuiltInIdentifierAsType =
const Template<Message Function(Token token)>(
messageTemplate:
@@ -765,6 +777,32 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeContinueOutsideOfLoop = messageContinueOutsideOfLoop;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageContinueOutsideOfLoop = const MessageCode(
+ "ContinueOutsideOfLoop",
+ analyzerCode: "CONTINUE_OUTSIDE_OF_LOOP",
+ dart2jsCode: "*ignored*",
+ message:
+ r"""A continue statement can't be used outside of a loop or switch statement.""",
+ tip: r"""Try removing the continue statement.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeContinueWithoutLabelInCase =
+ messageContinueWithoutLabelInCase;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageContinueWithoutLabelInCase = const MessageCode(
+ "ContinueWithoutLabelInCase",
+ analyzerCode: "CONTINUE_WITHOUT_LABEL_IN_CASE",
+ dart2jsCode: "*ignored*",
+ message:
+ r"""A continue statement in a switch statement must have a label as a target.""",
+ tip:
+ r"""Try adding a label associated with one of the case clauses to the continue statement.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String string, String string2)>
templateCouldNotParseUri =
const Template<Message Function(String string, String string2)>(
@@ -934,6 +972,42 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
+ Message Function(
+ DartType _type,
+ String
+ name)> templateDeferredTypeAnnotation = const Template<
+ Message Function(DartType _type, String name)>(
+ messageTemplate:
+ r"""The type '#type' is deferred loaded via prefix '#name' and can't be used as a type annotation.""",
+ tipTemplate:
+ r"""Try removing 'deferred' from the import of '#name' or use a supertype of '#type' that isn't deferred.""",
+ withArguments: _withArgumentsDeferredTypeAnnotation);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(DartType _type, String name)>
+ codeDeferredTypeAnnotation =
+ const Code<Message Function(DartType _type, String name)>(
+ "DeferredTypeAnnotation", templateDeferredTypeAnnotation,
+ analyzerCode: "TYPE_ANNOTATION_DEFERRED_CLASS",
+ dart2jsCode: "*fatal*",
+ severity: Severity.errorLegacyWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDeferredTypeAnnotation(DartType _type, String name) {
+ NameSystem nameSystem = new NameSystem();
+ StringBuffer buffer = new StringBuffer();
+ new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
+ String type = '$buffer';
+
+ return new Message(codeDeferredTypeAnnotation,
+ message:
+ """The type '$type' is deferred loaded via prefix '$name' and can't be used as a type annotation.""",
+ tip: """Try removing 'deferred' from the import of '$name' or use a supertype of '$type' that isn't deferred.""",
+ arguments: {'type': _type, 'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
Message Function(int count, int count2, String string, String string2,
String string3)> templateDillOutlineSummary =
const Template<
@@ -1805,7 +1879,7 @@
const MessageCode messageFactoryTopLevelDeclaration = const MessageCode(
"FactoryTopLevelDeclaration",
analyzerCode: "FACTORY_TOP_LEVEL_DECLARATION",
- dart2jsCode: "*ignored*",
+ dart2jsCode: "*fatal*",
message: r"""Top-level declarations can't be declared to be 'factory'.""",
tip: r"""Try removing the keyword 'factory'.""");
@@ -2231,9 +2305,8 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(Token token)> codeIntegerLiteralIsOutOfRange =
const Code<Message Function(Token token)>(
- "IntegerLiteralIsOutOfRange",
- templateIntegerLiteralIsOutOfRange,
-);
+ "IntegerLiteralIsOutOfRange", templateIntegerLiteralIsOutOfRange,
+ analyzerCode: "INTEGER_LITERAL_OUT_OF_RANGE", dart2jsCode: "*fatal*");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsIntegerLiteralIsOutOfRange(Token token) {
@@ -4690,7 +4763,7 @@
const MessageCode messageTopLevelOperator = const MessageCode(
"TopLevelOperator",
analyzerCode: "TOP_LEVEL_OPERATOR",
- dart2jsCode: "*ignored*",
+ dart2jsCode: "*fatal*",
message: r"""Operators must be declared within a class.""",
tip:
r"""Try removing the operator, moving it to a class, or converting it to be a function.""");
@@ -4963,16 +5036,6 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Null> codeUnimplementedBoundsOnTypeVariables =
- messageUnimplementedBoundsOnTypeVariables;
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const MessageCode messageUnimplementedBoundsOnTypeVariables = const MessageCode(
- "UnimplementedBoundsOnTypeVariables",
- severity: Severity.warning,
- message: r"""Unimplemented bounds on type variables.""");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String string, Token token)>
templateUnmatchedToken =
const Template<Message Function(String string, Token token)>(
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 2c8d581..70e3a76 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -7,23 +7,27 @@
import 'dart:async' show Future;
import 'package:kernel/kernel.dart'
- show Library, Program, Source, loadProgramFromBytes;
+ show loadProgramFromBytes, Library, Procedure, Program, Source;
import '../api_prototype/incremental_kernel_generator.dart'
show IncrementalKernelGenerator;
+import '../api_prototype/file_system.dart' show FileSystemEntity;
+
import 'builder/builder.dart' show LibraryBuilder;
+import 'builder_graph.dart' show BuilderGraph;
+
+import 'compiler_context.dart' show CompilerContext;
+
+import 'dill/dill_library_builder.dart' show DillLibraryBuilder;
+
import 'dill/dill_target.dart' show DillTarget;
import 'kernel/kernel_target.dart' show KernelTarget;
-import 'source/source_graph.dart' show SourceGraph;
-
import 'source/source_library_builder.dart' show SourceLibraryBuilder;
-import 'compiler_context.dart' show CompilerContext;
-
import 'ticker.dart' show Ticker;
import 'uri_translator.dart' show UriTranslator;
@@ -35,31 +39,90 @@
List<Uri> invalidatedUris = <Uri>[];
- DillTarget platform;
+ DillTarget dillLoadedData;
+ List<LibraryBuilder> platformBuilders;
+ Map<Uri, LibraryBuilder> userBuilders;
+ final Uri bootstrapDill;
+ bool bootstrapSuccess = false;
KernelTarget userCode;
- IncrementalCompiler(this.context) : ticker = context.options.ticker;
+ IncrementalCompiler(this.context, [this.bootstrapDill])
+ : ticker = context.options.ticker;
@override
Future<Program> computeDelta({Uri entryPoint}) async {
ticker.reset();
entryPoint ??= context.options.inputs.single;
return context.runInContext<Future<Program>>((CompilerContext c) async {
- if (platform == null) {
+ bool includeUserLoadedLibraries = false;
+ Map<Uri, Source> uriToSource = {};
+ Map<Uri, int> importUriToOrder = {};
+ Procedure userLoadedUriMain;
+ bootstrapSuccess = false;
+ if (dillLoadedData == null) {
UriTranslator uriTranslator = await c.options.getUriTranslator();
ticker.logMs("Read packages file");
- platform = new DillTarget(ticker, uriTranslator, c.options.target);
- List<int> bytes = await c.options.loadSdkSummaryBytes();
- if (bytes != null) {
+ dillLoadedData =
+ new DillTarget(ticker, uriTranslator, c.options.target);
+ List<int> summaryBytes = await c.options.loadSdkSummaryBytes();
+ int bytesLength = 0;
+ Program program;
+ if (summaryBytes != null) {
ticker.logMs("Read ${c.options.sdkSummary}");
- Program program = loadProgramFromBytes(bytes);
+ program = loadProgramFromBytes(summaryBytes);
ticker.logMs("Deserialized ${c.options.sdkSummary}");
- platform.loader.appendLibraries(program, byteCount: bytes.length);
- ticker.logMs("Appended libraries");
+ bytesLength += summaryBytes.length;
}
- await platform.buildOutlines();
+
+ if (bootstrapDill != null) {
+ FileSystemEntity entity =
+ c.options.fileSystem.entityForUri(bootstrapDill);
+ if (await entity.exists()) {
+ List<int> bootstrapBytes = await entity.readAsBytes();
+ if (bootstrapBytes != null) {
+ Set<Uri> prevLibraryUris = new Set<Uri>.from(
+ program.libraries.map((Library lib) => lib.importUri));
+ ticker.logMs("Read $bootstrapDill");
+ bool bootstrapFailed = false;
+ try {
+ loadProgramFromBytes(bootstrapBytes, program);
+ } catch (e) {
+ bootstrapFailed = true;
+ program = loadProgramFromBytes(summaryBytes);
+ }
+ if (!bootstrapFailed) {
+ bootstrapSuccess = true;
+ bytesLength += bootstrapBytes.length;
+ for (Library lib in program.libraries) {
+ if (prevLibraryUris.contains(lib.importUri)) continue;
+ importUriToOrder[lib.importUri] = importUriToOrder.length;
+ }
+ userLoadedUriMain = program.mainMethod;
+ includeUserLoadedLibraries = true;
+ uriToSource.addAll(program.uriToSource);
+ }
+ }
+ }
+ }
+ summaryBytes = null;
+ if (program != null) {
+ dillLoadedData.loader
+ .appendLibraries(program, byteCount: bytesLength);
+ }
+ ticker.logMs("Appended libraries");
+ await dillLoadedData.buildOutlines();
+ userBuilders = <Uri, LibraryBuilder>{};
+ platformBuilders = <LibraryBuilder>[];
+ dillLoadedData.loader.builders.forEach((uri, builder) {
+ if (builder.fileUri.scheme == "dart") {
+ platformBuilders.add(builder);
+ } else {
+ userBuilders[uri] = builder;
+ }
+ });
+ if (userBuilders.isEmpty) userBuilders = null;
}
List<Uri> invalidatedUris = this.invalidatedUris.toList();
@@ -67,16 +130,21 @@
List<LibraryBuilder> reusedLibraries =
computeReusedLibraries(invalidatedUris);
+ Set<Uri> reusedLibraryUris =
+ new Set<Uri>.from(reusedLibraries.map((b) => b.uri));
+ for (Uri uri in new Set<Uri>.from(dillLoadedData.loader.builders.keys)
+ ..removeAll(reusedLibraryUris)) {
+ dillLoadedData.loader.builders.remove(uri);
+ }
+
if (userCode != null) {
ticker.logMs("Decided to reuse ${reusedLibraries.length}"
" of ${userCode.loader.builders.length} libraries");
}
- platform.loader.builders.forEach((Uri uri, LibraryBuilder builder) {
- reusedLibraries.add(builder);
- });
+ reusedLibraries.addAll(platformBuilders);
userCode = new KernelTarget(
- c.fileSystem, false, platform, platform.uriTranslator,
+ c.fileSystem, false, dillLoadedData, dillLoadedData.uriTranslator,
uriToSource: c.uriToSource);
for (LibraryBuilder library in reusedLibraries) {
userCode.loader.builders[library.uri] = library;
@@ -94,16 +162,45 @@
Program programWithDill =
await userCode.buildProgram(verify: c.options.verify);
+ List<Library> libraries =
+ new List<Library>.from(userCode.loader.libraries);
+ uriToSource.addAll(userCode.uriToSource);
+ if (includeUserLoadedLibraries) {
+ for (LibraryBuilder library in reusedLibraries) {
+ if (library.fileUri.scheme == "dart") continue;
+ assert(library is DillLibraryBuilder);
+ libraries.add((library as DillLibraryBuilder).library);
+ }
+
+ // For now ensure original order of libraries to produce bit-perfect
+ // output.
+ List<Library> librariesOriginalOrder =
+ new List<Library>.filled(libraries.length, null, growable: true);
+ int lastOpen = libraries.length;
+ for (Library lib in libraries) {
+ int order = importUriToOrder[lib.importUri];
+ if (order != null) {
+ librariesOriginalOrder[order] = lib;
+ } else {
+ librariesOriginalOrder[--lastOpen] = lib;
+ }
+ }
+ libraries = librariesOriginalOrder;
+ }
+
// This is the incremental program.
- return new Program(
- libraries: new List<Library>.from(userCode.loader.libraries),
- uriToSource: new Map<Uri, Source>.from(userCode.uriToSource))
- ..mainMethod = programWithDill?.mainMethod;
+ Procedure mainMethod = programWithDill == null
+ ? userLoadedUriMain
+ : programWithDill.mainMethod;
+ return new Program(libraries: libraries, uriToSource: uriToSource)
+ ..mainMethod = mainMethod;
});
}
List<LibraryBuilder> computeReusedLibraries(Iterable<Uri> invalidatedUris) {
- if (userCode == null) return <LibraryBuilder>[];
+ if (userCode == null && userBuilders == null) {
+ return <LibraryBuilder>[];
+ }
// [invalidatedUris] converted to a set.
Set<Uri> invalidatedFileUris = invalidatedUris.toSet();
@@ -116,25 +213,29 @@
List<Uri> invalidatedImportUris = <Uri>[];
// Compute [builders] and [invalidatedImportUris].
- addBuilderAndInvalidateUris(Uri uri, LibraryBuilder libraryBuilder) {
- if (libraryBuilder.loader != platform.loader) {
- assert(libraryBuilder is SourceLibraryBuilder);
- SourceLibraryBuilder library = libraryBuilder;
- builders[uri] = library;
- if (invalidatedFileUris.contains(uri) ||
- (uri != library.fileUri &&
- invalidatedFileUris.contains(library.fileUri))) {
- invalidatedImportUris.add(uri);
- }
+ addBuilderAndInvalidateUris(Uri uri, LibraryBuilder library) {
+ builders[uri] = library;
+ if (invalidatedFileUris.contains(uri) ||
+ (uri != library.fileUri &&
+ invalidatedFileUris.contains(library.fileUri)) ||
+ (library is DillLibraryBuilder &&
+ uri != library.library.fileUri &&
+ invalidatedFileUris.contains(library.library.fileUri))) {
+ invalidatedImportUris.add(uri);
+ }
+ if (library is SourceLibraryBuilder) {
for (var part in library.parts) {
addBuilderAndInvalidateUris(part.uri, part);
}
}
}
- userCode.loader.builders.forEach(addBuilderAndInvalidateUris);
+ userBuilders?.forEach(addBuilderAndInvalidateUris);
+ if (userCode != null) {
+ userCode.loader.builders.forEach(addBuilderAndInvalidateUris);
+ }
- SourceGraph graph = new SourceGraph(builders);
+ BuilderGraph graph = new BuilderGraph(builders);
// Compute direct dependencies for each import URI (the reverse of the
// edges returned by `graph.neighborsOf`).
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 7a6968a..e70282b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -42,6 +42,8 @@
closeBraceTokenFor,
optional;
+import '../parser/class_member_parser.dart' show ClassMemberParser;
+
import '../parser/formal_parameter_kind.dart'
show isOptionalPositionalFormalParameterKind;
@@ -63,6 +65,8 @@
import '../scope.dart' show ProblemBuilder;
+import '../source/outline_builder.dart' show OutlineBuilder;
+
import '../source/scope_listener.dart'
show JumpTargetKind, NullValue, ScopeListener;
@@ -592,7 +596,7 @@
DartType _computeReturnTypeContext(MemberBuilder member) {
if (member is KernelProcedureBuilder) {
- return member.target.function.returnType;
+ return member.procedure.function.returnType;
} else {
assert(member is KernelConstructorBuilder);
return null;
@@ -1242,8 +1246,11 @@
deprecated_addCompileTimeError(
charOffset, "Not a constant expression.");
}
- return new TypeDeclarationAccessor(
+ TypeDeclarationAccessor accessor = new TypeDeclarationAccessor(
this, prefix, charOffset, builder, name, token);
+ return (prefix?.deferred == true)
+ ? new DeferredAccessor(this, token, prefix, accessor)
+ : accessor;
} else if (builder.isLocal) {
if (constantExpressionRequired &&
!builder.isConst &&
@@ -1849,12 +1856,8 @@
return;
}
}
- if (name is TypeDeclarationAccessor) {
+ if (name is FastaAccessor) {
push(name.buildTypeWithBuiltArguments(arguments));
- } else if (name is FastaAccessor) {
- addProblem(fasta.templateNotAType.withArguments(beginToken.lexeme),
- beginToken.charOffset);
- push(const InvalidType());
} else if (name is TypeBuilder) {
push(name.build(library));
} else if (name is PrefixBuilder) {
@@ -1871,15 +1874,12 @@
@override
void beginFunctionType(Token beginToken) {
debugEvent("beginFunctionType");
- enterFunctionTypeScope();
}
- void enterFunctionTypeScope() {
+ void enterFunctionTypeScope(List typeVariables) {
debugEvent("enterFunctionTypeScope");
- List typeVariables = pop();
enterLocalScope(null,
- scope.createNestedScope("function-type scope", isModifiable: false));
- push(typeVariables ?? NullValue.TypeVariables);
+ scope.createNestedScope("function-type scope", isModifiable: true));
if (typeVariables != null) {
ScopeBuilder scopeBuilder = new ScopeBuilder(scope);
for (KernelTypeVariableBuilder builder in typeVariables) {
@@ -2056,7 +2056,6 @@
void beginFunctionTypedFormalParameter(Token token) {
debugEvent("beginFunctionTypedFormalParameter");
functionNestingLevel++;
- enterFunctionTypeScope();
}
@override
@@ -2482,6 +2481,15 @@
String prefixName;
var type = pop();
+ PrefixBuilder deferredPrefix;
+ int checkOffset;
+ if (type is DeferredAccessor) {
+ DeferredAccessor accessor = type;
+ type = accessor.accessor;
+ deferredPrefix = accessor.builder;
+ checkOffset = accessor.token.charOffset;
+ }
+
if (type is TypeDeclarationAccessor) {
TypeDeclarationAccessor accessor = type;
if (accessor.prefix != null) {
@@ -2493,7 +2501,7 @@
bool savedConstantExpressionRequired = pop();
if (type is TypeDeclarationBuilder) {
- push(buildConstructorInvocation(
+ Expression expression = buildConstructorInvocation(
type,
nameToken,
arguments,
@@ -2501,8 +2509,11 @@
typeArguments,
token.charOffset,
optional("const", token) || optional("@", token),
- prefixName: prefixName));
- } else if (type is UnresolvedAccessor) {
+ prefixName: prefixName);
+ push(deferredPrefix != null
+ ? wrapInDeferredCheck(expression, deferredPrefix, checkOffset)
+ : expression);
+ } else if (type is ErrorAccessor) {
push(type.buildError(arguments));
} else {
push(throwNoSuchMethodError(
@@ -2667,7 +2678,6 @@
void enterFunction() {
debugEvent("enterFunction");
- enterFunctionTypeScope();
functionNestingLevel++;
push(switchScope ?? NullValue.SwitchScope);
switchScope = null;
@@ -3246,22 +3256,39 @@
}
@override
+ void beginTypeVariables(Token token) {
+ debugEvent("beginTypeVariables");
+ OutlineBuilder listener = new OutlineBuilder(library);
+ new ClassMemberParser(listener).parseTypeVariablesOpt(token.previous);
+ enterFunctionTypeScope(listener.pop());
+ }
+
+ @override
+ void handleNoTypeVariables(Token token) {
+ debugEvent("NoTypeVariables");
+ enterFunctionTypeScope(null);
+ push(NullValue.TypeVariables);
+ }
+
+ @override
void endTypeVariable(Token token, Token extendsOrSuper) {
debugEvent("TypeVariable");
DartType bound = pop();
- if (bound != null) {
- // TODO(ahe): To handle F-bounded types, this needs to be a TypeBuilder.
- // TODO(askesc): Remove message type when no longer needed.
- // https://github.com/dart-lang/sdk/issues/31766
- addProblem(fasta.messageUnimplementedBoundsOnTypeVariables,
- offsetForToken(extendsOrSuper.next));
- }
Identifier name = pop();
// TODO(ahe): Do not discard metadata.
pop(); // Metadata.
- push(new KernelTypeVariableBuilder(
- name.name, library, offsetForToken(name.token), null)
- ..finish(library, library.loader.coreLibrary["Object"]));
+ KernelTypeVariableBuilder variable;
+ Object inScope = scopeLookup(scope, name.name, token);
+ if (inScope is TypeDeclarationAccessor) {
+ variable = inScope.declaration;
+ } else {
+ // Something went wrong when pre-parsing the type variables.
+ // Assume an error is reported elsewhere.
+ variable = new KernelTypeVariableBuilder(
+ name.name, library, offsetForToken(name.token), null);
+ }
+ variable.parameter.bound = bound;
+ push(variable..finish(library, library.loader.coreLibrary["Object"]));
}
@override
@@ -3626,6 +3653,7 @@
library.addCompileTimeError(message, charOffset, uri);
}
+ @override
void addProblem(Message message, int charOffset) {
library.addProblem(message, charOffset, uri);
}
@@ -3657,11 +3685,12 @@
}
@override
- Expression makeDeferredCheck(Expression expression, PrefixBuilder prefix) {
- return new ShadowDeferredCheck(
- new VariableDeclaration.forValue(
- new CheckLibraryIsLoaded(prefix.dependency)),
- expression);
+ Expression wrapInDeferredCheck(
+ Expression expression, PrefixBuilder prefix, int charOffset) {
+ var check = new VariableDeclaration.forValue(
+ new CheckLibraryIsLoaded(prefix.dependency))
+ ..fileOffset = charOffset;
+ return new ShadowDeferredCheck(check, expression);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
index bebb020..a838287 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -13,7 +13,9 @@
messageInvalidInitializer,
messageLoadLibraryTakesNoArguments,
messageSuperAsExpression,
- templateIntegerLiteralIsOutOfRange;
+ templateDeferredTypeAnnotation,
+ templateIntegerLiteralIsOutOfRange,
+ templateNotAType;
import '../messages.dart' show Message;
@@ -139,7 +141,8 @@
StaticGet makeStaticGet(Member readTarget, Token token,
{String prefixName, int targetOffset: -1, Class targetClass});
- Expression makeDeferredCheck(Expression expression, PrefixBuilder prefix);
+ Expression wrapInDeferredCheck(
+ Expression expression, PrefixBuilder prefix, int charOffset);
dynamic deprecated_addCompileTimeError(int charOffset, String message);
@@ -165,6 +168,8 @@
DartType validatedTypeVariableUse(
TypeParameterType type, int offset, bool nonInstanceAccessIsError);
+ void addProblem(Message message, int charOffset);
+
void addProblemErrorIfConst(Message message, int charOffset, int length);
Message warnUnresolvedGet(Name name, int charOffset, {bool isSuper});
@@ -229,6 +234,13 @@
}
}
+ DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+ {bool nonInstanceAccessIsError: false}) {
+ helper.addProblem(
+ templateNotAType.withArguments(token.lexeme), token.charOffset);
+ return const InvalidType();
+ }
+
/* Expression | FastaAccessor */ buildThrowNoSuchMethodError(
Expression receiver, Arguments arguments,
{bool isSuper: false,
@@ -839,7 +851,7 @@
class DeferredAccessor extends kernel.DeferredAccessor with FastaAccessor {
DeferredAccessor(BuilderHelper helper, Token token, PrefixBuilder builder,
- StaticAccessor expression)
+ FastaAccessor expression)
: super(helper, token, builder, expression);
String get plainNameForRead {
@@ -847,11 +859,35 @@
"deferredAccessor.plainNameForRead", offsetForToken(token), uri);
}
- StaticAccessor get staticAccessor => super.staticAccessor;
+ FastaAccessor get accessor => super.accessor;
+
+ buildPropertyAccess(
+ IncompleteSend send, int operatorOffset, bool isNullAware) {
+ var propertyAccess =
+ accessor.buildPropertyAccess(send, operatorOffset, isNullAware);
+ if (propertyAccess is FastaAccessor) {
+ return new DeferredAccessor(helper, token, builder, propertyAccess);
+ } else {
+ Expression expression = propertyAccess;
+ return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
+ }
+ }
+
+ @override
+ DartType buildTypeWithBuiltArguments(List<DartType> arguments,
+ {bool nonInstanceAccessIsError: false}) {
+ helper.addProblem(
+ templateDeferredTypeAnnotation.withArguments(
+ accessor.buildTypeWithBuiltArguments(arguments,
+ nonInstanceAccessIsError: nonInstanceAccessIsError),
+ builder.name),
+ token.charOffset);
+ return const InvalidType();
+ }
Expression doInvocation(int offset, Arguments arguments) {
- return helper.makeDeferredCheck(
- staticAccessor.doInvocation(offset, arguments), builder);
+ return helper.wrapInDeferredCheck(
+ accessor.doInvocation(offset, arguments), builder, token.charOffset);
}
}
@@ -1155,6 +1191,7 @@
}
}
+ @override
DartType buildTypeWithBuiltArguments(List<DartType> arguments,
{bool nonInstanceAccessIsError: false}) {
if (arguments != null) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
index c0afd0a..e698255 100644
--- a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
@@ -738,22 +738,28 @@
abstract class DeferredAccessor extends Accessor {
final PrefixBuilder builder;
- final StaticAccessor staticAccessor;
+ final Accessor accessor;
DeferredAccessor(
- BuilderHelper helper, Token token, this.builder, this.staticAccessor)
+ BuilderHelper helper, Token token, this.builder, this.accessor)
: super(helper, token);
+ Expression _makeSimpleRead() {
+ return helper.wrapInDeferredCheck(
+ accessor._makeSimpleRead(), builder, token.charOffset);
+ }
+
Expression _makeRead(ShadowComplexAssignment complexAssignment) {
- return helper.makeDeferredCheck(
- staticAccessor._makeRead(complexAssignment), builder);
+ return helper.wrapInDeferredCheck(
+ accessor._makeRead(complexAssignment), builder, token.charOffset);
}
Expression _makeWrite(Expression value, bool voidContext,
ShadowComplexAssignment complexAssignment) {
- return helper.makeDeferredCheck(
- staticAccessor._makeWrite(value, voidContext, complexAssignment),
- builder);
+ return helper.wrapInDeferredCheck(
+ accessor._makeWrite(value, voidContext, complexAssignment),
+ builder,
+ token.charOffset);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 5e3d25a..ec69a92 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -595,9 +595,12 @@
endNestedDeclaration("#method").resolveTypes(typeVariables, this);
String procedureName;
ProcedureBuilder procedure;
- String constructorName =
- isTopLevel ? null : computeAndValidateConstructorName(name, charOffset);
MetadataCollector metadataCollector = loader.target.metadataCollector;
+ String constructorName = isTopLevel ||
+ kind == ProcedureKind.Getter ||
+ kind == ProcedureKind.Setter
+ ? null
+ : computeAndValidateConstructorName(name, charOffset);
if (constructorName != null) {
procedureName = constructorName;
procedure = new KernelConstructorBuilder(
diff --git a/pkg/front_end/lib/src/fasta/parser/loop_state.dart b/pkg/front_end/lib/src/fasta/parser/loop_state.dart
new file mode 100644
index 0000000..b6443b8
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/parser/loop_state.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fasta.parser.loop_state;
+
+enum LoopState {
+ OutsideLoop,
+ InsideSwitch, // `break` statement allowed
+ InsideLoop, // `break` and `continue` statements allowed
+}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 7d83002..dc031af 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -72,6 +72,8 @@
import 'listener.dart' show Listener;
+import 'loop_state.dart' show LoopState;
+
import 'member_kind.dart' show MemberKind;
import 'modifier_context.dart'
@@ -254,6 +256,17 @@
/// external clients, for example, to parse an expression outside a function.
AsyncModifier asyncState = AsyncModifier.Sync;
+ // TODO(danrubel): The [loopState] and associated functionality in the
+ // [Parser] duplicates work that the resolver needs to do when resolving
+ // break/continue targets. Long term, this state and functionality will be
+ // removed from the [Parser] class and the resolver will be responsible
+ // for generating all break/continue error messages.
+
+ /// Represents parser state: whether parsing outside a loop,
+ /// inside a loop, or inside a switch. This is used to determine whether
+ /// break and continue statements are allowed.
+ LoopState loopState = LoopState.OutsideLoop;
+
/// A rewriter for inserting synthetic tokens.
/// Access using [rewriter] for lazy initialization.
TokenStreamRewriter cachedRewriter;
@@ -277,6 +290,12 @@
bool get inPlainSync => asyncState == AsyncModifier.Sync;
+ bool get isBreakAllowed => loopState != LoopState.OutsideLoop;
+
+ bool get isContinueAllowed => loopState == LoopState.InsideLoop;
+
+ bool get isContinueWithLabelAllowed => loopState != LoopState.OutsideLoop;
+
/// Parse a compilation unit.
///
/// This method is only invoked from outside the parser. As a result, this
@@ -1307,6 +1326,154 @@
return token;
}
+ /// Skip over the `Function` type parameter.
+ /// For example, `Function<E>(int foo)` or `Function(foo)` or just `Function`.
+ Token skipGenericFunctionType(Token token) {
+ Token last = token;
+ Token next = token.next;
+ while (optional('Function', next)) {
+ last = token;
+ token = next;
+ next = token.next;
+ if (optional('<', next)) {
+ next = next.endGroup;
+ if (next == null) {
+ // TODO(danrubel): Consider better recovery
+ // because this is probably a type reference.
+ return token;
+ }
+ token = next;
+ next = token.next;
+ }
+ if (optional('(', next)) {
+ token = next.endGroup;
+ next = token.next;
+ }
+ }
+ if (next.isKeywordOrIdentifier) {
+ return token;
+ } else {
+ return last;
+ }
+ }
+
+ /// If the token after [token] begins a valid type reference
+ /// or looks like a valid type reference, then return the last token
+ /// in that type reference, otherwise return [token].
+ ///
+ /// For example, it is an error when built-in keyword is being used as a type,
+ /// as in `abstract<t> foo`. In situations such as this, return the last
+ /// token in that type reference and assume the caller will report the error
+ /// and recover.
+ Token skipTypeReferenceOpt(Token token) {
+ final Token beforeStart = token;
+ Token next = token.next;
+
+ TokenType type = next.type;
+ bool looksLikeTypeRef = false;
+ if (type != TokenType.IDENTIFIER) {
+ String value = next.stringValue;
+ if (identical(value, 'get') || identical(value, 'set')) {
+ // No type reference.
+ return beforeStart;
+ } else if (identical(value, 'factory') || identical(value, 'operator')) {
+ Token next2 = next.next;
+ if (!optional('<', next2) || next2.endGroup == null) {
+ // No type reference.
+ return beforeStart;
+ }
+ // Even though built-ins cannot be used as a type,
+ // it looks like its being used as such.
+ } else if (identical(value, 'void')) {
+ // Found type reference.
+ looksLikeTypeRef = true;
+ } else if (identical(value, 'Function')) {
+ // Found type reference.
+ return skipGenericFunctionType(token);
+ } else if (identical(value, 'typedef')) {
+ // `typedef` can be used as a prefix.
+ // For example: `typedef.A x = new typedef.A();`
+ if (!optional('.', next.next)) {
+ // No type reference.
+ return beforeStart;
+ }
+ } else if (!next.isIdentifier) {
+ // No type reference.
+ return beforeStart;
+ }
+ }
+ token = next;
+ next = token.next;
+
+ if (optional('.', next)) {
+ token = next;
+ next = token.next;
+ if (next.type != TokenType.IDENTIFIER) {
+ String value = next.stringValue;
+ if (identical(value, 'get') || identical(value, 'set')) {
+ // Found a type reference, but missing an identifier after the period.
+ rewriteAndRecover(
+ token,
+ fasta.templateExpectedIdentifier.withArguments(next),
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', next.charOffset, 0));
+ // Return the newly inserted synthetic token
+ // as the end of the type reference.
+ return token.next;
+ } else if (identical(value, '<') || identical(value, 'Function')) {
+ // Found a type reference, but missing an identifier after the period.
+ rewriteAndRecover(
+ token,
+ fasta.templateExpectedIdentifier.withArguments(next),
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER, '', next.charOffset, 0));
+ // Fall through to continue processing as a type reference.
+ next = token.next;
+ } else if (!next.isIdentifier) {
+ if (identical(value, 'void')) {
+ looksLikeTypeRef = true;
+ // Found a type reference, but the period
+ // and preceding identifier are both invalid.
+ reportRecoverableErrorWithToken(
+ token, fasta.templateUnexpectedToken);
+ // Fall through to continue processing as a type reference.
+ } else {
+ // No type reference.
+ return beforeStart;
+ }
+ }
+ }
+ token = next;
+ next = token.next;
+ }
+
+ if (optional('<', next)) {
+ token = next.endGroup;
+ if (token == null) {
+ // TODO(danrubel): Consider better recovery
+ // because this is probably a type reference.
+ return beforeStart;
+ }
+ next = token.next;
+ if (optional('(', next)) {
+ // No type reference - e.g. `f<E>()`.
+ return beforeStart;
+ }
+ }
+
+ if (optional('Function', next)) {
+ looksLikeTypeRef = true;
+ token = skipGenericFunctionType(token);
+ next = token.next;
+ }
+
+ return next.isIdentifier ||
+ (next.isOperator && !optional('=', next)) ||
+ looksLikeTypeRef
+ ? token
+ : beforeStart;
+ }
+
bool isValidTypeReference(Token token) {
int kind = token.kind;
if (IDENTIFIER_TOKEN == kind) return true;
@@ -2795,183 +2962,124 @@
}
typeContinuation ??= TypeContinuation.Required;
- Link<Token> identifiers = findMemberName(token);
- if (identifiers.isEmpty) {
- // Recovery
- if ((varFinalOrConst != null) &&
- isPostIdentifierForRecovery(
- next.next, IdentifierContext.topLevelVariableDeclaration)) {
- // Looks like a top level variable declaration
- // but missing a variable name.
- return parseFields(
- beforeStart,
- externalToken,
- null,
- null,
- varFinalOrConst,
- null,
- token,
- MemberKind.TopLevelField,
- typeContinuation);
- } else if (next.isIdentifier &&
- isPostIdentifierForRecovery(
- next.next, IdentifierContext.topLevelVariableDeclaration)) {
- // Looks like a top level variable declaration
- // but missing a variable name.
- return parseFields(
- beforeStart,
- externalToken,
- null,
- null,
- varFinalOrConst,
- null,
- token,
- MemberKind.TopLevelField,
- typeContinuation);
- } else {
- return reportInvalidTopLevelDeclaration(beforeStart.next);
- }
+ Token beforeType = token;
+ // TODO(danrubel): Consider changing the listener contract
+ // so that the type reference can be parsed immediately
+ // rather than skipped now and parsed later.
+ token = skipTypeReferenceOpt(token);
+ if (token == beforeType) {
+ // There is no type reference.
+ beforeType = null;
}
- Token afterName = identifiers.head.next;
- identifiers = identifiers.tail;
+ next = token.next;
- if (identifiers.isEmpty) {
- return reportInvalidTopLevelDeclaration(beforeStart.next);
- }
- Token beforeName = identifiers.head;
- identifiers = identifiers.tail;
- if (!beforeName.next.isIdentifier) {
- // Recovery
- if (identical(beforeName.stringValue, 'operator')) {
- // If the token before the invalid name is `operator`
- // then report the error on the `operator` keyword.
- reportRecoverableError(beforeName, fasta.messageTopLevelOperator);
- if (identifiers.isNotEmpty &&
- identical(identifiers.head.next.stringValue, 'operator')) {
- identifiers = identifiers.tail;
- }
- } else {
- reportRecoverableErrorWithToken(
- beforeName.next, fasta.templateUnexpectedToken);
- }
- // Insert a synthetic modifier
- // to be interpreted as the top level function's identifier.
- beforeName = beforeName.next;
- rewriter.insertTokenAfter(
- beforeName,
- new SyntheticStringToken(
- TokenType.IDENTIFIER,
- '#synthetic_function_${beforeName.charOffset}',
- beforeName.charOffset,
- 0));
- }
Token getOrSet;
- if (!identifiers.isEmpty) {
- String value = identifiers.head.next.stringValue;
- if ((identical(value, 'get')) || (identical(value, 'set'))) {
- getOrSet = identifiers.head.next;
- identifiers = identifiers.tail;
+ String value = next.stringValue;
+ if (identical(value, 'get') || identical(value, 'set')) {
+ if (next.next.isIdentifier) {
+ getOrSet = token = next;
+ next = token.next;
}
}
- Token beforeType;
- if (!identifiers.isEmpty) {
- Token maybeType = identifiers.head.next;
- if (isValidTypeReference(maybeType)) {
- beforeType = identifiers.head;
- identifiers = identifiers.tail;
- } else if (maybeType.type.isBuiltIn && optional('<', maybeType.next)) {
+
+ if (next.type != TokenType.IDENTIFIER) {
+ value = next.stringValue;
+ if (identical(value, 'factory') || identical(value, 'operator')) {
+ // `factory` and `operator` can be used as an identifier.
+ value = next.next.stringValue;
+ if (getOrSet == null &&
+ !identical(value, '(') &&
+ !identical(value, '{') &&
+ !identical(value, '<') &&
+ !identical(value, '=>') &&
+ !identical(value, '=') &&
+ !identical(value, ';') &&
+ !identical(value, ',')) {
+ // Recovery
+ value = next.stringValue;
+ if (identical(value, 'factory')) {
+ reportRecoverableError(
+ next, fasta.messageFactoryTopLevelDeclaration);
+ } else {
+ reportRecoverableError(next, fasta.messageTopLevelOperator);
+ if (next.next.isOperator) {
+ token = next;
+ next = token.next;
+ if (optional('(', next.next)) {
+ rewriter.insertTokenAfter(
+ next,
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER,
+ '#synthetic_identifier_${next.charOffset}',
+ next.charOffset,
+ 0));
+ }
+ }
+ }
+ listener.handleInvalidTopLevelDeclaration(next);
+ return next;
+ }
+ // Fall through and continue parsing
+ } else if (!next.isIdentifier) {
// Recovery
- // It is an error when built-in keyword is being used
- // as a type, as in `abstract<t> foo`.
- // This error is reported by parseFields and parseTopLevelMethod
- // via ensureIdentifier.
- beforeType = identifiers.head;
- identifiers = identifiers.tail;
- }
- }
-
- // Recovery: Anything left in the identifiers list is unexpected.
- if (identifiers.isNotEmpty) {
- identifiers = identifiers.reverse();
- while (identifiers.isNotEmpty) {
- Token token = identifiers.head;
- Token next = token.next;
- identifiers = identifiers.tail;
- // If we have find the start of a new top level declaration,
- // then return to parse that new declaration.
- if (next.isTopLevelKeyword) {
- listener.handleInvalidTopLevelDeclaration(token);
- return token;
- }
- // Report errors on any unexpected tokens.
- String value = next.stringValue;
- if (identical(value, 'operator')) {
- reportRecoverableError(next, fasta.messageTopLevelOperator);
- } else if (identical(value, 'factory')) {
- reportRecoverableError(next, fasta.messageFactoryTopLevelDeclaration);
+ if (next.isKeyword) {
+ reportRecoverableErrorWithToken(
+ next, fasta.templateExpectedIdentifier);
+ rewriter.insertTokenAfter(
+ next,
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER,
+ '#synthetic_identifier_${next.charOffset}',
+ next.charOffset,
+ 0));
+ token = next;
+ next = token.next;
+ } else if (token == beforeStart) {
+ // Ensure we make progress.
+ return reportInvalidTopLevelDeclaration(next);
} else {
- reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
+ // Looks like a declaration missing an identifier.
+ // Insert synthetic identifier and fall through.
+ rewriteAndRecover(
+ token,
+ fasta.templateExpectedIdentifier.withArguments(next),
+ new SyntheticStringToken(
+ TokenType.IDENTIFIER,
+ '#synthetic_identifier_${next.charOffset}',
+ next.charOffset,
+ 0));
+ next = token.next;
}
}
}
+ // At this point, `token` is beforeName.
- token = afterName;
- bool isField;
- while (true) {
- // Loop to allow the listener to rewrite the token stream for
- // error handling.
- final String value = token.stringValue;
- if ((identical(value, '(')) ||
- (identical(value, '{')) ||
- (identical(value, '=>'))) {
- isField = false;
- break;
- } else if (identical(value, '=') ||
- identical(value, ',') ||
- identical(value, '}')) {
- isField = true;
- break;
- } else if (identical(value, ';')) {
- if (getOrSet != null) {
- // If we found a "get" keyword, this must be an abstract
- // getter.
- isField = (!identical(getOrSet.stringValue, 'get'));
- // TODO(ahe): This feels like a hack.
- } else {
- isField = true;
- }
- break;
- } else {
- token = reportUnexpectedToken(token);
- if (identical(token.next.kind, EOF_TOKEN)) return token;
- }
- }
- if (isField) {
- if (externalToken != null) {
- reportRecoverableError(externalToken, fasta.messageExternalField);
- }
- if (getOrSet != null) {
- reportRecoverableErrorWithToken(
- getOrSet, fasta.templateExtraneousModifier);
- }
- return parseFields(
- beforeStart,
- externalToken,
- null,
- null,
- varFinalOrConst,
- beforeType,
- beforeName,
- MemberKind.TopLevelField,
- typeContinuation);
- } else {
+ next = next.next;
+ value = next.stringValue;
+ if (getOrSet != null ||
+ identical(value, '(') ||
+ identical(value, '{') ||
+ identical(value, '<') ||
+ identical(value, '.') ||
+ identical(value, '=>')) {
if (varFinalOrConst != null) {
- reportRecoverableErrorWithToken(
- varFinalOrConst, fasta.templateExtraneousModifier);
+ if (optional('var', varFinalOrConst)) {
+ reportRecoverableError(varFinalOrConst, fasta.messageVarReturnType);
+ } else {
+ reportRecoverableErrorWithToken(
+ varFinalOrConst, fasta.templateExtraneousModifier);
+ }
}
return parseTopLevelMethod(
- beforeStart, externalToken, beforeType, getOrSet, beforeName);
+ beforeStart, externalToken, beforeType, getOrSet, token);
}
+
+ if (getOrSet != null) {
+ reportRecoverableErrorWithToken(
+ getOrSet, fasta.templateExtraneousModifier);
+ }
+ return parseFields(beforeStart, externalToken, null, null, varFinalOrConst,
+ beforeType, token, MemberKind.TopLevelField, typeContinuation);
}
Token parseFields(
@@ -4243,6 +4351,8 @@
}
}
+ LoopState savedLoopState = loopState;
+ loopState = LoopState.OutsideLoop;
listener.beginBlockFunctionBody(begin);
token = next;
while (notEofOrValue('}', token.next)) {
@@ -4260,6 +4370,7 @@
token = token.next;
listener.endBlockFunctionBody(statementCount, begin, token);
expect('}', token);
+ loopState = savedLoopState;
return token;
}
@@ -5761,7 +5872,10 @@
}
expect(')', token);
listener.beginForStatementBody(token.next);
+ LoopState savedLoopState = loopState;
+ loopState = LoopState.InsideLoop;
token = parseStatement(token);
+ loopState = savedLoopState;
listener.endForStatementBody(token.next);
listener.endForStatement(
forToken, leftParenthesis, leftSeparator, expressionCount, token.next);
@@ -5789,7 +5903,10 @@
listener.endForInExpression(token);
expect(')', token);
listener.beginForInBody(token.next);
+ LoopState savedLoopState = loopState;
+ loopState = LoopState.InsideLoop;
token = parseStatement(token);
+ loopState = savedLoopState;
listener.endForInBody(token.next);
listener.endForIn(
awaitToken, forKeyword, leftParenthesis, inKeyword, token.next);
@@ -5807,7 +5924,10 @@
listener.beginWhileStatement(whileToken);
token = parseParenthesizedExpression(whileToken);
listener.beginWhileStatementBody(token.next);
+ LoopState savedLoopState = loopState;
+ loopState = LoopState.InsideLoop;
token = parseStatement(token);
+ loopState = savedLoopState;
listener.endWhileStatementBody(token.next);
listener.endWhileStatement(whileToken, token.next);
return token;
@@ -5823,7 +5943,10 @@
assert(optional('do', doToken));
listener.beginDoWhileStatement(doToken);
listener.beginDoWhileStatementBody(doToken.next);
+ LoopState savedLoopState = loopState;
+ loopState = LoopState.InsideLoop;
token = parseStatement(doToken).next;
+ loopState = savedLoopState;
listener.endDoWhileStatementBody(token);
Token whileToken = token;
expect('while', token);
@@ -6016,7 +6139,12 @@
assert(optional('switch', switchKeyword));
listener.beginSwitchStatement(switchKeyword);
token = parseParenthesizedExpression(switchKeyword);
+ LoopState savedLoopState = loopState;
+ if (loopState == LoopState.OutsideLoop) {
+ loopState = LoopState.InsideSwitch;
+ }
token = parseSwitchBlock(token);
+ loopState = savedLoopState;
listener.endSwitchStatement(switchKeyword, token);
return token;
}
@@ -6155,6 +6283,8 @@
if (token.next.isIdentifier) {
token = ensureIdentifier(token, IdentifierContext.labelReference);
hasTarget = true;
+ } else if (!isBreakAllowed) {
+ reportRecoverableError(breakKeyword, fasta.messageBreakOutsideOfLoop);
}
token = ensureSemicolon(token);
listener.handleBreakStatement(hasTarget, breakKeyword, token);
@@ -6233,6 +6363,16 @@
if (token.next.isIdentifier) {
token = ensureIdentifier(token, IdentifierContext.labelReference);
hasTarget = true;
+ if (!isContinueWithLabelAllowed) {
+ reportRecoverableError(
+ continueKeyword, fasta.messageContinueOutsideOfLoop);
+ }
+ } else if (!isContinueAllowed) {
+ reportRecoverableError(
+ continueKeyword,
+ loopState == LoopState.InsideSwitch
+ ? fasta.messageContinueWithoutLabelInCase
+ : fasta.messageContinueOutsideOfLoop);
}
token = ensureSemicolon(token);
listener.handleContinueStatement(hasTarget, continueKeyword, token);
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 2582768..fa54d3b 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -482,7 +482,7 @@
// redirecting factory bodies.
return;
}
- buildFunctionBody(bodyToken, lookupBuilder(beginToken, null, name),
+ buildFunctionBody(bodyToken, lookupConstructor(beginToken, name),
MemberKind.Factory, metadata);
}
@@ -521,7 +521,13 @@
// TODO(ahe): Don't skip this. We need to compile metadata.
return;
}
- ProcedureBuilder builder = lookupBuilder(beginToken, getOrSet, name);
+ ProcedureBuilder builder;
+ if (name is QualifiedName ||
+ (getOrSet == null && name == currentClass.name)) {
+ builder = lookupConstructor(beginToken, name);
+ } else {
+ builder = lookupBuilder(beginToken, getOrSet, name);
+ }
buildFunctionBody(
bodyToken,
builder,
@@ -735,18 +741,9 @@
listener.checkEmpty(token.charOffset);
}
- Builder lookupBuilder(Token token, Token getOrSet, Object nameOrQualified) {
+ Builder lookupBuilder(Token token, Token getOrSet, String name) {
// TODO(ahe): Can I move this to Scope or ScopeBuilder?
Builder builder;
- String name;
- String suffix;
- if (nameOrQualified is QualifiedName) {
- name = nameOrQualified.prefix;
- suffix = nameOrQualified.suffix;
- assert(currentClass != null);
- } else {
- name = nameOrQualified;
- }
if (currentClass != null) {
if (uri != currentClass.fileUri) {
unexpected("$uri", "${currentClass.fileUri}", currentClass.charOffset,
@@ -756,40 +753,46 @@
if (getOrSet != null && optional("set", getOrSet)) {
builder = currentClass.scope.setters[name];
} else {
- if (name == currentClass.name) {
- suffix ??= "";
- }
- if (suffix != null) {
- builder = currentClass.constructors.local[suffix];
- } else {
- builder = currentClass.constructors.local[name];
- if (builder == null) {
- builder = currentClass.scope.local[name];
- }
- }
+ builder = currentClass.scope.local[name];
}
} else if (getOrSet != null && optional("set", getOrSet)) {
builder = library.scope.setters[name];
} else {
builder = library.scopeBuilder[name];
}
+ checkBuilder(token, builder, name);
+ return builder;
+ }
+
+ Builder lookupConstructor(Token token, Object nameOrQualified) {
+ assert(currentClass != null);
+ Builder builder;
+ String name;
+ String suffix;
+ if (nameOrQualified is QualifiedName) {
+ name = nameOrQualified.prefix;
+ suffix = nameOrQualified.suffix;
+ } else {
+ name = nameOrQualified;
+ suffix = name == currentClass.name ? "" : name;
+ }
+ builder = currentClass.constructors.local[suffix];
+ checkBuilder(token, builder, nameOrQualified);
+ return builder;
+ }
+
+ void checkBuilder(Token token, Builder builder, Object name) {
if (builder == null) {
- return internalProblem(
- templateInternalProblemNotFound.withArguments(name),
- token.charOffset,
- uri);
+ internalProblem(templateInternalProblemNotFound.withArguments("$name"),
+ token.charOffset, uri);
}
if (builder.next != null) {
- String errorName = suffix == null ? name : "$name.$suffix";
- return deprecated_inputError(
- uri, token.charOffset, "Duplicated name: $errorName");
+ deprecated_inputError(uri, token.charOffset, "Duplicated name: $name");
}
-
if (uri != builder.fileUri) {
unexpected(
"$uri", "${builder.fileUri}", builder.charOffset, builder.fileUri);
}
- return builder;
}
@override
diff --git a/pkg/front_end/lib/src/fasta/source/source_graph.dart b/pkg/front_end/lib/src/fasta/source/source_graph.dart
deleted file mode 100644
index 00297c6..0000000
--- a/pkg/front_end/lib/src/fasta/source/source_graph.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library fasta.source_graph;
-
-import '../builder/builder.dart' show LibraryBuilder;
-
-import '../export.dart' show Export;
-
-import '../graph/graph.dart' show Graph;
-
-import '../import.dart' show Import;
-
-import 'source_library_builder.dart' show SourceLibraryBuilder;
-
-class SourceGraph implements Graph<Uri> {
- final Map<Uri, LibraryBuilder> builders;
-
- SourceGraph(this.builders);
-
- Iterable<Uri> get vertices => builders.keys;
-
- Iterable<Uri> neighborsOf(Uri vertex) sync* {
- SourceLibraryBuilder library = builders[vertex];
- if (library == null) {
- throw "Library not found: $vertex";
- }
- for (Import import in library.imports) {
- Uri uri = import.imported.uri;
- if (builders.containsKey(uri)) {
- yield uri;
- }
- }
- for (Export export in library.exports) {
- Uri uri = export.exported.uri;
- if (builders.containsKey(uri)) {
- yield uri;
- }
- }
- for (SourceLibraryBuilder part in library.parts) {
- Uri uri = part.uri;
- if (builders.containsKey(uri)) {
- yield uri;
- }
- }
- }
-}
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 7835088..e58f517 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -210,8 +210,8 @@
LibraryBuilder coreLibrary =
loader.read(resolve(this.uri, "dart:core", -1), -1);
- LibraryBuilder imported = coreLibrary
- .loader.builders[new Uri(scheme: 'dart', path: dottedName)];
+ LibraryBuilder imported =
+ coreLibrary.loader.builders[new Uri(scheme: 'dart', path: dottedName)];
return imported != null ? "true" : "";
}
@@ -399,7 +399,9 @@
}
bool isConstructor = builder is ProcedureBuilder &&
(builder.isConstructor || builder.isFactory);
- if (!isConstructor && name == currentDeclaration.name) {
+ if (!isConstructor &&
+ !builder.isSetter &&
+ name == currentDeclaration.name) {
addCompileTimeError(
messageMemberWithSameNameAsClass, charOffset, fileUri);
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index caa6991..febb348 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -417,7 +417,7 @@
}
function.body = new ReturnStatement(superCall)..parent = function;
procedure.transformerFlags |= TransformerFlag.superCalls;
- procedure.forwardingStubSuperTarget = superTarget.reference;
+ procedure.forwardingStubSuperTarget = superTarget;
}
/// Creates a forwarding stub based on the given [target].
@@ -465,7 +465,7 @@
returnType: substitution.substituteType(target.function.returnType));
Member finalTarget;
if (target is Procedure && target.isForwardingStub) {
- finalTarget = target.forwardingStubInterfaceTarget.node;
+ finalTarget = target.forwardingStubInterfaceTarget;
} else if (target is SyntheticAccessor) {
finalTarget = target._field;
} else {
@@ -475,7 +475,7 @@
isAbstract: true,
isForwardingStub: true,
fileUri: enclosingClass.fileUri,
- forwardingStubInterfaceTarget: finalTarget.reference)
+ forwardingStubInterfaceTarget: finalTarget)
..fileOffset = enclosingClass.fileOffset
..parent = enclosingClass
..isGenericContravariant = target.isGenericContravariant;
@@ -804,8 +804,7 @@
resolution = member;
}
if (resolution is Procedure &&
- resolution.isForwardingStub &&
- !resolution.isForwardingSemiStub &&
+ resolution.isSyntheticForwarder &&
identical(resolution.enclosingClass, class_)) {
if (strongMode) class_.addMember(resolution);
_instrumentation?.record(
@@ -978,7 +977,7 @@
for (var procedure in class_.procedures) {
if (procedure.isStatic) continue;
// Forwarding stubs are annotated separately
- if (procedure.isForwardingStub && !procedure.isForwardingSemiStub) {
+ if (procedure.isSyntheticForwarder) {
continue;
}
void recordFormalAnnotations(VariableDeclaration formal) {
diff --git a/pkg/front_end/lib/src/fasta/util/link.dart b/pkg/front_end/lib/src/fasta/util/link.dart
index 80e21ff..86c1c70 100644
--- a/pkg/front_end/lib/src/fasta/util/link.dart
+++ b/pkg/front_end/lib/src/fasta/util/link.dart
@@ -114,7 +114,7 @@
/// Returns true if f returns true for all elements of this list.
///
/// Returns true for the empty list.
- bool every(bool f(T)) {
+ bool every(bool f(T e)) {
for (Link<T> link = this; !link.isEmpty; link = link.tail) {
if (!f(link.head)) return false;
}
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 2fd52f9..7882c3b 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -565,6 +565,30 @@
script:
- "class C { static operator +(int x) => x + 1; }"
+BreakOutsideOfLoop:
+ template: "A break statement can't be used outside of a loop or switch statement."
+ tip: "Try removing the break statement."
+ analyzerCode: BREAK_OUTSIDE_OF_LOOP
+ dart2jsCode: "*ignored*"
+ script:
+ - "main() { break; }"
+
+ContinueOutsideOfLoop:
+ template: "A continue statement can't be used outside of a loop or switch statement."
+ tip: "Try removing the continue statement."
+ analyzerCode: CONTINUE_OUTSIDE_OF_LOOP
+ dart2jsCode: "*ignored*"
+ script:
+ - "main() { continue; }"
+
+ContinueWithoutLabelInCase:
+ template: "A continue statement in a switch statement must have a label as a target."
+ tip: "Try adding a label associated with one of the case clauses to the continue statement."
+ analyzerCode: CONTINUE_WITHOUT_LABEL_IN_CASE
+ dart2jsCode: "*ignored*"
+ script:
+ - "main() { switch (x) {case 1: continue;} }"
+
InvalidAwaitFor:
template: "The keyword 'await' isn't allowed for a normal 'for' statement."
tip: "Try removing the keyword, or use a for-each statement."
@@ -1041,12 +1065,6 @@
template: "Unimplemented #string."
severity: INTERNAL_PROBLEM
-UnimplementedBoundsOnTypeVariables:
- # Has its own message to make it just a warning.
- # TODO(askesc): Remove when no longer needed.
- template: "Unimplemented bounds on type variables."
- severity: WARNING
-
InternalProblemUnexpected:
template: "Expected '#string', but got '#string2'."
severity: INTERNAL_PROBLEM
@@ -1151,6 +1169,13 @@
analyzerCode: DUPLICATE_DEFERRED
dart2jsCode: "*fatal*"
+DeferredTypeAnnotation:
+ template: "The type '#type' is deferred loaded via prefix '#name' and can't be used as a type annotation."
+ tip: "Try removing 'deferred' from the import of '#name' or use a supertype of '#type' that isn't deferred."
+ severity: ERROR_LEGACY_WARNING
+ analyzerCode: TYPE_ANNOTATION_DEFERRED_CLASS
+ dart2jsCode: "*fatal*"
+
DuplicatePrefix:
template: "An import directive can only have one prefix ('as' clause)."
tip: "Try removing all but one prefix."
@@ -1398,7 +1423,7 @@
template: "Top-level declarations can't be declared to be 'factory'."
tip: "Try removing the keyword 'factory'."
analyzerCode: FACTORY_TOP_LEVEL_DECLARATION
- dart2jsCode: "*ignored*"
+ dart2jsCode: "*fatal*"
script:
- "factory class C {}"
@@ -1414,7 +1439,7 @@
template: "Operators must be declared within a class."
tip: "Try removing the operator, moving it to a class, or converting it to be a function."
analyzerCode: TOP_LEVEL_OPERATOR
- dart2jsCode: "*ignored*"
+ dart2jsCode: "*fatal*"
script:
- "operator +(bool x, bool y) => x | y;"
- "bool operator +(bool x, bool y) => x | y;"
@@ -1675,6 +1700,8 @@
IntegerLiteralIsOutOfRange:
template: "The integer literal #lexeme can't be represented in 64 bits."
tip: "Try using the BigInt class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808."
+ analyzerCode: INTEGER_LITERAL_OUT_OF_RANGE
+ dart2jsCode: "*fatal*"
ColonInPlaceOfIn:
template: "For-in loops use 'in' rather than a colon."
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 7b6e9cc..370ee5b 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,5 +1,5 @@
name: front_end
-version: 0.1.0-alpha.7
+version: 0.1.0-alpha.8
author: Dart Team <misc@dartlang.org>
description: Front end for compilation of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
@@ -9,7 +9,7 @@
charcode: '^1.1.1'
convert: '^2.0.1'
crypto: '^2.0.2'
- kernel: 0.3.0-alpha.4
+ kernel: 0.3.0-alpha.5
meta: '^1.1.1'
package_config: '^1.0.1'
path: '^1.3.9'
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 00f49bf..d40576b 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -241,7 +241,7 @@
File generated = new File.fromUri(uri);
StdioProcess process;
try {
- var args = ['--kernel-binaries=${context.platformBinaries.toFilePath()}'];
+ var args = [];
if (context.strongMode) {
args.add('--strong');
args.add('--reify-generic-functions');
diff --git a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
index 76dd52c..269c4c6 100644
--- a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
@@ -740,7 +740,7 @@
expect(y.isGenericCovariantImpl, isFalse);
expect(y.isGenericCovariantInterface, isFalse);
expect(y.isCovariant, isTrue);
- expect(stub.forwardingStubInterfaceTarget.node, same(methodA));
+ expect(stub.forwardingStubInterfaceTarget, same(methodA));
expect(getStubTarget(stub), same(methodA));
}
@@ -788,7 +788,7 @@
expect(y.isGenericCovariantImpl, isTrue);
expect(y.isGenericCovariantInterface, isFalse);
expect(y.isCovariant, isFalse);
- expect(stub.forwardingStubInterfaceTarget.node, same(methodA));
+ expect(stub.forwardingStubInterfaceTarget, same(methodA));
expect(getStubTarget(stub), same(methodA));
}
@@ -833,7 +833,7 @@
]);
var nodeE = getForwardingNode(e, false);
var stub = nodeE.finalize();
- expect(stub.forwardingStubInterfaceTarget.node, same(methodC));
+ expect(stub.forwardingStubInterfaceTarget, same(methodC));
expect(getStubTarget(stub), same(methodC));
}
@@ -866,7 +866,7 @@
implementedTypes: [i2.asThisSupertype]);
var nodeE = getForwardingNode(e, true);
var stub = nodeE.finalize();
- expect(stub.forwardingStubInterfaceTarget.node, same(setterC));
+ expect(stub.forwardingStubInterfaceTarget, same(setterC));
expect(getStubTarget(stub), same(setterC));
}
@@ -881,7 +881,7 @@
implementedTypes: [b.asThisSupertype]);
var node = getForwardingNode(c, false);
var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget.node, same(fieldB));
+ expect(stub.forwardingStubInterfaceTarget, same(fieldB));
}
void test_merge_candidates_including_mixin() {
@@ -976,7 +976,7 @@
name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
var node = getForwardingNode(c, false);
var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget.node, same(methodB));
+ expect(stub.forwardingStubInterfaceTarget, same(methodB));
expect(getStubTarget(stub), isNull);
expect(stub.function.returnType, intType);
}
@@ -995,7 +995,7 @@
]);
var node = getForwardingNode(d, true);
var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget.node, same(setterB));
+ expect(stub.forwardingStubInterfaceTarget, same(setterB));
expect(getStubTarget(stub), isNull);
expect(stub.function.positionalParameters[0].type, objectType);
}
@@ -1057,7 +1057,7 @@
]);
var node = getForwardingNode(d, false);
var stub = node.finalize();
- expect(stub.forwardingStubInterfaceTarget.node, same(methodB));
+ expect(stub.forwardingStubInterfaceTarget, same(methodB));
expect(getStubTarget(stub), isNull);
expect(stub.function.returnType, intType);
}
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
new file mode 100644
index 0000000..6a9403f
--- /dev/null
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -0,0 +1,120 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async' show Future;
+import 'dart:io' show Directory, File;
+
+import 'package:expect/expect.dart' show Expect;
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+ show CompilerOptions;
+import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart'
+ show IncrementalKernelGenerator;
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+ show computePlatformBinariesLocation;
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+ show IncrementalCompiler;
+import 'package:front_end/src/fasta/kernel/utils.dart' show writeProgramToFile;
+
+final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
+final Uri invalidateUri = Uri.parse("package:compiler/src/filenames.dart");
+Directory outDir;
+Uri normalDill;
+Uri bootstrappedDill;
+
+main() async {
+ outDir =
+ Directory.systemTemp.createTempSync("incremental_load_from_dill_test");
+ normalDill = outDir.uri.resolve("dart2js.full.dill");
+ bootstrappedDill = outDir.uri.resolve("dart2js.bootstrap.dill");
+ Uri nonexisting = outDir.uri.resolve("dart2js.nonexisting.dill");
+ Uri nonLoadable = outDir.uri.resolve("dart2js.nonloadable.dill");
+ try {
+ // Compile dart2js without bootstrapping.
+ Stopwatch stopwatch = new Stopwatch()..start();
+ await normalCompile();
+ print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
+
+ // Create a file that cannot be (fully) loaded as a dill file.
+ List<int> corruptData = new File.fromUri(normalDill).readAsBytesSync();
+ for (int i = 10 * (corruptData.length ~/ 16);
+ i < 15 * (corruptData.length ~/ 16);
+ ++i) {
+ corruptData[i] = 42;
+ }
+ new File.fromUri(nonLoadable).writeAsBytesSync(corruptData);
+
+ // Compile dart2js, bootstrapping from the just-compiled dill.
+ for (List<Object> bootstrapData in [
+ [normalDill, true],
+ [nonexisting, false],
+ // [nonLoadable, false] // disabled for now
+ ]) {
+ Uri bootstrapWith = bootstrapData[0];
+ bool bootstrapExpect = bootstrapData[1];
+ stopwatch.reset();
+ bool bootstrapResult = await bootstrapCompile(bootstrapWith);
+ Expect.equals(bootstrapExpect, bootstrapResult);
+ print("Bootstrapped compile(s) from ${bootstrapWith.pathSegments.last} "
+ "took ${stopwatch.elapsedMilliseconds} ms");
+
+ // Compare the two files.
+ List<int> normalDillData = new File.fromUri(normalDill).readAsBytesSync();
+ List<int> bootstrappedDillData =
+ new File.fromUri(bootstrappedDill).readAsBytesSync();
+ Expect.equals(normalDillData.length, bootstrappedDillData.length);
+ for (int i = 0; i < normalDillData.length; ++i) {
+ if (normalDillData[i] != bootstrappedDillData[i]) {
+ Expect.fail("Normally compiled and bootstrapped compile differs.");
+ }
+ }
+ }
+ } finally {
+ outDir.deleteSync(recursive: true);
+ }
+}
+
+CompilerOptions getOptions() {
+ final Uri sdkRoot = computePlatformBinariesLocation();
+ var options = new CompilerOptions()
+ ..sdkRoot = sdkRoot
+ ..librariesSpecificationUri = Uri.base.resolve("sdk/lib/libraries.json")
+ ..strongMode = false;
+ return options;
+}
+
+Future<bool> normalCompile() async {
+ CompilerOptions options = getOptions();
+ IncrementalCompiler compiler =
+ new IncrementalKernelGenerator(options, dart2jsUrl);
+ var y = await compiler.computeDelta();
+ await writeProgramToFile(y, normalDill);
+ return compiler.bootstrapSuccess;
+}
+
+Future<bool> bootstrapCompile(Uri bootstrapWith) async {
+ CompilerOptions options = getOptions();
+ IncrementalCompiler compiler =
+ new IncrementalKernelGenerator(options, dart2jsUrl, bootstrapWith);
+ compiler.invalidate(invalidateUri);
+ var bootstrappedProgram = await compiler.computeDelta();
+ bool result = compiler.bootstrapSuccess;
+ await writeProgramToFile(bootstrappedProgram, bootstrappedDill);
+ compiler.invalidate(invalidateUri);
+
+ var partialProgram = await compiler.computeDelta();
+ var emptyProgram = await compiler.computeDelta();
+
+ var fullLibUris =
+ bootstrappedProgram.libraries.map((lib) => lib.importUri).toList();
+ var partialLibUris =
+ partialProgram.libraries.map((lib) => lib.importUri).toList();
+ var emptyLibUris =
+ emptyProgram.libraries.map((lib) => lib.importUri).toList();
+
+ Expect.isTrue(fullLibUris.length > partialLibUris.length);
+ Expect.isTrue(partialLibUris.isNotEmpty);
+ Expect.isTrue(emptyLibUris.isEmpty);
+
+ return result;
+}
diff --git a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
index 9b33737..932fa35 100644
--- a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
@@ -102,7 +102,6 @@
var vmArgs = [
'--enable-vm-service=0', // Note: use 0 to avoid port collisions.
'--pause_isolates_on_start',
- '--kernel-binaries=${sdkRoot.toFilePath()}',
outputUri.toFilePath()
];
vmArgs.add('$reloadCount');
diff --git a/pkg/front_end/test/subpackage_relationships_test.dart b/pkg/front_end/test/subpackage_relationships_test.dart
index a0bc923..3875706 100644
--- a/pkg/front_end/test/subpackage_relationships_test.dart
+++ b/pkg/front_end/test/subpackage_relationships_test.dart
@@ -70,6 +70,7 @@
'lib/src/base',
'lib/src/fasta/builder',
'lib/src/fasta/dill',
+ 'lib/src/fasta/graph',
'lib/src/fasta/kernel',
'lib/src/fasta/parser',
'lib/src/fasta/scanner',
@@ -118,7 +119,6 @@
'lib/src/base',
'lib/src/fasta/builder',
'lib/src/fasta/dill',
- 'lib/src/fasta/graph',
'lib/src/fasta/kernel',
'lib/src/fasta/parser',
'lib/src/fasta/type_inference',
diff --git a/pkg/front_end/testcases/ast_builder.status b/pkg/front_end/testcases/ast_builder.status
index 4e4c471..b464fce 100644
--- a/pkg/front_end/testcases/ast_builder.status
+++ b/pkg/front_end/testcases/ast_builder.status
@@ -10,11 +10,15 @@
argument_mismatch: Crash
bad_setter_abstract: Crash
cascade: Crash
-check_deferred_read: Crash
-check_deferred_before_write: Crash
-check_deferred_before_call: Crash
-check_deferred_before_args: Crash
+check_deferred_allocation: Crash
check_deferred_before_args2: Crash
+check_deferred_before_args: Crash
+check_deferred_before_call: Crash
+check_deferred_before_write: Crash
+check_deferred_read: Crash
+check_deferred_read_static_field: Crash
+check_deferred_read_type: Crash
+check_deferred_static_method_call: Crash
classes: Crash
duplicated_named_args_3: Crash
dynamic_and_void: Fail
@@ -118,7 +122,6 @@
rasta/previsit_deferred: Crash
rasta/static: Crash
rasta/super_initializer: Crash
-rasta/supports_reflection: VerificationError
rasta/type_literals: Crash
rasta/typedef: Crash
rasta/unresolved: Crash
@@ -143,6 +146,8 @@
regress/issue_31187: Crash
regress/issue_31198: Crash
regress/issue_31213: Crash
+regress/issue_31299: Crash
+regress/issue_31766: Crash
reorder_super: Crash
runtime_checks/implicit_downcast_assert_initializer: Crash
runtime_checks/implicit_downcast_constructor_initializer: Crash
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart b/pkg/front_end/testcases/check_deferred_allocation.dart
new file mode 100644
index 0000000..3bf29bf
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {
+ print(new lib.C());
+}
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.direct.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.direct.expect
new file mode 100644
index 0000000..25dc9b8
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.direct.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
+}
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.outline.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method test() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
new file mode 100644
index 0000000..25dc9b8
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
+}
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart b/pkg/front_end/testcases/check_deferred_as_check.dart
new file mode 100644
index 0000000..e9d17ff
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {
+ x as lib.C;
+}
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.direct.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.direct.expect
new file mode 100644
index 0000000..d17f162
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.direct.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+ x as invalid-type;
+}
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.outline.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.outline.expect
new file mode 100644
index 0000000..dc16c61
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method test(dynamic x) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.strong.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.expect
new file mode 100644
index 0000000..bd033e5
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Error: The type '#lib1::C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.\nTry removing 'deferred' from the import of 'lib' or use a supertype of '#lib1::C' that isn't deferred.\n x as lib.C;\n ^"]/* from null */;
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+ x as invalid-type;
+}
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart b/pkg/front_end/testcases/check_deferred_is_check.dart
new file mode 100644
index 0000000..7069d9a
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test(x) {
+ print(x is lib.C);
+}
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.direct.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.direct.expect
new file mode 100644
index 0000000..8fa0c48
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.direct.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+ core::print(x is invalid-type);
+}
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.outline.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.outline.expect
new file mode 100644
index 0000000..dc16c61
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method test(dynamic x) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.strong.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.expect
new file mode 100644
index 0000000..c612334
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Error: The type '#lib1::C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.\nTry removing 'deferred' from the import of 'lib' or use a supertype of '#lib1::C' that isn't deferred.\n print(x is lib.C);\n ^"]/* from null */;
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+ core::print(x is invalid-type);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart b/pkg/front_end/testcases/check_deferred_read_static_field.dart
new file mode 100644
index 0000000..0a446f7
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {
+ print(lib.C.y);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.direct.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.direct.expect
new file mode 100644
index 0000000..7b3c2df
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.direct.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.outline.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method test() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
new file mode 100644
index 0000000..7b3c2df
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart b/pkg/front_end/testcases/check_deferred_read_type.dart
new file mode 100644
index 0000000..be64b65
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {
+ print(lib.C);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.direct.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.direct.expect
new file mode 100644
index 0000000..4c3620c
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.direct.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.outline.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method test() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
new file mode 100644
index 0000000..4c3620c
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C);
+}
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart b/pkg/front_end/testcases/check_deferred_static_method_call.dart
new file mode 100644
index 0000000..63008c6
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {
+ print(lib.C.m());
+}
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.direct.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.direct.expect
new file mode 100644
index 0000000..05236e5
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.direct.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
+}
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.outline.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method test() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
new file mode 100644
index 0000000..05236e5
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+ core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
+}
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart b/pkg/front_end/testcases/check_deferred_type_declaration.dart
new file mode 100644
index 0000000..f3cc305
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() => test();
+test() {
+ lib.C x = null;
+}
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.direct.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.direct.expect
new file mode 100644
index 0000000..fe4fe2e
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.direct.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ return self::test();
+static method test() → dynamic {
+ invalid-type x = null;
+}
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.outline.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+ ;
+static method test() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.expect
new file mode 100644
index 0000000..944b59d
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Error: The type '#lib1::C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.\nTry removing 'deferred' from the import of 'lib' or use a supertype of '#lib1::C' that isn't deferred.\n lib.C x = null;\n ^"]/* from null */;
+static method main() → dynamic
+ return self::test();
+static method test() → dynamic {
+ invalid-type x = null;
+}
diff --git a/pkg/front_end/testcases/deferred_lib.dart b/pkg/front_end/testcases/deferred_lib.dart
index b08a2df..94f5f06 100644
--- a/pkg/front_end/testcases/deferred_lib.dart
+++ b/pkg/front_end/testcases/deferred_lib.dart
@@ -5,3 +5,8 @@
dynamic m(x) => null;
var x = 0;
+
+class C {
+ static int y = 1;
+ static int m() => 2;
+}
diff --git a/pkg/front_end/testcases/rasta/supports_reflection.dart.strong.expect b/pkg/front_end/testcases/rasta/supports_reflection.dart.strong.expect
new file mode 100644
index 0000000..b7bfa56
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/supports_reflection.dart.strong.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+ core::print(const core::bool::fromEnvironment("dart.library.mirrors"));
+}
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart b/pkg/front_end/testcases/regress/issue_30834.dart
new file mode 100644
index 0000000..12a2a33
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+ set A(v) {}
+}
+
+main() {
+ var a = new A();
+ a.A = 5;
+}
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.direct.expect b/pkg/front_end/testcases/regress/issue_30834.dart.direct.expect
new file mode 100644
index 0000000..de8a7cd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.direct.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ set A(dynamic v) → dynamic {}
+}
+static method main() → dynamic {
+ dynamic a = new self::A::•();
+ a.A = 5;
+}
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
new file mode 100644
index 0000000..c591247
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ ;
+ set A(dynamic v) → dynamic
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.strong.expect b/pkg/front_end/testcases/regress/issue_30834.dart.strong.expect
new file mode 100644
index 0000000..21d109e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.strong.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ set A(dynamic v) → void {}
+}
+static method main() → dynamic {
+ self::A a = new self::A::•();
+ a.{self::A::A} = 5;
+}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart b/pkg/front_end/testcases/regress/issue_31299.dart
new file mode 100644
index 0000000..27c47ab
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+ int m;
+ A() : m = 1;
+
+ // Named constructor may not conflict with names of methods and fields.
+ A.foo() : m = 2;
+ int foo(int a, int b) => a + b * m;
+}
+
+test() {
+ new A().foo();
+ new A().foo(1, 2);
+ new A.foo();
+ new A.foo(1, 2);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
new file mode 100644
index 0000000..88fec62
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.direct.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int m;
+ constructor •() → void
+ : self::A::m = 1, super core::Object::•()
+ ;
+ constructor foo() → void
+ : self::A::m = 2, super core::Object::•()
+ ;
+ method foo(core::int a, core::int b) → core::int
+ return a.+(b.*(this.{self::A::m}));
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31299.dart:10:3: Error: Conflicts with member 'foo'.\n A.foo() : m = 2;\n ^", "pkg/front_end/testcases/regress/issue_31299.dart:11:7: Error: Conflicts with constructor 'A.foo'.\n int foo(int a, int b) => a + b * m;\n ^"]/* from null */;
+static method test() → dynamic {
+ new self::A::•().foo();
+ new self::A::•().foo(1, 2);
+ new self::A::foo();
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31299.dart.outline.expect
new file mode 100644
index 0000000..caa88eb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.outline.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int m;
+ constructor •() → void
+ ;
+ constructor foo() → void
+ ;
+ method foo(core::int a, core::int b) → core::int
+ ;
+}
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
new file mode 100644
index 0000000..d8441ee
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.strong.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int m;
+ constructor •() → void
+ : self::A::m = 1, super core::Object::•()
+ ;
+ constructor foo() → void
+ : self::A::m = 2, super core::Object::•()
+ ;
+ method foo(core::int a, core::int b) → core::int
+ return a.{core::num::+}(b.{core::num::*}(this.{self::A::m}));
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31299.dart:10:3: Error: Conflicts with member 'foo'.\n A.foo() : m = 2;\n ^", "pkg/front_end/testcases/regress/issue_31299.dart:11:7: Error: Conflicts with constructor 'A.foo'.\n int foo(int a, int b) => a + b * m;\n ^", "pkg/front_end/testcases/regress/issue_31299.dart:18:7: Error: Method not found: 'foo'.\n new A.foo(1, 2);\n ^"]/* from null */;
+static method test() → dynamic {
+ new self::A::•().{self::A::foo}();
+ new self::A::•().{self::A::foo}(1, 2);
+ new self::A::foo();
+ throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart b/pkg/front_end/testcases/regress/issue_31766.dart
new file mode 100644
index 0000000..491cb00
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+ foo() => null;
+}
+
+main() {
+ void bar<T extends A>(T t) {
+ print("t.foo()=${t.foo()}");
+ }
+
+ bar(new A());
+
+ (<S extends A>(S s) {
+ print("s.foo()=${s.foo()}");
+ })(new A());
+}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31766.dart.direct.expect
new file mode 100644
index 0000000..ad01f98
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.direct.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return null;
+}
+static method main() → dynamic {
+ function bar<T extends self::A>(T t) → void {
+ core::print("t.foo()=${t.foo()}");
+ }
+ bar.call(new self::A::•());
+ (<S extends self::A>(S s) → dynamic {
+ core::print("s.foo()=${s.foo()}");
+ }).call(new self::A::•());
+}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31766.dart.outline.expect
new file mode 100644
index 0000000..54cb769
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.outline.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ ;
+ method foo() → dynamic
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
new file mode 100644
index 0000000..5228fa9
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return null;
+}
+static method main() → dynamic {
+ function bar<T extends self::A>(T t) → void {
+ core::print("t.foo()=${t.{self::A::foo}()}");
+ }
+ bar.call<self::A>(new self::A::•());
+ (<S extends self::A>(S s) → core::Null {
+ core::print("s.foo()=${s.{self::A::foo}()}");
+ }).call<self::A>(new self::A::•());
+}
diff --git a/pkg/front_end/testcases/sdk.status b/pkg/front_end/testcases/sdk.status
index 5adfa9f..38cd79e 100644
--- a/pkg/front_end/testcases/sdk.status
+++ b/pkg/front_end/testcases/sdk.status
@@ -2,7 +2,12 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE.md file.
-language/bad_constructor_test/06_generated: Crash
+language/branches_test: Crash
+language/operator_test: Crash
+language/prefix5_negative_test: Crash
+language_2/branches_test: Crash
+language_2/operator_test: Crash
+language_2/prefix5_negative_test: Crash
language/async_test/constructor4_generated: VerificationError
language/const_factory_with_body_test/01_generated: VerificationError
@@ -10,7 +15,6 @@
language/constructor10_test/00_generated: VerificationError
language/constructor10_test/01_generated: VerificationError
language/constructor10_test/02_generated: VerificationError
-language/deferred_closurize_load_library_test: VerificationError
language/enum_syntax_test/20_generated: VerificationError
language/enum_syntax_test/22_generated: VerificationError
language/malformed_inheritance_test/03_generated: VerificationError
@@ -46,8 +50,6 @@
language_2/constructor10_test/00_generated: VerificationError
language_2/constructor10_test/01_generated: VerificationError
language_2/constructor10_test/02_generated: VerificationError
-language_2/covariant_subtyping_test: VerificationError
-language_2/deferred_closurize_load_library_test: VerificationError
language_2/enum_syntax_test/20_generated: VerificationError
language_2/enum_syntax_test/22_generated: VerificationError
language_2/malformed_inheritance_test/02_generated: VerificationError
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 96c1038..32163f0 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -179,7 +179,6 @@
rasta/super_initializer: Fail
rasta/super_mixin: TypeCheckError
rasta/super_operator: Fail
-rasta/supports_reflection: VerificationError
rasta/switch_execution_case_t02: Fail
rasta/switch_fall_through: Fail
rasta/this_invoke: Fail
@@ -199,6 +198,7 @@
regress/issue_30836: RuntimeError # Issue 30836.
regress/issue_31155: Crash # Issue 31155.
regress/issue_31184: TypeCheckError
+regress/issue_31299: TypeCheckError
runtime_checks/forwarding_stub_with_default_values: RuntimeError # Bug 31027
runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 0771100..ac2d0fe 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -167,6 +167,7 @@
"/sdk/tests/language/round_test\\.dart$",
"/sdk/tests/language_2/arg_param_trailing_comma_test\\.dart$",
"/sdk/tests/language_2/async_switch_test\\.dart$",
+ "/sdk/tests/language_2/built_in_identifier_type_annotation_test\\.dart$",
"/sdk/tests/language_2/case_expression_with_assignment_test\\.dart$",
"/sdk/tests/language_2/constructor_redirect1_negative_test\\.dart$",
"/sdk/tests/language_2/deferred_type_dependency_test\\.dart$",
@@ -176,6 +177,7 @@
"/sdk/tests/language_2/field_initialization_order_test\\.dart$",
"/sdk/tests/language_2/field_override_test\\.dart$",
"/sdk/tests/language_2/field3_test\\.dart$",
+ "/sdk/tests/language_2/known_identifier_usage_test\\.dart$",
"/sdk/tests/language_2/map_literal11_test\\.dart$",
"/sdk/tests/language_2/round_test\\.dart$",
"/sdk/tests/language_2/regress_23996_test\\.dart$",
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index aeb2bb5..a25d6be 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -228,9 +228,13 @@
final bool strongMode =
options.containsKey("--strong-mode") || options.containsKey("--strong");
+ final bool syncAsync = options.containsKey("--sync-async");
+
final String targetName = options["-t"] ?? options["--target"] ?? "vm";
- final TargetFlags flags = new TargetFlags(strongMode: strongMode);
+ final TargetFlags flags =
+ new TargetFlags(strongMode: strongMode, syncAsync: syncAsync);
+
final Target target = getTarget(targetName, flags);
if (target == null) {
return throw new CommandLineProblem.deprecated(
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index 399de1c..aabac5e 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -44,7 +44,10 @@
..addOption('transformation',
abbr: 't',
help: 'The transformation to apply.',
- defaultsTo: 'continuation');
+ defaultsTo: 'continuation')
+ ..addFlag('sync-async',
+ help: 'Whether `async` functions start synchronously.',
+ defaultsTo: false);
main(List<String> arguments) async {
if (arguments.isNotEmpty && arguments[0] == '--batch') {
@@ -69,6 +72,7 @@
var output = options['out'];
var format = options['format'];
var verbose = options['verbose'];
+ var syncAsync = options['sync-async'];
if (output == null) {
output = '${input.substring(0, input.lastIndexOf('.'))}.transformed.dill';
@@ -85,7 +89,7 @@
final hierarchy = new ClassHierarchy(program);
switch (options['transformation']) {
case 'continuation':
- program = cont.transformProgram(coreTypes, program);
+ program = cont.transformProgram(coreTypes, program, syncAsync);
break;
case 'resolve-mixins':
mix.transformLibraries(
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index c07f52a..dcbffd3 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1486,10 +1486,37 @@
/// The uri of the source file this procedure was loaded from.
Uri fileUri;
- Reference forwardingStubSuperTarget;
- Reference forwardingStubInterfaceTarget;
+ Reference forwardingStubSuperTargetReference;
+ Reference forwardingStubInterfaceTargetReference;
- Procedure(Name name, this.kind, this.function,
+ Procedure(Name name, ProcedureKind kind, FunctionNode function,
+ {bool isAbstract: false,
+ bool isStatic: false,
+ bool isExternal: false,
+ bool isConst: false,
+ bool isForwardingStub: false,
+ bool isForwardingSemiStub: false,
+ int transformerFlags: 0,
+ Uri fileUri,
+ Reference reference,
+ Member forwardingStubSuperTarget,
+ Member forwardingStubInterfaceTarget})
+ : this.byReference(name, kind, function,
+ isAbstract: isAbstract,
+ isStatic: isStatic,
+ isExternal: isExternal,
+ isConst: isConst,
+ isForwardingStub: isForwardingStub,
+ isForwardingSemiStub: isForwardingSemiStub,
+ transformerFlags: transformerFlags,
+ fileUri: fileUri,
+ reference: reference,
+ forwardingStubSuperTargetReference:
+ getMemberReference(forwardingStubSuperTarget),
+ forwardingStubInterfaceTargetReference:
+ getMemberReference(forwardingStubInterfaceTarget));
+
+ Procedure.byReference(Name name, this.kind, this.function,
{bool isAbstract: false,
bool isStatic: false,
bool isExternal: false,
@@ -1499,8 +1526,8 @@
int transformerFlags: 0,
this.fileUri,
Reference reference,
- this.forwardingStubSuperTarget,
- this.forwardingStubInterfaceTarget})
+ this.forwardingStubSuperTargetReference,
+ this.forwardingStubInterfaceTargetReference})
: super(name, reference) {
function?.parent = this;
this.isAbstract = isAbstract;
@@ -1528,6 +1555,14 @@
/// constant factories, such as `String.fromEnvironment`.
bool get isConst => flags & FlagConst != 0;
+ /// If set, this flag indicates that this function's implementation exists
+ /// solely for the purpose of type checking arguments and forwarding to
+ /// [forwardingStubSuperTarget].
+ ///
+ /// Note that just because this bit is set doesn't mean that the function was
+ /// not declared in the source; it's possible that this is a forwarding
+ /// semi-stub (see isForwardingSemiStub). To determine whether this function
+ /// was present in the source, consult [isSyntheticForwarder].
bool get isForwardingStub => flags & FlagForwardingStub != 0;
/// Indicates whether invocations using this interface target may need to
@@ -1542,6 +1577,11 @@
/// stub, it was present in the original source as an abstract method.
bool get isForwardingSemiStub => flags & FlagForwardingSemiStub != 0;
+ /// If set, this flag indicates that this function was not present in the
+ /// source, and it exists solely for the purpose of type checking arguments
+ /// and forwarding to [forwardingStubSuperTarget].
+ bool get isSyntheticForwarder => isForwardingStub && !isForwardingSemiStub;
+
void set isStatic(bool value) {
flags = value ? (flags | FlagStatic) : (flags & ~FlagStatic);
}
@@ -1583,6 +1623,20 @@
bool get hasSetter => kind == ProcedureKind.Setter;
bool get isFactory => kind == ProcedureKind.Factory;
+ Member get forwardingStubSuperTarget =>
+ forwardingStubSuperTargetReference?.asMember;
+
+ void set forwardingStubSuperTarget(Member target) {
+ forwardingStubSuperTargetReference = getMemberReference(target);
+ }
+
+ Member get forwardingStubInterfaceTarget =>
+ forwardingStubInterfaceTargetReference?.asMember;
+
+ void set forwardingStubInterfaceTarget(Member target) {
+ forwardingStubInterfaceTargetReference = getMemberReference(target);
+ }
+
accept(MemberVisitor v) => v.visitProcedure(this);
acceptReference(MemberReferenceVisitor v) => v.visitProcedureReference(this);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index a05093e..af75d44 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -940,9 +940,9 @@
bool readFunctionNodeNow =
(kind == ProcedureKind.Factory && functionNodeSize <= 50) ||
_disableLazyReading;
- var forwardingStubSuperTarget =
+ var forwardingStubSuperTargetReference =
readAndCheckOptionTag() ? readMemberReference() : null;
- var forwardingStubInterfaceTarget =
+ var forwardingStubInterfaceTargetReference =
readAndCheckOptionTag() ? readMemberReference() : null;
var function = readFunctionNodeOption(!readFunctionNodeNow, endOffset);
var transformerFlags = getAndResetTransformerFlags();
@@ -958,10 +958,12 @@
node.function = function;
function?.parent = node;
node.setTransformerFlagsWithoutLazyLoading(transformerFlags);
- node.forwardingStubSuperTarget = forwardingStubSuperTarget;
- node.forwardingStubInterfaceTarget = forwardingStubInterfaceTarget;
+ node.forwardingStubSuperTargetReference =
+ forwardingStubSuperTargetReference;
+ node.forwardingStubInterfaceTargetReference =
+ forwardingStubInterfaceTargetReference;
- assert((node.forwardingStubSuperTarget != null) ||
+ assert((node.forwardingStubSuperTargetReference != null) ||
!(node.isForwardingStub && node.function.body != null));
}
_byteOffset = endOffset;
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index ef1edea..8ed77d7 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -765,8 +765,8 @@
writeName(node.name ?? '');
writeUriReference(node.fileUri);
writeAnnotationList(node.annotations);
- writeOptionalReference(node.forwardingStubSuperTarget);
- writeOptionalReference(node.forwardingStubInterfaceTarget);
+ writeOptionalReference(node.forwardingStubSuperTargetReference);
+ writeOptionalReference(node.forwardingStubInterfaceTargetReference);
writeOptionalNode(node.function);
_variableIndexer = null;
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index f23ccbf..fe1cd4b 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -79,7 +79,9 @@
Class _stackTraceClass;
Class _streamClass;
Class _completerClass;
+ Class _asyncAwaitCompleterClass;
Class _futureOrClass;
+ Constructor _asyncAwaitCompleterConstructor;
Procedure _completerSyncConstructor;
Procedure _completerComplete;
Procedure _completerCompleteError;
@@ -162,11 +164,21 @@
return _completerClass ??= _index.getClass('dart:async', 'Completer');
}
+ Class get asyncAwaitCompleterClass {
+ return _asyncAwaitCompleterClass ??=
+ _index.getClass('dart:async', '_AsyncAwaitCompleter');
+ }
+
Procedure get completerSyncConstructor {
return _completerSyncConstructor ??=
_index.getMember('dart:async', 'Completer', 'sync');
}
+ Constructor get asyncAwaitCompleterConstructor {
+ return _asyncAwaitCompleterConstructor ??=
+ _index.getMember('dart:async', '_AsyncAwaitCompleter', '');
+ }
+
Procedure get completerComplete {
return _completerComplete ??=
_index.getMember('dart:async', 'Completer', 'complete');
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 342757e..1d1e8c9 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -15,16 +15,20 @@
final List<String> targetNames = targets.keys.toList();
class TargetFlags {
- bool strongMode;
- bool treeShake;
- List<ProgramRoot> programRoots;
- Uri kernelRuntime;
+ final bool strongMode;
+ final bool treeShake;
+
+ /// Whether `async` functions start synchronously.
+ final bool syncAsync;
+ final List<ProgramRoot> programRoots;
+ final Uri kernelRuntime;
TargetFlags(
{this.strongMode: false,
this.treeShake: false,
+ this.syncAsync: false,
this.programRoots: const <ProgramRoot>[],
- this.kernelRuntime}) {}
+ this.kernelRuntime});
}
typedef Target _TargetBuilder(TargetFlags flags);
diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart
index a30abbb..5079c65 100644
--- a/pkg/kernel/lib/target/vm.dart
+++ b/pkg/kernel/lib/target/vm.dart
@@ -64,7 +64,7 @@
logger?.call("Transformed mixin applications");
// TODO(kmillikin): Make this run on a per-method basis.
- transformAsync.transformLibraries(coreTypes, libraries);
+ transformAsync.transformLibraries(coreTypes, libraries, flags.syncAsync);
logger?.call("Transformed async methods");
}
diff --git a/pkg/kernel/lib/target/vmcc.dart b/pkg/kernel/lib/target/vmcc.dart
index 28522cf..3496882 100644
--- a/pkg/kernel/lib/target/vmcc.dart
+++ b/pkg/kernel/lib/target/vmcc.dart
@@ -44,7 +44,7 @@
performTreeShaking(coreTypes, program);
}
- cont.transformProgram(coreTypes, program);
+ cont.transformProgram(coreTypes, program, flags.syncAsync);
new SanitizeForVM().transform(program);
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index 8539f2d..8f8133e 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -484,8 +484,8 @@
}
visitFunctionNode(FunctionNode node) {
- var nestedRewriter =
- new RecursiveContinuationRewriter(continuationRewriter.helper);
+ var nestedRewriter = new RecursiveContinuationRewriter(
+ continuationRewriter.helper, continuationRewriter.syncAsync);
return node.accept(nestedRewriter);
}
}
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 2b77554..9d8e50e 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -12,29 +12,34 @@
import 'async.dart';
-void transformLibraries(CoreTypes coreTypes, List<Library> libraries) {
+void transformLibraries(
+ CoreTypes coreTypes, List<Library> libraries, bool syncAsync) {
var helper = new HelperNodes.fromCoreTypes(coreTypes);
- var rewriter = new RecursiveContinuationRewriter(helper);
+ var rewriter = new RecursiveContinuationRewriter(helper, syncAsync);
for (var library in libraries) {
rewriter.rewriteLibrary(library);
}
}
-Program transformProgram(CoreTypes coreTypes, Program program) {
+Program transformProgram(CoreTypes coreTypes, Program program, bool syncAsync) {
var helper = new HelperNodes.fromCoreTypes(coreTypes);
- var rewriter = new RecursiveContinuationRewriter(helper);
+ var rewriter = new RecursiveContinuationRewriter(helper, syncAsync);
return rewriter.rewriteProgram(program);
}
class RecursiveContinuationRewriter extends Transformer {
final HelperNodes helper;
+
+ /// Whether `async` functions should start synchronously.
+ final bool syncAsync;
+
final VariableDeclaration asyncJumpVariable = new VariableDeclaration(
":await_jump_var",
initializer: new IntLiteral(0));
final VariableDeclaration asyncContextVariable =
new VariableDeclaration(":await_ctx_var");
- RecursiveContinuationRewriter(this.helper);
+ RecursiveContinuationRewriter(this.helper, this.syncAsync);
Program rewriteProgram(Program node) {
return node.accept(this);
@@ -52,14 +57,15 @@
switch (node.asyncMarker) {
case AsyncMarker.Sync:
case AsyncMarker.SyncYielding:
- node.transformChildren(new RecursiveContinuationRewriter(helper));
+ node.transformChildren(
+ new RecursiveContinuationRewriter(helper, syncAsync));
return node;
case AsyncMarker.SyncStar:
- return new SyncStarFunctionRewriter(helper, node).rewrite();
+ return new SyncStarFunctionRewriter(helper, node, syncAsync).rewrite();
case AsyncMarker.Async:
- return new AsyncFunctionRewriter(helper, node).rewrite();
+ return new AsyncFunctionRewriter(helper, node, syncAsync).rewrite();
case AsyncMarker.AsyncStar:
- return new AsyncStarFunctionRewriter(helper, node).rewrite();
+ return new AsyncStarFunctionRewriter(helper, node, syncAsync).rewrite();
}
}
}
@@ -72,8 +78,9 @@
int capturedTryDepth = 0; // Deepest yield point within a try-block.
int capturedCatchDepth = 0; // Deepest yield point within a catch-block.
- ContinuationRewriterBase(HelperNodes helper, this.enclosingFunction)
- : super(helper);
+ ContinuationRewriterBase(
+ HelperNodes helper, this.enclosingFunction, bool syncAsync)
+ : super(helper, syncAsync);
/// Given a container [type], which is an instantiation of the given
/// [containerClass] extract its element type.
@@ -157,13 +164,14 @@
class SyncStarFunctionRewriter extends ContinuationRewriterBase {
final VariableDeclaration iteratorVariable;
- SyncStarFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction)
+ SyncStarFunctionRewriter(
+ HelperNodes helper, FunctionNode enclosingFunction, syncAsync)
: iteratorVariable = new VariableDeclaration(':iterator')
..type = new InterfaceType(helper.syncIteratorClass, [
ContinuationRewriterBase.elementTypeFrom(
helper.iterableClass, enclosingFunction.returnType)
]),
- super(helper, enclosingFunction);
+ super(helper, enclosingFunction, syncAsync);
FunctionNode rewrite() {
// :sync_op(:iterator) {
@@ -256,8 +264,9 @@
ExpressionLifter expressionRewriter;
- AsyncRewriterBase(helper, enclosingFunction)
- : super(helper, enclosingFunction) {}
+ AsyncRewriterBase(
+ HelperNodes helper, FunctionNode enclosingFunction, bool syncAsync)
+ : super(helper, enclosingFunction, syncAsync) {}
void setupAsyncContinuations(List<Statement> statements) {
expressionRewriter = new ExpressionLifter(this);
@@ -754,8 +763,9 @@
class AsyncStarFunctionRewriter extends AsyncRewriterBase {
VariableDeclaration controllerVariable;
- AsyncStarFunctionRewriter(helper, enclosingFunction)
- : super(helper, enclosingFunction);
+ AsyncStarFunctionRewriter(
+ HelperNodes helper, FunctionNode enclosingFunction, bool syncAsync)
+ : super(helper, enclosingFunction, syncAsync);
FunctionNode rewrite() {
var statements = <Statement>[];
@@ -862,8 +872,9 @@
VariableDeclaration completerVariable;
VariableDeclaration returnVariable;
- AsyncFunctionRewriter(helper, enclosingFunction)
- : super(helper, enclosingFunction);
+ AsyncFunctionRewriter(
+ HelperNodes helper, FunctionNode enclosingFunction, bool syncAsync)
+ : super(helper, enclosingFunction, syncAsync);
FunctionNode rewrite() {
var statements = <Statement>[];
@@ -877,16 +888,29 @@
final DartType returnType =
new InterfaceType(helper.futureOrClass, <DartType>[valueType]);
var completerTypeArguments = <DartType>[valueType];
- var completerType =
- new InterfaceType(helper.completerClass, completerTypeArguments);
- // final Completer<T> :completer = new Completer<T>.sync();
- completerVariable = new VariableDeclaration(":completer",
- initializer: new StaticInvocation(helper.completerConstructor,
- new Arguments([], types: completerTypeArguments))
- ..fileOffset = enclosingFunction.body?.fileOffset ?? -1,
- isFinal: true,
- type: completerType);
+ if (syncAsync) {
+ final completerType = new InterfaceType(
+ helper.asyncAwaitCompleterClass, completerTypeArguments);
+ // final Completer<T> :completer = new _AsyncAwaitCompleter<T>();
+ completerVariable = new VariableDeclaration(":completer",
+ initializer: new ConstructorInvocation(
+ helper.asyncAwaitCompleterConstructor,
+ new Arguments([], types: completerTypeArguments))
+ ..fileOffset = enclosingFunction.body?.fileOffset ?? -1,
+ isFinal: true,
+ type: completerType);
+ } else {
+ final completerType =
+ new InterfaceType(helper.completerClass, completerTypeArguments);
+ // final Completer<T> :completer = new Completer<T>.sync();
+ completerVariable = new VariableDeclaration(":completer",
+ initializer: new StaticInvocation(helper.completerConstructor,
+ new Arguments([], types: completerTypeArguments))
+ ..fileOffset = enclosingFunction.body?.fileOffset ?? -1,
+ isFinal: true,
+ type: completerType);
+ }
statements.add(completerVariable);
returnVariable = new VariableDeclaration(":return_value", type: returnType);
@@ -894,14 +918,23 @@
setupAsyncContinuations(statements);
- // new Future.microtask(:async_op);
- var newMicrotaskStatement = new ExpressionStatement(new StaticInvocation(
- helper.futureMicrotaskConstructor,
- new Arguments([new VariableGet(nestedClosureVariable)],
- types: [const DynamicType()]))
- ..fileOffset = enclosingFunction.fileOffset);
- statements.add(newMicrotaskStatement);
-
+ if (syncAsync) {
+ // :completer.start(:async_op);
+ var startStatement = new ExpressionStatement(new MethodInvocation(
+ new VariableGet(completerVariable),
+ new Name('start'),
+ new Arguments([new VariableGet(nestedClosureVariable)]))
+ ..fileOffset = enclosingFunction.fileOffset);
+ statements.add(startStatement);
+ } else {
+ // new Future.microtask(:async_op);
+ var newMicrotaskStatement = new ExpressionStatement(new StaticInvocation(
+ helper.futureMicrotaskConstructor,
+ new Arguments([new VariableGet(nestedClosureVariable)],
+ types: [const DynamicType()]))
+ ..fileOffset = enclosingFunction.fileOffset);
+ statements.add(newMicrotaskStatement);
+ }
// return :completer.future;
var completerGet = new VariableGet(completerVariable);
var returnStatement = new ReturnStatement(new PropertyGet(completerGet,
@@ -964,9 +997,11 @@
final Procedure asyncThenWrapper;
final Procedure awaitHelper;
final Class completerClass;
+ final Class asyncAwaitCompleterClass;
final Member completerComplete;
final Member completerCompleteError;
final Member completerConstructor;
+ final Member asyncAwaitCompleterConstructor;
final Member completerFuture;
final Library coreLibrary;
final CoreTypes coreTypes;
@@ -1001,9 +1036,11 @@
this.asyncThenWrapper,
this.awaitHelper,
this.completerClass,
+ this.asyncAwaitCompleterClass,
this.completerComplete,
this.completerCompleteError,
this.completerConstructor,
+ this.asyncAwaitCompleterConstructor,
this.completerFuture,
this.coreLibrary,
this.coreTypes,
@@ -1039,9 +1076,11 @@
coreTypes.asyncThenWrapperHelperProcedure,
coreTypes.awaitHelperProcedure,
coreTypes.completerClass,
+ coreTypes.asyncAwaitCompleterClass,
coreTypes.completerComplete,
coreTypes.completerCompleteError,
coreTypes.completerSyncConstructor,
+ coreTypes.asyncAwaitCompleterConstructor,
coreTypes.completerFuture,
coreTypes.coreLibrary,
coreTypes,
diff --git a/pkg/kernel/lib/transformations/mixin_full_resolution.dart b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
index 0935136..a38f134 100644
--- a/pkg/kernel/lib/transformations/mixin_full_resolution.dart
+++ b/pkg/kernel/lib/transformations/mixin_full_resolution.dart
@@ -107,6 +107,13 @@
// [Object] class.
if (!processedClasses.add(class_)) return;
+ if (!librariesToBeTransformed.contains(class_.enclosingLibrary) &&
+ class_.enclosingLibrary.importUri?.scheme == "dart") {
+ // If we're not asked to transform the platform libraries then we expect
+ // that they will be already transformed.
+ return;
+ }
+
// Ensure super classes have been transformed before this class.
if (class_.superclass != null &&
class_.superclass.level.index >= ClassLevel.Mixin.index) {
diff --git a/pkg/kernel/lib/transformations/treeshaker.dart b/pkg/kernel/lib/transformations/treeshaker.dart
index 74f236f..c64205c 100644
--- a/pkg/kernel/lib/transformations/treeshaker.dart
+++ b/pkg/kernel/lib/transformations/treeshaker.dart
@@ -1251,7 +1251,6 @@
}
}
}
- throw 'External procedure has no @ExternalName("...") annotation!';
}
return null;
}
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index dea57f8..4a5212c 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,5 +1,5 @@
name: kernel
-version: 0.3.0-alpha.4
+version: 0.3.0-alpha.5
author: Dart Team <misc@dartlang.org>
description: Dart IR (Intermediate Representation)
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
@@ -12,7 +12,7 @@
package_config: ^1.0.0
dev_dependencies:
analyzer: '>=0.30.0 <0.32.0'
- front_end: 0.1.0-alpha.7
+ front_end: 0.1.0-alpha.8
test: ^0.12.15+6
stack_trace: ^1.6.6
ansicolor: ^0.0.9
diff --git a/pkg/pkg.status b/pkg/pkg.status
index f5bf31f..2c26a32 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -45,7 +45,6 @@
front_end/test/minimal_incremental_kernel_generator_test: Slow, Pass
front_end/test/whole_program_test: Slow, Pass
front_end/testcases/*: Skip # These are not tests but input for tests.
-front_end/tool/_fasta/compile_platform_test: Fail
front_end/tool/incremental_perf_test: Slow, Pass
kernel/test/closures_test: Slow, Pass
kernel/testcases/*: Skip # These are not tests but input for tests.
@@ -71,6 +70,7 @@
compiler/tool/*: SkipByDesign # Only meant to run on vm
front_end/test/dependency_grapher_test: SkipByDesign # Uses dart:io
front_end/test/incremental_kernel_generator_test: SkipByDesign # Uses dart:io
+front_end/test/incremental_load_from_dill_test: SkipByDesign # Uses dart:io
front_end/test/incremental_resolved_ast_generator_test: SkipByDesign # Uses dart:io
front_end/test/memory_file_system_test: CompileTimeError # Issue 23773
front_end/test/src/base/file_repository_test: SkipByDesign # Uses dart:io
diff --git a/pkg/status_file/test/parse_and_normalize_test.dart b/pkg/status_file/test/parse_and_normalize_test.dart
index 2a90c33..0692c3a 100644
--- a/pkg/status_file/test/parse_and_normalize_test.dart
+++ b/pkg/status_file/test/parse_and_normalize_test.dart
@@ -20,16 +20,17 @@
// to be valid and looks more like some kind of template or help document.
// Ignore it.
var co19StatusFile = repoRoot.resolve('tests/co19/src/co19.status');
+ var co19_2StatusFile = repoRoot.resolve('tests/co19_2/src/co19.status');
if (FileSystemEntity.identicalSync(
- entry.path, new File.fromUri(co19StatusFile).path)) {
+ entry.path, new File.fromUri(co19StatusFile).path) ||
+ FileSystemEntity.identicalSync(
+ entry.path, new File.fromUri(co19_2StatusFile).path)) {
continue;
}
try {
var statusFile = new StatusFile.read(entry.path);
- print("-------" + entry.path + "---------------");
- print(statusFile.toString());
- print("-------" + entry.path + "---------------");
+ statusFile.toString();
} catch (err, st) {
print(err);
print(st);
diff --git a/pkg/status_file/test/repo_status_files_test.dart b/pkg/status_file/test/repo_status_files_test.dart
index ef4ae6d..ce57c42 100644
--- a/pkg/status_file/test/repo_status_files_test.dart
+++ b/pkg/status_file/test/repo_status_files_test.dart
@@ -10,26 +10,31 @@
import 'package:path/path.dart' as p;
import 'package:status_file/status_file.dart';
-final repoRoot =
- p.normalize(p.join(p.dirname(p.fromUri(Platform.script)), "../../../"));
+final Uri repoRoot = Platform.script.resolve("../../../");
void main() {
// Parse every status file in the repository.
- for (var directory in ["tests", p.join("runtime", "tests")]) {
- for (var entry in new Directory(p.join(repoRoot, directory))
+ for (var directory in ["tests", "runtime/tests"]) {
+ for (var entry in new Directory.fromUri(repoRoot.resolve(directory))
.listSync(recursive: true)) {
if (!entry.path.endsWith(".status")) continue;
// Inside the co19 repository, there is a status file that doesn't appear
// to be valid and looks more like some kind of template or help document.
// Ignore it.
- if (entry.path.endsWith(p.join("co19", "src", "co19.status"))) continue;
+ var co19StatusFile = repoRoot.resolve('tests/co19/src/co19.status');
+ var co19_2StatusFile = repoRoot.resolve('tests/co19_2/src/co19.status');
+ if (FileSystemEntity.identicalSync(
+ entry.path, new File.fromUri(co19StatusFile).path) ||
+ FileSystemEntity.identicalSync(
+ entry.path, new File.fromUri(co19_2StatusFile).path)) {
+ continue;
+ }
try {
new StatusFile.read(entry.path);
} catch (err) {
- var path = p.relative(entry.path, from: repoRoot);
- Expect.fail("Could not parse '$path'.\n$err");
+ Expect.fail("Could not parse '${entry.path}'.\n$err");
}
}
}
diff --git a/pkg/testing/lib/src/multitest.dart b/pkg/testing/lib/src/multitest.dart
index 3ba8410..c87a654 100644
--- a/pkg/testing/lib/src/multitest.dart
+++ b/pkg/testing/lib/src/multitest.dart
@@ -4,7 +4,7 @@
library testing.multitest;
-import 'dart:async' show Stream, StreamTransformer;
+import 'dart:async' show Stream, StreamTransformerBase;
import 'dart:io' show Directory, File;
@@ -25,7 +25,7 @@
}
class MultitestTransformer
- implements StreamTransformer<TestDescription, TestDescription> {
+ extends StreamTransformerBase<TestDescription, TestDescription> {
static RegExp multitestMarker = new RegExp(r"//[#/]");
static int _multitestMarkerLength = 3;
diff --git a/pkg/vm/bin/dump_kernel.dart b/pkg/vm/bin/dump_kernel.dart
index 28499bc..46f6680 100644
--- a/pkg/vm/bin/dump_kernel.dart
+++ b/pkg/vm/bin/dump_kernel.dart
@@ -11,6 +11,8 @@
import 'package:vm/metadata/direct_call.dart' show DirectCallMetadataRepository;
import 'package:vm/metadata/inferred_type.dart'
show InferredTypeMetadataRepository;
+import 'package:vm/metadata/procedure_attributes.dart'
+ show ProcedureAttributesMetadataRepository;
final String _usage = '''
Usage: dump_kernel input.dill output.txt
@@ -31,6 +33,7 @@
// Register VM-specific metadata.
program.addMetadataRepository(new DirectCallMetadataRepository());
program.addMetadataRepository(new InferredTypeMetadataRepository());
+ program.addMetadataRepository(new ProcedureAttributesMetadataRepository());
final List<int> bytes = new File(input).readAsBytesSync();
new BinaryBuilderWithMetadata(bytes).readProgram(program);
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index 8a501f5..1a5b13c 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -25,6 +25,7 @@
'Produce kernel file for AOT compilation (enables global transformations).',
defaultsTo: false)
..addFlag('strong-mode', help: 'Enable strong mode', defaultsTo: true)
+ ..addFlag('sync-async', help: 'Start `async` functions synchronously')
..addFlag('embed-sources',
help: 'Embed source files in the generated kernel program',
defaultsTo: true);
@@ -62,12 +63,14 @@
final String packages = options['packages'];
final bool strongMode = options['strong-mode'];
final bool aot = options['aot'];
+ final bool syncAsync = options['sync-async'];
ErrorDetector errorDetector = new ErrorDetector();
final CompilerOptions compilerOptions = new CompilerOptions()
..strongMode = strongMode
- ..target = new VmTarget(new TargetFlags(strongMode: strongMode))
+ ..target = new VmTarget(
+ new TargetFlags(strongMode: strongMode, syncAsync: syncAsync))
..linkedDependencies = <Uri>[Uri.base.resolve(platformKernel)]
..packagesFileUri = packages != null ? Uri.base.resolve(packages) : null
..reportMessages = true
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index da72077..60e73f2 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -39,6 +39,7 @@
import 'package:kernel/target/vm.dart' show VmTarget;
const bool verbose = const bool.fromEnvironment('DFE_VERBOSE');
+const String platformKernelFile = 'virtual_platform_kernel.dill';
abstract class Compiler {
final FileSystem fileSystem;
@@ -47,8 +48,10 @@
CompilerOptions options;
- Compiler(this.fileSystem, Uri platformKernel,
- {this.strongMode: false, bool suppressWarnings: false}) {
+ Compiler(this.fileSystem, Uri platformKernelPath,
+ {this.strongMode: false,
+ bool suppressWarnings: false,
+ bool syncAsync: false}) {
Uri packagesUri = (Platform.packageConfig != null)
? Uri.parse(Platform.packageConfig)
: null;
@@ -57,16 +60,18 @@
print("DFE: Platform.packageConfig: ${Platform.packageConfig}");
print("DFE: packagesUri: ${packagesUri}");
print("DFE: Platform.resolvedExecutable: ${Platform.resolvedExecutable}");
- print("DFE: platformKernel: ${platformKernel}");
+ print("DFE: platformKernelPath: ${platformKernelPath}");
print("DFE: strongMode: ${strongMode}");
+ print("DFE: syncAsync: ${syncAsync}");
}
options = new CompilerOptions()
..strongMode = strongMode
..fileSystem = fileSystem
- ..target = new VmTarget(new TargetFlags(strongMode: strongMode))
+ ..target = new VmTarget(
+ new TargetFlags(strongMode: strongMode, syncAsync: syncAsync))
..packagesFileUri = packagesUri
- ..sdkSummary = platformKernel
+ ..sdkSummary = platformKernelPath
..verbose = verbose
..onProblem =
(message, Severity severity, String formatted, int line, int column) {
@@ -98,10 +103,12 @@
class IncrementalCompiler extends Compiler {
IncrementalKernelGenerator generator;
- IncrementalCompiler(FileSystem fileSystem, Uri platformKernel,
- {bool strongMode: false, bool suppressWarnings: false})
- : super(fileSystem, platformKernel,
- strongMode: strongMode, suppressWarnings: suppressWarnings);
+ IncrementalCompiler(FileSystem fileSystem, Uri platformKernelPath,
+ {bool strongMode: false, bool suppressWarnings: false, syncAsync: false})
+ : super(fileSystem, platformKernelPath,
+ strongMode: strongMode,
+ suppressWarnings: suppressWarnings,
+ syncAsync: syncAsync);
@override
Future<Program> compileInternal(Uri script) async {
@@ -119,12 +126,15 @@
class SingleShotCompiler extends Compiler {
final bool requireMain;
- SingleShotCompiler(FileSystem fileSystem, Uri platformKernel,
+ SingleShotCompiler(FileSystem fileSystem, Uri platformKernelPath,
{this.requireMain: false,
bool strongMode: false,
- bool suppressWarnings: false})
- : super(fileSystem, platformKernel,
- strongMode: strongMode, suppressWarnings: suppressWarnings);
+ bool suppressWarnings: false,
+ bool syncAsync: false})
+ : super(fileSystem, platformKernelPath,
+ strongMode: strongMode,
+ suppressWarnings: suppressWarnings,
+ syncAsync: syncAsync);
@override
Future<Program> compileInternal(Uri script) async {
@@ -136,9 +146,11 @@
final Map<int, Compiler> isolateCompilers = new Map<int, Compiler>();
-Future<Compiler> lookupOrBuildNewIncrementalCompiler(
- int isolateId, List sourceFiles, Uri platformKernel,
- {bool strongMode: false, bool suppressWarnings: false}) async {
+Future<Compiler> lookupOrBuildNewIncrementalCompiler(int isolateId,
+ List sourceFiles, Uri platformKernelPath, List<int> platformKernel,
+ {bool strongMode: false,
+ bool suppressWarnings: false,
+ bool syncAsync: false}) async {
IncrementalCompiler compiler;
if (isolateCompilers.containsKey(isolateId)) {
compiler = isolateCompilers[isolateId];
@@ -153,42 +165,48 @@
}
}
} else {
- final FileSystem fileSystem = sourceFiles == null
+ final FileSystem fileSystem = sourceFiles == null && platformKernel == null
? StandardFileSystem.instance
- : _buildFileSystem(sourceFiles);
+ : _buildFileSystem(sourceFiles, platformKernel);
// TODO(aam): IncrementalCompiler instance created below have to be
// destroyed when corresponding isolate is shut down. To achieve that kernel
// isolate needs to receive a message indicating that particular
// isolate was shut down. Message should be handled here in this script.
- compiler = new IncrementalCompiler(fileSystem, platformKernel,
- strongMode: strongMode, suppressWarnings: suppressWarnings);
+ compiler = new IncrementalCompiler(fileSystem, platformKernelPath,
+ strongMode: strongMode,
+ suppressWarnings: suppressWarnings,
+ syncAsync: syncAsync);
isolateCompilers[isolateId] = compiler;
}
return compiler;
}
-// Process a request from the runtime. See KernelIsolate::CompileToKernel in
-// kernel_isolate.cc and Loader::SendKernelRequest in loader.cc.
Future _processLoadRequest(request) async {
if (verbose) print("DFE: request: $request");
int tag = request[0];
final SendPort port = request[1];
final String inputFileUri = request[2];
- final Uri script = Uri.base.resolve(inputFileUri);
- final Uri platformKernel = request[3] != null
- ? Uri.base.resolveUri(new Uri.file(request[3]))
- : computePlatformBinariesLocation().resolve(
- // TODO(sigmund): use `vm_outline.dill` when the mixin transformer is
- // modular.
- 'vm_platform.dill');
-
final bool incremental = request[4];
final bool strong = request[5];
final int isolateId = request[6];
final List sourceFiles = request[7];
final bool suppressWarnings = request[8];
+ final bool syncAsync = request[9];
+
+ final Uri script = Uri.base.resolve(inputFileUri);
+ Uri platformKernelPath = null;
+ List<int> platformKernel = null;
+ if (request[3] is String) {
+ platformKernelPath = Uri.base.resolveUri(new Uri.file(request[3]));
+ } else if (request[3] is List<int>) {
+ platformKernelPath = Uri.parse(platformKernelFile);
+ platformKernel = request[3];
+ } else {
+ platformKernelPath = computePlatformBinariesLocation()
+ .resolve(strong ? 'vm_platform_strong.dill' : 'vm_platform.dill');
+ }
Compiler compiler;
// TODO(aam): There should be no need to have an option to choose
@@ -197,16 +215,17 @@
// watch the performance though.
if (incremental) {
compiler = await lookupOrBuildNewIncrementalCompiler(
- isolateId, sourceFiles, platformKernel,
- suppressWarnings: suppressWarnings);
+ isolateId, sourceFiles, platformKernelPath, platformKernel,
+ suppressWarnings: suppressWarnings, syncAsync: syncAsync);
} else {
- final FileSystem fileSystem = sourceFiles == null
+ final FileSystem fileSystem = sourceFiles == null && platformKernel == null
? StandardFileSystem.instance
- : _buildFileSystem(sourceFiles);
- compiler = new SingleShotCompiler(fileSystem, platformKernel,
+ : _buildFileSystem(sourceFiles, platformKernel);
+ compiler = new SingleShotCompiler(fileSystem, platformKernelPath,
requireMain: sourceFiles == null,
strongMode: strong,
- suppressWarnings: suppressWarnings);
+ suppressWarnings: suppressWarnings,
+ syncAsync: syncAsync);
}
CompilationResult result;
@@ -256,17 +275,24 @@
///
/// The result can be used instead of StandardFileSystem.instance by the
/// frontend.
-FileSystem _buildFileSystem(List namedSources) {
+FileSystem _buildFileSystem(List namedSources, List<int> platformKernel) {
MemoryFileSystem fileSystem = new MemoryFileSystem(Uri.parse('file:///'));
- for (int i = 0; i < namedSources.length ~/ 2; i++) {
+ if (namedSources != null) {
+ for (int i = 0; i < namedSources.length ~/ 2; i++) {
+ fileSystem
+ .entityForUri(Uri.parse(namedSources[i * 2]))
+ .writeAsBytesSync(namedSources[i * 2 + 1]);
+ }
+ }
+ if (platformKernel != null) {
fileSystem
- .entityForUri(Uri.parse(namedSources[i * 2]))
- .writeAsBytesSync(namedSources[i * 2 + 1]);
+ .entityForUri(Uri.parse(platformKernelFile))
+ .writeAsBytesSync(platformKernel);
}
return new HybridFileSystem(fileSystem);
}
-train(String scriptUri, String platformKernel) {
+train(String scriptUri, String platformKernelPath) {
// TODO(28532): Enable on Windows.
if (Platform.isWindows) return;
@@ -287,12 +313,13 @@
tag,
responsePort.sendPort,
scriptUri,
- platformKernel,
+ platformKernelPath,
false /* incremental */,
false /* strong */,
1 /* isolateId chosen randomly */,
null /* source files */,
false /* suppress warnings */,
+ false /* synchronous async */,
];
_processLoadRequest(request);
}
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 281f67c..569b786 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -19,6 +19,8 @@
import 'transformations/devirtualization.dart' as devirtualization
show transformProgram;
+import 'transformations/no_dynamic_invocations_annotator.dart'
+ as no_dynamic_invocations_annotator show transformProgram;
import 'transformations/type_flow/transformer.dart' as globalTypeFlow
show transformProgram;
@@ -58,6 +60,7 @@
globalTypeFlow.transformProgram(coreTypes, program);
} else {
devirtualization.transformProgram(coreTypes, program);
+ no_dynamic_invocations_annotator.transformProgram(coreTypes, program);
}
}
}
diff --git a/pkg/vm/lib/metadata/procedure_attributes.dart b/pkg/vm/lib/metadata/procedure_attributes.dart
new file mode 100644
index 0000000..1e6acb8
--- /dev/null
+++ b/pkg/vm/lib/metadata/procedure_attributes.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library vm.metadata.procedure_attributes;
+
+import 'package:kernel/ast.dart';
+
+/// Metadata for annotating procedures with various attributes.
+class ProcedureAttributesMetadata {
+ final bool hasDynamicInvocations;
+
+ const ProcedureAttributesMetadata({this.hasDynamicInvocations});
+
+ const ProcedureAttributesMetadata.noDynamicInvocations()
+ : hasDynamicInvocations = false;
+
+ @override
+ String toString() => "hasDynamicInvocations:${hasDynamicInvocations}";
+}
+
+/// Repository for [ProcedureAttributesMetadata].
+class ProcedureAttributesMetadataRepository
+ extends MetadataRepository<ProcedureAttributesMetadata> {
+ @override
+ final String tag = 'vm.procedure-attributes.metadata';
+
+ @override
+ final Map<TreeNode, ProcedureAttributesMetadata> mapping =
+ <TreeNode, ProcedureAttributesMetadata>{};
+
+ @override
+ void writeToBinary(ProcedureAttributesMetadata metadata, BinarySink sink) {
+ assert(!metadata.hasDynamicInvocations);
+ }
+
+ @override
+ ProcedureAttributesMetadata readFromBinary(BinarySource source) {
+ return const ProcedureAttributesMetadata.noDynamicInvocations();
+ }
+}
diff --git a/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
new file mode 100644
index 0000000..7950fa0
--- /dev/null
+++ b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
@@ -0,0 +1,117 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library vm.transformations.no_dynamic_invocations_annotator;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart' show CoreTypes;
+
+import '../metadata/procedure_attributes.dart';
+
+/// Assumes strong mode and closed world. If a procedure can not be riched
+/// via dynamic invocation from anywhere then annotates it with appropriate
+/// [ProcedureAttributeMetadata] annotation.
+Program transformProgram(CoreTypes coreTypes, Program program) {
+ new NoDynamicInvocationsAnnotator(program).visitProgram(program);
+ return program;
+}
+
+enum Action { get, set, invoke }
+
+class Selector {
+ final Action action;
+ final Name target;
+
+ Selector(this.action, this.target);
+
+ bool operator ==(other) {
+ return other is Selector &&
+ other.action == this.action &&
+ other.target == this.target;
+ }
+
+ int get hashCode => (action.index * 31) ^ target.hashCode;
+
+ @override
+ String toString() {
+ switch (action) {
+ case Action.get:
+ return 'get:${target}';
+ case Action.set:
+ return 'set:${target}';
+ case Action.invoke:
+ return '${target}';
+ }
+ return '?';
+ }
+}
+
+class NoDynamicInvocationsAnnotator extends RecursiveVisitor<Null> {
+ final Set<Selector> _dynamicSelectors;
+ final ProcedureAttributesMetadataRepository _metadata;
+
+ NoDynamicInvocationsAnnotator(Program program)
+ : _dynamicSelectors = DynamicSelectorsCollector.collect(program),
+ _metadata = new ProcedureAttributesMetadataRepository() {
+ program.addMetadataRepository(_metadata);
+ }
+
+ @override
+ visitProcedure(Procedure node) {
+ if (node.isStatic || node.name.name == 'call') {
+ return;
+ }
+
+ Selector selector;
+ if (node.kind == ProcedureKind.Method) {
+ selector = new Selector(Action.invoke, node.name);
+ } else if (node.kind == ProcedureKind.Setter) {
+ selector = new Selector(Action.set, node.name);
+ } else {
+ return;
+ }
+
+ if (!_dynamicSelectors.contains(selector)) {
+ _metadata.mapping[node] =
+ const ProcedureAttributesMetadata.noDynamicInvocations();
+ }
+ }
+}
+
+class DynamicSelectorsCollector extends RecursiveVisitor<Null> {
+ final Set<Selector> dynamicSelectors = new Set<Selector>();
+
+ static Set<Selector> collect(Program program) {
+ final v = new DynamicSelectorsCollector();
+ v.visitProgram(program);
+ return v.dynamicSelectors;
+ }
+
+ @override
+ visitMethodInvocation(MethodInvocation node) {
+ super.visitMethodInvocation(node);
+
+ if (node.dispatchCategory == DispatchCategory.dynamicDispatch) {
+ dynamicSelectors.add(new Selector(Action.invoke, node.name));
+ }
+ }
+
+ @override
+ visitPropertyGet(PropertyGet node) {
+ super.visitPropertyGet(node);
+
+ if (node.dispatchCategory == DispatchCategory.dynamicDispatch) {
+ dynamicSelectors.add(new Selector(Action.get, node.name));
+ }
+ }
+
+ @override
+ visitPropertySet(PropertySet node) {
+ super.visitPropertySet(node);
+
+ if (node.dispatchCategory == DispatchCategory.dynamicDispatch) {
+ dynamicSelectors.add(new Selector(Action.set, node.name));
+ }
+ }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 390a625..de9316c 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -5,6 +5,7 @@
/// Global type flow analysis.
library kernel.transformations.analysis;
+import 'dart:collection';
import 'dart:core' hide Type;
import 'package:kernel/ast.dart' hide Statement, StatementVisitor;
@@ -24,7 +25,6 @@
// organized in several categories:
//
// === Correctness ===
-// * Handle noSuchMethod invocations correctly.
// * Verify incremental re-calculation by fresh analysis starting with known
// allocated classes.
// * Auto-generate entry_points.json during build.
@@ -68,7 +68,8 @@
/// This is the basic unit of processing in type flow analysis.
/// Call sites calling the same method with the same argument types
/// may reuse results of the analysis through the same _Invocation instance.
-abstract class _Invocation extends _DependencyTracker {
+abstract class _Invocation extends _DependencyTracker
+ with LinkedListEntry<_Invocation> {
final Selector selector;
final Args<Type> args;
@@ -96,6 +97,34 @@
@override
String toString() => "_Invocation $selector $args";
+
+ /// Processes noSuchMethod() invocation and returns its result.
+ /// Used if target is not found or number of arguments is incorrect.
+ Type _processNoSuchMethod(Type receiver, TypeFlowAnalysis typeFlowAnalysis) {
+ tracePrint("Processing noSuchMethod for receiver $receiver");
+
+ final nsmSelector = new InterfaceSelector(
+ typeFlowAnalysis.hierarchyCache.objectNoSuchMethod,
+ callKind: CallKind.Method);
+
+ final nsmArgs = new Args<Type>([
+ receiver,
+ new Type.cone(
+ typeFlowAnalysis.environment.coreTypes.invocationClass.rawType)
+ ]);
+
+ final nsmInvocation =
+ typeFlowAnalysis._invocationsCache.getInvocation(nsmSelector, nsmArgs);
+
+ final Type type =
+ typeFlowAnalysis.workList.processInvocation(nsmInvocation);
+
+ // Result of this invocation depends on the result of noSuchMethod
+ // inovcation.
+ nsmInvocation.addDependentInvocation(this);
+
+ return type;
+ }
}
class _DirectInvocation extends _Invocation {
@@ -160,8 +189,8 @@
.getSummary(member)
.apply(args, typeFlowAnalysis.hierarchyCache, typeFlowAnalysis);
} else {
- // TODO(alexmarkov): support noSuchMethod invocation here.
- return new Type.empty();
+ assertx(selector.callKind == CallKind.Method);
+ return _processNoSuchMethod(args.receiver, typeFlowAnalysis);
}
} else {
if (selector.callKind == CallKind.PropertyGet) {
@@ -211,6 +240,10 @@
Set<Call> _callSites; // Populated only if not polymorphic.
Member _monomorphicTarget;
+ /// Marker for noSuchMethod() invocation in the map of invocation targets.
+ static final Member kNoSuchMethodMarker =
+ new Procedure(new Name('noSuchMethod&&'), ProcedureKind.Method, null);
+
_DispatchableInvocation(Selector selector, Args<Type> args)
: super(selector, args) {
assertx(selector is! DirectSelector);
@@ -222,7 +255,7 @@
// Collect all possible targets for this invocation,
// along with more accurate receiver types for each target.
- final targets = <Member, Type>{};
+ final targets = <Member, _ReceiverTypeBuilder>{};
_collectTargetsForReceiverType(args.receiver, targets, typeFlowAnalysis);
// Calculate result as a union of results of direct invocations
@@ -233,29 +266,42 @@
tracePrint("No targets...");
} else {
if (targets.length == 1) {
- _setMonomorphicTarget(targets.keys.single);
+ final target = targets.keys.single;
+ if (target != kNoSuchMethodMarker) {
+ _setMonomorphicTarget(target);
+ } else {
+ _setPolymorphic();
+ }
} else {
_setPolymorphic();
}
- targets.forEach((Member target, Type receiver) {
- final directSelector =
- new DirectSelector(target, callKind: selector.callKind);
- Args<Type> directArgs = args;
- if (args.receiver != receiver) {
- directArgs = new Args<Type>.withReceiver(args, receiver);
+ targets
+ .forEach((Member target, _ReceiverTypeBuilder receiverTypeBuilder) {
+ Type receiver = receiverTypeBuilder.toType();
+ Type type;
+
+ if (target == kNoSuchMethodMarker) {
+ type = _processNoSuchMethod(receiver, typeFlowAnalysis);
+ } else {
+ final directSelector =
+ new DirectSelector(target, callKind: selector.callKind);
+
+ Args<Type> directArgs = args;
+ if (args.receiver != receiver) {
+ directArgs = new Args<Type>.withReceiver(args, receiver);
+ }
+
+ final directInvocation = typeFlowAnalysis._invocationsCache
+ .getInvocation(directSelector, directArgs);
+
+ type = typeFlowAnalysis.workList.processInvocation(directInvocation);
+
+ // Result of this invocation depends on the results of direct
+ // invocations corresponding to each target.
+ directInvocation.addDependentInvocation(this);
}
- final directInvocation = typeFlowAnalysis._invocationsCache
- .getInvocation(directSelector, directArgs);
-
- final Type type =
- typeFlowAnalysis.workList.processInvocation(directInvocation);
-
- // Result of this invocation depends on the results of direct
- // invocations corresponding to each target.
- directInvocation.addDependentInvocation(this);
-
result = result.union(type, typeFlowAnalysis.hierarchyCache);
});
}
@@ -269,12 +315,14 @@
return result;
}
- void _collectTargetsForReceiverType(Type receiver, Map<Member, Type> targets,
+ void _collectTargetsForReceiverType(
+ Type receiver,
+ Map<Member, _ReceiverTypeBuilder> targets,
TypeFlowAnalysis typeFlowAnalysis) {
assertx(receiver != const EmptyType()); // should be filtered earlier
- if (receiver is NullableType) {
- _collectTargetsForNull(targets, typeFlowAnalysis);
+ final bool isNullableReceiver = receiver is NullableType;
+ if (isNullableReceiver) {
receiver = (receiver as NullableType).baseType;
assertx(receiver is! NullableType);
}
@@ -286,7 +334,9 @@
staticReceiverType, typeFlowAnalysis.hierarchyCache);
assertx(receiver is! NullableType);
- tracePrint("Narrowed down receiver type: $receiver");
+ if (kPrintTrace) {
+ tracePrint("Narrowed down receiver type: $receiver");
+ }
}
if (receiver is ConeType) {
@@ -297,6 +347,8 @@
.specializeTypeCone((receiver as ConeType).dartType);
}
+ assertx(targets.isEmpty);
+
if (receiver is ConcreteType) {
_collectTargetsForConcreteType(receiver, targets, typeFlowAnalysis);
} else if (receiver is SetType) {
@@ -308,25 +360,32 @@
} else {
assertx(receiver is EmptyType);
}
+
+ if (isNullableReceiver) {
+ _collectTargetsForNull(targets, typeFlowAnalysis);
+ }
}
// TODO(alexmarkov): Consider caching targets for Null type.
- void _collectTargetsForNull(
- Map<Member, Type> targets, TypeFlowAnalysis typeFlowAnalysis) {
+ void _collectTargetsForNull(Map<Member, _ReceiverTypeBuilder> targets,
+ TypeFlowAnalysis typeFlowAnalysis) {
Class nullClass = typeFlowAnalysis.environment.coreTypes.nullClass;
Member target = typeFlowAnalysis.hierarchyCache.hierarchy
.getDispatchTarget(nullClass, selector.name, setter: selector.isSetter);
if (target != null) {
- tracePrint("Found $target for null receiver");
- _addTarget(targets, target, new Type.nullable(const EmptyType()),
- typeFlowAnalysis);
+ if (kPrintTrace) {
+ tracePrint("Found $target for null receiver");
+ }
+ _getReceiverTypeBuilder(targets, target).addNull();
}
}
- void _collectTargetsForConcreteType(ConcreteType receiver,
- Map<Member, Type> targets, TypeFlowAnalysis typeFlowAnalysis) {
+ void _collectTargetsForConcreteType(
+ ConcreteType receiver,
+ Map<Member, _ReceiverTypeBuilder> targets,
+ TypeFlowAnalysis typeFlowAnalysis) {
DartType receiverDartType = receiver.dartType;
assertx(receiverDartType is! FunctionType);
@@ -338,15 +397,27 @@
.getDispatchTarget(class_, selector.name, setter: selector.isSetter);
if (target != null) {
- tracePrint("Found $target for concrete receiver $receiver");
- _addTarget(targets, target, receiver, typeFlowAnalysis);
+ if (kPrintTrace) {
+ tracePrint("Found $target for concrete receiver $receiver");
+ }
+ _getReceiverTypeBuilder(targets, target).addConcreteType(receiver);
} else {
- tracePrint("Target is not found for receiver $receiver");
+ if (typeFlowAnalysis.hierarchyCache.hasNonTrivialNoSuchMethod(class_)) {
+ if (kPrintTrace) {
+ tracePrint("Found non-trivial noSuchMethod for receiver $receiver");
+ }
+ _getReceiverTypeBuilder(targets, kNoSuchMethodMarker)
+ .addConcreteType(receiver);
+ } else {
+ if (kPrintTrace) {
+ tracePrint("Target is not found for receiver $receiver");
+ }
+ }
}
}
- void _collectTargetsForSelector(
- Map<Member, Type> targets, TypeFlowAnalysis typeFlowAnalysis) {
+ void _collectTargetsForSelector(Map<Member, _ReceiverTypeBuilder> targets,
+ TypeFlowAnalysis typeFlowAnalysis) {
Selector selector = this.selector;
if (selector is InterfaceSelector) {
// TODO(alexmarkov): support generic types and make sure inferred types
@@ -357,20 +428,26 @@
}
final receiver = args.receiver;
- for (Member target in typeFlowAnalysis.hierarchyCache
- .getDynamicTargets(selector as DynamicSelector)) {
- _addTarget(targets, target, receiver, typeFlowAnalysis);
+ final _DynamicTargetSet dynamicTargetSet = typeFlowAnalysis.hierarchyCache
+ .getDynamicTargetSet(selector as DynamicSelector);
+
+ dynamicTargetSet.addDependentInvocation(this);
+
+ assertx(targets.isEmpty);
+ for (Member target in dynamicTargetSet.targets) {
+ _getReceiverTypeBuilder(targets, target).addType(receiver);
+ }
+
+ // Conservatively include noSuchMethod if selector is not from Object,
+ // as class might miss the implementation.
+ if (!dynamicTargetSet.isObjectMember) {
+ _getReceiverTypeBuilder(targets, kNoSuchMethodMarker).addType(receiver);
}
}
- void _addTarget(Map<Member, Type> targets, Member member, Type receiver,
- TypeFlowAnalysis typeFlowAnalysis) {
- Type oldReceiver = targets[member];
- if (oldReceiver != null) {
- receiver = receiver.union(oldReceiver, typeFlowAnalysis.hierarchyCache);
- }
- targets[member] = receiver;
- }
+ _ReceiverTypeBuilder _getReceiverTypeBuilder(
+ Map<Member, _ReceiverTypeBuilder> targets, Member member) =>
+ targets[member] ??= new _ReceiverTypeBuilder();
void _setPolymorphic() {
if (!_isPolymorphic) {
@@ -426,6 +503,72 @@
}
}
+/// Efficient builder of receiver type.
+///
+/// Supports the following operations:
+/// 1) Add 1..N concrete types OR add 1 arbitrary type.
+/// 2) Make type nullable.
+class _ReceiverTypeBuilder {
+ Type _type;
+ Set<ConcreteType> _set;
+ bool _nullable = false;
+
+ /// Appends a ConcreteType. May be called multiple times.
+ /// Should not be used in conjunction with [addType].
+ void addConcreteType(ConcreteType type) {
+ if (_set == null) {
+ if (_type == null) {
+ _type = type;
+ return;
+ }
+
+ assertx(_type is ConcreteType);
+ assertx(_type != type);
+
+ _set = new Set<ConcreteType>();
+ _set.add(_type);
+
+ _type = null;
+ }
+
+ _set.add(type);
+ }
+
+ /// Appends an arbitrary Type. May be called only once.
+ /// Should not be used in conjunction with [addConcreteType].
+ void addType(Type type) {
+ assertx(_type == null && _set == null);
+ _type = type;
+ }
+
+ /// Makes the resulting type nullable.
+ void addNull() {
+ _nullable = true;
+ }
+
+ /// Returns union of added types.
+ Type toType() {
+ Type t = _type;
+ if (t == null) {
+ if (_set == null) {
+ t = const EmptyType();
+ } else {
+ t = new SetType(_set);
+ }
+ } else {
+ assertx(_set == null);
+ }
+
+ if (_nullable) {
+ if (t is! NullableType) {
+ t = new NullableType(t);
+ }
+ }
+
+ return t;
+ }
+}
+
class _InvocationsCache {
final Set<_Invocation> _invocations = new Set<_Invocation>();
@@ -514,8 +657,9 @@
class _DynamicTargetSet extends _DependencyTracker {
final DynamicSelector selector;
final Set<Member> targets = new Set<Member>();
+ final bool isObjectMember;
- _DynamicTargetSet(this.selector);
+ _DynamicTargetSet(this.selector, this.isObjectMember);
}
class _ClassData extends _DependencyTracker {
@@ -523,6 +667,11 @@
final Set<_ClassData> supertypes; // List of super-types including this.
final Set<_ClassData> allocatedSubtypes = new Set<_ClassData>();
+ /// Flag indicating if this class has a noSuchMethod() method not inherited
+ /// from Object.
+ /// Lazy initialized by _ClassHierarchyCache.hasNonTrivialNoSuchMethod().
+ bool hasNonTrivialNoSuchMethod;
+
_ClassData(this.class_, this.supertypes) {
supertypes.add(this);
}
@@ -539,6 +688,11 @@
final Set<Class> allocatedClasses = new Set<Class>();
final Map<Class, _ClassData> classes = <Class, _ClassData>{};
+ /// Object.noSuchMethod().
+ final Member objectNoSuchMethod;
+
+ static final Name noSuchMethodName = new Name("noSuchMethod");
+
/// Class hierarchy is sealed after analysis is finished.
/// Once it is sealed, no new allocated classes may be added and no new
/// targets of invocations may appear.
@@ -547,7 +701,12 @@
final Map<DynamicSelector, _DynamicTargetSet> _dynamicTargets =
<DynamicSelector, _DynamicTargetSet>{};
- _ClassHierarchyCache(this._typeFlowAnalysis, this.hierarchy);
+ _ClassHierarchyCache(this._typeFlowAnalysis, this.hierarchy)
+ : objectNoSuchMethod = hierarchy.getDispatchTarget(
+ _typeFlowAnalysis.environment.coreTypes.objectClass,
+ noSuchMethodName) {
+ assertx(objectNoSuchMethod != null);
+ }
_ClassData getClassData(Class c) {
return classes[c] ??= _createClassData(c);
@@ -673,14 +832,26 @@
}
}
- Iterable<Member> getDynamicTargets(DynamicSelector selector) {
- final targetSet =
- (_dynamicTargets[selector] ??= _createDynamicTargetSet(selector));
- return targetSet.targets;
+ bool hasNonTrivialNoSuchMethod(Class c) {
+ final classData = getClassData(c);
+ classData.hasNonTrivialNoSuchMethod ??=
+ (hierarchy.getDispatchTarget(c, noSuchMethodName) !=
+ objectNoSuchMethod);
+ return classData.hasNonTrivialNoSuchMethod;
+ }
+
+ _DynamicTargetSet getDynamicTargetSet(DynamicSelector selector) {
+ return (_dynamicTargets[selector] ??= _createDynamicTargetSet(selector));
}
_DynamicTargetSet _createDynamicTargetSet(DynamicSelector selector) {
- final targetSet = new _DynamicTargetSet(selector);
+ // TODO(alexmarkov): consider caching the set of Object selectors.
+ final isObjectMethod = (hierarchy.getDispatchTarget(
+ _typeFlowAnalysis.environment.coreTypes.objectClass, selector.name,
+ setter: selector.isSetter) !=
+ null);
+
+ final targetSet = new _DynamicTargetSet(selector, isObjectMethod);
for (Class c in allocatedClasses) {
_addDynamicTarget(c, targetSet);
}
@@ -718,19 +889,22 @@
class _WorkList {
final TypeFlowAnalysis _typeFlowAnalysis;
- final Set<_Invocation> pending = new Set<_Invocation>();
+ final LinkedList<_Invocation> pending = new LinkedList<_Invocation>();
final Set<_Invocation> processing = new Set<_Invocation>();
final List<_Invocation> callStack = <_Invocation>[];
_WorkList(this._typeFlowAnalysis);
+ bool _isPending(_Invocation invocation) => invocation.list != null;
+
void enqueueInvocation(_Invocation invocation) {
assertx(invocation.result == null);
- if (!pending.add(invocation)) {
+ if (_isPending(invocation)) {
// Re-add the invocation to the tail of the pending queue.
pending.remove(invocation);
- pending.add(invocation);
+ assertx(!_isPending(invocation));
}
+ pending.add(invocation);
}
void invalidateInvocation(_Invocation invocation) {
@@ -745,14 +919,7 @@
void process() {
while (pending.isNotEmpty) {
assertx(callStack.isEmpty && processing.isEmpty);
- _Invocation invocation = pending.first;
-
- // Remove from pending before processing, as the invocation
- // could be invalidated and re-added to pending while processing.
- pending.remove(invocation);
-
- processInvocation(invocation);
- assertx(invocation.result != null);
+ processInvocation(pending.first);
}
}
@@ -770,6 +937,7 @@
if (processing.add(invocation)) {
callStack.add(invocation);
+ pending.remove(invocation);
final Type result = invocation.process(_typeFlowAnalysis);
@@ -783,6 +951,13 @@
invocation.invalidatedResult = null;
}
+ // Invocation is still pending - it was invalidated while being processed.
+ // Move result to invalidatedResult.
+ if (_isPending(invocation)) {
+ invocation.invalidatedResult = result;
+ invocation.result = null;
+ }
+
final last = callStack.removeLast();
assertx(identical(last, invocation));
diff --git a/pkg/vm/lib/transformations/type_flow/entry_points_extra.json b/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
index dc3849b..d45ef2a 100644
--- a/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
+++ b/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
@@ -62,6 +62,12 @@
"action": "call"
},
{
+ "library": "dart:core",
+ "class": "_AssertionError",
+ "name": "_throwNew",
+ "action": "call"
+ },
+ {
"library": "dart:_builtin",
"name": "_resolveScriptUri",
"action": "call"
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index 1272b69..50dfbb2 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -86,9 +86,6 @@
Narrow(this.arg, this.type);
@override
- DartType get staticType => type.staticType;
-
- @override
void accept(StatementVisitor visitor) => visitor.visitNarrow(this);
@override
@@ -133,9 +130,8 @@
class Call extends Statement {
final Selector selector;
final Args<TypeExpr> args;
- final DartType staticType;
- Call(this.selector, this.args, this.staticType);
+ Call(this.selector, this.args);
@override
void accept(StatementVisitor visitor) => visitor.visitCall(this);
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 8290f25..3899672 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -417,9 +417,7 @@
}
Call _makeCall(TreeNode node, Selector selector, Args<TypeExpr> args) {
- DartType staticType =
- (node is Expression) ? node.getStaticType(_environment) : null;
- Call call = new Call(selector, args, staticType);
+ Call call = new Call(selector, args);
_summary.add(call);
callSites[node] = call;
return call;
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 1d19d63..63f91ae 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -24,6 +24,8 @@
const bool kDumpAllSummaries =
const bool.fromEnvironment('global.type.flow.dump.all.summaries');
+const bool kDumpClassHierarchy =
+ const bool.fromEnvironment('global.type.flow.dump.class.hierarchy');
/// Whole-program type flow analysis and transformation.
/// Assumes strong mode and closed world.
@@ -33,7 +35,9 @@
'pkg/vm/lib/transformations/type_flow/entry_points.json',
'pkg/vm/lib/transformations/type_flow/entry_points_extra.json',
]}) {
- final hierarchy = new ClassHierarchy(program);
+ void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
+ final hierarchy = new ClassHierarchy(program,
+ onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
final types = new TypeEnvironment(coreTypes, hierarchy, strongMode: true);
final libraryIndex = new LibraryIndex.all(program);
@@ -56,6 +60,10 @@
analysisStopWatch.stop();
+ if (kDumpClassHierarchy) {
+ debugPrint(typeFlowAnalysis.hierarchyCache);
+ }
+
final transformsStopWatch = new Stopwatch()..start();
new DropMethodBodiesVisitor(typeFlowAnalysis).visitProgram(program);
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 4865e16..c8249b0 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -42,11 +42,6 @@
abstract class TypeExpr {
const TypeExpr();
- /// Static [DartType] approximation.
- /// May not be available for certain inferred types (such as [EmptyType] and
- /// [SetType]) as they don't have corresponding Dart types.
- DartType get staticType;
-
/// Returns computed type of this type expression.
/// [types] is the list of types computed for the statements in the summary.
Type getComputedType(List<Type> types);
@@ -97,9 +92,6 @@
return new Type.nullable(new ConeType(dartType));
}
- @override
- DartType get staticType;
-
Class getConcreteClass(TypeHierarchy typeHierarchy) => null;
@override
@@ -130,9 +122,6 @@
const EmptyType();
@override
- DartType get staticType => throw 'Unable to get static type of empty type';
-
- @override
int get hashCode => 997;
@override
@@ -162,10 +151,6 @@
}
@override
- DartType get staticType =>
- (baseType is EmptyType) ? const BottomType() : baseType.staticType;
-
- @override
int get hashCode => (baseType.hashCode + 31) & kHashMask;
@override
@@ -210,9 +195,6 @@
const AnyType();
@override
- DartType get staticType => const DynamicType();
-
- @override
int get hashCode => 991;
@override
@@ -252,9 +234,6 @@
}
@override
- DartType get staticType => throw 'Unable to get static type of set type';
-
- @override
int get hashCode => _hashCode ??= _computeHashCode();
int _computeHashCode() {
@@ -338,9 +317,6 @@
}
@override
- DartType get staticType => dartType;
-
- @override
Class getConcreteClass(TypeHierarchy typeHierarchy) => typeHierarchy
.specializeTypeCone(dartType)
.getConcreteClass(typeHierarchy);
@@ -423,9 +399,6 @@
}
@override
- DartType get staticType => dartType;
-
- @override
Class getConcreteClass(TypeHierarchy typeHierarchy) =>
(dartType is InterfaceType)
? (dartType as InterfaceType).classNode
diff --git a/pkg/vm/test/transformations/type_flow/types_test.dart b/pkg/vm/test/transformations/type_flow/types_test.dart
index 7d60091..83685b7 100644
--- a/pkg/vm/test/transformations/type_flow/types_test.dart
+++ b/pkg/vm/test/transformations/type_flow/types_test.dart
@@ -67,36 +67,6 @@
equals(new NullableType(new ConeType(t2Raw))));
});
- test('static-type', () {
- InterfaceType classType = new InterfaceType(new Class(name: 'C'));
- FunctionType funcType = new FunctionType([], const VoidType());
-
- // [T, T.staticType]
- final testCases = [
- [new Type.cone(classType), classType],
- [new Type.cone(funcType), const DynamicType()],
- [new Type.concrete(classType), classType],
- [new AnyType(), const DynamicType()],
- [new Type.nullable(new Type.empty()), const BottomType()],
- [new Type.nullable(new Type.cone(classType)), classType],
- [new Type.nullable(new Type.concrete(classType)), classType],
- [new Type.nullable(new AnyType()), const DynamicType()],
- [new Type.fromStatic(const DynamicType()), const DynamicType()],
- [new Type.fromStatic(const BottomType()), const BottomType()],
- [new Type.fromStatic(classType), classType],
- [new Type.fromStatic(funcType), const DynamicType()],
- ];
-
- for (List testCase in testCases) {
- Type type = testCase[0] as Type;
- DartType staticType = testCase[1] as DartType;
-
- expect(type.staticType, equals(staticType),
- reason:
- "Test case: ${type}.staticType is expected to be $staticType");
- }
- });
-
test('union-intersection', () {
// T1 <: T3, T2 <: T3
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart
new file mode 100644
index 0000000..cd5d128
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class T1 {}
+
+class T2 {}
+
+class T3 {}
+
+class A {
+ foo() => new T1();
+ bar() => new T2();
+ bazz() => new T3();
+}
+
+class B {
+ foo() => new T1();
+ bar() => new T2();
+ bazz() => new T3();
+}
+
+use_foo1(dynamic x) => x.foo();
+use_foo2(dynamic x) => x.foo();
+
+use_bar(dynamic x) => x.bar();
+
+use_bazz(dynamic x) => x.bazz();
+
+Function unknown;
+
+getDynamic() => unknown.call();
+
+allocateA() {
+ new A();
+}
+
+allocateB() {
+ new B();
+}
+
+main(List<String> args) {
+ use_foo1(getDynamic()); // No classes with 'foo' selector.
+
+ allocateA();
+
+ use_foo2(getDynamic()); // Only A with 'foo' selector.
+ use_bar(getDynamic()); // Only A with 'bar' selector.
+
+ allocateB();
+
+ use_bazz(getDynamic()); // A and B have 'bazz' selector.
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
new file mode 100644
index 0000000..68fff2b
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
@@ -0,0 +1,66 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class T1 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class T2 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class T3 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class A extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return new self::T1::•();
+ method bar() → dynamic
+ return new self::T2::•();
+ method bazz() → dynamic
+ return new self::T3::•();
+}
+class B extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ return new self::T1::•();
+ method bar() → dynamic
+ return new self::T2::•();
+ method bazz() → dynamic
+ return new self::T3::•();
+}
+static field core::Function unknown;
+static method use_foo1(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T1] x.foo();
+static method use_foo2(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T1] x.foo();
+static method use_bar(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T2] x.bar();
+static method use_bazz(dynamic x) → dynamic
+ return [@vm.inferred-type.metadata=#lib::T3] x.bazz();
+static method getDynamic() → dynamic
+ return self::unknown.call();
+static method allocateA() → dynamic {
+ new self::A::•();
+}
+static method allocateB() → dynamic {
+ new self::B::•();
+}
+static method main(core::List<core::String> args) → dynamic {
+ self::use_foo1(self::getDynamic());
+ self::allocateA();
+ self::use_foo2(self::getDynamic());
+ self::use_bar(self::getDynamic());
+ self::allocateB();
+ self::use_bazz(self::getDynamic());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart
new file mode 100644
index 0000000..1451811
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class I {
+ void foo();
+}
+
+class T1 implements I {
+ void foo() {}
+}
+
+class T2 implements I {
+ void foo() {}
+}
+
+class Point {
+ final I x;
+
+ const Point(I x) : this.x = x;
+
+ Point newPoint1() => new Point(x);
+ Point newPoint2() => new Point(x);
+}
+
+getX(var point) {
+ point.x;
+}
+
+main() {
+ var a = new Point(new T1());
+
+ print(a.x);
+
+ var c = new Point(new T2());
+
+ c.x.foo();
+
+ getX(a.newPoint1());
+ getX(a.newPoint2());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
new file mode 100644
index 0000000..17533c2
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
@@ -0,0 +1,43 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+abstract class I extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ throw "TFA Error: #lib::I::";
+ abstract method foo() → void;
+}
+class T1 extends core::Object implements self::I {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method foo() → void {}
+}
+class T2 extends core::Object implements self::I {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method foo() → void {}
+}
+class Point extends core::Object {
+ final field self::I x;
+ const constructor •(self::I x) → void
+ : self::Point::x = x, super core::Object::•()
+ ;
+ method newPoint1() → self::Point
+ return new self::Point::•([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
+ method newPoint2() → self::Point
+ return new self::Point::•([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] this.{self::Point::x});
+}
+static method getX(dynamic point) → dynamic {
+ point.x;
+}
+static method main() → dynamic {
+ self::Point a = new self::Point::•(new self::T1::•());
+ core::print([@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] a.{self::Point::x});
+ self::Point c = new self::Point::•(new self::T2::•());
+ [@vm.direct-call.metadata=#lib::Point::x] [@vm.inferred-type.metadata=!] c.{self::Point::x}.{self::I::foo}();
+ self::getX([@vm.direct-call.metadata=#lib::Point::newPoint1] [@vm.inferred-type.metadata=#lib::Point] a.{self::Point::newPoint1}());
+ self::getX([@vm.direct-call.metadata=#lib::Point::newPoint2] [@vm.inferred-type.metadata=#lib::Point] a.{self::Point::newPoint2}());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart
new file mode 100644
index 0000000..ab479a7
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class T1 {}
+
+class T2 {}
+
+class T3 {}
+
+class T4 {}
+
+class T5 {}
+
+abstract class A {
+ foo();
+ get bar;
+ bazz(a1, a2, a3, [a4, a5]);
+}
+
+class B extends A {
+ noSuchMethod(Invocation invocation) {
+ return new T1();
+ }
+}
+
+class C {
+ noSuchMethod(Invocation invocation) {
+ return new T2();
+ }
+}
+
+class D extends C implements A {}
+
+class E implements A {
+ foo() => new T3();
+
+ noSuchMethod(Invocation invocation) {
+ return new T4();
+ }
+}
+
+class F {
+ twoArg(a1, a2) => new T1();
+
+ noSuchMethod(Invocation invocation) {
+ return new T2();
+ }
+}
+
+class G {
+ noSuchMethod(Invocation invocation) {
+ return new T5();
+ }
+}
+
+A bb = new B();
+A dd = new D();
+
+Function unknown;
+
+getDynamic() => unknown.call();
+
+main(List<String> args) {
+ print(bb.foo());
+ print(bb.bar);
+ print(bb.bazz(1, 2, 3, 4));
+
+ print(dd.foo());
+ print(dd.bar);
+ print(dd.bazz(1, 2, 3, 4));
+
+ new E();
+ A xx = getDynamic();
+
+ print(xx.bar);
+
+ dynamic yy = getDynamic();
+ print(yy.twoArg(1, 2, 3));
+
+ new F();
+
+ dynamic gg = new G();
+
+ print(gg.noSuchMethod(null, null));
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
new file mode 100644
index 0000000..2d4e301
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -0,0 +1,107 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class T1 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class T2 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class T3 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ throw "TFA Error: #lib::T3::";
+}
+class T4 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class T5 extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+abstract class A extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ abstract method foo() → dynamic;
+ abstract get bar() → dynamic;
+ abstract method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4 = null, dynamic a5 = null]) → dynamic;
+}
+class B extends self::A {
+ synthetic constructor •() → void
+ : super self::A::•()
+ ;
+ method noSuchMethod(core::Invocation invocation) → dynamic {
+ return new self::T1::•();
+ }
+}
+class C extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation invocation) → dynamic {
+ return new self::T2::•();
+ }
+}
+class D extends self::C implements self::A {
+ synthetic constructor •() → void
+ : super self::C::•()
+ ;
+}
+class E extends core::Object implements self::A {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method foo() → dynamic
+ throw "TFA Error: #lib::E::foo";
+ method noSuchMethod(core::Invocation invocation) → dynamic {
+ return new self::T4::•();
+ }
+}
+class F extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method twoArg(dynamic a1, dynamic a2) → dynamic
+ throw "TFA Error: #lib::F::twoArg";
+ method noSuchMethod(core::Invocation invocation) → dynamic {
+ return new self::T2::•();
+ }
+}
+class G extends core::Object {
+ synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation invocation) → dynamic {
+ return new self::T5::•();
+ }
+}
+static field self::A bb = new self::B::•();
+static field self::A dd = new self::D::•();
+static field core::Function unknown;
+static method getDynamic() → dynamic
+ return self::unknown.call();
+static method main(core::List<core::String> args) → dynamic {
+ core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B] self::bb.{self::A::foo}());
+ core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B] self::bb.{self::A::bar});
+ core::print([@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B] self::bb.{self::A::bazz}(1, 2, 3, 4));
+ core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D] self::dd.{self::A::foo}());
+ core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D] self::dd.{self::A::bar});
+ core::print([@vm.inferred-type.metadata=#lib::T2] [@vm.inferred-type.metadata=#lib::D] self::dd.{self::A::bazz}(1, 2, 3, 4));
+ new self::E::•();
+ self::A xx = self::getDynamic() as{TypeError} self::A;
+ core::print([@vm.inferred-type.metadata=!] xx.{self::A::bar});
+ dynamic yy = self::getDynamic();
+ core::print([@vm.inferred-type.metadata=!] yy.twoArg(1, 2, 3));
+ new self::F::•();
+ dynamic gg = new self::G::•();
+ core::print([@vm.inferred-type.metadata=#lib::T5] gg.{core::Object::noSuchMethod}(null, null));
+}
diff --git a/pkg/vm/tool/dart2 b/pkg/vm/tool/dart2
index 364820c..66ac062 100755
--- a/pkg/vm/tool/dart2
+++ b/pkg/vm/tool/dart2
@@ -45,5 +45,4 @@
--reify-generic-functions \
--limit-ints-to-64-bits \
--dfe="$KERNEL_SERVICE_SNAPSHOT" \
- --kernel-binaries="$KERNEL_BINARIES_DIR" \
"$@"
diff --git a/pkg/vm/tool/dart2.bat b/pkg/vm/tool/dart2.bat
index 739671a..91004d6 100644
--- a/pkg/vm/tool/dart2.bat
+++ b/pkg/vm/tool/dart2.bat
@@ -13,10 +13,12 @@
set OUT_DIR=%SCRIPTPATH%/../../../out/
-REM Remove trailing spaces
-set DART_CONFIGURATION=%DART_CONFIGURATION: =%
-
+REM Remove trailing spaces if line is not empty
+if not "%DART_CONFIGURATION%" == "" (
+ set DART_CONFIGURATION=%DART_CONFIGURATION: =%
+)
if "%DART_CONFIGURATION%"=="" set DART_CONFIGURATION=ReleaseX64
+
if "%DART_USE_SDK%"=="" set DART_USE_SDK=0
set BUILD_DIR=%OUT_DIR%%DART_CONFIGURATION%
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index faf92c0..69062fe 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -16,6 +16,7 @@
OPTIONS=()
PACKAGES=
+SYNC_ASYNC=
ARGV=()
for arg in "$@"; do
@@ -23,6 +24,9 @@
--packages=*)
PACKAGES="$arg"
;;
+ --sync-async)
+ SYNC_ASYNC="--sync-async"
+ ;;
--*)
OPTIONS+=("$arg")
;;
@@ -72,6 +76,7 @@
"${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" \
--platform "${BIN_DIR}/vm_platform_strong.dill" \
--aot \
+ $SYNC_ASYNC \
$PACKAGES \
-o "$SNAPSHOT_FILE.dill" \
"$SOURCE_FILE"
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 9142737..e1ce40e 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -270,6 +270,10 @@
":generate_web_gl_cc_file",
":generate_web_sql_cc_file",
]
+ if (is_fuchsia) {
+ deps += [ "//zircon/public/lib/launchpad" ]
+ public_deps = [ "//zircon/public/lib/fdio" ]
+ }
include_dirs = [ ".." ]
set_sources_assignment_filter([
"*_test.cc",
@@ -321,6 +325,9 @@
":generate_cli_cc_file",
":generate_cli_patch_cc_file",
] + extra_deps
+ if (is_fuchsia) {
+ deps += [ "//zircon/public/lib/launchpad" ]
+ }
sources = [
# Include generated source files.
@@ -376,10 +383,6 @@
"winmm.lib",
]
}
-
- if (is_fuchsia) {
- libs = [ "launchpad" ]
- }
}
}
@@ -419,6 +422,7 @@
if (is_fuchsia) {
deps += [ "//garnet/public/lib/netstack/c" ]
+ public_deps = [ "//zircon/public/lib/fdio" ]
configs -= [ "//build/config:symbol_visibility_hidden" ]
}
@@ -515,8 +519,11 @@
deps += [ "//third_party/boringssl" ]
if (is_fuchsia) {
- deps += [ "//garnet/public/lib/netstack/c" ]
- libs = [ "launchpad" ]
+ deps += [
+ "//garnet/public/lib/netstack/c",
+ "//zircon/public/lib/launchpad",
+ ]
+ public_deps = [ "//zircon/public/lib/fdio" ]
}
sources = io_impl_sources + builtin_impl_sources + cli_impl_sources
@@ -673,24 +680,64 @@
executable = true
}
-action("kernel_service_dill_cc") {
+template("dill_to_cc") {
+ assert(defined(invoker.dill_file), "Need dill_file in $target_name.")
+ assert(defined(invoker.data_symbol), "Need data_symbol in $target_name.")
+ assert(defined(invoker.size_symbol), "Need size_symbol in $target_name.")
+ assert(defined(invoker.output), "Need output in $target_name.")
+
+ extra_deps = []
+ if (defined(invoker.deps)) {
+ extra_deps += invoker.deps
+ }
+
+ action(target_name) {
+ deps = extra_deps
+ script = "../tools/dill_to_data_cc.py"
+ inputs = [
+ "../tools/dill_to_data_cc.py",
+ invoker.dill_file,
+ ]
+ outputs = [
+ invoker.output,
+ ]
+ args = [
+ "--dill_file=" + rebase_path(invoker.dill_file),
+ "--data_symbol=" + invoker.data_symbol,
+ "--size_symbol=" + invoker.size_symbol,
+ "--output=" + rebase_path(invoker.output),
+ ]
+ }
+}
+
+dill_to_cc("kernel_service_dill_cc") {
deps = [
"../../utils/kernel-service:kernel_service_dill",
]
- script = "../tools/dill_to_data_cc.py"
- inputs = [
- "../tools/dill_to_data_cc.py",
- "$root_gen_dir/kernel_service.dill",
+ dill_file = "$root_gen_dir/kernel_service.dill"
+ data_symbol = "kKernelServiceDill"
+ size_symbol = "kKernelServiceDillSize"
+ output = "$root_gen_dir/kernel_service.dill.cc"
+}
+
+dill_to_cc("platform_dill_cc") {
+ deps = [
+ "../vm:vm_legacy_platform",
]
- outputs = [
- "$root_gen_dir/kernel_service.dill.cc",
+ dill_file = "$root_out_dir/vm_platform.dill"
+ data_symbol = "kPlatformDill"
+ size_symbol = "kPlatformDillSize"
+ output = "$target_gen_dir/vm_platform.dill.cc"
+}
+
+dill_to_cc("platform_strong_dill_cc") {
+ deps = [
+ "../vm:vm_platform",
]
- args = [
- "--dill_file=" + rebase_path("$root_gen_dir/kernel_service.dill"),
- "--data_symbol=kKernelServiceDill",
- "--size_symbol=kKernelServiceDillSize",
- "--output=" + rebase_path("$root_gen_dir/kernel_service.dill.cc"),
- ]
+ dill_file = "$root_out_dir/vm_platform_strong.dill"
+ data_symbol = "kPlatformStrongDill"
+ size_symbol = "kPlatformStrongDillSize"
+ output = "$target_gen_dir/vm_platform_strong.dill.cc"
}
source_set("dart_snapshot_cc") {
@@ -698,6 +745,8 @@
":isolate_snapshot_data_assembly",
":isolate_snapshot_instructions_assembly",
":kernel_service_dill_cc",
+ ":platform_dill_cc",
+ ":platform_strong_dill_cc",
":vm_snapshot_data_assembly",
":vm_snapshot_instructions_assembly",
]
@@ -705,6 +754,8 @@
"$root_gen_dir/kernel_service.dill.cc",
"$target_gen_dir/isolate_snapshot_data.S",
"$target_gen_dir/isolate_snapshot_instructions.S",
+ "$target_gen_dir/vm_platform.dill.cc",
+ "$target_gen_dir/vm_platform_strong.dill.cc",
"$target_gen_dir/vm_snapshot_data.S",
"$target_gen_dir/vm_snapshot_instructions.S",
]
@@ -755,6 +806,10 @@
"$dart_zlib_path",
] + extra_deps
+ if (is_fuchsia) {
+ deps += [ "//zircon/public/lib/launchpad" ]
+ }
+
defines = extra_defines
if (dart_use_tcmalloc) {
@@ -797,10 +852,6 @@
"winmm.lib",
]
}
-
- if (is_fuchsia) {
- libs = [ "launchpad" ]
- }
}
}
@@ -1068,7 +1119,7 @@
}
if (is_fuchsia) {
- deps += [ "//zircon/system/ulib/trace" ]
+ deps += [ "//zircon/public/lib/trace" ]
}
# The VM sources are already included in libdart, so we just want to add in
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 7ab6bcb..3e568ac 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -15,6 +15,10 @@
extern "C" {
extern const uint8_t kKernelServiceDill[];
extern intptr_t kKernelServiceDillSize;
+extern const uint8_t kPlatformDill[];
+extern intptr_t kPlatformDillSize;
+extern const uint8_t kPlatformStrongDill[];
+extern intptr_t kPlatformStrongDillSize;
}
namespace dart {
@@ -23,17 +27,21 @@
#if defined(DART_NO_SNAPSHOT) || defined(DART_PRECOMPILER)
const uint8_t* kernel_service_dill = NULL;
const intptr_t kernel_service_dill_size = 0;
+const uint8_t* platform_dill = NULL;
+const intptr_t platform_dill_size = 0;
+const uint8_t* platform_strong_dill = NULL;
+const intptr_t platform_strong_dill_size = 0;
#else
const uint8_t* kernel_service_dill = kKernelServiceDill;
const intptr_t kernel_service_dill_size = kKernelServiceDillSize;
+const uint8_t* platform_dill = kPlatformDill;
+const intptr_t platform_dill_size = kPlatformDillSize;
+const uint8_t* platform_strong_dill = kPlatformStrongDill;
+const intptr_t platform_strong_dill_size = kPlatformStrongDillSize;
#endif
const char kKernelServiceSnapshot[] = "kernel-service.dart.snapshot";
const char kSnapshotsDirectory[] = "snapshots";
-const char kPlatformBinaryName[] = "vm_platform.dill";
-const char kPlatformStrongBinaryName[] = "vm_platform_strong.dill";
-
-void* DFE::kKernelServiceProgram = NULL;
static char* GetDirectoryPrefixFromExeName() {
const char* name = Platform::GetExecutableName();
@@ -54,12 +62,14 @@
return StringUtils::StrNDup(name, i + 1);
}
+static void NoopRelease(uint8_t* buffer) {}
+
DFE::DFE()
: use_dfe_(false),
frontend_filename_(NULL),
- kernel_binaries_path_(NULL),
- platform_binary_filename_(NULL),
- kernel_platform_(NULL),
+ kernel_service_program_(NULL),
+ platform_program_(NULL),
+ platform_strong_program_(NULL),
application_kernel_binary_(NULL) {}
DFE::~DFE() {
@@ -68,23 +78,34 @@
}
frontend_filename_ = NULL;
- free(kernel_binaries_path_);
- kernel_binaries_path_ = NULL;
+ delete reinterpret_cast<kernel::Program*>(kernel_service_program_);
+ kernel_service_program_ = NULL;
- free(platform_binary_filename_);
- platform_binary_filename_ = NULL;
+ delete reinterpret_cast<kernel::Program*>(platform_program_);
+ platform_program_ = NULL;
- delete reinterpret_cast<kernel::Program*>(kernel_platform_);
- kernel_platform_ = NULL;
-
- delete reinterpret_cast<kernel::Program*>(kKernelServiceProgram);
- kKernelServiceProgram = NULL;
+ delete reinterpret_cast<kernel::Program*>(platform_strong_program_);
+ platform_strong_program_ = NULL;
delete reinterpret_cast<kernel::Program*>(application_kernel_binary_);
application_kernel_binary_ = NULL;
}
-char* DFE::FrontendFilename() {
+void DFE::Init() {
+ if (platform_dill == NULL) {
+ return;
+ }
+ // platform_dill is not NULL implies that platform_strong_dill is also
+ // not NULL.
+ if (platform_program_ == NULL) {
+ platform_program_ =
+ Dart_ReadKernelBinary(platform_dill, platform_dill_size, NoopRelease);
+ }
+ if (platform_strong_program_ == NULL) {
+ platform_strong_program_ = Dart_ReadKernelBinary(
+ platform_strong_dill, platform_strong_dill_size, NoopRelease);
+ }
+
if (frontend_filename_ == NULL) {
// Look for the frontend snapshot next to the executable.
char* dir_prefix = GetDirectoryPrefixFromExeName();
@@ -108,40 +129,34 @@
frontend_filename_ = NULL;
}
}
- return frontend_filename_;
}
bool DFE::KernelServiceDillAvailable() {
return kernel_service_dill != NULL;
}
-static void NoopRelease(uint8_t* buffer) {}
-
-void* DFE::KernelServiceProgram() {
+void* DFE::LoadKernelServiceProgram() {
if (kernel_service_dill == NULL) {
return NULL;
}
- if (kKernelServiceProgram == NULL) {
- kKernelServiceProgram = Dart_ReadKernelBinary(
+ if (kernel_service_program_ == NULL) {
+ kernel_service_program_ = Dart_ReadKernelBinary(
kernel_service_dill, kernel_service_dill_size, NoopRelease);
}
- return kKernelServiceProgram;
+ return kernel_service_program_;
}
-void DFE::SetKernelBinaries(const char* name) {
- kernel_binaries_path_ = strdup(name);
+void* DFE::platform_program(bool strong) const {
+ if (strong) {
+ return platform_strong_program_;
+ } else {
+ return platform_program_;
+ }
}
-const char* DFE::GetPlatformBinaryFilename() {
- if (kernel_binaries_path_ == NULL) {
- return NULL;
- }
- if (platform_binary_filename_ == NULL) {
- platform_binary_filename_ = OS::SCreate(
- /*zone=*/NULL, "%s%s%s", kernel_binaries_path_, File::PathSeparator(),
- FLAG_strong ? kPlatformStrongBinaryName : kPlatformBinaryName);
- }
- return platform_binary_filename_;
+bool DFE::CanUseDartFrontend() const {
+ return (platform_program() != NULL) &&
+ (KernelServiceDillAvailable() || (frontend_filename() != NULL));
}
static void ReleaseFetchedBytes(uint8_t* buffer) {
@@ -162,13 +177,8 @@
// recompile the script.
// TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill
// instead of vm_platform.dill to Frontend for compilation.
- const char* platform_kernel = GetPlatformBinaryFilename();
- if (platform_kernel == NULL) {
- return Dart_NewApiError(
- "Path to platfrom kernel not known; did you miss --kernel-binaries?");
- }
Dart_KernelCompilationResult kresult =
- Dart_CompileToKernel(url_string, platform_kernel);
+ Dart_CompileToKernel(url_string, platform_dill, platform_dill_size);
if (kresult.status != Dart_KernelCompilationStatus_Ok) {
return Dart_NewApiError(kresult.error);
}
@@ -219,7 +229,8 @@
void* DFE::CompileAndReadScript(const char* script_uri,
char** error,
- int* exit_code) {
+ int* exit_code,
+ bool strong) {
// TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill
// instead of vm_platform.dill to Frontend for compilation.
#if defined(HOST_OS_WINDOWS)
@@ -229,12 +240,12 @@
const char* sanitized_uri = script_uri;
#endif
- const char* platform_kernel = GetPlatformBinaryFilename();
- if (platform_kernel == NULL) {
- return NULL;
- }
- Dart_KernelCompilationResult result =
- Dart_CompileToKernel(sanitized_uri, platform_kernel);
+ const uint8_t* platform_binary =
+ strong ? platform_strong_dill : platform_dill;
+ intptr_t platform_binary_size =
+ strong ? platform_strong_dill_size : platform_dill_size;
+ Dart_KernelCompilationResult result = Dart_CompileToKernel(
+ sanitized_uri, platform_binary, platform_binary_size);
switch (result.status) {
case Dart_KernelCompilationStatus_Ok:
return Dart_ReadKernelBinary(result.kernel, result.kernel_size,
@@ -255,10 +266,6 @@
return NULL;
}
-void* DFE::ReadPlatform() {
- return ReadScript(GetPlatformBinaryFilename());
-}
-
void* DFE::ReadScript(const char* script_uri) const {
const uint8_t* buffer = NULL;
intptr_t buffer_length = -1;
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index 2d13b92..0ee4c25 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -18,7 +18,12 @@
DFE();
~DFE();
- char* FrontendFilename();
+ // Call Init before Dart_Initialize to prevent races between the
+ // different isolates.
+ void Init();
+
+ char* frontend_filename() const { return frontend_filename_; }
+
void set_frontend_filename(const char* name) {
if (frontend_filename_ != NULL) {
free(frontend_filename_);
@@ -26,24 +31,19 @@
frontend_filename_ = strdup(name);
set_use_dfe();
}
- void set_use_dfe() { use_dfe_ = true; }
+ void set_use_dfe(bool value = true) { use_dfe_ = value; }
bool UseDartFrontend() const { return use_dfe_; }
+ // Returns the platform binary file name if the path to
+ // kernel binaries was set using SetKernelBinaries.
const char* GetPlatformBinaryFilename();
- void SetKernelBinaries(const char* name);
-
- bool UsePlatformBinary() const { return kernel_binaries_path_ != NULL; }
-
- void* kernel_platform() const { return kernel_platform_; }
- void set_kernel_platform(void* kernel_platform) {
- kernel_platform_ = kernel_platform;
- }
-
- void* application_kernel_binary() const { return application_kernel_binary_; }
+ // Set the kernel program for the main application if it was specified
+ // as a dill file.
void set_application_kernel_binary(void* application_kernel_binary) {
application_kernel_binary_ = application_kernel_binary;
}
+ void* application_kernel_binary() const { return application_kernel_binary_; }
// Method to read a kernel file into a kernel program blob.
// If the specified script [url] is not a kernel IR, compile it first using
@@ -57,20 +57,26 @@
// 'error' and 'exit_code' have the error values in case of errors.
void* CompileAndReadScript(const char* script_uri,
char** error,
- int* exit_code);
-
- // Reads the platform kernel file.
- // Returns an in memory kernel representation of the platform kernel file.
- void* ReadPlatform();
+ int* exit_code,
+ bool strong);
// Reads the script kernel file if specified 'script_uri' is a kernel file.
// Returns an in memory kernel representation of the specified script is a
// valid kernel file, false otherwise.
void* ReadScript(const char* script_uri) const;
- static void* KernelServiceProgram();
static bool KernelServiceDillAvailable();
+ // We distinguish between "intent to use Dart frontend" vs "can actually
+ // use Dart frontend". The method UseDartFrontend tells us about the
+ // intent to use DFE. This method tells us if Dart frontend can actually
+ // be used.
+ bool CanUseDartFrontend() const;
+
+ void* platform_program(bool strong = false) const;
+
+ void* LoadKernelServiceProgram();
+
private:
// Tries to read [script_uri] as a Kernel IR file.
// Returns `true` if successful and sets [kernel_file] and [kernel_length]
@@ -83,16 +89,15 @@
bool use_dfe_;
char* frontend_filename_;
- char* kernel_binaries_path_;
- char* platform_binary_filename_;
- void* kernel_platform_;
+
+ void* kernel_service_program_;
+ void* platform_program_;
+ void* platform_strong_program_;
// Kernel binary specified on the cmd line.
// Loaded instead of platform if --kernel-binaries is not specified.
void* application_kernel_binary_;
- static void* kKernelServiceProgram;
-
DISALLOW_COPY_AND_ASSIGN(DFE);
};
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 956cfe2..462c1a2 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -72,6 +72,7 @@
kScript,
kAppAOTBlobs,
kAppAOTAssembly,
+ kVMAOTAssembly,
};
static SnapshotKind snapshot_kind = kCore;
@@ -128,7 +129,13 @@
}
static const char* kSnapshotKindNames[] = {
- "core", "core-jit", "script", "app-aot-blobs", "app-aot-assembly", NULL,
+ "core",
+ "core-jit",
+ "script",
+ "app-aot-blobs",
+ "app-aot-assembly",
+ "vm-aot-assembly",
+ NULL,
};
#define STRING_OPTIONS_LIST(V) \
@@ -169,7 +176,9 @@
DEFINE_CB_OPTION(ProcessEnvironmentOption);
static bool IsSnapshottingForPrecompilation() {
- return (snapshot_kind == kAppAOTBlobs) || (snapshot_kind == kAppAOTAssembly);
+ return (snapshot_kind == kAppAOTBlobs) ||
+ (snapshot_kind == kAppAOTAssembly) ||
+ (snapshot_kind == kVMAOTAssembly);
}
static bool SnapshotKindAllowedFromKernel() {
@@ -276,13 +285,15 @@
}
break;
}
- }
-
- if (IsSnapshottingForPrecompilation() && (entry_points_files->count() == 0)) {
- Log::PrintErr(
- "Building an AOT snapshot requires at least one embedder "
- "entry points manifest.\n\n");
- return -1;
+ case kVMAOTAssembly: {
+ if ((assembly_filename == NULL) || (*script_name != NULL)) {
+ Log::PrintErr(
+ "Building an AOT snapshot as assembly requires specifying "
+ "an output file for --assembly and a Dart script.\n\n");
+ return -1;
+ }
+ break;
+ }
}
if (!obfuscate && obfuscation_map_filename != NULL) {
@@ -504,6 +515,8 @@
// WriteDependenciesWithTarget(isolate_snapshot_data_filename);
// WriteDependenciesWithTarget(isolate_snapshot_instructions_filename);
break;
+ default:
+ UNREACHABLE();
}
if (!success_) {
@@ -795,27 +808,12 @@
}
// clang-format on
-static const char StubNativeFunctionName[] = "StubNativeFunction";
+static void LoadEntryPoint(size_t lib_index,
+ const Dart_QualifiedFunctionName* entry) {
+ if (strcmp(entry->library_uri, "::") == 0) {
+ return; // Root library always loaded; can't `import '::';`.
+ }
-void StubNativeFunction(Dart_NativeArguments arguments) {
- // This is a stub function for the resolver
- Dart_SetReturnValue(
- arguments, Dart_NewApiError("<EMBEDDER DID NOT SETUP NATIVE RESOLVER>"));
-}
-
-static Dart_NativeFunction StubNativeLookup(Dart_Handle name,
- int argument_count,
- bool* auto_setup_scope) {
- return &StubNativeFunction;
-}
-
-static const uint8_t* StubNativeSymbol(Dart_NativeFunction nf) {
- return reinterpret_cast<const uint8_t*>(StubNativeFunctionName);
-}
-
-static void SetupStubNativeResolver(size_t lib_index,
- const Dart_QualifiedFunctionName* entry) {
- // TODO(24686): Remove this.
Dart_Handle library_string = Dart_NewStringFromCString(entry->library_uri);
DART_CHECK_VALID(library_string);
Dart_Handle library = Dart_LookupLibrary(library_string);
@@ -842,29 +840,6 @@
}
DART_CHECK_VALID(library);
- Dart_Handle result =
- Dart_SetNativeResolver(library, &StubNativeLookup, &StubNativeSymbol);
- DART_CHECK_VALID(result);
-}
-
-// Iterate over all libraries and setup the stub native lookup. This must be
-// run after |SetupStubNativeResolversForPrecompilation| because the former
-// loads some libraries.
-static void SetupStubNativeResolvers() {
- Dart_Handle libraries = Dart_GetLoadedLibraries();
- intptr_t libraries_length;
- Dart_ListLength(libraries, &libraries_length);
- for (intptr_t i = 0; i < libraries_length; i++) {
- Dart_Handle library = Dart_ListGetAt(libraries, i);
- DART_CHECK_VALID(library);
- Dart_NativeEntryResolver old_resolver = NULL;
- Dart_GetNativeResolver(library, &old_resolver);
- if (old_resolver == NULL) {
- Dart_Handle result =
- Dart_SetNativeResolver(library, &StubNativeLookup, &StubNativeSymbol);
- DART_CHECK_VALID(result);
- }
- }
}
static void ImportNativeEntryPointLibrariesIntoRoot(
@@ -880,17 +855,18 @@
// The termination sentinel has null members.
break;
}
- Dart_Handle entry_library =
- Dart_LookupLibrary(Dart_NewStringFromCString(entry.library_uri));
- DART_CHECK_VALID(entry_library);
- Dart_Handle import_result = Dart_LibraryImportLibrary(
- entry_library, Dart_RootLibrary(), Dart_EmptyString());
- DART_CHECK_VALID(import_result);
+ if (strcmp(entry.library_uri, "::") != 0) {
+ Dart_Handle entry_library =
+ Dart_LookupLibrary(Dart_NewStringFromCString(entry.library_uri));
+ DART_CHECK_VALID(entry_library);
+ Dart_Handle import_result = Dart_LibraryImportLibrary(
+ entry_library, Dart_RootLibrary(), Dart_EmptyString());
+ DART_CHECK_VALID(import_result);
+ }
}
}
-static void SetupStubNativeResolversForPrecompilation(
- const Dart_QualifiedFunctionName* entries) {
+static void LoadEntryPoints(const Dart_QualifiedFunctionName* entries) {
if (entries == NULL) {
return;
}
@@ -903,8 +879,8 @@
// The termination sentinel has null members.
break;
}
- // Setup stub resolvers on loaded libraries
- SetupStubNativeResolver(index, &entry);
+ // Ensure library named in entry point is loaded.
+ LoadEntryPoint(index, &entry);
}
}
@@ -1439,8 +1415,7 @@
Dart_QualifiedFunctionName* entry_points =
ParseEntryPointsManifestIfPresent();
- SetupStubNativeResolversForPrecompilation(entry_points);
- SetupStubNativeResolvers();
+
CreateAndWritePrecompiledSnapshot(entry_points);
CreateAndWriteDependenciesFile();
@@ -1601,6 +1576,20 @@
Dart_Handle library;
Dart_EnterScope();
+ if (snapshot_kind == kVMAOTAssembly) {
+ uint8_t* assembly_buffer = NULL;
+ intptr_t assembly_size = 0;
+ result =
+ Dart_CreateVMAOTSnapshotAsAssembly(&assembly_buffer, &assembly_size);
+ CHECK_RESULT(result);
+
+ WriteFile(assembly_filename, assembly_buffer, assembly_size);
+
+ Dart_ExitScope();
+ Dart_ShutdownIsolate();
+ return 0;
+ }
+
result = Dart_SetEnvironmentCallback(EnvironmentCallback);
CHECK_RESULT(result);
@@ -1667,17 +1656,18 @@
AddDependency(commandline_packages_file);
}
- SetupStubNativeResolversForPrecompilation(entry_points);
+ ASSERT(kernel_program == NULL);
- SetupStubNativeResolvers();
+ // Load any libraries named in the entry points. Do this before loading the
+ // user's script to ensure conditional imports see the embedder-specific
+ // dart: libraries.
+ LoadEntryPoints(entry_points);
- if (kernel_program == NULL) {
- // Load the specified script.
- library = LoadSnapshotCreationScript(app_script_name);
- CHECK_RESULT(library);
+ // Load the specified script.
+ library = LoadSnapshotCreationScript(app_script_name);
+ CHECK_RESULT(library);
- ImportNativeEntryPointLibrariesIntoRoot(entry_points);
- }
+ ImportNativeEntryPointLibrariesIntoRoot(entry_points);
// Ensure that we mark all libraries as loaded.
result = Dart_FinalizeLoading(false);
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index bb6adc6..0f1db6e 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -209,39 +209,6 @@
}
}
-#if !defined(DART_PRECOMPILED_RUNTIME)
-// Forward a request from the tag handler to the kernel isolate.
-// [ tag, send port, url ]
-void Loader::SendKernelRequest(Dart_LibraryTag tag, Dart_Handle url) {
- // This port delivers loading messages to the Kernel isolate.
- Dart_Port kernel_port = Dart_KernelPort();
- ASSERT(kernel_port != ILLEGAL_PORT);
-
- // NOTE: This list should be kept in sync with kernel_service.dart
- // and kernel_isolate.cc.
- Dart_Handle request = Dart_NewList(9);
- Dart_ListSetAt(request, 0, Dart_NewInteger(tag));
- Dart_ListSetAt(request, 1, Dart_NewSendPort(port_));
- Dart_ListSetAt(request, 2, url);
- const char* platform_kernel = dfe.GetPlatformBinaryFilename();
- if (platform_kernel != NULL) {
- Dart_ListSetAt(request, 3, Dart_NewStringFromCString(platform_kernel));
- } else {
- Dart_ListSetAt(request, 3, Dart_Null());
- }
- Dart_ListSetAt(request, 4, Dart_False() /* incremental */);
- Dart_ListSetAt(request, 5, Dart_True() /* strong */);
- Dart_ListSetAt(request, 6,
- Dart_NewInteger(Dart_GetMainPortId()) /* isolateId */);
- Dart_ListSetAt(request, 7, Dart_Null() /* sourceFiles */);
- Dart_ListSetAt(request, 8, Dart_True() /* suppressWarnings */);
- if (Dart_Post(kernel_port, request)) {
- MonitorLocker ml(monitor_);
- pending_operations_++;
- }
-}
-#endif
-
void Loader::QueueMessage(Dart_CObject* message) {
MonitorLocker ml(monitor_);
if (results_length_ == results_capacity_) {
@@ -695,8 +662,8 @@
if (Dart_IsError(result)) {
return result;
}
+ Dart_Isolate current = Dart_CurrentIsolate();
if (tag == Dart_kKernelTag) {
- Dart_Isolate current = Dart_CurrentIsolate();
ASSERT(!Dart_IsServiceIsolate(current) && !Dart_IsKernelIsolate(current));
return dfe.ReadKernelBinary(current, url_string);
}
@@ -713,7 +680,7 @@
return Extensions::LoadExtension("/", absolute_path, library);
}
- ASSERT(Dart_IsKernelIsolate(Dart_CurrentIsolate()) || !dfe.UseDartFrontend());
+ ASSERT(Dart_IsKernelIsolate(current) || !dfe.UseDartFrontend());
if (tag != Dart_kScriptTag) {
// Special case for handling dart: imports and parts.
// Grab the library's url.
@@ -791,13 +758,9 @@
if (DartUtils::IsDartExtensionSchemeURL(url_string)) {
loader->SendImportExtensionRequest(url, Dart_LibraryUrl(library));
} else {
- if (Dart_KernelIsolateIsRunning() &&
- isolate_data->create_isolate_from_kernel()) {
- // TODO(sivachandra): After linking the platform kernel file with
- // the embedder, the library tag handler should not be called to compile
- // a script to kernel and load it. Remove this part when platform kernel
- // kernel file is linked in to the embedder.
- loader->SendKernelRequest(tag, url);
+ if (dfe.CanUseDartFrontend() && dfe.UseDartFrontend() &&
+ !Dart_IsKernelIsolate(current)) {
+ FATAL("Loader should not be called to compile scripts to kernel.");
} else {
loader->SendRequest(
tag, url,
diff --git a/runtime/bin/loader.h b/runtime/bin/loader.h
index 808524f..2e94033 100644
--- a/runtime/bin/loader.h
+++ b/runtime/bin/loader.h
@@ -101,9 +101,6 @@
uint8_t** payload,
intptr_t* payload_length);
- // Send a request from the tag handler to the kernel isolate.
- void SendKernelRequest(Dart_LibraryTag tag, Dart_Handle url);
-
/// Queue |message| and notify the loader that a message is available.
void QueueMessage(Dart_CObject* message);
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 0f33626..2741f90 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -302,7 +302,7 @@
Dart_IsolateFlags* flags,
char** error,
int* exit_code) {
- const char* kernel_snapshot_uri = dfe.FrontendFilename();
+ const char* kernel_snapshot_uri = dfe.frontend_filename();
const char* uri =
kernel_snapshot_uri != NULL ? kernel_snapshot_uri : script_uri;
@@ -333,11 +333,11 @@
DART_KERNEL_ISOLATE_NAME, main, isolate_snapshot_data,
isolate_snapshot_instructions, flags, isolate_data, error);
} else {
- void* kernel_service_program = DFE::KernelServiceProgram();
+ void* kernel_service_program = dfe.LoadKernelServiceProgram();
+ ASSERT(kernel_service_program != NULL);
IsolateData* isolate_data =
new IsolateData(uri, package_root, packages_config, NULL);
isolate_data->kernel_program = kernel_service_program;
- isolate_data->set_create_isolate_from_kernel(true);
isolate = Dart_CreateIsolateFromKernel(uri, main, kernel_service_program,
flags, isolate_data, error);
}
@@ -391,16 +391,25 @@
// non-kernel flow.
ASSERT(flags != NULL);
flags->load_vmservice_library = true;
- if (dfe.UsePlatformBinary()) {
- isolate_data->set_create_isolate_from_kernel(true);
- isolate = Dart_CreateIsolateFromKernel(
- script_uri, NULL, dfe.kernel_platform(), flags, isolate_data, error);
- skip_library_load = true;
- } else if (dfe.application_kernel_binary() != NULL) {
- isolate_data->set_create_isolate_from_kernel(true);
- isolate = Dart_CreateIsolateFromKernel(script_uri, NULL,
- dfe.application_kernel_binary(),
- flags, isolate_data, error);
+
+ if (dfe.UseDartFrontend()) {
+ // If there is intention to use DFE, then we create the isolate
+ // from kernel only if we can.
+ void* platform_program = dfe.platform_program(flags->strong) != NULL
+ ? dfe.platform_program(flags->strong)
+ : dfe.application_kernel_binary();
+ // TODO(sivachandra): When the platform program is unavailable, check if
+ // application kernel binary is self contained or an incremental binary.
+ // Isolate should be created only if it is a self contained kernel binary.
+ if (platform_program != NULL) {
+ isolate = Dart_CreateIsolateFromKernel(script_uri, NULL, platform_program,
+ flags, isolate_data, error);
+ } else {
+ *error = OS::SCreate(
+ NULL, "Platform kernel not available to create service isolate.");
+ delete isolate_data;
+ return NULL;
+ }
skip_library_load = true;
} else {
isolate = Dart_CreateIsolate(script_uri, main, isolate_snapshot_data,
@@ -447,16 +456,9 @@
char** error,
int* exit_code) {
ASSERT(script_uri != NULL);
- void* kernel_platform = NULL;
void* kernel_program = NULL;
AppSnapshot* app_snapshot = NULL;
- IsolateData* isolate_data =
- new IsolateData(script_uri, package_root, packages_config, app_snapshot);
- if (is_main_isolate && (Options::snapshot_deps_filename() != NULL)) {
- isolate_data->set_dependencies(new MallocGrowableArray<char*>());
- }
-
#if defined(DART_PRECOMPILED_RUNTIME)
// AOT: All isolates start from the app snapshot.
bool isolate_run_app_snapshot = true;
@@ -488,27 +490,45 @@
}
}
if (!isolate_run_app_snapshot) {
- kernel_platform = dfe.kernel_platform();
kernel_program = dfe.ReadScript(script_uri);
if (dfe.UseDartFrontend() && (kernel_program == NULL)) {
- kernel_program = dfe.CompileAndReadScript(script_uri, error, exit_code);
+ if (!dfe.CanUseDartFrontend()) {
+ *error = OS::SCreate(NULL, "Dart frontend unavailable to compile %s.",
+ script_uri);
+ return NULL;
+ }
+ kernel_program =
+ dfe.CompileAndReadScript(script_uri, error, exit_code, flags->strong);
if (kernel_program == NULL) {
+ // Error message would have been set by DFE::CompileAndReadScript.
return NULL;
}
}
- isolate_data->kernel_program = kernel_program;
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
+ IsolateData* isolate_data =
+ new IsolateData(script_uri, package_root, packages_config, app_snapshot);
+ if (is_main_isolate && (Options::snapshot_deps_filename() != NULL)) {
+ isolate_data->set_dependencies(new MallocGrowableArray<char*>());
+ }
+
Dart_Isolate isolate = NULL;
- if (kernel_platform != NULL) {
- isolate_data->set_create_isolate_from_kernel(true);
- isolate = Dart_CreateIsolateFromKernel(script_uri, main, kernel_platform,
+ if (kernel_program != NULL) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ UNREACHABLE();
+ return NULL;
+#else
+ isolate_data->kernel_program = kernel_program;
+ void* platform_program = dfe.platform_program(flags->strong) != NULL
+ ? dfe.platform_program(flags->strong)
+ : kernel_program;
+ // TODO(sivachandra): When the platform program is unavailable, check if
+ // application kernel binary is self contained or an incremental binary.
+ // Isolate should be created only if it is a self contained kernel binary.
+ isolate = Dart_CreateIsolateFromKernel(script_uri, main, platform_program,
flags, isolate_data, error);
- } else if (kernel_program != NULL) {
- isolate_data->set_create_isolate_from_kernel(true);
- isolate = Dart_CreateIsolateFromKernel(script_uri, main, kernel_program,
- flags, isolate_data, error);
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
} else {
isolate = Dart_CreateIsolate(script_uri, main, isolate_snapshot_data,
isolate_snapshot_instructions, flags,
@@ -1050,22 +1070,14 @@
// Note: must read platform only *after* VM flags are parsed because
// they might affect how the platform is loaded.
#if !defined(DART_PRECOMPILED_RUNTIME)
- // If a kernel platform binary file is specified, read it. This
- // step will become redundant once we have the snapshot version
- // of the kernel core/platform libraries.
- void* application_kernel_binary = NULL;
- if (dfe.UsePlatformBinary()) {
- void* kernel_platform = dfe.ReadPlatform();
- if (kernel_platform == NULL) {
- Log::PrintErr("The platform binary is not a valid Dart Kernel file.");
- Platform::Exit(kErrorExitCode);
- }
- dfe.set_kernel_platform(kernel_platform);
- } else {
- application_kernel_binary = dfe.ReadScript(script_name);
- if (application_kernel_binary != NULL) {
- dfe.set_application_kernel_binary(application_kernel_binary);
- }
+ dfe.Init();
+ void* application_kernel_binary = dfe.ReadScript(script_name);
+ if (application_kernel_binary != NULL) {
+ // Since we loaded the script anyway, save it.
+ dfe.set_application_kernel_binary(application_kernel_binary);
+ // Since we saw a dill file, it means we have to use DFE for
+ // any further source file parsing.
+ dfe.set_use_dfe();
}
#endif
@@ -1089,16 +1101,8 @@
init_params.entropy_source = DartUtils::EntropySource;
init_params.get_service_assets = GetVMServiceAssetsArchiveCallback;
#if !defined(DART_PRECOMPILED_RUNTIME)
- // Start the kernel isolate only if
- // 1. --dart_preview_2 and/or --dfe is used
- //
- // or
- //
- // 2. If we have kernel service dill file linked in and a dill file
- // was specified as the main dart program.
init_params.start_kernel_isolate =
- dfe.UseDartFrontend() || ((application_kernel_binary != NULL) &&
- DFE::KernelServiceDillAvailable());
+ dfe.UseDartFrontend() && dfe.CanUseDartFrontend();
#else
init_params.start_kernel_isolate = false;
#endif
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 5b89ff9..30f656b 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -72,8 +72,6 @@
// specifying --preview_dart_2.
DEFINE_STRING_OPTION_CB(dfe, { Options::dfe()->set_frontend_filename(value); });
-DEFINE_STRING_OPTION_CB(kernel_binaries,
- { Options::dfe()->SetKernelBinaries(value); });
#endif // !defined(DART_PRECOMPILED_RUNTIME)
DEFINE_BOOL_OPTION_CB(hot_reload_test_mode, {
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 4128b5f..6f58f55 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -3135,7 +3135,9 @@
DART_EXPORT bool Dart_KernelIsolateIsRunning();
DART_EXPORT Dart_Port Dart_KernelPort();
DART_EXPORT Dart_KernelCompilationResult
-Dart_CompileToKernel(const char* script_uri, const char* platform_kernel);
+Dart_CompileToKernel(const char* script_uri,
+ const uint8_t* platform_kernel,
+ const intptr_t platform_kernel_size);
typedef struct {
const char* uri;
@@ -3143,7 +3145,8 @@
} Dart_SourceFile;
DART_EXPORT Dart_KernelCompilationResult
Dart_CompileSourcesToKernel(const char* script_uri,
- const char* platform_kernel,
+ const uint8_t* platform_kernel,
+ intptr_t platform_kernel_size,
int source_files_count,
Dart_SourceFile source_files[],
bool incremental_compile);
diff --git a/runtime/lib/async_patch.dart b/runtime/lib/async_patch.dart
index de47bf2..19d5b6a 100644
--- a/runtime/lib/async_patch.dart
+++ b/runtime/lib/async_patch.dart
@@ -17,6 +17,43 @@
// Equivalent of calling FATAL from C++ code.
_fatal(msg) native "DartAsync_fatal";
+class _AsyncAwaitCompleter<T> implements Completer<T> {
+ final _completer = new Completer<T>.sync();
+ bool isSync;
+
+ _AsyncAwaitCompleter() : isSync = false;
+
+ void complete([FutureOr<T> value]) {
+ if (isSync) {
+ _completer.complete(value);
+ } else if (value is Future<T>) {
+ value.then(_completer.complete, onError: _completer.completeError);
+ } else {
+ scheduleMicrotask(() {
+ _completer.complete(value);
+ });
+ }
+ }
+
+ void completeError(e, [st]) {
+ if (isSync) {
+ _completer.completeError(e, st);
+ } else {
+ scheduleMicrotask(() {
+ _completer.completeError(e, st);
+ });
+ }
+ }
+
+ void start(f) {
+ f();
+ isSync = true;
+ }
+
+ Future<T> get future => _completer.future;
+ bool get isCompleted => _completer.isCompleted;
+}
+
// We need to pass the value as first argument and leave the second and third
// arguments empty (used for error handling).
// See vm/ast_transformer.cc for usage.
diff --git a/runtime/lib/bigint_patch.dart b/runtime/lib/bigint_patch.dart
new file mode 100644
index 0000000..5ad216f
--- /dev/null
+++ b/runtime/lib/bigint_patch.dart
@@ -0,0 +1,2110 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// part of dart.core;
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * Copyright (c) 2012 Adam Singer (adam@solvr.io)
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+@patch
+class BigInt implements Comparable<BigInt> {
+ @patch
+ static BigInt get zero => _BigIntImpl.zero;
+ @patch
+ static BigInt get one => _BigIntImpl.one;
+ @patch
+ static BigInt get two => _BigIntImpl.two;
+
+ @patch
+ static BigInt parse(String source, {int radix}) =>
+ _BigIntImpl.parse(source, radix: radix);
+
+ @patch
+ factory BigInt.from(num value) = _BigIntImpl.from;
+}
+
+int _max(int a, int b) => a > b ? a : b;
+int _min(int a, int b) => a < b ? a : b;
+
+/**
+ * An implementation for the arbitrarily large integer.
+ *
+ * The integer number is represented by a sign, an array of 16-bit unsigned
+ * integers in little endian format, and a number of used digits in that array.
+ */
+class _BigIntImpl implements BigInt {
+ // Bits per digit.
+ static const int _digitBits = 16;
+ static const int _digitBase = 1 << _digitBits;
+ static const int _digitMask = (1 << _digitBits) - 1;
+
+ static final _BigIntImpl zero = new _BigIntImpl._fromInt(0);
+ static final _BigIntImpl one = new _BigIntImpl._fromInt(1);
+ static final _BigIntImpl two = new _BigIntImpl._fromInt(2);
+
+ static final _BigIntImpl _minusOne = -one;
+ static final _BigIntImpl _bigInt10000 = new _BigIntImpl._fromInt(10000);
+
+ // Result cache for last _divRem call.
+ // Result cache for last _divRem call.
+ static Uint16List _lastDividendDigits;
+ static int _lastDividendUsed;
+ static Uint16List _lastDivisorDigits;
+ static int _lastDivisorUsed;
+ static Uint16List _lastQuoRemDigits;
+ static int _lastQuoRemUsed;
+ static int _lastRemUsed;
+ static int _lastRem_nsh;
+
+ /// Whether this bigint is negative.
+ final bool _isNegative;
+
+ /// The unsigned digits of this bigint.
+ ///
+ /// The least significant digit is in slot 0.
+ /// The list may have more digits than needed. That is, `_digits.length` may
+ /// be strictly greater than `_used`.
+ final Uint16List _digits;
+
+ /// The number of used entries in [_digits].
+ ///
+ /// To avoid reallocating [Uint16List]s, lists that are too big are not
+ /// replaced.
+ final int _used;
+
+ /**
+ * Parses [source] as a, possibly signed, integer literal and returns its
+ * value.
+ *
+ * The [source] must be a non-empty sequence of base-[radix] digits,
+ * optionally prefixed with a minus or plus sign ('-' or '+').
+ *
+ * The [radix] must be in the range 2..36. The digits used are
+ * first the decimal digits 0..9, and then the letters 'a'..'z' with
+ * values 10 through 35. Also accepts upper-case letters with the same
+ * values as the lower-case ones.
+ *
+ * If no [radix] is given then it defaults to 10. In this case, the [source]
+ * digits may also start with `0x`, in which case the number is interpreted
+ * as a hexadecimal literal, which effectively means that the `0x` is ignored
+ * and the radix is instead set to 16.
+ *
+ * For any int `n` and radix `r`, it is guaranteed that
+ * `n == int.parse(n.toRadixString(r), radix: r)`.
+ *
+ * Throws a [FormatException] if the [source] is not a valid integer literal,
+ * optionally prefixed by a sign.
+ */
+ static _BigIntImpl parse(String source, {int radix}) {
+ var result = _tryParse(source, radix: radix);
+ if (result == null) {
+ throw new FormatException("Could not parse BigInt", source);
+ }
+ return result;
+ }
+
+ /// Parses a decimal bigint literal.
+ ///
+ /// The [source] must not contain leading or trailing whitespace.
+ static _BigIntImpl _parseDecimal(String source, bool isNegative) {
+ const _0 = 48;
+
+ int part = 0;
+ _BigIntImpl result = zero;
+ // Read in the source 4 digits at a time.
+ // The first part may have a few leading virtual '0's to make the remaining
+ // parts all have exactly 4 digits.
+ int digitInPartCount = 4 - source.length.remainder(4);
+ if (digitInPartCount == 4) digitInPartCount = 0;
+ for (int i = 0; i < source.length; i++) {
+ part = part * 10 + source.codeUnitAt(i) - _0;
+ if (++digitInPartCount == 4) {
+ result = result * _bigInt10000 + new _BigIntImpl._fromInt(part);
+ part = 0;
+ digitInPartCount = 0;
+ }
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Returns the value of a given source digit.
+ ///
+ /// Source digits between "0" and "9" (inclusive) return their decimal value.
+ ///
+ /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return
+ /// 10 + their position in the ASCII alphabet.
+ ///
+ /// The incoming [codeUnit] must be an ASCII code-unit.
+ static int _codeUnitToRadixValue(int codeUnit) {
+ // We know that the characters must be ASCII as otherwise the
+ // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+ // guaranteed to be a safe operation, since it preserves digits
+ // and lower-cases ASCII letters.
+ const int _0 = 48;
+ const int _9 = 57;
+ const int _a = 97;
+ if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0;
+ codeUnit |= 0x20;
+ var result = codeUnit - _a + 10;
+ return result;
+ }
+
+ /// Parses the given [source] string, starting at [startPos], as a hex
+ /// literal.
+ ///
+ /// If [isNegative] is true, negates the result before returning it.
+ ///
+ /// The [source] (substring) must be a valid hex literal.
+ static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) {
+ int hexDigitsPerChunk = _digitBits ~/ 4;
+ int sourceLength = source.length - startPos;
+ int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
+ var digits = new Uint16List(chunkCount);
+
+ int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk;
+ int digitIndex = digits.length - 1;
+ int i = startPos;
+ int chunk = 0;
+ for (int j = 0; j < lastDigitLength; j++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (digitValue >= 16) return null;
+ chunk = chunk * 16 + digitValue;
+ }
+ digits[digitIndex--] = chunk;
+
+ while (i < source.length) {
+ chunk = 0;
+ for (int j = 0; j < 4; j++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (digitValue >= 16) return null;
+ chunk = chunk * 16 + digitValue;
+ }
+ digits[digitIndex--] = chunk;
+ }
+ if (digits.length == 1 && digits[0] == 0) return zero;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ /// Parses the given [source] as a [radix] literal.
+ ///
+ /// The [source] will be checked for invalid characters. If it is invalid,
+ /// this function returns `null`.
+ static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) {
+ var result = zero;
+ var base = new _BigIntImpl._fromInt(radix);
+ for (int i = 0; i < source.length; i++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i));
+ if (digitValue >= radix) return null;
+ result = result * base + new _BigIntImpl._fromInt(digitValue);
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Tries to parse the given [source] as a [radix] literal.
+ ///
+ /// Returns the parsed big integer, or `null` if it failed.
+ ///
+ /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
+ static _BigIntImpl _tryParse(String source, {int radix}) {
+ if (source == "") return null;
+
+ var re = new RegExp(r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$',
+ caseSensitive: false);
+ var match = re.firstMatch(source);
+ int signIndex = 1;
+ int hexIndex = 3;
+ int decimalIndex = 4;
+ int nonDecimalHexIndex = 5;
+ if (match == null) return null;
+
+ bool isNegative = match[signIndex] == "-";
+
+ String decimalMatch = match[decimalIndex];
+ String hexMatch = match[hexIndex];
+ String nonDecimalMatch = match[nonDecimalHexIndex];
+
+ if (radix == null) {
+ if (decimalMatch != null) {
+ // Cannot fail because we know that the digits are all decimal.
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (hexMatch != null) {
+ // Cannot fail because we know that the digits are all hex.
+ return _parseHex(hexMatch, 2, isNegative);
+ }
+ return null;
+ }
+
+ if (radix is! int) {
+ throw new ArgumentError.value(radix, 'radix', 'is not an integer');
+ }
+ if (radix < 2 || radix > 36) {
+ throw new RangeError.range(radix, 2, 36, 'radix');
+ }
+ if (radix == 10 && decimalMatch != null) {
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
+ return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative);
+ }
+
+ return _parseRadix(
+ decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative);
+ }
+
+ /// Finds the amount significant digits in the provided [digits] array.
+ static int _normalize(int used, Uint16List digits) {
+ while (used > 0 && digits[used - 1] == 0) used--;
+ return used;
+ }
+
+ /// Factory returning an instance initialized with the given field values.
+ /// If the [digits] array contains leading 0s, the [used] value is adjusted
+ /// accordingly. The [digits] array is not modified.
+ _BigIntImpl._(bool isNegative, int used, Uint16List digits)
+ : this._normalized(isNegative, _normalize(used, digits), digits);
+
+ _BigIntImpl._normalized(bool isNegative, this._used, this._digits)
+ : _isNegative = _used == 0 ? false : isNegative;
+
+ /// Whether this big integer is zero.
+ bool get _isZero => _used == 0;
+
+ /// Allocates an array of the given [length] and copies the [digits] in the
+ /// range [from] to [to-1], starting at index 0, followed by leading zero
+ /// digits.
+ static Uint16List _cloneDigits(
+ Uint16List digits, int from, int to, int length) {
+ var resultDigits = new Uint16List(length);
+ var n = to - from;
+ for (var i = 0; i < n; i++) {
+ resultDigits[i] = digits[from + i];
+ }
+ return resultDigits;
+ }
+
+ /// Allocates a big integer from the provided [value] number.
+ factory _BigIntImpl.from(num value) {
+ if (value == 0) return zero;
+ if (value == 1) return one;
+ if (value == 2) return two;
+
+ // Given this order dart2js will use the `_fromInt` for smaller value and
+ // then use the bit-manipulating `_fromDouble` for all other values.
+ if (value.abs() < 0x100000000)
+ return new _BigIntImpl._fromInt(value.toInt());
+ if (value is double) return new _BigIntImpl._fromDouble(value);
+ return new _BigIntImpl._fromInt(value);
+ }
+
+ factory _BigIntImpl._fromInt(int value) {
+ bool isNegative = value < 0;
+ if (isNegative) {
+ // Handle the min 64-bit value differently, since its negation is not
+ // positive.
+ // TODO(floitsch): we should use min.minValue or 0x8000000000000000 here.
+ const int minInt64 = -9223372036854775807 - 1;
+ if (value == minInt64) {
+ var digits = new Uint16List(4);
+ digits[3] = 0x8000;
+ return new _BigIntImpl._(true, digits.length, digits);
+ }
+ value = -value;
+ }
+ assert(_digitBits == 16);
+ if (value < _digitBase) {
+ var digits = new Uint16List(1);
+ digits[0] = value;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+ if (value <= 0xFFFFFFFF) {
+ var digits = new Uint16List(2);
+ digits[0] = value & _digitMask;
+ digits[1] = value >> _digitBits;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ var bits = value.bitLength;
+ var digits = new Uint16List((bits - 1) ~/ _digitBits + 1);
+ var i = 0;
+ while (value != 0) {
+ digits[i++] = value & _digitMask;
+ value = value ~/ _digitBase;
+ }
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating
+ /// garbage.
+ static final Uint8List _bitsForFromDouble = new Uint8List(8);
+
+ factory _BigIntImpl._fromDouble(double value) {
+ const int exponentBias = 1075;
+
+ if (value.isNaN || value.isInfinite) {
+ throw new ArgumentError("Value must be finite: $value");
+ }
+ bool isNegative = value < 0;
+ if (isNegative) value = -value;
+
+ value = value.floorToDouble();
+ if (value == 0) return zero;
+
+ var bits = _bitsForFromDouble;
+ for (int i = 0; i < 8; i++) {
+ bits[i] = 0;
+ }
+ bits.buffer.asByteData().setFloat64(0, value, Endian.little);
+ // The exponent is in bits 53..63.
+ var biasedExponent = (bits[7] << 4) + (bits[6] >> 4);
+ var exponent = biasedExponent - exponentBias;
+
+ assert(_digitBits == 16);
+ // The significant bits are in 0 .. 52.
+ var unshiftedDigits = new Uint16List(4);
+ unshiftedDigits[0] = (bits[1] << 8) + bits[0];
+ unshiftedDigits[1] = (bits[3] << 8) + bits[2];
+ unshiftedDigits[2] = (bits[5] << 8) + bits[4];
+ // Don't forget to add the hidden bit.
+ unshiftedDigits[3] = 0x10 | (bits[6] & 0xF);
+
+ var unshiftedBig = new _BigIntImpl._normalized(false, 4, unshiftedDigits);
+ _BigIntImpl absResult;
+ if (exponent < 0) {
+ absResult = unshiftedBig >> -exponent;
+ } else if (exponent > 0) {
+ absResult = unshiftedBig << exponent;
+ }
+ if (isNegative) return -absResult;
+ return absResult;
+ }
+
+ /**
+ * Return the negative value of this integer.
+ *
+ * The result of negating an integer always has the opposite sign, except
+ * for zero, which is its own negation.
+ */
+ _BigIntImpl operator -() {
+ if (_used == 0) return this;
+ return new _BigIntImpl._(!_isNegative, _used, _digits);
+ }
+
+ /**
+ * Returns the absolute value of this integer.
+ *
+ * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+ */
+ _BigIntImpl abs() => _isNegative ? -this : this;
+
+ /// Returns this << n *_DIGIT_BITS.
+ _BigIntImpl _dlShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used + n;
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ for (int i = used - 1; i >= 0; i--) {
+ resultDigits[i + n] = digits[i];
+ }
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ /// Same as [_dlShift] but works on the decomposed big integers.
+ ///
+ /// Returns `resultUsed`.
+ ///
+ /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`.
+ static int _dlShiftDigits(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ if (xUsed == 0) {
+ return 0;
+ }
+ if (n == 0 && identical(resultDigits, xDigits)) {
+ return xUsed;
+ }
+ final resultUsed = xUsed + n;
+ for (int i = xUsed - 1; i >= 0; i--) {
+ resultDigits[i + n] = xDigits[i];
+ }
+ for (int i = n - 1; i >= 0; i--) {
+ resultDigits[i] = 0;
+ }
+ return resultUsed;
+ }
+
+ /// Returns `this >> n*_DIGIT_BITS`.
+ _BigIntImpl _drShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used - n;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ for (var i = n; i < used; i++) {
+ resultDigits[i - n] = digits[i];
+ }
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ for (var i = 0; i < n; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Shifts the digits of [xDigits] into the right place in [resultDigits].
+ ///
+ /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)`
+ /// where `ds = ceil(n / _DIGIT_BITS)`
+ ///
+ /// Does *not* clear digits below ds.
+ static void _lsh(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << carryBitShift) - 1;
+ var carry = 0;
+ for (int i = xUsed - 1; i >= 0; i--) {
+ final digit = xDigits[i];
+ resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry;
+ carry = (digit & bitMask) << bitShift;
+ }
+ resultDigits[digitShift] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the left by [shiftAmount].
+ *
+ * Shifting to the left makes the number larger, effectively multiplying
+ * the number by `pow(2, shiftIndex)`.
+ *
+ * There is no limit on the size of the result. It may be relevant to
+ * limit intermediate values by using the "and" operator with a suitable
+ * mask.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator <<(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+ }
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _dlShift(digitShift);
+ }
+ var resultUsed = _used + digitShift + 1;
+ var resultDigits = new Uint16List(resultUsed);
+ _lsh(_digits, _used, shiftAmount, resultDigits);
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n.
+ // Returns resultUsed.
+ static int _lShiftDigits(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ if (bitShift == 0) {
+ return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits);
+ }
+ var resultUsed = xUsed + digitsShift + 1;
+ _lsh(xDigits, xUsed, n, resultDigits);
+ var i = digitsShift;
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ if (resultDigits[resultUsed - 1] == 0) {
+ resultUsed--; // Clamp result.
+ }
+ return resultUsed;
+ }
+
+ // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
+ static void _rsh(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << bitShift) - 1;
+ var carry = xDigits[digitsShift] >> bitShift;
+ final last = xUsed - digitsShift - 1;
+ for (var i = 0; i < last; i++) {
+ final digit = xDigits[i + digitsShift + 1];
+ resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry;
+ carry = digit >> bitShift;
+ }
+ resultDigits[last] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the right by [shiftAmount].
+ *
+ * Shifting to the right makes the number smaller and drops the least
+ * significant bits, effectively doing an integer division by
+ *`pow(2, shiftIndex)`.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator >>(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+ }
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _drShift(digitShift);
+ }
+ final used = _used;
+ final resultUsed = used - digitShift;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ _rsh(digits, used, shiftAmount, resultDigits);
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) {
+ return result - one;
+ }
+ for (var i = 0; i < digitShift; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Compares this to [other] taking the absolute value of both operands.
+ ///
+ /// Returns 0 if abs(this) == abs(other); a positive number if
+ /// abs(this) > abs(other); and a negative number if abs(this) < abs(other).
+ int _absCompare(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ return _compareDigits(_digits, _used, other._digits, other._used);
+ }
+
+ /**
+ * Compares this to `other`.
+ *
+ * Returns a negative number if `this` is less than `other`, zero if they are
+ * equal, and a positive number if `this` is greater than `other`.
+ */
+ int compareTo(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ var result = _absCompare(other);
+ // Use 0 - result to avoid negative zero in JavaScript.
+ return _isNegative ? 0 - result : result;
+ }
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`.
+ ///
+ /// Returns 0 if equal; a positive number if larger;
+ /// and a negative number if smaller.
+ static int _compareDigits(
+ Uint16List digits, int used, Uint16List otherDigits, int otherUsed) {
+ var result = used - otherUsed;
+ if (result == 0) {
+ for (int i = used - 1; i >= 0; i--) {
+ result = digits[i] - otherDigits[i];
+ if (result != 0) return result;
+ }
+ }
+ return result;
+ }
+
+ // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1].
+ // used >= otherUsed > 0.
+ static void _absAdd(Uint16List digits, int used, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] + otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ resultDigits[used] = carry;
+ }
+
+ // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1].
+ // used >= otherUsed > 0.
+ static void _absSub(Uint16List digits, int used, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] - otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ // Dart2js only supports unsigned shifts.
+ // Since the carry can only be -1 or 0 use this hack.
+ carry = 0 - ((carry >> _digitBits) & 1);
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ // Dart2js only supports unsigned shifts.
+ // Since the carry can only be -1 or 0 use this hack.
+ carry = 0 - ((carry >> _digitBits) & 1);
+ }
+ }
+
+ /// Returns `abs(this) + abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ if (used < otherUsed) {
+ return other._absAddSetSign(this, isNegative);
+ }
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultUsed = used + 1;
+ var resultDigits = new Uint16List(resultUsed);
+ _absAdd(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) - abs(other)` with sign set according to [isNegative].
+ ///
+ /// Requirement: `abs(this) >= abs(other)`.
+ _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) {
+ assert(_absCompare(other) >= 0);
+ var used = _used;
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ var otherUsed = other._used;
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultDigits = new Uint16List(used);
+ _absSub(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, used, resultDigits);
+ }
+
+ /// Returns `abs(this) & abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _min(_used, other._used);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ for (var i = 0; i < resultUsed; i++) {
+ resultDigits[i] = digits[i] & otherDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _used;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var m = _min(resultUsed, other._used);
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] & ~otherDigits[i];
+ }
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = digits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) | abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] | otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] ^ otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /**
+ * Bit-wise and operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with only the bits set that are set in
+ * both `this` and [other]
+ *
+ * Of both operands are negative, the result is negative, otherwise
+ * the result is non-negative.
+ */
+ _BigIntImpl operator &(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) & (-other) == ~(this-1) & ~(other-1)
+ // == ~((this-1) | (other-1))
+ // == -(((this-1) | (other-1)) + 1)
+ _BigIntImpl this1 = _absSubSetSign(one, true);
+ _BigIntImpl other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and other are negative.
+ return this1._absOrSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absAndSetSign(other, false);
+ }
+ // _isNegative != other._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // & is symmetric.
+ p = this;
+ n = other;
+ }
+ // p & (-n) == p & ~(n-1) == p &~ (n-1)
+ var n1 = n._absSubSetSign(one, false);
+ return p._absAndNotSetSign(n1, false);
+ }
+
+ /**
+ * Bit-wise or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in either
+ * of `this` and [other]
+ *
+ * If both operands are non-negative, the result is non-negative,
+ * otherwise the result us negative.
+ */
+ _BigIntImpl operator |(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) | (-other) == ~(this-1) | ~(other-1)
+ // == ~((this-1) & (other-1))
+ // == -(((this-1) & (other-1)) + 1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and a are negative.
+ return this1._absAndSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absOrSetSign(other, false);
+ }
+ // _neg != a._neg
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // | is symmetric.
+ p = this;
+ n = other;
+ }
+ // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * Bit-wise exclusive-or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in one,
+ * but not both, of `this` and [other]
+ *
+ * If the operands have the same sign, the result is non-negative,
+ * otherwise the result is negative.
+ */
+ _BigIntImpl operator ^(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ return this1._absXorSetSign(other1, false);
+ }
+ return _absXorSetSign(other, false);
+ }
+ // _isNegative != a._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // ^ is symmetric.
+ p = this;
+ n = other;
+ }
+ // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return p._absXorSetSign(n1, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * The bit-wise negate operator.
+ *
+ * Treating `this` as a sufficiently large two's component integer,
+ * the result is a number with the opposite bits set.
+ *
+ * This maps any integer `x` to `-x - 1`.
+ */
+ _BigIntImpl operator ~() {
+ if (_isNegative) {
+ // ~(-this) == ~(~(this-1)) == this-1
+ return _absSubSetSign(one, false);
+ }
+ // ~this == -this-1 == -(this+1)
+ // Result cannot be zero if this is positive.
+ return _absAddSetSign(one, true);
+ }
+
+ /// Addition operator.
+ _BigIntImpl operator +(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var isNegative = _isNegative;
+ if (isNegative == other._isNegative) {
+ // this + other == this + other
+ // (-this) + (-other) == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this + (-other) == this - other == -(this - other)
+ // (-this) + other == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Subtraction operator.
+ _BigIntImpl operator -(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var isNegative = _isNegative;
+ if (isNegative != other._isNegative) {
+ // this - (-other) == this + other
+ // (-this) - other == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this - other == this - a == -(this - other)
+ // (-this) - (-other) == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Multiplies [x] with [multiplicandDigits] and adds the result to
+ /// [accumulatorDigits].
+ ///
+ /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the
+ /// multiplicand digits.
+ ///
+ /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator
+ /// digits.
+ ///
+ /// Adds the result of the multiplicand-digits * [x] to the accumulator.
+ ///
+ /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`.
+ static void _mulAdd(int x, Uint16List multiplicandDigits, int i,
+ Uint16List accumulatorDigits, int j, int n) {
+ if (x == 0) {
+ // No-op if x is 0.
+ return;
+ }
+ int c = 0;
+ while (--n >= 0) {
+ int product = x * multiplicandDigits[i++];
+ int combined = product + accumulatorDigits[j] + c;
+ accumulatorDigits[j++] = combined & _digitMask;
+ // Note that this works with 53 bits, as the division will not lose
+ // bits.
+ c = combined ~/ _digitBase;
+ }
+ while (c != 0) {
+ int l = accumulatorDigits[j] + c;
+ accumulatorDigits[j++] = l & _digitMask;
+ c = l ~/ _digitBase;
+ }
+ }
+
+ /// Multiplication operator.
+ _BigIntImpl operator *(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var used = _used;
+ var otherUsed = other._used;
+ if (used == 0 || otherUsed == 0) {
+ return zero;
+ }
+ var resultUsed = used + otherUsed;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var i = 0;
+ while (i < otherUsed) {
+ _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used);
+ i++;
+ }
+ return new _BigIntImpl._(
+ _isNegative != other._isNegative, resultUsed, resultDigits);
+ }
+
+ // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1].
+ // Return resultUsed = xUsed + otherUsed.
+ static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ var resultUsed = xUsed + otherUsed;
+ var i = resultUsed;
+ assert(resultDigits.length >= i);
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ i = 0;
+ while (i < otherUsed) {
+ _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed);
+ i++;
+ }
+ return resultUsed;
+ }
+
+ /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`.
+ static int _estimateQuotientDigit(
+ int topDigitDivisor, Uint16List digits, int i) {
+ if (digits[i] == topDigitDivisor) return _digitMask;
+ var quotientDigit =
+ (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor;
+ if (quotientDigit > _digitMask) return _digitMask;
+ return quotientDigit;
+ }
+
+ /// Returns `trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _div(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return zero;
+ }
+ _divRem(other);
+ // Return quotient, i.e.
+ // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
+ var lastQuo_used = _lastQuoRemUsed - _lastRemUsed;
+ var quo_digits = _cloneDigits(
+ _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used);
+ var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits);
+ if ((_isNegative != other._isNegative) && (quo._used > 0)) {
+ quo = -quo;
+ }
+ return quo;
+ }
+
+ /// Returns `this - other * trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _rem(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return this;
+ }
+ _divRem(other);
+ // Return remainder, i.e.
+ // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
+ var remDigits =
+ _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed);
+ var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits);
+ if (_lastRem_nsh > 0) {
+ rem = rem >> _lastRem_nsh; // Denormalize remainder.
+ }
+ if (_isNegative && (rem._used > 0)) {
+ rem = -rem;
+ }
+ return rem;
+ }
+
+ /// Computes this ~/ other and this.remainder(other).
+ ///
+ /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and
+ /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the
+ /// quotient and the remainder.
+ ///
+ /// Caches the input to avoid doing the work again when users write
+ /// `a ~/ b` followed by a `a % b`.
+ void _divRem(_BigIntImpl other) {
+ // Check if result is already cached.
+ if ((this._used == _lastDividendUsed) &&
+ (other._used == _lastDivisorUsed) &&
+ identical(this._digits, _lastDividendDigits) &&
+ identical(other._digits, _lastDivisorDigits)) {
+ return;
+ }
+ assert(_used >= other._used);
+
+ var nsh = _digitBits - other._digits[other._used - 1].bitLength;
+ // Concatenated positive quotient and normalized positive remainder.
+ // The resultDigits can have at most one more digit than the dividend.
+ Uint16List resultDigits;
+ int resultUsed;
+ // Normalized positive divisor.
+ // The normalized divisor has the most-significant bit of it's most
+ // significant digit set.
+ // This makes estimating the quotient easier.
+ Uint16List yDigits;
+ int yUsed;
+ if (nsh > 0) {
+ yDigits = new Uint16List(other._used + 5);
+ yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits);
+ resultDigits = new Uint16List(_used + 5);
+ resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits);
+ } else {
+ yDigits = other._digits;
+ yUsed = other._used;
+ resultDigits = _cloneDigits(_digits, 0, _used, _used + 2);
+ resultUsed = _used;
+ }
+ var topDigitDivisor = yDigits[yUsed - 1];
+ var i = resultUsed;
+ var j = i - yUsed;
+ // tmpDigits is a temporary array of i (resultUsed) digits.
+ var tmpDigits = new Uint16List(i);
+ var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
+ // Explicit first division step in case normalized dividend is larger or
+ // equal to shifted normalized divisor.
+ if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
+ assert(i == resultUsed);
+ resultDigits[resultUsed++] = 1; // Quotient = 1.
+ // Subtract divisor from remainder.
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ } else {
+ // Account for possible carry in _mulAdd step.
+ resultDigits[resultUsed++] = 0;
+ }
+
+ // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
+ var nyDigits = new Uint16List(yUsed + 2);
+ nyDigits[yUsed] = 1;
+ _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits);
+ // nyDigits is read-only and has yUsed digits (possibly including several
+ // leading zeros).
+ // resultDigits is modified during iteration.
+ // resultDigits[0..yUsed-1] is the current remainder.
+ // resultDigits[yUsed..resultUsed-1] is the current quotient.
+ --i;
+
+ while (j > 0) {
+ var estimatedQuotientDigit =
+ _estimateQuotientDigit(topDigitDivisor, resultDigits, i);
+ j--;
+ _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed);
+ if (resultDigits[i] < estimatedQuotientDigit) {
+ // Reusing the already existing tmpDigits array.
+ var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ while (resultDigits[i] < --estimatedQuotientDigit) {
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ }
+ }
+ i--;
+ }
+ // Cache result.
+ _lastDividendDigits = _digits;
+ _lastDividendUsed = _used;
+ _lastDivisorDigits = other._digits;
+ _lastDivisorUsed = other._used;
+ _lastQuoRemDigits = resultDigits;
+ _lastQuoRemUsed = resultUsed;
+ _lastRemUsed = yUsed;
+ _lastRem_nsh = nsh;
+ }
+
+ int get hashCode {
+ // This is the [Jenkins hash function][1] but using masking to keep
+ // values in SMI range.
+ //
+ // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+
+ int combine(int hash, int value) {
+ hash = 0x1fffffff & (hash + value);
+ hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+ return hash ^ (hash >> 6);
+ }
+
+ int finish(int hash) {
+ hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+ hash = hash ^ (hash >> 11);
+ return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+ }
+
+ if (_isZero) return 6707; // Just a random number.
+ var hash = _isNegative ? 83585 : 429689; // Also random.
+ for (int i = 0; i < _used; i++) {
+ hash = combine(hash, _digits[i]);
+ }
+ return finish(hash);
+ }
+
+ /**
+ * Test whether this value is numerically equal to `other`.
+ *
+ * If [other] is a [_BigIntImpl] returns whether the two operands have the same
+ * value.
+ *
+ * Returns false if `other` is not a [_BigIntImpl].
+ */
+ bool operator ==(Object other) =>
+ other is _BigIntImpl && compareTo(other) == 0;
+
+ /**
+ * Returns the minimum number of bits required to store this big integer.
+ *
+ * The number of bits excludes the sign bit, which gives the natural length
+ * for non-negative (unsigned) values. Negative values are complemented to
+ * return the bit position of the first bit that differs from the sign bit.
+ *
+ * To find the number of bits needed to store the value as a signed value,
+ * add one, i.e. use `x.bitLength + 1`.
+ *
+ * ```
+ * x.bitLength == (-x-1).bitLength
+ *
+ * new BigInt.from(3).bitLength == 2; // 00000011
+ * new BigInt.from(2).bitLength == 2; // 00000010
+ * new BigInt.from(1).bitLength == 1; // 00000001
+ * new BigInt.from(0).bitLength == 0; // 00000000
+ * new BigInt.from(-1).bitLength == 0; // 11111111
+ * new BigInt.from(-2).bitLength == 1; // 11111110
+ * new BigInt.from(-3).bitLength == 2; // 11111101
+ * new BigInt.from(-4).bitLength == 2; // 11111100
+ * ```
+ */
+ int get bitLength {
+ if (_used == 0) return 0;
+ if (_isNegative) return (~this).bitLength;
+ return _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ }
+
+ /**
+ * Truncating division operator.
+ *
+ * Performs a truncating integer division, where the remainder is discarded.
+ *
+ * The remainder can be computed using the [remainder] method.
+ *
+ * Examples:
+ * ```
+ * var seven = new BigInt.from(7);
+ * var three = new BigInt.from(3);
+ * seven ~/ three; // => 2
+ * (-seven) ~/ three; // => -2
+ * seven ~/ -three; // => -2
+ * seven.remainder(three); // => 1
+ * (-seven).remainder(three); // => -1
+ * seven.remainder(-three); // => 1
+ * ```
+ */
+ _BigIntImpl operator ~/(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _div(other);
+ }
+
+ /**
+ * Returns the remainder of the truncating division of `this` by [other].
+ *
+ * The result `r` of this operation satisfies:
+ * `this == (this ~/ other) * other + r`.
+ * As a consequence the remainder `r` has the same sign as the divider `this`.
+ */
+ _BigIntImpl remainder(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _rem(other);
+ }
+
+ /// Division operator.
+ double operator /(BigInt other) => this.toDouble() / other.toDouble();
+
+ /** Relational less than operator. */
+ bool operator <(BigInt other) => compareTo(other) < 0;
+
+ /** Relational less than or equal operator. */
+ bool operator <=(BigInt other) => compareTo(other) <= 0;
+
+ /** Relational greater than operator. */
+ bool operator >(BigInt other) => compareTo(other) > 0;
+
+ /** Relational greater than or equal operator. */
+ bool operator >=(BigInt other) => compareTo(other) >= 0;
+
+ /**
+ * Euclidean modulo operator.
+ *
+ * Returns the remainder of the Euclidean division. The Euclidean division of
+ * two integers `a` and `b` yields two integers `q` and `r` such that
+ * `a == b * q + r` and `0 <= r < b.abs()`.
+ *
+ * The sign of the returned value `r` is always positive.
+ *
+ * See [remainder] for the remainder of the truncating division.
+ */
+ _BigIntImpl operator %(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ var result = _rem(other);
+ if (result._isNegative) {
+ if (other._isNegative) {
+ result = result - other;
+ } else {
+ result = result + other;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the sign of this big integer.
+ *
+ * Returns 0 for zero, -1 for values less than zero and
+ * +1 for values greater than zero.
+ */
+ int get sign {
+ if (_used == 0) return 0;
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Whether this big integer is even.
+ bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
+
+ /// Whether this big integer is odd.
+ bool get isOdd => !isEven;
+
+ /// Whether this number is negative.
+ bool get isNegative => _isNegative;
+
+ _BigIntImpl pow(int exponent) {
+ if (exponent < 0) {
+ throw new ArgumentError("Exponent must not be negative: $exponent");
+ }
+ if (exponent == 0) return one;
+
+ // Exponentiation by squaring.
+ var result = one;
+ var base = this;
+ while (exponent != 0) {
+ if ((exponent & 1) == 1) {
+ result *= base;
+ }
+ exponent >>= 1;
+ // Skip unnecessary operation.
+ if (exponent != 0) {
+ base *= base;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns this integer to the power of [exponent] modulo [modulus].
+ *
+ * The [exponent] must be non-negative and [modulus] must be
+ * positive.
+ */
+ _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) {
+ _BigIntImpl exponent = bigExponent;
+ _BigIntImpl modulus = bigModulus;
+ if (exponent._isNegative) {
+ throw new ArgumentError("exponent must be positive: $exponent");
+ }
+ if (modulus <= zero) {
+ throw new ArgumentError("modulus must be strictly positive: $modulus");
+ }
+ if (exponent._isZero) return one;
+
+ final modulusUsed = modulus._used;
+ final modulusUsed2p4 = 2 * modulusUsed + 4;
+ final exponentBitlen = exponent.bitLength;
+ if (exponentBitlen <= 0) return one;
+ _BigIntReduction z = new _BigIntClassic(modulus);
+ var resultDigits = new Uint16List(modulusUsed2p4);
+ var result2Digits = new Uint16List(modulusUsed2p4);
+ var gDigits = new Uint16List(modulusUsed);
+ var gUsed = z.convert(this, gDigits);
+ // Initialize result with g.
+ // Copy leading zero if any.
+ for (int j = gUsed - 1; j >= 0; j--) {
+ resultDigits[j] = gDigits[j];
+ }
+ var resultUsed = gUsed;
+ var result2Used;
+ for (int i = exponentBitlen - 2; i >= 0; i--) {
+ result2Used = z.sqr(resultDigits, resultUsed, result2Digits);
+ if (!(exponent & (one << i))._isZero) {
+ resultUsed =
+ z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits);
+ } else {
+ // Swap result and result2.
+ var tmpDigits = resultDigits;
+ var tmpUsed = resultUsed;
+ resultDigits = result2Digits;
+ resultUsed = result2Used;
+ result2Digits = tmpDigits;
+ result2Used = tmpUsed;
+ }
+ }
+ return z.revert(resultDigits, resultUsed);
+ }
+
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+ static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) {
+ var xDigits = x._digits;
+ var yDigits = y._digits;
+ var xUsed = x._used;
+ var yUsed = y._used;
+ var maxUsed = xUsed > yUsed ? xUsed : yUsed;
+ var unshiftedMaxUsed = maxUsed; // Keep
+ xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed);
+ yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed);
+ int shiftAmount = 0;
+ if (inv) {
+ if ((yUsed == 1) && (yDigits[0] == 1)) return one;
+ if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) {
+ throw new Exception("Not coprime");
+ }
+ } else {
+ if (x._isZero) {
+ throw new ArgumentError.value(0, "this", "must not be zero");
+ }
+ if (y._isZero) {
+ throw new ArgumentError.value(0, "other", "must not be zero");
+ }
+ if (((xUsed == 1) && (xDigits[0] == 1)) ||
+ ((yUsed == 1) && (yDigits[0] == 1))) return one;
+ while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) {
+ _rsh(xDigits, xUsed, 1, xDigits);
+ _rsh(yDigits, yUsed, 1, yDigits);
+ shiftAmount++;
+ }
+ if (shiftAmount >= _digitBits) {
+ var digitShiftAmount = shiftAmount ~/ _digitBits;
+ xUsed -= digitShiftAmount;
+ yUsed -= digitShiftAmount;
+ maxUsed -= digitShiftAmount;
+ }
+ if ((yDigits[0] & 1) == 1) {
+ // Swap x and y.
+ var tmpDigits = xDigits;
+ var tmpUsed = xUsed;
+ xDigits = yDigits;
+ xUsed = yUsed;
+ yDigits = tmpDigits;
+ yUsed = tmpUsed;
+ }
+ }
+ var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed);
+ var vDigits =
+ _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh.
+ final bool ac = (xDigits[0] & 1) == 0;
+
+ // Variables a, b, c, and d require one more digit.
+ final abcdUsed = maxUsed + 1;
+ final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd.
+ var aDigits, bDigits, cDigits, dDigits;
+ bool aIsNegative, bIsNegative, cIsNegative, dIsNegative;
+ if (ac) {
+ aDigits = new Uint16List(abcdLen);
+ aIsNegative = false;
+ aDigits[0] = 1;
+ cDigits = new Uint16List(abcdLen);
+ cIsNegative = false;
+ }
+ bDigits = new Uint16List(abcdLen);
+ bIsNegative = false;
+ dDigits = new Uint16List(abcdLen);
+ dIsNegative = false;
+ dDigits[0] = 1;
+
+ while (true) {
+ while ((uDigits[0] & 1) == 0) {
+ _rsh(uDigits, maxUsed, 1, uDigits);
+ if (ac) {
+ if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) {
+ if (aIsNegative) {
+ if ((aDigits[maxUsed] != 0) ||
+ (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) {
+ _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ } else {
+ _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits);
+ aIsNegative = false;
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ }
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(aDigits, abcdUsed, 1, aDigits);
+ } else if ((bDigits[0] & 1) == 1) {
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(bDigits, abcdUsed, 1, bDigits);
+ }
+ while ((vDigits[0] & 1) == 0) {
+ _rsh(vDigits, maxUsed, 1, vDigits);
+ if (ac) {
+ if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) {
+ if (cIsNegative) {
+ if ((cDigits[maxUsed] != 0) ||
+ (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) {
+ _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ } else {
+ _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits);
+ cIsNegative = false;
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ }
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(cDigits, abcdUsed, 1, cDigits);
+ } else if ((dDigits[0] & 1) == 1) {
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(dDigits, abcdUsed, 1, dDigits);
+ }
+ if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) {
+ _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits);
+ if (ac) {
+ if (aIsNegative == cIsNegative) {
+ var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed);
+ if (a_cmp_c > 0) {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ } else {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits);
+ aIsNegative = !aIsNegative && (a_cmp_c != 0);
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ }
+ }
+ if (bIsNegative == dIsNegative) {
+ var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed);
+ if (b_cmp_d > 0) {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ } else {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits);
+ bIsNegative = !bIsNegative && (b_cmp_d != 0);
+ }
+ } else {
+ _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ }
+ } else {
+ _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits);
+ if (ac) {
+ if (cIsNegative == aIsNegative) {
+ var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed);
+ if (c_cmp_a > 0) {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ } else {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits);
+ cIsNegative = !cIsNegative && (c_cmp_a != 0);
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ }
+ }
+ if (dIsNegative == bIsNegative) {
+ var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed);
+ if (d_cmp_b > 0) {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ } else {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits);
+ dIsNegative = !dIsNegative && (d_cmp_b != 0);
+ }
+ } else {
+ _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ }
+ }
+ // Exit loop if u == 0.
+ var i = maxUsed;
+ while ((i > 0) && (uDigits[i - 1] == 0)) --i;
+ if (i == 0) break;
+ }
+ if (!inv) {
+ if (shiftAmount > 0) {
+ maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits);
+ }
+ return new _BigIntImpl._(false, maxUsed, vDigits);
+ }
+ // No inverse if v != 1.
+ var i = maxUsed - 1;
+ while ((i > 0) && (vDigits[i] == 0)) --i;
+ if ((i != 0) || (vDigits[0] != 1)) {
+ throw new Exception("Not coprime");
+ }
+
+ if (dIsNegative) {
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = false;
+ }
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = false;
+ }
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ }
+ }
+ return new _BigIntImpl._(false, maxUsed, dDigits);
+ }
+
+ /**
+ * Returns the modular multiplicative inverse of this big integer
+ * modulo [modulus].
+ *
+ * The [modulus] must be positive.
+ *
+ * It is an error if no modular inverse exists.
+ */
+ // Returns 1/this % modulus, with modulus > 0.
+ _BigIntImpl modInverse(BigInt bigInt) {
+ _BigIntImpl modulus = bigInt;
+ if (modulus <= zero) {
+ throw new ArgumentError("Modulus must be strictly positive: $modulus");
+ }
+ if (modulus == one) return zero;
+ var tmp = this;
+ if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) {
+ tmp %= modulus;
+ }
+ return _binaryGcd(modulus, tmp, true);
+ }
+
+ /**
+ * Returns the greatest common divisor of this big integer and [other].
+ *
+ * If either number is non-zero, the result is the numerically greatest
+ * integer dividing both `this` and `other`.
+ *
+ * The greatest common divisor is independent of the order,
+ * so `x.gcd(y)` is always the same as `y.gcd(x)`.
+ *
+ * For any integer `x`, `x.gcd(x)` is `x.abs()`.
+ *
+ * If both `this` and `other` is zero, the result is also zero.
+ */
+ _BigIntImpl gcd(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return other.abs();
+ if (other._isZero) return this.abs();
+ return _binaryGcd(this, other, false);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this big integer as a
+ * non-negative number (i.e. unsigned representation). The returned value has
+ * zeros in all bit positions higher than [width].
+ *
+ * ```
+ * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit quantity:
+ *
+ * ```
+ * q = (q + 1).toUnsigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `255` and then wrap around to `0`.
+ *
+ * If the input fits in [width] bits without truncation, the result is the
+ * same as the input. The minimum width needed to avoid truncation of `x` is
+ * given by `x.bitLength`, i.e.
+ *
+ * ```
+ * x == x.toUnsigned(x.bitLength);
+ * ```
+ */
+ _BigIntImpl toUnsigned(int width) {
+ return this & ((one << width) - one);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this integer, extending the
+ * highest retained bit to the sign. This is the same as truncating the value
+ * to fit in [width] bits using an signed 2-s complement representation. The
+ * returned value has the same bit value in all positions higher than [width].
+ *
+ * ```
+ * var big15 = new BigInt.from(15);
+ * var big16 = new BigInt.from(16);
+ * var big239 = new BigInt.from(239);
+ * V--sign bit-V
+ * big16.toSigned(5) == -big16 // 00010000 -> 11110000
+ * big239.toSigned(5) == big15 // 11101111 -> 00001111
+ * ^ ^
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit signed quantity:
+ *
+ * ```
+ * q = (q + 1).toSigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+ * `127`.
+ *
+ * If the input value fits in [width] bits without truncation, the result is
+ * the same as the input. The minimum width needed to avoid truncation of `x`
+ * is `x.bitLength + 1`, i.e.
+ *
+ * ```
+ * x == x.toSigned(x.bitLength + 1);
+ * ```
+ */
+ _BigIntImpl toSigned(int width) {
+ // The value of binary number weights each bit by a power of two. The
+ // twos-complement value weights the sign bit negatively. We compute the
+ // value of the negative weighting by isolating the sign bit with the
+ // correct power of two weighting and subtracting it from the value of the
+ // lower bits.
+ var signMask = one << (width - 1);
+ return (this & (signMask - one)) - (this & signMask);
+ }
+
+ // TODO(floitsch): implement `isValidInt`.
+ // Remove the comment in [BigInt.isValidInt] when done.
+ bool get isValidInt => true;
+
+ // TODO(floitsch): implement the clamping. It behaves differently on dart2js
+ // and the VM.
+ // Remove the comment in [BigInt.isValidInt] when done.
+ int toInt() {
+ var result = 0;
+ for (int i = _used - 1; i >= 0; i--) {
+ result = result * _digitBase + _digits[i];
+ }
+ return _isNegative ? -result : result;
+ }
+
+ /**
+ * Returns this [_BigIntImpl] as a [double].
+ *
+ * If the number is not representable as a [double], an
+ * approximation is returned. For numerically large integers, the
+ * approximation may be infinite.
+ */
+ double toDouble() {
+ const int exponentBias = 1075;
+ // There are 11 bits for the exponent.
+ // 2047 (all bits set to 1) is reserved for infinity and NaN.
+ // When storing the exponent in the 11 bits, it is biased by exponentBias
+ // to support negative exponents.
+ const int maxDoubleExponent = 2046 - exponentBias;
+ if (_isZero) return 0.0;
+
+ // We fill the 53 bits little-endian.
+ var resultBits = new Uint8List(8);
+
+ var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ if (length - 53 > maxDoubleExponent) return double.INFINITY;
+
+ // The most significant bit is for the sign.
+ if (_isNegative) resultBits[7] = 0x80;
+
+ // Write the exponent into bits 1..12:
+ var biasedExponent = length - 53 + exponentBias;
+ resultBits[6] = (biasedExponent & 0xF) << 4;
+ resultBits[7] |= biasedExponent >> 4;
+
+ int cachedBits = 0;
+ int cachedBitsLength = 0;
+ int digitIndex = _used - 1;
+ int readBits(int n) {
+ // Ensure that we have enough bits in [cachedBits].
+ while (cachedBitsLength < n) {
+ int nextDigit;
+ int nextDigitLength = _digitBits; // May get updated.
+ if (digitIndex < 0) {
+ nextDigit = 0;
+ digitIndex--;
+ } else {
+ nextDigit = _digits[digitIndex];
+ if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength;
+ digitIndex--;
+ }
+ cachedBits = (cachedBits << nextDigitLength) + nextDigit;
+ cachedBitsLength += nextDigitLength;
+ }
+ // Read the top [n] bits.
+ var result = cachedBits >> (cachedBitsLength - n);
+ // Remove the bits from the cache.
+ cachedBits -= result << (cachedBitsLength - n);
+ cachedBitsLength -= n;
+ return result;
+ }
+
+ // The first leading 1 bit is implicit in the double-representation and can
+ // be discarded.
+ var leadingBits = readBits(5) & 0xF;
+ resultBits[6] |= leadingBits;
+
+ for (int i = 5; i >= 0; i--) {
+ // Get the remaining 48 bits.
+ resultBits[i] = readBits(8);
+ }
+
+ void roundUp() {
+ // Simply consists of adding 1 to the whole 64 bit "number".
+ // It will update the exponent, if necessary.
+ // It might even round up to infinity (which is what we want).
+ var carry = 1;
+ for (int i = 0; i < 8; i++) {
+ if (carry == 0) break;
+ var sum = resultBits[i] + carry;
+ resultBits[i] = sum & 0xFF;
+ carry = sum >> 8;
+ }
+ }
+
+ if (readBits(1) == 1) {
+ if (resultBits[0].isOdd) {
+ // Rounds to even all the time.
+ roundUp();
+ } else {
+ // Round up, if there is at least one other digit that is not 0.
+ if (cachedBits != 0) {
+ // There is already one in the cachedBits.
+ roundUp();
+ } else {
+ for (int i = digitIndex; digitIndex >= 0; i--) {
+ if (_digits[i] != 0) {
+ roundUp();
+ break;
+ }
+ }
+ }
+ }
+ }
+ return resultBits.buffer.asByteData().getFloat64(0, Endian.little);
+ }
+
+ /**
+ * Returns a String-representation of this integer.
+ *
+ * The returned string is parsable by [parse].
+ * For any `_BigIntImpl` `i`, it is guaranteed that
+ * `i == _BigIntImpl.parse(i.toString())`.
+ */
+ String toString() {
+ if (_used == 0) return "0";
+ if (_used == 1) {
+ if (_isNegative) return (-_digits[0]).toString();
+ return _digits[0].toString();
+ }
+
+ // Generate in chunks of 4 digits.
+ // The chunks are in reversed order.
+ var decimalDigitChunks = <String>[];
+ var rest = isNegative ? -this : this;
+ while (rest._used > 1) {
+ var digits4 = rest.remainder(_bigInt10000).toString();
+ decimalDigitChunks.add(digits4);
+ if (digits4.length == 1) decimalDigitChunks.add("000");
+ if (digits4.length == 2) decimalDigitChunks.add("00");
+ if (digits4.length == 3) decimalDigitChunks.add("0");
+ rest = rest ~/ _bigInt10000;
+ }
+ decimalDigitChunks.add(rest._digits[0].toString());
+ if (_isNegative) decimalDigitChunks.add("-");
+ return decimalDigitChunks.reversed.join();
+ }
+
+ int _toRadixCodeUnit(int digit) {
+ const int _0 = 48;
+ const int _a = 97;
+ if (digit < 10) return _0 + digit;
+ return _a + digit - 10;
+ }
+
+ /**
+ * Converts [this] to a string representation in the given [radix].
+ *
+ * In the string representation, lower-case letters are used for digits above
+ * '9', with 'a' being 10 an 'z' being 35.
+ *
+ * The [radix] argument must be an integer in the range 2 to 36.
+ */
+ String toRadixString(int radix) {
+ if (radix > 36) throw new RangeError.range(radix, 2, 36);
+
+ if (_used == 0) return "0";
+
+ if (_used == 1) {
+ var digitString = _digits[0].toRadixString(radix);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ if (radix == 16) return _toHexString();
+
+ var base = new _BigIntImpl._fromInt(radix);
+ var reversedDigitCodeUnits = <int>[];
+ var rest = this.abs();
+ while (!rest._isZero) {
+ var digit = rest.remainder(base).toInt();
+ rest = rest ~/ base;
+ reversedDigitCodeUnits.add(_toRadixCodeUnit(digit));
+ }
+ var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ String _toHexString() {
+ var chars = <int>[];
+ for (int i = 0; i < _used - 1; i++) {
+ int chunk = _digits[i];
+ for (int j = 0; j < (_digitBits ~/ 4); j++) {
+ chars.add(_toRadixCodeUnit(chunk & 0xF));
+ chunk >>= 4;
+ }
+ }
+ var msbChunk = _digits[_used - 1];
+ while (msbChunk != 0) {
+ chars.add(_toRadixCodeUnit(msbChunk & 0xF));
+ msbChunk >>= 4;
+ }
+ if (_isNegative) {
+ const _dash = 45;
+ chars.add(_dash);
+ }
+ return new String.fromCharCodes(chars.reversed);
+ }
+}
+
+// Interface for modular reduction.
+abstract class _BigIntReduction {
+ // Return the number of digits used by r_digits.
+ int convert(_BigIntImpl x, Uint16List r_digits);
+ int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+ Uint16List resultDigits);
+ int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits);
+
+ // Return x reverted to _BigIntImpl.
+ _BigIntImpl revert(Uint16List xDigits, int xUsed);
+}
+
+// Modular reduction using "classic" algorithm.
+class _BigIntClassic implements _BigIntReduction {
+ final _BigIntImpl _modulus; // Modulus.
+ final _BigIntImpl _normalizedModulus; // Normalized _modulus.
+
+ _BigIntClassic(this._modulus)
+ : _normalizedModulus = _modulus <<
+ (_BigIntImpl._digitBits -
+ _modulus._digits[_modulus._used - 1].bitLength);
+
+ int convert(_BigIntImpl x, Uint16List resultDigits) {
+ var digits;
+ var used;
+ if (x._isNegative || x.compareTo(_modulus) >= 0) {
+ var remainder = x._rem(_modulus);
+ if (x._isNegative && !remainder._isNegative && remainder._used > 0) {
+ remainder = _modulus - remainder;
+ }
+ assert(!remainder._isNegative);
+ used = remainder._used;
+ digits = remainder._digits;
+ } else {
+ used = x._used;
+ digits = x._digits;
+ }
+ var i = used; // Copy leading zero if any.
+ while (--i >= 0) {
+ resultDigits[i] = digits[i];
+ }
+ return used;
+ }
+
+ _BigIntImpl revert(Uint16List xDigits, int xUsed) {
+ return new _BigIntImpl._(false, xUsed, xDigits);
+ }
+
+ int _reduce(Uint16List xDigits, int xUsed) {
+ if (xUsed < _modulus._used) {
+ return xUsed;
+ }
+ var reverted = revert(xDigits, xUsed);
+ var rem = reverted._rem(_normalizedModulus);
+ return convert(rem, xDigits);
+ }
+
+ int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) {
+ var b = new _BigIntImpl._(false, xUsed, xDigits);
+ var b2 = b * b;
+ for (int i = 0; i < b2._used; i++) {
+ resultDigits[i] = b2._digits[i];
+ }
+ for (int i = b2._used; i < 2 * xUsed; i++) {
+ resultDigits[i] = 0;
+ }
+ return _reduce(resultDigits, 2 * xUsed);
+ }
+
+ int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+ Uint16List resultDigits) {
+ var resultUsed =
+ _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
+ return _reduce(resultDigits, resultUsed);
+ }
+}
diff --git a/runtime/lib/core_patch.dart b/runtime/lib/core_patch.dart
index f1ad81e..c7af7be 100644
--- a/runtime/lib/core_patch.dart
+++ b/runtime/lib/core_patch.dart
@@ -45,12 +45,14 @@
import "dart:math" show Random;
-import "dart:typed_data" show Uint8List, Int64List, Uint16List, Uint32List;
+import "dart:typed_data"
+ show Endian, Uint8List, Int64List, Uint16List, Uint32List;
/// These are the additional parts of this patch library:
// part "array.dart";
// part "array_patch.dart";
// part "bigint.dart";
+// part "bigint_patch.dart";
// part "bool_patch.dart";
// part "date_patch.dart";
// part "double.dart";
diff --git a/runtime/lib/core_sources.gni b/runtime/lib/core_sources.gni
index 221dc03..dc4f7c8 100644
--- a/runtime/lib/core_sources.gni
+++ b/runtime/lib/core_sources.gni
@@ -11,6 +11,7 @@
"array.dart",
"array_patch.dart",
"bigint.dart",
+ "bigint_patch.dart",
"bool.cc",
"bool_patch.dart",
"date.cc",
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 5f3e449..3030af2 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -483,7 +483,6 @@
const TypeArguments& type_arguments =
TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
const intptr_t len = type_arguments.Length();
- ASSERT(len > 0);
const Array& type_list = Array::Handle(zone, Array::New(len));
TypeArguments& type_list_type_args =
TypeArguments::Handle(zone, TypeArguments::New(1));
diff --git a/runtime/lib/regexp_patch.dart b/runtime/lib/regexp_patch.dart
index 53af5be..b7e0f46 100644
--- a/runtime/lib/regexp_patch.dart
+++ b/runtime/lib/regexp_patch.dart
@@ -37,6 +37,58 @@
return value.regexp;
}
+ /**
+ * Finds the index of the first RegExp-significant char in [text].
+ *
+ * Starts looking from [start]. Returns `text.length` if no character
+ * is found that has special meaning in RegExp syntax.
+ */
+ static int _findEscapeChar(String text, int start) {
+ // Table where each character in the range U+0000 to U+007f is represented
+ // by whether it needs to be escaped in a regexp.
+ // The \x00 characters means escacped, and \x01 means non-escaped.
+ const escapes =
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ // $ ( ) * + .
+ "\x01\x01\x01\x01\x00\x01\x01\x01\x00\x00\x00\x00\x01\x01\x00\x01"
+ // ?
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00"
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ // [ \ ] ^
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x00\x01"
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01"
+ // { | }
+ "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x00\x00\x00\x01\x01";
+ for (int i = start; i < text.length; i++) {
+ int char = text.codeUnitAt(i);
+ if (char <= 0x7f && escapes.codeUnitAt(char) == 0) return i;
+ }
+ return text.length;
+ }
+
+ @patch
+ static String escape(String text) {
+ int escapeCharIndex = _findEscapeChar(text, 0);
+ // If the text contains no characters needing escape, return it directly.
+ if (escapeCharIndex == text.length) return text;
+
+ var buffer = new StringBuffer();
+ int previousSliceEndIndex = 0;
+ do {
+ // Copy characters from previous escape to current escape into result.
+ // This includes the previously escaped character.
+ buffer.write(text.substring(previousSliceEndIndex, escapeCharIndex));
+ // Prepare the current character to be escaped by prefixing it with a '\'.
+ buffer.write(r"\");
+ previousSliceEndIndex = escapeCharIndex;
+ escapeCharIndex = _findEscapeChar(text, escapeCharIndex + 1);
+ } while (escapeCharIndex < text.length);
+ // Copy tail of string into result.
+ buffer.write(text.substring(previousSliceEndIndex, escapeCharIndex));
+ return buffer.toString();
+ }
+
// Regular expression objects are stored in a cache of up to _MAX_CACHE_SIZE
// elements using an LRU eviction strategy.
// TODO(zerny): Do not impose a fixed limit on the number of cached objects.
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index e00fe7a..9abd844 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -79,7 +79,6 @@
bad_reload_test: RuntimeError # Please triage.
coverage_leaf_function_test: RuntimeError # Please triage.
coverage_optimized_function_test: RuntimeError # Please triage.
-dev_fs_spawn_test: RuntimeError # Please triage.
get_object_rpc_test: RuntimeError # Please triage.
get_source_report_test: RuntimeError # Please triage.
library_dependency_test: RuntimeError # Please triage.
diff --git a/runtime/tests/vm/dart/callee_side_type_checks_test.dart b/runtime/tests/vm/dart/callee_side_type_checks_test.dart
new file mode 100644
index 0000000..5a8dfaf
--- /dev/null
+++ b/runtime/tests/vm/dart/callee_side_type_checks_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--reify-generic-functions
+
+import "package:expect/expect.dart";
+
+// This test tests that AOT compiler does not optimize away necessary
+// type checks.
+
+class A {
+ int _addOneToArgument(int x) => x + 1;
+}
+
+abstract class G<T> {
+ int _addOneToArgument(T x);
+}
+
+class B extends A implements G<int> {}
+
+class C {
+ int _addTwoToArgument(int x) => x + 2;
+}
+
+class D {
+ int _addThreeToArgument(num x) {
+ return 0;
+ }
+}
+
+class E extends D {
+ int _addThreeToArgument(covariant int x) {
+ return x + 3;
+ }
+}
+
+typedef dynamic F0<T>(T val);
+typedef U F1<T, U>(T val);
+
+class F<T> {
+ T fMethod1(F0<T> f, T val) => f(val) as T;
+ U fMethod2<U>(F1<T, U> f, T val) => f(val);
+}
+
+final arr = <Object>[
+ new B(),
+ new C(),
+ new E(),
+ new D(), // Just to confuse CHA
+ new F<int>(),
+];
+
+int _add42Int(int v) => v + 42;
+double _add42Double(double v) => v + 42;
+double _add42_0Int(int v) => v + 42.0;
+
+main() {
+ final b = arr[0] as G<num>;
+
+ Expect.equals(1, b._addOneToArgument(0));
+ Expect.equals(0, b._addOneToArgument(-1));
+ Expect.throwsTypeError(() => b._addOneToArgument(1.1));
+
+ final c = (arr[1] as C);
+ final tornMethod = c._addTwoToArgument;
+ Expect.equals(2, c._addTwoToArgument(0));
+ Expect.equals(0, c._addTwoToArgument(-2));
+ Expect.throwsTypeError(() => (tornMethod as dynamic)(1.1));
+
+ final e = (arr[2] as D);
+ Expect.equals(3, e._addThreeToArgument(0));
+ Expect.equals(0, e._addThreeToArgument(-3));
+ Expect.throwsTypeError(() => e._addThreeToArgument(1.1));
+
+ final f = (arr[4] as F<num>);
+ final torn1 = f.fMethod1 as dynamic;
+ Expect.equals(43, torn1(_add42Int, 1));
+ Expect.throwsTypeError(() => torn1(_add42Double, 1));
+ Expect.throwsTypeError(() => torn1(_add42Int, 1.1));
+
+ final torn2 = f.fMethod2 as dynamic;
+ Expect.equals(43, torn2<int>(_add42Int, 1));
+ Expect.equals(43.0, torn2<double>(_add42_0Int, 1));
+ Expect.throwsTypeError(() => torn2<double>(_add42Int, 1));
+ Expect.throwsTypeError(() => torn2<int>(_add42_0Int, 1));
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index afd3dd3..dcb48d1 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -46,8 +46,11 @@
dart/snapshot_version_test: Fail, OK # Expects to find script snapshot relative to Dart source.
[ $compiler == dart2analyzer ]
+dart/byte_array_optimized_test: CompileTimeError # int64
+dart/byte_array_test: CompileTimeError # int64
dart/optimized_stacktrace_line_and_column_test: StaticWarning
dart/optimized_stacktrace_line_test: StaticWarning
+dart/truncating_ints_test: CompileTimeError # int64
[ $compiler == dart2js ]
dart/byte_array_optimized_test: Skip # compilers not aware of byte arrays
@@ -102,6 +105,9 @@
cc/CorelibCompilerStats: Skip
cc/Service_Profile: Skip
+[ !$strong ]
+dart/callee_side_type_checks_test: SkipByDesign
+
# Following tests are failing in a weird way on macos/ia32/debug builds
# need to investigate.
[ $arch == ia32 && $mode == debug && $runtime == vm && $system == macos ]
diff --git a/runtime/tools/concatenate_patches.py b/runtime/tools/concatenate_patches.py
deleted file mode 100755
index 8b2df2a5..0000000
--- a/runtime/tools/concatenate_patches.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-from optparse import OptionParser
-
-def writePatch(output_file_name, input_file_names):
- dart_file_names = filter(lambda name: name.endswith('.dart'),
- input_file_names)
- with open(output_file_name, 'w') as output_file:
- is_first = True
- for dart_file_name in dart_file_names:
- with open(dart_file_name, 'r') as dart_file:
- if is_first:
- output_file.write(dart_file.read())
- is_first = False
- else:
- for line in dart_file.readlines():
- if not line.startswith("import "):
- output_file.write(line)
-
-
-def main():
- parser = OptionParser()
- parser.add_option('--output', action='store', type='string',
- help='output file path')
- (options, args) = parser.parse_args()
- if not options.output:
- parser.error('missing --output option\n')
- if len(args) == 0:
- parser.error('no input files given\n')
- writePatch(options.output, args)
-
-
-if __name__ == '__main__':
- main()
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index bc194bc..dc0a5b0 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -17,7 +17,6 @@
import("../../sdk/lib/typed_data/typed_data_sources.gni")
import("../../sdk/lib/vmservice/vmservice_sources.gni")
import("../../utils/compile_platform.gni")
-import("../../utils/generate_patch_sdk.gni")
import("../bin/io_sources.gni")
import("../bin/cli_sources.gni")
import("../lib/async_sources.gni")
@@ -38,10 +37,7 @@
config("libdart_vm_config") {
if (is_fuchsia) {
- libs = [
- "zircon",
- "trace-engine",
- ]
+ libs = [ "zircon" ]
} else if (is_win) {
libs = [
"advapi32.lib",
@@ -80,7 +76,8 @@
# TODO(zra): When the platform-specific timeline code is moved out to
# the embedder, this can go away.
- "//zircon/system/ulib/fbl",
+ "//zircon/public/lib/fbl",
+ "//zircon/public/lib/trace-engine",
]
}
public_configs = [ ":libdart_vm_config" ]
@@ -455,133 +452,6 @@
typed_data_runtime_sources + vmservice_runtime_sources
}
-template("concatenate_patch") {
- assert(defined(invoker.libsources), "Need a sources in $target_name")
- assert(defined(invoker.output), "Need an output in $target_name")
-
- process_library_source(target_name) {
- libsources = invoker.libsources
- inputs = []
- output = invoker.output
- script = "../tools/concatenate_patches.py"
- args = [
- "--output",
- rebase_path(output, root_build_dir),
- ]
- }
-}
-
-template("generate_vm_patched_sdk") {
- assert(defined(invoker.libraries), "Need libraries in $target_name")
-
- concatenation_target_names = []
-
- # Concatenate vm library patches.
- foreach(library, invoker.libraries) {
- name = library[0]
-
- target_output = "$target_gen_dir/patches/${name}_patch.dart"
- concatenate_patch("concatenate_${name}_patch") {
- libsources = rebase_path(library[1], ".", library[2])
- output = target_output
- }
- concatenation_target_names += [ ":concatenate_${name}_patch" ]
- }
-
- patched_sdk_dir = "patched_sdk"
-
- other_outputs = [
- # Instead of listing all outputs we list those consumed by
- # other BUILD rules.
- "$root_out_dir/$patched_sdk_dir/lib/libraries.json",
- ]
-
- # Build the patched sdk out of the concatenated patches and the special
- # libraries.
- generate_patched_sdk(target_name) {
- mode = "vm"
- deps = concatenation_target_names
- input_patches_dir = "$target_gen_dir/patches"
- patched_sdk_dir = patched_sdk_dir
- outputs = other_outputs
- }
-}
-
-generate_vm_patched_sdk("patched_sdk") {
- libraries = [
- [
- "async",
- async_runtime_sources,
- "../lib",
- ],
- [
- "collection",
- collection_runtime_sources,
- "../lib",
- ],
- [
- "convert",
- convert_runtime_sources,
- "../lib",
- ],
- [
- "core",
- core_runtime_sources,
- "../lib",
- ],
- [
- "developer",
- developer_runtime_sources,
- "../lib",
- ],
- [
- "internal",
- internal_runtime_sources,
- "../lib",
- ],
- [
- "isolate",
- isolate_runtime_sources,
- "../lib",
- ],
- [
- "math",
- math_runtime_sources,
- "../lib",
- ],
- [
- "mirrors",
- mirrors_runtime_sources,
- "../lib",
- ],
- [
- "profiler",
- profiler_runtime_sources,
- "../lib",
- ],
- [
- "typed_data",
- typed_data_runtime_sources,
- "../lib",
- ],
- [
- "vmservice",
- vmservice_runtime_sources,
- "../lib",
- ],
- [
- "io",
- io_runtime_sources,
- "../bin",
- ],
- [
- "cli",
- cli_runtime_sources,
- "../bin",
- ],
- ]
-}
-
compile_platform("vm_legacy_platform") {
sources = [
"../../sdk/lib/libraries.json",
@@ -601,7 +471,7 @@
compile_platform("vm_platform") {
sources = [
- "$root_out_dir/patched_sdk/lib/libraries.json",
+ "../../sdk/lib/libraries.json",
]
outputs = [
@@ -609,10 +479,6 @@
"$root_out_dir/vm_outline_strong.dill",
]
- deps = [
- ":patched_sdk",
- ]
-
args = [
"--strong-mode",
"dart:core",
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index ef3c299..4708321 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -5555,14 +5555,19 @@
codes_(new (zone) ZoneGrowableArray<Code*>(4 * KB)),
script_(Script::Handle(zone)),
code_(Code::Handle(zone)),
- stack_maps_(Array::Handle(zone)) {}
+ stack_maps_(Array::Handle(zone)),
+ library_(Library::Handle(zone)),
+ kernel_program_info_(KernelProgramInfo::Handle(zone)) {}
void Visit(const Class& cls) {
script_ = cls.script();
if (!script_.IsNull()) {
- objects_->Add(&Object::Handle(zone_, script_.tokens()));
+ Visit(script_);
}
+ library_ = cls.library();
+ objects_->Add(&Object::Handle(zone_, library_.kernel_data()));
+
if (!include_code_) return;
code_ = cls.allocation_stub();
@@ -5572,7 +5577,7 @@
void Visit(const Function& function) {
script_ = function.script();
if (!script_.IsNull()) {
- objects_->Add(&Object::Handle(zone_, script_.tokens()));
+ Visit(script_);
}
if (!include_code_) return;
@@ -5583,6 +5588,23 @@
Visit(code_);
}
+ void Visit(const Script& script) {
+ objects_->Add(&Object::Handle(zone_, script_.tokens()));
+ kernel_program_info_ = script_.kernel_program_info();
+ if (!kernel_program_info_.IsNull()) {
+ objects_->Add(
+ &Object::Handle(zone_, kernel_program_info_.string_offsets()));
+ objects_->Add(&Object::Handle(zone_, kernel_program_info_.string_data()));
+ objects_->Add(
+ &Object::Handle(zone_, kernel_program_info_.canonical_names()));
+ objects_->Add(
+ &Object::Handle(zone_, kernel_program_info_.metadata_payloads()));
+ objects_->Add(
+ &Object::Handle(zone_, kernel_program_info_.metadata_mappings()));
+ objects_->Add(&Object::Handle(zone_, kernel_program_info_.constants()));
+ }
+ }
+
ZoneGrowableArray<Object*>* objects() { return objects_; }
ZoneGrowableArray<Code*>* codes() { return codes_; }
@@ -5610,6 +5632,8 @@
Script& script_;
Code& code_;
Array& stack_maps_;
+ Library& library_;
+ KernelProgramInfo& kernel_program_info_;
};
FullSnapshotWriter::FullSnapshotWriter(Snapshot::Kind kind,
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index a211946..04b3fd6 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -788,9 +788,9 @@
lib = Library::LookupLibrary(T, library_uri);
}
if (lib.IsNull()) {
- String& msg =
- String::Handle(Z, String::NewFormatted("Cannot find entry point %s\n",
- entry_points[i].library_uri));
+ String& msg = String::Handle(
+ Z, String::NewFormatted("Cannot find entry point '%s'\n",
+ entry_points[i].library_uri));
Jump(Error::Handle(Z, ApiError::New(msg)));
UNREACHABLE();
}
@@ -808,7 +808,7 @@
cls = lib.LookupLocalClass(class_name);
if (cls.IsNull()) {
String& msg = String::Handle(
- Z, String::NewFormatted("Cannot find entry point %s %s\n",
+ Z, String::NewFormatted("Cannot find entry point '%s' '%s'\n",
entry_points[i].library_uri,
entry_points[i].class_name));
Jump(Error::Handle(Z, ApiError::New(msg)));
@@ -822,7 +822,7 @@
if (func.IsNull() && field.IsNull()) {
String& msg = String::Handle(
- Z, String::NewFormatted("Cannot find entry point %s %s %s\n",
+ Z, String::NewFormatted("Cannot find entry point '%s' '%s' '%s'\n",
entry_points[i].library_uri,
entry_points[i].class_name,
entry_points[i].function_name));
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 2e1d07b..2c204ee 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -1777,11 +1777,13 @@
Register rt,
int64_t imm,
OperandSize sz) {
+ // EncodeImm19BranchOffset will longjump out if the offset does not fit in
+ // 19 bits.
+ const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0);
ASSERT((sz == kDoubleWord) || (sz == kWord) || (sz == kUnsignedWord));
ASSERT(Utils::IsInt(21, imm) && ((imm & 0x3) == 0));
ASSERT((rt != CSP) && (rt != R31));
const int32_t size = (sz == kDoubleWord) ? B31 : 0;
- const int32_t encoded_offset = EncodeImm19BranchOffset(imm, 0);
const int32_t encoding = op | size | Arm64Encode::Rt(rt) | encoded_offset;
Emit(encoding);
}
@@ -1790,11 +1792,13 @@
Register rt,
intptr_t bit_number,
int64_t imm) {
+ // EncodeImm14BranchOffset will longjump out if the offset does not fit in
+ // 14 bits.
+ const int32_t encoded_offset = EncodeImm14BranchOffset(imm, 0);
ASSERT((bit_number >= 0) && (bit_number <= 63));
ASSERT(Utils::IsInt(16, imm) && ((imm & 0x3) == 0));
ASSERT((rt != CSP) && (rt != R31));
const Register crt = ConcreteRegister(rt);
- const int32_t encoded_offset = EncodeImm14BranchOffset(imm, 0);
const int32_t encoding = op | (static_cast<int32_t>(bit_number) << 19) |
(static_cast<int32_t>(crt) << kRtShift) |
encoded_offset;
@@ -1833,6 +1837,9 @@
} else {
EmitConditionalBranchOp(op, InvertCondition(cond),
2 * Instr::kInstrSize);
+ // Make a new dest that takes the new position into account after the
+ // inverted test.
+ const int64_t dest = label->Position() - buffer_.Size();
b(dest);
}
} else {
@@ -1863,6 +1870,9 @@
if (use_far_branches() && !CanEncodeImm19BranchOffset(dest)) {
EmitCompareAndBranchOp(op == CBZ ? CBNZ : CBZ, rt,
2 * Instr::kInstrSize, sz);
+ // Make a new dest that takes the new position into account after the
+ // inverted test.
+ const int64_t dest = label->Position() - buffer_.Size();
b(dest);
} else {
EmitCompareAndBranchOp(op, rt, dest, sz);
@@ -1889,12 +1899,15 @@
if (use_far_branches() && !CanEncodeImm14BranchOffset(dest)) {
EmitTestAndBranchOp(op == TBZ ? TBNZ : TBZ, rt, bit_number,
2 * Instr::kInstrSize);
+ // Make a new dest that takes the new position into account after the
+ // inverted test.
+ const int64_t dest = label->Position() - buffer_.Size();
b(dest);
} else {
EmitTestAndBranchOp(op, rt, bit_number, dest);
}
} else {
- const int64_t position = buffer_.Size();
+ int64_t position = buffer_.Size();
if (use_far_branches()) {
EmitTestAndBranchOp(op == TBZ ? TBNZ : TBZ, rt, bit_number,
2 * Instr::kInstrSize);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64_test.cc b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
index e1129ea..8bf00c9 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64_test.cc
@@ -1076,6 +1076,52 @@
EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
}
+ASSEMBLER_TEST_GENERATE(TstBranchIfZeroFar, assembler) {
+ Label l;
+
+ __ movz(R0, Immediate(42), 0);
+ __ movz(R1, Immediate((0 << 5) | 1), 0);
+
+ __ tbz(&l, R1, 5);
+
+ const intptr_t kRange = 1 << 14; // tbz has 14 bits of range.
+ for (intptr_t i = 0; i < kRange; i++) {
+ __ brk(0);
+ }
+
+ __ movz(R0, Immediate(0), 0);
+ __ Bind(&l);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TstBranchIfZeroFar, test) {
+ typedef int64_t (*Int64Return)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(TstBranchIfNotZeroFar, assembler) {
+ Label l;
+
+ __ movz(R0, Immediate(42), 0);
+ __ movz(R1, Immediate((1 << 5) | 1), 0);
+
+ __ tbnz(&l, R1, 5);
+
+ const intptr_t kRange = 1 << 14; // tbnz has 14 bits of range.
+ for (intptr_t i = 0; i < kRange; i++) {
+ __ brk(0);
+ }
+
+ __ movz(R0, Immediate(0), 0);
+ __ Bind(&l);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TstBranchIfNotZeroFar, test) {
+ typedef int64_t (*Int64Return)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
ASSEMBLER_TEST_GENERATE(FcmpEqBranch, assembler) {
Label l;
@@ -1095,6 +1141,80 @@
EXPECT_EQ(42.0, EXECUTE_TEST_CODE_DOUBLE(DoubleReturn, test->entry()));
}
+ASSEMBLER_TEST_GENERATE(TstBranchIfZeroFar1, assembler) {
+ Label l;
+
+ __ LoadImmediate(R0, 41);
+ __ tbnz(&l, R0, 5);
+ __ Stop("Hammertime");
+
+ for (int i = 0; i < 0x10000; i++) {
+ __ add(R0, R0, Operand(1));
+ __ sub(R0, R0, Operand(1));
+ }
+
+ __ AddImmediate(R0, R0, -1); // Not run.
+
+ __ Bind(&l);
+ __ AddImmediate(R0, R0, 1);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TstBranchIfZeroFar1, test) {
+ typedef int64_t (*Int64Return)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(TstBranchIfZeroFar2, assembler) {
+ Label l;
+
+ for (int i = 0; i < 0x10000; i++) {
+ __ add(R0, R0, Operand(1));
+ __ sub(R0, R0, Operand(1));
+ }
+
+ __ LoadImmediate(R0, 41);
+ __ tbnz(&l, R0, 5);
+ __ Stop("Hammertime");
+
+ __ AddImmediate(R0, R0, -1); // Not run.
+
+ __ Bind(&l);
+ __ AddImmediate(R0, R0, 1);
+ __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TstBranchIfZeroFar2, test) {
+ typedef int64_t (*Int64Return)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
+ASSEMBLER_TEST_GENERATE(TstBranchIfZeroFar3, assembler) {
+ Label l, l2;
+ __ LoadImmediate(R0, 41);
+ __ b(&l, AL);
+
+ __ AddImmediate(R0, R0, -1); // Not run.
+
+ __ Bind(&l2);
+ __ AddImmediate(R0, R0, 1);
+ __ ret();
+
+ for (int i = 0; i < 0x10000; i++) {
+ __ add(R0, R0, Operand(1));
+ __ sub(R0, R0, Operand(1));
+ }
+
+ __ Bind(&l);
+ __ tbnz(&l2, R0, 5);
+ __ Stop("Hammertime");
+}
+
+ASSEMBLER_TEST_RUN(TstBranchIfZeroFar3, test) {
+ typedef int64_t (*Int64Return)() DART_UNUSED;
+ EXPECT_EQ(42, EXECUTE_TEST_CODE_INT64(Int64Return, test->entry()));
+}
+
ASSEMBLER_TEST_GENERATE(FcmpEqBranchNotTaken, assembler) {
Label l;
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 2520f4b..d69740c 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -942,8 +942,18 @@
return CompileType(CompileType::kNonNullable, cid, &type);
}
- // TODO(dartbug.com/30480): Figure out how to use parameter types
- // without interfering with argument type checks.
+ if (Isolate::Current()->strong() && FLAG_use_strong_mode_types) {
+ LocalScope* scope = graph_entry->parsed_function().node_sequence()->scope();
+ // Note: in catch-blocks we have ParameterInstr for each local variable
+ // not only for normal parameters.
+ if (index() < scope->num_variables()) {
+ LocalVariable* param = scope->VariableAt(index());
+ if (param->was_type_checked_by_caller()) {
+ return CompileType::FromAbstractType(param->type(),
+ CompileType::kNullable);
+ }
+ }
+ }
return CompileType::Dynamic();
}
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index da16741..30e0407 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -887,7 +887,7 @@
LoadFieldInstr* load = new (Z) LoadFieldInstr(
new (Z) Value(call->ArgumentAt(0)), &field,
AbstractType::ZoneHandle(Z, field.type()), call->token_pos(),
- FLAG_use_field_guards ? &flow_graph()->parsed_function() : NULL);
+ isolate()->use_field_guards() ? &flow_graph()->parsed_function() : NULL);
load->set_is_immutable(field.is_final());
// Discard the environment from the original instruction because the load
@@ -945,7 +945,7 @@
AddReceiverCheck(instr);
}
- if (FLAG_use_field_guards) {
+ if (I->use_field_guards()) {
if (field.guarded_cid() != kDynamicCid) {
ASSERT(I->use_field_guards());
InsertBefore(instr,
@@ -972,8 +972,8 @@
new (Z) Value(instr->ArgumentAt(1)),
kEmitStoreBarrier, instr->token_pos());
- ASSERT(FLAG_use_field_guards || !store->IsUnboxedStore());
- if (FLAG_use_field_guards && store->IsUnboxedStore()) {
+ ASSERT(I->use_field_guards() || !store->IsUnboxedStore());
+ if (I->use_field_guards() && store->IsUnboxedStore()) {
flow_graph()->parsed_function().AddToGuardedFields(&field);
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 52d5650..d76581c 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -566,9 +566,8 @@
}
#endif // DEBUG
- last_node_offset_ = builder_->data_program_offset_ +
- builder_->parsed_function()->function().kernel_offset();
- last_mapping_index_ = FindMetadataMapping(last_node_offset_);
+ last_node_offset_ = kIntptrMax;
+ last_mapping_index_ = 0;
}
intptr_t MetadataHelper::FindMetadataMapping(intptr_t node_offset) {
@@ -732,6 +731,25 @@
return DirectCallMetadata(target, check_receiver_for_null);
}
+bool ProcedureAttributesMetadataHelper::ReadMetadata(intptr_t node_offset,
+ bool* has_dynamic_calls) {
+ intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
+ if (md_offset < 0) {
+ *has_dynamic_calls = true;
+ return false;
+ }
+ *has_dynamic_calls = false;
+ return true;
+}
+
+ProcedureAttributesMetadata
+ProcedureAttributesMetadataHelper::GetProcedureAttributes(
+ intptr_t node_offset) {
+ bool has_dynamic_calls = true;
+ ReadMetadata(node_offset, &has_dynamic_calls);
+ return ProcedureAttributesMetadata(has_dynamic_calls);
+}
+
InferredTypeMetadata InferredTypeMetadataHelper::GetInferredType(
intptr_t node_offset) {
const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
@@ -803,7 +821,21 @@
ActiveTypeParametersScope active_type_params(&active_class_, function, Z);
LocalScope* enclosing_scope = NULL;
- if (function.IsLocalFunction()) {
+ if (function.IsImplicitClosureFunction() && !function.is_static()) {
+ // Create artificial enclosing scope for the tear-off that contains
+ // captured receiver value. This ensure that AssertAssignable will correctly
+ // load instantiator type arguments if they are needed.
+ Class& klass = Class::Handle(Z, function.Owner());
+ Type& klass_type = H.GetCanonicalType(klass);
+ result_->this_variable =
+ MakeVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+ Symbols::This(), klass_type);
+ result_->this_variable->set_index(0);
+ result_->this_variable->set_is_captured();
+ enclosing_scope = new (Z) LocalScope(NULL, 0, 0);
+ enclosing_scope->set_context_level(0);
+ enclosing_scope->AddVariable(result_->this_variable);
+ } else if (function.IsLocalFunction()) {
enclosing_scope = LocalScope::RestoreOuterScope(
ContextScope::Handle(Z, function.context_scope()));
}
@@ -835,6 +867,9 @@
builder_->SetOffset(function.kernel_offset());
FunctionNodeHelper function_node_helper(builder_);
+ const ProcedureAttributesMetadata attrs =
+ builder_->procedure_attributes_metadata_helper_.GetProcedureAttributes(
+ function.kernel_offset());
switch (function.kind()) {
case RawFunction::kClosureFunction:
@@ -904,9 +939,34 @@
result_->type_arguments_variable = variable;
}
+ ParameterTypeCheckMode type_check_mode = kTypeCheckAllParameters;
+ if (!function.IsImplicitClosureFunction()) {
+ if (function.is_static()) {
+ // In static functions we don't check anything.
+ type_check_mode = kTypeCheckForStaticFunction;
+ } else if (!attrs.has_dynamic_invocations) {
+ // If the current function is never a target of a dynamic invocation
+ // and this parameter is not marked with generic-covariant-impl
+ // (which means that among all super-interfaces no type parameters
+ // ever occur at the position of this parameter) then we don't need
+ // to check this parameter on the callee side, because strong mode
+ // guarantees that it was checked at the caller side.
+ type_check_mode = kTypeCheckForNonDynamicallyInvokedMethod;
+ }
+ } else {
+ if (!attrs.has_dynamic_invocations) {
+ // This is a tear-off of an instance method that can not be reached
+ // from any dynamic invocation. The method would not check any
+ // parameters except covariant ones and those annotated with
+ // generic-covariant-impl. Which means that we have to check
+ // the rest in the tear-off itself..
+ type_check_mode = kTypeCheckForTearOffOfNonDynamicallyInvokedMethod;
+ }
+ }
+
// Continue reading FunctionNode:
// read positional_parameters and named_parameters.
- AddPositionalAndNamedParameters(pos);
+ AddPositionalAndNamedParameters(pos, type_check_mode);
// We generate a synthetic body for implicit closure functions - which
// will forward the call to the real function.
@@ -1945,7 +2005,7 @@
// read positional_parameters and named_parameters.
function_node_helper.ReadUntilExcluding(
FunctionNodeHelper::kPositionalParameters);
- AddPositionalAndNamedParameters();
+ AddPositionalAndNamedParameters(0, kTypeCheckAllParameters);
// "Peek" is now done.
builder_->SetOffset(offset);
@@ -1971,21 +2031,25 @@
scope_ = scope_->parent();
}
-void StreamingScopeBuilder::AddPositionalAndNamedParameters(intptr_t pos) {
+void StreamingScopeBuilder::AddPositionalAndNamedParameters(
+ intptr_t pos,
+ ParameterTypeCheckMode type_check_mode /* = kTypeCheckAllParameters*/) {
// List of positional.
intptr_t list_length = builder_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
- AddVariableDeclarationParameter(pos++); // read ith positional parameter.
+ AddVariableDeclarationParameter(pos++, type_check_mode);
}
// List of named.
list_length = builder_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
- AddVariableDeclarationParameter(pos++); // read ith named parameter.
+ AddVariableDeclarationParameter(pos++, type_check_mode);
}
}
-void StreamingScopeBuilder::AddVariableDeclarationParameter(intptr_t pos) {
+void StreamingScopeBuilder::AddVariableDeclarationParameter(
+ intptr_t pos,
+ ParameterTypeCheckMode type_check_mode) {
intptr_t kernel_offset = builder_->ReaderOffset(); // no tag.
VariableDeclarationHelper helper(builder_);
helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
@@ -2002,6 +2066,35 @@
if (variable->name().raw() == Symbols::IteratorParameter().raw()) {
variable->set_is_forced_stack();
}
+
+ const bool is_covariant =
+ helper.IsGenericCovariantImpl() || helper.IsCovariant();
+ switch (type_check_mode) {
+ case kTypeCheckAllParameters:
+ variable->set_type_check_mode(LocalVariable::kDoTypeCheck);
+ break;
+ case kTypeCheckForTearOffOfNonDynamicallyInvokedMethod:
+ if (is_covariant) {
+ // Don't type check covariant parameters - they will be checked by
+ // a function we forward to. Their types however are not known.
+ variable->set_type_check_mode(LocalVariable::kSkipTypeCheck);
+ } else {
+ variable->set_type_check_mode(LocalVariable::kDoTypeCheck);
+ }
+ break;
+ case kTypeCheckForNonDynamicallyInvokedMethod:
+ if (is_covariant) {
+ variable->set_type_check_mode(LocalVariable::kDoTypeCheck);
+ } else {
+ // Types of non-covariant parameters are guaranteed to match by
+ // front-end enforcing strong mode types at call site.
+ variable->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
+ }
+ break;
+ case kTypeCheckForStaticFunction:
+ variable->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
+ break;
+ }
scope_->InsertParameterAt(pos, variable);
result_->locals.Insert(builder_->data_program_offset_ + kernel_offset,
variable);
@@ -3980,11 +4073,25 @@
FunctionNodeHelper function_node_helper(this);
function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
- // Tearoffs of static methods needs to perform arguments checks since static
- // methods they forward to don't do it themselves.
- if (I->argument_type_checks() && !target.NeedsArgumentTypeChecks(I)) {
- AlternativeReadingScope _(reader_);
- body += BuildArgumentTypeChecks();
+ if (I->argument_type_checks()) {
+ if (!target.NeedsArgumentTypeChecks(I)) {
+ // Tearoffs of static methods needs to perform arguments checks since
+ // static methods they forward to don't do it themselves.
+ AlternativeReadingScope _(reader_);
+ body += BuildArgumentTypeChecks();
+ } else {
+ // Check if target function was annotated with no-dynamic-invocations.
+ const ProcedureAttributesMetadata attrs =
+ procedure_attributes_metadata_helper_.GetProcedureAttributes(
+ target.kernel_offset());
+ if (!attrs.has_dynamic_invocations) {
+ // If it was then we might need to build some checks in the
+ // tear-off.
+ AlternativeReadingScope _(reader_);
+ body +=
+ BuildArgumentTypeChecks(kTypeChecksForNoDynamicInvocationsTearOff);
+ }
+ }
}
function_node_helper.ReadUntilExcluding(
@@ -4041,7 +4148,8 @@
flow_graph_builder_->last_used_block_id_, prologue_info);
}
-Fragment StreamingFlowGraphBuilder::BuildArgumentTypeChecks() {
+Fragment StreamingFlowGraphBuilder::BuildArgumentTypeChecks(
+ TypeChecksToBuild mode /*= kDefaultTypeChecks*/) {
FunctionNodeHelper function_node_helper(this);
function_node_helper.SetNext(FunctionNodeHelper::kTypeParameters);
const Function& dart_function = parsed_function()->function();
@@ -4060,53 +4168,60 @@
}
// Type parameters
- intptr_t list_length = ReadListLength();
- TypeArguments& forwarding_params = TypeArguments::Handle(Z);
- if (forwarding_target != NULL) {
- forwarding_params = forwarding_target->type_parameters();
- ASSERT(forwarding_params.Length() == list_length);
- }
- TypeParameter& forwarding_param = TypeParameter::Handle(Z);
- for (intptr_t i = 0; i < list_length; ++i) {
- ReadFlags(); // skip flags
- SkipListOfExpressions(); // skip annotations
- String& name = H.DartSymbol(ReadStringReference()); // read name
- AbstractType& bound = T.BuildType(); // read bound
-
+ if (mode == kDefaultTypeChecks) {
+ intptr_t num_type_params = ReadListLength();
+ TypeArguments& forwarding_params = TypeArguments::Handle(Z);
if (forwarding_target != NULL) {
- forwarding_param ^= forwarding_params.TypeAt(i);
- bound = forwarding_param.bound();
+ forwarding_params = forwarding_target->type_parameters();
+ ASSERT(forwarding_params.Length() == num_type_params);
}
+ TypeParameter& forwarding_param = TypeParameter::Handle(Z);
+ for (intptr_t i = 0; i < num_type_params; ++i) {
+ ReadFlags(); // skip flags
+ SkipListOfExpressions(); // skip annotations
+ String& name = H.DartSymbol(ReadStringReference()); // read name
+ AbstractType& bound = T.BuildType(); // read bound
- if (I->strong() && !bound.IsObjectType() &&
- (I->reify_generic_functions() || dart_function.IsFactory())) {
- ASSERT(!bound.IsDynamicType());
- TypeParameter& param = TypeParameter::Handle(Z);
- if (dart_function.IsFactory()) {
- param ^= TypeArguments::Handle(
- Class::Handle(dart_function.Owner()).type_parameters())
- .TypeAt(i);
- } else {
- param ^=
- TypeArguments::Handle(dart_function.type_parameters()).TypeAt(i);
+ if (forwarding_target != NULL) {
+ forwarding_param ^= forwarding_params.TypeAt(i);
+ bound = forwarding_param.bound();
}
- ASSERT(param.IsFinalized());
- body += CheckTypeArgumentBound(param, bound, name);
+
+ if (I->strong() && !bound.IsObjectType() &&
+ (I->reify_generic_functions() || dart_function.IsFactory())) {
+ ASSERT(!bound.IsDynamicType());
+ TypeParameter& param = TypeParameter::Handle(Z);
+ if (dart_function.IsFactory()) {
+ param ^= TypeArguments::Handle(
+ Class::Handle(dart_function.Owner()).type_parameters())
+ .TypeAt(i);
+ } else {
+ param ^=
+ TypeArguments::Handle(dart_function.type_parameters()).TypeAt(i);
+ }
+ ASSERT(param.IsFinalized());
+ body += CheckTypeArgumentBound(param, bound, name);
+ }
}
+ function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
}
- function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
function_node_helper.ReadUntilExcluding(
FunctionNodeHelper::kPositionalParameters);
// Positional.
- list_length = ReadListLength();
- const intptr_t positional_length = list_length;
+ const intptr_t num_positional_params = ReadListLength();
const intptr_t kFirstParameterOffset = 1;
- for (intptr_t i = 0; i < list_length; ++i) {
+ for (intptr_t i = 0; i < num_positional_params; ++i) {
// ith variable offset.
const intptr_t offset = ReaderOffset();
+ SkipVariableDeclaration();
+
LocalVariable* param = LookupVariable(offset + data_program_offset_);
+ if (!param->needs_type_check()) {
+ continue;
+ }
+
const AbstractType* target_type = ¶m->type();
if (forwarding_target != NULL) {
// We add 1 to the parameter index to account for the receiver.
@@ -4116,25 +4231,29 @@
body += LoadLocal(param);
body += CheckArgumentType(param, *target_type);
body += Drop();
- SkipVariableDeclaration(); // read ith variable.
}
// Named.
- list_length = ReadListLength();
- for (intptr_t i = 0; i < list_length; ++i) {
+ const intptr_t num_named_params = ReadListLength();
+ for (intptr_t i = 0; i < num_named_params; ++i) {
// ith variable offset.
- LocalVariable* param =
- LookupVariable(ReaderOffset() + data_program_offset_);
- body += LoadLocal(param);
+ const intptr_t offset = ReaderOffset();
+ SkipVariableDeclaration();
+
+ LocalVariable* param = LookupVariable(offset + data_program_offset_);
+ if (!param->needs_type_check()) {
+ continue;
+ }
+
const AbstractType* target_type = ¶m->type();
if (forwarding_target != NULL) {
// We add 1 to the parameter index to account for the receiver.
target_type = &AbstractType::ZoneHandle(
- Z, forwarding_target->ParameterTypeAt(positional_length + i + 1));
+ Z, forwarding_target->ParameterTypeAt(num_positional_params + i + 1));
}
+ body += LoadLocal(param);
body += CheckArgumentType(param, *target_type);
body += Drop();
- SkipVariableDeclaration(); // read ith variable.
}
return body;
@@ -5554,7 +5673,7 @@
// List of positional.
intptr_t list_length = ReadListLength(); // read list length.
- for (intptr_t i = 0; i < list_length; ++i) {
+ if (list_length > 0) {
return ReadTag(); // read first tag.
}
@@ -9584,6 +9703,9 @@
const intptr_t kUInt32Size = 4;
Reader reader(H.metadata_mappings());
+ if (reader.size() == 0) {
+ return;
+ }
// Scan through metadata mappings in reverse direction.
@@ -9631,6 +9753,18 @@
inferred_type_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
mappings_num);
}
+ } else if (H.StringEquals(tag, ProcedureAttributesMetadataHelper::tag())) {
+ ASSERT(node_references_num == 0);
+
+ if (mappings_num > 0) {
+ if (!FLAG_precompiled_mode) {
+ FATAL(
+ "ProcedureAttributesMetadata is allowed in precompiled mode "
+ "only");
+ }
+ procedure_attributes_metadata_helper_.SetMetadataMappings(
+ offset + kUInt32Size, mappings_num);
+ }
}
}
}
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 7a2ea01..b99111b 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -590,6 +590,26 @@
InferredTypeMetadata GetInferredType(intptr_t node_offset);
};
+struct ProcedureAttributesMetadata {
+ explicit ProcedureAttributesMetadata(bool has_dynamic_invocations)
+ : has_dynamic_invocations(has_dynamic_invocations) {}
+ const bool has_dynamic_invocations;
+};
+
+// Helper class which provides access to direct call metadata.
+class ProcedureAttributesMetadataHelper : public MetadataHelper {
+ public:
+ static const char* tag() { return "vm.procedure-attributes.metadata"; }
+
+ explicit ProcedureAttributesMetadataHelper(StreamingFlowGraphBuilder* builder)
+ : MetadataHelper(builder) {}
+
+ ProcedureAttributesMetadata GetProcedureAttributes(intptr_t node_offset);
+
+ private:
+ bool ReadMetadata(intptr_t node_offset, bool* has_dynamic_invocations);
+};
+
class StreamingDartTypeTranslator {
public:
StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder,
@@ -692,16 +712,34 @@
void EnterScope(intptr_t kernel_offset);
void ExitScope(TokenPosition start_position, TokenPosition end_position);
- /**
- * This assumes that the reader is at a FunctionNode,
- * about to read the positional parameters.
- */
- void AddPositionalAndNamedParameters(intptr_t pos = 0);
- /**
- * This assumes that the reader is at a FunctionNode,
- * about to read a parameter (i.e. VariableDeclaration).
- */
- void AddVariableDeclarationParameter(intptr_t pos);
+ // This enum controls which parameters would be marked as requring type
+ // check on the callee side.
+ enum ParameterTypeCheckMode {
+ // All parameters will be checked.
+ kTypeCheckAllParameters,
+
+ // Only parameters marked as covariant or generic-covariant-impl will be
+ // checked.
+ kTypeCheckForNonDynamicallyInvokedMethod,
+
+ // Only parameters *not* marked as covariant or generic-covariant-impl will
+ // be checked. The rest would be checked in the method itself.
+ // Inverse of kTypeCheckOnlyGenericCovariantImplParameters.
+ kTypeCheckForTearOffOfNonDynamicallyInvokedMethod,
+
+ // No parameters will be checked.
+ kTypeCheckForStaticFunction,
+ };
+
+ // This assumes that the reader is at a FunctionNode,
+ // about to read the positional parameters.
+ void AddPositionalAndNamedParameters(intptr_t pos,
+ ParameterTypeCheckMode type_check_mode);
+
+ // This assumes that the reader is at a FunctionNode,
+ // about to read a parameter (i.e. VariableDeclaration).
+ void AddVariableDeclarationParameter(intptr_t pos,
+ ParameterTypeCheckMode type_check_mode);
LocalVariable* MakeVariable(TokenPosition declaration_pos,
TokenPosition token_pos,
@@ -894,6 +932,7 @@
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
+ procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
@@ -915,6 +954,7 @@
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
+ procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
@@ -936,6 +976,7 @@
record_yield_positions_into_(NULL),
direct_call_metadata_helper_(this),
inferred_type_metadata_helper_(this),
+ procedure_attributes_metadata_helper_(this),
metadata_scanned_(false) {}
~StreamingFlowGraphBuilder() { delete reader_; }
@@ -1126,7 +1167,14 @@
const InferredTypeMetadata* result_type = NULL,
intptr_t argument_check_bits = 0,
intptr_t type_argument_check_bits = 0);
- Fragment BuildArgumentTypeChecks();
+
+ enum TypeChecksToBuild {
+ kDefaultTypeChecks,
+ kTypeChecksForNoDynamicInvocationsTearOff
+ };
+
+ Fragment BuildArgumentTypeChecks(TypeChecksToBuild mode = kDefaultTypeChecks);
+
Fragment ThrowException(TokenPosition position);
Fragment BooleanNegate();
Fragment TranslateInstantiatedTypeArguments(
@@ -1323,12 +1371,14 @@
GrowableArray<intptr_t>* record_yield_positions_into_;
DirectCallMetadataHelper direct_call_metadata_helper_;
InferredTypeMetadataHelper inferred_type_metadata_helper_;
+ ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_;
bool metadata_scanned_;
friend class ClassHelper;
friend class ConstantHelper;
friend class ConstructorHelper;
friend class DirectCallMetadataHelper;
+ friend class ProcedureAttributesMetadataHelper;
friend class FieldHelper;
friend class FunctionNodeHelper;
friend class InferredTypeMetadataHelper;
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 6219611..4c0c8eb 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5905,20 +5905,24 @@
}
DART_EXPORT Dart_KernelCompilationResult
-Dart_CompileToKernel(const char* script_uri, const char* platform_kernel) {
+Dart_CompileToKernel(const char* script_uri,
+ const uint8_t* platform_kernel,
+ intptr_t platform_kernel_size) {
#if defined(DART_PRECOMPILED_RUNTIME)
Dart_KernelCompilationResult result;
result.status = Dart_KernelCompilationStatus_Unknown;
result.error = strdup("Dart_CompileToKernel is unsupported.");
return result;
#else
- return KernelIsolate::CompileToKernel(script_uri, platform_kernel);
+ return KernelIsolate::CompileToKernel(script_uri, platform_kernel,
+ platform_kernel_size);
#endif
}
DART_EXPORT Dart_KernelCompilationResult
Dart_CompileSourcesToKernel(const char* script_uri,
- const char* platform_kernel,
+ const uint8_t* platform_kernel,
+ intptr_t platform_kernel_size,
int source_files_count,
Dart_SourceFile sources[],
bool incremental_compile) {
@@ -5928,9 +5932,9 @@
result.error = strdup("Dart_CompileSourcesToKernel is unsupported.");
return result;
#else
- return KernelIsolate::CompileToKernel(script_uri, platform_kernel,
- source_files_count, sources,
- incremental_compile);
+ return KernelIsolate::CompileToKernel(
+ script_uri, platform_kernel, platform_kernel_size, source_files_count,
+ sources, incremental_compile);
#endif
}
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 67d23d6..b8242e4 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -157,6 +157,7 @@
C(stress_async_stacks, false, false, bool, false, \
"Stress test async stack traces") \
P(strong, bool, false, "Enable strong mode.") \
+ P(sync_async, bool, false, "Start `async` functions synchronously.") \
R(support_ast_printer, false, bool, true, "Support the AST printer.") \
R(support_compiler_stats, false, bool, true, "Support compiler stats.") \
R(support_disassembler, false, bool, true, "Support the disassembler.") \
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 9b804c7..8767588 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -84,8 +84,10 @@
isolate = reinterpret_cast<Isolate*>(create_callback(
KernelIsolate::kName, NULL, NULL, NULL, &api_flags, NULL, &error));
if (isolate == NULL) {
- OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Isolate creation error: %s\n",
- error);
+ if (FLAG_trace_kernel) {
+ OS::PrintErr(DART_KERNEL_ISOLATE_NAME ": Isolate creation error: %s\n",
+ error);
+ }
KernelIsolate::SetKernelIsolate(NULL);
KernelIsolate::FinishedInitializing();
return;
@@ -281,6 +283,10 @@
return files;
}
+static void PassThroughFinalizer(void* isolate_callback_data,
+ Dart_WeakPersistentHandle handle,
+ void* peer) {}
+
class KernelCompilationRequest : public ValueObject {
public:
KernelCompilationRequest()
@@ -307,7 +313,8 @@
Dart_KernelCompilationResult SendAndWaitForResponse(
Dart_Port kernel_port,
const char* script_uri,
- const char* platform_kernel,
+ const uint8_t* platform_kernel,
+ intptr_t platform_kernel_size,
int source_files_count,
Dart_SourceFile source_files[],
bool incremental_compile) {
@@ -329,9 +336,20 @@
Dart_CObject dart_platform_kernel;
if (platform_kernel != NULL) {
- dart_platform_kernel.type = Dart_CObject_kString;
- dart_platform_kernel.value.as_string = const_cast<char*>(platform_kernel);
+ dart_platform_kernel.type = Dart_CObject_kExternalTypedData;
+ dart_platform_kernel.value.as_external_typed_data.type =
+ Dart_TypedData_kUint8;
+ dart_platform_kernel.value.as_external_typed_data.length =
+ platform_kernel_size;
+ dart_platform_kernel.value.as_external_typed_data.data =
+ const_cast<uint8_t*>(platform_kernel);
+ dart_platform_kernel.value.as_external_typed_data.peer =
+ const_cast<uint8_t*>(platform_kernel);
+ dart_platform_kernel.value.as_external_typed_data.callback =
+ PassThroughFinalizer;
} else {
+ // If NULL, the kernel service looks up the platform dill file
+ // next to the executable.
dart_platform_kernel.type = Dart_CObject_kNull;
}
@@ -370,6 +388,10 @@
suppress_warnings.type = Dart_CObject_kBool;
suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
+ Dart_CObject dart_sync_async;
+ dart_sync_async.type = Dart_CObject_kBool;
+ dart_sync_async.value.as_bool = FLAG_sync_async;
+
Dart_CObject* message_arr[] = {&tag,
&send_port,
&uri,
@@ -378,7 +400,8 @@
&dart_strong,
&isolate_id,
&files,
- &suppress_warnings};
+ &suppress_warnings,
+ &dart_sync_async};
message.value.as_array.values = message_arr;
message.value.as_array.length = ARRAY_SIZE(message_arr);
// Send the message.
@@ -492,7 +515,8 @@
Dart_KernelCompilationResult KernelIsolate::CompileToKernel(
const char* script_uri,
- const char* platform_kernel,
+ const uint8_t* platform_kernel,
+ intptr_t platform_kernel_size,
int source_file_count,
Dart_SourceFile source_files[],
bool incremental_compile) {
@@ -507,9 +531,9 @@
}
KernelCompilationRequest request;
- return request.SendAndWaitForResponse(kernel_port, script_uri,
- platform_kernel, source_file_count,
- source_files, incremental_compile);
+ return request.SendAndWaitForResponse(
+ kernel_port, script_uri, platform_kernel, platform_kernel_size,
+ source_file_count, source_files, incremental_compile);
}
#endif // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index 89507d1..b0f0819 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -29,7 +29,8 @@
static Dart_KernelCompilationResult CompileToKernel(
const char* script_uri,
- const char* platform_kernel = NULL,
+ const uint8_t* platform_kernel,
+ intptr_t platform_kernel_size,
int source_files_count = 0,
Dart_SourceFile source_files[] = NULL,
bool incremental_compile = false);
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index a9abbd7..624c883 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -44,7 +44,7 @@
static zx_status_t GetTimeServicePtr(
time_service::TimeServiceSyncPtr* time_svc) {
zx::channel service_root = app::subtle::CreateStaticServiceRootHandle();
- zx::channel time_svc_channel = GetSynchronousProxy(time_svc).PassChannel();
+ zx::channel time_svc_channel = GetSynchronousProxy(time_svc).TakeChannel();
return fdio_service_connect_at(service_root.get(), kTimeServiceName,
time_svc_channel.release());
}
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 5ea02e7..a144a86 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -2012,7 +2012,7 @@
// It is too early to resolve the type here, since it can be a result type
// referring to a not yet declared function type parameter.
parameter.type = &AbstractType::ZoneHandle(
- Z, ParseTypeOrFunctionType(false, ClassFinalizer::kDoNotResolve));
+ Z, ParseTypeOrFunctionType(true, ClassFinalizer::kDoNotResolve));
// At this point, we must see an identifier for the parameter name, unless
// we are using the function type syntax (in which case the name is optional,
@@ -2060,10 +2060,6 @@
ASSERT(params->num_optional_parameters == 0);
}
}
- if (parameter.type->IsVoidType()) {
- ReportError("parameter '%s' may not be 'void'",
- parameter.name->ToCString());
- }
if (params->implicitly_final) {
parameter.is_final = true;
}
@@ -2287,10 +2283,6 @@
ASSERT(params->num_optional_parameters == 0);
}
}
- if (parameter.type->IsVoidType()) {
- ReportError("parameter '%s' may not be 'void'",
- parameter.name->ToCString());
- }
if (params->implicitly_final) {
parameter.is_final = true;
}
@@ -4756,8 +4748,6 @@
"missing 'var', 'final', 'const' or type"
" in field declaration");
}
- } else if (member.type->IsVoidType()) {
- ReportError(member.name_pos, "field may not be 'void'");
}
if (!member.type->IsResolved()) {
AbstractType& type = AbstractType::ZoneHandle(Z, member.type->raw());
@@ -7584,30 +7574,42 @@
Symbols::AsyncStackTraceVar(), false);
ASSERT((existing_var != NULL) && existing_var->is_captured());
- // Create and return a new future that executes a closure with the current
- // body.
+ // Create a completer that executes a closure with the current body and
+ // return the corresponding future.
// No need to capture parameters or other variables, since they have already
// been captured in the corresponding scope as the body has been parsed within
// a nested block (contained in the async function's block).
- const Class& future = Class::ZoneHandle(Z, I->object_store()->future_class());
- ASSERT(!future.IsNull());
- const Function& constructor = Function::ZoneHandle(
- Z, future.LookupFunction(Symbols::FutureMicrotask()));
- ASSERT(!constructor.IsNull());
- const Class& completer =
- Class::ZoneHandle(Z, I->object_store()->completer_class());
- ASSERT(!completer.IsNull());
- const Function& completer_constructor = Function::ZoneHandle(
- Z, completer.LookupFunction(Symbols::CompleterSyncConstructor()));
- ASSERT(!completer_constructor.IsNull());
+
+ const Library& async_lib = Library::Handle(Z, Library::AsyncLibrary());
LocalVariable* async_completer =
current_block_->scope->LookupVariable(Symbols::AsyncCompleter(), false);
const TokenPosition token_pos = ST(closure_body->token_pos());
- // Add to AST:
- // :async_completer = new Completer.sync();
+
+ Function& completer_constructor = Function::ZoneHandle(Z);
+ if (FLAG_sync_async) {
+ const Class& completer_class = Class::Handle(
+ Z, async_lib.LookupClassAllowPrivate(Symbols::_AsyncAwaitCompleter()));
+ ASSERT(!completer_class.IsNull());
+ completer_constructor = completer_class.LookupConstructorAllowPrivate(
+ Symbols::_AsyncAwaitCompleterConstructor());
+ ASSERT(!completer_constructor.IsNull());
+
+ // Add to AST:
+ // :async_completer = new _AsyncAwaitCompleter();
+ } else {
+ const Class& completer =
+ Class::Handle(Z, I->object_store()->completer_class());
+ ASSERT(!completer.IsNull());
+ completer_constructor =
+ completer.LookupFunction(Symbols::CompleterSyncConstructor());
+ ASSERT(!completer_constructor.IsNull());
+
+ // Add to AST:
+ // :async_completer = new Completer.sync();
+ }
ArgumentListNode* empty_args = new (Z) ArgumentListNode(token_pos);
ConstructorCallNode* completer_constructor_node =
new (Z) ConstructorCallNode(token_pos, TypeArguments::ZoneHandle(Z),
@@ -7634,8 +7636,6 @@
new (Z) StoreLocalNode(token_pos, async_op_var, cn);
current_block_->statements->Add(store_async_op);
- const Library& async_lib = Library::Handle(Library::AsyncLibrary());
-
if (FLAG_causal_async_stacks) {
// Add to AST:
// :async_stack_trace = _asyncStackTraceHelper();
@@ -7699,13 +7699,29 @@
current_block_->statements->Add(store_async_catch_error_callback);
- // Add to AST:
- // new Future.microtask(:async_op);
- ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
- arguments->Add(new (Z) LoadLocalNode(token_pos, async_op_var));
- ConstructorCallNode* future_node = new (Z) ConstructorCallNode(
- token_pos, TypeArguments::ZoneHandle(Z), constructor, arguments);
- current_block_->statements->Add(future_node);
+ if (FLAG_sync_async) {
+ // Add to AST:
+ // :async_completer.start(:async_op);
+ ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
+ arguments->Add(new (Z) LoadLocalNode(token_pos, async_op_var));
+ InstanceCallNode* start_call = new (Z) InstanceCallNode(
+ token_pos, new (Z) LoadLocalNode(token_pos, async_completer),
+ Symbols::_AsyncAwaitStart(), arguments);
+ current_block_->statements->Add(start_call);
+ } else {
+ // Add to AST:
+ // new Future.microtask(:async_op);
+ const Class& future = Class::Handle(Z, I->object_store()->future_class());
+ ASSERT(!future.IsNull());
+ const Function& constructor = Function::ZoneHandle(
+ Z, future.LookupFunction(Symbols::FutureMicrotask()));
+ ASSERT(!constructor.IsNull());
+ ArgumentListNode* arguments = new (Z) ArgumentListNode(token_pos);
+ arguments->Add(new (Z) LoadLocalNode(token_pos, async_op_var));
+ ConstructorCallNode* future_node = new (Z) ConstructorCallNode(
+ token_pos, TypeArguments::ZoneHandle(Z), constructor, arguments);
+ current_block_->statements->Add(future_node);
+ }
// Add to AST:
// return :async_completer.future;
@@ -8003,7 +8019,7 @@
type_is_optional = true;
}
if ((CurrentToken() == Token::kVOID) || IsFunctionTypeSymbol()) {
- return ParseFunctionType(AbstractType::Handle(Z), finalization);
+ return ParseTypeOrFunctionType(true, finalization);
}
if (CurrentToken() != Token::kIDENT) {
if (type_is_optional) {
@@ -8023,7 +8039,7 @@
return Type::DynamicType();
}
}
- return ParseTypeOrFunctionType(false, finalization);
+ return ParseTypeOrFunctionType(false, finalization); // void handled above.
}
// Returns ast nodes of the variable initialization. Variables without an
@@ -8480,6 +8496,8 @@
// Allow 'void' as type if 'allow_void' is true.
// Note that 'void Function()' is always allowed, since it is a function type
// and not the void type.
+// TODO(regis): Consider removing allow_void argument, since this call is only
+// used where void is allowed. Wait for Dart 2 spec to stabilize.
bool Parser::TryParseType(bool allow_void) {
bool found = false;
if (CurrentToken() == Token::kVOID) {
@@ -8536,8 +8554,7 @@
}
if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kVOID) &&
(CurrentToken() != Token::kCONST)) {
- // Not a legal type identifier or void (result type of function type)
- // or const keyword or metadata.
+ // Not a legal type identifier or void or const keyword or metadata.
return false;
}
const TokenPosition saved_pos = TokenPos();
@@ -8548,7 +8565,7 @@
have_type = true; // Type is dynamic if 'const' is not followed by a type.
}
if ((CurrentToken() == Token::kVOID) || IsFunctionTypeSymbol()) {
- if (TryParseType(false)) {
+ if (TryParseType(true)) {
have_type = true;
}
} else if (IsIdentifier()) { // Type or variable name.
@@ -8558,7 +8575,7 @@
Token::IsIdentifier(follower)) { // Variable name following a type.
// We see the beginning of something that could be a type.
const TokenPosition type_pos = TokenPos();
- if (TryParseType(false)) {
+ if (TryParseType(false)) { // void handled above.
have_type = true;
} else {
SetPosition(type_pos);
@@ -8685,10 +8702,12 @@
CurrentToken() == Token::kCONST) {
ConsumeToken();
}
- if (IsIdentifier()) {
- if (LookaheadToken(1) == Token::kIN) {
+ // void as the loop variable type does not make much sense, but it is not
+ // disallowed by the spec.
+ if (IsIdentifier() || (CurrentToken() == Token::kVOID)) {
+ if ((CurrentToken() != Token::kVOID) && (LookaheadToken(1) == Token::kIN)) {
return true;
- } else if (TryParseType(false)) {
+ } else if (TryParseType(true)) {
if (IsIdentifier()) {
ConsumeToken();
}
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index 7ed478e..7a1a51e 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -35,6 +35,7 @@
is_invisible_(false),
is_captured_parameter_(false),
is_forced_stack_(false),
+ type_check_mode_(kDoTypeCheck),
index_(LocalVariable::kUninitializedIndex) {
ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
ASSERT(type.IsFinalized());
@@ -65,6 +66,24 @@
bool is_forced_stack() const { return is_forced_stack_; }
void set_is_forced_stack() { is_forced_stack_ = true; }
+ enum TypeCheckMode {
+ kDoTypeCheck,
+ kSkipTypeCheck,
+ kTypeCheckedByCaller,
+ };
+
+ // Returns true if this local variable represents a parameter that needs type
+ // check when we enter the function.
+ bool needs_type_check() const { return type_check_mode_ == kDoTypeCheck; }
+
+ // Returns true if this local variable represents a parameter which type is
+ // guaranteed by the caller.
+ bool was_type_checked_by_caller() const {
+ return type_check_mode_ == kTypeCheckedByCaller;
+ }
+
+ void set_type_check_mode(TypeCheckMode mode) { type_check_mode_ = mode; }
+
bool HasIndex() const { return index_ != kUninitializedIndex; }
int index() const {
ASSERT(HasIndex());
@@ -124,6 +143,7 @@
bool is_invisible_;
bool is_captured_parameter_;
bool is_forced_stack_;
+ TypeCheckMode type_check_mode_;
int index_; // Allocation index in words relative to frame pointer (if not
// captured), or relative to the context pointer (if captured).
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index 05dce87..2c42ec5 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -352,13 +352,16 @@
got_unwind = RunMain(isolate);
}
+ // FinishedInitializing should be called irrespective of whether
+ // running main caused an error or not. Otherwise, other isolates
+ // waiting for service isolate to come up will deadlock.
+ ServiceIsolate::FinishedInitializing();
+
if (got_unwind) {
ShutdownIsolate(reinterpret_cast<uword>(isolate));
return;
}
- ServiceIsolate::FinishedInitializing();
-
isolate->message_handler()->Run(Dart::thread_pool(), NULL, ShutdownIsolate,
reinterpret_cast<uword>(isolate));
}
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 0d2dfcd..276657a 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -145,6 +145,9 @@
V(CompleterComplete, "complete") \
V(CompleterCompleteError, "completeError") \
V(CompleterSyncConstructor, "Completer.sync") \
+ V(_AsyncAwaitCompleter, "_AsyncAwaitCompleter") \
+ V(_AsyncAwaitCompleterConstructor, "_AsyncAwaitCompleter.") \
+ V(_AsyncAwaitStart, "start") \
V(CompleterFuture, "future") \
V(StreamIterator, "StreamIterator") \
V(StreamIteratorConstructor, "StreamIterator.") \
diff --git a/runtime/vm/thread_interrupter_fuchsia.cc b/runtime/vm/thread_interrupter_fuchsia.cc
index 66f7fbce..26409ca 100644
--- a/runtime/vm/thread_interrupter_fuchsia.cc
+++ b/runtime/vm/thread_interrupter_fuchsia.cc
@@ -76,10 +76,9 @@
public:
#if defined(TARGET_ARCH_X64)
static bool GrabRegisters(zx_handle_t thread, InterruptedThreadState* state) {
- zx_x86_64_general_regs_t regs;
- uint32_t regset_size;
+ zx_thread_state_general_regs regs;
zx_status_t status = zx_thread_read_state(
- thread, ZX_THREAD_STATE_REGSET0, ®s, sizeof(regs), ®set_size);
+ thread, ZX_THREAD_STATE_GENERAL_REGS, ®s, sizeof(regs));
if (status != ZX_OK) {
if (FLAG_trace_thread_interrupter) {
OS::PrintErr("ThreadInterrupter failed to get registers: %s\n",
@@ -95,10 +94,9 @@
}
#elif defined(TARGET_ARCH_ARM64)
static bool GrabRegisters(zx_handle_t thread, InterruptedThreadState* state) {
- zx_arm64_general_regs_t regs;
- uint32_t regset_size;
+ zx_thread_state_general_regs regs;
zx_status_t status = zx_thread_read_state(
- thread, ZX_THREAD_STATE_REGSET0, ®s, sizeof(regs), ®set_size);
+ thread, ZX_THREAD_STATE_GENERAL_REGS, ®s, sizeof(regs));
if (status != ZX_OK) {
if (FLAG_trace_thread_interrupter) {
OS::PrintErr("ThreadInterrupter failed to get registers: %s\n",
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index caba5b0..81fe031 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -195,7 +195,7 @@
bool incrementally) {
Zone* zone = Thread::Current()->zone();
Dart_KernelCompilationResult compilation_result = Dart_CompileSourcesToKernel(
- url, NULL /* platform binary can be found at the default location */,
+ url, NULL /* platform binary can be found at the default location */, 0,
sourcefiles_count, sourcefiles, incrementally);
if (compilation_result.status != Dart_KernelCompilationStatus_Ok) {
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 56bdc05..53910eb 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -86,11 +86,30 @@
#define ASSEMBLER_TEST_RUN(name, test) \
static void AssemblerTestRun##name(AssemblerTest* test); \
ISOLATE_UNIT_TEST_CASE(name) { \
- Assembler __assembler__; \
- AssemblerTest test("" #name, &__assembler__); \
- AssemblerTestGenerate##name(test.assembler()); \
- test.Assemble(); \
- AssemblerTestRun##name(&test); \
+ { \
+ bool use_far_branches = false; \
+ LongJumpScope jump; \
+ if (setjmp(*jump.Set()) == 0) { \
+ Assembler assembler(use_far_branches); \
+ AssemblerTest test("" #name, &assembler); \
+ AssemblerTestGenerate##name(test.assembler()); \
+ test.Assemble(); \
+ AssemblerTestRun##name(&test); \
+ return; \
+ } \
+ } \
+ \
+ const Error& error = Error::Handle(Thread::Current()->sticky_error()); \
+ if (error.raw() == Object::branch_offset_error().raw()) { \
+ bool use_far_branches = true; \
+ Assembler assembler(use_far_branches); \
+ AssemblerTest test("" #name, &assembler); \
+ AssemblerTestGenerate##name(test.assembler()); \
+ test.Assemble(); \
+ AssemblerTestRun##name(&test); \
+ } else { \
+ FATAL1("Unexpected error: %s\n", error.ToErrorCString()); \
+ } \
} \
static void AssemblerTestRun##name(AssemblerTest* test)
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index be475bd7..bec28e9 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -132,6 +132,53 @@
}
}
+class _AsyncAwaitCompleter<T> implements Completer<T> {
+ final _completer = new Completer<T>.sync();
+ bool isSync;
+
+ _AsyncAwaitCompleter() : isSync = false;
+
+ void complete([FutureOr<T> value]) {
+ if (isSync) {
+ _completer.complete(value);
+ } else if (value is Future<T>) {
+ value.then(_completer.complete, onError: _completer.completeError);
+ } else {
+ scheduleMicrotask(() {
+ _completer.complete(value);
+ });
+ }
+ }
+
+ void completeError(e, [st]) {
+ if (isSync) {
+ _completer.completeError(e, st);
+ } else {
+ scheduleMicrotask(() {
+ _completer.completeError(e, st);
+ });
+ }
+ }
+
+ Future<T> get future => _completer.future;
+ bool get isCompleted => _completer.isCompleted;
+}
+
+/// Initiates the computation of an `async` function and starts the body
+/// synchronously.
+///
+/// Used as part of the runtime support for the async/await transformation.
+///
+/// This function sets up the first call into the transformed [bodyFunction].
+/// Independently, it takes the [completer] and returns the future of the
+/// completer for convenience of the transformed code.
+dynamic _asyncStartSync(
+ _WrappedAsyncBody bodyFunction, _AsyncAwaitCompleter completer) {
+ bodyFunction(async_error_codes.SUCCESS, null);
+ completer.isSync = true;
+ return completer.future;
+}
+
/// Initiates the computation of an `async` function.
///
/// Used as part of the runtime support for the async/await transformation.
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 1c8beff..2815296 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -19,6 +19,7 @@
objectHashCode,
patch,
Primitives,
+ quoteStringForRegExp,
stringJoinUnchecked,
getTraceFromException,
RuntimeError;
@@ -29,6 +30,8 @@
import "dart:convert" show Encoding, utf8;
+import 'dart:typed_data' show Endian, Uint8List, Uint16List;
+
String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol);
Map<String, dynamic> _symbolMapToStringMap(Map<Symbol, dynamic> map) {
@@ -180,6 +183,23 @@
}
@patch
+class BigInt implements Comparable<BigInt> {
+ @patch
+ static BigInt get zero => _BigIntImpl.zero;
+ @patch
+ static BigInt get one => _BigIntImpl.one;
+ @patch
+ static BigInt get two => _BigIntImpl.two;
+
+ @patch
+ static BigInt parse(String source, {int radix}) =>
+ _BigIntImpl.parse(source, radix: radix);
+
+ @patch
+ factory BigInt.from(num value) = _BigIntImpl.from;
+}
+
+@patch
class Error {
@patch
static String _objectToString(Object object) {
@@ -469,6 +489,9 @@
{bool multiLine: false, bool caseSensitive: true}) =>
new JSSyntaxRegExp(source,
multiLine: multiLine, caseSensitive: caseSensitive);
+
+ @patch
+ static String escape(String text) => quoteStringForRegExp(text);
}
// Patch for 'identical' function.
@@ -780,3 +803,2101 @@
@patch
_throw(error) => throw error;
}
+
+// TODO(sra): The rest of this core_patch.dart source should reside in an
+// included part file instead of being inlined. However, part files are not
+// properly supported here.
+
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// part of dart.core;
+
+int _max(int a, int b) => a > b ? a : b;
+int _min(int a, int b) => a < b ? a : b;
+
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * Copyright (c) 2012 Adam Singer (adam@solvr.io)
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+/**
+ * An implementation for the arbitrarily large integer.
+ *
+ * The integer number is represented by a sign, an array of 16-bit unsigned
+ * integers in little endian format, and a number of used digits in that array.
+ */
+class _BigIntImpl implements BigInt {
+ // Bits per digit.
+ static const int _digitBits = 16;
+ static const int _digitBase = 1 << _digitBits;
+ static const int _digitMask = (1 << _digitBits) - 1;
+
+ static final _BigIntImpl zero = new _BigIntImpl._fromInt(0);
+ static final _BigIntImpl one = new _BigIntImpl._fromInt(1);
+ static final _BigIntImpl two = new _BigIntImpl._fromInt(2);
+
+ static final _BigIntImpl _minusOne = -one;
+ static final _BigIntImpl _bigInt10000 = new _BigIntImpl._fromInt(10000);
+
+ // Result cache for last _divRem call.
+ // Result cache for last _divRem call.
+ static Uint16List _lastDividendDigits;
+ static int _lastDividendUsed;
+ static Uint16List _lastDivisorDigits;
+ static int _lastDivisorUsed;
+ static Uint16List _lastQuoRemDigits;
+ static int _lastQuoRemUsed;
+ static int _lastRemUsed;
+ static int _lastRem_nsh;
+
+ /// Whether this bigint is negative.
+ final bool _isNegative;
+
+ /// The unsigned digits of this bigint.
+ ///
+ /// The least significant digit is in slot 0.
+ /// The list may have more digits than needed. That is, `_digits.length` may
+ /// be strictly greater than `_used`.
+ final Uint16List _digits;
+
+ /// The number of used entries in [_digits].
+ ///
+ /// To avoid reallocating [Uint16List]s, lists that are too big are not
+ /// replaced.
+ final int _used;
+
+ /**
+ * Parses [source] as a, possibly signed, integer literal and returns its
+ * value.
+ *
+ * The [source] must be a non-empty sequence of base-[radix] digits,
+ * optionally prefixed with a minus or plus sign ('-' or '+').
+ *
+ * The [radix] must be in the range 2..36. The digits used are
+ * first the decimal digits 0..9, and then the letters 'a'..'z' with
+ * values 10 through 35. Also accepts upper-case letters with the same
+ * values as the lower-case ones.
+ *
+ * If no [radix] is given then it defaults to 10. In this case, the [source]
+ * digits may also start with `0x`, in which case the number is interpreted
+ * as a hexadecimal literal, which effectively means that the `0x` is ignored
+ * and the radix is instead set to 16.
+ *
+ * For any int `n` and radix `r`, it is guaranteed that
+ * `n == int.parse(n.toRadixString(r), radix: r)`.
+ *
+ * Throws a [FormatException] if the [source] is not a valid integer literal,
+ * optionally prefixed by a sign.
+ */
+ static _BigIntImpl parse(String source, {int radix}) {
+ var result = _tryParse(source, radix: radix);
+ if (result == null) {
+ throw new FormatException("Could not parse BigInt", source);
+ }
+ return result;
+ }
+
+ /// Parses a decimal bigint literal.
+ ///
+ /// The [source] must not contain leading or trailing whitespace.
+ static _BigIntImpl _parseDecimal(String source, bool isNegative) {
+ const _0 = 48;
+
+ int part = 0;
+ _BigIntImpl result = zero;
+ // Read in the source 4 digits at a time.
+ // The first part may have a few leading virtual '0's to make the remaining
+ // parts all have exactly 4 digits.
+ int digitInPartCount = 4 - source.length.remainder(4);
+ if (digitInPartCount == 4) digitInPartCount = 0;
+ for (int i = 0; i < source.length; i++) {
+ part = part * 10 + source.codeUnitAt(i) - _0;
+ if (++digitInPartCount == 4) {
+ result = result * _bigInt10000 + new _BigIntImpl._fromInt(part);
+ part = 0;
+ digitInPartCount = 0;
+ }
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Returns the value of a given source digit.
+ ///
+ /// Source digits between "0" and "9" (inclusive) return their decimal value.
+ ///
+ /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return
+ /// 10 + their position in the ASCII alphabet.
+ ///
+ /// The incoming [codeUnit] must be an ASCII code-unit.
+ static int _codeUnitToRadixValue(int codeUnit) {
+ // We know that the characters must be ASCII as otherwise the
+ // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
+ // guaranteed to be a safe operation, since it preserves digits
+ // and lower-cases ASCII letters.
+ const int _0 = 48;
+ const int _9 = 57;
+ const int _a = 97;
+ if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0;
+ codeUnit |= 0x20;
+ var result = codeUnit - _a + 10;
+ return result;
+ }
+
+ /// Parses the given [source] string, starting at [startPos], as a hex
+ /// literal.
+ ///
+ /// If [isNegative] is true, negates the result before returning it.
+ ///
+ /// The [source] (substring) must be a valid hex literal.
+ static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) {
+ int hexDigitsPerChunk = _digitBits ~/ 4;
+ int sourceLength = source.length - startPos;
+ int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
+ var digits = new Uint16List(chunkCount);
+
+ int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk;
+ int digitIndex = digits.length - 1;
+ int i = startPos;
+ int chunk = 0;
+ for (int j = 0; j < lastDigitLength; j++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (digitValue >= 16) return null;
+ chunk = chunk * 16 + digitValue;
+ }
+ digits[digitIndex--] = chunk;
+
+ while (i < source.length) {
+ chunk = 0;
+ for (int j = 0; j < 4; j++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
+ if (digitValue >= 16) return null;
+ chunk = chunk * 16 + digitValue;
+ }
+ digits[digitIndex--] = chunk;
+ }
+ if (digits.length == 1 && digits[0] == 0) return zero;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ /// Parses the given [source] as a [radix] literal.
+ ///
+ /// The [source] will be checked for invalid characters. If it is invalid,
+ /// this function returns `null`.
+ static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) {
+ var result = zero;
+ var base = new _BigIntImpl._fromInt(radix);
+ for (int i = 0; i < source.length; i++) {
+ var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i));
+ if (digitValue >= radix) return null;
+ result = result * base + new _BigIntImpl._fromInt(digitValue);
+ }
+ if (isNegative) return -result;
+ return result;
+ }
+
+ /// Tries to parse the given [source] as a [radix] literal.
+ ///
+ /// Returns the parsed big integer, or `null` if it failed.
+ ///
+ /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
+ static _BigIntImpl _tryParse(String source, {int radix}) {
+ if (source == "") return null;
+
+ var re = new RegExp(r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$',
+ caseSensitive: false);
+ var match = re.firstMatch(source);
+ int signIndex = 1;
+ int hexIndex = 3;
+ int decimalIndex = 4;
+ int nonDecimalHexIndex = 5;
+ if (match == null) return null;
+
+ bool isNegative = match[signIndex] == "-";
+
+ String decimalMatch = match[decimalIndex];
+ String hexMatch = match[hexIndex];
+ String nonDecimalMatch = match[nonDecimalHexIndex];
+
+ if (radix == null) {
+ if (decimalMatch != null) {
+ // Cannot fail because we know that the digits are all decimal.
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (hexMatch != null) {
+ // Cannot fail because we know that the digits are all hex.
+ return _parseHex(hexMatch, 2, isNegative);
+ }
+ return null;
+ }
+
+ if (radix is! int) {
+ throw new ArgumentError.value(radix, 'radix', 'is not an integer');
+ }
+ if (radix < 2 || radix > 36) {
+ throw new RangeError.range(radix, 2, 36, 'radix');
+ }
+ if (radix == 10 && decimalMatch != null) {
+ return _parseDecimal(decimalMatch, isNegative);
+ }
+ if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
+ return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative);
+ }
+
+ return _parseRadix(
+ decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative);
+ }
+
+ /// Finds the amount significant digits in the provided [digits] array.
+ static int _normalize(int used, Uint16List digits) {
+ while (used > 0 && digits[used - 1] == 0) used--;
+ return used;
+ }
+
+ /// Factory returning an instance initialized with the given field values.
+ /// If the [digits] array contains leading 0s, the [used] value is adjusted
+ /// accordingly. The [digits] array is not modified.
+ _BigIntImpl._(bool isNegative, int used, Uint16List digits)
+ : this._normalized(isNegative, _normalize(used, digits), digits);
+
+ _BigIntImpl._normalized(bool isNegative, this._used, this._digits)
+ : _isNegative = _used == 0 ? false : isNegative;
+
+ /// Whether this big integer is zero.
+ bool get _isZero => _used == 0;
+
+ /// Allocates an array of the given [length] and copies the [digits] in the
+ /// range [from] to [to-1], starting at index 0, followed by leading zero
+ /// digits.
+ static Uint16List _cloneDigits(
+ Uint16List digits, int from, int to, int length) {
+ var resultDigits = new Uint16List(length);
+ var n = to - from;
+ for (var i = 0; i < n; i++) {
+ resultDigits[i] = digits[from + i];
+ }
+ return resultDigits;
+ }
+
+ /// Allocates a big integer from the provided [value] number.
+ factory _BigIntImpl.from(num value) {
+ if (value == 0) return zero;
+ if (value == 1) return one;
+ if (value == 2) return two;
+
+ // Given this order dart2js will use the `_fromInt` for smaller value and
+ // then use the bit-manipulating `_fromDouble` for all other values.
+ if (value.abs() < 0x100000000)
+ return new _BigIntImpl._fromInt(value.toInt());
+ if (value is double) return new _BigIntImpl._fromDouble(value);
+ return new _BigIntImpl._fromInt(value);
+ }
+
+ factory _BigIntImpl._fromInt(int value) {
+ bool isNegative = value < 0;
+ if (isNegative) {
+ // Handle the min 64-bit value differently, since its negation is not
+ // positive.
+ // TODO(floitsch): we should use min.minValue or 0x8000000000000000 here.
+ const int minInt64 = -9223372036854775807 - 1;
+ if (value == minInt64) {
+ var digits = new Uint16List(4);
+ digits[3] = 0x8000;
+ return new _BigIntImpl._(true, digits.length, digits);
+ }
+ value = -value;
+ }
+ assert(_digitBits == 16);
+ if (value < _digitBase) {
+ var digits = new Uint16List(1);
+ digits[0] = value;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+ if (value <= 0xFFFFFFFF) {
+ var digits = new Uint16List(2);
+ digits[0] = value & _digitMask;
+ digits[1] = value >> _digitBits;
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ var bits = value.bitLength;
+ var digits = new Uint16List((bits - 1) ~/ _digitBits + 1);
+ var i = 0;
+ while (value != 0) {
+ digits[i++] = value & _digitMask;
+ value = value ~/ _digitBase;
+ }
+ return new _BigIntImpl._(isNegative, digits.length, digits);
+ }
+
+ /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating
+ /// garbage.
+ static final Uint8List _bitsForFromDouble = new Uint8List(8);
+
+ factory _BigIntImpl._fromDouble(double value) {
+ const int exponentBias = 1075;
+
+ if (value.isNaN || value.isInfinite) {
+ throw new ArgumentError("Value must be finite: $value");
+ }
+ bool isNegative = value < 0;
+ if (isNegative) value = -value;
+
+ value = value.floorToDouble();
+ if (value == 0) return zero;
+
+ var bits = _bitsForFromDouble;
+ for (int i = 0; i < 8; i++) {
+ bits[i] = 0;
+ }
+ bits.buffer.asByteData().setFloat64(0, value, Endian.little);
+ // The exponent is in bits 53..63.
+ var biasedExponent = (bits[7] << 4) + (bits[6] >> 4);
+ var exponent = biasedExponent - exponentBias;
+
+ assert(_digitBits == 16);
+ // The significant bits are in 0 .. 52.
+ var unshiftedDigits = new Uint16List(4);
+ unshiftedDigits[0] = (bits[1] << 8) + bits[0];
+ unshiftedDigits[1] = (bits[3] << 8) + bits[2];
+ unshiftedDigits[2] = (bits[5] << 8) + bits[4];
+ // Don't forget to add the hidden bit.
+ unshiftedDigits[3] = 0x10 | (bits[6] & 0xF);
+
+ var unshiftedBig = new _BigIntImpl._normalized(false, 4, unshiftedDigits);
+ _BigIntImpl absResult;
+ if (exponent < 0) {
+ absResult = unshiftedBig >> -exponent;
+ } else if (exponent > 0) {
+ absResult = unshiftedBig << exponent;
+ }
+ if (isNegative) return -absResult;
+ return absResult;
+ }
+
+ /**
+ * Return the negative value of this integer.
+ *
+ * The result of negating an integer always has the opposite sign, except
+ * for zero, which is its own negation.
+ */
+ _BigIntImpl operator -() {
+ if (_used == 0) return this;
+ return new _BigIntImpl._(!_isNegative, _used, _digits);
+ }
+
+ /**
+ * Returns the absolute value of this integer.
+ *
+ * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
+ */
+ _BigIntImpl abs() => _isNegative ? -this : this;
+
+ /// Returns this << n *_DIGIT_BITS.
+ _BigIntImpl _dlShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used + n;
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ for (int i = used - 1; i >= 0; i--) {
+ resultDigits[i + n] = digits[i];
+ }
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ /// Same as [_dlShift] but works on the decomposed big integers.
+ ///
+ /// Returns `resultUsed`.
+ ///
+ /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`.
+ static int _dlShiftDigits(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ if (xUsed == 0) {
+ return 0;
+ }
+ if (n == 0 && identical(resultDigits, xDigits)) {
+ return xUsed;
+ }
+ final resultUsed = xUsed + n;
+ for (int i = xUsed - 1; i >= 0; i--) {
+ resultDigits[i + n] = xDigits[i];
+ }
+ for (int i = n - 1; i >= 0; i--) {
+ resultDigits[i] = 0;
+ }
+ return resultUsed;
+ }
+
+ /// Returns `this >> n*_DIGIT_BITS`.
+ _BigIntImpl _drShift(int n) {
+ final used = _used;
+ if (used == 0) {
+ return zero;
+ }
+ final resultUsed = used - n;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ for (var i = n; i < used; i++) {
+ resultDigits[i - n] = digits[i];
+ }
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ for (var i = 0; i < n; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Shifts the digits of [xDigits] into the right place in [resultDigits].
+ ///
+ /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)`
+ /// where `ds = ceil(n / _DIGIT_BITS)`
+ ///
+ /// Does *not* clear digits below ds.
+ static void _lsh(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << carryBitShift) - 1;
+ var carry = 0;
+ for (int i = xUsed - 1; i >= 0; i--) {
+ final digit = xDigits[i];
+ resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry;
+ carry = (digit & bitMask) << bitShift;
+ }
+ resultDigits[digitShift] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the left by [shiftAmount].
+ *
+ * Shifting to the left makes the number larger, effectively multiplying
+ * the number by `pow(2, shiftIndex)`.
+ *
+ * There is no limit on the size of the result. It may be relevant to
+ * limit intermediate values by using the "and" operator with a suitable
+ * mask.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator <<(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+ }
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _dlShift(digitShift);
+ }
+ var resultUsed = _used + digitShift + 1;
+ var resultDigits = new Uint16List(resultUsed);
+ _lsh(_digits, _used, shiftAmount, resultDigits);
+ return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ }
+
+ // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n.
+ // Returns resultUsed.
+ static int _lShiftDigits(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ if (bitShift == 0) {
+ return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits);
+ }
+ var resultUsed = xUsed + digitsShift + 1;
+ _lsh(xDigits, xUsed, n, resultDigits);
+ var i = digitsShift;
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ if (resultDigits[resultUsed - 1] == 0) {
+ resultUsed--; // Clamp result.
+ }
+ return resultUsed;
+ }
+
+ // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
+ static void _rsh(
+ Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
+ final digitsShift = n ~/ _digitBits;
+ final bitShift = n % _digitBits;
+ final carryBitShift = _digitBits - bitShift;
+ final bitMask = (1 << bitShift) - 1;
+ var carry = xDigits[digitsShift] >> bitShift;
+ final last = xUsed - digitsShift - 1;
+ for (var i = 0; i < last; i++) {
+ final digit = xDigits[i + digitsShift + 1];
+ resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry;
+ carry = digit >> bitShift;
+ }
+ resultDigits[last] = carry;
+ }
+
+ /**
+ * Shift the bits of this integer to the right by [shiftAmount].
+ *
+ * Shifting to the right makes the number smaller and drops the least
+ * significant bits, effectively doing an integer division by
+ *`pow(2, shiftIndex)`.
+ *
+ * It is an error if [shiftAmount] is negative.
+ */
+ _BigIntImpl operator >>(int shiftAmount) {
+ if (shiftAmount < 0) {
+ throw new ArgumentError("shift-amount must be posititve $shiftAmount");
+ }
+ final digitShift = shiftAmount ~/ _digitBits;
+ final bitShift = shiftAmount % _digitBits;
+ if (bitShift == 0) {
+ return _drShift(digitShift);
+ }
+ final used = _used;
+ final resultUsed = used - digitShift;
+ if (resultUsed <= 0) {
+ return _isNegative ? _minusOne : zero;
+ }
+ final digits = _digits;
+ final resultDigits = new Uint16List(resultUsed);
+ _rsh(digits, used, shiftAmount, resultDigits);
+ final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
+ if (_isNegative) {
+ // Round down if any bit was shifted out.
+ if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) {
+ return result - one;
+ }
+ for (var i = 0; i < digitShift; i++) {
+ if (digits[i] != 0) {
+ return result - one;
+ }
+ }
+ }
+ return result;
+ }
+
+ /// Compares this to [other] taking the absolute value of both operands.
+ ///
+ /// Returns 0 if abs(this) == abs(other); a positive number if
+ /// abs(this) > abs(other); and a negative number if abs(this) < abs(other).
+ int _absCompare(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ return _compareDigits(_digits, _used, other._digits, other._used);
+ }
+
+ /**
+ * Compares this to `other`.
+ *
+ * Returns a negative number if `this` is less than `other`, zero if they are
+ * equal, and a positive number if `this` is greater than `other`.
+ */
+ int compareTo(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ var result = _absCompare(other);
+ // Use 0 - result to avoid negative zero in JavaScript.
+ return _isNegative ? 0 - result : result;
+ }
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`.
+ ///
+ /// Returns 0 if equal; a positive number if larger;
+ /// and a negative number if smaller.
+ static int _compareDigits(
+ Uint16List digits, int used, Uint16List otherDigits, int otherUsed) {
+ var result = used - otherUsed;
+ if (result == 0) {
+ for (int i = used - 1; i >= 0; i--) {
+ result = digits[i] - otherDigits[i];
+ if (result != 0) return result;
+ }
+ }
+ return result;
+ }
+
+ // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1].
+ // used >= otherUsed > 0.
+ static void _absAdd(Uint16List digits, int used, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] + otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ carry >>= _digitBits;
+ }
+ resultDigits[used] = carry;
+ }
+
+ // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1].
+ // used >= otherUsed > 0.
+ static void _absSub(Uint16List digits, int used, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ assert(used >= otherUsed && otherUsed > 0);
+
+ var carry = 0;
+ for (var i = 0; i < otherUsed; i++) {
+ carry += digits[i] - otherDigits[i];
+ resultDigits[i] = carry & _digitMask;
+ // Dart2js only supports unsigned shifts.
+ // Since the carry can only be -1 or 0 use this hack.
+ carry = 0 - ((carry >> _digitBits) & 1);
+ }
+ for (var i = otherUsed; i < used; i++) {
+ carry += digits[i];
+ resultDigits[i] = carry & _digitMask;
+ // Dart2js only supports unsigned shifts.
+ // Since the carry can only be -1 or 0 use this hack.
+ carry = 0 - ((carry >> _digitBits) & 1);
+ }
+ }
+
+ /// Returns `abs(this) + abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ if (used < otherUsed) {
+ return other._absAddSetSign(this, isNegative);
+ }
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultUsed = used + 1;
+ var resultDigits = new Uint16List(resultUsed);
+ _absAdd(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) - abs(other)` with sign set according to [isNegative].
+ ///
+ /// Requirement: `abs(this) >= abs(other)`.
+ _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) {
+ assert(_absCompare(other) >= 0);
+ var used = _used;
+ if (used == 0) {
+ assert(!isNegative);
+ return zero;
+ }
+ var otherUsed = other._used;
+ if (otherUsed == 0) {
+ return _isNegative == isNegative ? this : -this;
+ }
+ var resultDigits = new Uint16List(used);
+ _absSub(_digits, used, other._digits, otherUsed, resultDigits);
+ return new _BigIntImpl._(isNegative, used, resultDigits);
+ }
+
+ /// Returns `abs(this) & abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _min(_used, other._used);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ for (var i = 0; i < resultUsed; i++) {
+ resultDigits[i] = digits[i] & otherDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) {
+ var resultUsed = _used;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var m = _min(resultUsed, other._used);
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] & ~otherDigits[i];
+ }
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = digits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) | abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] | otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative].
+ _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) {
+ var used = _used;
+ var otherUsed = other._used;
+ var resultUsed = _max(used, otherUsed);
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var l, m;
+ if (used < otherUsed) {
+ l = other;
+ m = used;
+ } else {
+ l = this;
+ m = otherUsed;
+ }
+ for (var i = 0; i < m; i++) {
+ resultDigits[i] = digits[i] ^ otherDigits[i];
+ }
+ var lDigits = l._digits;
+ for (var i = m; i < resultUsed; i++) {
+ resultDigits[i] = lDigits[i];
+ }
+ return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
+ }
+
+ /**
+ * Bit-wise and operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with only the bits set that are set in
+ * both `this` and [other]
+ *
+ * Of both operands are negative, the result is negative, otherwise
+ * the result is non-negative.
+ */
+ _BigIntImpl operator &(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) & (-other) == ~(this-1) & ~(other-1)
+ // == ~((this-1) | (other-1))
+ // == -(((this-1) | (other-1)) + 1)
+ _BigIntImpl this1 = _absSubSetSign(one, true);
+ _BigIntImpl other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and other are negative.
+ return this1._absOrSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absAndSetSign(other, false);
+ }
+ // _isNegative != other._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // & is symmetric.
+ p = this;
+ n = other;
+ }
+ // p & (-n) == p & ~(n-1) == p &~ (n-1)
+ var n1 = n._absSubSetSign(one, false);
+ return p._absAndNotSetSign(n1, false);
+ }
+
+ /**
+ * Bit-wise or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in either
+ * of `this` and [other]
+ *
+ * If both operands are non-negative, the result is non-negative,
+ * otherwise the result us negative.
+ */
+ _BigIntImpl operator |(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) | (-other) == ~(this-1) | ~(other-1)
+ // == ~((this-1) & (other-1))
+ // == -(((this-1) & (other-1)) + 1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ // Result cannot be zero if this and a are negative.
+ return this1._absAndSetSign(other1, true)._absAddSetSign(one, true);
+ }
+ return _absOrSetSign(other, false);
+ }
+ // _neg != a._neg
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // | is symmetric.
+ p = this;
+ n = other;
+ }
+ // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * Bit-wise exclusive-or operator.
+ *
+ * Treating both `this` and [other] as sufficiently large two's component
+ * integers, the result is a number with the bits set that are set in one,
+ * but not both, of `this` and [other]
+ *
+ * If the operands have the same sign, the result is non-negative,
+ * otherwise the result is negative.
+ */
+ _BigIntImpl operator ^(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isNegative == other._isNegative) {
+ if (_isNegative) {
+ // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1)
+ var this1 = _absSubSetSign(one, true);
+ var other1 = other._absSubSetSign(one, true);
+ return this1._absXorSetSign(other1, false);
+ }
+ return _absXorSetSign(other, false);
+ }
+ // _isNegative != a._isNegative
+ var p, n;
+ if (_isNegative) {
+ p = other;
+ n = this;
+ } else {
+ // ^ is symmetric.
+ p = this;
+ n = other;
+ }
+ // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
+ var n1 = n._absSubSetSign(one, true);
+ // Result cannot be zero if only one of this or a is negative.
+ return p._absXorSetSign(n1, true)._absAddSetSign(one, true);
+ }
+
+ /**
+ * The bit-wise negate operator.
+ *
+ * Treating `this` as a sufficiently large two's component integer,
+ * the result is a number with the opposite bits set.
+ *
+ * This maps any integer `x` to `-x - 1`.
+ */
+ _BigIntImpl operator ~() {
+ if (_isNegative) {
+ // ~(-this) == ~(~(this-1)) == this-1
+ return _absSubSetSign(one, false);
+ }
+ // ~this == -this-1 == -(this+1)
+ // Result cannot be zero if this is positive.
+ return _absAddSetSign(one, true);
+ }
+
+ /// Addition operator.
+ _BigIntImpl operator +(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var isNegative = _isNegative;
+ if (isNegative == other._isNegative) {
+ // this + other == this + other
+ // (-this) + (-other) == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this + (-other) == this - other == -(this - other)
+ // (-this) + other == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Subtraction operator.
+ _BigIntImpl operator -(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var isNegative = _isNegative;
+ if (isNegative != other._isNegative) {
+ // this - (-other) == this + other
+ // (-this) - other == -(this + other)
+ return _absAddSetSign(other, isNegative);
+ }
+ // this - other == this - a == -(this - other)
+ // (-this) - (-other) == other - this == -(this - other)
+ if (_absCompare(other) >= 0) {
+ return _absSubSetSign(other, isNegative);
+ }
+ return other._absSubSetSign(this, !isNegative);
+ }
+
+ /// Multiplies [x] with [multiplicandDigits] and adds the result to
+ /// [accumulatorDigits].
+ ///
+ /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the
+ /// multiplicand digits.
+ ///
+ /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator
+ /// digits.
+ ///
+ /// Adds the result of the multiplicand-digits * [x] to the accumulator.
+ ///
+ /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`.
+ static void _mulAdd(int x, Uint16List multiplicandDigits, int i,
+ Uint16List accumulatorDigits, int j, int n) {
+ if (x == 0) {
+ // No-op if x is 0.
+ return;
+ }
+ int c = 0;
+ while (--n >= 0) {
+ int product = x * multiplicandDigits[i++];
+ int combined = product + accumulatorDigits[j] + c;
+ accumulatorDigits[j++] = combined & _digitMask;
+ // Note that this works with 53 bits, as the division will not lose
+ // bits.
+ c = combined ~/ _digitBase;
+ }
+ while (c != 0) {
+ int l = accumulatorDigits[j] + c;
+ accumulatorDigits[j++] = l & _digitMask;
+ c = l ~/ _digitBase;
+ }
+ }
+
+ /// Multiplication operator.
+ _BigIntImpl operator *(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ var used = _used;
+ var otherUsed = other._used;
+ if (used == 0 || otherUsed == 0) {
+ return zero;
+ }
+ var resultUsed = used + otherUsed;
+ var digits = _digits;
+ var otherDigits = other._digits;
+ var resultDigits = new Uint16List(resultUsed);
+ var i = 0;
+ while (i < otherUsed) {
+ _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used);
+ i++;
+ }
+ return new _BigIntImpl._(
+ _isNegative != other._isNegative, resultUsed, resultDigits);
+ }
+
+ // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1].
+ // Return resultUsed = xUsed + otherUsed.
+ static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits,
+ int otherUsed, Uint16List resultDigits) {
+ var resultUsed = xUsed + otherUsed;
+ var i = resultUsed;
+ assert(resultDigits.length >= i);
+ while (--i >= 0) {
+ resultDigits[i] = 0;
+ }
+ i = 0;
+ while (i < otherUsed) {
+ _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed);
+ i++;
+ }
+ return resultUsed;
+ }
+
+ /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`.
+ static int _estimateQuotientDigit(
+ int topDigitDivisor, Uint16List digits, int i) {
+ if (digits[i] == topDigitDivisor) return _digitMask;
+ var quotientDigit =
+ (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor;
+ if (quotientDigit > _digitMask) return _digitMask;
+ return quotientDigit;
+ }
+
+ /// Returns `trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _div(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return zero;
+ }
+ _divRem(other);
+ // Return quotient, i.e.
+ // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
+ var lastQuo_used = _lastQuoRemUsed - _lastRemUsed;
+ var quo_digits = _cloneDigits(
+ _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used);
+ var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits);
+ if ((_isNegative != other._isNegative) && (quo._used > 0)) {
+ quo = -quo;
+ }
+ return quo;
+ }
+
+ /// Returns `this - other * trunc(this / other)`, with `other != 0`.
+ _BigIntImpl _rem(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ assert(other._used > 0);
+ if (_used < other._used) {
+ return this;
+ }
+ _divRem(other);
+ // Return remainder, i.e.
+ // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
+ var remDigits =
+ _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed);
+ var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits);
+ if (_lastRem_nsh > 0) {
+ rem = rem >> _lastRem_nsh; // Denormalize remainder.
+ }
+ if (_isNegative && (rem._used > 0)) {
+ rem = -rem;
+ }
+ return rem;
+ }
+
+ /// Computes this ~/ other and this.remainder(other).
+ ///
+ /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and
+ /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the
+ /// quotient and the remainder.
+ ///
+ /// Caches the input to avoid doing the work again when users write
+ /// `a ~/ b` followed by a `a % b`.
+ void _divRem(_BigIntImpl other) {
+ // Check if result is already cached.
+ if ((this._used == _lastDividendUsed) &&
+ (other._used == _lastDivisorUsed) &&
+ identical(this._digits, _lastDividendDigits) &&
+ identical(other._digits, _lastDivisorDigits)) {
+ return;
+ }
+ assert(_used >= other._used);
+
+ var nsh = _digitBits - other._digits[other._used - 1].bitLength;
+ // Concatenated positive quotient and normalized positive remainder.
+ // The resultDigits can have at most one more digit than the dividend.
+ Uint16List resultDigits;
+ int resultUsed;
+ // Normalized positive divisor.
+ // The normalized divisor has the most-significant bit of it's most
+ // significant digit set.
+ // This makes estimating the quotient easier.
+ Uint16List yDigits;
+ int yUsed;
+ if (nsh > 0) {
+ yDigits = new Uint16List(other._used + 5);
+ yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits);
+ resultDigits = new Uint16List(_used + 5);
+ resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits);
+ } else {
+ yDigits = other._digits;
+ yUsed = other._used;
+ resultDigits = _cloneDigits(_digits, 0, _used, _used + 2);
+ resultUsed = _used;
+ }
+ var topDigitDivisor = yDigits[yUsed - 1];
+ var i = resultUsed;
+ var j = i - yUsed;
+ // tmpDigits is a temporary array of i (resultUsed) digits.
+ var tmpDigits = new Uint16List(i);
+ var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
+ // Explicit first division step in case normalized dividend is larger or
+ // equal to shifted normalized divisor.
+ if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
+ assert(i == resultUsed);
+ resultDigits[resultUsed++] = 1; // Quotient = 1.
+ // Subtract divisor from remainder.
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ } else {
+ // Account for possible carry in _mulAdd step.
+ resultDigits[resultUsed++] = 0;
+ }
+
+ // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
+ var nyDigits = new Uint16List(yUsed + 2);
+ nyDigits[yUsed] = 1;
+ _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits);
+ // nyDigits is read-only and has yUsed digits (possibly including several
+ // leading zeros).
+ // resultDigits is modified during iteration.
+ // resultDigits[0..yUsed-1] is the current remainder.
+ // resultDigits[yUsed..resultUsed-1] is the current quotient.
+ --i;
+
+ while (j > 0) {
+ var estimatedQuotientDigit =
+ _estimateQuotientDigit(topDigitDivisor, resultDigits, i);
+ j--;
+ _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed);
+ if (resultDigits[i] < estimatedQuotientDigit) {
+ // Reusing the already existing tmpDigits array.
+ var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ while (resultDigits[i] < --estimatedQuotientDigit) {
+ _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
+ }
+ }
+ i--;
+ }
+ // Cache result.
+ _lastDividendDigits = _digits;
+ _lastDividendUsed = _used;
+ _lastDivisorDigits = other._digits;
+ _lastDivisorUsed = other._used;
+ _lastQuoRemDigits = resultDigits;
+ _lastQuoRemUsed = resultUsed;
+ _lastRemUsed = yUsed;
+ _lastRem_nsh = nsh;
+ }
+
+ int get hashCode {
+ // This is the [Jenkins hash function][1] but using masking to keep
+ // values in SMI range.
+ //
+ // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
+
+ int combine(int hash, int value) {
+ hash = 0x1fffffff & (hash + value);
+ hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
+ return hash ^ (hash >> 6);
+ }
+
+ int finish(int hash) {
+ hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
+ hash = hash ^ (hash >> 11);
+ return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
+ }
+
+ if (_isZero) return 6707; // Just a random number.
+ var hash = _isNegative ? 83585 : 429689; // Also random.
+ for (int i = 0; i < _used; i++) {
+ hash = combine(hash, _digits[i]);
+ }
+ return finish(hash);
+ }
+
+ /**
+ * Test whether this value is numerically equal to `other`.
+ *
+ * If [other] is a [_BigIntImpl] returns whether the two operands have the same
+ * value.
+ *
+ * Returns false if `other` is not a [_BigIntImpl].
+ */
+ bool operator ==(Object other) =>
+ other is _BigIntImpl && compareTo(other) == 0;
+
+ /**
+ * Returns the minimum number of bits required to store this big integer.
+ *
+ * The number of bits excludes the sign bit, which gives the natural length
+ * for non-negative (unsigned) values. Negative values are complemented to
+ * return the bit position of the first bit that differs from the sign bit.
+ *
+ * To find the number of bits needed to store the value as a signed value,
+ * add one, i.e. use `x.bitLength + 1`.
+ *
+ * ```
+ * x.bitLength == (-x-1).bitLength
+ *
+ * new BigInt.from(3).bitLength == 2; // 00000011
+ * new BigInt.from(2).bitLength == 2; // 00000010
+ * new BigInt.from(1).bitLength == 1; // 00000001
+ * new BigInt.from(0).bitLength == 0; // 00000000
+ * new BigInt.from(-1).bitLength == 0; // 11111111
+ * new BigInt.from(-2).bitLength == 1; // 11111110
+ * new BigInt.from(-3).bitLength == 2; // 11111101
+ * new BigInt.from(-4).bitLength == 2; // 11111100
+ * ```
+ */
+ int get bitLength {
+ if (_used == 0) return 0;
+ if (_isNegative) return (~this).bitLength;
+ return _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ }
+
+ /**
+ * Truncating division operator.
+ *
+ * Performs a truncating integer division, where the remainder is discarded.
+ *
+ * The remainder can be computed using the [remainder] method.
+ *
+ * Examples:
+ * ```
+ * var seven = new BigInt.from(7);
+ * var three = new BigInt.from(3);
+ * seven ~/ three; // => 2
+ * (-seven) ~/ three; // => -2
+ * seven ~/ -three; // => -2
+ * seven.remainder(three); // => 1
+ * (-seven).remainder(three); // => -1
+ * seven.remainder(-three); // => 1
+ * ```
+ */
+ _BigIntImpl operator ~/(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _div(other);
+ }
+
+ /**
+ * Returns the remainder of the truncating division of `this` by [other].
+ *
+ * The result `r` of this operation satisfies:
+ * `this == (this ~/ other) * other + r`.
+ * As a consequence the remainder `r` has the same sign as the divider `this`.
+ */
+ _BigIntImpl remainder(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ return _rem(other);
+ }
+
+ /// Division operator.
+ double operator /(BigInt other) => this.toDouble() / other.toDouble();
+
+ /** Relational less than operator. */
+ bool operator <(BigInt other) => compareTo(other) < 0;
+
+ /** Relational less than or equal operator. */
+ bool operator <=(BigInt other) => compareTo(other) <= 0;
+
+ /** Relational greater than operator. */
+ bool operator >(BigInt other) => compareTo(other) > 0;
+
+ /** Relational greater than or equal operator. */
+ bool operator >=(BigInt other) => compareTo(other) >= 0;
+
+ /**
+ * Euclidean modulo operator.
+ *
+ * Returns the remainder of the Euclidean division. The Euclidean division of
+ * two integers `a` and `b` yields two integers `q` and `r` such that
+ * `a == b * q + r` and `0 <= r < b.abs()`.
+ *
+ * The sign of the returned value `r` is always positive.
+ *
+ * See [remainder] for the remainder of the truncating division.
+ */
+ _BigIntImpl operator %(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (other._used == 0) {
+ throw const IntegerDivisionByZeroException();
+ }
+ var result = _rem(other);
+ if (result._isNegative) {
+ if (other._isNegative) {
+ result = result - other;
+ } else {
+ result = result + other;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns the sign of this big integer.
+ *
+ * Returns 0 for zero, -1 for values less than zero and
+ * +1 for values greater than zero.
+ */
+ int get sign {
+ if (_used == 0) return 0;
+ return _isNegative ? -1 : 1;
+ }
+
+ /// Whether this big integer is even.
+ bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
+
+ /// Whether this big integer is odd.
+ bool get isOdd => !isEven;
+
+ /// Whether this number is negative.
+ bool get isNegative => _isNegative;
+
+ _BigIntImpl pow(int exponent) {
+ if (exponent < 0) {
+ throw new ArgumentError("Exponent must not be negative: $exponent");
+ }
+ if (exponent == 0) return one;
+
+ // Exponentiation by squaring.
+ var result = one;
+ var base = this;
+ while (exponent != 0) {
+ if ((exponent & 1) == 1) {
+ result *= base;
+ }
+ exponent >>= 1;
+ // Skip unnecessary operation.
+ if (exponent != 0) {
+ base *= base;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns this integer to the power of [exponent] modulo [modulus].
+ *
+ * The [exponent] must be non-negative and [modulus] must be
+ * positive.
+ */
+ _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) {
+ _BigIntImpl exponent = bigExponent;
+ _BigIntImpl modulus = bigModulus;
+ if (exponent._isNegative) {
+ throw new ArgumentError("exponent must be positive: $exponent");
+ }
+ if (modulus <= zero) {
+ throw new ArgumentError("modulus must be strictly positive: $modulus");
+ }
+ if (exponent._isZero) return one;
+
+ final modulusUsed = modulus._used;
+ final modulusUsed2p4 = 2 * modulusUsed + 4;
+ final exponentBitlen = exponent.bitLength;
+ if (exponentBitlen <= 0) return one;
+ _BigIntReduction z = new _BigIntClassic(modulus);
+ var resultDigits = new Uint16List(modulusUsed2p4);
+ var result2Digits = new Uint16List(modulusUsed2p4);
+ var gDigits = new Uint16List(modulusUsed);
+ var gUsed = z.convert(this, gDigits);
+ // Initialize result with g.
+ // Copy leading zero if any.
+ for (int j = gUsed - 1; j >= 0; j--) {
+ resultDigits[j] = gDigits[j];
+ }
+ var resultUsed = gUsed;
+ var result2Used;
+ for (int i = exponentBitlen - 2; i >= 0; i--) {
+ result2Used = z.sqr(resultDigits, resultUsed, result2Digits);
+ if (!(exponent & (one << i))._isZero) {
+ resultUsed =
+ z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits);
+ } else {
+ // Swap result and result2.
+ var tmpDigits = resultDigits;
+ var tmpUsed = resultUsed;
+ resultDigits = result2Digits;
+ resultUsed = result2Used;
+ result2Digits = tmpDigits;
+ result2Used = tmpUsed;
+ }
+ }
+ return z.revert(resultDigits, resultUsed);
+ }
+
+ // If inv is false, returns gcd(x, y).
+ // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
+ // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
+ static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) {
+ var xDigits = x._digits;
+ var yDigits = y._digits;
+ var xUsed = x._used;
+ var yUsed = y._used;
+ var maxUsed = xUsed > yUsed ? xUsed : yUsed;
+ var unshiftedMaxUsed = maxUsed; // Keep
+ xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed);
+ yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed);
+ int shiftAmount = 0;
+ if (inv) {
+ if ((yUsed == 1) && (yDigits[0] == 1)) return one;
+ if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) {
+ throw new Exception("Not coprime");
+ }
+ } else {
+ if (x._isZero) {
+ throw new ArgumentError.value(0, "this", "must not be zero");
+ }
+ if (y._isZero) {
+ throw new ArgumentError.value(0, "other", "must not be zero");
+ }
+ if (((xUsed == 1) && (xDigits[0] == 1)) ||
+ ((yUsed == 1) && (yDigits[0] == 1))) return one;
+ while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) {
+ _rsh(xDigits, xUsed, 1, xDigits);
+ _rsh(yDigits, yUsed, 1, yDigits);
+ shiftAmount++;
+ }
+ if (shiftAmount >= _digitBits) {
+ var digitShiftAmount = shiftAmount ~/ _digitBits;
+ xUsed -= digitShiftAmount;
+ yUsed -= digitShiftAmount;
+ maxUsed -= digitShiftAmount;
+ }
+ if ((yDigits[0] & 1) == 1) {
+ // Swap x and y.
+ var tmpDigits = xDigits;
+ var tmpUsed = xUsed;
+ xDigits = yDigits;
+ xUsed = yUsed;
+ yDigits = tmpDigits;
+ yUsed = tmpUsed;
+ }
+ }
+ var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed);
+ var vDigits =
+ _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh.
+ final bool ac = (xDigits[0] & 1) == 0;
+
+ // Variables a, b, c, and d require one more digit.
+ final abcdUsed = maxUsed + 1;
+ final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd.
+ var aDigits, bDigits, cDigits, dDigits;
+ bool aIsNegative, bIsNegative, cIsNegative, dIsNegative;
+ if (ac) {
+ aDigits = new Uint16List(abcdLen);
+ aIsNegative = false;
+ aDigits[0] = 1;
+ cDigits = new Uint16List(abcdLen);
+ cIsNegative = false;
+ }
+ bDigits = new Uint16List(abcdLen);
+ bIsNegative = false;
+ dDigits = new Uint16List(abcdLen);
+ dIsNegative = false;
+ dDigits[0] = 1;
+
+ while (true) {
+ while ((uDigits[0] & 1) == 0) {
+ _rsh(uDigits, maxUsed, 1, uDigits);
+ if (ac) {
+ if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) {
+ if (aIsNegative) {
+ if ((aDigits[maxUsed] != 0) ||
+ (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) {
+ _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ } else {
+ _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits);
+ aIsNegative = false;
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
+ }
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(aDigits, abcdUsed, 1, aDigits);
+ } else if ((bDigits[0] & 1) == 1) {
+ if (bIsNegative) {
+ _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else if ((bDigits[maxUsed] != 0) ||
+ (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
+ } else {
+ _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
+ bIsNegative = true;
+ }
+ }
+ _rsh(bDigits, abcdUsed, 1, bDigits);
+ }
+ while ((vDigits[0] & 1) == 0) {
+ _rsh(vDigits, maxUsed, 1, vDigits);
+ if (ac) {
+ if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) {
+ if (cIsNegative) {
+ if ((cDigits[maxUsed] != 0) ||
+ (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) {
+ _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ } else {
+ _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits);
+ cIsNegative = false;
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
+ }
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(cDigits, abcdUsed, 1, cDigits);
+ } else if ((dDigits[0] & 1) == 1) {
+ if (dIsNegative) {
+ _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = true;
+ }
+ }
+ _rsh(dDigits, abcdUsed, 1, dDigits);
+ }
+ if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) {
+ _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits);
+ if (ac) {
+ if (aIsNegative == cIsNegative) {
+ var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed);
+ if (a_cmp_c > 0) {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ } else {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits);
+ aIsNegative = !aIsNegative && (a_cmp_c != 0);
+ }
+ } else {
+ _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
+ }
+ }
+ if (bIsNegative == dIsNegative) {
+ var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed);
+ if (b_cmp_d > 0) {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ } else {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits);
+ bIsNegative = !bIsNegative && (b_cmp_d != 0);
+ }
+ } else {
+ _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
+ }
+ } else {
+ _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits);
+ if (ac) {
+ if (cIsNegative == aIsNegative) {
+ var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed);
+ if (c_cmp_a > 0) {
+ _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ } else {
+ _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits);
+ cIsNegative = !cIsNegative && (c_cmp_a != 0);
+ }
+ } else {
+ _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
+ }
+ }
+ if (dIsNegative == bIsNegative) {
+ var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed);
+ if (d_cmp_b > 0) {
+ _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ } else {
+ _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits);
+ dIsNegative = !dIsNegative && (d_cmp_b != 0);
+ }
+ } else {
+ _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
+ }
+ }
+ // Exit loop if u == 0.
+ var i = maxUsed;
+ while ((i > 0) && (uDigits[i - 1] == 0)) --i;
+ if (i == 0) break;
+ }
+ if (!inv) {
+ if (shiftAmount > 0) {
+ maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits);
+ }
+ return new _BigIntImpl._(false, maxUsed, vDigits);
+ }
+ // No inverse if v != 1.
+ var i = maxUsed - 1;
+ while ((i > 0) && (vDigits[i] == 0)) --i;
+ if ((i != 0) || (vDigits[0] != 1)) {
+ throw new Exception("Not coprime");
+ }
+
+ if (dIsNegative) {
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = false;
+ }
+ } else {
+ _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
+ dIsNegative = false;
+ }
+ } else if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ if ((dDigits[maxUsed] != 0) ||
+ (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
+ _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
+ }
+ }
+ return new _BigIntImpl._(false, maxUsed, dDigits);
+ }
+
+ /**
+ * Returns the modular multiplicative inverse of this big integer
+ * modulo [modulus].
+ *
+ * The [modulus] must be positive.
+ *
+ * It is an error if no modular inverse exists.
+ */
+ // Returns 1/this % modulus, with modulus > 0.
+ _BigIntImpl modInverse(BigInt bigInt) {
+ _BigIntImpl modulus = bigInt;
+ if (modulus <= zero) {
+ throw new ArgumentError("Modulus must be strictly positive: $modulus");
+ }
+ if (modulus == one) return zero;
+ var tmp = this;
+ if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) {
+ tmp %= modulus;
+ }
+ return _binaryGcd(modulus, tmp, true);
+ }
+
+ /**
+ * Returns the greatest common divisor of this big integer and [other].
+ *
+ * If either number is non-zero, the result is the numerically greatest
+ * integer dividing both `this` and `other`.
+ *
+ * The greatest common divisor is independent of the order,
+ * so `x.gcd(y)` is always the same as `y.gcd(x)`.
+ *
+ * For any integer `x`, `x.gcd(x)` is `x.abs()`.
+ *
+ * If both `this` and `other` is zero, the result is also zero.
+ */
+ _BigIntImpl gcd(BigInt bigInt) {
+ _BigIntImpl other = bigInt;
+ if (_isZero) return other.abs();
+ if (other._isZero) return this.abs();
+ return _binaryGcd(this, other, false);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this big integer as a
+ * non-negative number (i.e. unsigned representation). The returned value has
+ * zeros in all bit positions higher than [width].
+ *
+ * ```
+ * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit quantity:
+ *
+ * ```
+ * q = (q + 1).toUnsigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `255` and then wrap around to `0`.
+ *
+ * If the input fits in [width] bits without truncation, the result is the
+ * same as the input. The minimum width needed to avoid truncation of `x` is
+ * given by `x.bitLength`, i.e.
+ *
+ * ```
+ * x == x.toUnsigned(x.bitLength);
+ * ```
+ */
+ _BigIntImpl toUnsigned(int width) {
+ return this & ((one << width) - one);
+ }
+
+ /**
+ * Returns the least significant [width] bits of this integer, extending the
+ * highest retained bit to the sign. This is the same as truncating the value
+ * to fit in [width] bits using an signed 2-s complement representation. The
+ * returned value has the same bit value in all positions higher than [width].
+ *
+ * ```
+ * var big15 = new BigInt.from(15);
+ * var big16 = new BigInt.from(16);
+ * var big239 = new BigInt.from(239);
+ * V--sign bit-V
+ * big16.toSigned(5) == -big16 // 00010000 -> 11110000
+ * big239.toSigned(5) == big15 // 11101111 -> 00001111
+ * ^ ^
+ * ```
+ *
+ * This operation can be used to simulate arithmetic from low level languages.
+ * For example, to increment an 8 bit signed quantity:
+ *
+ * ```
+ * q = (q + 1).toSigned(8);
+ * ```
+ *
+ * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
+ * `127`.
+ *
+ * If the input value fits in [width] bits without truncation, the result is
+ * the same as the input. The minimum width needed to avoid truncation of `x`
+ * is `x.bitLength + 1`, i.e.
+ *
+ * ```
+ * x == x.toSigned(x.bitLength + 1);
+ * ```
+ */
+ _BigIntImpl toSigned(int width) {
+ // The value of binary number weights each bit by a power of two. The
+ // twos-complement value weights the sign bit negatively. We compute the
+ // value of the negative weighting by isolating the sign bit with the
+ // correct power of two weighting and subtracting it from the value of the
+ // lower bits.
+ var signMask = one << (width - 1);
+ return (this & (signMask - one)) - (this & signMask);
+ }
+
+ // TODO(floitsch): implement `isValidInt`.
+ // Remove the comment in [BigInt.isValidInt] when done.
+ bool get isValidInt => true;
+
+ // TODO(floitsch): implement the clamping. It behaves differently on dart2js
+ // and the VM.
+ // Remove the comment in [BigInt.isValidInt] when done.
+ int toInt() {
+ var result = 0;
+ for (int i = _used - 1; i >= 0; i--) {
+ result = result * _digitBase + _digits[i];
+ }
+ return _isNegative ? -result : result;
+ }
+
+ /**
+ * Returns this [_BigIntImpl] as a [double].
+ *
+ * If the number is not representable as a [double], an
+ * approximation is returned. For numerically large integers, the
+ * approximation may be infinite.
+ */
+ double toDouble() {
+ const int exponentBias = 1075;
+ // There are 11 bits for the exponent.
+ // 2047 (all bits set to 1) is reserved for infinity and NaN.
+ // When storing the exponent in the 11 bits, it is biased by exponentBias
+ // to support negative exponents.
+ const int maxDoubleExponent = 2046 - exponentBias;
+ if (_isZero) return 0.0;
+
+ // We fill the 53 bits little-endian.
+ var resultBits = new Uint8List(8);
+
+ var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
+ if (length - 53 > maxDoubleExponent) return double.INFINITY;
+
+ // The most significant bit is for the sign.
+ if (_isNegative) resultBits[7] = 0x80;
+
+ // Write the exponent into bits 1..12:
+ var biasedExponent = length - 53 + exponentBias;
+ resultBits[6] = (biasedExponent & 0xF) << 4;
+ resultBits[7] |= biasedExponent >> 4;
+
+ int cachedBits = 0;
+ int cachedBitsLength = 0;
+ int digitIndex = _used - 1;
+ int readBits(int n) {
+ // Ensure that we have enough bits in [cachedBits].
+ while (cachedBitsLength < n) {
+ int nextDigit;
+ int nextDigitLength = _digitBits; // May get updated.
+ if (digitIndex < 0) {
+ nextDigit = 0;
+ digitIndex--;
+ } else {
+ nextDigit = _digits[digitIndex];
+ if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength;
+ digitIndex--;
+ }
+ cachedBits = (cachedBits << nextDigitLength) + nextDigit;
+ cachedBitsLength += nextDigitLength;
+ }
+ // Read the top [n] bits.
+ var result = cachedBits >> (cachedBitsLength - n);
+ // Remove the bits from the cache.
+ cachedBits -= result << (cachedBitsLength - n);
+ cachedBitsLength -= n;
+ return result;
+ }
+
+ // The first leading 1 bit is implicit in the double-representation and can
+ // be discarded.
+ var leadingBits = readBits(5) & 0xF;
+ resultBits[6] |= leadingBits;
+
+ for (int i = 5; i >= 0; i--) {
+ // Get the remaining 48 bits.
+ resultBits[i] = readBits(8);
+ }
+
+ void roundUp() {
+ // Simply consists of adding 1 to the whole 64 bit "number".
+ // It will update the exponent, if necessary.
+ // It might even round up to infinity (which is what we want).
+ var carry = 1;
+ for (int i = 0; i < 8; i++) {
+ if (carry == 0) break;
+ var sum = resultBits[i] + carry;
+ resultBits[i] = sum & 0xFF;
+ carry = sum >> 8;
+ }
+ }
+
+ if (readBits(1) == 1) {
+ if (resultBits[0].isOdd) {
+ // Rounds to even all the time.
+ roundUp();
+ } else {
+ // Round up, if there is at least one other digit that is not 0.
+ if (cachedBits != 0) {
+ // There is already one in the cachedBits.
+ roundUp();
+ } else {
+ for (int i = digitIndex; digitIndex >= 0; i--) {
+ if (_digits[i] != 0) {
+ roundUp();
+ break;
+ }
+ }
+ }
+ }
+ }
+ return resultBits.buffer.asByteData().getFloat64(0, Endian.little);
+ }
+
+ /**
+ * Returns a String-representation of this integer.
+ *
+ * The returned string is parsable by [parse].
+ * For any `_BigIntImpl` `i`, it is guaranteed that
+ * `i == _BigIntImpl.parse(i.toString())`.
+ */
+ String toString() {
+ if (_used == 0) return "0";
+ if (_used == 1) {
+ if (_isNegative) return (-_digits[0]).toString();
+ return _digits[0].toString();
+ }
+
+ // Generate in chunks of 4 digits.
+ // The chunks are in reversed order.
+ var decimalDigitChunks = <String>[];
+ var rest = isNegative ? -this : this;
+ while (rest._used > 1) {
+ var digits4 = rest.remainder(_bigInt10000).toString();
+ decimalDigitChunks.add(digits4);
+ if (digits4.length == 1) decimalDigitChunks.add("000");
+ if (digits4.length == 2) decimalDigitChunks.add("00");
+ if (digits4.length == 3) decimalDigitChunks.add("0");
+ rest = rest ~/ _bigInt10000;
+ }
+ decimalDigitChunks.add(rest._digits[0].toString());
+ if (_isNegative) decimalDigitChunks.add("-");
+ return decimalDigitChunks.reversed.join();
+ }
+
+ int _toRadixCodeUnit(int digit) {
+ const int _0 = 48;
+ const int _a = 97;
+ if (digit < 10) return _0 + digit;
+ return _a + digit - 10;
+ }
+
+ /**
+ * Converts [this] to a string representation in the given [radix].
+ *
+ * In the string representation, lower-case letters are used for digits above
+ * '9', with 'a' being 10 an 'z' being 35.
+ *
+ * The [radix] argument must be an integer in the range 2 to 36.
+ */
+ String toRadixString(int radix) {
+ if (radix > 36) throw new RangeError.range(radix, 2, 36);
+
+ if (_used == 0) return "0";
+
+ if (_used == 1) {
+ var digitString = _digits[0].toRadixString(radix);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ if (radix == 16) return _toHexString();
+
+ var base = new _BigIntImpl._fromInt(radix);
+ var reversedDigitCodeUnits = <int>[];
+ var rest = this.abs();
+ while (!rest._isZero) {
+ var digit = rest.remainder(base).toInt();
+ rest = rest ~/ base;
+ reversedDigitCodeUnits.add(_toRadixCodeUnit(digit));
+ }
+ var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed);
+ if (_isNegative) return "-" + digitString;
+ return digitString;
+ }
+
+ String _toHexString() {
+ var chars = <int>[];
+ for (int i = 0; i < _used - 1; i++) {
+ int chunk = _digits[i];
+ for (int j = 0; j < (_digitBits ~/ 4); j++) {
+ chars.add(_toRadixCodeUnit(chunk & 0xF));
+ chunk >>= 4;
+ }
+ }
+ var msbChunk = _digits[_used - 1];
+ while (msbChunk != 0) {
+ chars.add(_toRadixCodeUnit(msbChunk & 0xF));
+ msbChunk >>= 4;
+ }
+ if (_isNegative) {
+ const _dash = 45;
+ chars.add(_dash);
+ }
+ return new String.fromCharCodes(chars.reversed);
+ }
+}
+
+// Interface for modular reduction.
+abstract class _BigIntReduction {
+ // Return the number of digits used by r_digits.
+ int convert(_BigIntImpl x, Uint16List r_digits);
+ int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+ Uint16List resultDigits);
+ int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits);
+
+ // Return x reverted to _BigIntImpl.
+ _BigIntImpl revert(Uint16List xDigits, int xUsed);
+}
+
+// Modular reduction using "classic" algorithm.
+class _BigIntClassic implements _BigIntReduction {
+ final _BigIntImpl _modulus; // Modulus.
+ final _BigIntImpl _normalizedModulus; // Normalized _modulus.
+
+ _BigIntClassic(this._modulus)
+ : _normalizedModulus = _modulus <<
+ (_BigIntImpl._digitBits -
+ _modulus._digits[_modulus._used - 1].bitLength);
+
+ int convert(_BigIntImpl x, Uint16List resultDigits) {
+ var digits;
+ var used;
+ if (x._isNegative || x.compareTo(_modulus) >= 0) {
+ var remainder = x._rem(_modulus);
+ if (x._isNegative && !remainder._isNegative && remainder._used > 0) {
+ remainder = _modulus - remainder;
+ }
+ assert(!remainder._isNegative);
+ used = remainder._used;
+ digits = remainder._digits;
+ } else {
+ used = x._used;
+ digits = x._digits;
+ }
+ var i = used; // Copy leading zero if any.
+ while (--i >= 0) {
+ resultDigits[i] = digits[i];
+ }
+ return used;
+ }
+
+ _BigIntImpl revert(Uint16List xDigits, int xUsed) {
+ return new _BigIntImpl._(false, xUsed, xDigits);
+ }
+
+ int _reduce(Uint16List xDigits, int xUsed) {
+ if (xUsed < _modulus._used) {
+ return xUsed;
+ }
+ var reverted = revert(xDigits, xUsed);
+ var rem = reverted._rem(_normalizedModulus);
+ return convert(rem, xDigits);
+ }
+
+ int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) {
+ var b = new _BigIntImpl._(false, xUsed, xDigits);
+ var b2 = b * b;
+ for (int i = 0; i < b2._used; i++) {
+ resultDigits[i] = b2._digits[i];
+ }
+ for (int i = b2._used; i < 2 * xUsed; i++) {
+ resultDigits[i] = 0;
+ }
+ return _reduce(resultDigits, 2 * xUsed);
+ }
+
+ int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
+ Uint16List resultDigits) {
+ var resultUsed =
+ _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
+ return _reduce(resultDigits, resultUsed);
+ }
+}
diff --git a/sdk/lib/convert/codec.dart b/sdk/lib/convert/codec.dart
index 033e082..95aadd1 100644
--- a/sdk/lib/convert/codec.dart
+++ b/sdk/lib/convert/codec.dart
@@ -40,7 +40,7 @@
/**
* Returns the decoder of `this`, converting from [T] to [S].
*
- * It may be stateful an should not be reused.
+ * It may be stateful and should not be reused.
*/
Converter<T, S> get decoder;
diff --git a/sdk/lib/core/bigint.dart b/sdk/lib/core/bigint.dart
index 92fe61b..5f92625 100644
--- a/sdk/lib/core/bigint.dart
+++ b/sdk/lib/core/bigint.dart
@@ -4,49 +4,13 @@
part of dart.core;
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * Copyright (c) 2012 Adam Singer (adam@solvr.io)
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
/**
* An arbitrarily large integer.
*/
abstract class BigInt implements Comparable<BigInt> {
- static final BigInt zero = _BigIntImpl.zero;
- static final BigInt one = _BigIntImpl.one;
- static final BigInt two = _BigIntImpl.two;
+ external static BigInt get zero;
+ external static BigInt get one;
+ external static BigInt get two;
/**
* Parses [source] as a, possibly signed, integer literal and returns its
@@ -71,11 +35,10 @@
* Throws a [FormatException] if the [source] is not a valid integer literal,
* optionally prefixed by a sign.
*/
- static BigInt parse(String source, {int radix}) =>
- _BigIntImpl.parse(source, radix: radix);
+ external static BigInt parse(String source, {int radix});
/// Allocates a big integer from the provided [value] number.
- factory BigInt.from(num value) = _BigIntImpl.from;
+ external factory BigInt.from(num value);
/**
* Returns the absolute value of this integer.
@@ -436,2055 +399,3 @@
*/
String toRadixString(int radix);
}
-
-int _max(int a, int b) => a > b ? a : b;
-int _min(int a, int b) => a < b ? a : b;
-
-/**
- * An implementation for the arbitrarily large integer.
- *
- * The integer number is represented by a sign, an array of 16-bit unsigned
- * integers in little endian format, and a number of used digits in that array.
- */
-class _BigIntImpl implements BigInt {
- // Bits per digit.
- static const int _digitBits = 16;
- static const int _digitBase = 1 << _digitBits;
- static const int _digitMask = (1 << _digitBits) - 1;
-
- static final _BigIntImpl zero = new _BigIntImpl._fromInt(0);
- static final _BigIntImpl one = new _BigIntImpl._fromInt(1);
- static final _BigIntImpl two = new _BigIntImpl._fromInt(2);
-
- static final _BigIntImpl _minusOne = -one;
- static final _BigIntImpl _bigInt10000 = new _BigIntImpl._fromInt(10000);
-
- // Result cache for last _divRem call.
- // Result cache for last _divRem call.
- static Uint16List _lastDividendDigits;
- static int _lastDividendUsed;
- static Uint16List _lastDivisorDigits;
- static int _lastDivisorUsed;
- static Uint16List _lastQuoRemDigits;
- static int _lastQuoRemUsed;
- static int _lastRemUsed;
- static int _lastRem_nsh;
-
- /// Whether this bigint is negative.
- final bool _isNegative;
-
- /// The unsigned digits of this bigint.
- ///
- /// The least significant digit is in slot 0.
- /// The list may have more digits than needed. That is, `_digits.length` may
- /// be strictly greater than `_used`.
- final Uint16List _digits;
-
- /// The number of used entries in [_digits].
- ///
- /// To avoid reallocating [Uint16List]s, lists that are too big are not
- /// replaced.
- final int _used;
-
- /**
- * Parses [source] as a, possibly signed, integer literal and returns its
- * value.
- *
- * The [source] must be a non-empty sequence of base-[radix] digits,
- * optionally prefixed with a minus or plus sign ('-' or '+').
- *
- * The [radix] must be in the range 2..36. The digits used are
- * first the decimal digits 0..9, and then the letters 'a'..'z' with
- * values 10 through 35. Also accepts upper-case letters with the same
- * values as the lower-case ones.
- *
- * If no [radix] is given then it defaults to 10. In this case, the [source]
- * digits may also start with `0x`, in which case the number is interpreted
- * as a hexadecimal literal, which effectively means that the `0x` is ignored
- * and the radix is instead set to 16.
- *
- * For any int `n` and radix `r`, it is guaranteed that
- * `n == int.parse(n.toRadixString(r), radix: r)`.
- *
- * Throws a [FormatException] if the [source] is not a valid integer literal,
- * optionally prefixed by a sign.
- */
- static _BigIntImpl parse(String source, {int radix}) {
- var result = _tryParse(source, radix: radix);
- if (result == null) {
- throw new FormatException("Could not parse BigInt", source);
- }
- return result;
- }
-
- /// Parses a decimal bigint literal.
- ///
- /// The [source] must not contain leading or trailing whitespace.
- static _BigIntImpl _parseDecimal(String source, bool isNegative) {
- const _0 = 48;
-
- int part = 0;
- _BigIntImpl result = zero;
- // Read in the source 4 digits at a time.
- // The first part may have a few leading virtual '0's to make the remaining
- // parts all have exactly 4 digits.
- int digitInPartCount = 4 - source.length.remainder(4);
- if (digitInPartCount == 4) digitInPartCount = 0;
- for (int i = 0; i < source.length; i++) {
- part = part * 10 + source.codeUnitAt(i) - _0;
- if (++digitInPartCount == 4) {
- result = result * _bigInt10000 + new _BigIntImpl._fromInt(part);
- part = 0;
- digitInPartCount = 0;
- }
- }
- if (isNegative) return -result;
- return result;
- }
-
- /// Returns the value of a given source digit.
- ///
- /// Source digits between "0" and "9" (inclusive) return their decimal value.
- ///
- /// Source digits between "a" and "z", or "A" and "Z" (inclusive) return
- /// 10 + their position in the ASCII alphabet.
- ///
- /// The incoming [codeUnit] must be an ASCII code-unit.
- static int _codeUnitToRadixValue(int codeUnit) {
- // We know that the characters must be ASCII as otherwise the
- // regexp wouldn't have matched. Lowercasing by doing `| 0x20` is thus
- // guaranteed to be a safe operation, since it preserves digits
- // and lower-cases ASCII letters.
- const int _0 = 48;
- const int _9 = 57;
- const int _a = 97;
- if (_0 <= codeUnit && codeUnit <= _9) return codeUnit - _0;
- codeUnit |= 0x20;
- var result = codeUnit - _a + 10;
- return result;
- }
-
- /// Parses the given [source] string, starting at [startPos], as a hex
- /// literal.
- ///
- /// If [isNegative] is true, negates the result before returning it.
- ///
- /// The [source] (substring) must be a valid hex literal.
- static _BigIntImpl _parseHex(String source, int startPos, bool isNegative) {
- int hexDigitsPerChunk = _digitBits ~/ 4;
- int sourceLength = source.length - startPos;
- int chunkCount = (sourceLength / hexDigitsPerChunk).ceil();
- var digits = new Uint16List(chunkCount);
-
- int lastDigitLength = sourceLength - (chunkCount - 1) * hexDigitsPerChunk;
- int digitIndex = digits.length - 1;
- int i = startPos;
- int chunk = 0;
- for (int j = 0; j < lastDigitLength; j++) {
- var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
- if (digitValue >= 16) return null;
- chunk = chunk * 16 + digitValue;
- }
- digits[digitIndex--] = chunk;
-
- while (i < source.length) {
- chunk = 0;
- for (int j = 0; j < 4; j++) {
- var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i++));
- if (digitValue >= 16) return null;
- chunk = chunk * 16 + digitValue;
- }
- digits[digitIndex--] = chunk;
- }
- if (digits.length == 1 && digits[0] == 0) return zero;
- return new _BigIntImpl._(isNegative, digits.length, digits);
- }
-
- /// Parses the given [source] as a [radix] literal.
- ///
- /// The [source] will be checked for invalid characters. If it is invalid,
- /// this function returns `null`.
- static _BigIntImpl _parseRadix(String source, int radix, bool isNegative) {
- var result = zero;
- var base = new _BigIntImpl._fromInt(radix);
- for (int i = 0; i < source.length; i++) {
- var digitValue = _codeUnitToRadixValue(source.codeUnitAt(i));
- if (digitValue >= radix) return null;
- result = result * base + new _BigIntImpl._fromInt(digitValue);
- }
- if (isNegative) return -result;
- return result;
- }
-
- /// Tries to parse the given [source] as a [radix] literal.
- ///
- /// Returns the parsed big integer, or `null` if it failed.
- ///
- /// If the [radix] is `null` accepts decimal literals or `0x` hex literals.
- static _BigIntImpl _tryParse(String source, {int radix}) {
- if (source == "") return null;
-
- var re = new RegExp(r'^\s*([+-]?)((0x[a-f0-9]+)|(\d+)|([a-z0-9]+))\s*$',
- caseSensitive: false);
- var match = re.firstMatch(source);
- int signIndex = 1;
- int hexIndex = 3;
- int decimalIndex = 4;
- int nonDecimalHexIndex = 5;
- if (match == null) return null;
-
- bool isNegative = match[signIndex] == "-";
-
- String decimalMatch = match[decimalIndex];
- String hexMatch = match[hexIndex];
- String nonDecimalMatch = match[nonDecimalHexIndex];
-
- if (radix == null) {
- if (decimalMatch != null) {
- // Cannot fail because we know that the digits are all decimal.
- return _parseDecimal(decimalMatch, isNegative);
- }
- if (hexMatch != null) {
- // Cannot fail because we know that the digits are all hex.
- return _parseHex(hexMatch, 2, isNegative);
- }
- return null;
- }
-
- if (radix is! int) {
- throw new ArgumentError.value(radix, 'radix', 'is not an integer');
- }
- if (radix < 2 || radix > 36) {
- throw new RangeError.range(radix, 2, 36, 'radix');
- }
- if (radix == 10 && decimalMatch != null) {
- return _parseDecimal(decimalMatch, isNegative);
- }
- if (radix == 16 && (decimalMatch != null || nonDecimalMatch != null)) {
- return _parseHex(decimalMatch ?? nonDecimalMatch, 0, isNegative);
- }
-
- return _parseRadix(
- decimalMatch ?? nonDecimalMatch ?? hexMatch, radix, isNegative);
- }
-
- /// Finds the amount significant digits in the provided [digits] array.
- static int _normalize(int used, Uint16List digits) {
- while (used > 0 && digits[used - 1] == 0) used--;
- return used;
- }
-
- /// Factory returning an instance initialized with the given field values.
- /// If the [digits] array contains leading 0s, the [used] value is adjusted
- /// accordingly. The [digits] array is not modified.
- _BigIntImpl._(bool isNegative, int used, Uint16List digits)
- : this._normalized(isNegative, _normalize(used, digits), digits);
-
- _BigIntImpl._normalized(bool isNegative, this._used, this._digits)
- : _isNegative = _used == 0 ? false : isNegative;
-
- /// Whether this big integer is zero.
- bool get _isZero => _used == 0;
-
- /// Allocates an array of the given [length] and copies the [digits] in the
- /// range [from] to [to-1], starting at index 0, followed by leading zero
- /// digits.
- static Uint16List _cloneDigits(
- Uint16List digits, int from, int to, int length) {
- var resultDigits = new Uint16List(length);
- var n = to - from;
- for (var i = 0; i < n; i++) {
- resultDigits[i] = digits[from + i];
- }
- return resultDigits;
- }
-
- /// Allocates a big integer from the provided [value] number.
- factory _BigIntImpl.from(num value) {
- if (value == 0) return zero;
- if (value == 1) return one;
- if (value == 2) return two;
-
- // Given this order dart2js will use the `_fromInt` for smaller value and
- // then use the bit-manipulating `_fromDouble` for all other values.
- if (value.abs() < 0x100000000)
- return new _BigIntImpl._fromInt(value.toInt());
- if (value is double) return new _BigIntImpl._fromDouble(value);
- return new _BigIntImpl._fromInt(value);
- }
-
- factory _BigIntImpl._fromInt(int value) {
- bool isNegative = value < 0;
- if (isNegative) {
- // Handle the min 64-bit value differently, since its negation is not
- // positive.
- // TODO(floitsch): we should use min.minValue or 0x8000000000000000 here.
- const int minInt64 = -9223372036854775807 - 1;
- if (value == minInt64) {
- var digits = new Uint16List(4);
- digits[3] = 0x8000;
- return new _BigIntImpl._(true, digits.length, digits);
- }
- value = -value;
- }
- assert(_digitBits == 16);
- if (value < _digitBase) {
- var digits = new Uint16List(1);
- digits[0] = value;
- return new _BigIntImpl._(isNegative, digits.length, digits);
- }
- if (value <= 0xFFFFFFFF) {
- var digits = new Uint16List(2);
- digits[0] = value & _digitMask;
- digits[1] = value >> _digitBits;
- return new _BigIntImpl._(isNegative, digits.length, digits);
- }
-
- var bits = value.bitLength;
- var digits = new Uint16List((bits - 1) ~/ _digitBits + 1);
- var i = 0;
- while (value != 0) {
- digits[i++] = value & _digitMask;
- value = value ~/ _digitBase;
- }
- return new _BigIntImpl._(isNegative, digits.length, digits);
- }
-
- /// An 8-byte Uint8List we can reuse for [_fromDouble] to avoid generating
- /// garbage.
- static final Uint8List _bitsForFromDouble = new Uint8List(8);
-
- factory _BigIntImpl._fromDouble(double value) {
- const int exponentBias = 1075;
-
- if (value.isNaN || value.isInfinite) {
- throw new ArgumentError("Value must be finite: $value");
- }
- bool isNegative = value < 0;
- if (isNegative) value = -value;
-
- value = value.floorToDouble();
- if (value == 0) return zero;
-
- var bits = _bitsForFromDouble;
- for (int i = 0; i < 8; i++) {
- bits[i] = 0;
- }
- bits.buffer.asByteData().setFloat64(0, value, Endian.little);
- // The exponent is in bits 53..63.
- var biasedExponent = (bits[7] << 4) + (bits[6] >> 4);
- var exponent = biasedExponent - exponentBias;
-
- assert(_digitBits == 16);
- // The significant bits are in 0 .. 52.
- var unshiftedDigits = new Uint16List(4);
- unshiftedDigits[0] = (bits[1] << 8) + bits[0];
- unshiftedDigits[1] = (bits[3] << 8) + bits[2];
- unshiftedDigits[2] = (bits[5] << 8) + bits[4];
- // Don't forget to add the hidden bit.
- unshiftedDigits[3] = 0x10 | (bits[6] & 0xF);
-
- var unshiftedBig = new _BigIntImpl._normalized(false, 4, unshiftedDigits);
- _BigIntImpl absResult;
- if (exponent < 0) {
- absResult = unshiftedBig >> -exponent;
- } else if (exponent > 0) {
- absResult = unshiftedBig << exponent;
- }
- if (isNegative) return -absResult;
- return absResult;
- }
-
- /**
- * Return the negative value of this integer.
- *
- * The result of negating an integer always has the opposite sign, except
- * for zero, which is its own negation.
- */
- _BigIntImpl operator -() {
- if (_used == 0) return this;
- return new _BigIntImpl._(!_isNegative, _used, _digits);
- }
-
- /**
- * Returns the absolute value of this integer.
- *
- * For any integer `x`, the result is the same as `x < 0 ? -x : x`.
- */
- _BigIntImpl abs() => _isNegative ? -this : this;
-
- /// Returns this << n *_DIGIT_BITS.
- _BigIntImpl _dlShift(int n) {
- final used = _used;
- if (used == 0) {
- return zero;
- }
- final resultUsed = used + n;
- final digits = _digits;
- final resultDigits = new Uint16List(resultUsed);
- for (int i = used - 1; i >= 0; i--) {
- resultDigits[i + n] = digits[i];
- }
- return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
- }
-
- /// Same as [_dlShift] but works on the decomposed big integers.
- ///
- /// Returns `resultUsed`.
- ///
- /// `resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n*_DIGIT_BITS`.
- static int _dlShiftDigits(
- Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
- if (xUsed == 0) {
- return 0;
- }
- if (n == 0 && identical(resultDigits, xDigits)) {
- return xUsed;
- }
- final resultUsed = xUsed + n;
- for (int i = xUsed - 1; i >= 0; i--) {
- resultDigits[i + n] = xDigits[i];
- }
- for (int i = n - 1; i >= 0; i--) {
- resultDigits[i] = 0;
- }
- return resultUsed;
- }
-
- /// Returns `this >> n*_DIGIT_BITS`.
- _BigIntImpl _drShift(int n) {
- final used = _used;
- if (used == 0) {
- return zero;
- }
- final resultUsed = used - n;
- if (resultUsed <= 0) {
- return _isNegative ? _minusOne : zero;
- }
- final digits = _digits;
- final resultDigits = new Uint16List(resultUsed);
- for (var i = n; i < used; i++) {
- resultDigits[i - n] = digits[i];
- }
- final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
- if (_isNegative) {
- // Round down if any bit was shifted out.
- for (var i = 0; i < n; i++) {
- if (digits[i] != 0) {
- return result - one;
- }
- }
- }
- return result;
- }
-
- /// Shifts the digits of [xDigits] into the right place in [resultDigits].
- ///
- /// `resultDigits[ds..xUsed+ds] = xDigits[0..xUsed-1] << (n % _DIGIT_BITS)`
- /// where `ds = ceil(n / _DIGIT_BITS)`
- ///
- /// Does *not* clear digits below ds.
- static void _lsh(
- Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
- final digitShift = n ~/ _digitBits;
- final bitShift = n % _digitBits;
- final carryBitShift = _digitBits - bitShift;
- final bitMask = (1 << carryBitShift) - 1;
- var carry = 0;
- for (int i = xUsed - 1; i >= 0; i--) {
- final digit = xDigits[i];
- resultDigits[i + digitShift + 1] = (digit >> carryBitShift) | carry;
- carry = (digit & bitMask) << bitShift;
- }
- resultDigits[digitShift] = carry;
- }
-
- /**
- * Shift the bits of this integer to the left by [shiftAmount].
- *
- * Shifting to the left makes the number larger, effectively multiplying
- * the number by `pow(2, shiftIndex)`.
- *
- * There is no limit on the size of the result. It may be relevant to
- * limit intermediate values by using the "and" operator with a suitable
- * mask.
- *
- * It is an error if [shiftAmount] is negative.
- */
- _BigIntImpl operator <<(int shiftAmount) {
- if (shiftAmount < 0) {
- throw new ArgumentError("shift-amount must be posititve $shiftAmount");
- }
- final digitShift = shiftAmount ~/ _digitBits;
- final bitShift = shiftAmount % _digitBits;
- if (bitShift == 0) {
- return _dlShift(digitShift);
- }
- var resultUsed = _used + digitShift + 1;
- var resultDigits = new Uint16List(resultUsed);
- _lsh(_digits, _used, shiftAmount, resultDigits);
- return new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
- }
-
- // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] << n.
- // Returns resultUsed.
- static int _lShiftDigits(
- Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
- final digitsShift = n ~/ _digitBits;
- final bitShift = n % _digitBits;
- if (bitShift == 0) {
- return _dlShiftDigits(xDigits, xUsed, digitsShift, resultDigits);
- }
- var resultUsed = xUsed + digitsShift + 1;
- _lsh(xDigits, xUsed, n, resultDigits);
- var i = digitsShift;
- while (--i >= 0) {
- resultDigits[i] = 0;
- }
- if (resultDigits[resultUsed - 1] == 0) {
- resultUsed--; // Clamp result.
- }
- return resultUsed;
- }
-
- // resultDigits[0..resultUsed-1] = xDigits[0..xUsed-1] >> n.
- static void _rsh(
- Uint16List xDigits, int xUsed, int n, Uint16List resultDigits) {
- final digitsShift = n ~/ _digitBits;
- final bitShift = n % _digitBits;
- final carryBitShift = _digitBits - bitShift;
- final bitMask = (1 << bitShift) - 1;
- var carry = xDigits[digitsShift] >> bitShift;
- final last = xUsed - digitsShift - 1;
- for (var i = 0; i < last; i++) {
- final digit = xDigits[i + digitsShift + 1];
- resultDigits[i] = ((digit & bitMask) << carryBitShift) | carry;
- carry = digit >> bitShift;
- }
- resultDigits[last] = carry;
- }
-
- /**
- * Shift the bits of this integer to the right by [shiftAmount].
- *
- * Shifting to the right makes the number smaller and drops the least
- * significant bits, effectively doing an integer division by
- *`pow(2, shiftIndex)`.
- *
- * It is an error if [shiftAmount] is negative.
- */
- _BigIntImpl operator >>(int shiftAmount) {
- if (shiftAmount < 0) {
- throw new ArgumentError("shift-amount must be posititve $shiftAmount");
- }
- final digitShift = shiftAmount ~/ _digitBits;
- final bitShift = shiftAmount % _digitBits;
- if (bitShift == 0) {
- return _drShift(digitShift);
- }
- final used = _used;
- final resultUsed = used - digitShift;
- if (resultUsed <= 0) {
- return _isNegative ? _minusOne : zero;
- }
- final digits = _digits;
- final resultDigits = new Uint16List(resultUsed);
- _rsh(digits, used, shiftAmount, resultDigits);
- final result = new _BigIntImpl._(_isNegative, resultUsed, resultDigits);
- if (_isNegative) {
- // Round down if any bit was shifted out.
- if ((digits[digitShift] & ((1 << bitShift) - 1)) != 0) {
- return result - one;
- }
- for (var i = 0; i < digitShift; i++) {
- if (digits[i] != 0) {
- return result - one;
- }
- }
- }
- return result;
- }
-
- /// Compares this to [other] taking the absolute value of both operands.
- ///
- /// Returns 0 if abs(this) == abs(other); a positive number if
- /// abs(this) > abs(other); and a negative number if abs(this) < abs(other).
- int _absCompare(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- return _compareDigits(_digits, _used, other._digits, other._used);
- }
-
- /**
- * Compares this to `other`.
- *
- * Returns a negative number if `this` is less than `other`, zero if they are
- * equal, and a positive number if `this` is greater than `other`.
- */
- int compareTo(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (_isNegative == other._isNegative) {
- var result = _absCompare(other);
- // Use 0 - result to avoid negative zero in JavaScript.
- return _isNegative ? 0 - result : result;
- }
- return _isNegative ? -1 : 1;
- }
-
- /// Compares `digits[0..used-1]` with `otherDigits[0..otherUsed-1]`.
- ///
- /// Returns 0 if equal; a positive number if larger;
- /// and a negative number if smaller.
- static int _compareDigits(
- Uint16List digits, int used, Uint16List otherDigits, int otherUsed) {
- var result = used - otherUsed;
- if (result == 0) {
- for (int i = used - 1; i >= 0; i--) {
- result = digits[i] - otherDigits[i];
- if (result != 0) return result;
- }
- }
- return result;
- }
-
- // resultDigits[0..used] = digits[0..used-1] + otherDigits[0..otherUsed-1].
- // used >= otherUsed > 0.
- static void _absAdd(Uint16List digits, int used, Uint16List otherDigits,
- int otherUsed, Uint16List resultDigits) {
- assert(used >= otherUsed && otherUsed > 0);
- var carry = 0;
- for (var i = 0; i < otherUsed; i++) {
- carry += digits[i] + otherDigits[i];
- resultDigits[i] = carry & _digitMask;
- carry >>= _digitBits;
- }
- for (var i = otherUsed; i < used; i++) {
- carry += digits[i];
- resultDigits[i] = carry & _digitMask;
- carry >>= _digitBits;
- }
- resultDigits[used] = carry;
- }
-
- // resultDigits[0..used-1] = digits[0..used-1] - otherDigits[0..otherUsed-1].
- // used >= otherUsed > 0.
- static void _absSub(Uint16List digits, int used, Uint16List otherDigits,
- int otherUsed, Uint16List resultDigits) {
- assert(used >= otherUsed && otherUsed > 0);
-
- var carry = 0;
- for (var i = 0; i < otherUsed; i++) {
- carry += digits[i] - otherDigits[i];
- resultDigits[i] = carry & _digitMask;
- // Dart2js only supports unsigned shifts.
- // Since the carry can only be -1 or 0 use this hack.
- carry = 0 - ((carry >> _digitBits) & 1);
- }
- for (var i = otherUsed; i < used; i++) {
- carry += digits[i];
- resultDigits[i] = carry & _digitMask;
- // Dart2js only supports unsigned shifts.
- // Since the carry can only be -1 or 0 use this hack.
- carry = 0 - ((carry >> _digitBits) & 1);
- }
- }
-
- /// Returns `abs(this) + abs(other)` with sign set according to [isNegative].
- _BigIntImpl _absAddSetSign(_BigIntImpl other, bool isNegative) {
- var used = _used;
- var otherUsed = other._used;
- if (used < otherUsed) {
- return other._absAddSetSign(this, isNegative);
- }
- if (used == 0) {
- assert(!isNegative);
- return zero;
- }
- if (otherUsed == 0) {
- return _isNegative == isNegative ? this : -this;
- }
- var resultUsed = used + 1;
- var resultDigits = new Uint16List(resultUsed);
- _absAdd(_digits, used, other._digits, otherUsed, resultDigits);
- return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
- }
-
- /// Returns `abs(this) - abs(other)` with sign set according to [isNegative].
- ///
- /// Requirement: `abs(this) >= abs(other)`.
- _BigIntImpl _absSubSetSign(_BigIntImpl other, bool isNegative) {
- assert(_absCompare(other) >= 0);
- var used = _used;
- if (used == 0) {
- assert(!isNegative);
- return zero;
- }
- var otherUsed = other._used;
- if (otherUsed == 0) {
- return _isNegative == isNegative ? this : -this;
- }
- var resultDigits = new Uint16List(used);
- _absSub(_digits, used, other._digits, otherUsed, resultDigits);
- return new _BigIntImpl._(isNegative, used, resultDigits);
- }
-
- /// Returns `abs(this) & abs(other)` with sign set according to [isNegative].
- _BigIntImpl _absAndSetSign(_BigIntImpl other, bool isNegative) {
- var resultUsed = _min(_used, other._used);
- var digits = _digits;
- var otherDigits = other._digits;
- var resultDigits = new Uint16List(resultUsed);
- for (var i = 0; i < resultUsed; i++) {
- resultDigits[i] = digits[i] & otherDigits[i];
- }
- return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
- }
-
- /// Returns `abs(this) &~ abs(other)` with sign set according to [isNegative].
- _BigIntImpl _absAndNotSetSign(_BigIntImpl other, bool isNegative) {
- var resultUsed = _used;
- var digits = _digits;
- var otherDigits = other._digits;
- var resultDigits = new Uint16List(resultUsed);
- var m = _min(resultUsed, other._used);
- for (var i = 0; i < m; i++) {
- resultDigits[i] = digits[i] & ~otherDigits[i];
- }
- for (var i = m; i < resultUsed; i++) {
- resultDigits[i] = digits[i];
- }
- return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
- }
-
- /// Returns `abs(this) | abs(other)` with sign set according to [isNegative].
- _BigIntImpl _absOrSetSign(_BigIntImpl other, bool isNegative) {
- var used = _used;
- var otherUsed = other._used;
- var resultUsed = _max(used, otherUsed);
- var digits = _digits;
- var otherDigits = other._digits;
- var resultDigits = new Uint16List(resultUsed);
- var l, m;
- if (used < otherUsed) {
- l = other;
- m = used;
- } else {
- l = this;
- m = otherUsed;
- }
- for (var i = 0; i < m; i++) {
- resultDigits[i] = digits[i] | otherDigits[i];
- }
- var lDigits = l._digits;
- for (var i = m; i < resultUsed; i++) {
- resultDigits[i] = lDigits[i];
- }
- return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
- }
-
- /// Returns `abs(this) ^ abs(other)` with sign set according to [isNegative].
- _BigIntImpl _absXorSetSign(_BigIntImpl other, bool isNegative) {
- var used = _used;
- var otherUsed = other._used;
- var resultUsed = _max(used, otherUsed);
- var digits = _digits;
- var otherDigits = other._digits;
- var resultDigits = new Uint16List(resultUsed);
- var l, m;
- if (used < otherUsed) {
- l = other;
- m = used;
- } else {
- l = this;
- m = otherUsed;
- }
- for (var i = 0; i < m; i++) {
- resultDigits[i] = digits[i] ^ otherDigits[i];
- }
- var lDigits = l._digits;
- for (var i = m; i < resultUsed; i++) {
- resultDigits[i] = lDigits[i];
- }
- return new _BigIntImpl._(isNegative, resultUsed, resultDigits);
- }
-
- /**
- * Bit-wise and operator.
- *
- * Treating both `this` and [other] as sufficiently large two's component
- * integers, the result is a number with only the bits set that are set in
- * both `this` and [other]
- *
- * Of both operands are negative, the result is negative, otherwise
- * the result is non-negative.
- */
- _BigIntImpl operator &(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (_isNegative == other._isNegative) {
- if (_isNegative) {
- // (-this) & (-other) == ~(this-1) & ~(other-1)
- // == ~((this-1) | (other-1))
- // == -(((this-1) | (other-1)) + 1)
- _BigIntImpl this1 = _absSubSetSign(one, true);
- _BigIntImpl other1 = other._absSubSetSign(one, true);
- // Result cannot be zero if this and other are negative.
- return this1._absOrSetSign(other1, true)._absAddSetSign(one, true);
- }
- return _absAndSetSign(other, false);
- }
- // _isNegative != other._isNegative
- var p, n;
- if (_isNegative) {
- p = other;
- n = this;
- } else {
- // & is symmetric.
- p = this;
- n = other;
- }
- // p & (-n) == p & ~(n-1) == p &~ (n-1)
- var n1 = n._absSubSetSign(one, false);
- return p._absAndNotSetSign(n1, false);
- }
-
- /**
- * Bit-wise or operator.
- *
- * Treating both `this` and [other] as sufficiently large two's component
- * integers, the result is a number with the bits set that are set in either
- * of `this` and [other]
- *
- * If both operands are non-negative, the result is non-negative,
- * otherwise the result us negative.
- */
- _BigIntImpl operator |(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (_isNegative == other._isNegative) {
- if (_isNegative) {
- // (-this) | (-other) == ~(this-1) | ~(other-1)
- // == ~((this-1) & (other-1))
- // == -(((this-1) & (other-1)) + 1)
- var this1 = _absSubSetSign(one, true);
- var other1 = other._absSubSetSign(one, true);
- // Result cannot be zero if this and a are negative.
- return this1._absAndSetSign(other1, true)._absAddSetSign(one, true);
- }
- return _absOrSetSign(other, false);
- }
- // _neg != a._neg
- var p, n;
- if (_isNegative) {
- p = other;
- n = this;
- } else {
- // | is symmetric.
- p = this;
- n = other;
- }
- // p | (-n) == p | ~(n-1) == ~((n-1) &~ p) == -(~((n-1) &~ p) + 1)
- var n1 = n._absSubSetSign(one, true);
- // Result cannot be zero if only one of this or a is negative.
- return n1._absAndNotSetSign(p, true)._absAddSetSign(one, true);
- }
-
- /**
- * Bit-wise exclusive-or operator.
- *
- * Treating both `this` and [other] as sufficiently large two's component
- * integers, the result is a number with the bits set that are set in one,
- * but not both, of `this` and [other]
- *
- * If the operands have the same sign, the result is non-negative,
- * otherwise the result is negative.
- */
- _BigIntImpl operator ^(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (_isNegative == other._isNegative) {
- if (_isNegative) {
- // (-this) ^ (-other) == ~(this-1) ^ ~(other-1) == (this-1) ^ (other-1)
- var this1 = _absSubSetSign(one, true);
- var other1 = other._absSubSetSign(one, true);
- return this1._absXorSetSign(other1, false);
- }
- return _absXorSetSign(other, false);
- }
- // _isNegative != a._isNegative
- var p, n;
- if (_isNegative) {
- p = other;
- n = this;
- } else {
- // ^ is symmetric.
- p = this;
- n = other;
- }
- // p ^ (-n) == p ^ ~(n-1) == ~(p ^ (n-1)) == -((p ^ (n-1)) + 1)
- var n1 = n._absSubSetSign(one, true);
- // Result cannot be zero if only one of this or a is negative.
- return p._absXorSetSign(n1, true)._absAddSetSign(one, true);
- }
-
- /**
- * The bit-wise negate operator.
- *
- * Treating `this` as a sufficiently large two's component integer,
- * the result is a number with the opposite bits set.
- *
- * This maps any integer `x` to `-x - 1`.
- */
- _BigIntImpl operator ~() {
- if (_isNegative) {
- // ~(-this) == ~(~(this-1)) == this-1
- return _absSubSetSign(one, false);
- }
- // ~this == -this-1 == -(this+1)
- // Result cannot be zero if this is positive.
- return _absAddSetSign(one, true);
- }
-
- /// Addition operator.
- _BigIntImpl operator +(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- var isNegative = _isNegative;
- if (isNegative == other._isNegative) {
- // this + other == this + other
- // (-this) + (-other) == -(this + other)
- return _absAddSetSign(other, isNegative);
- }
- // this + (-other) == this - other == -(this - other)
- // (-this) + other == other - this == -(this - other)
- if (_absCompare(other) >= 0) {
- return _absSubSetSign(other, isNegative);
- }
- return other._absSubSetSign(this, !isNegative);
- }
-
- /// Subtraction operator.
- _BigIntImpl operator -(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- var isNegative = _isNegative;
- if (isNegative != other._isNegative) {
- // this - (-other) == this + other
- // (-this) - other == -(this + other)
- return _absAddSetSign(other, isNegative);
- }
- // this - other == this - a == -(this - other)
- // (-this) - (-other) == other - this == -(this - other)
- if (_absCompare(other) >= 0) {
- return _absSubSetSign(other, isNegative);
- }
- return other._absSubSetSign(this, !isNegative);
- }
-
- /// Multiplies [x] with [multiplicandDigits] and adds the result to
- /// [accumulatorDigits].
- ///
- /// The [multiplicandDigits] in the range [i] to [i]+[n]-1 are the
- /// multiplicand digits.
- ///
- /// The [acculumatorDigits] in the range [j] to [j]+[n]-1 are the accumulator
- /// digits.
- ///
- /// Adds the result of the multiplicand-digits * [x] to the accumulator.
- ///
- /// Concretely: `accumulatorDigits[j..j+n] += x * m_digits[i..i+n-1]`.
- static void _mulAdd(int x, Uint16List multiplicandDigits, int i,
- Uint16List accumulatorDigits, int j, int n) {
- if (x == 0) {
- // No-op if x is 0.
- return;
- }
- int c = 0;
- while (--n >= 0) {
- int product = x * multiplicandDigits[i++];
- int combined = product + accumulatorDigits[j] + c;
- accumulatorDigits[j++] = combined & _digitMask;
- // Note that this works with 53 bits, as the division will not lose
- // bits.
- c = combined ~/ _digitBase;
- }
- while (c != 0) {
- int l = accumulatorDigits[j] + c;
- accumulatorDigits[j++] = l & _digitMask;
- c = l ~/ _digitBase;
- }
- }
-
- /// Multiplication operator.
- _BigIntImpl operator *(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- var used = _used;
- var otherUsed = other._used;
- if (used == 0 || otherUsed == 0) {
- return zero;
- }
- var resultUsed = used + otherUsed;
- var digits = _digits;
- var otherDigits = other._digits;
- var resultDigits = new Uint16List(resultUsed);
- var i = 0;
- while (i < otherUsed) {
- _mulAdd(otherDigits[i], digits, 0, resultDigits, i, used);
- i++;
- }
- return new _BigIntImpl._(
- _isNegative != other._isNegative, resultUsed, resultDigits);
- }
-
- // r_digits[0..rUsed-1] = xDigits[0..xUsed-1]*otherDigits[0..otherUsed-1].
- // Return resultUsed = xUsed + otherUsed.
- static int _mulDigits(Uint16List xDigits, int xUsed, Uint16List otherDigits,
- int otherUsed, Uint16List resultDigits) {
- var resultUsed = xUsed + otherUsed;
- var i = resultUsed;
- assert(resultDigits.length >= i);
- while (--i >= 0) {
- resultDigits[i] = 0;
- }
- i = 0;
- while (i < otherUsed) {
- _mulAdd(otherDigits[i], xDigits, 0, resultDigits, i, xUsed);
- i++;
- }
- return resultUsed;
- }
-
- /// Returns an estimate of `digits[i-1..i] ~/ topDigitDivisor`.
- static int _estimateQuotientDigit(
- int topDigitDivisor, Uint16List digits, int i) {
- if (digits[i] == topDigitDivisor) return _digitMask;
- var quotientDigit =
- (digits[i] << _digitBits | digits[i - 1]) ~/ topDigitDivisor;
- if (quotientDigit > _digitMask) return _digitMask;
- return quotientDigit;
- }
-
- /// Returns `trunc(this / other)`, with `other != 0`.
- _BigIntImpl _div(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- assert(other._used > 0);
- if (_used < other._used) {
- return zero;
- }
- _divRem(other);
- // Return quotient, i.e.
- // _lastQuoRem_digits[_lastRem_used.._lastQuoRem_used-1] with proper sign.
- var lastQuo_used = _lastQuoRemUsed - _lastRemUsed;
- var quo_digits = _cloneDigits(
- _lastQuoRemDigits, _lastRemUsed, _lastQuoRemUsed, lastQuo_used);
- var quo = new _BigIntImpl._(false, lastQuo_used, quo_digits);
- if ((_isNegative != other._isNegative) && (quo._used > 0)) {
- quo = -quo;
- }
- return quo;
- }
-
- /// Returns `this - other * trunc(this / other)`, with `other != 0`.
- _BigIntImpl _rem(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- assert(other._used > 0);
- if (_used < other._used) {
- return this;
- }
- _divRem(other);
- // Return remainder, i.e.
- // denormalized _lastQuoRem_digits[0.._lastRem_used-1] with proper sign.
- var remDigits =
- _cloneDigits(_lastQuoRemDigits, 0, _lastRemUsed, _lastRemUsed);
- var rem = new _BigIntImpl._(false, _lastRemUsed, remDigits);
- if (_lastRem_nsh > 0) {
- rem = rem >> _lastRem_nsh; // Denormalize remainder.
- }
- if (_isNegative && (rem._used > 0)) {
- rem = -rem;
- }
- return rem;
- }
-
- /// Computes this ~/ other and this.remainder(other).
- ///
- /// Stores the result in [_lastQuoRemDigits], [_lastQuoRemUsed] and
- /// [_lastRemUsed]. The [_lastQuoRemDigits] contains the digits of *both*, the
- /// quotient and the remainder.
- ///
- /// Caches the input to avoid doing the work again when users write
- /// `a ~/ b` followed by a `a % b`.
- void _divRem(_BigIntImpl other) {
- // Check if result is already cached.
- if ((this._used == _lastDividendUsed) &&
- (other._used == _lastDivisorUsed) &&
- identical(this._digits, _lastDividendDigits) &&
- identical(other._digits, _lastDivisorDigits)) {
- return;
- }
- assert(_used >= other._used);
-
- var nsh = _digitBits - other._digits[other._used - 1].bitLength;
- // Concatenated positive quotient and normalized positive remainder.
- // The resultDigits can have at most one more digit than the dividend.
- Uint16List resultDigits;
- int resultUsed;
- // Normalized positive divisor.
- // The normalized divisor has the most-significant bit of it's most
- // significant digit set.
- // This makes estimating the quotient easier.
- Uint16List yDigits;
- int yUsed;
- if (nsh > 0) {
- yDigits = new Uint16List(other._used + 5);
- yUsed = _lShiftDigits(other._digits, other._used, nsh, yDigits);
- resultDigits = new Uint16List(_used + 5);
- resultUsed = _lShiftDigits(_digits, _used, nsh, resultDigits);
- } else {
- yDigits = other._digits;
- yUsed = other._used;
- resultDigits = _cloneDigits(_digits, 0, _used, _used + 2);
- resultUsed = _used;
- }
- var topDigitDivisor = yDigits[yUsed - 1];
- var i = resultUsed;
- var j = i - yUsed;
- // tmpDigits is a temporary array of i (resultUsed) digits.
- var tmpDigits = new Uint16List(i);
- var tmpUsed = _dlShiftDigits(yDigits, yUsed, j, tmpDigits);
- // Explicit first division step in case normalized dividend is larger or
- // equal to shifted normalized divisor.
- if (_compareDigits(resultDigits, resultUsed, tmpDigits, tmpUsed) >= 0) {
- assert(i == resultUsed);
- resultDigits[resultUsed++] = 1; // Quotient = 1.
- // Subtract divisor from remainder.
- _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
- } else {
- // Account for possible carry in _mulAdd step.
- resultDigits[resultUsed++] = 0;
- }
-
- // Negate y so we can later use _mulAdd instead of non-existent _mulSub.
- var nyDigits = new Uint16List(yUsed + 2);
- nyDigits[yUsed] = 1;
- _absSub(nyDigits, yUsed + 1, yDigits, yUsed, nyDigits);
- // nyDigits is read-only and has yUsed digits (possibly including several
- // leading zeros).
- // resultDigits is modified during iteration.
- // resultDigits[0..yUsed-1] is the current remainder.
- // resultDigits[yUsed..resultUsed-1] is the current quotient.
- --i;
-
- while (j > 0) {
- var estimatedQuotientDigit =
- _estimateQuotientDigit(topDigitDivisor, resultDigits, i);
- j--;
- _mulAdd(estimatedQuotientDigit, nyDigits, 0, resultDigits, j, yUsed);
- if (resultDigits[i] < estimatedQuotientDigit) {
- // Reusing the already existing tmpDigits array.
- var tmpUsed = _dlShiftDigits(nyDigits, yUsed, j, tmpDigits);
- _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
- while (resultDigits[i] < --estimatedQuotientDigit) {
- _absSub(resultDigits, resultUsed, tmpDigits, tmpUsed, resultDigits);
- }
- }
- i--;
- }
- // Cache result.
- _lastDividendDigits = _digits;
- _lastDividendUsed = _used;
- _lastDivisorDigits = other._digits;
- _lastDivisorUsed = other._used;
- _lastQuoRemDigits = resultDigits;
- _lastQuoRemUsed = resultUsed;
- _lastRemUsed = yUsed;
- _lastRem_nsh = nsh;
- }
-
- int get hashCode {
- // This is the [Jenkins hash function][1] but using masking to keep
- // values in SMI range.
- //
- // [1]: http://en.wikipedia.org/wiki/Jenkins_hash_function
-
- int combine(int hash, int value) {
- hash = 0x1fffffff & (hash + value);
- hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10));
- return hash ^ (hash >> 6);
- }
-
- int finish(int hash) {
- hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3));
- hash = hash ^ (hash >> 11);
- return 0x1fffffff & (hash + ((0x00003fff & hash) << 15));
- }
-
- if (_isZero) return 6707; // Just a random number.
- var hash = _isNegative ? 83585 : 429689; // Also random.
- for (int i = 0; i < _used; i++) {
- hash = combine(hash, _digits[i]);
- }
- return finish(hash);
- }
-
- /**
- * Test whether this value is numerically equal to `other`.
- *
- * If [other] is a [_BigIntImpl] returns whether the two operands have the same
- * value.
- *
- * Returns false if `other` is not a [_BigIntImpl].
- */
- bool operator ==(Object other) =>
- other is _BigIntImpl && compareTo(other) == 0;
-
- /**
- * Returns the minimum number of bits required to store this big integer.
- *
- * The number of bits excludes the sign bit, which gives the natural length
- * for non-negative (unsigned) values. Negative values are complemented to
- * return the bit position of the first bit that differs from the sign bit.
- *
- * To find the number of bits needed to store the value as a signed value,
- * add one, i.e. use `x.bitLength + 1`.
- *
- * ```
- * x.bitLength == (-x-1).bitLength
- *
- * new BigInt.from(3).bitLength == 2; // 00000011
- * new BigInt.from(2).bitLength == 2; // 00000010
- * new BigInt.from(1).bitLength == 1; // 00000001
- * new BigInt.from(0).bitLength == 0; // 00000000
- * new BigInt.from(-1).bitLength == 0; // 11111111
- * new BigInt.from(-2).bitLength == 1; // 11111110
- * new BigInt.from(-3).bitLength == 2; // 11111101
- * new BigInt.from(-4).bitLength == 2; // 11111100
- * ```
- */
- int get bitLength {
- if (_used == 0) return 0;
- if (_isNegative) return (~this).bitLength;
- return _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
- }
-
- /**
- * Truncating division operator.
- *
- * Performs a truncating integer division, where the remainder is discarded.
- *
- * The remainder can be computed using the [remainder] method.
- *
- * Examples:
- * ```
- * var seven = new BigInt.from(7);
- * var three = new BigInt.from(3);
- * seven ~/ three; // => 2
- * (-seven) ~/ three; // => -2
- * seven ~/ -three; // => -2
- * seven.remainder(three); // => 1
- * (-seven).remainder(three); // => -1
- * seven.remainder(-three); // => 1
- * ```
- */
- _BigIntImpl operator ~/(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (other._used == 0) {
- throw const IntegerDivisionByZeroException();
- }
- return _div(other);
- }
-
- /**
- * Returns the remainder of the truncating division of `this` by [other].
- *
- * The result `r` of this operation satisfies:
- * `this == (this ~/ other) * other + r`.
- * As a consequence the remainder `r` has the same sign as the divider `this`.
- */
- _BigIntImpl remainder(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (other._used == 0) {
- throw const IntegerDivisionByZeroException();
- }
- return _rem(other);
- }
-
- /// Division operator.
- double operator /(BigInt other) => this.toDouble() / other.toDouble();
-
- /** Relational less than operator. */
- bool operator <(BigInt other) => compareTo(other) < 0;
-
- /** Relational less than or equal operator. */
- bool operator <=(BigInt other) => compareTo(other) <= 0;
-
- /** Relational greater than operator. */
- bool operator >(BigInt other) => compareTo(other) > 0;
-
- /** Relational greater than or equal operator. */
- bool operator >=(BigInt other) => compareTo(other) >= 0;
-
- /**
- * Euclidean modulo operator.
- *
- * Returns the remainder of the Euclidean division. The Euclidean division of
- * two integers `a` and `b` yields two integers `q` and `r` such that
- * `a == b * q + r` and `0 <= r < b.abs()`.
- *
- * The sign of the returned value `r` is always positive.
- *
- * See [remainder] for the remainder of the truncating division.
- */
- _BigIntImpl operator %(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (other._used == 0) {
- throw const IntegerDivisionByZeroException();
- }
- var result = _rem(other);
- if (result._isNegative) {
- if (other._isNegative) {
- result = result - other;
- } else {
- result = result + other;
- }
- }
- return result;
- }
-
- /**
- * Returns the sign of this big integer.
- *
- * Returns 0 for zero, -1 for values less than zero and
- * +1 for values greater than zero.
- */
- int get sign {
- if (_used == 0) return 0;
- return _isNegative ? -1 : 1;
- }
-
- /// Whether this big integer is even.
- bool get isEven => _used == 0 || (_digits[0] & 1) == 0;
-
- /// Whether this big integer is odd.
- bool get isOdd => !isEven;
-
- /// Whether this number is negative.
- bool get isNegative => _isNegative;
-
- _BigIntImpl pow(int exponent) {
- if (exponent < 0) {
- throw new ArgumentError("Exponent must not be negative: $exponent");
- }
- if (exponent == 0) return one;
-
- // Exponentiation by squaring.
- var result = one;
- var base = this;
- while (exponent != 0) {
- if ((exponent & 1) == 1) {
- result *= base;
- }
- exponent >>= 1;
- // Skip unnecessary operation.
- if (exponent != 0) {
- base *= base;
- }
- }
- return result;
- }
-
- /**
- * Returns this integer to the power of [exponent] modulo [modulus].
- *
- * The [exponent] must be non-negative and [modulus] must be
- * positive.
- */
- _BigIntImpl modPow(BigInt bigExponent, BigInt bigModulus) {
- _BigIntImpl exponent = bigExponent;
- _BigIntImpl modulus = bigModulus;
- if (exponent._isNegative) {
- throw new ArgumentError("exponent must be positive: $exponent");
- }
- if (modulus <= zero) {
- throw new ArgumentError("modulus must be strictly positive: $modulus");
- }
- if (exponent._isZero) return one;
-
- final modulusUsed = modulus._used;
- final modulusUsed2p4 = 2 * modulusUsed + 4;
- final exponentBitlen = exponent.bitLength;
- if (exponentBitlen <= 0) return one;
- _BigIntReduction z = new _BigIntClassic(modulus);
- var resultDigits = new Uint16List(modulusUsed2p4);
- var result2Digits = new Uint16List(modulusUsed2p4);
- var gDigits = new Uint16List(modulusUsed);
- var gUsed = z.convert(this, gDigits);
- // Initialize result with g.
- // Copy leading zero if any.
- for (int j = gUsed - 1; j >= 0; j--) {
- resultDigits[j] = gDigits[j];
- }
- var resultUsed = gUsed;
- var result2Used;
- for (int i = exponentBitlen - 2; i >= 0; i--) {
- result2Used = z.sqr(resultDigits, resultUsed, result2Digits);
- if (!(exponent & (one << i))._isZero) {
- resultUsed =
- z.mul(result2Digits, result2Used, gDigits, gUsed, resultDigits);
- } else {
- // Swap result and result2.
- var tmpDigits = resultDigits;
- var tmpUsed = resultUsed;
- resultDigits = result2Digits;
- resultUsed = result2Used;
- result2Digits = tmpDigits;
- result2Used = tmpUsed;
- }
- }
- return z.revert(resultDigits, resultUsed);
- }
-
- // If inv is false, returns gcd(x, y).
- // If inv is true and gcd(x, y) = 1, returns d, so that c*x + d*y = 1.
- // If inv is true and gcd(x, y) != 1, throws Exception("Not coprime").
- static _BigIntImpl _binaryGcd(_BigIntImpl x, _BigIntImpl y, bool inv) {
- var xDigits = x._digits;
- var yDigits = y._digits;
- var xUsed = x._used;
- var yUsed = y._used;
- var maxUsed = xUsed > yUsed ? xUsed : yUsed;
- var unshiftedMaxUsed = maxUsed; // Keep
- xDigits = _cloneDigits(xDigits, 0, xUsed, maxUsed);
- yDigits = _cloneDigits(yDigits, 0, yUsed, maxUsed);
- int shiftAmount = 0;
- if (inv) {
- if ((yUsed == 1) && (yDigits[0] == 1)) return one;
- if ((yUsed == 0) || (yDigits[0].isEven && xDigits[0].isEven)) {
- throw new Exception("Not coprime");
- }
- } else {
- if (x._isZero) {
- throw new ArgumentError.value(0, "this", "must not be zero");
- }
- if (y._isZero) {
- throw new ArgumentError.value(0, "other", "must not be zero");
- }
- if (((xUsed == 1) && (xDigits[0] == 1)) ||
- ((yUsed == 1) && (yDigits[0] == 1))) return one;
- while (((xDigits[0] & 1) == 0) && ((yDigits[0] & 1) == 0)) {
- _rsh(xDigits, xUsed, 1, xDigits);
- _rsh(yDigits, yUsed, 1, yDigits);
- shiftAmount++;
- }
- if (shiftAmount >= _digitBits) {
- var digitShiftAmount = shiftAmount ~/ _digitBits;
- xUsed -= digitShiftAmount;
- yUsed -= digitShiftAmount;
- maxUsed -= digitShiftAmount;
- }
- if ((yDigits[0] & 1) == 1) {
- // Swap x and y.
- var tmpDigits = xDigits;
- var tmpUsed = xUsed;
- xDigits = yDigits;
- xUsed = yUsed;
- yDigits = tmpDigits;
- yUsed = tmpUsed;
- }
- }
- var uDigits = _cloneDigits(xDigits, 0, xUsed, unshiftedMaxUsed);
- var vDigits =
- _cloneDigits(yDigits, 0, yUsed, unshiftedMaxUsed + 2); // +2 for lsh.
- final bool ac = (xDigits[0] & 1) == 0;
-
- // Variables a, b, c, and d require one more digit.
- final abcdUsed = maxUsed + 1;
- final abcdLen = abcdUsed + 2; // +2 to satisfy _absAdd.
- var aDigits, bDigits, cDigits, dDigits;
- bool aIsNegative, bIsNegative, cIsNegative, dIsNegative;
- if (ac) {
- aDigits = new Uint16List(abcdLen);
- aIsNegative = false;
- aDigits[0] = 1;
- cDigits = new Uint16List(abcdLen);
- cIsNegative = false;
- }
- bDigits = new Uint16List(abcdLen);
- bIsNegative = false;
- dDigits = new Uint16List(abcdLen);
- dIsNegative = false;
- dDigits[0] = 1;
-
- while (true) {
- while ((uDigits[0] & 1) == 0) {
- _rsh(uDigits, maxUsed, 1, uDigits);
- if (ac) {
- if (((aDigits[0] & 1) == 1) || ((bDigits[0] & 1) == 1)) {
- if (aIsNegative) {
- if ((aDigits[maxUsed] != 0) ||
- (_compareDigits(aDigits, maxUsed, yDigits, maxUsed)) > 0) {
- _absSub(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
- } else {
- _absSub(yDigits, maxUsed, aDigits, maxUsed, aDigits);
- aIsNegative = false;
- }
- } else {
- _absAdd(aDigits, abcdUsed, yDigits, maxUsed, aDigits);
- }
- if (bIsNegative) {
- _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
- } else if ((bDigits[maxUsed] != 0) ||
- (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
- } else {
- _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
- bIsNegative = true;
- }
- }
- _rsh(aDigits, abcdUsed, 1, aDigits);
- } else if ((bDigits[0] & 1) == 1) {
- if (bIsNegative) {
- _absAdd(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
- } else if ((bDigits[maxUsed] != 0) ||
- (_compareDigits(bDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(bDigits, abcdUsed, xDigits, maxUsed, bDigits);
- } else {
- _absSub(xDigits, maxUsed, bDigits, maxUsed, bDigits);
- bIsNegative = true;
- }
- }
- _rsh(bDigits, abcdUsed, 1, bDigits);
- }
- while ((vDigits[0] & 1) == 0) {
- _rsh(vDigits, maxUsed, 1, vDigits);
- if (ac) {
- if (((cDigits[0] & 1) == 1) || ((dDigits[0] & 1) == 1)) {
- if (cIsNegative) {
- if ((cDigits[maxUsed] != 0) ||
- (_compareDigits(cDigits, maxUsed, yDigits, maxUsed) > 0)) {
- _absSub(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
- } else {
- _absSub(yDigits, maxUsed, cDigits, maxUsed, cDigits);
- cIsNegative = false;
- }
- } else {
- _absAdd(cDigits, abcdUsed, yDigits, maxUsed, cDigits);
- }
- if (dIsNegative) {
- _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- } else if ((dDigits[maxUsed] != 0) ||
- (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- } else {
- _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
- dIsNegative = true;
- }
- }
- _rsh(cDigits, abcdUsed, 1, cDigits);
- } else if ((dDigits[0] & 1) == 1) {
- if (dIsNegative) {
- _absAdd(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- } else if ((dDigits[maxUsed] != 0) ||
- (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- } else {
- _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
- dIsNegative = true;
- }
- }
- _rsh(dDigits, abcdUsed, 1, dDigits);
- }
- if (_compareDigits(uDigits, maxUsed, vDigits, maxUsed) >= 0) {
- _absSub(uDigits, maxUsed, vDigits, maxUsed, uDigits);
- if (ac) {
- if (aIsNegative == cIsNegative) {
- var a_cmp_c = _compareDigits(aDigits, abcdUsed, cDigits, abcdUsed);
- if (a_cmp_c > 0) {
- _absSub(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
- } else {
- _absSub(cDigits, abcdUsed, aDigits, abcdUsed, aDigits);
- aIsNegative = !aIsNegative && (a_cmp_c != 0);
- }
- } else {
- _absAdd(aDigits, abcdUsed, cDigits, abcdUsed, aDigits);
- }
- }
- if (bIsNegative == dIsNegative) {
- var b_cmp_d = _compareDigits(bDigits, abcdUsed, dDigits, abcdUsed);
- if (b_cmp_d > 0) {
- _absSub(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
- } else {
- _absSub(dDigits, abcdUsed, bDigits, abcdUsed, bDigits);
- bIsNegative = !bIsNegative && (b_cmp_d != 0);
- }
- } else {
- _absAdd(bDigits, abcdUsed, dDigits, abcdUsed, bDigits);
- }
- } else {
- _absSub(vDigits, maxUsed, uDigits, maxUsed, vDigits);
- if (ac) {
- if (cIsNegative == aIsNegative) {
- var c_cmp_a = _compareDigits(cDigits, abcdUsed, aDigits, abcdUsed);
- if (c_cmp_a > 0) {
- _absSub(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
- } else {
- _absSub(aDigits, abcdUsed, cDigits, abcdUsed, cDigits);
- cIsNegative = !cIsNegative && (c_cmp_a != 0);
- }
- } else {
- _absAdd(cDigits, abcdUsed, aDigits, abcdUsed, cDigits);
- }
- }
- if (dIsNegative == bIsNegative) {
- var d_cmp_b = _compareDigits(dDigits, abcdUsed, bDigits, abcdUsed);
- if (d_cmp_b > 0) {
- _absSub(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
- } else {
- _absSub(bDigits, abcdUsed, dDigits, abcdUsed, dDigits);
- dIsNegative = !dIsNegative && (d_cmp_b != 0);
- }
- } else {
- _absAdd(dDigits, abcdUsed, bDigits, abcdUsed, dDigits);
- }
- }
- // Exit loop if u == 0.
- var i = maxUsed;
- while ((i > 0) && (uDigits[i - 1] == 0)) --i;
- if (i == 0) break;
- }
- if (!inv) {
- if (shiftAmount > 0) {
- maxUsed = _lShiftDigits(vDigits, maxUsed, shiftAmount, vDigits);
- }
- return new _BigIntImpl._(false, maxUsed, vDigits);
- }
- // No inverse if v != 1.
- var i = maxUsed - 1;
- while ((i > 0) && (vDigits[i] == 0)) --i;
- if ((i != 0) || (vDigits[0] != 1)) {
- throw new Exception("Not coprime");
- }
-
- if (dIsNegative) {
- if ((dDigits[maxUsed] != 0) ||
- (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- if ((dDigits[maxUsed] != 0) ||
- (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- } else {
- _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
- dIsNegative = false;
- }
- } else {
- _absSub(xDigits, maxUsed, dDigits, maxUsed, dDigits);
- dIsNegative = false;
- }
- } else if ((dDigits[maxUsed] != 0) ||
- (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- if ((dDigits[maxUsed] != 0) ||
- (_compareDigits(dDigits, maxUsed, xDigits, maxUsed) > 0)) {
- _absSub(dDigits, abcdUsed, xDigits, maxUsed, dDigits);
- }
- }
- return new _BigIntImpl._(false, maxUsed, dDigits);
- }
-
- /**
- * Returns the modular multiplicative inverse of this big integer
- * modulo [modulus].
- *
- * The [modulus] must be positive.
- *
- * It is an error if no modular inverse exists.
- */
- // Returns 1/this % modulus, with modulus > 0.
- _BigIntImpl modInverse(BigInt bigInt) {
- _BigIntImpl modulus = bigInt;
- if (modulus <= zero) {
- throw new ArgumentError("Modulus must be strictly positive: $modulus");
- }
- if (modulus == one) return zero;
- var tmp = this;
- if (tmp._isNegative || (tmp._absCompare(modulus) >= 0)) {
- tmp %= modulus;
- }
- return _binaryGcd(modulus, tmp, true);
- }
-
- /**
- * Returns the greatest common divisor of this big integer and [other].
- *
- * If either number is non-zero, the result is the numerically greatest
- * integer dividing both `this` and `other`.
- *
- * The greatest common divisor is independent of the order,
- * so `x.gcd(y)` is always the same as `y.gcd(x)`.
- *
- * For any integer `x`, `x.gcd(x)` is `x.abs()`.
- *
- * If both `this` and `other` is zero, the result is also zero.
- */
- _BigIntImpl gcd(BigInt bigInt) {
- _BigIntImpl other = bigInt;
- if (_isZero) return other.abs();
- if (other._isZero) return this.abs();
- return _binaryGcd(this, other, false);
- }
-
- /**
- * Returns the least significant [width] bits of this big integer as a
- * non-negative number (i.e. unsigned representation). The returned value has
- * zeros in all bit positions higher than [width].
- *
- * ```
- * new BigInt.from(-1).toUnsigned(5) == 31 // 11111111 -> 00011111
- * ```
- *
- * This operation can be used to simulate arithmetic from low level languages.
- * For example, to increment an 8 bit quantity:
- *
- * ```
- * q = (q + 1).toUnsigned(8);
- * ```
- *
- * `q` will count from `0` up to `255` and then wrap around to `0`.
- *
- * If the input fits in [width] bits without truncation, the result is the
- * same as the input. The minimum width needed to avoid truncation of `x` is
- * given by `x.bitLength`, i.e.
- *
- * ```
- * x == x.toUnsigned(x.bitLength);
- * ```
- */
- _BigIntImpl toUnsigned(int width) {
- return this & ((one << width) - one);
- }
-
- /**
- * Returns the least significant [width] bits of this integer, extending the
- * highest retained bit to the sign. This is the same as truncating the value
- * to fit in [width] bits using an signed 2-s complement representation. The
- * returned value has the same bit value in all positions higher than [width].
- *
- * ```
- * var big15 = new BigInt.from(15);
- * var big16 = new BigInt.from(16);
- * var big239 = new BigInt.from(239);
- * V--sign bit-V
- * big16.toSigned(5) == -big16 // 00010000 -> 11110000
- * big239.toSigned(5) == big15 // 11101111 -> 00001111
- * ^ ^
- * ```
- *
- * This operation can be used to simulate arithmetic from low level languages.
- * For example, to increment an 8 bit signed quantity:
- *
- * ```
- * q = (q + 1).toSigned(8);
- * ```
- *
- * `q` will count from `0` up to `127`, wrap to `-128` and count back up to
- * `127`.
- *
- * If the input value fits in [width] bits without truncation, the result is
- * the same as the input. The minimum width needed to avoid truncation of `x`
- * is `x.bitLength + 1`, i.e.
- *
- * ```
- * x == x.toSigned(x.bitLength + 1);
- * ```
- */
- _BigIntImpl toSigned(int width) {
- // The value of binary number weights each bit by a power of two. The
- // twos-complement value weights the sign bit negatively. We compute the
- // value of the negative weighting by isolating the sign bit with the
- // correct power of two weighting and subtracting it from the value of the
- // lower bits.
- var signMask = one << (width - 1);
- return (this & (signMask - one)) - (this & signMask);
- }
-
- // TODO(floitsch): implement `isValidInt`.
- // Remove the comment in [BigInt.isValidInt] when done.
- bool get isValidInt => true;
-
- // TODO(floitsch): implement the clamping. It behaves differently on dart2js
- // and the VM.
- // Remove the comment in [BigInt.isValidInt] when done.
- int toInt() {
- var result = 0;
- for (int i = _used - 1; i >= 0; i--) {
- result = result * _digitBase + _digits[i];
- }
- return _isNegative ? -result : result;
- }
-
- /**
- * Returns this [_BigIntImpl] as a [double].
- *
- * If the number is not representable as a [double], an
- * approximation is returned. For numerically large integers, the
- * approximation may be infinite.
- */
- double toDouble() {
- const int exponentBias = 1075;
- // There are 11 bits for the exponent.
- // 2047 (all bits set to 1) is reserved for infinity and NaN.
- // When storing the exponent in the 11 bits, it is biased by exponentBias
- // to support negative exponents.
- const int maxDoubleExponent = 2046 - exponentBias;
- if (_isZero) return 0.0;
-
- // We fill the 53 bits little-endian.
- var resultBits = new Uint8List(8);
-
- var length = _digitBits * (_used - 1) + _digits[_used - 1].bitLength;
- if (length - 53 > maxDoubleExponent) return double.INFINITY;
-
- // The most significant bit is for the sign.
- if (_isNegative) resultBits[7] = 0x80;
-
- // Write the exponent into bits 1..12:
- var biasedExponent = length - 53 + exponentBias;
- resultBits[6] = (biasedExponent & 0xF) << 4;
- resultBits[7] |= biasedExponent >> 4;
-
- int cachedBits = 0;
- int cachedBitsLength = 0;
- int digitIndex = _used - 1;
- int readBits(int n) {
- // Ensure that we have enough bits in [cachedBits].
- while (cachedBitsLength < n) {
- int nextDigit;
- int nextDigitLength = _digitBits; // May get updated.
- if (digitIndex < 0) {
- nextDigit = 0;
- digitIndex--;
- } else {
- nextDigit = _digits[digitIndex];
- if (digitIndex == _used - 1) nextDigitLength = nextDigit.bitLength;
- digitIndex--;
- }
- cachedBits = (cachedBits << nextDigitLength) + nextDigit;
- cachedBitsLength += nextDigitLength;
- }
- // Read the top [n] bits.
- var result = cachedBits >> (cachedBitsLength - n);
- // Remove the bits from the cache.
- cachedBits -= result << (cachedBitsLength - n);
- cachedBitsLength -= n;
- return result;
- }
-
- // The first leading 1 bit is implicit in the double-representation and can
- // be discarded.
- var leadingBits = readBits(5) & 0xF;
- resultBits[6] |= leadingBits;
-
- for (int i = 5; i >= 0; i--) {
- // Get the remaining 48 bits.
- resultBits[i] = readBits(8);
- }
-
- void roundUp() {
- // Simply consists of adding 1 to the whole 64 bit "number".
- // It will update the exponent, if necessary.
- // It might even round up to infinity (which is what we want).
- var carry = 1;
- for (int i = 0; i < 8; i++) {
- if (carry == 0) break;
- var sum = resultBits[i] + carry;
- resultBits[i] = sum & 0xFF;
- carry = sum >> 8;
- }
- }
-
- if (readBits(1) == 1) {
- if (resultBits[0].isOdd) {
- // Rounds to even all the time.
- roundUp();
- } else {
- // Round up, if there is at least one other digit that is not 0.
- if (cachedBits != 0) {
- // There is already one in the cachedBits.
- roundUp();
- } else {
- for (int i = digitIndex; digitIndex >= 0; i--) {
- if (_digits[i] != 0) {
- roundUp();
- break;
- }
- }
- }
- }
- }
- return resultBits.buffer.asByteData().getFloat64(0, Endian.little);
- }
-
- /**
- * Returns a String-representation of this integer.
- *
- * The returned string is parsable by [parse].
- * For any `_BigIntImpl` `i`, it is guaranteed that
- * `i == _BigIntImpl.parse(i.toString())`.
- */
- String toString() {
- if (_used == 0) return "0";
- if (_used == 1) {
- if (_isNegative) return (-_digits[0]).toString();
- return _digits[0].toString();
- }
-
- // Generate in chunks of 4 digits.
- // The chunks are in reversed order.
- var decimalDigitChunks = <String>[];
- var rest = isNegative ? -this : this;
- while (rest._used > 1) {
- var digits4 = rest.remainder(_bigInt10000).toString();
- decimalDigitChunks.add(digits4);
- if (digits4.length == 1) decimalDigitChunks.add("000");
- if (digits4.length == 2) decimalDigitChunks.add("00");
- if (digits4.length == 3) decimalDigitChunks.add("0");
- rest = rest ~/ _bigInt10000;
- }
- decimalDigitChunks.add(rest._digits[0].toString());
- if (_isNegative) decimalDigitChunks.add("-");
- return decimalDigitChunks.reversed.join();
- }
-
- int _toRadixCodeUnit(int digit) {
- const int _0 = 48;
- const int _a = 97;
- if (digit < 10) return _0 + digit;
- return _a + digit - 10;
- }
-
- /**
- * Converts [this] to a string representation in the given [radix].
- *
- * In the string representation, lower-case letters are used for digits above
- * '9', with 'a' being 10 an 'z' being 35.
- *
- * The [radix] argument must be an integer in the range 2 to 36.
- */
- String toRadixString(int radix) {
- if (radix > 36) throw new RangeError.range(radix, 2, 36);
-
- if (_used == 0) return "0";
-
- if (_used == 1) {
- var digitString = _digits[0].toRadixString(radix);
- if (_isNegative) return "-" + digitString;
- return digitString;
- }
-
- if (radix == 16) return _toHexString();
-
- var base = new _BigIntImpl._fromInt(radix);
- var reversedDigitCodeUnits = <int>[];
- var rest = this.abs();
- while (!rest._isZero) {
- var digit = rest.remainder(base).toInt();
- rest = rest ~/ base;
- reversedDigitCodeUnits.add(_toRadixCodeUnit(digit));
- }
- var digitString = new String.fromCharCodes(reversedDigitCodeUnits.reversed);
- if (_isNegative) return "-" + digitString;
- return digitString;
- }
-
- String _toHexString() {
- var chars = <int>[];
- for (int i = 0; i < _used - 1; i++) {
- int chunk = _digits[i];
- for (int j = 0; j < (_digitBits ~/ 4); j++) {
- chars.add(_toRadixCodeUnit(chunk & 0xF));
- chunk >>= 4;
- }
- }
- var msbChunk = _digits[_used - 1];
- while (msbChunk != 0) {
- chars.add(_toRadixCodeUnit(msbChunk & 0xF));
- msbChunk >>= 4;
- }
- if (_isNegative) {
- const _dash = 45;
- chars.add(_dash);
- }
- return new String.fromCharCodes(chars.reversed);
- }
-}
-
-// Interface for modular reduction.
-abstract class _BigIntReduction {
- // Return the number of digits used by r_digits.
- int convert(_BigIntImpl x, Uint16List r_digits);
- int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
- Uint16List resultDigits);
- int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits);
-
- // Return x reverted to _BigIntImpl.
- _BigIntImpl revert(Uint16List xDigits, int xUsed);
-}
-
-// Modular reduction using "classic" algorithm.
-class _BigIntClassic implements _BigIntReduction {
- final _BigIntImpl _modulus; // Modulus.
- final _BigIntImpl _normalizedModulus; // Normalized _modulus.
-
- _BigIntClassic(this._modulus)
- : _normalizedModulus = _modulus <<
- (_BigIntImpl._digitBits -
- _modulus._digits[_modulus._used - 1].bitLength);
-
- int convert(_BigIntImpl x, Uint16List resultDigits) {
- var digits;
- var used;
- if (x._isNegative || x.compareTo(_modulus) >= 0) {
- var remainder = x._rem(_modulus);
- if (x._isNegative && !remainder._isNegative && remainder._used > 0) {
- remainder = _modulus - remainder;
- }
- assert(!remainder._isNegative);
- used = remainder._used;
- digits = remainder._digits;
- } else {
- used = x._used;
- digits = x._digits;
- }
- var i = used; // Copy leading zero if any.
- while (--i >= 0) {
- resultDigits[i] = digits[i];
- }
- return used;
- }
-
- _BigIntImpl revert(Uint16List xDigits, int xUsed) {
- return new _BigIntImpl._(false, xUsed, xDigits);
- }
-
- int _reduce(Uint16List xDigits, int xUsed) {
- if (xUsed < _modulus._used) {
- return xUsed;
- }
- var reverted = revert(xDigits, xUsed);
- var rem = reverted._rem(_normalizedModulus);
- return convert(rem, xDigits);
- }
-
- int sqr(Uint16List xDigits, int xUsed, Uint16List resultDigits) {
- var b = new _BigIntImpl._(false, xUsed, xDigits);
- var b2 = b * b;
- for (int i = 0; i < b2._used; i++) {
- resultDigits[i] = b2._digits[i];
- }
- for (int i = b2._used; i < 2 * xUsed; i++) {
- resultDigits[i] = 0;
- }
- return _reduce(resultDigits, 2 * xUsed);
- }
-
- int mul(Uint16List xDigits, int xUsed, Uint16List yDigits, int yUsed,
- Uint16List resultDigits) {
- var resultUsed =
- _BigIntImpl._mulDigits(xDigits, xUsed, yDigits, yUsed, resultDigits);
- return _reduce(resultDigits, resultUsed);
- }
-}
diff --git a/sdk/lib/core/regexp.dart b/sdk/lib/core/regexp.dart
index 7388256..95e12b5 100644
--- a/sdk/lib/core/regexp.dart
+++ b/sdk/lib/core/regexp.dart
@@ -24,11 +24,12 @@
*
* The following example finds all matches of a regular expression in
* a string.
+ * ```dart
+ * RegExp exp = new RegExp(r"(\w+)");
+ * String str = "Parse my string";
+ * Iterable<Match> matches = exp.allMatches(str);
+ * ```
*
- * RegExp exp = new RegExp(r"(\w+)");
- * String str = "Parse my string";
- * Iterable<Match> matches = exp.allMatches(str);
- *
* Note the use of a _raw string_ (a string prefixed with `r`)
* in the example above. Use a raw string to treat each character in a string
* as a literal character.
@@ -44,6 +45,19 @@
{bool multiLine: false, bool caseSensitive: true});
/**
+ * Returns a regular expression that matches [text].
+ *
+ * If [text] contains characters that are meaningful in regular expressions,
+ * the resulting regular expression will match those characters literally.
+ * If [text] contains no characters that have special meaning in a regular
+ * expression, it is returned unmodified.
+ *
+ * The characters that have special meaning in regular expressions are:
+ * `(`, `)`, `[`, `]`, `{`, `}`, `*`, `+`, `?`, `.`, `^`, `$`, `|` and `\`.
+ */
+ external static String escape(String text);
+
+ /**
* Searches for the first match of the regular expression
* in the string [input]. Returns `null` if there is no match.
*/
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index a5c6212..9a4ae55 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -9651,9 +9651,9 @@
@DomName('DirectoryEntry.getDirectory')
@DocsEditable()
void __getDirectory(String path,
- {Map options,
+ [Map options,
_EntryCallback successCallback,
- _ErrorCallback errorCallback}) {
+ _ErrorCallback errorCallback]) {
if (errorCallback != null) {
var options_1 = convertDartToNative_Dictionary(options);
__getDirectory_1(path, options_1, successCallback, errorCallback);
@@ -9696,9 +9696,9 @@
@DocsEditable()
Future<Entry> _getDirectory(String path, {Map options}) {
var completer = new Completer<Entry>();
- __getDirectory(path, options: options, successCallback: (value) {
+ __getDirectory(path, options, (value) {
completer.complete(value);
- }, errorCallback: (error) {
+ }, (error) {
completer.completeError(error);
});
return completer.future;
@@ -9707,9 +9707,9 @@
@DomName('DirectoryEntry.getFile')
@DocsEditable()
void __getFile(String path,
- {Map options,
+ [Map options,
_EntryCallback successCallback,
- _ErrorCallback errorCallback}) {
+ _ErrorCallback errorCallback]) {
if (errorCallback != null) {
var options_1 = convertDartToNative_Dictionary(options);
__getFile_1(path, options_1, successCallback, errorCallback);
@@ -9752,10 +9752,10 @@
@DocsEditable()
Future<Entry> _getFile(String path, {Map options}) {
var completer = new Completer<Entry>();
- __getFile(path, options: options, successCallback: (value) {
+ __getFile(path, options, (value) {
applyExtension('FileEntry', value);
completer.complete(value);
- }, errorCallback: (error) {
+ }, (error) {
completer.completeError(error);
});
return completer.future;
@@ -16310,18 +16310,18 @@
@DomName('Entry.copyTo')
@DocsEditable()
void _copyTo(DirectoryEntry parent,
- {String name,
+ [String name,
_EntryCallback successCallback,
- _ErrorCallback errorCallback}) native;
+ _ErrorCallback errorCallback]) native;
@JSName('copyTo')
@DomName('Entry.copyTo')
@DocsEditable()
Future<Entry> copyTo(DirectoryEntry parent, {String name}) {
var completer = new Completer<Entry>();
- _copyTo(parent, name: name, successCallback: (value) {
+ _copyTo(parent, name, (value) {
completer.complete(value);
- }, errorCallback: (error) {
+ }, (error) {
completer.completeError(error);
});
return completer.future;
@@ -16339,6 +16339,7 @@
Future<Metadata> getMetadata() {
var completer = new Completer<Metadata>();
_getMetadata((value) {
+ applyExtension('Metadata', value);
completer.complete(value);
}, (error) {
completer.completeError(error);
@@ -16369,18 +16370,18 @@
@DomName('Entry.moveTo')
@DocsEditable()
void _moveTo(DirectoryEntry parent,
- {String name,
+ [String name,
_EntryCallback successCallback,
- _ErrorCallback errorCallback}) native;
+ _ErrorCallback errorCallback]) native;
@JSName('moveTo')
@DomName('Entry.moveTo')
@DocsEditable()
Future<Entry> moveTo(DirectoryEntry parent, {String name}) {
var completer = new Completer<Entry>();
- _moveTo(parent, name: name, successCallback: (value) {
+ _moveTo(parent, name, (value) {
completer.complete(value);
- }, errorCallback: (error) {
+ }, (error) {
completer.completeError(error);
});
return completer.future;
@@ -17219,6 +17220,16 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+// WARNING: Do not edit - generated code.
+
+@DomName('FileCallback')
+// http://www.w3.org/TR/file-system-api/#the-filecallback-interface
+@Experimental()
+typedef void _FileCallback(File file);
+// 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
+// BSD-style license that can be found in the LICENSE file.
+
@DocsEditable()
@DomName('FileEntry')
// http://www.w3.org/TR/file-system-api/#the-fileentry-interface
@@ -17253,16 +17264,16 @@
@JSName('file')
@DomName('FileEntry.file')
@DocsEditable()
- void _file(BlobCallback successCallback, [_ErrorCallback errorCallback])
+ void _file(_FileCallback successCallback, [_ErrorCallback errorCallback])
native;
@JSName('file')
@DomName('FileEntry.file')
@DocsEditable()
- Future<Blob> file() {
- var completer = new Completer<Blob>();
+ Future<File> file() {
+ var completer = new Completer<File>();
_file((value) {
- applyExtension('Blob', value);
+ applyExtension('File', value);
completer.complete(value);
}, (error) {
completer.completeError(error);
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index be981c7..e1a1a6e 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -18,6 +18,7 @@
"../../runtime/lib/array.dart",
"../../runtime/lib/array_patch.dart",
"../../runtime/lib/bigint.dart",
+ "../../runtime/lib/bigint_patch.dart",
"../../runtime/lib/bool_patch.dart",
"../../runtime/lib/date_patch.dart",
"../../runtime/lib/double.dart",
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index deff85f..c959674 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -50,6 +50,7 @@
- "../../runtime/lib/array.dart"
- "../../runtime/lib/array_patch.dart"
- "../../runtime/lib/bigint.dart"
+ - "../../runtime/lib/bigint_patch.dart"
- "../../runtime/lib/bool_patch.dart"
- "../../runtime/lib/date_patch.dart"
- "../../runtime/lib/double.dart"
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer.status
similarity index 88%
rename from tests/co19/co19-analyzer2.status
rename to tests/co19/co19-analyzer.status
index 85a56bd..a4810dd 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer.status
@@ -3,12 +3,25 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2analyzer ]
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t01: MissingStaticWarning # test is out of date
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t02: MissingStaticWarning # test is out of date
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t04: MissingStaticWarning # test is out of date
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t05: MissingStaticWarning # test is out of date
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t06: MissingStaticWarning # test is out of date
Language/Classes/Classes/method_definition_t06: MissingStaticWarning # Please triage this failure.
Language/Classes/Getters/static_getter_t02: CompileTimeError # Issue 24534
Language/Classes/Getters/static_t01: StaticWarning # Please triage this failure.
Language/Classes/Getters/void_return_type_t01: MissingStaticWarning # Issue co19/30264
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t01: MissingStaticWarning # test is out of date
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t02: MissingStaticWarning # test is out of date
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t04: MissingStaticWarning # test is out of date
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t05: MissingStaticWarning # test is out of date
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t06: MissingStaticWarning # test is out of date
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t07: MissingStaticWarning # test is out of date
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t09: MissingStaticWarning # test is out of date
Language/Classes/Instance_Variables/definition_t03: StaticWarning # Please triage this failure.
Language/Classes/Static_Methods/same_name_method_and_setter_t01: MissingStaticWarning # Issue 23749
+Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t02: MissingStaticWarning # test is out of date
Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t05: MissingStaticWarning # TBF: Static members should not be accessible via subclasses.
Language/Classes/definition_t23: CompileTimeError # This seems correct, need to adjust test.
Language/Classes/method_definition_t06: MissingStaticWarning # Please triage this failure.
@@ -16,7 +29,10 @@
Language/Enums/syntax_t09: MissingCompileTimeError # Please triage this failure.
Language/Expressions/Assignment/super_assignment_static_warning_t03: StaticWarning # Issue 15467
Language/Expressions/Constants/exception_t01: Fail, OK # co19 issue #438, Static variables are initialized lazily, need not be constants
-Language/Expressions/Constants/exception_t02: Fail, OK # co19 issue #438, Static variables are initialized lazily, need not be constants
+Language/Expressions/Constants/literal_number_t01: CompileTimeError # int64
+Language/Expressions/Constants/logical_expression_t03: MissingCompileTimeError
+Language/Expressions/Constants/math_operators_t01: CompileTimeError # int64
+Language/Expressions/Constants/math_operators_t06: CompileTimeError # int64
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/Function_Invocation/Unqualified_Invocation/invocation_t17: MissingCompileTimeError # Please triage this failure
@@ -46,6 +62,10 @@
Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: StaticWarning # Please triage this failure.
Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: StaticWarning # Please triage this failure.
Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: StaticWarning # Please triage this failure.
+Language/Expressions/Numbers/static_type_of_int_t01: CompileTimeError # int64
+Language/Expressions/Numbers/syntax_t06: CompileTimeError # int64
+Language/Expressions/Numbers/syntax_t09: CompileTimeError # int64
+Language/Expressions/Numbers/syntax_t10: CompileTimeError # int64
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t01: MissingCompileTimeError # Issue 24332
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t02: MissingCompileTimeError # Issue 24332
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t03: MissingCompileTimeError # Issue 24332
@@ -86,8 +106,10 @@
Language/Mixins/Mixin_Application/warning_t03: StaticWarning # This seems correct, need to adjust test.
Language/Mixins/declaring_constructor_t05: MissingCompileTimeError # Issue 24767
Language/Mixins/declaring_constructor_t06: MissingCompileTimeError # Issue 24767
+Language/Statements/Assert/execution_t08: StaticWarning
Language/Statements/Assert/syntax_t04: MissingCompileTimeError # Assert messages are enabled by default
-Language/Statements/Assert/type_t04: MissingStaticWarning # Please triage this failure
+Language/Statements/Assert/type_t02: StaticWarning
+Language/Statements/Assert/type_t08: StaticWarning
Language/Statements/Switch/last_statement_t03: MissingStaticWarning # Please triage this failure
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
@@ -175,8 +197,7 @@
LayoutTests/fast/html/article-element_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/html/aside-element_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/html/imports/import-element-removed-flag_t01: StaticWarning # Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: StaticWarning # Please triage this failure.
-LayoutTests/fast/html/imports/import-events_t01: CompileTimeError # Please triage this failure.
+LayoutTests/fast/html/imports/import-events_t01: CompileTimeError, StaticWarning # Please triage this failure.
LayoutTests/fast/html/select-dropdown-consistent-background-color_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/html/text-field-input-types_t01: StaticWarning # Please triage this failure.
LayoutTests/fast/inline/boundingBox-with-continuation_t01: StaticWarning # Please triage this failure.
@@ -219,7 +240,52 @@
LibTest/collection/SplayTreeMap/inherited_tests_A01_t01: StaticWarning # Please triage this failure.
LibTest/collection/SplayTreeSet/SplayTreeSet_class_A01_t01: StaticWarning # Please triage this failure.
LibTest/convert/JsonEncoder/JsonEncoder_A01_t01: StaticWarning # Please triage this failure
+LibTest/core/Duration/Duration_A02_t01: CompileTimeError # int64
LibTest/core/Set/IterableBase_A01_t01: StaticWarning # Imports libraries with static warnings
+LibTest/core/double/isInfinite_A01_t03: CompileTimeError # int64
+LibTest/core/double/toStringAsExponential_A02_t01: CompileTimeError # int64
+LibTest/core/int/abs_A01_t01: CompileTimeError # int64
+LibTest/core/int/ceilToDouble_A01_t01: CompileTimeError # int64
+LibTest/core/int/ceil_A01_t01: CompileTimeError # int64
+LibTest/core/int/compareTo_A01_t01: CompileTimeError # int64
+LibTest/core/int/floorToDouble_A01_t01: CompileTimeError # int64
+LibTest/core/int/floor_A01_t01: CompileTimeError # int64
+LibTest/core/int/isEven_A01_t01: CompileTimeError # int64
+LibTest/core/int/isInfinite_A01_t01: CompileTimeError # int64
+LibTest/core/int/isNaN_A01_t01: CompileTimeError # int64
+LibTest/core/int/isNegative_A01_t01: CompileTimeError # int64
+LibTest/core/int/isOdd_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_AND_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_GE_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_GT_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_LE_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_LT_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_NOT_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_OR_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_XOR_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_addition_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_division_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_left_shift_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_multiplication_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_remainder_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_remainder_A01_t02: CompileTimeError # int64
+LibTest/core/int/operator_right_shift_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_subtraction_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_truncating_division_A01_t01: CompileTimeError # int64
+LibTest/core/int/operator_truncating_division_A01_t02: CompileTimeError # int64
+LibTest/core/int/operator_unary_minus_A01_t01: CompileTimeError # int64
+LibTest/core/int/parse_A01_t01: CompileTimeError # int64
+LibTest/core/int/remainder_A01_t01: CompileTimeError # int64
+LibTest/core/int/remainder_A01_t02: CompileTimeError # int64
+LibTest/core/int/roundToDouble_A01_t01: CompileTimeError # int64
+LibTest/core/int/round_A01_t01: CompileTimeError # int64
+LibTest/core/int/toDouble_A01_t01: CompileTimeError # int64
+LibTest/core/int/toInt_A01_t01: CompileTimeError # int64
+LibTest/core/int/toStringAsExponential_A02_t01: CompileTimeError # int64
+LibTest/core/int/toStringAsFixed_A02_t01: CompileTimeError # int64
+LibTest/core/int/toStringAsPrecision_A01_t02: CompileTimeError # int64
+LibTest/core/int/truncateToDouble_A01_t01: CompileTimeError # int64
+LibTest/core/int/truncate_A01_t01: CompileTimeError # int64
LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: StaticWarning # Please triage this failure.
LibTest/html/Document/adoptNode_A01_t01: StaticWarning # Please triage this failure.
LibTest/html/Document/childNodes_A01_t01: StaticWarning # Please triage this failure.
@@ -280,12 +346,19 @@
LibTest/math/Point/operator_addition_A02_t01: StaticWarning # Please triage this failure.
LibTest/math/Point/operator_mult_A03_t01: StaticWarning # Please triage this failure.
LibTest/math/Point/operator_subtraction_A02_t01: StaticWarning # Please triage this failure.
+LibTest/math/pow_A10_t01: CompileTimeError # int64
+LibTest/typed_data/ByteData/getUint64_A01_t01: CompileTimeError # int64
+LibTest/typed_data/ByteData/setUint64_A01_t01: CompileTimeError # int64
LibTest/typed_data/Float32x4/equal_A01_t01: Skip # co19 issue 656
LibTest/typed_data/Float32x4/greaterThanOrEqual_A01_t01: Skip # co19 issue 656
LibTest/typed_data/Float32x4/greaterThan_A01_t01: Skip # co19 issue 656
LibTest/typed_data/Float32x4/lessThanOrEqual_A01_t01: Skip # co19 issue 656
LibTest/typed_data/Float32x4/lessThan_A01_t01: Skip # co19 issue 656
LibTest/typed_data/Float32x4/notEqual_A01_t01: Skip # co19 issue 656
+LibTest/typed_data/Uint64List/Uint64List.fromList_A01_t01: CompileTimeError # int64
+LibTest/typed_data/Uint64List/Uint64List.fromList_A01_t02: CompileTimeError # int64
+LibTest/typed_data/Uint64List/Uint64List.view_A01_t01: CompileTimeError # int64
+LibTest/typed_data/Uint64List/Uint64List.view_A01_t02: CompileTimeError # int64
WebPlatformTest/DOMEvents/approved/Event.bubbles.false_t01: StaticWarning # Please triage this failure.
WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: StaticWarning # Please triage this failure.
WebPlatformTest/custom-elements/*: Pass, StaticWarning # Issue 18095.
@@ -430,4 +503,3 @@
[ $builder_tag == strong && $compiler == dart2analyzer ]
*: Skip # Issue 28649
-
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index f6c1323..ce7e564 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -484,7 +484,9 @@
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-clip-text_t01: RuntimeError
LayoutTests/fast/css/background-serialize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/border-radius-property-value_t01: RuntimeError
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/content/content-none_t01: RuntimeError # Please triage this failure
@@ -514,6 +516,7 @@
LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getComputedStyle/font-family-fallback-reset_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/getPropertyValue-border_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/getPropertyValue-clip_t01: RuntimeError
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/implicit-attach-marking_t01: Skip # Times out. Please triage this failure
@@ -524,6 +527,7 @@
LayoutTests/fast/css/invalidation/targeted-class-shadow-combinator_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/max-device-aspect-ratio_t01: RuntimeError, Pass # Issue 28998
LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/modify-ua-rules-from-javascript_t01: RuntimeError
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-page-rule_t01: RuntimeError # Please triage this failure
@@ -547,6 +551,7 @@
LayoutTests/fast/css/transform-origin-parsing_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css/url-with-multi-byte-unicode-escape_t01: RuntimeError # co19 issue 14
LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/word-break-user-modify-allowed-values_t01: RuntimeError
LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent-inherited_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # Please triage this failure
@@ -635,9 +640,15 @@
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 # Please triage this failure
+LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: RuntimeError
+LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: RuntimeError
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-null-crash_t01: RuntimeError
+LayoutTests/fast/dom/Window/getMatchedCSSRules-parent-stylesheets_t01: RuntimeError
+LayoutTests/fast/dom/Window/getMatchedCSSRules-with-invalid-pseudo-elements_t01: RuntimeError
LayoutTests/fast/dom/Window/getMatchedCSSRules-with-pseudo-elements-complex_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/Window/getMatchedCSSRules-with-pseudo-elements_t01: RuntimeError
LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # Please triage this failure
@@ -662,8 +673,8 @@
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: Pass, 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/icon-size-property_t01: RuntimeError # https://github.com/dart-lang/sdk/issues/26422
LayoutTests/fast/dom/icon-size-property_t01: Skip # Roll 50 failure
+LayoutTests/fast/dom/icon-size-property_t01: RuntimeError # https://github.com/dart-lang/sdk/issues/26422
LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
@@ -672,25 +683,34 @@
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/distribution-crash_t01: RuntimeError
LayoutTests/fast/dom/shadow/distribution-update-recalcs-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/shadow/insertion-point-list-menu-crash_t01: RuntimeError
+LayoutTests/fast/dom/shadow/insertion-point-shadow-crash_t01: RuntimeError
+LayoutTests/fast/dom/shadow/insertion-point-video-crash_t01: RuntimeError
LayoutTests/fast/dom/shadow/link-in-shadow-tree_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/shadow/nested-reprojection-inconsistent_t01: RuntimeError
LayoutTests/fast/dom/shadow/olderShadowRoot_t01: RuntimeError # Issue 26729
LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-optgroup_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/pseudoclass-update-disabled-option_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/shadow/shadow-aware-shadow-root_t01: RuntimeError
LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # Please triage this failure
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
LayoutTests/fast/dom/shadow/shadowdom-for-input-spellcheck_t01: RuntimeError # Issue 26729
LayoutTests/fast/dom/shadow/shadowdom-for-input-type-change_t01: RuntimeError # Issue 26729
LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/dom/shadow/shadowroot-clonenode_t01: RuntimeError # Issue 26729
LayoutTests/fast/dom/shadow/shadowroot-host_t01: RuntimeError # Issue 26729
LayoutTests/fast/dom/shadow/shadowroot-keyframes_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/dom/shadow/stale-distribution-after-shadow-removal_t01: RuntimeError
+LayoutTests/fast/dom/shadow/style-sharing-styles-in-older-shadow-roots_t01: RuntimeError
LayoutTests/fast/dom/vertical-scrollbar-in-rtl-doesnt-fire-onscroll_t01: Pass, RuntimeError
LayoutTests/fast/dynamic/checkbox-selection-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # Please triage this failure
@@ -1196,15 +1216,19 @@
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: RuntimeError # Please triage this failure
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/attributes/test-005_t01: RuntimeError
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-element-interface/methods/test-003_t01: RuntimeError
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
WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-002_t01: RuntimeError
WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-004_t01: RuntimeError
WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/events/event-dispatch/test-002_t01: RuntimeError # Please triage this failure.
@@ -1234,10 +1258,16 @@
WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-004_t01: RuntimeError # Issue 26729
+WebPlatformTest/shadow-dom/shadow-trees/composition/test-001_t01: RuntimeError
WebPlatformTest/shadow-dom/shadow-trees/custom-pseudo-elements/test-001_t01: RuntimeError # Please triage this failure
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/hosting-multiple-shadow-trees/test-001_t01: RuntimeError
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-002_t01: RuntimeError
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-003_t01: RuntimeError
WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/shadow-trees/rendering-shadow-trees/test-001_t01: RuntimeError
+WebPlatformTest/shadow-dom/shadow-trees/reprojection/test-001_t01: RuntimeError
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-001_t01: RuntimeError # Please triage this failure.
WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-002_t01: RuntimeError # Please triage this failure.
@@ -1256,26 +1286,6 @@
LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError, Pass # Please triage this flake
LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError, Pass # Please triage this flake
LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # Please triage this flake
-LayoutTests/fast/css/background-clip-text_t01: RuntimeError
-LayoutTests/fast/css/border-radius-property-value_t01: RuntimeError
-LayoutTests/fast/css/getPropertyValue-clip_t01: RuntimeError
-LayoutTests/fast/css/modify-ua-rules-from-javascript_t01: RuntimeError
-LayoutTests/fast/css/word-break-user-modify-allowed-values_t01: RuntimeError
-LayoutTests/fast/dom/StyleSheet/removed-media-rule-deleted-parent-crash_t01: RuntimeError
-LayoutTests/fast/dom/StyleSheet/removed-stylesheet-rule-deleted-parent-crash_t01: RuntimeError
-LayoutTests/fast/dom/Window/getMatchedCSSRules-null-crash_t01: RuntimeError
-LayoutTests/fast/dom/Window/getMatchedCSSRules-parent-stylesheets_t01: RuntimeError
-LayoutTests/fast/dom/Window/getMatchedCSSRules-with-invalid-pseudo-elements_t01: RuntimeError
-LayoutTests/fast/dom/Window/getMatchedCSSRules-with-pseudo-elements_t01: RuntimeError
-LayoutTests/fast/dom/shadow/distribution-crash_t01: RuntimeError
-LayoutTests/fast/dom/shadow/insertion-point-list-menu-crash_t01: RuntimeError
-LayoutTests/fast/dom/shadow/insertion-point-shadow-crash_t01: RuntimeError
-LayoutTests/fast/dom/shadow/insertion-point-video-crash_t01: RuntimeError
-LayoutTests/fast/dom/shadow/nested-reprojection-inconsistent_t01: RuntimeError
-LayoutTests/fast/dom/shadow/shadow-aware-shadow-root_t01: RuntimeError
-LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError
-LayoutTests/fast/dom/shadow/stale-distribution-after-shadow-removal_t01: RuntimeError
-LayoutTests/fast/dom/shadow/style-sharing-styles-in-older-shadow-roots_t01: RuntimeError
LayoutTests/fast/multicol/newmulticol/balance_t04: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-left_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
@@ -1284,16 +1294,6 @@
LayoutTests/fast/text/regional-indicator-symobls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
LibTest/math/log_A01_t01: RuntimeError # Please triage this failure
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005_t01: RuntimeError
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-003_t01: RuntimeError
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-002_t01: RuntimeError
-WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-004_t01: RuntimeError
-WebPlatformTest/shadow-dom/shadow-trees/composition/test-001_t01: RuntimeError
-WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-001_t01: RuntimeError
-WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-002_t01: RuntimeError
-WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-003_t01: RuntimeError
-WebPlatformTest/shadow-dom/shadow-trees/rendering-shadow-trees/test-001_t01: RuntimeError
-WebPlatformTest/shadow-dom/shadow-trees/reprojection/test-001_t01: RuntimeError
[ $compiler == dart2js && $runtime == chrome && $system == macos ]
Language/Expressions/Function_Invocation/async_invokation_t04: RuntimeError # Please triage this failure
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index d599d4ec..2946921 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -60,8 +60,6 @@
# are to be triaged. Isolate tests are skipped on purpose due to the usage of
# batch mode.
[ $compiler == dartk && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
-Language/Classes/Superinterfaces/more_than_once_t01: MissingCompileTimeError # Please triaage.
-Language/Classes/Superinterfaces/superclass_as_superinterface_t01: MissingCompileTimeError # Please triaage.
Language/Classes/definition_t23: RuntimeError # Please triaage.
Language/Expressions/Spawning_an_Isolate/*: Skip
Language/Mixins/Mixin_Application/syntax_t16: RuntimeError # Please triaage.
@@ -140,8 +138,8 @@
Language/Expressions/Constants/math_operators_t05: Crash
Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t03: MissingCompileTimeError
Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t04: MissingCompileTimeError
-Language/Expressions/Instance_Creation/New/evaluation_t19: RuntimeError # Kernel Issue 28335 (deferred libraries)
-Language/Expressions/Instance_Creation/New/evaluation_t20: RuntimeError # Kernel Issue 28335 (deferred libraries)
+Language/Expressions/Instance_Creation/New/evaluation_t19: CompileTimeError # Issue 31938
+Language/Expressions/Instance_Creation/New/evaluation_t20: CompileTimeError # Issue 31938
Language/Expressions/Maps/key_value_equals_operator_t01: MissingCompileTimeError
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
@@ -157,7 +155,6 @@
Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError # Issue 24332
Language/Expressions/This/placement_t04: MissingCompileTimeError
Language/Expressions/Throw/syntax_t02: MissingCompileTimeError
-Language/Expressions/Type_Test/evaluation_t10: RuntimeError # Kernel Issue 28335 (deferred libraries)
Language/Functions/External_Functions/not_connected_to_a_body_t01: RuntimeError # Dartk Issue 28565
Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
@@ -185,12 +182,7 @@
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/Continue/label_t06: MissingCompileTimeError
Language/Statements/Continue/label_t07: MissingCompileTimeError
-Language/Statements/Continue/label_t08: MissingCompileTimeError
-Language/Statements/Continue/label_t09: MissingCompileTimeError
-Language/Statements/Continue/label_t10: MissingCompileTimeError
-Language/Statements/Continue/label_t11: MissingCompileTimeError
Language/Statements/For/syntax_t12: MissingCompileTimeError
Language/Statements/For/syntax_t13: MissingCompileTimeError
Language/Statements/For/syntax_t19: MissingCompileTimeError
@@ -205,7 +197,7 @@
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/Static_Types/deferred_type_t01: RuntimeError # Kernel Issue 28335 (deferred libraries)
+Language/Types/Dynamic_Type_System/deferred_type_error_t01: CompileTimeError # Issue 31938
Language/Types/Type_Void/syntax_t01: Pass # Issue 30470
Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError
Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index e423b3e..7190664 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -300,6 +300,9 @@
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/Types/Type_Void/syntax_t01: MissingCompileTimeError # Issue co19/30264
+Language/Types/Type_Void/syntax_t02: MissingCompileTimeError # Issue co19/30264
+Language/Types/Type_Void/syntax_t04: MissingCompileTimeError # Issue co19/30264
+Language/Types/Type_Void/syntax_t09: MissingCompileTimeError # Issue co19/30264
LayoutTests/fast/*: SkipByDesign # DOM not supported on VM.
LibTest/collection/ListBase/ListBase_class_A01_t01: RuntimeError # Large integers
LibTest/collection/ListMixin/ListMixin_class_A01_t01: RuntimeError # Large integers
diff --git a/tests/co19_2/.gitignore b/tests/co19_2/.gitignore
new file mode 100644
index 0000000..a57582c
--- /dev/null
+++ b/tests/co19_2/.gitignore
@@ -0,0 +1 @@
+/src
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status
new file mode 100644
index 0000000..5eea4d2
--- /dev/null
+++ b/tests/co19_2/co19_2-analyzer.status
@@ -0,0 +1,286 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $compiler == dart2analyzer && $strong ]
+Language/Classes/Abstract_Instance_Members/override_default_value_t01: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t02: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t03: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t04: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t05: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t01: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t02: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t04: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t05: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t06: MissingCompileTimeError
+Language/Classes/Getters/type_object_t01: CompileTimeError
+Language/Classes/Getters/type_object_t02: CompileTimeError
+Language/Classes/Instance_Methods/override_different_default_values_t01: MissingCompileTimeError
+Language/Classes/Instance_Methods/override_different_default_values_t02: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t01: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t02: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t04: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t05: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t06: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t07: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t09: MissingCompileTimeError
+Language/Classes/method_definition_t06: MissingCompileTimeError
+Language/Expressions/Assignment/expression_assignment_failed_t02: CompileTimeError
+Language/Expressions/Assignment/indexed_expression_super_t03: CompileTimeError
+Language/Expressions/Assignment/indexed_expression_super_t04: CompileTimeError
+Language/Expressions/Assignment/static_type_t02: CompileTimeError
+Language/Expressions/Assignment/static_type_t03: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t01: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t02: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t03: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t04: CompileTimeError
+Language/Expressions/Assignment/super_assignment_static_warning_t02: CompileTimeError
+Language/Expressions/Assignment/super_assignment_static_warning_t03: CompileTimeError
+Language/Expressions/Assignment/super_assignment_t06: CompileTimeError
+Language/Expressions/Assignment/super_assignment_value_t02: CompileTimeError
+Language/Expressions/Assignment/this_assignment_t02: CompileTimeError
+Language/Expressions/Constants/identifier_denotes_a_constant_t03: MissingCompileTimeError
+Language/Expressions/Identifier_Reference/built_in_identifier_t02: CompileTimeError
+Language/Expressions/Identifier_Reference/evaluation_library_or_getter_t01: StaticWarning
+Language/Expressions/Identifier_Reference/evaluation_property_extraction_t04: CompileTimeError
+Language/Expressions/Identifier_Reference/evaluation_type_parameter_t02: MissingCompileTimeError
+Language/Expressions/Lookup/Getter_and_Setter_Lookup/definition_t09: CompileTimeError
+Language/Expressions/Lookup/Getter_and_Setter_Lookup/definition_t10: CompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/accessible_instance_member_t03: CompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/accessible_instance_member_t04: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t01: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t02: CompileTimeError
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: CompileTimeError
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t02: CompileTimeError
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t03: CompileTimeError
+Language/Functions/generator_return_type_t02: MissingCompileTimeError
+Language/Functions/generator_return_type_t06: MissingCompileTimeError
+Language/Generics/syntax_t02: Crash
+Language/Generics/syntax_t03: Crash
+Language/Libraries_and_Scripts/Imports/namespace_changes_t01: StaticWarning
+Language/Libraries_and_Scripts/Imports/namespace_changes_t02: StaticWarning
+Language/Libraries_and_Scripts/Imports/namespace_changes_t16: StaticWarning
+Language/Libraries_and_Scripts/Imports/namespace_changes_t17: StaticWarning
+Language/Libraries_and_Scripts/Parts/compilation_t03: StaticWarning
+Language/Libraries_and_Scripts/Parts/compilation_t05: StaticWarning
+Language/Mixins/Mixin_Application/static_warning_t02: CompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t07: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t11: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t12: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t13: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t14: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t21: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t22: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t23: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t24: CompileTimeError
+Language/Mixins/Mixin_Application/syntax_t25: CompileTimeError
+Language/Mixins/Mixin_Application/warning_t01: CompileTimeError
+Language/Mixins/Mixin_Application/warning_t02: CompileTimeError
+Language/Mixins/Mixin_Application/warning_t03: CompileTimeError
+Language/Mixins/declaring_constructor_t05: MissingCompileTimeError
+Language/Mixins/declaring_constructor_t06: MissingCompileTimeError
+Language/Statements/Assert/execution_t10: MissingCompileTimeError
+Language/Statements/Assert/type_t02: MissingCompileTimeError
+Language/Statements/Assert/type_t04: MissingCompileTimeError
+Language/Statements/Do/condition_type_t02: MissingCompileTimeError
+Language/Types/Interface_Types/subtype_t12: StaticWarning
+Language/Types/Type_Declarations/Typedef/syntax_t01: StaticWarning
+Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
+Language/Types/Type_Void/using_t02: MissingCompileTimeError
+Language/Variables/final_or_static_initialization_t01: MissingCompileTimeError
+Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError
+Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError
+LayoutTests/fast/canvas/canvas-blending-clipping_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-color-over-color_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-color-over-gradient_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-color-over-image_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-color-over-pattern_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-fill-style_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-global-alpha_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-gradient-over-color_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-gradient-over-gradient_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-gradient-over-image_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-gradient-over-pattern_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-image-over-color_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-image-over-gradient_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-image-over-image_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-image-over-pattern_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-pattern-over-color_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-pattern-over-gradient_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-pattern-over-image_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-pattern-over-pattern_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-shadow_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-text_t01: StaticWarning
+LayoutTests/fast/canvas/canvas-blending-transforms_t01: StaticWarning
+LibTest/async/Stream/Stream.fromFutures_A01_t01: StaticWarning
+LibTest/async/Stream/Stream.fromFutures_A01_t02: StaticWarning
+LibTest/async/Stream/Stream.fromFutures_A02_t01: StaticWarning
+LibTest/async/Stream/Stream.fromFutures_A02_t02: StaticWarning
+LibTest/async/Stream/Stream.fromFutures_A04_t01: StaticWarning
+LibTest/async/Stream/Stream.fromIterable_A03_t01: StaticWarning
+LibTest/async/Stream/Stream.periodic_A01_t01: StaticWarning
+LibTest/async/Stream/Stream.periodic_A04_t01: StaticWarning
+LibTest/async/StreamController/StreamController.broadcast_A09_t01: StaticWarning
+LibTest/async/StreamController/StreamController.broadcast_A10_t01: StaticWarning
+LibTest/async/StreamController/stream_A02_t01: StaticWarning
+LibTest/async/StreamController/stream_A03_t01: StaticWarning
+LibTest/async/Zone/runBinaryGuarded_A01_t02: CompileTimeError
+LibTest/async/Zone/runUnary_A01_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/firstWhere_A02_t01: StaticWarning
+LibTest/collection/DoubleLinkedQueue/firstWhere_A03_t01: StaticWarning
+LibTest/collection/DoubleLinkedQueue/lastWhere_A02_t01: StaticWarning
+LibTest/collection/DoubleLinkedQueue/lastWhere_A03_t01: StaticWarning
+LibTest/collection/DoubleLinkedQueue/skipWhile_A02_t01: StaticWarning
+LibTest/collection/DoubleLinkedQueue/takeWhile_A02_t01: StaticWarning
+LibTest/collection/DoubleLinkedQueue/where_A02_t01: StaticWarning
+LibTest/collection/HashMap/HashMap_class_A01_t01: StaticWarning
+LibTest/collection/HashSet/HashSet_A01_t02: StaticWarning
+LibTest/collection/HashSet/HashSet_class_A01_t01: StaticWarning
+LibTest/collection/IterableBase/IterableBase_class_A01_t02: StaticWarning
+LibTest/collection/IterableMixin/IterableMixin_class_A02_t01: StaticWarning
+LibTest/collection/IterableMixin/contains_A02_t01: StaticWarning
+LibTest/collection/IterableMixin/every_A01_t01: StaticWarning
+LibTest/collection/IterableMixin/every_A01_t02: StaticWarning
+LibTest/collection/IterableMixin/every_A02_t01: StaticWarning
+LibTest/collection/IterableMixin/expand_A02_t01: StaticWarning
+LibTest/collection/IterableMixin/firstWhere_A02_t01: StaticWarning
+LibTest/collection/IterableMixin/firstWhere_A02_t02: StaticWarning
+LibTest/collection/IterableMixin/map_A03_t01: StaticWarning
+LibTest/collection/IterableMixin/skipWhile_A02_t01: StaticWarning
+LibTest/collection/IterableMixin/takeWhile_A02_t01: StaticWarning
+LibTest/collection/IterableMixin/where_A02_t01: StaticWarning
+LibTest/collection/LinkedHashMap/LinkedHashMap_A03_t01: StaticWarning
+LibTest/collection/LinkedHashMap/LinkedHashMap_A04_t01: StaticWarning
+LibTest/collection/LinkedHashMap/LinkedHashMap_A04_t02: StaticWarning
+LibTest/collection/LinkedHashMap/LinkedHashMap_class_A01_t01: StaticWarning
+LibTest/collection/LinkedHashSet/LinkedHashSet_A03_t01: StaticWarning
+LibTest/collection/LinkedHashSet/LinkedHashSet_A05_t01: StaticWarning
+LibTest/collection/LinkedHashSet/LinkedHashSet_A05_t02: StaticWarning
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: StaticWarning
+LibTest/collection/LinkedList/remove_A01_t01: StaticWarning
+LibTest/collection/ListBase/ListBase_class_A01_t01: StaticWarning
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: StaticWarning
+LibTest/collection/ListQueue/ListQueue_class_A01_t01: StaticWarning
+LibTest/collection/MapBase/MapBase_class_A01_t01: StaticWarning
+LibTest/collection/MapMixin/MapMixin_class_A01_t01: StaticWarning
+LibTest/collection/MapView/MapView_class_A01_t01: StaticWarning
+LibTest/collection/Maps/forEach_A01_t01: StaticWarning
+LibTest/collection/Maps/forEach_A01_t03: StaticWarning
+LibTest/collection/Maps/forEach_A01_t04: StaticWarning
+LibTest/collection/Maps/forEach_A01_t05: StaticWarning
+LibTest/collection/Maps/forEach_A01_t06: StaticWarning
+LibTest/collection/Maps/forEach_A02_t01: StaticWarning
+LibTest/collection/Queue/Queue_class_A01_t01: StaticWarning
+LibTest/collection/SetBase/SetBase_class_A01_t01: StaticWarning
+LibTest/collection/SetMixin/SetMixin_class_A01_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A03_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A05_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A06_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A06_t02: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterables_A04_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterables_A05_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterables_A05_t02: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.from_A02_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.from_A03_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap.from_A03_t02: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A02_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A02_t02: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A03_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A03_t02: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A04_t02: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A05_t01: StaticWarning
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A05_t02: StaticWarning
+LibTest/collection/SplayTreeMap/inherited_tests_A01_t01: StaticWarning
+LibTest/collection/SplayTreeSet/SplayTreeSet.from_A02_t07: StaticWarning
+LibTest/collection/SplayTreeSet/SplayTreeSet.from_A02_t08: StaticWarning
+LibTest/collection/SplayTreeSet/SplayTreeSet_A04_t01: StaticWarning
+LibTest/collection/SplayTreeSet/SplayTreeSet_A05_t01: StaticWarning
+LibTest/collection/SplayTreeSet/SplayTreeSet_A06_t01: StaticWarning
+LibTest/collection/SplayTreeSet/SplayTreeSet_class_A01_t01: StaticWarning
+LibTest/collection/UnmodifiableListView/UnmodifiableListView_class_A01_t01: StaticWarning
+LibTest/core/List/Iterable_A01_t01: StaticWarning
+LibTest/core/List/List_class_A01_t01: StaticWarning
+LibTest/core/List/List_class_A01_t02: StaticWarning
+LibTest/core/Map/allTests_A01_t01: StaticWarning
+LibTest/core/RegExp/allMatches_A01_t01: StaticWarning
+LibTest/core/Set/every_A01_t01: StaticWarning
+LibTest/core/Set/every_A01_t02: StaticWarning
+LibTest/core/Set/every_A01_t03: StaticWarning
+LibTest/core/Set/forEach_A01_t01: StaticWarning
+LibTest/core/Set/forEach_A01_t02: StaticWarning
+LibTest/core/Set/forEach_A01_t03: StaticWarning
+LibTest/core/Set/forEach_A01_t04: StaticWarning
+LibTest/core/Set/forEach_A01_t05: StaticWarning
+LibTest/core/double/operator_GE_A01_t03: StaticWarning
+LibTest/core/double/operator_GE_A02_t01: StaticWarning
+LibTest/core/double/operator_GT_A01_t03: StaticWarning
+LibTest/core/double/operator_GT_A02_t01: StaticWarning
+LibTest/core/double/operator_LE_A01_t03: StaticWarning
+LibTest/core/double/operator_LE_A02_t01: StaticWarning
+LibTest/core/double/operator_LT_A01_t03: StaticWarning
+LibTest/core/double/operator_LT_A02_t01: StaticWarning
+LibTest/core/double/operator_addition_A01_t07: StaticWarning
+LibTest/core/double/operator_addition_A02_t01: StaticWarning
+LibTest/core/double/operator_division_A01_t07: StaticWarning
+LibTest/core/double/operator_division_A01_t08: StaticWarning
+LibTest/core/double/operator_division_A01_t11: StaticWarning
+LibTest/core/double/operator_division_A02_t01: StaticWarning
+LibTest/core/double/operator_multiplication_A01_t06: StaticWarning
+LibTest/core/double/operator_multiplication_A01_t08: StaticWarning
+LibTest/core/double/operator_multiplication_A02_t01: StaticWarning
+LibTest/core/double/operator_remainder_A01_t02: StaticWarning
+LibTest/core/double/operator_remainder_A01_t03: StaticWarning
+LibTest/core/double/operator_remainder_A01_t04: StaticWarning
+LibTest/core/double/operator_remainder_A01_t05: StaticWarning
+LibTest/core/double/operator_remainder_A01_t06: StaticWarning
+LibTest/core/double/operator_remainder_A02_t01: StaticWarning
+LibTest/core/double/operator_subtraction_A01_t07: StaticWarning
+LibTest/core/double/operator_subtraction_A01_t08: StaticWarning
+LibTest/core/double/operator_subtraction_A02_t01: StaticWarning
+LibTest/core/double/operator_truncating_division_A01_t08: StaticWarning
+LibTest/core/double/operator_truncating_division_A02_t01: StaticWarning
+LibTest/core/double/remainder_A01_t02: StaticWarning
+LibTest/core/double/remainder_A01_t03: StaticWarning
+LibTest/core/double/remainder_A01_t04: StaticWarning
+LibTest/core/double/remainder_A01_t05: StaticWarning
+LibTest/core/double/remainder_A01_t06: StaticWarning
+LibTest/core/double/remainder_A02_t01: StaticWarning
+LibTest/core/double/toStringAsFixed_A02_t01: StaticWarning
+LibTest/io/Directory/Directory.fromUri_A01_t01: CompileTimeError
+LibTest/io/File/parent_A01_t02: CompileTimeError
+LibTest/io/HttpClientRequest/addError_A02_t01: StaticWarning
+LibTest/io/HttpClientRequest/addStream_A01_t01: StaticWarning
+LibTest/io/HttpClientRequest/addStream_A02_t01: StaticWarning
+LibTest/io/HttpClientRequest/addStream_A02_t02: StaticWarning
+LibTest/io/HttpClientRequest/add_A03_t01: StaticWarning
+LibTest/io/HttpClientRequest/add_A03_t02: StaticWarning
+LibTest/io/HttpClientRequest/flush_A02_t01: StaticWarning
+LibTest/io/HttpClientRequest/flush_A02_t02: StaticWarning
+LibTest/io/Link/Link_A03_t02: CompileTimeError
+LibTest/io/WebSocket/connect_A01_t01: CompileTimeError
+LibTest/io/WebSocket/connect_A01_t02: CompileTimeError
+LibTest/isolate/Isolate/spawn_A01_t03: StaticWarning
+LibTest/isolate/RawReceivePort/sendPort_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/any_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/any_A01_t02: StaticWarning
+LibTest/isolate/ReceivePort/every_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/firstWhere_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/firstWhere_A02_t01: StaticWarning
+LibTest/isolate/ReceivePort/firstWhere_A03_t02: StaticWarning
+LibTest/isolate/ReceivePort/fold_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/forEach_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/lastWhere_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/lastWhere_A02_t01: StaticWarning
+LibTest/isolate/ReceivePort/lastWhere_A04_t01: StaticWarning
+LibTest/isolate/ReceivePort/reduce_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/singleWhere_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/singleWhere_A02_t01: StaticWarning
+LibTest/isolate/ReceivePort/toSet_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/transform_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/where_A01_t01: StaticWarning
+LibTest/isolate/ReceivePort/where_A01_t02: StaticWarning
+WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: StaticWarning
+
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
new file mode 100644
index 0000000..4632eb0
--- /dev/null
+++ b/tests/co19_2/co19_2-kernel.status
@@ -0,0 +1,1093 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $fasta ]
+Language/Classes/Abstract_Instance_Members/inherited_t01: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t02: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t03: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t04: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t05: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t06: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/invocation_t01: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/invocation_t02: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/no_implementation_t01: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t01: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t02: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t03: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t04: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t05: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t06: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t01: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t02: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t04: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t05: MissingCompileTimeError
+Language/Classes/Abstract_Instance_Members/same_name_static_method_in_superclass_t06: MissingCompileTimeError
+Language/Classes/Constructors/Constant_Constructors/initializer_not_a_constant_t03: MissingCompileTimeError
+Language/Classes/Constructors/Factories/arguments_type_t01: MissingCompileTimeError
+Language/Classes/Constructors/Factories/const_modifier_t01: MissingCompileTimeError
+Language/Classes/Constructors/Factories/const_modifier_t02: MissingCompileTimeError
+Language/Classes/Constructors/Factories/default_value_t01: MissingCompileTimeError
+Language/Classes/Constructors/Factories/default_value_t02: MissingCompileTimeError
+Language/Classes/Constructors/Factories/function_type_t01: MissingCompileTimeError
+Language/Classes/Constructors/Factories/function_type_t02: MissingCompileTimeError
+Language/Classes/Constructors/Factories/name_t03: MissingCompileTimeError
+Language/Classes/Constructors/Factories/name_t05: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/execution_t04: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/execution_t05: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/execution_t06: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/execution_t07: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/execution_t12: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/explicit_type_t01: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/initializers_t15: CompileTimeError
+Language/Classes/Constructors/Generative_Constructors/redirection_t02: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/redirection_t03: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/redirection_t07: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/redirection_t08: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/static_type_t01: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/syntax_t04: MissingCompileTimeError
+Language/Classes/Constructors/Generative_Constructors/syntax_t05: MissingCompileTimeError
+Language/Classes/Getters/instance_getter_t01: MissingCompileTimeError
+Language/Classes/Getters/instance_getter_t02: MissingCompileTimeError
+Language/Classes/Getters/instance_getter_t03: MissingCompileTimeError
+Language/Classes/Getters/instance_getter_t04: MissingCompileTimeError
+Language/Classes/Getters/instance_getter_t05: MissingCompileTimeError
+Language/Classes/Getters/instance_getter_t06: MissingCompileTimeError
+Language/Classes/Getters/override_t02: MissingCompileTimeError
+Language/Classes/Getters/override_t03: MissingCompileTimeError
+Language/Classes/Getters/static_getter_t01: MissingCompileTimeError
+Language/Classes/Getters/type_object_t01: CompileTimeError
+Language/Classes/Getters/type_object_t02: CompileTimeError
+Language/Classes/Instance_Methods/override_different_default_values_t01: MissingCompileTimeError
+Language/Classes/Instance_Methods/override_different_default_values_t02: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_setter_t01: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_setter_t02: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t01: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t02: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t04: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t05: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t06: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t07: MissingCompileTimeError
+Language/Classes/Instance_Methods/same_name_static_member_in_superclass_t09: MissingCompileTimeError
+Language/Classes/Instance_Variables/constant_t01: MissingCompileTimeError
+Language/Classes/Setters/instance_setter_t01: MissingCompileTimeError
+Language/Classes/Setters/instance_setter_t02: MissingCompileTimeError
+Language/Classes/Setters/instance_setter_t03: MissingCompileTimeError
+Language/Classes/Setters/instance_setter_t04: MissingCompileTimeError
+Language/Classes/Setters/instance_setter_t05: MissingCompileTimeError
+Language/Classes/Setters/instance_setter_t06: MissingCompileTimeError
+Language/Classes/Setters/name_t01: MissingCompileTimeError
+Language/Classes/Setters/name_t02: MissingCompileTimeError
+Language/Classes/Setters/name_t03: MissingCompileTimeError
+Language/Classes/Setters/name_t04: MissingCompileTimeError
+Language/Classes/Setters/name_t05: MissingCompileTimeError
+Language/Classes/Setters/override_t02: MissingCompileTimeError
+Language/Classes/Setters/static_setter_t05: MissingCompileTimeError
+Language/Classes/Setters/static_setter_t06: MissingCompileTimeError
+Language/Classes/Superclasses/Inheritance_and_Overriding/abstract_method_t01: MissingCompileTimeError
+Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError
+Language/Classes/Superinterfaces/no_member_t01: MissingCompileTimeError
+Language/Classes/Superinterfaces/no_member_t05: MissingCompileTimeError
+Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError
+Language/Classes/declarations_t06: MissingCompileTimeError
+Language/Classes/declarations_t08: MissingCompileTimeError
+Language/Classes/declarations_t33: MissingCompileTimeError
+Language/Classes/definition_t23: CompileTimeError
+Language/Classes/method_definition_t03: MissingCompileTimeError
+Language/Classes/method_definition_t04: MissingCompileTimeError
+Language/Classes/method_definition_t05: MissingCompileTimeError
+Language/Classes/method_definition_t06: MissingCompileTimeError
+Language/Classes/same_name_type_variable_t04: MissingCompileTimeError
+Language/Classes/same_name_type_variable_t07: MissingCompileTimeError
+Language/Enums/syntax_t08: CompileTimeError
+Language/Enums/syntax_t09: CompileTimeError
+Language/Expressions/Assignable_Expressions/syntax_t01: CompileTimeError
+Language/Expressions/Assignment/expression_assignment_failed_t02: CompileTimeError
+Language/Expressions/Assignment/indexed_expression_super_t03: CompileTimeError
+Language/Expressions/Assignment/indexed_expression_super_t04: CompileTimeError
+Language/Expressions/Assignment/static_type_t02: CompileTimeError
+Language/Expressions/Assignment/static_type_t03: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t01: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t02: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t03: CompileTimeError
+Language/Expressions/Assignment/super_assignment_failed_t04: CompileTimeError
+Language/Expressions/Assignment/super_assignment_static_warning_t02: CompileTimeError
+Language/Expressions/Assignment/super_assignment_static_warning_t03: CompileTimeError
+Language/Expressions/Assignment/super_assignment_t06: CompileTimeError
+Language/Expressions/Assignment/super_assignment_value_t02: CompileTimeError
+Language/Expressions/Assignment/this_assignment_t02: CompileTimeError
+Language/Expressions/Bitwise_Expressions/syntax_t01: CompileTimeError
+Language/Expressions/Constants/constant_list_t02: MissingCompileTimeError
+Language/Expressions/Constants/constant_map_t02: MissingCompileTimeError
+Language/Expressions/Constants/equals_expression_t03: MissingCompileTimeError
+Language/Expressions/Constants/exception_t04: MissingCompileTimeError
+Language/Expressions/Constants/literal_number_t01: CompileTimeError
+Language/Expressions/Constants/literal_string_t02: MissingCompileTimeError
+Language/Expressions/Constants/math_operators_t01: CompileTimeError
+Language/Expressions/Constants/math_operators_t06: CompileTimeError
+Language/Expressions/Equality/syntax_t01: CompileTimeError
+Language/Expressions/Function_Expressions/syntax_t05: CompileTimeError
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/names_matching_t02: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/names_matching_t03: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/number_of_arguments_t02: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/number_of_arguments_t03: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/number_of_arguments_t06: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/number_of_arguments_t07: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Binding_Actuals_to_Formals/optional_parameter_type_t02: MissingCompileTimeError
+Language/Expressions/Function_Invocation/Function_Expression_Invocation/static_type_t02: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t01: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t02: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t03: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t04: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t05: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t06: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t07: CompileTimeError
+Language/Expressions/Function_Invocation/async_cleanup_t08: CompileTimeError
+Language/Expressions/Identifier_Reference/built_in_identifier_t02: CompileTimeError
+Language/Expressions/Identifier_Reference/evaluation_property_extraction_t04: CompileTimeError
+Language/Expressions/Instance_Creation/Const/abstract_class_t02: MissingCompileTimeError
+Language/Expressions/Instance_Creation/Const/abstract_class_t04: MissingCompileTimeError
+Language/Expressions/Instance_Creation/Const/arguments_t03: MissingCompileTimeError
+Language/Expressions/Instance_Creation/Const/parameterized_type_t01: CompileTimeError
+Language/Expressions/Instance_Creation/Const/parameterized_type_t02: CompileTimeError
+Language/Expressions/Instance_Creation/New/evaluation_t16: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/evaluation_t17: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/evaluation_t18: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/generic_type_t01: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/generic_type_t02: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/generic_type_t03: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/redirecting_factory_constructor_t02: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/syntax_t04: MissingCompileTimeError
+Language/Expressions/Instance_Creation/New/type_argument_t01: MissingCompileTimeError
+Language/Expressions/Instance_Creation/malformed_or_malbounded_t07: MissingCompileTimeError
+Language/Expressions/Lists/constant_list_t01: CompileTimeError
+Language/Expressions/Lookup/Getter_and_Setter_Lookup/definition_t09: CompileTimeError
+Language/Expressions/Lookup/Getter_and_Setter_Lookup/definition_t10: CompileTimeError
+Language/Expressions/Maps/constant_map_t02: MissingCompileTimeError
+Language/Expressions/Maps/constant_map_type_t01: CompileTimeError
+Language/Expressions/Maps/equal_keys_t01: MissingCompileTimeError
+Language/Expressions/Maps/key_value_equals_operator_t01: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/accessible_instance_member_t03: CompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/accessible_instance_member_t04: CompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/function_type_t01: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/method_lookup_failed_t21: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/static_type_t04: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t03: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t04: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t05: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t05: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t06: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t07: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t08: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t09: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t01: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t02: CompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/invocation_t02: MissingCompileTimeError
+Language/Expressions/Method_Invocation/Super_Invocation/static_type_dynamic_t02: CompileTimeError
+Language/Expressions/Multiplicative_Expressions/syntax_t01: CompileTimeError
+Language/Expressions/Numbers/static_type_of_int_t01: CompileTimeError
+Language/Expressions/Numbers/syntax_t06: CompileTimeError
+Language/Expressions/Numbers/syntax_t09: CompileTimeError
+Language/Expressions/Numbers/syntax_t10: CompileTimeError
+Language/Expressions/Postfix_Expressions/syntax_t01: CompileTimeError
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/instance_of_type_getter_t01: CompileTimeError
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/instance_of_type_getter_t03: CompileTimeError
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/instance_of_type_t01: CompileTimeError
+Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/instance_of_type_t03: CompileTimeError
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t01: CompileTimeError
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/no_such_method_t02: CompileTimeError
+Language/Expressions/Property_Extraction/Super_Getter_Access_and_Method_Closurization/static_type_t03: CompileTimeError
+Language/Expressions/Relational_Expressions/syntax_t01: CompileTimeError
+Language/Expressions/Shift/syntax_t01: CompileTimeError
+Language/Expressions/Strings/String_Interpolation/double_quote_t02: CompileTimeError
+Language/Expressions/Strings/String_Interpolation/single_quote_t02: CompileTimeError
+Language/Expressions/This/placement_t04: MissingCompileTimeError
+Language/Expressions/Throw/syntax_t02: MissingCompileTimeError
+Language/Expressions/Type_Cast/evaluation_t10: MissingCompileTimeError
+Language/Expressions/Type_Test/evaluation_t10: MissingCompileTimeError
+Language/Expressions/Unary_Expressions/syntax_t10: CompileTimeError
+Language/Expressions/Unary_Expressions/syntax_t27: CompileTimeError
+Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
+Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
+Language/Functions/async_return_type_t01: MissingCompileTimeError
+Language/Functions/async_return_type_t02: MissingCompileTimeError
+Language/Functions/generator_return_type_t01: MissingCompileTimeError
+Language/Functions/generator_return_type_t02: MissingCompileTimeError
+Language/Functions/generator_return_type_t05: MissingCompileTimeError
+Language/Functions/generator_return_type_t06: MissingCompileTimeError
+Language/Generics/scope_t06: MissingCompileTimeError
+Language/Generics/upper_bound_t01: MissingCompileTimeError
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_members_t01: MissingCompileTimeError
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: MissingCompileTimeError
+Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: MissingCompileTimeError
+Language/Libraries_and_Scripts/Exports/reexport_t01: MissingCompileTimeError
+Language/Libraries_and_Scripts/Exports/same_name_t01: MissingCompileTimeError
+Language/Libraries_and_Scripts/Imports/deferred_import_t01: CompileTimeError
+Language/Libraries_and_Scripts/Imports/deferred_import_t02: CompileTimeError
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t03: CompileTimeError
+Language/Libraries_and_Scripts/Imports/invalid_uri_t01: MissingCompileTimeError
+Language/Libraries_and_Scripts/Imports/library_name_t01: MissingCompileTimeError
+Language/Libraries_and_Scripts/Imports/namespace_changes_t01: CompileTimeError
+Language/Libraries_and_Scripts/Imports/namespace_changes_t02: CompileTimeError
+Language/Libraries_and_Scripts/Imports/namespace_changes_t16: CompileTimeError
+Language/Libraries_and_Scripts/Imports/namespace_changes_t17: CompileTimeError
+Language/Libraries_and_Scripts/Imports/static_type_t01: CompileTimeError
+Language/Mixins/Mixin_Application/abstract_t05: MissingCompileTimeError
+Language/Mixins/Mixin_Application/abstract_t06: MissingCompileTimeError
+Language/Mixins/Mixin_Application/deferred_t01: MissingCompileTimeError
+Language/Mixins/Mixin_Application/interfaces_t05: MissingCompileTimeError
+Language/Mixins/Mixin_Application/static_warning_t01: MissingCompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t01: MissingCompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t02: MissingCompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t06: MissingCompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t08: MissingCompileTimeError
+Language/Mixins/Mixin_Application/syntax_t16: CompileTimeError
+Language/Mixins/declaring_constructor_t05: MissingCompileTimeError
+Language/Mixins/declaring_constructor_t06: MissingCompileTimeError
+Language/Overview/Privacy/private_and_public_t11: CompileTimeError
+Language/Statements/Assert/execution_t08: CompileTimeError
+Language/Statements/Assert/production_mode_t01: CompileTimeError
+Language/Statements/Assert/type_t08: CompileTimeError
+Language/Statements/Continue/async_loops_t01: CompileTimeError
+Language/Statements/Continue/async_loops_t02: CompileTimeError
+Language/Statements/Continue/async_loops_t03: CompileTimeError
+Language/Statements/Continue/async_loops_t04: CompileTimeError
+Language/Statements/Continue/async_loops_t05: CompileTimeError
+Language/Statements/Continue/async_loops_t06: CompileTimeError
+Language/Statements/Continue/async_loops_t07: CompileTimeError
+Language/Statements/Continue/async_loops_t08: CompileTimeError
+Language/Statements/Continue/async_loops_t09: CompileTimeError
+Language/Statements/Continue/async_loops_t10: CompileTimeError
+Language/Statements/Continue/control_transfer_t08: CompileTimeError
+Language/Statements/Continue/control_transfer_t09: CompileTimeError
+Language/Statements/Continue/label_t06: MissingCompileTimeError
+Language/Statements/Continue/label_t07: MissingCompileTimeError
+Language/Statements/Continue/label_t08: MissingCompileTimeError
+Language/Statements/Continue/label_t09: MissingCompileTimeError
+Language/Statements/Continue/label_t10: MissingCompileTimeError
+Language/Statements/Continue/label_t11: MissingCompileTimeError
+Language/Statements/Do/condition_type_t02: MissingCompileTimeError
+Language/Statements/For/syntax_t12: MissingCompileTimeError
+Language/Statements/For/syntax_t19: MissingCompileTimeError
+Language/Statements/Labels/scope_t05: MissingCompileTimeError
+Language/Statements/Switch/equal_operator_t01: MissingCompileTimeError
+Language/Statements/Switch/equal_operator_t02: MissingCompileTimeError
+Language/Statements/Switch/execution_t01: MissingCompileTimeError
+Language/Statements/Switch/expressions_t01: MissingCompileTimeError
+Language/Statements/Switch/expressions_t02: MissingCompileTimeError
+Language/Statements/Switch/expressions_t04: MissingCompileTimeError
+Language/Statements/Switch/type_t01: MissingCompileTimeError
+Language/Statements/Switch/type_t02: MissingCompileTimeError
+Language/Statements/Try/catch_scope_t01: CompileTimeError
+Language/Types/Dynamic_Type_System/deferred_type_error_t01: MissingCompileTimeError
+Language/Types/Dynamic_Type_System/malbounded_type_error_t01: MissingCompileTimeError
+Language/Types/Function_Types/call_t02: MissingCompileTimeError
+Language/Types/Interface_Types/subtype_t12: CompileTimeError
+Language/Types/Interface_Types/subtype_t30: CompileTimeError
+Language/Types/Parameterized_Types/arity_mismatch_t01: MissingCompileTimeError
+Language/Types/Parameterized_Types/arity_mismatch_t05: MissingCompileTimeError
+Language/Types/Parameterized_Types/arity_mismatch_t07: MissingCompileTimeError
+Language/Types/Parameterized_Types/malbounded_t01: MissingCompileTimeError
+Language/Types/Parameterized_Types/malbounded_t02: MissingCompileTimeError
+Language/Types/Parameterized_Types/malbounded_t03: MissingCompileTimeError
+Language/Types/Parameterized_Types/malbounded_t04: MissingCompileTimeError
+Language/Types/Parameterized_Types/malbounded_t05: MissingCompileTimeError
+Language/Types/Parameterized_Types/malbounded_t06: MissingCompileTimeError
+Language/Types/Static_Types/deferred_type_t01: MissingCompileTimeError
+Language/Types/Static_Types/deferred_type_t02: MissingCompileTimeError
+Language/Types/Static_Types/deferred_type_t03: MissingCompileTimeError
+Language/Types/Static_Types/deferred_type_t04: MissingCompileTimeError
+Language/Types/Static_Types/malformed_type_t01/04: MissingCompileTimeError
+Language/Types/Static_Types/malformed_type_t01/05: MissingCompileTimeError
+Language/Types/Static_Types/malformed_type_t01/06: MissingCompileTimeError
+Language/Types/Type_Declarations/Typedef/syntax_t01: CompileTimeError
+Language/Types/Type_Void/returning_t03: MissingCompileTimeError
+Language/Types/Type_Void/returning_t04: MissingCompileTimeError
+Language/Types/Type_Void/returning_t05: MissingCompileTimeError
+Language/Types/Type_Void/syntax_t05: MissingCompileTimeError
+Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
+Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
+Language/Types/Type_Void/using_t01: MissingCompileTimeError
+Language/Types/Type_Void/using_t02: MissingCompileTimeError
+Language/Variables/final_or_static_initialization_t02: MissingCompileTimeError
+Language/Variables/final_or_static_initialization_t03: MissingCompileTimeError
+LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: CompileTimeError
+LibTest/async/Stream/Stream.fromFutures_A01_t01: CompileTimeError
+LibTest/async/Stream/Stream.fromFutures_A01_t02: CompileTimeError
+LibTest/async/Stream/Stream.fromFutures_A02_t01: CompileTimeError
+LibTest/async/Stream/Stream.fromFutures_A02_t02: CompileTimeError
+LibTest/async/Stream/Stream.fromFutures_A04_t01: CompileTimeError
+LibTest/async/Stream/Stream.fromIterable_A03_t01: CompileTimeError
+LibTest/async/Stream/Stream.periodic_A01_t01: CompileTimeError
+LibTest/async/Stream/Stream.periodic_A04_t01: CompileTimeError
+LibTest/async/StreamController/StreamController.broadcast_A09_t01: CompileTimeError
+LibTest/async/StreamController/StreamController.broadcast_A10_t01: CompileTimeError
+LibTest/async/StreamController/stream_A02_t01: CompileTimeError
+LibTest/async/StreamController/stream_A03_t01: CompileTimeError
+LibTest/async/Zone/runBinaryGuarded_A01_t02: CompileTimeError
+LibTest/async/Zone/runUnary_A01_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/firstWhere_A02_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/firstWhere_A03_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/lastWhere_A02_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/lastWhere_A03_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/skipWhile_A02_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/takeWhile_A02_t01: CompileTimeError
+LibTest/collection/DoubleLinkedQueue/where_A02_t01: CompileTimeError
+LibTest/collection/HashMap/HashMap_class_A01_t01: CompileTimeError
+LibTest/collection/HashSet/HashSet_A01_t02: CompileTimeError
+LibTest/collection/HashSet/HashSet_class_A01_t01: CompileTimeError
+LibTest/collection/IterableBase/IterableBase_class_A01_t02: CompileTimeError
+LibTest/collection/IterableMixin/IterableMixin_class_A02_t01: CompileTimeError
+LibTest/collection/IterableMixin/contains_A02_t01: CompileTimeError
+LibTest/collection/IterableMixin/every_A01_t01: CompileTimeError
+LibTest/collection/IterableMixin/every_A01_t02: CompileTimeError
+LibTest/collection/IterableMixin/every_A02_t01: CompileTimeError
+LibTest/collection/IterableMixin/expand_A02_t01: CompileTimeError
+LibTest/collection/IterableMixin/firstWhere_A02_t01: CompileTimeError
+LibTest/collection/IterableMixin/firstWhere_A02_t02: CompileTimeError
+LibTest/collection/IterableMixin/map_A03_t01: CompileTimeError
+LibTest/collection/IterableMixin/skipWhile_A02_t01: CompileTimeError
+LibTest/collection/IterableMixin/takeWhile_A02_t01: CompileTimeError
+LibTest/collection/IterableMixin/where_A02_t01: CompileTimeError
+LibTest/collection/LinkedHashMap/LinkedHashMap_A03_t01: CompileTimeError
+LibTest/collection/LinkedHashMap/LinkedHashMap_A04_t01: CompileTimeError
+LibTest/collection/LinkedHashMap/LinkedHashMap_A04_t02: CompileTimeError
+LibTest/collection/LinkedHashMap/LinkedHashMap_class_A01_t01: CompileTimeError
+LibTest/collection/LinkedHashSet/LinkedHashSet_A03_t01: CompileTimeError
+LibTest/collection/LinkedHashSet/LinkedHashSet_A05_t01: CompileTimeError
+LibTest/collection/LinkedHashSet/LinkedHashSet_A05_t02: CompileTimeError
+LibTest/collection/LinkedHashSet/LinkedHashSet_class_A01_t01: CompileTimeError
+LibTest/collection/LinkedList/remove_A01_t01: CompileTimeError
+LibTest/collection/ListBase/ListBase_class_A01_t01: CompileTimeError
+LibTest/collection/ListMixin/ListMixin_class_A01_t01: CompileTimeError
+LibTest/collection/ListQueue/ListQueue_class_A01_t01: CompileTimeError
+LibTest/collection/MapBase/MapBase_class_A01_t01: CompileTimeError
+LibTest/collection/MapMixin/MapMixin_class_A01_t01: CompileTimeError
+LibTest/collection/MapView/MapView_class_A01_t01: CompileTimeError
+LibTest/collection/Maps/forEach_A01_t01: CompileTimeError
+LibTest/collection/Maps/forEach_A01_t03: CompileTimeError
+LibTest/collection/Maps/forEach_A01_t04: CompileTimeError
+LibTest/collection/Maps/forEach_A01_t05: CompileTimeError
+LibTest/collection/Maps/forEach_A01_t06: CompileTimeError
+LibTest/collection/Maps/forEach_A02_t01: CompileTimeError
+LibTest/collection/Queue/Queue_class_A01_t01: CompileTimeError
+LibTest/collection/SetBase/SetBase_class_A01_t01: CompileTimeError
+LibTest/collection/SetMixin/SetMixin_class_A01_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A03_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A05_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A06_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterable_A06_t02: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterables_A04_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterables_A05_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.fromIterables_A05_t02: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.from_A02_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.from_A03_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap.from_A03_t02: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A02_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A02_t02: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A03_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A03_t02: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A04_t02: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A05_t01: CompileTimeError
+LibTest/collection/SplayTreeMap/SplayTreeMap_class_A05_t02: CompileTimeError
+LibTest/collection/SplayTreeMap/inherited_tests_A01_t01: CompileTimeError
+LibTest/collection/SplayTreeSet/SplayTreeSet.from_A02_t07: CompileTimeError
+LibTest/collection/SplayTreeSet/SplayTreeSet.from_A02_t08: CompileTimeError
+LibTest/collection/SplayTreeSet/SplayTreeSet_A04_t01: CompileTimeError
+LibTest/collection/SplayTreeSet/SplayTreeSet_A05_t01: CompileTimeError
+LibTest/collection/SplayTreeSet/SplayTreeSet_A06_t01: CompileTimeError
+LibTest/collection/SplayTreeSet/SplayTreeSet_class_A01_t01: CompileTimeError
+LibTest/collection/UnmodifiableListView/UnmodifiableListView_class_A01_t01: CompileTimeError
+LibTest/core/Function/apply_A01_t01: CompileTimeError
+LibTest/core/List/Iterable_A01_t01: CompileTimeError
+LibTest/core/List/List_class_A01_t01: CompileTimeError
+LibTest/core/List/List_class_A01_t02: CompileTimeError
+LibTest/core/Map/allTests_A01_t01: CompileTimeError
+LibTest/core/RegExp/allMatches_A01_t01: CompileTimeError
+LibTest/core/Set/every_A01_t01: CompileTimeError
+LibTest/core/Set/every_A01_t02: CompileTimeError
+LibTest/core/Set/every_A01_t03: CompileTimeError
+LibTest/core/Set/forEach_A01_t01: CompileTimeError
+LibTest/core/Set/forEach_A01_t02: CompileTimeError
+LibTest/core/Set/forEach_A01_t03: CompileTimeError
+LibTest/core/Set/forEach_A01_t04: CompileTimeError
+LibTest/core/Set/forEach_A01_t05: CompileTimeError
+LibTest/core/double/isInfinite_A01_t03: CompileTimeError
+LibTest/core/double/operator_GE_A01_t03: CompileTimeError
+LibTest/core/double/operator_GE_A02_t01: CompileTimeError
+LibTest/core/double/operator_GT_A01_t03: CompileTimeError
+LibTest/core/double/operator_GT_A02_t01: CompileTimeError
+LibTest/core/double/operator_LE_A01_t03: CompileTimeError
+LibTest/core/double/operator_LE_A02_t01: CompileTimeError
+LibTest/core/double/operator_LT_A01_t03: CompileTimeError
+LibTest/core/double/operator_LT_A02_t01: CompileTimeError
+LibTest/core/double/operator_addition_A01_t07: CompileTimeError
+LibTest/core/double/operator_addition_A02_t01: CompileTimeError
+LibTest/core/double/operator_division_A01_t07: CompileTimeError
+LibTest/core/double/operator_division_A01_t08: CompileTimeError
+LibTest/core/double/operator_division_A01_t11: CompileTimeError
+LibTest/core/double/operator_division_A02_t01: CompileTimeError
+LibTest/core/double/operator_multiplication_A01_t06: CompileTimeError
+LibTest/core/double/operator_multiplication_A01_t08: CompileTimeError
+LibTest/core/double/operator_multiplication_A02_t01: CompileTimeError
+LibTest/core/double/operator_remainder_A01_t02: CompileTimeError
+LibTest/core/double/operator_remainder_A01_t03: CompileTimeError
+LibTest/core/double/operator_remainder_A01_t04: CompileTimeError
+LibTest/core/double/operator_remainder_A01_t05: CompileTimeError
+LibTest/core/double/operator_remainder_A01_t06: CompileTimeError
+LibTest/core/double/operator_remainder_A02_t01: CompileTimeError
+LibTest/core/double/operator_subtraction_A01_t07: CompileTimeError
+LibTest/core/double/operator_subtraction_A01_t08: CompileTimeError
+LibTest/core/double/operator_subtraction_A02_t01: CompileTimeError
+LibTest/core/double/operator_truncating_division_A01_t08: CompileTimeError
+LibTest/core/double/operator_truncating_division_A02_t01: CompileTimeError
+LibTest/core/double/remainder_A01_t02: CompileTimeError
+LibTest/core/double/remainder_A01_t03: CompileTimeError
+LibTest/core/double/remainder_A01_t04: CompileTimeError
+LibTest/core/double/remainder_A01_t05: CompileTimeError
+LibTest/core/double/remainder_A01_t06: CompileTimeError
+LibTest/core/double/remainder_A02_t01: CompileTimeError
+LibTest/core/double/toStringAsFixed_A02_t01: CompileTimeError
+LibTest/core/int/abs_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/ceilToDouble_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/ceil_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/compareTo_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/floorToDouble_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/floor_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/isEven_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/isFinite_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/isInfinite_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/isNaN_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/isNegative_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/isOdd_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_AND_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_GE_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_GT_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_LE_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_LT_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_NOT_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_OR_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_XOR_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_addition_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_division_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_equality_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_equality_A02_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_equality_A03_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_left_shift_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_multiplication_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_remainder_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_remainder_A01_t02: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_right_shift_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_subtraction_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_truncating_division_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_truncating_division_A01_t02: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/operator_unary_minus_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/parse_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/remainder_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/remainder_A01_t02: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/roundToDouble_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/round_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/sign_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/toDouble_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/toInt_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/truncateToDouble_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/core/int/truncate_A01_t01: CompileTimeError # co19 issue 131. Test is broken for 64-bit ints
+LibTest/io/Directory/Directory.fromUri_A01_t01: CompileTimeError
+LibTest/io/File/parent_A01_t02: CompileTimeError
+LibTest/io/HttpClientRequest/addError_A02_t01: CompileTimeError
+LibTest/io/HttpClientRequest/addStream_A01_t01: CompileTimeError
+LibTest/io/HttpClientRequest/addStream_A02_t01: CompileTimeError
+LibTest/io/HttpClientRequest/addStream_A02_t02: CompileTimeError
+LibTest/io/HttpClientRequest/add_A03_t01: CompileTimeError
+LibTest/io/HttpClientRequest/add_A03_t02: CompileTimeError
+LibTest/io/HttpClientRequest/flush_A02_t01: CompileTimeError
+LibTest/io/HttpClientRequest/flush_A02_t02: CompileTimeError
+LibTest/io/Link/Link_A03_t02: CompileTimeError
+LibTest/io/RawDatagramSocket/asyncExpand_A01_t01: CompileTimeError
+LibTest/io/RawDatagramSocket/asyncExpand_A01_t02: CompileTimeError
+LibTest/io/WebSocket/connect_A01_t01: CompileTimeError
+LibTest/io/WebSocket/connect_A01_t02: CompileTimeError
+LibTest/isolate/Isolate/spawn_A01_t03: CompileTimeError
+LibTest/isolate/RawReceivePort/sendPort_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/any_A01_t02: CompileTimeError
+LibTest/isolate/ReceivePort/firstWhere_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/firstWhere_A02_t01: CompileTimeError
+LibTest/isolate/ReceivePort/fold_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/forEach_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/lastWhere_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/lastWhere_A02_t01: CompileTimeError
+LibTest/isolate/ReceivePort/reduce_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/singleWhere_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/toSet_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/transform_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/where_A01_t01: CompileTimeError
+LibTest/isolate/ReceivePort/where_A01_t02: CompileTimeError
+LibTest/math/pow_A10_t01: CompileTimeError
+LibTest/typed_data/ByteData/getUint64_A01_t01: CompileTimeError
+LibTest/typed_data/ByteData/setUint64_A01_t01: CompileTimeError
+LibTest/typed_data/Int32x4List/skipWhile_A01_t01: CompileTimeError
+LibTest/typed_data/Int32x4List/takeWhile_A01_t01: CompileTimeError
+LibTest/typed_data/Int32x4List/where_A01_t01: CompileTimeError
+LibTest/typed_data/Uint64List/Uint64List.fromList_A01_t01: CompileTimeError
+LibTest/typed_data/Uint64List/Uint64List.fromList_A01_t02: CompileTimeError
+LibTest/typed_data/Uint64List/Uint64List.fromList_A02_t01: CompileTimeError
+LibTest/typed_data/Uint64List/Uint64List.view_A01_t01: CompileTimeError
+LibTest/typed_data/Uint64List/Uint64List.view_A01_t02: CompileTimeError
+
+[ $compiler == dartk && $strong ]
+Language/Classes/Constructors/Constant_Constructors/potentially_constant_expression_t01: Crash
+Language/Expressions/Additive_Expressions/syntax_t01: RuntimeError
+Language/Expressions/Assignment/null_aware_assignment_static_type_t01: RuntimeError
+Language/Expressions/Booleans/Boolean_Conversion/definition_t01: RuntimeError
+Language/Expressions/Constants/depending_on_itself_t03: Crash
+Language/Expressions/Function_Invocation/async_generator_invokation_t08: Fail
+Language/Expressions/Function_Invocation/async_generator_invokation_t10: Fail
+Language/Expressions/Instance_Creation/Const/canonicalized_t05: RuntimeError
+Language/Expressions/Instance_Creation/New/evaluation_t19: RuntimeError
+Language/Expressions/Instance_Creation/New/evaluation_t20: RuntimeError
+Language/Expressions/Lists/identical_t02: RuntimeError
+Language/Expressions/Maps/identical_t02: RuntimeError
+Language/Expressions/Object_Identity/string_t01: RuntimeError
+Language/Expressions/Strings/adjacent_strings_t02: RuntimeError
+Language/Expressions/Type_Cast/syntax_t01: RuntimeError
+Language/Expressions/Unary_Expressions/variable_negative_t03: RuntimeError
+Language/Functions/External_Functions/not_connected_to_a_body_t01: RuntimeError
+Language/Generics/syntax_t02: DartkCrash
+Language/Generics/syntax_t03: DartkCrash
+Language/Libraries_and_Scripts/Parts/compilation_t03: RuntimeError
+Language/Libraries_and_Scripts/Parts/compilation_t05: RuntimeError
+Language/Metadata/before_export_t01: RuntimeError
+Language/Metadata/before_import_t01: RuntimeError
+Language/Metadata/before_library_t01: RuntimeError
+Language/Metadata/before_param_t01: RuntimeError
+Language/Metadata/before_param_t02: RuntimeError
+Language/Metadata/before_param_t03: RuntimeError
+Language/Metadata/before_param_t04: RuntimeError
+Language/Metadata/before_param_t05: RuntimeError
+Language/Metadata/before_param_t06: RuntimeError
+Language/Metadata/before_param_t07: RuntimeError
+Language/Metadata/before_param_t08: RuntimeError
+Language/Metadata/before_param_t09: RuntimeError
+Language/Metadata/before_type_param_t01: RuntimeError
+Language/Metadata/before_typedef_t01: RuntimeError
+Language/Overview/Privacy/private_and_public_t18: RuntimeError
+Language/Statements/Assert/execution_t03: RuntimeError
+Language/Statements/Assert/execution_t09: RuntimeError
+Language/Statements/Assert/execution_t11: RuntimeError
+Language/Statements/Do/execution_t06: RuntimeError
+Language/Statements/For/For_Loop/execution_t11: RuntimeError
+Language/Statements/For/For_in/execution_t02: RuntimeError
+Language/Statements/If/condition_evaluation_t02: RuntimeError
+Language/Statements/If/condition_evaluation_t03: RuntimeError
+Language/Statements/While/execution_t02: RuntimeError
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t08: RuntimeError
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t10: RuntimeError
+Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_sync_t05: RuntimeError
+Language/Types/Function_Types/subtype_named_args_t01: RuntimeError
+Language/Types/Function_Types/subtype_named_args_t02: RuntimeError
+Language/Types/Function_Types/subtype_named_args_t03: RuntimeError
+Language/Types/Function_Types/subtype_named_args_t04: RuntimeError
+Language/Types/Function_Types/subtype_named_args_t11: RuntimeError
+Language/Types/Function_Types/subtype_named_args_t12: RuntimeError
+Language/Types/Function_Types/subtype_no_args_t04: RuntimeError
+Language/Types/Function_Types/subtype_optional_args_t01: RuntimeError
+Language/Types/Function_Types/subtype_optional_args_t02: RuntimeError
+Language/Types/Function_Types/subtype_optional_args_t03: RuntimeError
+Language/Types/Function_Types/subtype_optional_args_t04: RuntimeError
+Language/Types/Function_Types/subtype_required_args_t01: RuntimeError
+Language/Types/Function_Types/subtype_required_args_t02: RuntimeError
+Language/Types/Interface_Types/subtype_t02: RuntimeError
+Language/Types/Interface_Types/subtype_t03: RuntimeError
+Language/Types/Interface_Types/subtype_t06: RuntimeError
+Language/Types/Interface_Types/subtype_t17: RuntimeError
+Language/Types/Interface_Types/subtype_t21: RuntimeError
+Language/Types/Interface_Types/subtype_t22: RuntimeError
+Language/Types/Interface_Types/subtype_t23: RuntimeError
+Language/Types/Interface_Types/subtype_t26: RuntimeError
+Language/Types/Type_Declarations/Typedef/dynamic_param_type_t02: RuntimeError
+Language/Types/Type_Declarations/Typedef/self_reference_t08: DartkCrash
+Language/Types/Type_Declarations/Typedef/self_reference_t09: DartkCrash
+Language/Variables/constant_initialization_t03: RuntimeError
+Language/Variables/constant_variable_t09: RuntimeError
+LibTest/async/Future/asStream_A01_t02: RuntimeError
+LibTest/async/Stream/Stream.fromFutures_A04_t02: RuntimeError
+LibTest/async/Stream/Stream.fromFutures_A04_t03: RuntimeError
+LibTest/async/Stream/Stream.fromIterable_A03_t02: RuntimeError
+LibTest/async/Stream/Stream.periodic_A02_t01: RuntimeError
+LibTest/async/Stream/Stream.periodic_A03_t01: RuntimeError
+LibTest/async/Stream/Stream.periodic_A04_t02: RuntimeError
+LibTest/async/Stream/Stream.periodic_A04_t03: RuntimeError
+LibTest/async/StreamController/StreamController.broadcast_A03_t02: RuntimeError
+LibTest/async/StreamController/StreamController.broadcast_A09_t02: RuntimeError
+LibTest/async/StreamController/StreamController.broadcast_A09_t03: RuntimeError
+LibTest/async/StreamController/StreamController.broadcast_A10_t02: RuntimeError
+LibTest/async/StreamController/StreamController.broadcast_A10_t03: RuntimeError
+LibTest/async/StreamController/StreamController_A03_t03: RuntimeError
+LibTest/async/StreamController/stream_A02_t02: RuntimeError
+LibTest/async/StreamController/stream_A02_t03: RuntimeError
+LibTest/async/StreamController/stream_A03_t02: RuntimeError
+LibTest/async/StreamController/stream_A03_t03: RuntimeError
+LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t03: RuntimeError
+LibTest/async/StreamTransformer/StreamTransformer.fromHandlers_A01_t04: RuntimeError
+LibTest/async/StreamTransformer/StreamTransformer_A01_t02: RuntimeError
+LibTest/async/StreamTransformer/StreamTransformer_A01_t03: RuntimeError
+LibTest/async/StreamTransformer/StreamTransformer_A02_t01: RuntimeError
+LibTest/async/StreamTransformer/StreamTransformer_A02_t02: RuntimeError
+LibTest/async/Zone/registerBinaryCallback_A01_t01: RuntimeError
+LibTest/collection/DoubleLinkedQueue/DoubleLinkedQueue.from_A01_t01: RuntimeError
+LibTest/collection/DoubleLinkedQueue/fold_A01_t01: RuntimeError
+LibTest/collection/DoubleLinkedQueue/reduce_A01_t01: RuntimeError
+LibTest/collection/DoubleLinkedQueue/removeWhere_A02_t02: RuntimeError
+LibTest/collection/DoubleLinkedQueue/removeWhere_A02_t03: RuntimeError
+LibTest/collection/DoubleLinkedQueue/retainWhere_A02_t02: RuntimeError
+LibTest/collection/DoubleLinkedQueue/retainWhere_A02_t03: RuntimeError
+LibTest/collection/HashMap/HashMap_A06_t01: RuntimeError
+LibTest/collection/HashSet/HashSet_A04_t01: RuntimeError
+LibTest/collection/IterableMixin/any_A01_t02: RuntimeError
+LibTest/collection/IterableMixin/expand_A01_t01: RuntimeError
+LibTest/collection/IterableMixin/first_A01_t02: RuntimeError
+LibTest/collection/IterableMixin/fold_A01_t01: RuntimeError
+LibTest/collection/IterableMixin/reduce_A01_t01: RuntimeError
+LibTest/collection/IterableMixin/single_A01_t02: RuntimeError
+LibTest/collection/IterableMixin/skipWhile_A03_t01: RuntimeError
+LibTest/collection/IterableMixin/skipWhile_A04_t01: RuntimeError
+LibTest/collection/LinkedList/addAll_A01_t02: RuntimeError
+LibTest/collection/LinkedList/add_A01_t01: RuntimeError
+LibTest/collection/LinkedList/forEach_A01_t01: RuntimeError
+LibTest/collection/LinkedList/join_A01_t01: RuntimeError
+LibTest/collection/LinkedList/map_A01_t01: RuntimeError
+LibTest/collection/LinkedList/map_A02_t01: RuntimeError
+LibTest/collection/LinkedList/map_A03_t01: RuntimeError
+LibTest/collection/LinkedList/reduce_A01_t01: RuntimeError
+LibTest/collection/LinkedList/reduce_A02_t01: RuntimeError
+LibTest/collection/LinkedList/reduce_A03_t01: RuntimeError
+LibTest/collection/LinkedList/reduce_A04_t01: RuntimeError
+LibTest/collection/LinkedList/remove_A01_t03: RuntimeError
+LibTest/collection/LinkedList/singleWhere_A01_t01: RuntimeError
+LibTest/collection/LinkedList/singleWhere_A02_t01: RuntimeError
+LibTest/collection/LinkedList/singleWhere_A02_t02: RuntimeError
+LibTest/collection/LinkedList/skipWhile_A01_t01: RuntimeError
+LibTest/collection/LinkedList/skipWhile_A03_t01: RuntimeError
+LibTest/collection/LinkedList/skipWhile_A04_t01: RuntimeError
+LibTest/collection/LinkedList/skipWhile_A05_t01: RuntimeError
+LibTest/collection/LinkedList/takeWhile_A01_t01: RuntimeError
+LibTest/collection/LinkedList/takeWhile_A01_t02: RuntimeError
+LibTest/collection/LinkedList/takeWhile_A02_t01: RuntimeError
+LibTest/collection/LinkedList/takeWhile_A03_t01: RuntimeError
+LibTest/collection/LinkedList/take_A01_t01: RuntimeError
+LibTest/collection/LinkedList/take_A02_t01: RuntimeError
+LibTest/collection/LinkedList/take_A03_t01: RuntimeError
+LibTest/collection/LinkedList/toString_A03_t01: RuntimeError
+LibTest/collection/LinkedList/where_A01_t01: RuntimeError
+LibTest/collection/LinkedList/where_A02_t01: RuntimeError
+LibTest/collection/ListQueue/ListQueue.from_A01_t01: RuntimeError
+LibTest/collection/Queue/Queue.from_A01_t01: RuntimeError
+LibTest/convert/ByteConversionSink/ByteConversionSink.from_A01_t01: RuntimeError
+LibTest/convert/ByteConversionSink/ByteConversionSink_class_A01_t01: RuntimeError
+LibTest/convert/LineSplitter/fuse_A01_t01: RuntimeError
+LibTest/convert/StringConversionSink/StringConversionSink.from_A01_t01: RuntimeError
+LibTest/convert/StringConversionSink/asStringSink_A02_t01: RuntimeError
+LibTest/convert/StringConversionSink/asUtf8Sink_A02_t01: RuntimeError
+LibTest/convert/Utf8Codec/Utf8Codec_A01_t02: RuntimeError
+LibTest/convert/Utf8Codec/Utf8Codec_A01_t03: RuntimeError
+LibTest/convert/Utf8Codec/decode_A03_t01: RuntimeError
+LibTest/convert/Utf8Codec/decode_A03_t02: RuntimeError
+LibTest/convert/Utf8Decoder/Utf8Decoder_A02_t01: RuntimeError
+LibTest/convert/Utf8Decoder/Utf8Decoder_A02_t02: RuntimeError
+LibTest/core/AssertionError/AssertionError_A01_t01: RuntimeError
+LibTest/core/AssertionError/message_A01_t01: RuntimeError
+LibTest/core/AssertionError/toString_A01_t01: RuntimeError
+LibTest/core/Expando/operator_square_brackets_A01_t01: RuntimeError
+LibTest/core/Expando/operator_square_brackets_A01_t03: RuntimeError
+LibTest/core/Expando/operator_square_brackets_A01_t04: RuntimeError
+LibTest/core/Expando/operator_square_brackets_A01_t05: RuntimeError
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: RuntimeError
+LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: RuntimeError
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError
+LibTest/core/Runes/any_A01_t01: RuntimeError
+LibTest/core/Runes/every_A01_t01: RuntimeError
+LibTest/core/StackOverflowError/stackTrace_A01_t01: RuntimeError
+LibTest/core/StackOverflowError/stackTrace_A01_t02: RuntimeError
+LibTest/core/String/padRight_A01_t01: RuntimeError
+LibTest/core/String/replaceAllMapped_A03_t01: RuntimeError
+LibTest/core/String/replaceFirstMapped_A03_t01: RuntimeError
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError
+LibTest/core/Symbol/Symbol_A01_t04: RuntimeError
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError
+LibTest/core/Uri/Uri.dataFromBytes_A01_t01: RuntimeError
+LibTest/core/Uri/Uri.dataFromBytes_A01_t02: RuntimeError
+LibTest/core/Uri/Uri.dataFromBytes_A01_t03: RuntimeError
+LibTest/core/Uri/Uri.dataFromBytes_A01_t04: RuntimeError
+LibTest/core/Uri/Uri.dataFromBytes_A01_t05: RuntimeError
+LibTest/core/Uri/Uri.dataFromString_A01_t01: RuntimeError
+LibTest/core/Uri/Uri.dataFromString_A01_t02: RuntimeError
+LibTest/core/Uri/Uri.dataFromString_A01_t03: RuntimeError
+LibTest/core/Uri/Uri.dataFromString_A01_t04: RuntimeError
+LibTest/core/Uri/Uri.dataFromString_A01_t05: RuntimeError
+LibTest/core/Uri/Uri.dataFromString_A02_t01: RuntimeError
+LibTest/core/Uri/Uri.dataFromString_A02_t03: RuntimeError
+LibTest/core/Uri/Uri.directory_A05_t01: RuntimeError
+LibTest/core/Uri/Uri.file_A02_t03: RuntimeError
+LibTest/core/Uri/parse_A07_t01: RuntimeError
+LibTest/core/Uri/queryParametersAll_A01_t01: RuntimeError
+LibTest/core/Uri/queryParametersAll_A01_t02: RuntimeError
+LibTest/core/Uri/queryParametersAll_A01_t04: RuntimeError
+LibTest/core/Uri/queryParametersAll_A03_t01: RuntimeError
+LibTest/core/Uri/queryParametersAll_A04_t01: RuntimeError
+LibTest/core/UriData/UriData.fromBytes_A01_t03: RuntimeError
+LibTest/core/UriData/UriData.fromString_A02_t03: RuntimeError
+LibTest/core/UriData/UriData.fromUri_A01_t03: RuntimeError
+LibTest/core/UriData/charset_A01_t01: RuntimeError
+LibTest/core/UriData/contentText_A01_t01: RuntimeError
+LibTest/core/UriData/isBase64_A01_t01: RuntimeError
+LibTest/core/UriData/parse_A01_t01: RuntimeError
+LibTest/core/UriData/toString_A01_t01: RuntimeError
+LibTest/core/double/ceil_A01_t04: RuntimeError
+LibTest/core/double/floor_A01_t04: RuntimeError
+LibTest/core/double/round_A01_t03: RuntimeError
+LibTest/core/double/toInt_A01_t05: RuntimeError
+LibTest/core/double/truncate_A01_t05: RuntimeError
+LibTest/core/int/toStringAsFixed_A03_t01: RuntimeError
+LibTest/io/CompressionOptions/DEFAULT_A01_t01: RuntimeError
+LibTest/io/Cookie/Cookie_A01_t01: RuntimeError
+LibTest/io/Cookie/Cookie_A01_t02: RuntimeError
+LibTest/io/Cookie/domain_A01_t02: RuntimeError
+LibTest/io/Cookie/name_A01_t02: RuntimeError
+LibTest/io/Cookie/path_A01_t02: RuntimeError
+LibTest/io/Directory/deleteSync_A02_t06: RuntimeError
+LibTest/io/Directory/delete_A02_t05: RuntimeError
+LibTest/io/Directory/existsSync_A02_t02: RuntimeError
+LibTest/io/Directory/exists_A02_t02: RuntimeError
+LibTest/io/Directory/listSync_A01_t02: RuntimeError
+LibTest/io/Directory/listSync_A01_t03: RuntimeError
+LibTest/io/Directory/listSync_A01_t04: RuntimeError
+LibTest/io/Directory/list_A01_t02: RuntimeError
+LibTest/io/Directory/list_A01_t03: RuntimeError
+LibTest/io/Directory/list_A01_t04: RuntimeError
+LibTest/io/Directory/renameSync_A02_t01: RuntimeError
+LibTest/io/Directory/rename_A02_t01: RuntimeError
+LibTest/io/Directory/statSync_A01_t05: RuntimeError
+LibTest/io/Directory/stat_A01_t05: RuntimeError
+LibTest/io/Directory/watch_A01_t01: RuntimeError
+LibTest/io/Directory/watch_A01_t02: RuntimeError
+LibTest/io/Directory/watch_A02_t01: RuntimeError
+LibTest/io/File/absolute_A01_t01: RuntimeError
+LibTest/io/File/openRead_A01_t04: RuntimeError
+LibTest/io/File/openRead_A02_t01: RuntimeError
+LibTest/io/File/openSync_A01_t03: RuntimeError
+LibTest/io/File/openWrite_A03_t01: RuntimeError
+LibTest/io/File/open_A01_t03: RuntimeError
+LibTest/io/File/statSync_A01_t05: RuntimeError
+LibTest/io/File/stat_A01_t05: RuntimeError
+LibTest/io/FileStat/changed_A01_t01: RuntimeError
+LibTest/io/FileStat/modeString_A01_t01: RuntimeError
+LibTest/io/FileStat/mode_A01_t01: RuntimeError
+LibTest/io/FileStat/modified_A01_t01: RuntimeError
+LibTest/io/FileSystemCreateEvent/isDirectory_A01_t01: RuntimeError
+LibTest/io/FileSystemCreateEvent/isDirectory_A01_t02: RuntimeError
+LibTest/io/FileSystemCreateEvent/isDirectory_A01_t03: RuntimeError
+LibTest/io/FileSystemCreateEvent/isDirectory_A01_t04: RuntimeError
+LibTest/io/FileSystemCreateEvent/isDirectory_A01_t05: RuntimeError
+LibTest/io/FileSystemCreateEvent/isDirectory_A01_t06: RuntimeError
+LibTest/io/FileSystemCreateEvent/path_A01_t01: RuntimeError
+LibTest/io/FileSystemCreateEvent/path_A01_t02: RuntimeError
+LibTest/io/FileSystemCreateEvent/path_A01_t03: RuntimeError
+LibTest/io/FileSystemCreateEvent/type_A01_t01: RuntimeError
+LibTest/io/FileSystemCreateEvent/type_A01_t02: RuntimeError
+LibTest/io/FileSystemCreateEvent/type_A01_t03: RuntimeError
+LibTest/io/FileSystemDeleteEvent/isDirectory_A01_t01: RuntimeError
+LibTest/io/FileSystemDeleteEvent/isDirectory_A01_t02: RuntimeError
+LibTest/io/FileSystemDeleteEvent/isDirectory_A01_t03: RuntimeError
+LibTest/io/FileSystemDeleteEvent/isDirectory_A01_t04: RuntimeError
+LibTest/io/FileSystemDeleteEvent/isDirectory_A01_t05: RuntimeError
+LibTest/io/FileSystemDeleteEvent/isDirectory_A01_t06: RuntimeError
+LibTest/io/FileSystemDeleteEvent/path_A01_t01: RuntimeError
+LibTest/io/FileSystemDeleteEvent/path_A01_t02: RuntimeError
+LibTest/io/FileSystemDeleteEvent/path_A01_t03: RuntimeError
+LibTest/io/FileSystemDeleteEvent/type_A01_t01: RuntimeError
+LibTest/io/FileSystemDeleteEvent/type_A01_t02: RuntimeError
+LibTest/io/FileSystemDeleteEvent/type_A01_t03: RuntimeError
+LibTest/io/FileSystemEntity/isDirectorySync_A01_t03: RuntimeError
+LibTest/io/FileSystemEntity/isDirectory_A01_t03: RuntimeError
+LibTest/io/FileSystemEntity/isFileSync_A01_t03: RuntimeError
+LibTest/io/FileSystemEntity/isFile_A01_t01: RuntimeError
+LibTest/io/FileSystemEntity/isFile_A01_t03: RuntimeError
+LibTest/io/FileSystemModifyEvent/contentChanged_A01_t01: RuntimeError
+LibTest/io/FileSystemModifyEvent/isDirectory_A01_t01: RuntimeError
+LibTest/io/FileSystemModifyEvent/isDirectory_A01_t02: RuntimeError
+LibTest/io/FileSystemModifyEvent/path_A01_t01: RuntimeError
+LibTest/io/FileSystemModifyEvent/path_A01_t02: RuntimeError
+LibTest/io/FileSystemModifyEvent/type_A01_t01: RuntimeError
+LibTest/io/FileSystemModifyEvent/type_A01_t02: RuntimeError
+LibTest/io/FileSystemMoveEvent/destination_A01_t01: RuntimeError
+LibTest/io/FileSystemMoveEvent/destination_A01_t02: RuntimeError
+LibTest/io/FileSystemMoveEvent/destination_A01_t03: RuntimeError
+LibTest/io/FileSystemMoveEvent/isDirectory_A01_t01: RuntimeError
+LibTest/io/FileSystemMoveEvent/isDirectory_A01_t02: RuntimeError
+LibTest/io/FileSystemMoveEvent/isDirectory_A01_t03: RuntimeError
+LibTest/io/FileSystemMoveEvent/path_A01_t01: RuntimeError
+LibTest/io/FileSystemMoveEvent/path_A01_t02: RuntimeError
+LibTest/io/FileSystemMoveEvent/path_A01_t03: RuntimeError
+LibTest/io/FileSystemMoveEvent/type_A01_t01: RuntimeError
+LibTest/io/FileSystemMoveEvent/type_A01_t02: RuntimeError
+LibTest/io/FileSystemMoveEvent/type_A01_t03: RuntimeError
+LibTest/io/HttpClient/addCredentials_A03_t01: RuntimeError
+LibTest/io/HttpClient/addProxyCredentials_A03_t01: RuntimeError
+LibTest/io/HttpClient/authenticateProxy_A01_t01: RuntimeError
+LibTest/io/HttpClient/authenticateProxy_A01_t02: RuntimeError
+LibTest/io/HttpClient/authenticateProxy_A02_t01: RuntimeError
+LibTest/io/HttpClient/authenticate_A01_t01: RuntimeError
+LibTest/io/HttpClient/authenticate_A01_t02: RuntimeError
+LibTest/io/HttpClient/authenticate_A02_t01: RuntimeError
+LibTest/io/HttpClient/autoUncompress_A02_t01: RuntimeError
+LibTest/io/HttpClient/autoUncompress_A04_t01: RuntimeError
+LibTest/io/HttpClient/autoUncompress_A04_t03: RuntimeError
+LibTest/io/HttpClient/close_A01_t01: RuntimeError
+LibTest/io/HttpClient/findProxy_A01_t01: RuntimeError
+LibTest/io/HttpClient/findProxy_A01_t02: RuntimeError
+LibTest/io/HttpClient/findProxy_A02_t01: RuntimeError
+LibTest/io/HttpClient/findProxy_A02_t02: RuntimeError
+LibTest/io/HttpClient/findProxy_A03_t01: RuntimeError
+LibTest/io/HttpClient/findProxy_A03_t02: RuntimeError
+LibTest/io/HttpClientBasicCredentials/HttpClientBasicCredentials_A01_t01: RuntimeError
+LibTest/io/HttpClientDigestCredentials/HttpClientDigestCredentials_A01_t01: RuntimeError
+LibTest/io/HttpClientRequest/close_A02_t01: RuntimeError
+LibTest/io/HttpClientRequest/done_A02_t01: RuntimeError
+LibTest/io/HttpClientResponse/certificate_A01_t01: RuntimeError
+LibTest/io/HttpClientResponse/isRedirect_A01_t02: RuntimeError
+LibTest/io/HttpServer/autoCompress_A02_t01: RuntimeError
+LibTest/io/HttpServer/bind_A02_t03: RuntimeError
+LibTest/io/HttpServer/bind_A03_t01: RuntimeError
+LibTest/io/HttpServer/bind_A03_t02: RuntimeError
+LibTest/io/HttpServer/bind_A05_t02: Fail
+LibTest/io/HttpServer/isBroadcast_A01_t01: RuntimeError
+LibTest/io/IOSink/IOSink_class_A01_t01: RuntimeError
+LibTest/io/IOSink/IOSink_class_A02_t01: RuntimeError
+LibTest/io/IOSink/addError_A01_t01: RuntimeError
+LibTest/io/IOSink/addError_A01_t02: RuntimeError
+LibTest/io/IOSink/addError_A01_t03: RuntimeError
+LibTest/io/IOSink/addError_A01_t04: RuntimeError
+LibTest/io/IOSink/addError_A02_t01: RuntimeError
+LibTest/io/IOSink/addError_A02_t02: RuntimeError
+LibTest/io/IOSink/addError_A03_t01: RuntimeError
+LibTest/io/IOSink/addStream_A01_t01: RuntimeError
+LibTest/io/IOSink/addStream_A02_t01: RuntimeError
+LibTest/io/IOSink/addStream_A02_t02: RuntimeError
+LibTest/io/IOSink/add_A01_t01: RuntimeError
+LibTest/io/IOSink/add_A01_t02: RuntimeError
+LibTest/io/IOSink/add_A02_t01: RuntimeError
+LibTest/io/IOSink/add_A03_t01: RuntimeError
+LibTest/io/IOSink/add_A03_t02: RuntimeError
+LibTest/io/IOSink/add_A04_t01: RuntimeError
+LibTest/io/IOSink/close_A01_t01: RuntimeError
+LibTest/io/IOSink/close_A01_t02: RuntimeError
+LibTest/io/IOSink/close_A02_t01: RuntimeError
+LibTest/io/IOSink/flush_A01_t01: RuntimeError
+LibTest/io/IOSink/flush_A02_t01: RuntimeError
+LibTest/io/IOSink/writeAll_A01_t01: RuntimeError
+LibTest/io/IOSink/writeAll_A01_t02: RuntimeError
+LibTest/io/IOSink/writeAll_A01_t03: RuntimeError
+LibTest/io/IOSink/writeAll_A01_t04: RuntimeError
+LibTest/io/IOSink/writeAll_A02_t01: RuntimeError
+LibTest/io/IOSink/writeAll_A02_t02: RuntimeError
+LibTest/io/IOSink/writeAll_A02_t03: RuntimeError
+LibTest/io/IOSink/writeAll_A02_t04: RuntimeError
+LibTest/io/IOSink/writeAll_A02_t05: RuntimeError
+LibTest/io/IOSink/writeCharCode_A01_t01: RuntimeError
+LibTest/io/IOSink/writeCharCode_A01_t02: RuntimeError
+LibTest/io/IOSink/writeCharCode_A01_t03: RuntimeError
+LibTest/io/IOSink/write_A01_t01: RuntimeError
+LibTest/io/IOSink/write_A01_t02: RuntimeError
+LibTest/io/IOSink/write_A01_t03: RuntimeError
+LibTest/io/IOSink/write_A01_t04: RuntimeError
+LibTest/io/IOSink/write_A01_t05: RuntimeError
+LibTest/io/IOSink/write_A01_t06: RuntimeError
+LibTest/io/IOSink/write_A01_t07: RuntimeError
+LibTest/io/IOSink/writeln_A01_t01: RuntimeError
+LibTest/io/IOSink/writeln_A01_t02: RuntimeError
+LibTest/io/InternetAddress/reverse_A01_t01: RuntimeError
+LibTest/io/Link/renameSync_A02_t03: RuntimeError
+LibTest/io/Link/rename_A02_t03: RuntimeError
+LibTest/io/Link/statSync_A01_t01: RuntimeError
+LibTest/io/Link/stat_A01_t01: RuntimeError
+LibTest/io/Link/watch_A01_t01: RuntimeError
+LibTest/io/Process/run_A01_t02: RuntimeError
+LibTest/io/Process/stderr_A01_t01: RuntimeError
+LibTest/io/Process/stdin_A01_t01: RuntimeError
+LibTest/io/Process/stdout_A01_t01: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A01_t01: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A01_t02: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A02_t01: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A02_t02: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A02_t03: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A02_t04: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A03_t01: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A03_t02: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A03_t03: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A04_t01: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A04_t02: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A04_t03: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A04_t04: RuntimeError
+LibTest/io/RandomAccessFile/lockSync_A05_t01: RuntimeError
+LibTest/io/RandomAccessFile/lock_A01_t02: RuntimeError
+LibTest/io/RandomAccessFile/lock_A01_t03: RuntimeError
+LibTest/io/RandomAccessFile/lock_A01_t04: RuntimeError
+LibTest/io/RandomAccessFile/lock_A02_t01: RuntimeError
+LibTest/io/RandomAccessFile/lock_A02_t02: RuntimeError
+LibTest/io/RandomAccessFile/lock_A02_t03: RuntimeError
+LibTest/io/RandomAccessFile/lock_A03_t01: RuntimeError
+LibTest/io/RandomAccessFile/lock_A03_t02: RuntimeError
+LibTest/io/RandomAccessFile/lock_A03_t03: RuntimeError
+LibTest/io/RandomAccessFile/lock_A04_t01: RuntimeError
+LibTest/io/RandomAccessFile/lock_A04_t02: RuntimeError
+LibTest/io/RandomAccessFile/lock_A04_t03: RuntimeError
+LibTest/io/RandomAccessFile/lock_A04_t04: RuntimeError
+LibTest/io/RandomAccessFile/lock_A05_t01: RuntimeError
+LibTest/io/RandomAccessFile/lock_A05_t02: RuntimeError
+LibTest/io/RandomAccessFile/unlockSync_A01_t01: RuntimeError
+LibTest/io/RandomAccessFile/unlockSync_A01_t02: RuntimeError
+LibTest/io/RandomAccessFile/unlockSync_A01_t03: RuntimeError
+LibTest/io/RandomAccessFile/unlockSync_A02_t01: RuntimeError
+LibTest/io/RandomAccessFile/unlock_A01_t02: RuntimeError
+LibTest/io/RandomAccessFile/unlock_A01_t03: RuntimeError
+LibTest/io/RandomAccessFile/unlock_A01_t04: RuntimeError
+LibTest/io/RandomAccessFile/unlock_A02_t01: RuntimeError
+LibTest/io/RawDatagramSocket/any_A01_t01: RuntimeError
+LibTest/io/RawDatagramSocket/any_A01_t04: Timeout
+LibTest/io/RawDatagramSocket/any_A01_t05: Timeout
+LibTest/io/RawDatagramSocket/any_A01_t06: Timeout
+LibTest/io/RawDatagramSocket/any_A01_t07: Timeout
+LibTest/io/RawDatagramSocket/any_A01_t08: Timeout
+LibTest/io/RawDatagramSocket/multicastInterface_A01_t01: RuntimeError
+LibTest/io/RawDatagramSocket/receive_A02_t02: RuntimeError
+LibTest/io/Stdin/echoMode_A01_t01: RuntimeError
+LibTest/io/Stdin/echoMode_A01_t02: RuntimeError
+LibTest/io/Stdin/lineMode_A01_t01: RuntimeError
+LibTest/io/Stdin/lineMode_A01_t02: RuntimeError
+LibTest/io/Stdin/readByteSync_A01_t02: RuntimeError
+LibTest/io/Stdin/readByteSync_A02_t01: RuntimeError
+LibTest/io/Stdin/supportsAnsiEscapes_A02_t01: RuntimeError
+LibTest/io/Stdout/Stdout_class_A02_t01: RuntimeError
+LibTest/io/Stdout/Stdout_class_A03_t01: RuntimeError
+LibTest/io/Stdout/addError_A02_t01: RuntimeError
+LibTest/io/Stdout/addStream_A02_t01: RuntimeError
+LibTest/io/Stdout/addStream_A03_t01: RuntimeError
+LibTest/io/Stdout/addStream_A03_t02: RuntimeError
+LibTest/io/Stdout/add_A03_t01: RuntimeError
+LibTest/io/Stdout/add_A03_t02: RuntimeError
+LibTest/io/Stdout/close_A02_t01: RuntimeError
+LibTest/io/Stdout/close_A02_t02: RuntimeError
+LibTest/io/Stdout/flush_A01_t01: RuntimeError
+LibTest/io/Stdout/flush_A02_t01: RuntimeError
+LibTest/io/Stdout/supportsAnsiEscapes_A02_t01: RuntimeError
+LibTest/io/Stdout/writeAll_A02_t05: RuntimeError
+LibTest/io/Stdout/writeCharCode_A01_t03: RuntimeError
+LibTest/io/SystemEncoding/name_A01_t01: RuntimeError
+LibTest/io/WebSocket/isEmpty_A01_t01: RuntimeError
+LibTest/io/WebSocketTransformer/bind_A01_t01: RuntimeError
+LibTest/io/ZLibDecoder/fuse_A01_t01: RuntimeError
+LibTest/io/ZLibEncoder/fuse_A01_t01: RuntimeError
+LibTest/isolate/Isolate/addOnExitListener_A04_t01: RuntimeError
+LibTest/isolate/Isolate/ping_A03_t02: RuntimeError
+LibTest/isolate/Isolate/ping_A04_t01: RuntimeError
+LibTest/isolate/Isolate/spawnUri_A05_t04: RuntimeError
+LibTest/isolate/Isolate/spawn_A04_t04: RuntimeError
+LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError
+LibTest/isolate/ReceivePort/every_A01_t01: RuntimeError
+LibTest/isolate/ReceivePort/firstWhere_A03_t02: RuntimeError
+LibTest/isolate/ReceivePort/lastWhere_A04_t01: RuntimeError
+LibTest/isolate/ReceivePort/singleWhere_A02_t01: RuntimeError
+LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError
+LibTest/isolate/SendPort/send_A01_t02: Crash
+LibTest/isolate/SendPort/send_A01_t03: Crash
+LibTest/math/MutableRectangle/MutableRectangle_A03_t04: RuntimeError
+LibTest/math/MutableRectangle/height_A03_t02: RuntimeError
+LibTest/math/MutableRectangle/width_A03_t02: RuntimeError
+LibTest/math/Rectangle/Rectangle_A03_t04: RuntimeError
+LibTest/typed_data/ByteBuffer/asByteData_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asFloat32List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asFloat32x4List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asFloat64List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asFloat64x2List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asInt16List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asInt32List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asInt32x4List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asInt64List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asInt8List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asUint16List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asUint32List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asUint64List_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asUint8ClampedList_A01_t01: RuntimeError
+LibTest/typed_data/ByteBuffer/asUint8List_A01_t01: RuntimeError
+LibTest/typed_data/Float32List/any_A01_t01: RuntimeError
+LibTest/typed_data/Float32List/every_A01_t01: RuntimeError
+LibTest/typed_data/Float32List/first_A01_t02: RuntimeError
+LibTest/typed_data/Float32List/last_A01_t02: RuntimeError
+LibTest/typed_data/Float32x4List/any_A01_t01: RuntimeError
+LibTest/typed_data/Float32x4List/every_A01_t01: RuntimeError
+LibTest/typed_data/Float32x4List/first_A01_t02: RuntimeError
+LibTest/typed_data/Float32x4List/last_A01_t02: RuntimeError
+LibTest/typed_data/Float32x4List/shuffle_A01_t01: RuntimeError
+LibTest/typed_data/Float64List/any_A01_t01: RuntimeError
+LibTest/typed_data/Float64List/every_A01_t01: RuntimeError
+LibTest/typed_data/Float64List/first_A01_t02: RuntimeError
+LibTest/typed_data/Float64List/last_A01_t02: RuntimeError
+LibTest/typed_data/Float64x2List/first_A01_t02: RuntimeError
+LibTest/typed_data/Float64x2List/last_A01_t02: RuntimeError
+LibTest/typed_data/Float64x2List/shuffle_A01_t01: RuntimeError
+LibTest/typed_data/Float64x2List/sort_A01_t01: RuntimeError
+LibTest/typed_data/Int16List/any_A01_t01: RuntimeError
+LibTest/typed_data/Int16List/every_A01_t01: RuntimeError
+LibTest/typed_data/Int16List/first_A01_t02: RuntimeError
+LibTest/typed_data/Int16List/last_A01_t02: RuntimeError
+LibTest/typed_data/Int32List/any_A01_t01: RuntimeError
+LibTest/typed_data/Int32List/every_A01_t01: RuntimeError
+LibTest/typed_data/Int32List/first_A01_t02: RuntimeError
+LibTest/typed_data/Int32List/last_A01_t02: RuntimeError
+LibTest/typed_data/Int32x4List/Int32x4List.fromList_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/Int32x4List.fromList_A01_t02: RuntimeError
+LibTest/typed_data/Int32x4List/Int32x4List.view_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/clear_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/first_A01_t02: RuntimeError
+LibTest/typed_data/Int32x4List/fold_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/forEach_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/last_A01_t02: RuntimeError
+LibTest/typed_data/Int32x4List/lengthInBytes_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/length_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/offsetInBytes_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/shuffle_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/skip_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/skip_A02_t01: RuntimeError
+LibTest/typed_data/Int32x4List/sublist_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/take_A01_t01: RuntimeError
+LibTest/typed_data/Int32x4List/take_A02_t01: RuntimeError
+LibTest/typed_data/Int64List/any_A01_t01: RuntimeError
+LibTest/typed_data/Int64List/every_A01_t01: RuntimeError
+LibTest/typed_data/Int64List/first_A01_t02: RuntimeError
+LibTest/typed_data/Int64List/last_A01_t02: RuntimeError
+LibTest/typed_data/Int8List/any_A01_t01: RuntimeError
+LibTest/typed_data/Int8List/every_A01_t01: RuntimeError
+LibTest/typed_data/Int8List/first_A01_t02: RuntimeError
+LibTest/typed_data/Int8List/last_A01_t02: RuntimeError
+LibTest/typed_data/Uint16List/any_A01_t01: RuntimeError
+LibTest/typed_data/Uint16List/every_A01_t01: RuntimeError
+LibTest/typed_data/Uint16List/first_A01_t02: RuntimeError
+LibTest/typed_data/Uint16List/last_A01_t02: RuntimeError
+LibTest/typed_data/Uint32List/any_A01_t01: RuntimeError
+LibTest/typed_data/Uint32List/every_A01_t01: RuntimeError
+LibTest/typed_data/Uint32List/first_A01_t02: RuntimeError
+LibTest/typed_data/Uint32List/last_A01_t02: RuntimeError
+LibTest/typed_data/Uint64List/any_A01_t01: RuntimeError
+LibTest/typed_data/Uint64List/every_A01_t01: RuntimeError
+LibTest/typed_data/Uint64List/first_A01_t02: RuntimeError
+LibTest/typed_data/Uint64List/last_A01_t02: RuntimeError
+LibTest/typed_data/Uint8ClampedList/any_A01_t01: RuntimeError
+LibTest/typed_data/Uint8ClampedList/every_A01_t01: RuntimeError
+LibTest/typed_data/Uint8ClampedList/first_A01_t02: RuntimeError
+LibTest/typed_data/Uint8ClampedList/last_A01_t02: RuntimeError
+LibTest/typed_data/Uint8List/any_A01_t01: RuntimeError
+LibTest/typed_data/Uint8List/every_A01_t01: RuntimeError
+LibTest/typed_data/Uint8List/first_A01_t02: RuntimeError
+LibTest/typed_data/Uint8List/last_A01_t02: RuntimeError
+Utils/tests/Expect/throws_A01_t04: RuntimeError
diff --git a/tests/co19_2/co19_2-runtime.status b/tests/co19_2/co19_2-runtime.status
new file mode 100644
index 0000000..5a133f5
--- /dev/null
+++ b/tests/co19_2/co19_2-runtime.status
@@ -0,0 +1,8 @@
+# Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+[ $runtime == dart_precompiled || $runtime == flutter || $runtime == vm ]
+LayoutTests/fast/*: SkipByDesign # DOM not supported on VM.
+LibTest/html/*: SkipByDesign # dart:html not supported on VM.
+WebPlatformTest/*: SkipByDesign # dart:html not supported on VM.
diff --git a/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
new file mode 100644
index 0000000..892f55e
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/data/deferred_typedef.dart
@@ -0,0 +1,12 @@
+// 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 '../libs/deferred_typedef_lib1.dart' deferred as lib1;
+
+/*element: main:OutputUnit(main, {})*/
+main() async {
+ await lib1.loadLibrary();
+ print(lib1.cA);
+ print(lib1.cB);
+}
diff --git a/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart b/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
new file mode 100644
index 0000000..9344b77
--- /dev/null
+++ b/tests/compiler/dart2js/deferred_loading/libs/deferred_typedef_lib1.dart
@@ -0,0 +1,29 @@
+// 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 deferred_typedef_lib1;
+
+class C {
+ /*element: C.a:OutputUnit(1, {lib1})*/
+ final a;
+
+ /*element: C.b:OutputUnit(1, {lib1})*/
+ final b;
+
+ /*element: C.:OutputUnit(1, {lib1})*/
+ const C(this.a, this.b);
+}
+
+typedef void MyF1();
+
+typedef void MyF2();
+
+/*element: topLevelMethod:OutputUnit(1, {lib1})*/
+topLevelMethod() {}
+
+/*element: cA:OutputUnit(1, {lib1})*/
+const cA = /*OutputUnit(1, {lib1})*/ const C(MyF1, topLevelMethod);
+
+/*element: cB:OutputUnit(1, {lib1})*/
+const cB = /*OutputUnit(1, {lib1})*/ MyF2;
diff --git a/tests/compiler/dart2js/old_frontend/mock_compiler.dart b/tests/compiler/dart2js/old_frontend/mock_compiler.dart
index 239aceb..94ea07a 100644
--- a/tests/compiler/dart2js/old_frontend/mock_compiler.dart
+++ b/tests/compiler/dart2js/old_frontend/mock_compiler.dart
@@ -282,7 +282,7 @@
}
/// Create a new [MockCompiler] and apply it asynchronously to [f].
- static Future<T> create<T>(T f(MockCompiler compiler)) {
+ static Future<T> create<T>(FutureOr<T> f(MockCompiler compiler)) {
MockCompiler compiler = new MockCompiler.internal();
return compiler.init().then((_) => f(compiler));
}
diff --git a/tests/compiler/dart2js/old_frontend/parser_test.dart b/tests/compiler/dart2js/old_frontend/parser_test.dart
index 0ef19e8..c4f9881 100644
--- a/tests/compiler/dart2js/old_frontend/parser_test.dart
+++ b/tests/compiler/dart2js/old_frontend/parser_test.dart
@@ -361,21 +361,6 @@
Expect.throws(parse, check);
}
-void testUnmatchedAngleBracket() {
- final String source = 'A<'; // unmatched '<'
- parse() {
- fullParseUnit(source, reporter: new Collector());
- }
-
- check(exn) {
- Collector c = exn;
- Expect.equals(LT_TOKEN, c.token);
- return true;
- }
-
- Expect.throws(parse, check);
-}
-
void main() {
testGenericTypes();
// TODO(ahe): Enable this test when we handle library prefixes.
@@ -393,5 +378,4 @@
testOperatorParse();
testMissingCloseParen();
testMissingCloseBraceInClass();
- testUnmatchedAngleBracket();
}
diff --git a/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart
index c0c24b1..8bf986a 100644
--- a/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*class: A:explicit=[B<A>],required*/
+/*class: A:arg,explicit=[B<A>]*/
class A {}
/*class: B:deps=[C],explicit=[B<A>],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_class_is.dart b/tests/compiler/dart2js/rti/data/generic_class_is.dart
index ad3cf6c..d82f758 100644
--- a/tests/compiler/dart2js/rti/data/generic_class_is.dart
+++ b/tests/compiler/dart2js/rti/data/generic_class_is.dart
@@ -4,7 +4,7 @@
import 'package:meta/dart2js.dart';
-/*class: A:checks=[A],implicit=[A],required*/
+/*class: A:arg,checked,implicit=[A]*/
class A {}
/*class: B:direct,explicit=[B.T],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_class_is2.dart b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
new file mode 100644
index 0000000..612fe1d
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:meta/dart2js.dart';
+
+// TODO(johnniwinther): A, C and C2 should be checked or A1, C1, and C2 should
+// have checks againts A, C and C, respectively.
+/*class: A:arg,checks=[A],implicit=[List<A<C2>>,List<A<C>>]*/
+class A<T> {}
+
+/*class: A1:arg,checks=[A]*/
+class A1 implements A<C1> {}
+
+/*class: B:direct,explicit=[B.T],needsArgs*/
+class B<T> {
+ @noInline
+ method(var t) => t is T;
+}
+
+/*class: C:arg,checks=[C],implicit=[List<A<C>>]*/
+class C {}
+
+/*class: C1:arg*/
+class C1 implements C {}
+
+/*class: C2:arg,checks=[C,C2],implicit=[List<A<C2>>]*/
+class C2 implements C {}
+
+main() {
+ Expect.isTrue(new B<List<A<C>>>().method(new List<A1>()));
+ Expect.isFalse(new B<List<A<C2>>>().method(new List<A1>()));
+}
diff --git a/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart
index 8fc9584..cc83ed0 100644
--- a/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart
@@ -6,7 +6,7 @@
class A {}
/*ast.class: B:deps=[closure],explicit=[B<A>],needsArgs*/
-/*kernel.class: B:deps=[closure],explicit=[B<A>],needsArgs,required*/
+/*kernel.class: B:arg,checks=[B],deps=[closure],explicit=[B<A>],needsArgs*/
class B<T> {}
main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_instanceof4.dart b/tests/compiler/dart2js/rti/data/generic_instanceof4.dart
index 0da5574..b035806 100644
--- a/tests/compiler/dart2js/rti/data/generic_instanceof4.dart
+++ b/tests/compiler/dart2js/rti/data/generic_instanceof4.dart
@@ -12,7 +12,7 @@
}
}
-/*class: BB:checks=[BB],implicit=[BB],required*/
+/*class: BB:arg,checked,implicit=[BB]*/
class BB {}
/*class: B:implicit=[B.T],indirect,needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_method1_strong.dart b/tests/compiler/dart2js/rti/data/generic_method1_strong.dart
index 7549db2..376861d 100644
--- a/tests/compiler/dart2js/rti/data/generic_method1_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method1_strong.dart
@@ -13,16 +13,15 @@
}
}
-// TODO(johnniwinther): Should include 'required'. Update the 'checkedArguments'
+// TODO(johnniwinther): Should include 'arg'. Update the 'checkedArguments'
// computation to take method type arguments into account.
-/*class: BB:implicit=[BB]*/
+/*class: BB:checked,implicit=[BB]*/
class BB {}
/*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
@noInline
method2<T>() => new A<T>();
-// TODO(johnniwinther): Should include 'checks=[BB]'.
/*class: B:deps=[method1],implicit=[B.T],indirect,needsArgs*/
class B<T> implements BB {
@noInline
diff --git a/tests/compiler/dart2js/rti/data/generic_method2_strong.dart b/tests/compiler/dart2js/rti/data/generic_method2_strong.dart
index 27a1d49..1235481 100644
--- a/tests/compiler/dart2js/rti/data/generic_method2_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method2_strong.dart
@@ -13,7 +13,9 @@
}
}
-/*class: BB:implicit=[BB]*/
+// TODO(johnniwinther): Should include 'arg'. Update the 'checkedArguments'
+// computation to take method type arguments into account.
+/*class: BB:checked,implicit=[BB]*/
class BB {}
/*class: B:deps=[method1],implicit=[B.T],indirect,needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_method3_strong.dart b/tests/compiler/dart2js/rti/data/generic_method3_strong.dart
index 3e7bc03..dddc5f0 100644
--- a/tests/compiler/dart2js/rti/data/generic_method3_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method3_strong.dart
@@ -13,14 +13,13 @@
}
}
-/*class: BB:checks=[BB],implicit=[BB],required*/
+/*class: BB:arg,checked,implicit=[BB]*/
class BB {}
/*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
@noInline
method2<T>() => new A<T>();
-// TODO(johnniwinther): Should include 'checks=[BB]'.
/*class: B:implicit=[B.T],indirect,needsArgs*/
class B<T> implements BB {
@noInline
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart b/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
index db9a3f7..bcd1f4b 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
@@ -12,29 +12,30 @@
class B2 {}
-/*class: C1:implicit=[C1]*/
+/*class: C1:checked,implicit=[C1]*/
class C1 {}
class C2 {}
+/*class: C3:checked*/
class C3 {}
-/*class: D1:implicit=[D1]*/
+/*class: D1:checked,implicit=[D1]*/
class D1 {}
class D2 {}
-/*class: E1:implicit=[E1]*/
+/*class: E1:checked,implicit=[E1]*/
class E1 {}
class E2 {}
-/*class: F1:implicit=[F1]*/
+/*class: F1:checked,implicit=[F1]*/
class F1 {}
class F2 {}
-/*class: F3:implicit=[F3]*/
+/*class: F3:checked,implicit=[F3]*/
class F3 {}
/*element: topLevelMethod1:direct,explicit=[topLevelMethod1.T],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/list_to_set.dart b/tests/compiler/dart2js/rti/data/list_to_set.dart
index bdb8503..fd08537 100644
--- a/tests/compiler/dart2js/rti/data/list_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/list_to_set.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
/*class: global#List:deps=[Class],explicit=[List],indirect,needsArgs*/
-/*class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*class: global#JSArray:checked,deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
main() {
var c = new Class<int>();
diff --git a/tests/compiler/dart2js/rti/data/map_literal.dart b/tests/compiler/dart2js/rti/data/map_literal.dart
index 8b7bb96..409bb7d 100644
--- a/tests/compiler/dart2js/rti/data/map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/map_literal.dart
@@ -5,7 +5,8 @@
/*class: global#Map:*/
/*class: global#LinkedHashMap:deps=[Map]*/
/*class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
-/*class: global#double:checks=[num],explicit=[double],required*/
+/*class: global#double:arg,explicit=[double]*/
+/*class: global#JSDouble:*/
main() {
<int, double>{}[0] = 0.5;
diff --git a/tests/compiler/dart2js/rti/data/map_literal_checked.dart b/tests/compiler/dart2js/rti/data/map_literal_checked.dart
index c9f25c1..a6dc521 100644
--- a/tests/compiler/dart2js/rti/data/map_literal_checked.dart
+++ b/tests/compiler/dart2js/rti/data/map_literal_checked.dart
@@ -2,10 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-/*class: global#Map:explicit=[Map],indirect,needsArgs*/
-/*class: global#LinkedHashMap:deps=[Map],explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.KLinkedHashMap.V],indirect,needsArgs*/
-/*class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.KJsLinkedHashMap.VJsLinkedHashMap<JsLinkedHashMap.K,JsLinkedHashMap.V>void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.KJsLinkedHashMap.V],needsArgs*/
-/*class: global#double:checks=[double,num,Object],explicit=[double],implicit=[double],required*/
+/*class: global#Map:checked,explicit=[Map],indirect,needsArgs*/
+/*class: global#LinkedHashMap:checked,deps=[Map],explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],indirect,needsArgs*/
+/*class: global#JsLinkedHashMap:checked,deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V,JsLinkedHashMap<JsLinkedHashMap.K,JsLinkedHashMap.V>,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*class: global#double:arg,checked,explicit=[double],implicit=[double]*/
+/*class: global#JSDouble:*/
main() {
<int, double>{}[0] = 0.5;
diff --git a/tests/compiler/dart2js/rti/data/map_to_set.dart b/tests/compiler/dart2js/rti/data/map_to_set.dart
index 2d79522..2d8037c 100644
--- a/tests/compiler/dart2js/rti/data/map_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/map_to_set.dart
@@ -5,7 +5,8 @@
/*class: global#Map:deps=[Class],needsArgs*/
/*class: global#LinkedHashMap:deps=[Map],needsArgs*/
/*class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
-/*class: global#double:checks=[num],explicit=[double],required*/
+/*class: global#double:arg,explicit=[double]*/
+/*class: global#JSDouble:*/
main() {
var c = new Class<double, int>();
diff --git a/tests/compiler/dart2js/rti/data/subtype_named_args.dart b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
new file mode 100644
index 0000000..10e7145
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// From co19/Language/Types/Function_Types/subtype_named_args_t02.
+
+import 'package:expect/expect.dart';
+
+/*ast.class: A:arg,checks=[A,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: A:arg,checks=[A,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+class A {}
+
+/*class: A1:arg,checks=[A1,Object]*/
+class A1 {}
+
+/*class: A2:arg,checks=[A2,Object]*/
+class A2 {}
+
+/*ast.class: B:arg,checks=[A,A1,A2,B,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: B:arg,checks=[A,A1,A2,B,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+class B implements A, A1, A2 {}
+
+/*ast.class: C:arg,checks=[A,A1,A2,B,C,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: C:arg,checks=[A,A1,A2,B,C,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+class C implements B {}
+
+/*ast.class: D:arg,checks=[A,A1,A2,B,C,D,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: D:arg,checks=[A,A1,A2,B,C,D,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+class D implements C {}
+
+/*ast.class: G:arg,checks=[G,Object],explicit=[dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: G:arg,checks=[G,Object],explicit=[dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+class G<T, S, U, W> {}
+
+typedef classesFunc({A a, B b, C c, D d});
+typedef genericsFunc({Map<num, int> m, List<List<B>> l, G<A, B, C, D> g});
+typedef dynamicFunc({var x, var y, var z, var v});
+typedef funcFunc({classesFunc f1, genericsFunc f2, dynamicFunc f3});
+typedef mixFunc({var x, B b, G<A, B, C, D> g, funcFunc f});
+
+typedef okWithClassesFunc_1({A a, A1 b, A1 c, A1 d});
+typedef okWithClassesFunc_2({D a, D b, D c, D d});
+
+typedef okWithGenericsFunc_1(
+ {Map<num, num> m, List<List<A1>> l, G<A, A1, A1, A1> g});
+typedef okWithGenericsFunc_2(
+ {Map<int, int> m, List<List<D>> l, G<D, D, D, D> g});
+
+typedef okWithDynamicFunc_1({A x, G y, mixFunc z, var v});
+typedef okWithDynamicFunc_2({int x, bool y, List<Map> z, classesFunc v});
+
+main() {
+ Expect.isTrue(({D a, B b, C c, A d}) {} is classesFunc);
+ Expect.isTrue(({A a, A b, A c, A d}) {} is classesFunc);
+ Expect.isTrue(({D a, A1 b, A1 c, A1 d}) {} is classesFunc);
+ Expect.isTrue(({D a, A2 b, A2 c, A2 d}) {} is classesFunc);
+ Expect.isTrue(({D a, D b, D c, D d}) {} is classesFunc);
+ Expect.isTrue(({var a, var b, var c, var d}) {} is classesFunc);
+ Expect.isTrue(({Object a, Object b, Object c, Object d}) {} is classesFunc);
+
+ Expect.isTrue(({Map<num, num> m, List<List<A1>> l, G<A, A1, A1, A1> g}) {}
+ is genericsFunc);
+ Expect.isTrue(
+ ({Map<int, int> m, List<List<D>> l, G<D, D, D, D> g}) {} is genericsFunc);
+ Expect.isTrue(({var m, var l, var g}) {} is genericsFunc);
+ Expect.isTrue(({Object m, Object l, Object g}) {} is genericsFunc);
+
+ Expect.isTrue(({A x, G y, mixFunc z, var v}) {} is dynamicFunc);
+ Expect
+ .isTrue(({int x, bool y, List<Map> z, classesFunc v}) {} is dynamicFunc);
+
+ Expect.isTrue((
+ {okWithClassesFunc_1 f1,
+ okWithGenericsFunc_1 f2,
+ okWithDynamicFunc_1 f3}) {} is funcFunc);
+ Expect.isTrue((
+ {okWithClassesFunc_2 f1,
+ okWithGenericsFunc_2 f2,
+ okWithDynamicFunc_2 f3}) {} is funcFunc);
+}
diff --git a/tests/compiler/dart2js/rti/data/type_argument_substitution.dart b/tests/compiler/dart2js/rti/data/type_argument_substitution.dart
new file mode 100644
index 0000000..c1e227e
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/type_argument_substitution.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that substitutions are emitted for classes that are only used as
+// type arguments.
+
+import 'package:expect/expect.dart';
+
+/*class: K:arg*/
+class K {}
+
+/*class: A:arg,checks=[A],explicit=[X<A<String>>]*/
+class A<T> {}
+
+/*class: B:arg,checks=[A]*/
+class B extends A<K> {}
+
+/*class: X:checked,explicit=[X<A<String>>],needsArgs*/
+class X<T> {}
+
+main() {
+ var v = new DateTime.now().millisecondsSinceEpoch != 42
+ ? new X<B>()
+ : new X<A<String>>();
+ Expect.isFalse(v is X<A<String>>);
+}
diff --git a/tests/compiler/dart2js/rti/rti_need_test.dart b/tests/compiler/dart2js/rti/rti_need_test.dart
index bcac3f2..75a94d4 100644
--- a/tests/compiler/dart2js/rti/rti_need_test.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test.dart
@@ -12,6 +12,7 @@
import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/resolution_types.dart';
import 'package:compiler/src/elements/types.dart';
import 'package:compiler/src/tree/nodes.dart' as ast;
import 'package:compiler/src/js_backend/runtime_types.dart';
@@ -70,8 +71,23 @@
static const String directTypeArgumentTest = 'direct';
static const String indirectTypeArgumentTest = 'indirect';
static const String typeLiteral = 'exp';
- static const String requiredArgumentClass = 'required';
static const String typeChecks = 'checks';
+
+ /// This class is needed as a checked type argument.
+ ///
+ /// For instance directly in `String` in `o is List<String>` or indirectly
+ /// as `String` in
+ ///
+ /// class C<T> {
+ /// method(o) => o is T;
+ /// }
+ /// main() => new C<String>().method('');
+ static const String argumentClass = 'arg';
+
+ // Objects are checked against this class.
+ //
+ // For instance `String` in `o is String`.
+ static const String checkedClass = 'checked';
}
abstract class ComputeValueMixin<T> {
@@ -84,11 +100,7 @@
RuntimeTypesNeed get rtiNeed => compiler.backendClosedWorldForTesting.rtiNeed;
RuntimeTypesChecks get rtiChecks =>
compiler.backend.emitter.typeTestRegistry.rtiChecks;
- TypeChecks get requiredChecks =>
- // TODO(johnniwinther): This should have been
- // rtiChecks.requiredChecks;
- // but it is incomplete and extended? by this:
- compiler.backend.emitter.typeTestRegistry.requiredChecks;
+ TypeChecks get requiredChecks => rtiChecks.requiredChecks;
ClassEntity getFrontendClass(ClassEntity cls);
MemberEntity getFrontendMember(MemberEntity member);
Local getFrontendClosure(MemberEntity member);
@@ -104,7 +116,7 @@
}
List<String> list = types.map(typeToString).toList()..sort();
if (list.isNotEmpty) {
- features[key] = '[${list.join('')}]';
+ features[key] = '[${list.join(',')}]';
}
}
@@ -140,13 +152,16 @@
rtiNeedBuilder.typeVariableTests.explicitIsChecks);
findChecks(features, Tags.implicitTypeCheck, frontendClass,
rtiNeedBuilder.typeVariableTests.implicitIsChecks);
+ if (rtiChecks.checkedClasses.contains(backendClass)) {
+ features.add(Tags.checkedClass);
+ }
if (rtiChecks.getRequiredArgumentClasses().contains(backendClass)) {
- features.add(Tags.requiredArgumentClass);
+ features.add(Tags.argumentClass);
}
Iterable<TypeCheck> checks = requiredChecks[backendClass];
if (checks.isNotEmpty) {
features[Tags.typeChecks] =
- '[${checks.map((c) => c.cls.name).join(',')}]';
+ '[${(checks.map((c) => c.cls.name).toList()..sort()).join(',')}]';
}
return features.getText();
}
@@ -203,7 +218,7 @@
}
/// Visitor that determines whether a type refers to [entity].
-class FindTypeVisitor extends BaseDartTypeVisitor<bool, Null> {
+class FindTypeVisitor extends BaseResolutionDartTypeVisitor<bool, Null> {
final Entity entity;
FindTypeVisitor(this.entity);
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 5065972..441c6d5 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -11,6 +11,7 @@
local_function_call_test: RuntimeError # Issue 31879
mirror_printer_test: Pass, Slow # Issue 25940, 16473
mirrors_used_closure_test: Fail # Issue 17939
+generic_class_is_test: Fail # Issue 32004
no_such_method_test: Fail # Wrong Invocation.memberName.
statements_test: Fail
typed_locals_test: Pass, Fail
@@ -84,7 +85,6 @@
deferred_fail_and_retry_worker_test: Fail
dummy_compiler_test: CompileTimeError
invalid_annotation2_test/none: RuntimeError
-label_test/06: MissingCompileTimeError
minus_zero_test/01: MissingCompileTimeError
mirror_invalid_field_access2_test: RuntimeError
mirror_invalid_field_access3_test: RuntimeError
@@ -132,7 +132,6 @@
deferred/reflect_multiple_default_arg_test: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
deferred_fail_and_retry_test: RuntimeError
deferred_fail_and_retry_worker_test: Fail
-label_test/06: MissingCompileTimeError
mirror_enqueuer_regression_test: Pass
private_symbol_literal_test/01: MissingCompileTimeError
private_symbol_literal_test/02: MissingCompileTimeError
@@ -160,7 +159,6 @@
deferred_fail_and_retry_worker_test: Fail
inference_nsm_mirrors_test: CompileTimeError
invalid_annotation2_test/none: CompileTimeError
-label_test/06: MissingCompileTimeError
mirror_enqueuer_regression_test: CompileTimeError
mirror_invalid_field_access2_test: CompileTimeError
mirror_invalid_field_access3_test: CompileTimeError
@@ -209,7 +207,6 @@
dummy_compiler_test: CompileTimeError
inference_nsm_mirrors_test: CompileTimeError
invalid_annotation2_test/none: CompileTimeError
-label_test/06: MissingCompileTimeError
mirror_enqueuer_regression_test: CompileTimeError
mirror_invalid_field_access2_test: CompileTimeError
mirror_invalid_field_access3_test: CompileTimeError
diff --git a/tests/compiler/dart2js_extra/generic_class_is_test.dart b/tests/compiler/dart2js_extra/generic_class_is_test.dart
new file mode 100644
index 0000000..d97cb7c
--- /dev/null
+++ b/tests/compiler/dart2js_extra/generic_class_is_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:meta/dart2js.dart';
+
+class A<T> {}
+
+class A1 implements A<C1> {}
+
+class B<T> {
+ @noInline
+ method(var t) => t is T;
+}
+
+class C {}
+
+class C1 implements C {}
+
+class C2 implements C {}
+
+main() {
+ Expect.isTrue(new B<List<A<C>>>().method(new List<A1>()));
+ Expect.isFalse(new B<List<A<C2>>>().method(new List<A1>()));
+}
diff --git a/tests/compiler/dart2js_extra/recursive_metadata_test.dart b/tests/compiler/dart2js_extra/recursive_metadata_test.dart
new file mode 100644
index 0000000..1c46209
--- /dev/null
+++ b/tests/compiler/dart2js_extra/recursive_metadata_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+// Tests that the compiler doesn't crash resolving annotations that refer
+// to other annotated types.
+
+class Annotation {
+ final String value;
+ const Annotation({this.value});
+}
+
+enum Enum {
+ a,
+ b,
+}
+
+class SubAnno extends Annotation {
+ final Enum e;
+ final Type type;
+ const SubAnno({String value, this.e, this.type}) : super(value: value);
+}
+
+@SubAnno(value: 'super')
+class A {}
+
+@SubAnno(value: 'sub')
+class B extends A {}
+
+@SubAnno(type: B)
+class C {}
+
+main() {
+ var c = new C();
+ Expect.isTrue(c != null);
+}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index b4055c8..0fa1d5c 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -3,12 +3,51 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2analyzer ]
+big_integer_arith_vm_test/add: CompileTimeError # int64
+big_integer_arith_vm_test/div: CompileTimeError # int64
+big_integer_arith_vm_test/gcd: CompileTimeError # int64
+big_integer_arith_vm_test/mod: CompileTimeError # int64
+big_integer_arith_vm_test/modInv: CompileTimeError # int64
+big_integer_arith_vm_test/modPow: CompileTimeError # int64
+big_integer_arith_vm_test/mul: CompileTimeError # int64
+big_integer_arith_vm_test/negate: CompileTimeError # int64
+big_integer_arith_vm_test/none: CompileTimeError # int64
+big_integer_arith_vm_test/overflow: CompileTimeError # int64
+big_integer_arith_vm_test/shift: CompileTimeError # int64
+big_integer_arith_vm_test/sub: CompileTimeError # int64
+big_integer_arith_vm_test/trunDiv: CompileTimeError # int64
+bit_twiddling_bigint_test: CompileTimeError # int64
+bit_twiddling_test: CompileTimeError # int64
+double_ceil_test: CompileTimeError # int64
+double_floor_test: CompileTimeError # int64
+double_round_test: CompileTimeError # int64
+double_truncate_test: CompileTimeError # int64
duration2_test: StaticWarning, OK # Test generates error on purpose.
error_stack_trace_test: StaticWarning, OK # Test generates errors on purpose.
hash_set_type_check_test: StaticWarning, OK # Tests failing type tests.
+int_ceil_test: CompileTimeError # int64
+int_ceil_to_double_test: CompileTimeError # int64
+int_floor_test: CompileTimeError # int64
+int_floor_to_double_test: CompileTimeError # int64
+int_from_environment_test: CompileTimeError # int64
+int_modulo_arith_test/bignum: CompileTimeError # int64
+int_modulo_arith_test/modPow: CompileTimeError # int64
+int_modulo_arith_test/none: CompileTimeError # int64
int_parse_radix_bad_handler_test: Fail
+int_parse_radix_test/02: CompileTimeError # int64
+int_round_test: CompileTimeError # int64
+int_round_to_double_test: CompileTimeError # int64
+int_to_int_test: CompileTimeError # int64
+int_truncate_test: CompileTimeError # int64
+int_truncate_to_double_test: CompileTimeError # int64
+integer_to_radix_string_test: CompileTimeError # int64
+integer_to_string_test/01: CompileTimeError # int64
iterable_element_at_test: StaticWarning, OK # Test generates errors on purpose.
num_clamp_test: StaticWarning, OK # Test generates errors on purpose.
+num_parse_test/01: CompileTimeError # int64
+num_parse_test/none: CompileTimeError # int64
+num_sign_test: CompileTimeError # int64
+regress_r21715_test: CompileTimeError # int64
string_test: StaticWarning, OK # Test generates error on purpose.
[ $compiler == dart2js ]
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index a5abcca..3ba808b 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -3,6 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2analyzer ]
+compare_to2_test: CompileTimeError # invalid test
int_parse_radix_bad_handler_test: MissingCompileTimeError
iterable_element_at_test/static: Pass
num_sign_test: Crash, Pass # Issue 31768
@@ -130,14 +131,14 @@
[ $compiler == dart2js && $runtime == drt && $csp && !$dart2js_with_kernel && $minified ]
core_runtime_types_test: Pass, Fail # Issue 27913
+[ $compiler == dart2js && $runtime != none ]
+regexp/pcre_test: Pass, Slow # Issue 21593
+
[ $compiler == dart2js && $runtime != none && !$checked && !$dart2js_with_kernel ]
growable_list_test: RuntimeError # Concurrent modifications test always runs
splay_tree_from_iterable_test: RuntimeError
string_split_test/checkedstore: RuntimeError # Issue 30548: does not check stores into List<String>
-[ $compiler == dart2js && $runtime != none ]
-regexp/pcre_test: Pass, Slow # Issue 21593
-
[ $compiler == dart2js && $runtime != none && !$dart2js_with_kernel ]
error_stack_trace1_test: RuntimeError # Issue 12399
int_parse_radix_test/01: RuntimeError
@@ -181,6 +182,7 @@
iterable_return_type_test/01: RuntimeError
iterable_return_type_test/02: RuntimeError
iterable_to_list_test/01: RuntimeError
+list_replace_range_test: RuntimeError # Issue 32010
list_test/01: Crash # Unsupported operation: Unsupported type parameter type node T.
list_test/none: Crash # Unsupported operation: Unsupported type parameter type node T.
map_test: Crash # tests/corelib_2/map_test.dart:903:7: Internal problem: Unhandled Null in installDefaultConstructor.
@@ -250,6 +252,8 @@
list_concurrent_modify_test: RuntimeError
list_filled_type_argument_test: RuntimeError
list_insert_all_test: RuntimeError
+list_replace_range_test: RuntimeError
+list_set_all_test: RuntimeError
list_test/01: RuntimeError
list_test/none: RuntimeError
list_unmodifiable_test: Crash # Assertion failure: Unexpected arguments. Expected 1 argument, actual: [invoke dynamic getter: selector=Selector(getter, length, arity=0), mask=[subtype=SetMixin], HTypeInfoReadVariable(SetMixin.E)].
@@ -313,6 +317,8 @@
list_concurrent_modify_test: RuntimeError
list_filled_type_argument_test: RuntimeError
list_insert_all_test: RuntimeError
+list_replace_range_test: RuntimeError # Issue 32010
+list_set_all_test: RuntimeError # Issue 32010
list_test/01: RuntimeError
list_test/none: RuntimeError
list_unmodifiable_test: Crash # Wrong number of template arguments, given 2, expected 1
@@ -380,6 +386,7 @@
iterable_mapping_test/01: MissingCompileTimeError
[ $compiler == dartdevc && $runtime != none ]
+compare_to2_test: CompileTimeError # invalid test
symbol_operator_test: RuntimeError # Issue 29921
[ $compiler != dartdevc && $compiler != dartdevk && $checked && !$strong ]
@@ -406,9 +413,6 @@
bool_from_environment2_test/03: MissingCompileTimeError
iterable_to_list_test/01: RuntimeError
iterable_to_list_test/none: RuntimeError
-json_map_test: RuntimeError
-list_replace_range_test: RuntimeError
-list_set_all_test: RuntimeError
null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments)
null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments)
string_from_environment3_test/03: MissingCompileTimeError # Issue 31936 - throwing const constructors.
@@ -429,9 +433,6 @@
bool_from_environment2_test/03: MissingCompileTimeError
iterable_to_list_test/01: RuntimeError
iterable_to_list_test/none: RuntimeError
-json_map_test: RuntimeError
-list_replace_range_test: RuntimeError
-list_set_all_test: RuntimeError
null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments)
null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments)
regexp/stack-overflow_test: RuntimeError
@@ -494,7 +495,6 @@
integer_parsed_arith_vm_test: RuntimeError # Issues 10245, 29921
integer_parsed_div_rem_vm_test: RuntimeError # Issue 29921
integer_parsed_mul_div_vm_test: RuntimeError # Issue 29921
-json_map_test: RuntimeError
regress_r21715_test: RuntimeError # Requires fixed-size int64 support.
typed_data_with_limited_ints_test: Skip # dart2js and dartdevc don't know about --limit-ints-to-64-bits
@@ -516,11 +516,8 @@
integer_to_string_test/01: RuntimeError # Issue 29921
iterable_return_type_test/02: RuntimeError # Issue 29921
iterable_to_list_test/*: RuntimeError
-json_map_test: RuntimeError # Issue 29921
list_concurrent_modify_test: RuntimeError # DDC uses ES6 array iterators so it does not issue this
list_removeat_test: RuntimeError # Issue 29921
-list_replace_range_test: RuntimeError # Issue 29921
-list_set_all_test: RuntimeError # Issue 29921
main_test: RuntimeError # Issue 29921
nan_infinity_test/01: RuntimeError # Issue 29921
null_nosuchmethod_test/01: RuntimeError # DDC checks type before too many arguments, so TypeError instead of NSM
diff --git a/tests/corelib_2/json_map_test.dart b/tests/corelib_2/json_map_test.dart
index 2e288cd..ed0544c 100644
--- a/tests/corelib_2/json_map_test.dart
+++ b/tests/corelib_2/json_map_test.dart
@@ -9,7 +9,7 @@
import 'dart:collection' show LinkedHashMap, HashMap;
bool useReviver = false;
-Map jsonify(Map map) {
+Map<String, dynamic> jsonify(Map map) {
String encoded = json.encode(map);
return useReviver
? json.decode(encoded, reviver: (key, value) => value)
@@ -35,7 +35,10 @@
testEmpty(jsonify({}));
testAtoB(jsonify({'a': 'b'}));
- Map map = jsonify({});
+ // You can write 'Map<String, dynamic>' here (or 'var' which infers the
+ // same), but if you write just 'Map' as the type, then the type of the
+ // constant argument in the addAll below is not inferred correctly.
+ var map = jsonify({});
map['a'] = 'b';
testAtoB(map);
@@ -298,17 +301,12 @@
}
void testType() {
+ // The documentation of json.decode doesn't actually specify that it returns
+ // a map (it's marked dynamic), but it's a reasonable expectation if you
+ // don't provide a reviver function.
Expect.isTrue(jsonify({}) is Map);
- Expect.isTrue(jsonify({}) is HashMap);
- Expect.isTrue(jsonify({}) is LinkedHashMap);
-
Expect.isTrue(jsonify({}) is Map<String, dynamic>);
- Expect.isTrue(jsonify({}) is HashMap<String, dynamic>);
- Expect.isTrue(jsonify({}) is LinkedHashMap<String, dynamic>);
-
Expect.isFalse(jsonify({}) is Map<int, dynamic>);
- Expect.isFalse(jsonify({}) is HashMap<int, dynamic>);
- Expect.isFalse(jsonify({}) is LinkedHashMap<int, dynamic>);
}
void testClear() {
diff --git a/tests/corelib_2/list_replace_range_test.dart b/tests/corelib_2/list_replace_range_test.dart
index 237774aa..964ed44 100644
--- a/tests/corelib_2/list_replace_range_test.dart
+++ b/tests/corelib_2/list_replace_range_test.dart
@@ -5,7 +5,7 @@
import "package:expect/expect.dart";
import "dart:collection";
-test(List list, int start, int end, Iterable iterable) {
+test(List<int> list, int start, int end, Iterable<int> iterable) {
List copy = list.toList();
list.replaceRange(start, end, iterable);
List iterableList = iterable.toList();
@@ -22,7 +22,7 @@
}
}
-class MyList extends ListBase {
+class MyList<T> extends ListBase<T> {
List list;
MyList(this.list);
get length => list.length;
diff --git a/tests/corelib_2/list_set_all_test.dart b/tests/corelib_2/list_set_all_test.dart
index d5f9a60..85f2081 100644
--- a/tests/corelib_2/list_set_all_test.dart
+++ b/tests/corelib_2/list_set_all_test.dart
@@ -5,7 +5,7 @@
import "package:expect/expect.dart";
import "dart:collection";
-test(List list, int index, Iterable iterable) {
+test(List<int> list, int index, Iterable<int> iterable) {
List copy = list.toList();
list.setAll(index, iterable);
Expect.equals(copy.length, list.length);
@@ -21,7 +21,7 @@
}
}
-class MyList extends ListBase {
+class MyList<T> extends ListBase<T> {
List list;
MyList(this.list);
get length => list.length;
diff --git a/tests/corelib_2/regexp/regexp_escape_test.dart b/tests/corelib_2/regexp/regexp_escape_test.dart
new file mode 100644
index 0000000..e082206
--- /dev/null
+++ b/tests/corelib_2/regexp/regexp_escape_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+var escapeChars = r"([)}{]?*+.$^|\";
+
+var nonEscapeAscii = "\x00\x01\x02\x03\x04\x05\x06\x07" //
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" //
+ "\x10\x11\x12\x13\x14\x15\x16\x17" //
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" //
+ """ !"#%&',-/0123456789:;<=>""" //
+ """@ABCDEFGHIJKLMNOPQRSTUVWXYZ_""" //
+ """`abcdefghijklmnopqrstuvwxyz~\x7f""";
+var someNonAscii =
+ new String.fromCharCodes(new List.generate(0x1000 - 128, (x) => x + 128));
+
+test(String string, [bool shouldEscape]) {
+ var escape = RegExp.escape(string);
+ Expect.isTrue(new RegExp(escape).hasMatch(string), "$escape");
+ Expect.equals(string, new RegExp(escape).firstMatch(string)[0], "$escape");
+ if (shouldEscape == true) {
+ Expect.notEquals(string, escape);
+ } else if (shouldEscape == false) {
+ Expect.equals(string, escape);
+ }
+}
+
+main() {
+ for (var c in escapeChars.split("")) {
+ test(c, true);
+ }
+ for (var c in nonEscapeAscii.split("")) {
+ test(c, false);
+ }
+ test(escapeChars, true);
+ test(nonEscapeAscii, false);
+ test(someNonAscii, false);
+ test((nonEscapeAscii + escapeChars) * 3, true);
+ test(r'.abc', true); // First only.
+ test(r'abc.', true); // Last only.
+}
diff --git a/tests/kernel/kernel.status b/tests/kernel/kernel.status
index a39cb57..9c3de36 100644
--- a/tests/kernel/kernel.status
+++ b/tests/kernel/kernel.status
@@ -17,6 +17,8 @@
[ $compiler == dart2analyzer && $runtime == none ]
unsorted/invocation_errors_test: StaticWarning
+unsorted/loop_test: CompileTimeError # int64
+unsorted/simple_literal_test: CompileTimeError # int64
unsorted/super_mixin_test: CompileTimeError
[ $compiler == dartk && $strong ]
diff --git a/tests/language/language.status b/tests/language/language.status
index 25f3407..ebde631 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -424,7 +424,6 @@
example_constructor_test: Fail, OK # Failures related to super call in ctor initializer list
field_initialization_order_test: Fail, OK # Failures related to super call in ctor initializer list
final_field_initialization_order_test: Fail, OK # Failures related to super call in ctor initializer list
-generalized_void_syntax_test: CompileTimeError
generic_methods_type_expression_test: RuntimeError # Issue 25869 / 27460
least_upper_bound_expansive_test/*: Fail, OK # Non-contractive types are not supported in the vm.
main_not_a_function_test/01: Skip # Skipped temporaril until Issue 29895 is fixed.
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index d2c1b6f..b567887 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -11,6 +11,9 @@
accessor_conflict_import_prefixed_test: StaticWarning # Issue 25624
accessor_conflict_import_test: StaticWarning # Issue 25624
application_negative_test: CompileTimeError # Issue 14528, The following tests are currently assumed to be failing because the test is wrong.
+assert_message_test: StaticWarning
+assertion_initializer_test: StaticWarning
+assertion_test: StaticWarning
bad_initializer1_negative_test: CompileTimeError # Issue 14529, The following tests are currently assumed to be failing because the test is wrong.
bad_initializer2_negative_test: Fail # Issue 14880
bad_named_constructor_negative_test: CompileTimeError # Issue 18693, The following tests are currently assumed to be failing because the test is wrong.
@@ -387,6 +390,7 @@
unresolved_in_factory_negative_test: Fail # Issue 12163
unresolved_top_level_method_negative_test: StaticWarning
unresolved_top_level_var_negative_test: Fail # Issue 12163
+vm/canonicalization_preserves_deopt_test: StaticWarning
vm/debug_break_enabled_vm_test: Skip
vm/debug_break_vm_test/*: Skip
vm/reflect_core_vm_test: CompileTimeError # This test uses "const Symbol('_setAt')"
@@ -398,12 +402,25 @@
*: Skip # Issue 28649
[ $compiler == dart2analyzer && $runtime == none ]
-assertion_initializer_const_function_error_test/01: MissingCompileTimeError
-assertion_initializer_const_function_test/01: MissingStaticWarning
+arithmetic_test: CompileTimeError # int64
+bit_operations_test/01: CompileTimeError # int64
+bit_operations_test/02: CompileTimeError # int64
+bit_operations_test/03: CompileTimeError # int64
+bit_operations_test/04: CompileTimeError # int64
+bit_operations_test/none: CompileTimeError # int64
+deopt_inlined_function_lazy_test: CompileTimeError # int64
+guess_cid_test: CompileTimeError # int64
+identical_closure2_test: CompileTimeError # int64
+int2_test: CompileTimeError # int64
+mint_compares_test: CompileTimeError # int64
+number_identity_test: CompileTimeError # int64
+vm/regress_14903_test: CompileTimeError # int64
[ $compiler == dart2analyzer && $runtime == none && $checked ]
-assertion_initializer_const_error2_test/*: MissingCompileTimeError # Issue #
assertion_initializer_const_error2_test/cc10: Pass # Issue #31321
assertion_initializer_const_error2_test/cc11: Pass # Issue #31321
assertion_initializer_const_error2_test/none: Pass
+[ $compiler == dart2analyzer && $runtime == none && !$checked ]
+assertion_initializer_const_function_error_test/01: MissingCompileTimeError
+
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index d88c1e5..e2e9167 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -62,7 +62,6 @@
async_return_types_test/nestedFuture: Fail # Issue 26429
async_return_types_test/wrongTypeParameter: Fail # Issue 26429
async_star_cancel_while_paused_test: RuntimeError
-bad_constructor_test/06: Crash # NoSuchMethodError: The getter 'iterator' was called on null.
bad_override_test/03: MissingCompileTimeError
bad_override_test/04: MissingCompileTimeError
bad_override_test/05: MissingCompileTimeError
@@ -479,7 +478,6 @@
assertion_initializer_test: CompileTimeError
assertion_test: RuntimeError
async_star_cancel_while_paused_test: RuntimeError
-bad_constructor_test/06: Crash # NoSuchMethodError: The getter 'iterator' was called on null.
bad_override_test/03: MissingCompileTimeError
bad_override_test/04: MissingCompileTimeError
bad_override_test/05: MissingCompileTimeError
@@ -786,7 +784,6 @@
assertion_test: RuntimeError
async_star_cancel_while_paused_test: RuntimeError
async_test/setter1: Crash # 'file:*/pkg/compiler/lib/src/kernel/element_map_impl.dart': Failed assertion: line 939 pos 18: 'asyncMarker == AsyncMarker.SYNC': is not true.
-bad_constructor_test/06: Crash # NoSuchMethodError: The getter 'iterator' was called on null.
bad_override_test/03: MissingCompileTimeError
bad_override_test/04: MissingCompileTimeError
bad_override_test/05: MissingCompileTimeError
@@ -837,13 +834,9 @@
cyclic_constructor_test/01: Crash # Issue 30856
deferred_constraints_constants_test/none: CompileTimeError
deferred_constraints_constants_test/reference_after_load: CompileTimeError
-deferred_constraints_type_annotation_test/as_operation: RuntimeError
-deferred_constraints_type_annotation_test/catch_check: RuntimeError
-deferred_constraints_type_annotation_test/is_check: RuntimeError
deferred_inheritance_constraints_test/extends: MissingCompileTimeError
deferred_inheritance_constraints_test/implements: MissingCompileTimeError
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
-deferred_load_constants_test/none: RuntimeError
deferred_load_library_wrong_args_test/01: MissingRuntimeError
deferred_not_loaded_check_test: RuntimeError
deferred_redirecting_factory_test: RuntimeError
@@ -959,16 +952,8 @@
mixin_illegal_superclass_test/28: MissingCompileTimeError
mixin_illegal_superclass_test/29: MissingCompileTimeError
mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_issue10216_2_test: RuntimeError
mixin_mixin2_test: RuntimeError
mixin_mixin3_test: RuntimeError
-mixin_mixin4_test: RuntimeError
-mixin_mixin5_test: RuntimeError
-mixin_mixin6_test: RuntimeError
-mixin_mixin7_test: RuntimeError
-mixin_mixin_bound2_test: RuntimeError
-mixin_mixin_bound_test: RuntimeError
-mixin_mixin_test: RuntimeError
mixin_mixin_type_arguments_test: RuntimeError
mixin_of_mixin_test/01: CompileTimeError
mixin_of_mixin_test/02: CompileTimeError
@@ -1111,7 +1096,6 @@
assertion_initializer_test: CompileTimeError
assertion_test: RuntimeError
async_star_cancel_while_paused_test: RuntimeError
-bad_constructor_test/06: Crash # NoSuchMethodError: The getter 'iterator' was called on null.
bad_override_test/03: MissingCompileTimeError
bad_override_test/04: MissingCompileTimeError
bad_override_test/05: MissingCompileTimeError
@@ -1158,25 +1142,11 @@
constructor_redirect2_test/01: MissingCompileTimeError
constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2).
cyclic_constructor_test/01: Crash # Issue 30856
-cyclic_type2_test: RuntimeError
-cyclic_type_test/00: RuntimeError
-cyclic_type_test/01: RuntimeError
-cyclic_type_test/02: RuntimeError
-cyclic_type_test/03: RuntimeError
-cyclic_type_test/04: RuntimeError
deferred_constraints_constants_test/none: CompileTimeError
deferred_constraints_constants_test/reference_after_load: CompileTimeError
-deferred_constraints_type_annotation_test/as_operation: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
-deferred_constraints_type_annotation_test/as_operation: RuntimeError
-deferred_constraints_type_annotation_test/catch_check: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
-deferred_constraints_type_annotation_test/catch_check: RuntimeError
-deferred_constraints_type_annotation_test/is_check: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
-deferred_constraints_type_annotation_test/is_check: RuntimeError
deferred_inheritance_constraints_test/extends: MissingCompileTimeError
deferred_inheritance_constraints_test/implements: MissingCompileTimeError
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
-deferred_load_constants_test/none: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
-deferred_load_constants_test/none: RuntimeError
deferred_load_library_wrong_args_test/01: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
deferred_load_library_wrong_args_test/01: MissingRuntimeError
deferred_not_loaded_check_test: RuntimeError
@@ -1196,7 +1166,6 @@
external_test/10: MissingRuntimeError
external_test/13: MissingRuntimeError
external_test/20: MissingRuntimeError
-f_bounded_quantification4_test: RuntimeError
f_bounded_quantification5_test: RuntimeError
factory_redirection_test/07: MissingCompileTimeError
fauxverride_test/03: MissingCompileTimeError
@@ -1214,7 +1183,6 @@
full_stacktrace1_test: RuntimeError # Issue 12698
full_stacktrace2_test: RuntimeError # Issue 12698
full_stacktrace3_test: RuntimeError # Issue 12698
-generic_closure_test: RuntimeError
generic_methods_type_expression_test/01: RuntimeError
generic_methods_type_expression_test/03: RuntimeError
generic_methods_type_expression_test/none: RuntimeError
@@ -1255,7 +1223,6 @@
mixin_forwarding_constructor4_test/01: MissingCompileTimeError
mixin_forwarding_constructor4_test/02: MissingCompileTimeError
mixin_forwarding_constructor4_test/03: MissingCompileTimeError
-mixin_generic_test: RuntimeError
mixin_illegal_super_use_test/01: MissingCompileTimeError
mixin_illegal_super_use_test/02: MissingCompileTimeError
mixin_illegal_super_use_test/03: MissingCompileTimeError
@@ -1297,16 +1264,6 @@
mixin_illegal_superclass_test/28: MissingCompileTimeError
mixin_illegal_superclass_test/29: MissingCompileTimeError
mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_issue10216_2_test: RuntimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
-mixin_mixin4_test: RuntimeError
-mixin_mixin5_test: RuntimeError
-mixin_mixin6_test: RuntimeError
-mixin_mixin7_test: RuntimeError
-mixin_mixin_bound2_test: RuntimeError
-mixin_mixin_bound_test: RuntimeError
-mixin_mixin_test: RuntimeError
mixin_mixin_type_arguments_test: RuntimeError
mixin_of_mixin_test/01: CompileTimeError
mixin_of_mixin_test/02: CompileTimeError
@@ -1406,7 +1363,6 @@
regress_17382_test: RuntimeError
regress_18535_test: CompileTimeError
regress_20394_test/01: MissingCompileTimeError
-regress_21795_test: RuntimeError
regress_22936_test/01: RuntimeError
regress_24283_test: RuntimeError
regress_27572_test: RuntimeError
@@ -1416,7 +1372,6 @@
regress_28255_test: CompileTimeError
setter_override_test/00: MissingCompileTimeError
setter_override_test/03: MissingCompileTimeError
-stack_trace_test: RuntimeError
stacktrace_demangle_ctors_test: RuntimeError # Issue 12698
stacktrace_rethrow_error_test/none: RuntimeError # Issue 12698
stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
@@ -1633,21 +1588,21 @@
regress_26855_test/4: Crash # Issue 26867
[ $compiler == dart2js && !$dart2js_with_kernel && $minified ]
-cyclic_type2_test: Fail # Issue 12605
-cyclic_type_test/0*: Fail # Issue 12605
-f_bounded_quantification4_test: Fail, Pass # Issue 12605
-generic_closure_test: Fail # Issue 12605
-mixin_generic_test: Fail # Issue 12605
-mixin_mixin2_test: Fail # Issue 12605
-mixin_mixin3_test: Fail # Issue 12605
-mixin_mixin4_test: Fail # Issue 12605
-mixin_mixin5_test: Fail # Issue 12605
-mixin_mixin6_test: Fail # Issue 12605
-mixin_mixin_bound2_test: RuntimeError # Issue 12605
-mixin_mixin_bound_test: RuntimeError # Issue 12605
symbol_conflict_test: RuntimeError # Issue 23857
-[ !$dart2js_with_kernel && $minified ]
-regress_21795_test: RuntimeError # Issue 12605
-stack_trace_test: Fail, OK # Stack trace not preserved in minified code.
+[ $compiler == dart2js && $minified ]
+cyclic_type2_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+cyclic_type_test/0*: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+f_bounded_quantification4_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+generic_closure_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_generic_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_mixin2_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_mixin3_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_mixin4_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_mixin5_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_mixin6_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_mixin_bound2_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+mixin_mixin_bound_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+regress_21795_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+stack_trace_test: RuntimeError, OK # Stack trace not preserved in minified code.
diff --git a/tests/language_2/assertion_initializer_const_error2_test.dart b/tests/language_2/assertion_initializer_const_error2_test.dart
index e21bc80..cf7788d 100644
--- a/tests/language_2/assertion_initializer_const_error2_test.dart
+++ b/tests/language_2/assertion_initializer_const_error2_test.dart
@@ -10,38 +10,38 @@
final int x;
// Const constructors.
const C.cc01(this.x, y)
- : assert(x < y) //# cc01: checked mode compile-time error
+ : assert(x < y) //# cc01: compile-time error
;
const C.cc02(x, y) : x = x
- , assert(x < y) //# cc02: checked mode compile-time error
+ , assert(x < y) //# cc02: compile-time error
;
const C.cc03(x, y) :
- assert(x < y), //# cc03: checked mode compile-time error
+ assert(x < y), //# cc03: compile-time error
x = x;
const C.cc05(this.x, y) :
- assert(x < y), //# cc05: checked mode compile-time error
+ assert(x < y), //# cc05: compile-time error
super();
const C.cc06(x, y) : x = x
- , assert(x < y) //# cc06: checked mode compile-time error
+ , assert(x < y) //# cc06: compile-time error
, super()
;
const C.cc07(x, y) :
- assert(x < y), //# cc07: checked mode compile-time error
+ assert(x < y), //# cc07: compile-time error
x = x, super();
const C.cc08(x, y) :
- assert(x < y), //# cc08: checked mode compile-time error
+ assert(x < y), //# cc08: compile-time error
x = x
, assert(y > x) //# cc08: continued
, super()
;
const C.cc09(this.x, y)
- : assert(x < y, "$x < $y") //# cc09: checked mode compile-time error
+ : assert(x < y, "$x < $y") //# cc09: compile-time error
;
const C.cc10(this.x, y)
- : assert(x < y,) //# cc10: checked mode compile-time error
+ : assert(x < y,) //# cc10: compile-time error
;
const C.cc11(this.x, y)
- : assert(x < y, "$x < $y",) //# cc11: checked mode compile-time error
+ : assert(x < y, "$x < $y",) //# cc11: compile-time error
;
}
diff --git a/tests/language_2/assertion_initializer_test.dart b/tests/language_2/assertion_initializer_test.dart
index 9ff69c9..b2fe755 100644
--- a/tests/language_2/assertion_initializer_test.dart
+++ b/tests/language_2/assertion_initializer_test.dart
@@ -15,11 +15,10 @@
C.c01(this.x, y) : assert(x < y);
C.c02(x, y) : x = x, assert(x < y);
C.c03(x, y) : assert(x < y), x = x;
- C.c04(this.x, y) : super(), assert(x < y);
C.c05(this.x, y) : assert(x < y), super();
- C.c06(x, y) : x = x, super(), assert(x < y);
- C.c07(x, y) : assert(x < y), super(), x = x;
- C.c08(x, y) : assert(x < y), super(), x = x, assert(y > x);
+ C.c06(x, y) : x = x, assert(x < y), super();
+ C.c07(x, y) : assert(x < y), x = x, super();
+ C.c08(x, y) : assert(x < y), x = x, assert(y > x), super();
C.c09(this.x, y) : assert(x < y, "$x < $y");
C.c10(this.x, y) : assert(x < y,);
C.c11(this.x, y) : assert(x < y, "$x < $y",);
@@ -27,11 +26,10 @@
const C.cc01(this.x, y) : assert(x < y);
const C.cc02(x, y) : x = x, assert(x < y);
const C.cc03(x, y) : assert(x < y), x = x;
- const C.cc04(this.x, y) : super(), assert(x < y);
const C.cc05(this.x, y) : assert(x < y), super();
- const C.cc06(x, y) : x = x, super(), assert(x < y);
- const C.cc07(x, y) : assert(x < y), super(), x = x;
- const C.cc08(x, y) : assert(x < y), super(), x = x, assert(y > x);
+ const C.cc06(x, y) : x = x, assert(x < y), super();
+ const C.cc07(x, y) : assert(x < y), x = x, super();
+ const C.cc08(x, y) : assert(x < y), x = x, assert(y > x), super();
const C.cc09(this.x, y) : assert(x < y, "$x < $y");
const C.cc10(this.x, y) : assert(x < y,);
const C.cc11(this.x, y) : assert(x < y, "$x < $y",);
@@ -39,26 +37,24 @@
C.nc01(this.x, y) : assert(check(x, y));
C.nc02(x, y) : x = x, assert(check(x, y));
C.nc03(x, y) : assert(check(x, y)), x = x;
- C.nc04(this.x, y) : super(), assert(check(x, y));
C.nc05(this.x, y) : assert(check(x, y)), super();
- C.nc06(x, y) : x = x, super(), assert(check(x, y));
- C.nc07(x, y) : assert(check(x, y)), super(), x = x;
- C.nc08(x, y) : assert(check(x, y)), super(), x = x, assert(y > x);
+ C.nc06(x, y) : x = x, assert(check(x, y)), super();
+ C.nc07(x, y) : assert(check(x, y)), x = x, super();
+ C.nc08(x, y) : assert(check(x, y)), x = x, assert(y > x), super();
C.nc09(this.x, y) : assert(check(x, y), "$x < $y");
C.nc10(this.x, y) : assert(check(x, y),);
C.nc11(this.x, y) : assert(check(x, y), "$x < $y",);
- C.fc01(this.x, y) : assert(() => x < y);
- C.fc02(x, y) : x = x, assert(() => x < y);
- C.fc03(x, y) : assert(() => x < y), x = x;
- C.fc04(this.x, y) : super(), assert(() => x < y);
- C.fc05(this.x, y) : assert(() => x < y), super();
- C.fc06(x, y) : x = x, super(), assert(() => x < y);
- C.fc07(x, y) : assert(() => x < y), super(), x = x;
- C.fc08(x, y) : assert(() => x < y), super(), x = x, assert(y > x);
- C.fc09(this.x, y) : assert(() => x < y, "$x < $y");
- C.fc10(this.x, y) : assert(() => x < y,);
- C.fc11(this.x, y) : assert(() => x < y, "$x < $y",);
+ C.fc01(this.x, y) : assert((() => x < y)());
+ C.fc02(x, y) : x = x, assert((() => x < y)());
+ C.fc03(x, y) : assert((() => x < y)()), x = x;
+ C.fc05(this.x, y) : assert((() => x < y)()), super();
+ C.fc06(x, y) : x = x, assert((() => x < y)()), super();
+ C.fc07(x, y) : assert((() => x < y)()), x = x, super();
+ C.fc08(x, y) : assert((() => x < y)()),x = x, assert(y > x), super();
+ C.fc09(this.x, y) : assert((() => x < y)(), "$x < $y");
+ C.fc10(this.x, y) : assert((() => x < y)(),);
+ C.fc11(this.x, y) : assert((() => x < y)(), "$x < $y",);
}
@@ -73,7 +69,6 @@
Expect.identical(c1, const C.cc01(1, 2));
Expect.identical(c1, const C.cc02(1, 2));
Expect.identical(c1, const C.cc03(1, 2));
- Expect.identical(c1, const C.cc04(1, 2));
Expect.identical(c1, const C.cc05(1, 2));
Expect.identical(c1, const C.cc06(1, 2));
Expect.identical(c1, const C.cc07(1, 2));
@@ -94,7 +89,6 @@
doTest(() => new C.c01(x, y));
doTest(() => new C.c02(x, y));
doTest(() => new C.c03(x, y));
- doTest(() => new C.c04(x, y));
doTest(() => new C.c05(x, y));
doTest(() => new C.c06(x, y));
doTest(() => new C.c07(x, y));
@@ -105,7 +99,6 @@
doTest(() => new C.cc01(x, y));
doTest(() => new C.cc02(x, y));
doTest(() => new C.cc03(x, y));
- doTest(() => new C.cc04(x, y));
doTest(() => new C.cc05(x, y));
doTest(() => new C.cc06(x, y));
doTest(() => new C.cc07(x, y));
@@ -116,7 +109,6 @@
doTest(() => new C.nc01(x, y));
doTest(() => new C.nc02(x, y));
doTest(() => new C.nc03(x, y));
- doTest(() => new C.nc04(x, y));
doTest(() => new C.nc05(x, y));
doTest(() => new C.nc06(x, y));
doTest(() => new C.nc07(x, y));
@@ -127,7 +119,6 @@
doTest(() => new C.fc01(x, y));
doTest(() => new C.fc02(x, y));
doTest(() => new C.fc03(x, y));
- doTest(() => new C.fc04(x, y));
doTest(() => new C.fc05(x, y));
doTest(() => new C.fc06(x, y));
doTest(() => new C.fc07(x, y));
diff --git a/tests/language_2/async_await_test.dart b/tests/language_2/async_await_test.dart
index 4048692..7c19b9c 100644
--- a/tests/language_2/async_await_test.dart
+++ b/tests/language_2/async_await_test.dart
@@ -19,8 +19,8 @@
return expect42(f());
});
- test("async waits", () {
- // Calling an "async" function won't do anything immediately.
+ test("async starts synchronously", () {
+ // Calling an "async" function starts immediately.
var result = [];
f() async {
result.add(1);
@@ -31,7 +31,7 @@
var future = f();
result.add(0);
return future.whenComplete(() {
- expect(result, equals([0, 1]));
+ expect(result, equals([1, 0]));
});
});
@@ -184,7 +184,6 @@
return new Future.error("err"); // Not awaited.
}
- ;
return throwsErr(f());
});
diff --git a/tests/language_2/async_call_test.dart b/tests/language_2/async_call_test.dart
index a3643f9..bc107b6 100644
--- a/tests/language_2/async_call_test.dart
+++ b/tests/language_2/async_call_test.dart
@@ -14,6 +14,8 @@
bar() async {
result += "bar";
+ await null;
+ result += "bar2";
}
main() {
@@ -21,13 +23,13 @@
() async {
var f = new Future(foo);
var b = bar();
- Expect.equals("", result);
+ Expect.equals("bar", result);
scheduleMicrotask(() => result += "micro");
await b;
await f;
// Validates that bar is scheduled as a microtask, before foo.
- Expect.equals("barmicrofoo", result);
+ Expect.equals("barbar2microfoo", result);
asyncEnd();
}();
}
diff --git a/tests/language_2/async_error_timing_test.dart b/tests/language_2/async_error_timing_test.dart
new file mode 100644
index 0000000..4b840c7
--- /dev/null
+++ b/tests/language_2/async_error_timing_test.dart
@@ -0,0 +1,264 @@
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+class AsyncTracker {
+ int runningAsyncs = 0;
+ List expectedEvents;
+ final List actualEvents = [];
+
+ AsyncTracker() {
+ asyncStart();
+ }
+
+ void start(String event) {
+ actualEvents.add("start $event");
+ runningAsyncs++;
+ }
+
+ void stop(String event) {
+ actualEvents.add("stop $event");
+ if (--runningAsyncs == 0) {
+ Expect.listEquals(expectedEvents, actualEvents);
+ asyncEnd();
+ }
+ }
+
+ void add(e) {
+ actualEvents.add(e);
+ }
+}
+
+void test1() {
+ var tracker = new AsyncTracker();
+
+ Future foo() async {
+ tracker.add("error-foo");
+ throw "foo";
+ }
+
+ tracker.start("micro1");
+ scheduleMicrotask(() {
+ tracker.start("micro2");
+ scheduleMicrotask(() {
+ tracker.stop("micro2");
+ });
+ tracker.stop("micro1");
+ });
+
+ tracker.start("foo");
+ foo().catchError((e) {
+ tracker.stop("foo");
+ });
+ tracker.start("micro3");
+ scheduleMicrotask(() {
+ tracker.stop("micro3");
+ });
+
+ tracker.expectedEvents = [
+ "start micro1",
+ "start foo",
+ "error-foo",
+ "start micro3",
+ "start micro2",
+ "stop micro1",
+ "stop foo",
+ "stop micro3",
+ "stop micro2",
+ ];
+}
+
+void test2() {
+ var tracker = new AsyncTracker();
+
+ Future bar() async {
+ tracker.add("await null");
+ await null;
+ tracker.add("error-bar");
+ throw "bar";
+ }
+
+ tracker.start("micro1");
+ scheduleMicrotask(() {
+ tracker.start("micro2");
+ scheduleMicrotask(() {
+ tracker.start("micro3");
+ scheduleMicrotask(() {
+ tracker.stop("micro3");
+ });
+ tracker.stop("micro2");
+ });
+ tracker.stop("micro1");
+ });
+
+ tracker.start("bar");
+ bar().catchError((e) {
+ tracker.stop("bar");
+ });
+ tracker.start("micro4");
+ scheduleMicrotask(() {
+ tracker.start("micro5");
+ scheduleMicrotask(() {
+ tracker.stop("micro5");
+ });
+ tracker.stop("micro4");
+ });
+
+ tracker.expectedEvents = [
+ "start micro1",
+ "start bar",
+ "await null",
+ "start micro4",
+ "start micro2",
+ "stop micro1",
+ "error-bar",
+ "stop bar",
+ "start micro5",
+ "stop micro4",
+ "start micro3",
+ "stop micro2",
+ "stop micro5",
+ "stop micro3",
+ ];
+}
+
+void test3() {
+ var tracker = new AsyncTracker();
+
+ Future gee() async {
+ tracker.add("error-gee");
+ return new Future.error("gee");
+ }
+
+ tracker.start("micro1");
+ scheduleMicrotask(() {
+ tracker.start("micro2");
+ scheduleMicrotask(() {
+ tracker.stop("micro2");
+ });
+ tracker.stop("micro1");
+ });
+
+ tracker.start("gee");
+ gee().catchError((e) {
+ tracker.stop("gee");
+ });
+ tracker.start("micro3");
+ scheduleMicrotask(() {
+ tracker.stop("micro3");
+ });
+
+ tracker.expectedEvents = [
+ "start micro1",
+ "start gee",
+ "error-gee",
+ "start micro3",
+ "start micro2",
+ "stop micro1",
+ "stop gee",
+ "stop micro3",
+ "stop micro2",
+ ];
+}
+
+void test4() {
+ var tracker = new AsyncTracker();
+
+ Future toto() async {
+ tracker.add("await null");
+ await null;
+ tracker.add("error-toto");
+ return new Future.error("toto");
+ }
+
+ tracker.start("micro1");
+ scheduleMicrotask(() {
+ tracker.start("micro2");
+ scheduleMicrotask(() {
+ tracker.start("micro3");
+ scheduleMicrotask(() {
+ tracker.stop("micro3");
+ });
+ tracker.stop("micro2");
+ });
+ tracker.stop("micro1");
+ });
+
+ tracker.start("toto");
+ toto().catchError((e) {
+ tracker.stop("toto");
+ });
+ tracker.start("micro4");
+ scheduleMicrotask(() {
+ tracker.start("micro5");
+ scheduleMicrotask(() {
+ tracker.stop("micro5");
+ });
+ tracker.stop("micro4");
+ });
+
+ tracker.expectedEvents = [
+ "start micro1",
+ "start toto",
+ "await null",
+ "start micro4",
+ "start micro2",
+ "stop micro1",
+ "error-toto",
+ "start micro5",
+ "stop micro4",
+ "start micro3",
+ "stop micro2",
+ "stop toto",
+ "stop micro5",
+ "stop micro3",
+ ];
+}
+
+void test5() {
+ var tracker = new AsyncTracker();
+
+ Future foo() async {
+ tracker.add("throw");
+ throw "foo";
+ }
+
+ bar() async {
+ tracker.start('micro');
+ scheduleMicrotask(() {
+ tracker.stop('micro');
+ });
+ try {
+ tracker.start('foo');
+ await foo();
+ } catch (e) {
+ tracker.stop('foo');
+ }
+ tracker.stop("bar");
+ }
+
+ tracker.start('bar');
+
+ tracker.expectedEvents = [
+ "start bar",
+ "start micro",
+ "start foo",
+ "throw",
+ "stop micro",
+ "stop foo",
+ "stop bar",
+ ];
+}
+
+main() {
+ asyncStart();
+ test1();
+ test2();
+ test3();
+ test4();
+ asyncEnd();
+}
diff --git a/tests/language_2/asyncstar_throw_in_catch_test.dart b/tests/language_2/asyncstar_throw_in_catch_test.dart
index e1a3a95..884b492 100644
--- a/tests/language_2/asyncstar_throw_in_catch_test.dart
+++ b/tests/language_2/asyncstar_throw_in_catch_test.dart
@@ -40,9 +40,9 @@
yield 3;
tracer.trace("f");
} finally {
- tracer.trace("f");
+ tracer.trace("g");
}
- tracer.trace("g");
+ tracer.trace("h");
}
foo2(Tracer tracer) async* {
@@ -116,10 +116,10 @@
test() async {
// TODO(sigurdm): These tests are too dependent on scheduling, and buffering
// behavior.
- await runTest(foo1, "abcdYefC", null, true);
+ await runTest(foo1, "abcYdgC", null, true);
await runTest(foo2, "abcX", "Error", false);
await runTest(foo3, "abcYX", "Error", false);
- await runTest(foo4, "abcdYeYfX", "Error2", false);
+ await runTest(foo4, "abcYdYefX", "Error2", false);
}
void main() {
diff --git a/tests/language_2/await_nonfuture_test.dart b/tests/language_2/await_nonfuture_test.dart
index 739f73a..1aa6855 100644
--- a/tests/language_2/await_nonfuture_test.dart
+++ b/tests/language_2/await_nonfuture_test.dart
@@ -5,16 +5,23 @@
// VMOptions=--optimization-counter-threshold=5
import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
var X = 0;
foo() async {
- Expect.equals(X, 10); // foo runs after main returns.
- return await 5;
+ Expect.equals(X, 0);
+ await 5;
+ Expect.equals(X, 10);
+ return await 499;
}
main() {
+ asyncStart();
var f = foo();
- f.then((res) => print("f completed with $res"));
+ f.then((res) {
+ Expect.equals(499, res);
+ asyncEnd();
+ });
X = 10;
}
diff --git a/tests/language_2/await_not_started_immediately_test.dart b/tests/language_2/await_started_immediately_test.dart
similarity index 84%
rename from tests/language_2/await_not_started_immediately_test.dart
rename to tests/language_2/await_started_immediately_test.dart
index 5101c58..c21591f 100644
--- a/tests/language_2/await_not_started_immediately_test.dart
+++ b/tests/language_2/await_started_immediately_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// Test that an async function does not start immediately.
+// Test that an async function does start immediately.
import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";
@@ -18,5 +18,5 @@
void main() {
asyncStart();
foo().then((_) => Expect.equals(2, x)).whenComplete(asyncEnd);
- Expect.equals(0, x);
+ Expect.equals(1, x);
}
diff --git a/tests/language_2/function_subtype_bound_closure1_test.dart b/tests/language_2/function_subtype_bound_closure1_test.dart
index c55a741..01363e0 100644
--- a/tests/language_2/function_subtype_bound_closure1_test.dart
+++ b/tests/language_2/function_subtype_bound_closure1_test.dart
@@ -30,10 +30,10 @@
Expect.isFalse(foo is Baz<int>, 'foo is Baz<int>');
Expect.isFalse(foo is Boz<int>, 'foo is Boz<int>');
- Expect.isTrue(foo is Foo, 'foo is Foo');
- Expect.isTrue(foo is Bar, 'foo is Bar');
+ Expect.isFalse(foo is Foo, 'foo is Foo');
+ Expect.isFalse(foo is Bar, 'foo is Bar');
Expect.isFalse(foo is Baz, 'foo is Baz');
- Expect.isTrue(foo is Boz, 'foo is Boz');
+ Expect.isFalse(foo is Boz, 'foo is Boz');
var baz = c.baz;
Expect.isFalse(baz is Foo<bool>, 'baz is Foo<bool>');
@@ -48,6 +48,6 @@
Expect.isFalse(baz is Foo, 'baz is Foo');
Expect.isFalse(baz is Bar, 'baz is Bar');
- Expect.isTrue(baz is Baz, 'baz is Baz');
- Expect.isTrue(baz is Boz, 'baz is Boz');
+ Expect.isFalse(baz is Baz, 'baz is Baz');
+ Expect.isFalse(baz is Boz, 'baz is Boz');
}
diff --git a/tests/language_2/function_subtype_bound_closure2_test.dart b/tests/language_2/function_subtype_bound_closure2_test.dart
index 9a7da9c..d8f4a40 100644
--- a/tests/language_2/function_subtype_bound_closure2_test.dart
+++ b/tests/language_2/function_subtype_bound_closure2_test.dart
@@ -36,5 +36,6 @@
main() {
new C<bool>().test('bool', true);
new C<int>().test('int', false);
- new C().test('dynamic', true);
+ new C<Object>().test('Object', false);
+ new C<dynamic>().test('dynamic', false);
}
diff --git a/tests/language_2/function_subtype_bound_closure3_test.dart b/tests/language_2/function_subtype_bound_closure3_test.dart
index 6334342..471f2ca 100644
--- a/tests/language_2/function_subtype_bound_closure3_test.dart
+++ b/tests/language_2/function_subtype_bound_closure3_test.dart
@@ -32,5 +32,5 @@
main() {
new C<bool>().test('bool');
new C<int>().test('int');
- new C().test('dynamic');
+ new C<dynamic>().test('dynamic');
}
diff --git a/tests/language_2/function_subtype_bound_closure4_test.dart b/tests/language_2/function_subtype_bound_closure4_test.dart
index 1b6bf7a..a48fb94 100644
--- a/tests/language_2/function_subtype_bound_closure4_test.dart
+++ b/tests/language_2/function_subtype_bound_closure4_test.dart
@@ -34,5 +34,5 @@
main() {
new D<String, bool>().test('bool');
new D<bool, int>().test('int');
- new D().test('dynamic');
+ new D<dynamic, dynamic>().test('dynamic');
}
diff --git a/tests/language_2/function_subtype_bound_closure5_test.dart b/tests/language_2/function_subtype_bound_closure5_test.dart
index 39cfba8..4c6d36c 100644
--- a/tests/language_2/function_subtype_bound_closure5_test.dart
+++ b/tests/language_2/function_subtype_bound_closure5_test.dart
@@ -38,5 +38,7 @@
main() {
new D<String, bool>().test('bool', true);
new D<bool, int>().test('int', false);
- new D().test('dynamic', true);
+ new D<Object, Object>().test('Object', false);
+ new D<Null, Null>().test('Null', true);
+ new D<dynamic, dynamic>().test('dynamic', false);
}
diff --git a/tests/language_2/function_subtype_bound_closure5a_test.dart b/tests/language_2/function_subtype_bound_closure5a_test.dart
index 7f4d209..6b240ed 100644
--- a/tests/language_2/function_subtype_bound_closure5a_test.dart
+++ b/tests/language_2/function_subtype_bound_closure5a_test.dart
@@ -40,5 +40,7 @@
main() {
new D<String, bool>().test('bool', true);
new D<bool, int>().test('int', false);
- new D().test('dynamic', true);
+ new D<Object, Object>().test('Object', false);
+ new D<Null, Null>().test('Null', true);
+ new D<dynamic, dynamic>().test('dynamic', false);
}
diff --git a/tests/language_2/function_subtype_bound_closure6_test.dart b/tests/language_2/function_subtype_bound_closure6_test.dart
index 78651e3..721d78b 100644
--- a/tests/language_2/function_subtype_bound_closure6_test.dart
+++ b/tests/language_2/function_subtype_bound_closure6_test.dart
@@ -40,5 +40,7 @@
main() {
new C<bool>().test('bool', true);
new C<int>().test('int', false);
- new C().test('dynamic', true);
+ new C<Object>().test('Object', false);
+ new C<dynamic>().test('dynamic', false);
+ new C<Null>().test('Null', true);
}
diff --git a/tests/language_2/function_subtype_cast2_test.dart b/tests/language_2/function_subtype_cast2_test.dart
index 6f16bb0..123af74 100644
--- a/tests/language_2/function_subtype_cast2_test.dart
+++ b/tests/language_2/function_subtype_cast2_test.dart
@@ -24,7 +24,9 @@
void bar(int i) {}
void main() {
- new Class().test(true, bar, "dynamic");
+ new Class<dynamic>().test(false, bar, "dynamic");
+ new Class<Object>().test(false, bar, "Object");
+ new Class<Null>().test(true, bar, "Null");
new Class<int>().test(true, bar, "int");
new Class<bool>().test(false, bar, "bool");
}
diff --git a/tests/language_2/function_subtype_cast3_test.dart b/tests/language_2/function_subtype_cast3_test.dart
index edcc4e8..ec222ac 100644
--- a/tests/language_2/function_subtype_cast3_test.dart
+++ b/tests/language_2/function_subtype_cast3_test.dart
@@ -28,7 +28,8 @@
void bar(int i) {}
void main() {
- new Class().test(true, bar, "dynamic");
+ new Class<dynamic>().test(false, bar, "dynamic");
+ new Class<Object>().test(false, bar, "Object");
new Class<int>().test(true, bar, "int");
new Class<bool>().test(false, bar, "bool");
}
diff --git a/tests/language_2/function_subtype_checked0_test.dart b/tests/language_2/function_subtype_checked0_test.dart
index c5e4e004..0ded8d0 100644
--- a/tests/language_2/function_subtype_checked0_test.dart
+++ b/tests/language_2/function_subtype_checked0_test.dart
@@ -67,5 +67,7 @@
main() {
new C<bool>().test('bool', true);
new C<int>().test('int', false);
- new C().test('dynamic', true);
+ new C<dynamic>().test('dynamic', false);
+ new C<Object>().test('Object', false);
+ new C<Null>().test('Null', true);
}
diff --git a/tests/language_2/function_subtype_inline0_test.dart b/tests/language_2/function_subtype_inline0_test.dart
index dca9e6b..3e1db32 100644
--- a/tests/language_2/function_subtype_inline0_test.dart
+++ b/tests/language_2/function_subtype_inline0_test.dart
@@ -37,5 +37,5 @@
main() {
new C<bool>().test('bool', true);
new C<int>().test('int', false);
- new C().test('dynamic', true);
+ new C<dynamic>().test('dynamic', true);
}
diff --git a/tests/language_2/function_subtype_local1_test.dart b/tests/language_2/function_subtype_local1_test.dart
index d41b360..83f9350 100644
--- a/tests/language_2/function_subtype_local1_test.dart
+++ b/tests/language_2/function_subtype_local1_test.dart
@@ -26,10 +26,10 @@
Expect.isFalse(foo is Baz<int>, 'foo is Baz<int>');
Expect.isFalse(foo is Boz<int>, 'foo is Boz<int>');
- Expect.isTrue(foo is Foo, 'foo is Foo');
- Expect.isTrue(foo is Bar, 'foo is Bar');
+ Expect.isFalse(foo is Foo, 'foo is Foo');
+ Expect.isFalse(foo is Bar, 'foo is Bar');
Expect.isFalse(foo is Baz, 'foo is Baz');
- Expect.isTrue(foo is Boz, 'foo is Boz');
+ Expect.isFalse(foo is Boz, 'foo is Boz');
Expect.isFalse(baz is Foo<bool>, 'baz is Foo<bool>');
Expect.isFalse(baz is Bar<bool>, 'baz is Bar<bool>');
@@ -43,6 +43,6 @@
Expect.isFalse(baz is Foo, 'baz is Foo');
Expect.isFalse(baz is Bar, 'baz is Bar');
- Expect.isTrue(baz is Baz, 'baz is Baz');
- Expect.isTrue(baz is Boz, 'baz is Boz');
+ Expect.isFalse(baz is Baz, 'baz is Baz');
+ Expect.isFalse(baz is Boz, 'baz is Boz');
}
diff --git a/tests/language_2/function_subtype_local2_test.dart b/tests/language_2/function_subtype_local2_test.dart
index 65d470d..0f774fb 100644
--- a/tests/language_2/function_subtype_local2_test.dart
+++ b/tests/language_2/function_subtype_local2_test.dart
@@ -36,5 +36,7 @@
main() {
new C<bool>().test('bool', true);
new C<int>().test('int', false);
- new C().test('dynamic', true);
+ new C<dynamic>().test('dynamic', false);
+ new C<Object>().test('Object', false);
+ new C<Null>().test('Null', true);
}
diff --git a/tests/language_2/function_subtype_local3_test.dart b/tests/language_2/function_subtype_local3_test.dart
index 344f7c2..e491dde 100644
--- a/tests/language_2/function_subtype_local3_test.dart
+++ b/tests/language_2/function_subtype_local3_test.dart
@@ -32,5 +32,5 @@
main() {
new C<bool>().test('bool', true);
new C<int>().test('int', false);
- new C().test('dynamic', true);
+ new C<dynamic>().test('dynamic', true);
}
diff --git a/tests/language_2/function_subtype_local5_test.dart b/tests/language_2/function_subtype_local5_test.dart
index be742bf..00f18af 100644
--- a/tests/language_2/function_subtype_local5_test.dart
+++ b/tests/language_2/function_subtype_local5_test.dart
@@ -38,5 +38,7 @@
main() {
new D<String, bool>().test('bool', true);
new D<bool, int>().test('int', false);
- new D().test('dynamic', true);
+ new D<dynamic, dynamic>().test('dynamic', false);
+ new D<Object, Object>().test('Object', false);
+ new D<Null, Null>().test('Null', true);
}
diff --git a/tests/language_2/function_subtype_not0_test.dart b/tests/language_2/function_subtype_not0_test.dart
index 60ab4c7..4959ece 100644
--- a/tests/language_2/function_subtype_not0_test.dart
+++ b/tests/language_2/function_subtype_not0_test.dart
@@ -13,7 +13,7 @@
void bar(int i) {}
void main() {
- Expect.isFalse(bar is! Foo);
+ Expect.isTrue(bar is! Foo);
Expect.isTrue(bar is! Foo<bool>);
Expect.isFalse(bar is! Foo<int>);
Expect.isFalse(bar is! Bar);
diff --git a/tests/language_2/function_subtype_not2_test.dart b/tests/language_2/function_subtype_not2_test.dart
index 5481a8c..218c04d 100644
--- a/tests/language_2/function_subtype_not2_test.dart
+++ b/tests/language_2/function_subtype_not2_test.dart
@@ -20,7 +20,9 @@
void bar(int i) {}
void main() {
- new Class().test(false, bar, "dynamic");
+ new Class<dynamic>().test(true, bar, "dynamic");
+ new Class<Object>().test(true, bar, "Object");
+ new Class<Null>().test(false, bar, "Null");
new Class<int>().test(false, bar, "int");
new Class<bool>().test(true, bar, "bool");
}
diff --git a/tests/language_2/function_subtype_not3_test.dart b/tests/language_2/function_subtype_not3_test.dart
index 0c8d2bb..07c40ea 100644
--- a/tests/language_2/function_subtype_not3_test.dart
+++ b/tests/language_2/function_subtype_not3_test.dart
@@ -24,7 +24,9 @@
void bar(int i) {}
void main() {
- new Class().test(false, bar, "dynamic");
+ new Class<dynamic>().test(true, bar, "dynamic");
+ new Class<Object>().test(true, bar, "Object");
+ new Class<Null>().test(false, bar, "Null");
new Class<int>().test(false, bar, "int");
new Class<bool>().test(true, bar, "bool");
}
diff --git a/tests/language_2/function_subtype_simple1_test.dart b/tests/language_2/function_subtype_simple1_test.dart
index dc276c5..1d0b053 100644
--- a/tests/language_2/function_subtype_simple1_test.dart
+++ b/tests/language_2/function_subtype_simple1_test.dart
@@ -8,21 +8,28 @@
import 'package:expect/expect.dart';
typedef Args0();
-typedef Args1(a);
-typedef Args2(a, b);
-typedef Args3(a, b, c);
-typedef Args4(a, b, c, d);
-typedef Args5(a, b, c, d, e);
-typedef Args6(a, b, c, d, e, f);
-typedef Args7(a, b, c, d, e, f, g);
-typedef Args8(a, b, c, d, e, f, g, h);
-typedef Args9(a, b, c, d, e, f, g, h, i);
-typedef Args10(a, b, c, d, e, f, g, h, i, j);
-typedef Args11(a, b, c, d, e, f, g, h, i, j, k);
-typedef Args12(a, b, c, d, e, f, g, h, i, j, k, l);
-typedef Args13(a, b, c, d, e, f, g, h, i, j, k, l, m);
-typedef Args14(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
-typedef Args15(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
+typedef Args1(Null a);
+typedef Args2(Null a, Null b);
+typedef Args3(Null a, Null b, Null c);
+typedef Args4(Null a, Null b, Null c, Null d);
+typedef Args5(Null a, Null b, Null c, Null d, Null e);
+typedef Args6(Null a, Null b, Null c, Null d, Null e, Null f);
+typedef Args7(Null a, Null b, Null c, Null d, Null e, Null f, Null g);
+typedef Args8(Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h);
+typedef Args9(
+ Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h, Null i);
+typedef Args10(Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h,
+ Null i, Null j);
+typedef Args11(Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h,
+ Null i, Null j, Null k);
+typedef Args12(Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h,
+ Null i, Null j, Null k, Null l);
+typedef Args13(Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h,
+ Null i, Null j, Null k, Null l, Null m);
+typedef Args14(Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h,
+ Null i, Null j, Null k, Null l, Null m, Null n);
+typedef Args15(Null a, Null b, Null c, Null d, Null e, Null f, Null g, Null h,
+ Null i, Null j, Null k, Null l, Null m, Null n, Null o);
void args0() {}
void args1(int a) {}
diff --git a/tests/language_2/function_subtype_top_level1_test.dart b/tests/language_2/function_subtype_top_level1_test.dart
index bc89332..d522349 100644
--- a/tests/language_2/function_subtype_top_level1_test.dart
+++ b/tests/language_2/function_subtype_top_level1_test.dart
@@ -38,5 +38,7 @@
main() {
new C<bool>().test('bool', true);
new C<int>().test('int', false);
- new C().test('dynamic', true);
+ new C<Object>().test('Object', false);
+ new C<dynamic>().test('dynamic', false);
+ new C<Null>().test('Null', true);
}
diff --git a/tests/language_2/function_subtype_typearg5_test.dart b/tests/language_2/function_subtype_typearg5_test.dart
index 763e187..018d592 100644
--- a/tests/language_2/function_subtype_typearg5_test.dart
+++ b/tests/language_2/function_subtype_typearg5_test.dart
@@ -19,11 +19,11 @@
class CheckEnv<X, Y> {
test(bool intX) {
- Expect.isTrue(<F<X>>[] is List<F>);
+ Expect.isTrue(<F<X>>[] is! List<F>);
Expect.isTrue(<F<X>>[] is List<F<X>>);
Expect.isTrue(<F<X>>[] is List<G<Y, X>>);
- Expect.isTrue(dyn(<F<X>>[]) is List<F>);
+ Expect.isTrue(dyn(<F<X>>[]) is! List<F>);
Expect.isTrue(dyn(<F<X>>[]) is List<F<X>>);
Expect.isTrue(dyn(<F<X>>[]) is List<G<Y, X>>);
diff --git a/tests/language_2/function_type_alias2_test.dart b/tests/language_2/function_type_alias2_test.dart
index 8bd1c95..fdc0b00 100644
--- a/tests/language_2/function_type_alias2_test.dart
+++ b/tests/language_2/function_type_alias2_test.dart
@@ -21,16 +21,16 @@
int bar({int a, int b, int c}) {}
main() {
- Expect.isTrue(baz is f1);
+ Expect.isFalse(baz is f1);
Expect.isFalse(baz is f3);
Expect.isFalse(bar is f1);
- Expect.isTrue(bar is f3);
- Expect.isTrue(baz is f1);
+ Expect.isFalse(bar is f3);
+ Expect.isFalse(baz is f1);
Expect.isTrue(baz is f1<int>);
Expect.isTrue(bar is f3<int>);
Expect.isFalse(baz is f1<double>);
Expect.isFalse(bar is f3<double>);
- Expect.isTrue(baz is f2);
+ Expect.isFalse(baz is f2);
Expect.isFalse(bar is f4);
Expect.isTrue(baz is f2<int>);
Expect.isFalse(bar is f2<int>);
diff --git a/tests/language_2/function_type_alias3_test.dart b/tests/language_2/function_type_alias3_test.dart
index 33d6b23..dad6b8a 100644
--- a/tests/language_2/function_type_alias3_test.dart
+++ b/tests/language_2/function_type_alias3_test.dart
@@ -17,10 +17,10 @@
main() {
var a = new A<lib11.Library111<bool>>();
var b = new A<lib11.Library111<int>>();
- Expect.isTrue(a.foo is F);
+ Expect.isTrue(a.foo is! F);
Expect.isTrue(a.foo is F<bool>);
Expect.isTrue(a.foo is! F<int>);
- Expect.isTrue(b.foo is F);
+ Expect.isTrue(b.foo is! F);
Expect.isTrue(b.foo is! F<bool>);
Expect.isTrue(a.foo is! F<int>);
}
diff --git a/tests/language_2/function_type_alias4_test.dart b/tests/language_2/function_type_alias4_test.dart
index 7e06db9..3d68fd4 100644
--- a/tests/language_2/function_type_alias4_test.dart
+++ b/tests/language_2/function_type_alias4_test.dart
@@ -16,8 +16,10 @@
}
main() {
- Expect.isTrue(bar is F);
- Expect.isTrue(baz is F);
+ Expect.isTrue(bar is! F);
+ Expect.isTrue(baz is! F);
+ Expect.isTrue(bar is! F<Object>);
+ Expect.isTrue(baz is! F<Object>);
Expect.isTrue(bar is F<bool>);
Expect.isTrue(baz is F<int>);
Expect.isTrue(bar is! F<int>);
@@ -25,8 +27,12 @@
var b = new A<bool>();
var i = new A<int>();
- Expect.isTrue(b.foo is F);
- Expect.isTrue(i.foo is F);
+ Expect.isTrue(b.foo is F, 'runtime type of covaraint parameters is Object');
+ Expect.isTrue(i.foo is F, 'runtime type of covaraint parameters is Object');
+ Expect.isTrue(
+ b.foo is F<Object>, 'runtime type of covaraint parameters is Object');
+ Expect.isTrue(
+ i.foo is F<Object>, 'runtime type of covaraint parameters is Object');
Expect.isTrue(b.foo is F<bool>);
Expect.isTrue(i.foo is F<int>);
Expect.isTrue(b.foo is! F<int>);
diff --git a/tests/language_2/function_type_alias_test.dart b/tests/language_2/function_type_alias_test.dart
index 486a980..b725a5f 100644
--- a/tests/language_2/function_type_alias_test.dart
+++ b/tests/language_2/function_type_alias_test.dart
@@ -7,11 +7,11 @@
import "package:expect/expect.dart";
-typedef Fun(a, b);
+typedef Fun(Null a, Null b);
-typedef int IntFun(a, b);
+typedef int IntFun(Null a, Null b);
-typedef bool BoolFun(a, b);
+typedef bool BoolFun(Null a, Null b);
typedef int CompareObj(Object a, Object b);
diff --git a/tests/language_2/generic_closure_test.dart b/tests/language_2/generic_closure_test.dart
index 501141c..333ba2f 100644
--- a/tests/language_2/generic_closure_test.dart
+++ b/tests/language_2/generic_closure_test.dart
@@ -26,7 +26,7 @@
Expect.equals(14, g(14));
Expect.isTrue(f is Function);
Expect.isTrue(g is Function);
- Expect.isTrue(f is F);
+ Expect.isTrue(f is! F);
Expect.isTrue(g is F);
Expect.isTrue(f is F<int>);
Expect.isTrue(g is F<int>);
@@ -46,7 +46,7 @@
var g = c.g;
Expect.equals("(bool) => bool", f.runtimeType.toString()); //# 01: ok
Expect.equals("(Object) => bool", g.runtimeType.toString()); //# 01: ok
- Expect.isTrue(f is F);
+ Expect.isTrue(f is! F);
Expect.isTrue(g is F);
Expect.isTrue(f is! F<int>);
Expect.isTrue(g is! F<int>);
diff --git a/tests/language_2/generic_test.dart b/tests/language_2/generic_test.dart
index df51fbd..0b00d05 100644
--- a/tests/language_2/generic_test.dart
+++ b/tests/language_2/generic_test.dart
@@ -29,7 +29,7 @@
}
}
-class C<T> {
+class C<T extends A> {
B<T> b_;
C(T t) : b_ = new B<T>(t) {}
}
@@ -40,34 +40,19 @@
}
class E {
- C<AX> cax_;
- E() : cax_ = new C<AX>(const AX()) {}
-}
-
-class GenericTest {
- static test() {
- int result = 0;
- D d = new D();
- Expect.equals(true, d.caa_.b_ is B<AA>);
- Expect.equals(true, d.caa_.b_.isT(const AA()));
- C c = new C(const AA()); // c is of raw type C, T in C<T> is dynamic.
- Expect.equals(true, c.b_ is B);
- Expect.equals(true, c.b_ is B<AA>);
- Expect.equals(true, c.b_.isT(const AA()));
- Expect.equals(true, c.b_.isT(const AX()));
- try {
- E e = new E(); // Throws a type error, if type checks are enabled.
- } on TypeError catch (error) {
- result = 1;
- }
- return result;
- }
-
- static testMain() {
- Expect.equals(1, test());
- }
+ C<AX> cax_ = new C<AX>(const AX()); //# 01: compile-time error
}
main() {
- GenericTest.testMain();
+ D d = new D();
+ Expect.equals(true, d.caa_.b_ is B<AA>);
+ Expect.equals(true, d.caa_.b_.isT(const AA()));
+ C c = new C(const AA()); // inferred as `C<A>` because of the `extends A`.
+ Expect.equals(true, c is C<A>);
+ Expect.equals(false, c is C<AA>, 'C<A> is not a subtype of C<AA>');
+ Expect.equals(true, c.b_ is B);
+ Expect.equals(false, c.b_ is B<AA>);
+ Expect.equals(true, c.b_.isT(const AA()), 'AA is a subtype of A');
+ Expect.equals(false, c.b_.isT(const AX()), 'AX is not a subtype of A');
+ new E();
}
diff --git a/tests/language_2/generics_test.dart b/tests/language_2/generics_test.dart
index 931083b..e676434 100644
--- a/tests/language_2/generics_test.dart
+++ b/tests/language_2/generics_test.dart
@@ -5,7 +5,7 @@
import "package:expect/expect.dart";
-class GenericsTest<T, V> implements Map<int, int> {
+abstract class GenericsTest<T, V> implements Map<int, int> {
static int myFunc(bool a, bool b) {
Expect.equals(true, a);
Expect.equals(false, b);
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 9f38477..fea64fd 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -43,6 +43,29 @@
[ $compiler != dartdevc && !$checked ]
function_type/*: Skip # Needs checked mode.
+[ $compiler != dartdevc && !$fasta && $strong ]
+implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError
+implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError
+implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError
+implicit_creation/implicit_const_context_constructor_test: CompileTimeError
+implicit_creation/implicit_const_context_list_test: CompileTimeError
+implicit_creation/implicit_const_context_map_test: CompileTimeError
+implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
+implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError
+implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError
+implicit_creation/implicit_const_context_prefix_constructor_test: CompileTimeError
+implicit_creation/implicit_new_constructor_generic_named_test: CompileTimeError
+implicit_creation/implicit_new_constructor_generic_test: CompileTimeError
+implicit_creation/implicit_new_constructor_named_test: CompileTimeError
+implicit_creation/implicit_new_constructor_test: CompileTimeError
+implicit_creation/implicit_new_or_const_composite_test: CompileTimeError
+implicit_creation/implicit_new_or_const_generic_test: CompileTimeError
+implicit_creation/implicit_new_or_const_test: CompileTimeError
+implicit_creation/implicit_new_prefix_constructor_generic_named_test: CompileTimeError
+implicit_creation/implicit_new_prefix_constructor_generic_test: CompileTimeError
+implicit_creation/implicit_new_prefix_constructor_named_test: CompileTimeError
+implicit_creation/implicit_new_prefix_constructor_test: CompileTimeError
+
[ $compiler != dartk && $compiler != dartkp && $mode == debug && $runtime == vm ]
built_in_identifier_type_annotation_test/15: Crash # Not supported by legacy VM front-end.
@@ -186,29 +209,6 @@
regress_21795_test: RuntimeError # Issue 12605
stack_trace_test: Fail, OK # Stack trace not preserved in minified code.
-[ !$fasta && $strong ]
-implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError
-implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError
-implicit_creation/implicit_const_context_constructor_test: CompileTimeError
-implicit_creation/implicit_const_context_list_test: CompileTimeError
-implicit_creation/implicit_const_context_map_test: CompileTimeError
-implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError
-implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError
-implicit_creation/implicit_const_context_prefix_constructor_test: CompileTimeError
-implicit_creation/implicit_new_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_new_constructor_generic_test: CompileTimeError
-implicit_creation/implicit_new_constructor_named_test: CompileTimeError
-implicit_creation/implicit_new_constructor_test: CompileTimeError
-implicit_creation/implicit_new_or_const_composite_test: CompileTimeError
-implicit_creation/implicit_new_or_const_generic_test: CompileTimeError
-implicit_creation/implicit_new_or_const_test: CompileTimeError
-implicit_creation/implicit_new_prefix_constructor_generic_named_test: CompileTimeError
-implicit_creation/implicit_new_prefix_constructor_generic_test: CompileTimeError
-implicit_creation/implicit_new_prefix_constructor_named_test: CompileTimeError
-implicit_creation/implicit_new_prefix_constructor_test: CompileTimeError
-
[ !$fasta && !$strong ]
implicit_creation/implicit_const_context_constructor_generic_named_test: Fail # No support for implicit creation.
implicit_creation/implicit_const_context_constructor_generic_test: Fail # No support for implicit creation.
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 73292b2e..29ec35a 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -7,8 +7,6 @@
abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue #30568
abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568
abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
-assertion_initializer_const_function_test/01: MissingCompileTimeError
-async_return_types_test/nestedFuture: MissingCompileTimeError
bad_initializer2_negative_test: Fail # Issue 14880
black_listed_test/none: Fail # Issue 14228
built_in_identifier_prefix_test: CompileTimeError
@@ -43,8 +41,6 @@
generic_local_functions_test: CompileTimeError # Issue 28515
generic_methods_generic_function_parameter_test: CompileTimeError # Issue 28515
generic_no_such_method_dispatcher_simple_test: Skip # This test is just for kernel.
-generic_test: StaticWarning
-generics_test: StaticWarning
getter_declaration_negative_test: CompileTimeError
getter_setter_in_lib_test: Fail # Issue 23286
import_core_prefix_test: StaticWarning
@@ -357,16 +353,9 @@
void_type_usage_test/paren_while: MissingCompileTimeError
[ $compiler == dart2analyzer && $runtime == none ]
-assertion_initializer_const_function_test/01: CompileTimeError
error_stacktrace_test/00: MissingCompileTimeError
vm/lazy_deopt_with_exception_test: CompileTimeError
-[ $compiler == dart2analyzer && $checked ]
-assertion_initializer_const_error2_test/*: MissingCompileTimeError # Issue #
-assertion_initializer_const_error2_test/cc10: Pass # Issue #31321
-assertion_initializer_const_error2_test/cc11: Pass # Issue #31321
-assertion_initializer_const_error2_test/none: Pass
-
[ $compiler == dart2analyzer && $checked && !$strong ]
abstract_beats_arguments_test: MissingCompileTimeError
abstract_exact_selector_test/01: MissingCompileTimeError
@@ -535,8 +524,6 @@
generic_methods_recursive_bound_test/02: MissingCompileTimeError
generic_no_such_method_dispatcher_test: StaticWarning
generic_tearoff_test: CompileTimeError
-generic_test: CompileTimeError
-generics_test: CompileTimeError
getter_no_setter2_test/00: MissingCompileTimeError
getter_no_setter2_test/01: MissingCompileTimeError
getter_no_setter2_test/03: MissingCompileTimeError
@@ -766,13 +753,22 @@
type_variable_static_context_test: MissingCompileTimeError
unresolved_in_factory_test: MissingCompileTimeError
-# Analyzer only implements Dart 2.0 static type checking with "--strong".
[ $compiler == dart2analyzer && !$checked && !$strong ]
abstract_beats_arguments_test: MissingCompileTimeError
abstract_exact_selector_test/01: MissingCompileTimeError
abstract_factory_constructor_test/00: MissingCompileTimeError
abstract_getter_test/01: MissingCompileTimeError
abstract_syntax_test/00: MissingCompileTimeError
+assertion_initializer_const_error2_test/cc01: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc02: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc03: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc05: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc06: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc07: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc08: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc11: MissingCompileTimeError # Not reporting failed assert() at compile time.
assign_static_type_test/01: MissingCompileTimeError
assign_static_type_test/02: MissingCompileTimeError
assign_static_type_test/03: MissingCompileTimeError
@@ -1228,9 +1224,6 @@
accessor_conflict_import_prefixed_test: CompileTimeError # Issue 25626
accessor_conflict_import_test: CompileTimeError # Issue 25626
additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
-assertion_initializer_const_function_test/01: MissingStaticWarning
-assertion_initializer_test: CompileTimeError
-async_return_types_test/nestedFuture: MissingCompileTimeError
cascaded_forwarding_stubs_test: CompileTimeError
config_import_corelib_test: CompileTimeError
const_types_test/07: MissingCompileTimeError # Incorrectly allows using type parameter in const expression.
@@ -1246,12 +1239,8 @@
generic_methods_overriding_test/03: MissingCompileTimeError # Issue 29070
generic_no_such_method_dispatcher_test: CompileTimeError
generic_tearoff_test: CompileTimeError
-generic_test: CompileTimeError
-generics_test: CompileTimeError
import_core_prefix_test: CompileTimeError # "dynamic" should be defined in core.
instantiate_type_variable_test/01: CompileTimeError
-int64_literal_test/03: MissingCompileTimeError # http://dartbug.com/31479
-int64_literal_test/30: MissingCompileTimeError # http://dartbug.com/31479
interceptor6_test: CompileTimeError
issue13673_test: StaticWarning # Issue 31925
issue31596_implement_covariant_test: CompileTimeError
@@ -1361,7 +1350,7 @@
additional_interface_adds_optional_args_test: StaticWarning
argument_assignability_function_typed_test/01: MissingCompileTimeError
argument_assignability_function_typed_test/02: MissingCompileTimeError
-assertion_initializer_const_function_test/01: MissingStaticWarning
+assertion_initializer_const_function_test/01: MissingCompileTimeError
async_congruence_local_test/01: MissingCompileTimeError
async_congruence_local_test/02: MissingCompileTimeError
async_congruence_method_test/01: MissingCompileTimeError
@@ -1491,6 +1480,7 @@
generic_field_mixin6_test/01: MissingCompileTimeError
generic_function_typedef2_test/04: MissingCompileTimeError
generic_methods_generic_function_result_test/01: MissingCompileTimeError # Issue #30207
+generic_test/01: MissingCompileTimeError
identical_const_test/01: MissingCompileTimeError
identical_const_test/02: MissingCompileTimeError
identical_const_test/03: MissingCompileTimeError
@@ -1532,8 +1522,6 @@
inferrer_constructor5_test/01: MissingCompileTimeError
initializing_formal_type_test: MissingCompileTimeError
instantiate_type_variable_test/01: StaticWarning
-int64_literal_test/03: MissingCompileTimeError
-int64_literal_test/30: MissingCompileTimeError
interceptor6_test: StaticWarning
invalid_cast_test/01: MissingCompileTimeError
invalid_cast_test/02: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 8c77d68..16de69c 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -40,15 +40,13 @@
field_override_optimization_test: RuntimeError
field_type_check2_test/01: MissingRuntimeError
-[ $compiler == dart2js && $runtime != drt && !$dart2js_with_kernel ]
-issue23244_test: RuntimeError # 23244
-
[ $compiler == dart2js && $runtime == ff && !$dart2js_with_kernel ]
field_override_optimization_test: RuntimeError
field_type_check2_test/01: MissingRuntimeError
round_test: Pass, Fail, OK # Fixed in ff 35. Common JavaScript engine Math.round bug.
[ $compiler == dart2js && $runtime == jsshell ]
+async_call_test: RuntimeError # Timer interface not supported: Issue 7728.
async_star_test/01: RuntimeError
async_star_test/02: RuntimeError
async_star_test/03: RuntimeError
@@ -71,17 +69,32 @@
[ $compiler == dart2js && $runtime != none && $checked ]
assert_with_message_test: RuntimeError
+function_subtype_bound_closure1_test: RuntimeError
+function_subtype_bound_closure2_test: RuntimeError
function_subtype_bound_closure3_test: RuntimeError
function_subtype_bound_closure4_test: RuntimeError
+function_subtype_bound_closure5_test: RuntimeError
+function_subtype_bound_closure5a_test: RuntimeError
+function_subtype_bound_closure6_test: RuntimeError
function_subtype_bound_closure7_test: RuntimeError
function_subtype_call1_test: RuntimeError
function_subtype_call2_test: RuntimeError
function_subtype_cast1_test: RuntimeError
+function_subtype_cast2_test: RuntimeError
+function_subtype_cast3_test: RuntimeError
+function_subtype_checked0_test: RuntimeError
+function_subtype_local1_test: RuntimeError
+function_subtype_local2_test: RuntimeError
+function_subtype_local5_test: RuntimeError
function_subtype_named1_test: RuntimeError
function_subtype_named2_test: RuntimeError
+function_subtype_not0_test: RuntimeError
function_subtype_not1_test: RuntimeError
+function_subtype_not2_test: RuntimeError
+function_subtype_not3_test: RuntimeError
function_subtype_optional1_test: RuntimeError
function_subtype_optional2_test: RuntimeError
+function_subtype_top_level1_test: RuntimeError
function_subtype_typearg2_test: RuntimeError
function_subtype_typearg3_test: RuntimeError
function_subtype_typearg5_test: RuntimeError
@@ -154,6 +167,8 @@
function_type/function_type96_test: RuntimeError # Issue 30476
function_type/function_type9_test: RuntimeError # Issue 30476
function_type_alias2_test: RuntimeError
+function_type_alias3_test: RuntimeError
+function_type_alias4_test: RuntimeError
[ $compiler == dart2js && $runtime != none && !$checked && !$dart2js_with_kernel ]
callable_test/none: RuntimeError
@@ -169,29 +184,45 @@
covariant_subtyping_unsafe_call1_test: RuntimeError
covariant_subtyping_unsafe_call2_test: RuntimeError
covariant_subtyping_unsafe_call3_test: RuntimeError
+function_subtype_bound_closure1_test: RuntimeError
+function_subtype_bound_closure2_test: RuntimeError
function_subtype_bound_closure3_test: RuntimeError
function_subtype_bound_closure4_test: RuntimeError
+function_subtype_bound_closure5_test: RuntimeError
+function_subtype_bound_closure5a_test: RuntimeError
+function_subtype_bound_closure6_test: RuntimeError
function_subtype_bound_closure7_test: RuntimeError
function_subtype_call1_test: RuntimeError
function_subtype_call2_test: RuntimeError
function_subtype_cast1_test: RuntimeError
+function_subtype_cast2_test: RuntimeError
+function_subtype_cast3_test: RuntimeError
function_subtype_checked0_test: RuntimeError
function_subtype_closure0_test: RuntimeError
function_subtype_closure1_test: RuntimeError
function_subtype_factory1_test: RuntimeError
function_subtype_inline1_test: RuntimeError
+function_subtype_local1_test: RuntimeError
+function_subtype_local2_test: RuntimeError
+function_subtype_local5_test: RuntimeError
function_subtype_named1_test: RuntimeError
function_subtype_named2_test: RuntimeError
+function_subtype_not0_test: RuntimeError
function_subtype_not1_test: RuntimeError
+function_subtype_not2_test: RuntimeError
+function_subtype_not3_test: RuntimeError
function_subtype_optional1_test: RuntimeError
function_subtype_optional2_test: RuntimeError
function_subtype_regression_ddc_588_test: RuntimeError
function_subtype_setter0_test: RuntimeError
+function_subtype_top_level1_test: RuntimeError
function_subtype_typearg2_test: RuntimeError
function_subtype_typearg3_test: RuntimeError
function_subtype_typearg5_test: RuntimeError
function_type2_test: RuntimeError
function_type_alias2_test: RuntimeError
+function_type_alias3_test: RuntimeError
+function_type_alias4_test: RuntimeError
function_type_call_getter2_test/none: RuntimeError
function_type_test: RuntimeError
generic_field_mixin6_test/none: RuntimeError
@@ -281,6 +312,7 @@
invalid_cast_test/09: MissingCompileTimeError
invalid_cast_test/10: MissingCompileTimeError
invalid_cast_test/11: MissingCompileTimeError
+issue23244_test: RuntimeError # 23244
issue31596_super_test/05: RuntimeError
many_generic_instanceof_test: RuntimeError
map_literal8_test: RuntimeError
@@ -334,7 +366,6 @@
[ $compiler == dart2js && $checked && $dart2js_with_kernel && $strong ]
assertion_initializer_const_function_test/01: MissingCompileTimeError
-assertion_initializer_test: CompileTimeError
assertion_test: RuntimeError
async_star_cancel_while_paused_test: RuntimeError
async_star_test/02: RuntimeError
@@ -727,6 +758,8 @@
function_type_call_getter2_test/03: MissingCompileTimeError
function_type_call_getter2_test/04: MissingCompileTimeError
function_type_call_getter2_test/05: MissingCompileTimeError
+generic_test/01: MissingCompileTimeError
+generic_test/none: RuntimeError
malbounded_instantiation_test/01: Fail # Issue 12702
malbounded_redirecting_factory_test/02: Fail # Issue 12825
malbounded_redirecting_factory_test/03: Fail # Issue 12825
@@ -759,8 +792,6 @@
type_argument_in_super_type_test: RuntimeError
[ $compiler == dart2js && !$checked && $dart2js_with_kernel ]
-assertion_initializer_const_error2_test/*: CompileTimeError # Issue #31321
-assertion_initializer_const_error2_test/none: Pass
cascaded_forwarding_stubs_generic_test: RuntimeError
cascaded_forwarding_stubs_test: RuntimeError
checked_setter3_test: RuntimeError # Issue 31128
@@ -823,7 +854,8 @@
forwarding_stub_tearoff_generic_test: RuntimeError
forwarding_stub_tearoff_test: RuntimeError
function_subtype_inline2_test: RuntimeError
-generic_test: RuntimeError, OK
+generic_test/01: MissingCompileTimeError
+generic_test/none: RuntimeError # test requires Dart 2 subtyping for `is`
issue31596_implement_covariant_test: RuntimeError
issue31596_test: RuntimeError
list_literal1_test/01: MissingCompileTimeError
@@ -833,6 +865,7 @@
function_subtype_inline2_test: RuntimeError
[ $compiler == dart2js && $dart2js_with_kernel ]
+async_error_timing_test: Crash
bug31436_test: RuntimeError
built_in_identifier_type_annotation_test/22: Crash # Issue 28815
built_in_identifier_type_annotation_test/52: MissingCompileTimeError # Issue 28815
@@ -855,6 +888,7 @@
checked_setter_test: RuntimeError # Issue 31128
closure_param_null_to_object_test: RuntimeError
extract_type_arguments_test: Crash # Issue 31371
+generic_test/01: MissingCompileTimeError # front end does not validate `extends`
implicit_downcast_during_constructor_invocation_test: RuntimeError
implicit_downcast_during_for_in_element_test: RuntimeError
implicit_downcast_during_for_in_iterable_test: RuntimeError
@@ -874,7 +908,6 @@
[ $compiler == dart2js && $dart2js_with_kernel && $fast_startup && $strong ]
assertion_initializer_const_error2_test/none: CompileTimeError
assertion_initializer_const_function_test/01: MissingCompileTimeError
-assertion_initializer_test: CompileTimeError
assertion_test: RuntimeError
async_star_cancel_while_paused_test: RuntimeError
async_star_test/02: RuntimeError
@@ -1079,7 +1112,7 @@
generic_list_checked_test: RuntimeError
generic_local_functions_test: Crash # Unsupported operation: Unsupported type parameter type node Y.
generic_tearoff_test: Crash # Unsupported operation: Unsupported type parameter type node T.
-generic_test: RuntimeError
+generic_test/none: RuntimeError
generic_typedef_test: Crash # Unsupported operation: Unsupported type parameter type node S.
getter_override2_test/02: MissingCompileTimeError
getter_override_test/00: MissingCompileTimeError
@@ -1409,6 +1442,7 @@
await_null_aware_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
await_postfix_expr_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
await_regression_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
+await_started_immediately_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
await_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
bad_named_parameters2_test/01: MissingCompileTimeError
bad_named_parameters_test/01: MissingCompileTimeError
@@ -1526,24 +1560,11 @@
deferred_constant_list_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_constants_test/none: CompileTimeError
deferred_constraints_constants_test/reference_after_load: CompileTimeError
-deferred_constraints_type_annotation_test/as_operation: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/catch_check: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/is_check: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/new: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/new_before_load: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/new_generic1: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/new_generic2: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/new_generic3: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/none: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/static_method: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation1: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic1: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic2: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic3: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic4: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/type_annotation_non_deferred: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_null: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_top_level: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_function_type_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_global_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_import_core_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
@@ -1624,12 +1645,19 @@
full_stacktrace2_test: RuntimeError
full_stacktrace3_test: RuntimeError
function_propagation_test: CompileTimeError
+function_subtype_bound_closure1_test: RuntimeError
+function_subtype_bound_closure2_test: RuntimeError
function_subtype_bound_closure3_test: RuntimeError
function_subtype_bound_closure4_test: RuntimeError
+function_subtype_bound_closure5_test: RuntimeError
+function_subtype_bound_closure5a_test: RuntimeError
+function_subtype_bound_closure6_test: RuntimeError
function_subtype_bound_closure7_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
function_subtype_call1_test: RuntimeError
function_subtype_call2_test: RuntimeError
function_subtype_cast1_test: RuntimeError
+function_subtype_cast2_test: RuntimeError
+function_subtype_cast3_test: RuntimeError
function_subtype_checked0_test: RuntimeError
function_subtype_closure0_test: RuntimeError
function_subtype_closure1_test: RuntimeError
@@ -1637,18 +1665,27 @@
function_subtype_factory1_test: RuntimeError
function_subtype_inline1_test: RuntimeError
function_subtype_inline2_test: RuntimeError
+function_subtype_local1_test: RuntimeError
+function_subtype_local2_test: RuntimeError
+function_subtype_local5_test: RuntimeError
function_subtype_named1_test: RuntimeError
function_subtype_named2_test: RuntimeError
+function_subtype_not0_test: RuntimeError
function_subtype_not1_test: RuntimeError
+function_subtype_not2_test: RuntimeError
+function_subtype_not3_test: RuntimeError
function_subtype_optional1_test: RuntimeError
function_subtype_optional2_test: RuntimeError
function_subtype_regression_ddc_588_test: RuntimeError
function_subtype_setter0_test: RuntimeError
+function_subtype_top_level1_test: RuntimeError
function_subtype_typearg2_test: RuntimeError
function_subtype_typearg3_test: RuntimeError
function_subtype_typearg5_test: RuntimeError
function_type2_test: RuntimeError
function_type_alias2_test: RuntimeError
+function_type_alias3_test: RuntimeError
+function_type_alias4_test: RuntimeError
function_type_alias_test: RuntimeError
function_type_call_getter2_test/none: RuntimeError
function_type_test: RuntimeError
@@ -1658,7 +1695,7 @@
generic_closure_test/01: RuntimeError
generic_closure_test/none: RuntimeError
generic_field_mixin6_test/none: RuntimeError
-generic_function_bounds_test: CompileTimeError
+generic_function_bounds_test: Crash # Unsupported operation: Unsupported type parameter type node U.
generic_function_dcall_test: Crash # Unsupported operation: Unsupported type parameter type node T.
generic_function_type_as_type_argument_test/01: MissingCompileTimeError
generic_function_type_as_type_argument_test/02: MissingCompileTimeError
@@ -1682,7 +1719,7 @@
generic_methods_unused_parameter_test: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
generic_no_such_method_dispatcher_simple_test: CompileTimeError
generic_no_such_method_dispatcher_test: CompileTimeError
-generic_tearoff_test: Crash # Unsupported operation: Unsupported type parameter type node T.
+generic_tearoff_test: CompileTimeError
generic_test: RuntimeError
getter_override2_test/02: MissingCompileTimeError
getter_override_test/00: MissingCompileTimeError
@@ -1847,16 +1884,8 @@
mixin_invalid_bound_test/08: MissingCompileTimeError
mixin_invalid_bound_test/09: MissingCompileTimeError
mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_issue10216_2_test: RuntimeError
mixin_mixin2_test: RuntimeError
mixin_mixin3_test: RuntimeError
-mixin_mixin4_test: RuntimeError
-mixin_mixin5_test: RuntimeError
-mixin_mixin6_test: RuntimeError
-mixin_mixin7_test: RuntimeError
-mixin_mixin_bound2_test: RuntimeError
-mixin_mixin_bound_test: RuntimeError
-mixin_mixin_test: RuntimeError
mixin_mixin_type_arguments_test: RuntimeError
mixin_of_mixin_test/none: CompileTimeError
mixin_super_2_test/none: CompileTimeError
@@ -2313,6 +2342,7 @@
await_null_aware_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
await_postfix_expr_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
await_regression_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
+await_started_immediately_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
await_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
bad_named_parameters2_test/01: MissingCompileTimeError
bad_named_parameters_test/01: MissingCompileTimeError
@@ -2428,24 +2458,11 @@
deferred_constant_list_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_constants_test/none: CompileTimeError
deferred_constraints_constants_test/reference_after_load: CompileTimeError
-deferred_constraints_type_annotation_test/as_operation: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/catch_check: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/is_check: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/new: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/new_before_load: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/new_generic1: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/new_generic2: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/new_generic3: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/none: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/static_method: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation1: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic1: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic2: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic3: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_generic4: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_constraints_type_annotation_test/type_annotation_non_deferred: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_null: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
-deferred_constraints_type_annotation_test/type_annotation_top_level: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_function_type_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_global_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
deferred_import_core_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
@@ -2527,12 +2544,19 @@
full_stacktrace2_test: RuntimeError # Issue 12698
full_stacktrace3_test: RuntimeError # Issue 12698
function_propagation_test: CompileTimeError
+function_subtype_bound_closure1_test: RuntimeError
+function_subtype_bound_closure2_test: RuntimeError
function_subtype_bound_closure3_test: RuntimeError
function_subtype_bound_closure4_test: RuntimeError
+function_subtype_bound_closure5_test: RuntimeError
+function_subtype_bound_closure5a_test: RuntimeError
+function_subtype_bound_closure6_test: RuntimeError
function_subtype_bound_closure7_test: RuntimeError
function_subtype_call1_test: RuntimeError
function_subtype_call2_test: RuntimeError
function_subtype_cast1_test: RuntimeError
+function_subtype_cast2_test: RuntimeError
+function_subtype_cast3_test: RuntimeError
function_subtype_checked0_test: RuntimeError
function_subtype_closure0_test: RuntimeError
function_subtype_closure1_test: RuntimeError
@@ -2540,18 +2564,27 @@
function_subtype_factory1_test: RuntimeError
function_subtype_inline1_test: RuntimeError
function_subtype_inline2_test: RuntimeError
+function_subtype_local1_test: RuntimeError
+function_subtype_local2_test: RuntimeError
+function_subtype_local5_test: RuntimeError
function_subtype_named1_test: RuntimeError
function_subtype_named2_test: RuntimeError
+function_subtype_not0_test: RuntimeError
function_subtype_not1_test: RuntimeError
+function_subtype_not2_test: RuntimeError
+function_subtype_not3_test: RuntimeError
function_subtype_optional1_test: RuntimeError
function_subtype_optional2_test: RuntimeError
function_subtype_regression_ddc_588_test: RuntimeError
function_subtype_setter0_test: RuntimeError
+function_subtype_top_level1_test: RuntimeError
function_subtype_typearg2_test: RuntimeError
function_subtype_typearg3_test: RuntimeError
function_subtype_typearg5_test: RuntimeError
function_type2_test: RuntimeError
function_type_alias2_test: RuntimeError
+function_type_alias3_test: RuntimeError
+function_type_alias4_test: RuntimeError
function_type_alias_test: RuntimeError
function_type_call_getter2_test/none: RuntimeError
function_type_test: RuntimeError
@@ -2559,7 +2592,7 @@
generic_async_star_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
generic_async_test: Crash # Assertion failure: Runtime type information not available for type_variable_local(bindCallback.R) in (local(_RootZone.bindCallback#)) for j:closure_call(_RootZone_bindCallback_closure.call).
generic_field_mixin6_test/none: RuntimeError
-generic_function_bounds_test: CompileTimeError
+generic_function_bounds_test: Crash # Unsupported operation: Unsupported type parameter type node U.
generic_function_dcall_test: RuntimeError
generic_function_type_as_type_argument_test/01: MissingCompileTimeError
generic_function_type_as_type_argument_test/02: MissingCompileTimeError
@@ -2583,8 +2616,7 @@
generic_methods_unused_parameter_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [Instance of 'LiteralNull', null]
generic_no_such_method_dispatcher_simple_test: CompileTimeError
generic_no_such_method_dispatcher_test: CompileTimeError
-generic_tearoff_test: Crash # Unsupported operation: Unsupported type parameter type node T.
-generic_test: RuntimeError
+generic_tearoff_test: CompileTimeError
getter_override2_test/02: MissingCompileTimeError
getter_override_test/00: MissingCompileTimeError
getter_override_test/01: MissingCompileTimeError
@@ -2747,9 +2779,6 @@
mixin_invalid_bound_test/08: MissingCompileTimeError
mixin_invalid_bound_test/09: MissingCompileTimeError
mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_issue10216_2_test: RuntimeError
-mixin_mixin7_test: RuntimeError
-mixin_mixin_test: RuntimeError
mixin_mixin_type_arguments_test: RuntimeError
mixin_of_mixin_test/none: CompileTimeError
mixin_super_2_test/none: CompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 5deda7c..6cee575 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -11,20 +11,11 @@
accessor_conflict_import_prefixed_test: CompileTimeError # Issue 25626
accessor_conflict_import_test: CompileTimeError # Issue 25626
additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
-assertion_initializer_const_error2_test/*: Crash # Issue #27809
-assertion_initializer_const_error2_test/cc10: Pass # Issue #31319
-assertion_initializer_const_error2_test/cc11: Pass # Issue #31319
-assertion_initializer_const_error2_test/none: Pass
-assertion_initializer_const_function_test/01: Crash
-assertion_initializer_test: CompileTimeError
black_listed_test/none: Fail # Issue 14228
built_in_identifier_prefix_test: CompileTimeError
built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28816
-call_type_literal_test: CompileTimeError
cascaded_forwarding_stubs_generic_test: RuntimeError
cascaded_forwarding_stubs_test: CompileTimeError
-class_literal_static_test/none: CompileTimeError
-class_literal_test/none: CompileTimeError
conflicting_type_variable_and_setter_test: CompileTimeError
const_for_in_variable_test/01: MissingCompileTimeError
const_types_test/07: MissingCompileTimeError
@@ -32,7 +23,6 @@
const_types_test/14: MissingCompileTimeError
const_types_test/15: MissingCompileTimeError
constant_type_literal_test/01: MissingCompileTimeError # DDC allows type parameter type literals in const expressions.
-constructor_call_as_function_test: CompileTimeError
emit_const_fields_test: CompileTimeError
enum_syntax_test/05: MissingCompileTimeError
enum_syntax_test/06: MissingCompileTimeError
@@ -49,10 +39,21 @@
generic_methods_generic_function_result_test/none: CompileTimeError # Issue #30208
generic_no_such_method_dispatcher_simple_test: Skip # This test is just for kernel.
generic_no_such_method_dispatcher_test: CompileTimeError
-generic_test: CompileTimeError
-generics_test: CompileTimeError
getter_setter_in_lib_test: CompileTimeError
-implicit_downcast_during_assert_initializer_test: Crash
+implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError
+implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError
+implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError
+implicit_creation/implicit_const_context_list_test: CompileTimeError
+implicit_creation/implicit_const_context_map_test: CompileTimeError
+implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
+implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError
+implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError
+implicit_creation/implicit_new_constructor_generic_named_test: CompileTimeError
+implicit_creation/implicit_new_constructor_generic_test: CompileTimeError
+implicit_creation/implicit_new_or_const_composite_test: CompileTimeError
+implicit_creation/implicit_new_or_const_generic_test: RuntimeError
+implicit_creation/implicit_new_or_const_test: RuntimeError
+implicit_creation/implicit_new_prefix_constructor_generic_test: CompileTimeError
import_core_prefix_test: CompileTimeError
import_private_test/01: MissingCompileTimeError # Issue 29920
initializing_formal_final_test: MissingCompileTimeError
@@ -100,11 +101,12 @@
parameter_initializer_test: CompileTimeError
part_refers_to_core_library_test/01: Crash
prefix10_negative_test: Fail # Issue 29920
+private_access_test/04: MissingCompileTimeError
regress_23408_test: CompileTimeError
regress_29025_test: CompileTimeError # Issue 29081
regress_29349_test: CompileTimeError # Issue 31093
regress_29405_test: CompileTimeError # Issue 29421
-regress_29784_test/02: CompileTimeError, Crash # Issue 27809
+regress_29784_test/02: MissingCompileTimeError
regress_30121_test: CompileTimeError # Issue 31087
regress_30339_test: CompileTimeError # As expected. Should we make this a multi test?
reify_typevar_static_test/00: MissingCompileTimeError # Issue 29920
@@ -118,7 +120,7 @@
try_catch_on_syntax_test/11: MissingCompileTimeError
type_inference_circularity_test: MissingCompileTimeError
type_inference_inconsistent_inheritance_test: MissingCompileTimeError
-type_literal_prefix_call_test: CompileTimeError
+type_literal_prefix_call_test: RuntimeError
type_promotion_functions_test/02: CompileTimeError # Issue 30895
type_promotion_functions_test/03: CompileTimeError # Issue 30895
type_promotion_functions_test/04: CompileTimeError # Issue 30895
@@ -340,13 +342,13 @@
additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError
-assertion_initializer_test: CompileTimeError
async_await_syntax_test/c10a: MissingCompileTimeError
async_await_syntax_test/d08b: MissingCompileTimeError
async_await_syntax_test/d10a: MissingCompileTimeError
async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError
+async_return_types_test/nestedFuture: MissingCompileTimeError
async_return_types_test/tooManyTypeParameters: MissingCompileTimeError
async_return_types_test/wrongReturnType: MissingCompileTimeError
bad_named_parameters2_test/01: MissingCompileTimeError
@@ -438,19 +440,6 @@
default_factory2_test/01: MissingCompileTimeError
default_factory_test/01: MissingCompileTimeError
deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
-deferred_constraints_type_annotation_test/catch_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/is_check: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_before_load: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/new_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic1: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic2: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic3: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_generic4: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_null: MissingCompileTimeError
-deferred_constraints_type_annotation_test/type_annotation_top_level: MissingCompileTimeError
deferred_inheritance_constraints_test/extends: MissingCompileTimeError
deferred_inheritance_constraints_test/implements: MissingCompileTimeError
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
@@ -482,80 +471,15 @@
field_override_test/00: MissingCompileTimeError
field_override_test/01: MissingCompileTimeError
function_propagation_test: CompileTimeError
-function_type/function_type10_test: RuntimeError # Issue 31766
-function_type/function_type11_test: RuntimeError # Issue 31766
-function_type/function_type14_test: RuntimeError # Issue 31766
-function_type/function_type15_test: RuntimeError # Issue 31766
-function_type/function_type18_test: RuntimeError # Issue 31766
-function_type/function_type19_test: RuntimeError # Issue 31766
-function_type/function_type20_test: RuntimeError # Issue 31766
-function_type/function_type21_test: RuntimeError # Issue 31766
-function_type/function_type22_test: RuntimeError # Issue 31766
-function_type/function_type23_test: RuntimeError # Issue 31766
-function_type/function_type24_test: RuntimeError # Issue 31766
-function_type/function_type25_test: RuntimeError # Issue 31766
-function_type/function_type26_test: RuntimeError # Issue 31766
-function_type/function_type27_test: RuntimeError # Issue 31766
-function_type/function_type28_test: RuntimeError # Issue 31766
-function_type/function_type29_test: RuntimeError # Issue 31766
-function_type/function_type2_test: RuntimeError # Issue 31766
-function_type/function_type30_test: RuntimeError # Issue 31766
-function_type/function_type31_test: RuntimeError # Issue 31766
-function_type/function_type32_test: RuntimeError # Issue 31766
-function_type/function_type33_test: RuntimeError # Issue 31766
-function_type/function_type34_test: RuntimeError # Issue 31766
-function_type/function_type35_test: RuntimeError # Issue 31766
-function_type/function_type36_test: RuntimeError # Issue 31766
-function_type/function_type37_test: RuntimeError # Issue 31766
-function_type/function_type38_test: RuntimeError # Issue 31766
-function_type/function_type39_test: RuntimeError # Issue 31766
-function_type/function_type3_test: RuntimeError # Issue 31766
-function_type/function_type40_test: RuntimeError # Issue 31766
-function_type/function_type41_test: RuntimeError # Issue 31766
-function_type/function_type42_test: RuntimeError # Issue 31766
-function_type/function_type43_test: RuntimeError # Issue 31766
-function_type/function_type44_test: RuntimeError # Issue 31766
-function_type/function_type45_test: RuntimeError # Issue 31766
-function_type/function_type46_test: RuntimeError # Issue 31766
-function_type/function_type47_test: RuntimeError # Issue 31766
-function_type/function_type48_test: RuntimeError # Issue 31766
-function_type/function_type49_test: RuntimeError # Issue 31766
-function_type/function_type50_test: RuntimeError # Issue 31766
-function_type/function_type51_test: RuntimeError # Issue 31766
-function_type/function_type54_test: RuntimeError # Issue 31766
-function_type/function_type55_test: RuntimeError # Issue 31766
-function_type/function_type58_test: RuntimeError # Issue 31766
-function_type/function_type59_test: RuntimeError # Issue 31766
-function_type/function_type62_test: RuntimeError # Issue 31766
-function_type/function_type63_test: RuntimeError # Issue 31766
-function_type/function_type66_test: RuntimeError # Issue 31766
-function_type/function_type67_test: RuntimeError # Issue 31766
-function_type/function_type6_test: RuntimeError # Issue 31766
-function_type/function_type70_test: RuntimeError # Issue 31766
-function_type/function_type71_test: RuntimeError # Issue 31766
-function_type/function_type74_test: RuntimeError # Issue 31766
-function_type/function_type75_test: RuntimeError # Issue 31766
-function_type/function_type78_test: RuntimeError # Issue 31766
-function_type/function_type79_test: RuntimeError # Issue 31766
-function_type/function_type7_test: RuntimeError # Issue 31766
-function_type/function_type82_test: RuntimeError # Issue 31766
-function_type/function_type83_test: RuntimeError # Issue 31766
-function_type/function_type86_test: RuntimeError # Issue 31766
-function_type/function_type87_test: RuntimeError # Issue 31766
-function_type/function_type90_test: RuntimeError # Issue 31766
-function_type/function_type91_test: RuntimeError # Issue 31766
-function_type/function_type94_test: RuntimeError # Issue 31766
-function_type/function_type95_test: RuntimeError # Issue 31766
-function_type/function_type98_test: RuntimeError # Issue 31766
-function_type/function_type99_test: RuntimeError # Issue 31766
function_type_parameter2_negative_test: Fail
function_type_parameter_negative_test: Fail
-generic_function_bounds_test: CompileTimeError
+generic_function_bounds_test: RuntimeError
generic_methods_bounds_test/01: MissingCompileTimeError
generic_methods_generic_function_result_test/01: MissingCompileTimeError
generic_methods_recursive_bound_test/02: MissingCompileTimeError
generic_no_such_method_dispatcher_simple_test: CompileTimeError # Warning: Superclass has no method named 'foo'.
generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
+generic_test/01: MissingCompileTimeError # front end does not validate `extends`
getter_override2_test/02: MissingCompileTimeError
getter_override_test/00: MissingCompileTimeError
getter_override_test/01: MissingCompileTimeError
@@ -834,9 +758,7 @@
execute_finally6_test: RuntimeError # Issue 29920
expect_test: RuntimeError # Issue 29920
f_bounded_quantification3_test: RuntimeError # Issue 29920
-final_field_initialization_order_test: RuntimeError # Issue 31058
forwarding_stub_tearoff_generic_test: RuntimeError
-fuzzy_arrows_test/03: RuntimeError # Issue 29630
generic_methods_overriding_test/03: MissingCompileTimeError # Issue 29920
getter_closure_execution_order_test: RuntimeError # Issue 29920
implicit_downcast_during_compound_assignment_test: RuntimeError
@@ -870,32 +792,8 @@
[ $compiler == dartdevk && $runtime != none ]
conditional_import_string_test: CompileTimeError # Test is broken
conditional_import_test: CompileTimeError # Test is broken
-function_subtype_bound_closure1_test: RuntimeError # Expect.isTrue(false, 'foo is Foo') fails.
-function_subtype_bound_closure2_test: RuntimeError # ReferenceError: TAndStringToint is not defined
-function_subtype_bound_closure5_test: RuntimeError # ReferenceError: TAndStringToint is not defined
-function_subtype_bound_closure5a_test: RuntimeError # ReferenceError: TAndStringToint is not defined
-function_subtype_bound_closure6_test: RuntimeError # ReferenceError: TAndStringToint is not defined
function_subtype_cast0_test: RuntimeError # CastError: Casting value of type '(int) => void' to type '(dynamic) => void' which is incompatible
-function_subtype_cast2_test: RuntimeError # ReferenceError: TTovoid is not defined
-function_subtype_cast3_test: RuntimeError # ReferenceError: TTovoid is not defined
-function_subtype_checked0_test: RuntimeError # Expect.throws(TypeError) fails: Did not throw
function_subtype_closure0_test: RuntimeError # Expect.throws(TypeError) fails: Did not throw
-function_subtype_local1_test: RuntimeError # Expect.isTrue(false, 'foo is Foo') fails.
-function_subtype_local2_test: RuntimeError # ReferenceError: TAndStringToint is not defined
-function_subtype_local5_test: RuntimeError # ReferenceError: TAndStringToint is not defined
-function_subtype_not0_test: RuntimeError # Expect.isFalse(true) fails.
-function_subtype_not2_test: RuntimeError # ReferenceError: TTovoid is not defined
-function_subtype_not3_test: RuntimeError # ReferenceError: TTovoid is not defined
-function_subtype_simple1_test: RuntimeError # Expect.isTrue(false) fails.
-function_subtype_top_level1_test: RuntimeError # ReferenceError: TAndStringToint is not defined
-function_subtype_typearg5_test: RuntimeError # ReferenceError: JSArrayOfXAndXToX is not defined
-function_type_alias2_test: RuntimeError # Expect.isTrue(false) fails.
-function_type_alias3_test: RuntimeError # TypeError: library11.Library111$ is not a function
-function_type_alias4_test: RuntimeError # Expect.isTrue(false) fails.
-function_type_alias_test: RuntimeError # Expect.isTrue(false) fails.
-generic_closure_test/01: RuntimeError # ReferenceError: TToT is not defined
-generic_closure_test/none: RuntimeError # ReferenceError: TToT is not defined
-generic_test: RuntimeError # ReferenceError: BOfT is not defined
implicit_creation/implicit_new_or_const_composite_test: RuntimeError
implicit_creation/implicit_new_or_const_test: RuntimeError
library_env_test/has_io_support: RuntimeError # Unsupported operation: bool.fromEnvironment can only be used as a const constructor
@@ -1034,7 +932,6 @@
abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue #30568
abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568
abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
-async_return_types_test/nestedFuture: MissingCompileTimeError
bit_operations_test/01: MissingCompileTimeError
bit_operations_test/02: MissingCompileTimeError
built_in_identifier_prefix_test: CompileTimeError
diff --git a/tests/language_2/language_2_flutter.status b/tests/language_2/language_2_flutter.status
index 2953d2c..8ed9601 100644
--- a/tests/language_2/language_2_flutter.status
+++ b/tests/language_2/language_2_flutter.status
@@ -85,7 +85,6 @@
field_increment_bailout_test: CompileTimeError
field_override_test/01: CompileTimeError
function_malformed_result_type_test: CompileTimeError
-generalized_void_syntax_test: CompileTimeError # Issue #30176
generic_function_typedef2_test/04: CompileTimeError
instance_creation_in_function_annotation_test: CompileTimeError
internal_library_test/01: CompileTimeError
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 032adc8..981f39d 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -274,7 +274,6 @@
cyclic_type_variable_test/04: Crash
cyclic_type_variable_test/none: Crash
deopt_inlined_function_lazy_test: Skip
-flatten_test/04: Crash # Issue #31381
instance_call_wrong_argument_count_negative_test: Crash # Issue(http//dartbug.com/31630)
optional_named_parameters_test/02: Crash # Issue(http://dartbug.com/31630)
optional_named_parameters_test/04: Crash # Issue(http://dartbug.com/31630)
@@ -318,19 +317,10 @@
assert_initializer_test/47: MissingCompileTimeError # KernelVM bug: Constant evaluation.
assert_initializer_test/48: MissingCompileTimeError # KernelVM bug: Constant evaluation.
assert_initializer_test/none: RuntimeError # KernelVM bug: Constant evaluation.
-async_await_syntax_test/c03a: RuntimeError
-async_await_syntax_test/c09a: RuntimeError
-async_await_syntax_test/d03a: RuntimeError
-async_await_syntax_test/d09a: RuntimeError
async_await_test/02: RuntimeError
async_await_test/03: RuntimeError
async_await_test/none: RuntimeError
async_return_types_test/nestedFuture: Fail
-async_return_types_test/none: RuntimeError
-async_star_regression_2238_test: RuntimeError
-async_star_take_reyield_test: RuntimeError
-asyncstar_yield_test: RuntimeError
-asyncstar_yieldstar_test: RuntimeError
compile_time_constant_checked_test/02: MissingCompileTimeError
const_constructor2_test/20: MissingCompileTimeError
const_constructor2_test/22: MissingCompileTimeError
@@ -340,74 +330,6 @@
covariance_type_parameter_test/03: RuntimeError
covariance_type_parameter_test/none: RuntimeError
default_factory2_test/01: Fail
-f_bounded_quantification4_test: RuntimeError
-function_type/function_type10_test: RuntimeError
-function_type/function_type11_test: RuntimeError
-function_type/function_type14_test: RuntimeError
-function_type/function_type15_test: RuntimeError
-function_type/function_type18_test: RuntimeError
-function_type/function_type19_test: RuntimeError
-function_type/function_type20_test: RuntimeError
-function_type/function_type21_test: RuntimeError
-function_type/function_type22_test: RuntimeError
-function_type/function_type23_test: RuntimeError
-function_type/function_type24_test: RuntimeError
-function_type/function_type25_test: RuntimeError
-function_type/function_type26_test: RuntimeError
-function_type/function_type27_test: RuntimeError
-function_type/function_type28_test: RuntimeError
-function_type/function_type29_test: RuntimeError
-function_type/function_type2_test: RuntimeError
-function_type/function_type30_test: RuntimeError
-function_type/function_type31_test: RuntimeError
-function_type/function_type32_test: RuntimeError
-function_type/function_type33_test: RuntimeError
-function_type/function_type34_test: RuntimeError
-function_type/function_type35_test: RuntimeError
-function_type/function_type36_test: RuntimeError
-function_type/function_type37_test: RuntimeError
-function_type/function_type38_test: RuntimeError
-function_type/function_type39_test: RuntimeError
-function_type/function_type3_test: RuntimeError
-function_type/function_type40_test: RuntimeError
-function_type/function_type41_test: RuntimeError
-function_type/function_type42_test: RuntimeError
-function_type/function_type43_test: RuntimeError
-function_type/function_type44_test: RuntimeError
-function_type/function_type45_test: RuntimeError
-function_type/function_type46_test: RuntimeError
-function_type/function_type47_test: RuntimeError
-function_type/function_type48_test: RuntimeError
-function_type/function_type49_test: RuntimeError
-function_type/function_type50_test: RuntimeError
-function_type/function_type51_test: RuntimeError
-function_type/function_type54_test: RuntimeError
-function_type/function_type55_test: RuntimeError
-function_type/function_type58_test: RuntimeError
-function_type/function_type59_test: RuntimeError
-function_type/function_type62_test: RuntimeError
-function_type/function_type63_test: RuntimeError
-function_type/function_type66_test: RuntimeError
-function_type/function_type67_test: RuntimeError
-function_type/function_type6_test: RuntimeError
-function_type/function_type70_test: RuntimeError
-function_type/function_type71_test: RuntimeError
-function_type/function_type74_test: RuntimeError
-function_type/function_type75_test: RuntimeError
-function_type/function_type78_test: RuntimeError
-function_type/function_type79_test: RuntimeError
-function_type/function_type7_test: RuntimeError
-function_type/function_type82_test: RuntimeError
-function_type/function_type83_test: RuntimeError
-function_type/function_type86_test: RuntimeError
-function_type/function_type87_test: RuntimeError
-function_type/function_type90_test: RuntimeError
-function_type/function_type91_test: RuntimeError
-function_type/function_type94_test: RuntimeError
-function_type/function_type95_test: RuntimeError
-function_type/function_type98_test: RuntimeError
-function_type/function_type99_test: RuntimeError
-known_identifier_usage_error_test/none: RuntimeError # Issue 28814
malbounded_redirecting_factory_test/03: Fail
malbounded_redirecting_factory_test/04: Fail
malbounded_type_test_test/03: Fail
@@ -417,6 +339,7 @@
mixin_invalid_bound2_test/10: Fail
mixin_invalid_bound_test/06: Fail
mixin_invalid_bound_test/07: Fail
+recursive_inheritance_test: RuntimeError
recursive_mixin_test: Crash
redirecting_factory_infinite_steps_test/01: Fail
redirecting_factory_malbounded_test/01: Fail
@@ -449,17 +372,16 @@
# ===== dartk + vm status lines =====
[ $compiler == dartk && $runtime == vm && $strong ]
-abstract_factory_constructor_test/00: MissingCompileTimeError
-abstract_getter_test/01: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError
-abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError
-abstract_syntax_test/00: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
-additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError
+abstract_factory_constructor_test/00: MissingCompileTimeError # Issue 32013.
+abstract_getter_test/01: MissingCompileTimeError # Issue 32013.
+abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue 32013.
+abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue 32014.
+abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue 32014.
+abstract_syntax_test/00: MissingCompileTimeError # Issue 32013.
+additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue 32014.
+additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError # Issue 32014.
+additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError # Issue 32014.
arithmetic2_test: RuntimeError # Throws CastError instead of TypeError
-assertion_initializer_test: CompileTimeError # Issue 31402 (Assert statement)
async_await_syntax_test/c10a: MissingCompileTimeError
async_await_syntax_test/d08b: MissingCompileTimeError
async_await_syntax_test/d10a: MissingCompileTimeError
@@ -505,7 +427,7 @@
call_non_method_field_test/02: MissingCompileTimeError
call_with_no_such_method_test: CompileTimeError # Issue 31402 (Invocation arguments)
callable_test/none: CompileTimeError # Issue 31402 (Variable declaration)
-cha_deopt1_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+cha_deopt1_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
cha_deopt1_test: RuntimeError
check_member_static_test/01: MissingCompileTimeError
closure_invoked_through_interface_target_field_test: MissingCompileTimeError
@@ -522,8 +444,8 @@
compile_time_constant_static5_test/16: CompileTimeError # Issue 31537
compile_time_constant_static5_test/21: CompileTimeError # Issue 31537
compile_time_constant_static5_test/23: CompileTimeError # Issue 31402 (Field declaration)
-conditional_import_string_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-conditional_import_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+conditional_import_string_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+conditional_import_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
config_import_corelib_test: CompileTimeError # Issue 31533
config_import_test: RuntimeError # KernelVM bug: Configurable imports.
const_constructor2_test/11: CompileTimeError # Issue 31402 (Invocation arguments)
@@ -573,45 +495,45 @@
cyclic_typedef_test/11: Crash
default_factory2_test/01: MissingCompileTimeError
default_factory_test/01: MissingCompileTimeError
-deferred_call_empty_before_load_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_closurize_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constant_list_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constraints_constants_test/default_argument2: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constraints_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constraints_constants_test/reference_after_load: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constraints_type_annotation_test/new: CompileTimeError # Deferred loading kernel issue 28335.
-deferred_constraints_type_annotation_test/new_generic1: CompileTimeError # Deferred loading kernel issue 28335
-deferred_constraints_type_annotation_test/none: CompileTimeError # Deferred loading kernel issue 28335.
-deferred_constraints_type_annotation_test/static_method: CompileTimeError # Deferred loading kernel issue 28335.
-deferred_constraints_type_annotation_test/type_annotation_non_deferred: CompileTimeError # Deferred loading kernel issue 28335.
-deferred_function_type_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_global_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_import_core_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inlined_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_inval_code_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_library_wrong_args_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_mixin_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_no_such_method_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_not_loaded_check_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_only_constant_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_optimized_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_redirecting_factory_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_regression_22995_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_regression_28678_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_shadow_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_static_seperate_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_super_dependency_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/as: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/is: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/type_annotation: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+deferred_call_empty_before_load_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_closurize_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constant_list_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constraints_constants_test/default_argument2: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constraints_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constraints_constants_test/reference_after_load: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constraints_type_annotation_test/new: CompileTimeError # Deferred loading kernel issue 30273.
+deferred_constraints_type_annotation_test/new_generic1: CompileTimeError # Deferred loading kernel issue 30273
+deferred_constraints_type_annotation_test/none: CompileTimeError # Deferred loading kernel issue 30273.
+deferred_constraints_type_annotation_test/static_method: CompileTimeError # Deferred loading kernel issue 30273.
+deferred_constraints_type_annotation_test/type_annotation_non_deferred: CompileTimeError # Deferred loading kernel issue 30273.
+deferred_function_type_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_global_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_import_core_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inlined_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_inval_code_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_library_wrong_args_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_mixin_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_no_such_method_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_not_loaded_check_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_only_constant_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_optimized_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_redirecting_factory_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_regression_22995_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_regression_28678_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_shadow_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_static_seperate_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_super_dependency_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/as: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/is: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/type_annotation: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
disassemble_test: Pass, Slow
duplicate_export_negative_test: Fail # Issue 6134
dynamic_prefix_core_test/none: CompileTimeError
@@ -637,36 +559,13 @@
for_in_side_effects_test/01: MissingCompileTimeError
function_propagation_test: CompileTimeError # Issue 31402 (Variable declaration)
function_subtype3_test: RuntimeError
-function_subtype_bound_closure1_test: RuntimeError
-function_subtype_bound_closure2_test: RuntimeError
-function_subtype_bound_closure5_test: RuntimeError
-function_subtype_bound_closure5a_test: RuntimeError
-function_subtype_bound_closure6_test: RuntimeError
function_subtype_call1_test: RuntimeError
function_subtype_call2_test: RuntimeError
function_subtype_cast0_test: RuntimeError
-function_subtype_cast2_test: RuntimeError
-function_subtype_cast3_test: RuntimeError
-function_subtype_checked0_test: RuntimeError
function_subtype_inline2_test: RuntimeError
-function_subtype_local1_test: RuntimeError
-function_subtype_local2_test: RuntimeError
-function_subtype_local5_test: RuntimeError
-function_subtype_not0_test: RuntimeError
-function_subtype_not2_test: RuntimeError
-function_subtype_not3_test: RuntimeError
-function_subtype_simple1_test: RuntimeError
-function_subtype_top_level1_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
function_type2_test: RuntimeError
-function_type_alias2_test: RuntimeError
-function_type_alias3_test: RuntimeError
-function_type_alias4_test: RuntimeError
function_type_alias6_test/none: RuntimeError
-function_type_alias_test: RuntimeError
-generic_closure_test: RuntimeError
-generic_function_bounds_test: CompileTimeError
-generic_function_bounds_test: RuntimeError
+generic_function_bounds_test: Crash # Issue 32012
generic_function_dcall_test: RuntimeError
generic_instanceof2_test: RuntimeError
generic_is_check_test: RuntimeError
@@ -677,7 +576,7 @@
generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
generic_tearoff_test: CompileTimeError
generic_tearoff_test: RuntimeError
-generic_test: RuntimeError
+generic_test/01: MissingCompileTimeError # front end does not validate `extends`
getter_override_test/03: MissingCompileTimeError
identical_const_test/01: MissingCompileTimeError
identical_const_test/02: MissingCompileTimeError
@@ -698,7 +597,7 @@
issue31596_super_test/03: CompileTimeError
issue31596_super_test/04: MissingCompileTimeError
issue31596_super_test/05: RuntimeError
-issue_1751477_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+issue_1751477_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
issue_25671a_test/01: CompileTimeError # Test assumes Dart 1.0 semantics
issue_25671b_test/01: DartkCrash
least_upper_bound_expansive_test/none: CompileTimeError
@@ -866,13 +765,13 @@
redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
redirecting_factory_long_test: RuntimeError # Fasta bug: Bad compilation of type arguments for redirecting factory.
redirecting_factory_malbounded_test/01: MissingCompileTimeError
-regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
regress_23089_test: Crash
-regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
regress_23408_test: RuntimeError
regress_25550_test: CompileTimeError # Issue 31402 (Variable declaration)
regress_27617_test/1: MissingCompileTimeError # Fasta bug: Bad constructor redirection.
-regress_28278_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+regress_28278_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
regress_29025_test: CompileTimeError # Issue 31402 (Variable declaration)
regress_29405_test: CompileTimeError # Issue 31402 (Invocation arguments)
regress_29784_test/01: MissingCompileTimeError
@@ -936,7 +835,7 @@
vm/debug_break_enabled_vm_test/01: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
vm/debug_break_enabled_vm_test/none: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
vm/optimized_guarded_field_isolates_test: RuntimeError # Issue 31402 (Variable declaration)
-vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
vm/regress_29145_test: Skip # Issue 29145
vm/type_cast_vm_test: RuntimeError
void_block_return_test/00: MissingCompileTimeError
@@ -950,8 +849,18 @@
ct_const2_test: Fail
[ $compiler == dartk && $strong ]
-cha_deopt2_test: CompileTimeError, DartkCrash # KernelVM bug: Deferred loading kernel issue 28335.
-cha_deopt3_test: CompileTimeError, DartkCrash # KernelVM bug: Deferred loading kernel issue 28335.
+assertion_initializer_const_error2_test/cc01: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc02: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc03: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc05: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc06: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc07: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc08: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc11: MissingCompileTimeError # Not reporting failed assert() at compile time.
+cha_deopt2_test: CompileTimeError, DartkCrash # KernelVM bug: Deferred loading kernel issue 30273.
+cha_deopt3_test: CompileTimeError, DartkCrash # KernelVM bug: Deferred loading kernel issue 30273.
hello_dart_test: Crash
recursive_mixin_test: Crash
redirecting_factory_reflection_test: Crash
@@ -960,12 +869,8 @@
# are to be triaged. Isolate tests are skipped on purpose due to the usage of
# batch mode.
[ $compiler == dartk && $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
-class_cycle_test/02: MissingCompileTimeError # Please triage.
-class_cycle_test/03: MissingCompileTimeError # Please triage.
-deferred_constraints_constants_test/default_argument2: MissingCompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-duplicate_implements_test/01: MissingCompileTimeError # Please triage.
-duplicate_implements_test/02: MissingCompileTimeError # Please triage.
-generic_methods_generic_function_result_test/01: MissingCompileTimeError # Please triage.
+deferred_constraints_constants_test/default_argument2: MissingCompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+duplicate_implements_test/02: Slow, Pass
least_upper_bound_expansive_test/none: RuntimeError # Please triage.
[ $compiler == dartk && !$strong ]
@@ -1035,16 +940,8 @@
assertion_initializer_const_error2_test/cc09: Crash
assertion_initializer_const_error2_test/cc10: Crash
assertion_initializer_const_error2_test/cc11: Crash
-async_await_syntax_test/c03a: RuntimeError
-async_await_syntax_test/c09a: RuntimeError
-async_await_syntax_test/d03a: RuntimeError
-async_await_syntax_test/d09a: RuntimeError
async_await_test: RuntimeError
async_return_types_test/nestedFuture: Fail
-async_return_types_test/none: RuntimeError
-async_star_take_reyield_test: RuntimeError
-asyncstar_yield_test: RuntimeError
-asyncstar_yieldstar_test: RuntimeError
compile_time_constant_checked_test/02: MissingCompileTimeError
const_constructor2_test/20: MissingCompileTimeError
const_constructor2_test/22: MissingCompileTimeError
@@ -1061,72 +958,6 @@
function_subtype_inline1_test: Pass
function_subtype_inline2_test: Pass
function_subtype_setter0_test: Pass
-function_type/function_type10_test: RuntimeError
-function_type/function_type11_test: RuntimeError
-function_type/function_type14_test: RuntimeError
-function_type/function_type15_test: RuntimeError
-function_type/function_type18_test: RuntimeError
-function_type/function_type19_test: RuntimeError
-function_type/function_type20_test: RuntimeError
-function_type/function_type21_test: RuntimeError
-function_type/function_type22_test: RuntimeError
-function_type/function_type23_test: RuntimeError
-function_type/function_type24_test: RuntimeError
-function_type/function_type25_test: RuntimeError
-function_type/function_type26_test: RuntimeError
-function_type/function_type27_test: RuntimeError
-function_type/function_type28_test: RuntimeError
-function_type/function_type29_test: RuntimeError
-function_type/function_type2_test: RuntimeError
-function_type/function_type30_test: RuntimeError
-function_type/function_type31_test: RuntimeError
-function_type/function_type32_test: RuntimeError
-function_type/function_type33_test: RuntimeError
-function_type/function_type34_test: RuntimeError
-function_type/function_type35_test: RuntimeError
-function_type/function_type36_test: RuntimeError
-function_type/function_type37_test: RuntimeError
-function_type/function_type38_test: RuntimeError
-function_type/function_type39_test: RuntimeError
-function_type/function_type3_test: RuntimeError
-function_type/function_type40_test: RuntimeError
-function_type/function_type41_test: RuntimeError
-function_type/function_type42_test: RuntimeError
-function_type/function_type43_test: RuntimeError
-function_type/function_type44_test: RuntimeError
-function_type/function_type45_test: RuntimeError
-function_type/function_type46_test: RuntimeError
-function_type/function_type47_test: RuntimeError
-function_type/function_type48_test: RuntimeError
-function_type/function_type49_test: RuntimeError
-function_type/function_type50_test: RuntimeError
-function_type/function_type51_test: RuntimeError
-function_type/function_type54_test: RuntimeError
-function_type/function_type55_test: RuntimeError
-function_type/function_type58_test: RuntimeError
-function_type/function_type59_test: RuntimeError
-function_type/function_type62_test: RuntimeError
-function_type/function_type63_test: RuntimeError
-function_type/function_type66_test: RuntimeError
-function_type/function_type67_test: RuntimeError
-function_type/function_type6_test: RuntimeError
-function_type/function_type70_test: RuntimeError
-function_type/function_type71_test: RuntimeError
-function_type/function_type74_test: RuntimeError
-function_type/function_type75_test: RuntimeError
-function_type/function_type78_test: RuntimeError
-function_type/function_type79_test: RuntimeError
-function_type/function_type7_test: RuntimeError
-function_type/function_type82_test: RuntimeError
-function_type/function_type83_test: RuntimeError
-function_type/function_type86_test: RuntimeError
-function_type/function_type87_test: RuntimeError
-function_type/function_type90_test: RuntimeError
-function_type/function_type91_test: RuntimeError
-function_type/function_type94_test: RuntimeError
-function_type/function_type95_test: RuntimeError
-function_type/function_type98_test: RuntimeError
-function_type/function_type99_test: RuntimeError
function_type2_test: RuntimeError
generic_functions_test: Pass # Issue 25869
generic_local_functions_test: Pass # Issue 25869
@@ -1144,6 +975,7 @@
mixin_invalid_bound2_test/10: Fail
mixin_invalid_bound_test/06: Fail
mixin_invalid_bound_test/07: Fail
+recursive_inheritance_test: RuntimeError
redirecting_factory_infinite_steps_test/01: Fail
redirecting_factory_malbounded_test/01: Fail
regress_22728_test: Fail # Dartk Issue 28498
@@ -1197,18 +1029,17 @@
# ==== dartkp + dart_precompiled status lines ====
[ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
-abstract_factory_constructor_test/00: MissingCompileTimeError
-abstract_getter_test/01: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError
-abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError
-abstract_syntax_test/00: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
-additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
-additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError
+abstract_factory_constructor_test/00: MissingCompileTimeError # Issue 32013.
+abstract_getter_test/01: MissingCompileTimeError # Issue 32013.
+abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue 32013.
+abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue 32014.
+abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue 32014.
+abstract_syntax_test/00: MissingCompileTimeError # Issue 32013.
+additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue 32014.
+additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError # Issue 32014.
+additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError # Issue 32014.
assert_with_type_test_or_cast_test: Pass, Crash
assertion_initializer_const_error_test/01: Pass
-assertion_initializer_test: CompileTimeError # Issue 31402 (Assert statement)
async_await_syntax_test/c10a: MissingCompileTimeError
async_await_syntax_test/d08b: MissingCompileTimeError
async_await_syntax_test/d10a: MissingCompileTimeError
@@ -1256,9 +1087,9 @@
call_non_method_field_test/02: MissingCompileTimeError
call_with_no_such_method_test: CompileTimeError # Issue 31402 (Invocation arguments)
callable_test/none: CompileTimeError # Issue 31402 (Variable declaration)
-cha_deopt1_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-cha_deopt2_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-cha_deopt3_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+cha_deopt1_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+cha_deopt2_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+cha_deopt3_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
check_member_static_test/01: MissingCompileTimeError
checked_setter3_test/01: MissingCompileTimeError
checked_setter3_test/02: MissingCompileTimeError
@@ -1279,8 +1110,8 @@
compile_time_constant_static5_test/16: CompileTimeError # Issue 31537
compile_time_constant_static5_test/21: CompileTimeError # Issue 31537
compile_time_constant_static5_test/23: CompileTimeError # Issue 31402 (Field declaration)
-conditional_import_string_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-conditional_import_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+conditional_import_string_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+conditional_import_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
config_import_corelib_test: CompileTimeError # Issue 31533
config_import_test: RuntimeError # KernelVM bug: Configurable imports.
const_constructor2_test/11: CompileTimeError # Issue 31402 (Invocation arguments)
@@ -1330,47 +1161,47 @@
deep_nesting2_negative_test: Skip # Issue 31158
default_factory2_test/01: MissingCompileTimeError
default_factory_test/01: MissingCompileTimeError
-deferred_call_empty_before_load_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_closurize_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constant_list_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+deferred_call_empty_before_load_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_closurize_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constant_list_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
deferred_constraints_constants_test: SkipByDesign
-deferred_constraints_constants_test/default_argument2: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constraints_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constraints_constants_test/reference_after_load: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+deferred_constraints_constants_test/default_argument2: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constraints_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_constraints_constants_test/reference_after_load: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
deferred_constraints_type_annotation_test/new: CompileTimeError
deferred_constraints_type_annotation_test/new_generic1: CompileTimeError
deferred_constraints_type_annotation_test/none: CompileTimeError
deferred_constraints_type_annotation_test/static_method: CompileTimeError
deferred_constraints_type_annotation_test/type_annotation_non_deferred: CompileTimeError
-deferred_function_type_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_global_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+deferred_function_type_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_global_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
deferred_global_test: Fail
-deferred_import_core_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+deferred_import_core_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError
-deferred_inlined_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_inval_code_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
-deferred_load_library_wrong_args_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_mixin_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_no_such_method_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_not_loaded_check_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_only_constant_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_optimized_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_redirecting_factory_test: CompileTimeError, Fail, Crash # Issue 23408, KernelVM bug: Deferred loading kernel issue 28335.
-deferred_regression_22995_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_regression_28678_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_shadow_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_static_seperate_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_super_dependency_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/as: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/is: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_type_dependency_test/type_annotation: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+deferred_inlined_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_inval_code_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
+deferred_load_library_wrong_args_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_mixin_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_no_such_method_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_not_loaded_check_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
+deferred_only_constant_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_optimized_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_redirecting_factory_test: CompileTimeError, Fail, Crash # Issue 23408, KernelVM bug: Deferred loading kernel issue 30273.
+deferred_regression_22995_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_regression_28678_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_shadow_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_static_seperate_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_super_dependency_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/as: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/is: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
+deferred_type_dependency_test/type_annotation: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
deopt_inlined_function_lazy_test: Skip # Incompatible flag: --deoptimize-alot
duplicate_export_negative_test: Fail # Issue 6134
duplicate_implements_test/01: MissingCompileTimeError
@@ -1405,36 +1236,14 @@
for_in_side_effects_test/01: MissingCompileTimeError
function_propagation_test: CompileTimeError # Issue 31402 (Variable declaration)
function_subtype3_test: RuntimeError
-function_subtype_bound_closure1_test: RuntimeError
-function_subtype_bound_closure2_test: RuntimeError
-function_subtype_bound_closure5_test: RuntimeError
-function_subtype_bound_closure5a_test: RuntimeError
-function_subtype_bound_closure6_test: RuntimeError
function_subtype_call1_test: RuntimeError
function_subtype_call2_test: RuntimeError
function_subtype_cast0_test: RuntimeError
-function_subtype_cast2_test: RuntimeError
-function_subtype_cast3_test: RuntimeError
-function_subtype_checked0_test: RuntimeError
function_subtype_inline2_test: RuntimeError
-function_subtype_local1_test: RuntimeError
-function_subtype_local2_test: RuntimeError
-function_subtype_local5_test: RuntimeError
-function_subtype_not0_test: RuntimeError
-function_subtype_not2_test: RuntimeError
-function_subtype_not3_test: RuntimeError
function_subtype_setter0_test: RuntimeError
-function_subtype_simple1_test: RuntimeError
-function_subtype_top_level1_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
function_type2_test: RuntimeError
-function_type_alias2_test: RuntimeError
-function_type_alias3_test: RuntimeError
-function_type_alias4_test: RuntimeError
function_type_alias6_test/none: RuntimeError
-function_type_alias_test: RuntimeError
-generic_closure_test: RuntimeError
-generic_function_bounds_test: CompileTimeError
+generic_function_bounds_test: Crash # Issue 32012
generic_function_dcall_test: RuntimeError
generic_instanceof2_test: RuntimeError
generic_is_check_test: RuntimeError
@@ -1451,7 +1260,7 @@
generic_no_such_method_dispatcher_simple_test: CompileTimeError # Issue 31533
generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
generic_tearoff_test: CompileTimeError
-generic_test: RuntimeError
+generic_test/01: MissingCompileTimeError # front end does not validate `extends`
getter_override_test/03: MissingCompileTimeError
hello_dart_test: Skip # Incompatible flag: --compile_all
identical_const_test/01: MissingCompileTimeError
@@ -1498,7 +1307,7 @@
issue31596_super_test/03: CompileTimeError
issue31596_super_test/04: MissingCompileTimeError
issue31596_super_test/05: RuntimeError
-issue_1751477_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+issue_1751477_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
issue_25671a_test/01: CompileTimeError # Test assumes Dart 1.0 semantics
issue_25671b_test/01: Crash
least_upper_bound_expansive_test/none: RuntimeError
@@ -1677,14 +1486,14 @@
regress_13462_0_test: SkipByDesign
regress_13462_1_test: SkipByDesign
regress_18535_test: SkipByDesign
-regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
regress_23089_test: Crash
-regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
regress_23408_test: RuntimeError
regress_25550_test: CompileTimeError # Issue 31402 (Variable declaration)
regress_27617_test/1: MissingCompileTimeError # Fasta bug: Bad constructor redirection.
regress_28255_test: SkipByDesign
-regress_28278_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
+regress_28278_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 30273.
regress_29025_test: CompileTimeError # Issue 31402 (Variable declaration)
regress_29405_test: CompileTimeError # Issue 31402 (Invocation arguments)
regress_29784_test/01: MissingCompileTimeError
@@ -1757,7 +1566,7 @@
vm/optimized_stacktrace_test: Crash
vm/optimized_stacktrace_test: Skip # Issue 30198
vm/reflect_core_vm_test: SkipByDesign
-vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
vm/regress_27201_test: Fail
vm/regress_27671_test: Skip # Unsupported
vm/regress_27671_test: Crash
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index 043971c..139219d 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -376,7 +376,6 @@
function_type_call_getter2_test/05: MissingCompileTimeError
fuzzy_arrows_test/01: MissingCompileTimeError
fuzzy_arrows_test/03: RuntimeError
-generalized_void_syntax_test: CompileTimeError # Issue #30176
generic_closure_test: RuntimeError
generic_constructor_mixin2_test/01: MissingCompileTimeError
generic_constructor_mixin3_test/01: MissingCompileTimeError
@@ -884,6 +883,8 @@
symbol_literal_test/01: MissingCompileTimeError
sync_generator1_test/01: MissingCompileTimeError
syntax_test/59: MissingCompileTimeError, OK # Issue 30516.
+syntax_test/60: MissingCompileTimeError, OK # Issue 30516.
+syntax_test/61: MissingCompileTimeError, OK # Issue 30516.
top_level_getter_no_setter1_test: MissingCompileTimeError
top_level_getter_no_setter2_test: MissingCompileTimeError
transitive_private_library_access_test: MissingCompileTimeError
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index af851e4..dc3c9fe 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -4,6 +4,16 @@
# Sections in this file should contain "$runtime == vm".
[ $compiler == dartkp ]
+assertion_initializer_const_error2_test/cc01: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc02: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc03: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc05: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc06: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc07: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc08: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time.
+assertion_initializer_const_error2_test/cc11: MissingCompileTimeError # Not reporting failed assert() at compile time.
implicit_creation/implicit_new_or_const_composite_test: RuntimeError
implicit_creation/implicit_new_or_const_test: RuntimeError
@@ -46,7 +56,6 @@
example_constructor_test: Fail, OK
export_ambiguous_main_negative_test: Fail # Issue 14763
field_initialization_order_test: Fail, OK
-generalized_void_syntax_test: CompileTimeError # Issue #30176
hello_dart_test: Skip # Incompatible flag: --compile_all
language_2/least_upper_bound_expansive_test/none: CompileTimeError
library_env_test/has_html_support: RuntimeError, OK
@@ -372,14 +381,31 @@
for_in3_test: MissingCompileTimeError
for_in_side_effects_test/01: MissingCompileTimeError
function_malformed_result_type_test/00: MissingCompileTimeError
+function_subtype_bound_closure1_test: RuntimeError
+function_subtype_bound_closure2_test: RuntimeError
function_subtype_bound_closure3_test: RuntimeError
function_subtype_bound_closure4_test: RuntimeError
+function_subtype_bound_closure5_test: RuntimeError
+function_subtype_bound_closure5a_test: RuntimeError
+function_subtype_bound_closure6_test: RuntimeError
function_subtype_bound_closure7_test: RuntimeError
function_subtype_call1_test: RuntimeError
function_subtype_call2_test: RuntimeError
function_subtype_cast1_test: RuntimeError
+function_subtype_cast2_test: RuntimeError
+function_subtype_cast3_test: RuntimeError
+function_subtype_checked0_test: RuntimeError
+function_subtype_local1_test: RuntimeError
+function_subtype_local2_test: RuntimeError
+function_subtype_local5_test: RuntimeError
+function_subtype_not0_test: RuntimeError
function_subtype_not1_test: RuntimeError
+function_subtype_not2_test: RuntimeError
+function_subtype_not3_test: RuntimeError
+function_subtype_top_level1_test: RuntimeError
function_subtype_typearg5_test: RuntimeError
+function_type_alias3_test: RuntimeError
+function_type_alias4_test: RuntimeError
function_type_alias_test: RuntimeError
function_type_call_getter2_test/00: MissingCompileTimeError
function_type_call_getter2_test/01: MissingCompileTimeError
@@ -411,6 +437,8 @@
generic_methods_unused_parameter_test: RuntimeError
generic_no_such_method_dispatcher_simple_test: Skip # This test is only for kernel.
generic_tearoff_test: RuntimeError
+generic_test/01: MissingCompileTimeError
+generic_test/none: RuntimeError # test requires Dart 2 subtyping for `is`
getter_no_setter2_test/00: MissingCompileTimeError
getter_no_setter2_test/01: MissingCompileTimeError
getter_no_setter2_test/03: MissingCompileTimeError
@@ -846,6 +874,8 @@
symbol_literal_test/01: MissingCompileTimeError
sync_generator1_test/01: MissingCompileTimeError
syntax_test/59: MissingCompileTimeError, OK # Issue 30516.
+syntax_test/60: MissingCompileTimeError, OK # Issue 30516.
+syntax_test/61: MissingCompileTimeError, OK # Issue 30516.
top_level_getter_no_setter1_test: MissingCompileTimeError
top_level_getter_no_setter2_test: MissingCompileTimeError
transitive_private_library_access_test: MissingCompileTimeError
@@ -1212,7 +1242,6 @@
example_constructor_test: Fail, OK
export_ambiguous_main_negative_test: Fail # Issue 14763
field_initialization_order_test: Fail, OK
-generalized_void_syntax_test: CompileTimeError # Issue #30176
generic_methods_bounds_test/02: MissingRuntimeError
library_env_test/has_html_support: RuntimeError, OK
library_env_test/has_no_io_support: RuntimeError, OK
diff --git a/tests/language_2/method_not_found_test.dart b/tests/language_2/method_not_found_test.dart
new file mode 100644
index 0000000..803f251
--- /dev/null
+++ b/tests/language_2/method_not_found_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {
+ B(); //# 01: compile-time error
+ static const field = const B();
+}
+
+class B {
+ const B();
+}
+
+main() {
+ print(A.field);
+}
diff --git a/tests/language_2/mixin_accessor_test.dart b/tests/language_2/mixin_accessor_test.dart
new file mode 100644
index 0000000..bb346e8
--- /dev/null
+++ b/tests/language_2/mixin_accessor_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Regression test case for DDC bug where if a getter/setter is mixed in
+// without a corresponding getter/setter, DDC fails to install a the
+// corresponding getter/setter that calls super.
+
+import "package:expect/expect.dart";
+
+abstract class C<E> {
+ E get first;
+ set first(E value);
+ E operator [](int index);
+ operator []=(int index, E value);
+}
+
+abstract class CMixin<E> implements C<E> {
+ E get first => this[0];
+ set first(E x) {
+ this[0] = x;
+ }
+}
+
+abstract class CBase<E> extends Object with CMixin<E> {}
+
+abstract class DMixin<E> implements C<E> {
+ set first(E _) => throw new UnsupportedError('');
+ operator []=(int index, E value) => throw new UnsupportedError('');
+}
+
+abstract class DBase<E> = CBase<E> with DMixin<E>;
+
+class DView<E> extends DBase<E> {
+ final Iterable<E> _source;
+ DView(this._source);
+ E operator [](int index) => _source.elementAt(index);
+}
+
+abstract class FMixin<E> implements C<E> {
+ E get first => throw new UnsupportedError('');
+ E operator [](int index) => throw new UnsupportedError('');
+}
+
+class FView<E> extends CBase<E> with FMixin<E> {
+ List<E> _values;
+ FView(this._values);
+ operator []=(int index, E value) {
+ _values[index] = value;
+ }
+}
+
+void main() {
+ var d = new DView([3]);
+ Expect.equals(3, d.first);
+ Expect.throws(() => d.first = 42, (e) => e is UnsupportedError);
+
+ var list = [3];
+ var f = new FView(list);
+ f.first = 42;
+ Expect.equals(42, list[0]);
+ Expect.throws(() => f.first, (e) => e is UnsupportedError);
+}
diff --git a/tests/language_2/super_call2_test.dart b/tests/language_2/super_call2_test.dart
index e3fd9dc..156d344 100644
--- a/tests/language_2/super_call2_test.dart
+++ b/tests/language_2/super_call2_test.dart
@@ -4,6 +4,10 @@
// Regresion test for bug discovered in frog handling super calls: the test case
// mixes generics, super calls, and purposely doesn't allocate the base type.
+//
+// Also is a regression test for https://github.com/dart-lang/sdk/issues/31973
+
+import 'package:expect/expect.dart';
class C<T> {
foo(T a) {}
@@ -15,7 +19,22 @@
}
}
+class A {
+ static int _value;
+ Function foo = (int x) => _value = x + 1;
+}
+
+class B extends A {
+ void m(int x) {
+ super.foo(x);
+ }
+}
+
main() {
var d = new D();
d.foo(null);
+
+ var b = new B();
+ b.m(41);
+ Expect.equals(42, A._value);
}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 2784f4c..e6defdc 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -12,6 +12,9 @@
mirrors/*: Skip # Issue 27929: Triage
[ $compiler == dart2analyzer ]
+convert/base64_test/01: CompileTimeError # int64
+convert/utf82_test: CompileTimeError # int64
+math/double_pow_test: CompileTimeError # int64
mirrors/generic_f_bounded_mixin_application_test: StaticWarning # Test Issue
mirrors/immutable_collections_test: StaticWarning, OK # Expect failure for any type of Iterable.
mirrors/inference_and_no_such_method_test: StaticWarning, OK # Expect to trigger noSuchMethod.
@@ -23,6 +26,7 @@
mirrors/repeated_private_anon_mixin_app_test: StaticWarning, OK # Intentional library name conflict.
profiler/metrics_num_test: Fail # Issue 20309
profiler/metrics_test: Fail # Issue 20309
+typed_data/int32x4_bigint_test: CompileTimeError # int64
[ $compiler == dart2js ]
async/schedule_microtask6_test: RuntimeError # global error handling is not supported. Issue 5958
diff --git a/tests/lib_2/async/async_await_sync_completer_test.dart b/tests/lib_2/async/async_await_sync_completer_test.dart
index b6887d6..889632f 100644
--- a/tests/lib_2/async/async_await_sync_completer_test.dart
+++ b/tests/lib_2/async/async_await_sync_completer_test.dart
@@ -13,6 +13,10 @@
var delayedError = new Completer();
foo() async {
+ // Because of this `await null` the function returns and lets the caller
+ // install handlers. When the function finishes, it can then synchronously
+ // propagate the values.
+ await null;
new Future.microtask(() => 'in microtask')
.then(events.add)
.then(delayedValue.complete);
@@ -20,6 +24,10 @@
}
bar() async {
+ // Because of this `await null` the function returns and lets the caller
+ // install handlers. When the function finishes, it can then synchronously
+ // propagate the values.
+ await null;
new Future.microtask(() => throw 'in microtask error')
.catchError(events.add)
.then(delayedError.complete);
diff --git a/tests/lib_2/async/future_or_strong_test.dart b/tests/lib_2/async/future_or_strong_test.dart
index d026233..f9f1ff9 100644
--- a/tests/lib_2/async/future_or_strong_test.dart
+++ b/tests/lib_2/async/future_or_strong_test.dart
@@ -53,10 +53,7 @@
void foo2(FutureOr<String> x) {}
- // In is-checks `dynamic` is treat specially (counting as bottom in parameter
- // positions).
- Expect.isTrue(foo2 is FunTakes<dynamic>);
-
+ Expect.isFalse(foo2 is FunTakes<dynamic>);
Expect.isFalse(foo2 is FunTakes<Object>);
Expect.isFalse(foo2 is FunTakes<int>);
Expect.isTrue(foo2 is FunTakes<String>);
@@ -86,10 +83,7 @@
void foo3(String x) {}
- // In is-checks `dynamic` is treat specially (counting as bottom in parameter
- // positions).
- Expect.isTrue(foo3 is FunTakes<dynamic>);
-
+ Expect.isFalse(foo3 is FunTakes<dynamic>);
Expect.isFalse(foo3 is FunTakes<Object>);
Expect.isFalse(foo3 is FunTakes<int>);
Expect.isTrue(foo3 is FunTakes<String>);
diff --git a/tests/lib_2/async/slow_consumer2_test.dart b/tests/lib_2/async/slow_consumer2_test.dart
index 6b1ab56..de37668 100644
--- a/tests/lib_2/async/slow_consumer2_test.dart
+++ b/tests/lib_2/async/slow_consumer2_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--old_gen_heap_size=64
+// VMOptions=--old_gen_heap_size=64 --no-background-compilation
library slow_consumer2_test;
diff --git a/tests/lib_2/async/slow_consumer3_test.dart b/tests/lib_2/async/slow_consumer3_test.dart
index 17de0e0..806f929 100644
--- a/tests/lib_2/async/slow_consumer3_test.dart
+++ b/tests/lib_2/async/slow_consumer3_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--old_gen_heap_size=64
+// VMOptions=--old_gen_heap_size=64 --no-background-compilation
library slow_consumer3_test;
diff --git a/tests/lib_2/async/slow_consumer_test.dart b/tests/lib_2/async/slow_consumer_test.dart
index 9a3c92e..2eaa8ef 100644
--- a/tests/lib_2/async/slow_consumer_test.dart
+++ b/tests/lib_2/async/slow_consumer_test.dart
@@ -2,7 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// VMOptions=--old_gen_heap_size=64
+// VMOptions=--old_gen_heap_size=64 --no-background-compilation
library slow_consumer_test;
diff --git a/tests/lib_2/async/stream_zones_test.dart b/tests/lib_2/async/stream_zones_test.dart
index d87eb94..6d4582e 100644
--- a/tests/lib_2/async/stream_zones_test.dart
+++ b/tests/lib_2/async/stream_zones_test.dart
@@ -186,7 +186,7 @@
test7(),
];
- Future.wait(tests.map((l) => l.first)).then((_) {
+ Future.wait(tests.map((l) => l.first as Future)).then((_) {
// Give time to complete all pending actions.
Timer.run(() {
tests.forEach((l) => (l.last)());
diff --git a/tests/lib_2/async/timer_cancel2_test.dart b/tests/lib_2/async/timer_cancel2_test.dart
index 0d992a5..7b3d0e2 100644
--- a/tests/lib_2/async/timer_cancel2_test.dart
+++ b/tests/lib_2/async/timer_cancel2_test.dart
@@ -5,19 +5,20 @@
library timer_cancel2_test;
import 'dart:async';
-
-import 'package:unittest/unittest.dart';
+import 'package:expect/expect.dart';
main() {
// Test that a timeout handler can cancel itself.
- test("timer cancel test 2", () {
- var cancelTimer;
+ var cancelTimer;
+ var completer = new Completer();
+ int calls = 0;
+ void cancelHandler(Timer timer) {
+ Expect.equals(1, ++calls);
+ cancelTimer.cancel();
+ completer.complete();
+ }
- void cancelHandler(Timer timer) {
- cancelTimer.cancel();
- }
-
- cancelTimer = new Timer.periodic(
- const Duration(milliseconds: 1), expectAsync(cancelHandler));
- });
+ cancelTimer =
+ new Timer.periodic(const Duration(milliseconds: 1), cancelHandler);
+ return completer.future;
}
diff --git a/tests/lib_2/async/timer_cancel_test.dart b/tests/lib_2/async/timer_cancel_test.dart
index a7c5a7a..55d8303 100644
--- a/tests/lib_2/async/timer_cancel_test.dart
+++ b/tests/lib_2/async/timer_cancel_test.dart
@@ -6,39 +6,48 @@
import 'dart:async';
-import 'package:unittest/unittest.dart';
+import 'package:expect/minitest.dart';
+
+final ms = const Duration(milliseconds: 1);
main() {
- final ms = const Duration(milliseconds: 1);
- test("simple timer", () {
- Timer cancelTimer;
- int repeatTimer;
+ return testSimpleTimer().then((_) => cancelTimerWithSame());
+}
- void unreachable() {
- fail("should not be reached");
- }
+Future testSimpleTimer() {
+ var cancelTimer = new Timer(ms * 1000, unreachable);
+ cancelTimer.cancel();
- void handler() {
- cancelTimer.cancel();
- }
-
- void repeatHandler(Timer timer) {
- repeatTimer++;
- timer.cancel();
- expect(repeatTimer, 1);
- }
-
- cancelTimer = new Timer(ms * 1000, expectAsync(unreachable, count: 0));
+ var handler = new Completer();
+ var repeatHandler = new Completer();
+ new Timer(ms * 1000, () {
cancelTimer.cancel();
- new Timer(ms * 1000, expectAsync(handler));
- cancelTimer = new Timer(ms * 2000, expectAsync(unreachable, count: 0));
- repeatTimer = 0;
- new Timer.periodic(ms * 1500, expectAsync(repeatHandler));
+ handler.complete();
});
- test("cancel timer with same time", () {
- var t2;
- var t1 = new Timer(ms * 0, expectAsync(() => t2.cancel()));
- t2 = new Timer(ms * 0, expectAsync(t1.cancel, count: 0));
+ cancelTimer = new Timer(ms * 2000, unreachable);
+ var repeatTimer = 0;
+ new Timer.periodic(ms * 1500, (Timer timer) {
+ repeatTimer++;
+ timer.cancel();
+ expect(repeatTimer, 1);
+ repeatHandler.complete();
});
+
+ return handler.future.then((_) => repeatHandler.future);
+}
+
+Future cancelTimerWithSame() {
+ var completer = new Completer();
+ var t2;
+ var t1 = new Timer(ms * 0, () {
+ t2.cancel();
+ completer.complete();
+ });
+ t2 = new Timer(ms * 0, unreachable);
+ return completer.future;
+}
+
+void unreachable() {
+ fail("should not be reached");
}
diff --git a/tests/lib_2/async/timer_isActive_test.dart b/tests/lib_2/async/timer_isActive_test.dart
index 1c272a6..25aa1dd 100644
--- a/tests/lib_2/async/timer_isActive_test.dart
+++ b/tests/lib_2/async/timer_isActive_test.dart
@@ -5,13 +5,22 @@
import 'dart:async';
import 'package:unittest/unittest.dart';
+import 'package:unittest/src/expected_function.dart' show ExpectedFunction;
+
+T Function() expectAsync0<T>(T Function() callback,
+ {int count: 1, int max: 0}) =>
+ new ExpectedFunction<T>(callback, count, max).max0;
+
+T Function(A) expectAsync1<T, A>(T Function(A) callback,
+ {int count: 1, int max: 0}) =>
+ new ExpectedFunction<T>(callback, count, max).max1;
main() {
test("timer isActive test", () {
Timer t;
t = new Timer(const Duration(seconds: 1),
- expectAsync(() => expect(t.isActive, equals(false))));
+ expectAsync0(() => expect(t.isActive, equals(false))));
expect(t.isActive, equals(true));
});
@@ -29,14 +38,14 @@
}
t = new Timer.periodic(
- new Duration(milliseconds: 1), expectAsync(checkActive, count: 3));
+ new Duration(milliseconds: 1), expectAsync1(checkActive, count: 3));
expect(t.isActive, equals(true));
});
test("timer cancel test", () {
Timer timer = new Timer(
const Duration(seconds: 15), () => fail("Should not be reached."));
- Timer.run(expectAsync(() {
+ Timer.run(expectAsync0(() {
expect(timer.isActive, equals(true));
timer.cancel();
expect(timer.isActive, equals(false));
diff --git a/tests/lib_2/async/timer_repeat_test.dart b/tests/lib_2/async/timer_repeat_test.dart
index 71d26fa..afe1957 100644
--- a/tests/lib_2/async/timer_repeat_test.dart
+++ b/tests/lib_2/async/timer_repeat_test.dart
@@ -6,7 +6,7 @@
import 'dart:async';
-import 'package:unittest/unittest.dart';
+import 'package:expect/expect.dart';
const Duration TIMEOUT = const Duration(milliseconds: 500);
const int ITERATIONS = 5;
@@ -20,25 +20,26 @@
// compiled by dart2js.
int get safetyMargin => identical(1, 1.0) ? 100 : 0;
+var completer = new Completer();
+
void timeoutHandler(Timer timer) {
iteration++;
- expect(iteration, lessThanOrEqualTo(ITERATIONS));
+ Expect.isTrue(iteration <= ITERATIONS);
if (iteration == ITERATIONS) {
// When we are done with all of the iterations, we expect a
// certain amount of time to have passed. Checking the time on
// each iteration doesn't work because the timeoutHandler runs
// concurrently with the periodic timer.
- expect(stopwatch.elapsedMilliseconds + safetyMargin,
- greaterThanOrEqualTo(ITERATIONS * TIMEOUT.inMilliseconds));
+ Expect.isTrue(stopwatch.elapsedMilliseconds + safetyMargin >=
+ ITERATIONS * TIMEOUT.inMilliseconds);
timer.cancel();
+ completer.complete();
}
}
main() {
- test("timer_repeat", () {
- iteration = 0;
- stopwatch.start();
- timer = new Timer.periodic(
- TIMEOUT, expectAsync(timeoutHandler, count: ITERATIONS));
- });
+ iteration = 0;
+ stopwatch.start();
+ timer = new Timer.periodic(TIMEOUT, timeoutHandler);
+ return completer.future;
}
diff --git a/tests/lib_2/async/zone_run_unary_test.dart b/tests/lib_2/async/zone_run_unary_test.dart
index 03f9548..ebf78ee 100644
--- a/tests/lib_2/async/zone_run_unary_test.dart
+++ b/tests/lib_2/async/zone_run_unary_test.dart
@@ -13,12 +13,13 @@
bool shouldForward = true;
Expect.identical(Zone.root, Zone.current);
Zone forked = Zone.current.fork(specification: new ZoneSpecification(runUnary:
- <R, T>(Zone self, ZoneDelegate parent, Zone origin, R f(arg), T arg) {
+ <R, T>(Zone self, ZoneDelegate parent, Zone origin, R f(T arg), T arg) {
// The zone is still the same as when origin.run was invoked, which
// is the root zone. (The origin zone hasn't been set yet).
Expect.identical(Zone.current, Zone.root);
events.add("forked.run1");
- if (shouldForward) return parent.runUnary(origin, f, (arg as int) + 1);
+ if (shouldForward)
+ return parent.runUnary<R, T>(origin, f, ((arg as int) + 1) as T);
return 42 as R;
}));
diff --git a/tests/lib_2/html/cross_domain_iframe_test.dart b/tests/lib_2/html/cross_domain_iframe_test.dart
index 9feee15..3b7cf7f 100644
--- a/tests/lib_2/html/cross_domain_iframe_test.dart
+++ b/tests/lib_2/html/cross_domain_iframe_test.dart
@@ -3,30 +3,27 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:html';
-
-import 'package:unittest/unittest.dart';
+import 'package:expect/minitest.dart';
main() {
- test('cross_domain_iframe', () {
- var uri = Uri.parse(window.location.href);
+ var uri = Uri.parse(window.location.href);
- var crossOriginPort = int.parse(uri.queryParameters['crossOriginPort']);
- var crossOrigin = '${uri.scheme}://${uri.host}:$crossOriginPort';
- var crossOriginUrl =
- '$crossOrigin/root_dart/tests/html/cross_domain_iframe_script.html';
+ var crossOriginPort = int.parse(uri.queryParameters['crossOriginPort']);
+ var crossOrigin = '${uri.scheme}://${uri.host}:$crossOriginPort';
+ var crossOriginUrl =
+ '$crossOrigin/root_dart/tests/html/cross_domain_iframe_script.html';
- var iframe = new IFrameElement();
- iframe.src = crossOriginUrl;
- document.body.append(iframe);
+ var iframe = new IFrameElement();
+ iframe.src = crossOriginUrl;
+ document.body.append(iframe);
- window.onMessage
- .where((MessageEvent event) {
- return event.origin == crossOrigin;
- })
- .first
- .then(expectAsync((MessageEvent event) {
- expect(event.data, equals('foobar'));
- expect(event.source, isNotNull);
- }));
- });
+ return window.onMessage
+ .where((MessageEvent event) {
+ return event.origin == crossOrigin;
+ })
+ .first
+ .then((MessageEvent event) {
+ expect(event.data, equals('foobar'));
+ expect(event.source, isNotNull);
+ });
}
diff --git a/tests/lib_2/html/element_test.dart b/tests/lib_2/html/element_test.dart
index 25967d3..366b98d 100644
--- a/tests/lib_2/html/element_test.dart
+++ b/tests/lib_2/html/element_test.dart
@@ -6,11 +6,16 @@
import 'package:unittest/unittest.dart';
import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/src/expected_function.dart' show ExpectedFunction;
import 'dart:async';
import 'dart:html';
import 'dart:svg' as svg;
import 'utils.dart';
+T Function(A) expectAsync1<T, A>(T Function(A) callback,
+ {int count: 1, int max: 0}) =>
+ new ExpectedFunction<T>(callback, count, max).max1;
+
expectLargeRect(Rectangle rect) {
expect(rect.top, 0);
expect(rect.left, 0);
@@ -126,7 +131,8 @@
test('.html caption', () {
var table = new TableElement();
- TableCaptionElement node = table.createFragment('<caption><p>Table 1.').nodes.single;
+ TableCaptionElement node =
+ table.createFragment('<caption><p>Table 1.').nodes.single;
expect(
node,
predicate(
@@ -150,7 +156,8 @@
test('.html tbody', () {
var innerHtml = '<tr><td headers="n r1">Sad</td><td>Happy</td></tr>';
var table = new TableElement();
- TableSectionElement node = table.createFragment('<tbody>$innerHtml').nodes.single;
+ TableSectionElement node =
+ table.createFragment('<tbody>$innerHtml').nodes.single;
expect(
node,
predicate(
@@ -165,7 +172,8 @@
test('.html thead', () {
var innerHtml = '<tr><th id="n">Negative</th><th>Positive</th></tr>';
var table = new TableElement();
- TableSectionElement node = table.createFragment('<thead>$innerHtml').nodes.single;
+ TableSectionElement node =
+ table.createFragment('<thead>$innerHtml').nodes.single;
expect(
node,
predicate(
@@ -180,7 +188,8 @@
test('.html tfoot', () {
var innerHtml = '<tr><th>percentage</th><td>34.3%</td></tr>';
var table = new TableElement();
- TableSectionElement node = table.createFragment('<tfoot>$innerHtml').nodes.single;
+ TableSectionElement node =
+ table.createFragment('<tfoot>$innerHtml').nodes.single;
expect(
node,
predicate(
@@ -196,7 +205,8 @@
var table = new TableElement();
document.body.append(table);
var tBody = table.createTBody();
- TableRowElement node = tBody.createFragment('<tr><td>foo<td>bar').nodes.single;
+ TableRowElement node =
+ tBody.createFragment('<tr><td>foo<td>bar').nodes.single;
expect(
node, predicate((x) => x is TableRowElement, 'is a TableRowElement'));
expect(node.tagName, 'TR');
@@ -801,7 +811,7 @@
document.body.onClick
.matches('.selector')
- .listen(expectAsync((Event event) {
+ .listen(expectAsync1((Event event) {
expect(event.currentTarget, document.body);
expect(event.target, clickOne);
expect(event.matchingTarget, selectorOne);
@@ -809,7 +819,7 @@
selectorOne.onClick
.matches('.selector')
- .listen(expectAsync((Event event) {
+ .listen(expectAsync1((Event event) {
expect(event.currentTarget, selectorOne);
expect(event.target, clickOne);
expect(event.matchingTarget, selectorOne);
diff --git a/tests/lib_2/html/events_test.dart b/tests/lib_2/html/events_test.dart
index 43a6737..ef7e22e 100644
--- a/tests/lib_2/html/events_test.dart
+++ b/tests/lib_2/html/events_test.dart
@@ -8,6 +8,15 @@
import 'dart:html';
import 'package:unittest/unittest.dart';
import 'package:unittest/html_config.dart';
+import 'package:unittest/src/expected_function.dart' show ExpectedFunction;
+
+T Function() expectAsync0<T>(T Function() callback,
+ {int count: 1, int max: 0}) =>
+ new ExpectedFunction<T>(callback, count, max).max0;
+
+T Function(A) expectAsync1<T, A>(T Function(A) callback,
+ {int count: 1, int max: 0}) =>
+ new ExpectedFunction<T>(callback, count, max).max1;
main() {
useHtmlConfiguration();
@@ -97,7 +106,7 @@
// runZoned executes the function synchronously, but we don't want to
// rely on this. We therefore wrap it into an expectAsync.
- runZoned(expectAsync(() {
+ runZoned(expectAsync0(() {
var zone = Zone.current;
expect(zone, isNot(equals(Zone.root)));
@@ -106,13 +115,13 @@
void handler(Event e) {
expect(Zone.current, equals(zone));
- scheduleMicrotask(expectAsync(() {
+ scheduleMicrotask(expectAsync0(() {
expect(Zone.current, equals(zone));
sub.cancel();
}));
}
- sub = element.on['test'].listen(expectAsync(handler));
+ sub = element.on['test'].listen(expectAsync1(handler));
}));
element.dispatchEvent(new Event('test'));
});
diff --git a/tests/lib_2/html/file_sample_test.dart b/tests/lib_2/html/file_sample_test.dart
index 30c037d..51f846d 100644
--- a/tests/lib_2/html/file_sample_test.dart
+++ b/tests/lib_2/html/file_sample_test.dart
@@ -129,7 +129,7 @@
expect(fileEntry.name, 'log.txt');
List<Entry> entries = await readEntries(fs.root);
- expect(entries.length, 1);
+ expect(entries.length > 0, true);
expect(entries[0].isDirectory, true);
expect(entries[0].name, 'my_directory');
diff --git a/tests/lib_2/html/fileapi_directory_reader_test.dart b/tests/lib_2/html/fileapi_directory_reader_test.dart
index 9d626ea..ea6280c 100644
--- a/tests/lib_2/html/fileapi_directory_reader_test.dart
+++ b/tests/lib_2/html/fileapi_directory_reader_test.dart
@@ -1,10 +1,11 @@
library fileapi;
-import 'dart:html';
import 'dart:async';
+import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
class FileAndDir {
FileEntry file;
@@ -14,37 +15,30 @@
FileSystem fs;
-main() {
- useHtmlIndividualConfiguration();
+main() async {
+ useHtmlConfiguration();
- getFileSystem() {
- return window.requestFileSystem(100).then((FileSystem fileSystem) {
- fs = fileSystem;
- });
+ getFileSystem() async {
+ var fileSystem = await window.requestFileSystem(100);
+ fs = fileSystem;
}
// Do the boilerplate to get several files and directories created to then
// test the functions that use those items.
- Future doDirSetup(String testName) {
- return fs.root.createFile('file_$testName').then((Entry file) {
- return fs.root
- .createDirectory('dir_$testName')
- .then((Entry dir) {
- return new Future.value(new FileAndDir(file, dir));
- });
- });
+ Future doDirSetup(String testName) async {
+ await getFileSystem();
+
+ var file = await fs.root.createFile('file_$testName');
+ var dir = await fs.root.createDirectory('dir_$testName');
+ return new Future.value(new FileAndDir(file, dir));
}
if (FileSystem.supported) {
- test('getFileSystem', getFileSystem);
-
- test('readEntries', () {
- return doDirSetup('readEntries').then((fileAndDir) {
- var reader = fileAndDir.dir.createReader();
- return reader.readEntries();
- }).then((entries) {
- expect(entries is List, true);
- });
+ test('readEntries', () async {
+ var fileAndDir = await doDirSetup('readEntries');
+ var reader = await fileAndDir.dir.createReader();
+ var entries = await reader.readEntries();
+ expect(entries is List, true);
});
}
}
diff --git a/tests/lib_2/html/fileapi_directory_test.dart b/tests/lib_2/html/fileapi_directory_test.dart
index 935dd03..6dda69a 100644
--- a/tests/lib_2/html/fileapi_directory_test.dart
+++ b/tests/lib_2/html/fileapi_directory_test.dart
@@ -4,7 +4,8 @@
import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
class FileAndDir {
FileEntry file;
@@ -14,28 +15,29 @@
FileSystem fs;
-main() {
- useHtmlIndividualConfiguration();
+main() async {
+ useHtmlConfiguration();
- getFileSystem() {
- return window.requestFileSystem(100).then((FileSystem fileSystem) {
- fs = fileSystem;
- });
+ getFileSystem() async {
+ var fileSystem = await window.requestFileSystem(100);
+ fs = fileSystem;
}
if (FileSystem.supported) {
- test('getFileSystem', getFileSystem);
+ await getFileSystem();
- test('directoryDoesntExist', () {
- return fs.root.getDirectory('directory2').catchError((error) {
- expect(error.code, equals(FileError.NOT_FOUND_ERR));
- }, test: (e) => e is FileError);
+ test('directoryDoesntExist', () async {
+ try {
+ await fs.root.getDirectory('directory2');
+ } catch (error) {
+ expect(true, error is DomException);
+ expect(DomException.NOT_FOUND, error.name);
+ }
});
- test('directoryCreate', () {
- return fs.root.createDirectory('directory3').then((Entry e) {
- expect(e.name, equals('directory3'));
- });
+ test('directoryCreate', () async {
+ var entry = await fs.root.createDirectory('directory3');
+ expect(entry.name, equals('directory3'));
});
}
}
diff --git a/tests/lib_2/html/fileapi_entry_test.dart b/tests/lib_2/html/fileapi_entry_test.dart
index 7d79a0e..8d8ece0 100644
--- a/tests/lib_2/html/fileapi_entry_test.dart
+++ b/tests/lib_2/html/fileapi_entry_test.dart
@@ -1,10 +1,11 @@
library fileapi;
-import 'dart:html';
import 'dart:async';
+import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
class FileAndDir {
FileEntry file;
@@ -14,65 +15,63 @@
FileSystem fs;
-main() {
- useHtmlIndividualConfiguration();
+main() async {
+ useHtmlConfiguration();
- getFileSystem() {
- return window.requestFileSystem(100).then((FileSystem fileSystem) {
+ getFileSystem() async {
+ return await window.requestFileSystem(100).then((FileSystem fileSystem) {
fs = fileSystem;
});
}
// Do the boilerplate to get several files and directories created to then
// test the functions that use those items.
- Future doDirSetup(String testName) {
- return fs.root.createFile('file_$testName').then((Entry file) {
- return fs.root
- .createDirectory('dir_$testName')
- .then((Entry dir) {
- return new Future.value(new FileAndDir(file, dir));
- });
- });
+ Future doDirSetup(String testName) async {
+ await getFileSystem();
+
+ var file = await fs.root.createFile('file_$testName');
+ var dir = await fs.root.createDirectory('dir_$testName');
+ return new Future.value(new FileAndDir(file, dir));
}
if (FileSystem.supported) {
- test('getFileSystem', getFileSystem);
+ test('copy_move', () async {
+ var fileAndDir = await doDirSetup('copyTo');
+ var entry = await fileAndDir.file.copyTo(fileAndDir.dir, name: 'copiedFile');
+ expect(entry.isFile, true, reason: "Expected File");
+ expect(entry.name, 'copiedFile');
- test('copyTo', () {
- return doDirSetup('copyTo').then((fileAndDir) {
- return fileAndDir.file.copyTo(fileAndDir.dir, name: 'copiedFile');
- }).then((entry) {
- expect(entry.isFile, true);
- expect(entry.name, 'copiedFile');
- });
- });
+ // getParent
+ fileAndDir = await doDirSetup('getParent');
+ entry = await fileAndDir.file.getParent();
+ expect(entry.name, '');
+ expect(entry.isDirectory, true, reason: "Expected Directory");
- test('getParent', () {
- return doDirSetup('getParent').then((fileAndDir) {
- return fileAndDir.file.getParent();
- }).then((entry) {
- expect(entry.name, '');
- expect(entry.isFile, false);
- });
- });
+ // moveTo
+ fileAndDir = await doDirSetup('moveTo');
+ entry = await fileAndDir.file.moveTo(fileAndDir.dir, name: 'movedFile');
+ expect(entry.name, 'movedFile');
+ expect(entry.fullPath, '/dir_moveTo/movedFile');
- test('moveTo', () {
- return doDirSetup('moveTo').then((fileAndDir) {
- return fileAndDir.file.moveTo(fileAndDir.dir, name: 'movedFile');
- }).then((entry) {
- expect(entry.name, 'movedFile');
- expect(entry.fullPath, '/dir_moveTo/movedFile');
- return fs.root.getFile('file4');
- }).catchError((error) {
- expect(error.code, equals(FileError.NOT_FOUND_ERR));
- }, test: (e) => e is FileError);
- });
+ try {
+ entry = await fs.root.getFile('file4');
+ fail("File file4 should not exist.");
+ } catch (error) {
+ expect(error is DomException, true, reason: "Not DomException - not exist");
+ expect(DomException.NOT_FOUND, error.name);
+ }
- test('remove', () {
- return doDirSetup('remove').then((fileAndDir) {
- return fileAndDir.file.remove().then((_) {});
- });
+ // remove
+ fileAndDir = await doDirSetup('remove');
+ expect('file_remove', fileAndDir.file.name);
+ await fileAndDir.file.remove();
+ try {
+ var entry = await fileAndDir.dir.getFile(fileAndDir.file.name);
+ fail("file not removed");
+ } catch (error) {
+ expect(error is DomException, true, reason: "Not DomException - removed");
+ expect(DomException.NOT_FOUND, error.name);
+ }
});
}
}
-
diff --git a/tests/lib_2/html/fileapi_file_entry_test.dart b/tests/lib_2/html/fileapi_file_entry_test.dart
index 495fefe..a047a01 100644
--- a/tests/lib_2/html/fileapi_file_entry_test.dart
+++ b/tests/lib_2/html/fileapi_file_entry_test.dart
@@ -1,10 +1,11 @@
library fileapi;
-import 'dart:html';
import 'dart:async';
+import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
class FileAndDir {
FileEntry file;
@@ -14,52 +15,40 @@
FileSystem fs;
-main() {
- useHtmlIndividualConfiguration();
+main() async {
+ useHtmlConfiguration();
- getFileSystem() {
- return window.requestFileSystem(100).then((FileSystem fileSystem) {
- fs = fileSystem;
- });
+ getFileSystem() async {
+ var fileSystem = await window.requestFileSystem(100);
+ fs = fileSystem;
}
// Do the boilerplate to get several files and directories created to then
// test the functions that use those items.
- Future doDirSetup(String testName) {
- return fs.root.createFile('file_$testName').then((Entry file) {
- return fs.root
- .createDirectory('dir_$testName')
- .then((Entry dir) {
- return new Future.value(new FileAndDir(file, dir));
- });
- });
+ Future doDirSetup(String testName) async {
+ await getFileSystem();
+
+ var file = await fs.root.createFile('file_$testName');
+ var dir = await fs.root.createDirectory('dir_$testName');
+ return new Future.value(new FileAndDir(file, dir));
}
if (FileSystem.supported) {
- test('getFileSystem', getFileSystem);
-
- test('createWriter', () {
- return doDirSetup('createWriter').then((fileAndDir) {
- return fileAndDir.file.createWriter();
- }).then((writer) {
- expect(writer.position, 0);
- expect(writer.readyState, FileWriter.INIT);
- expect(writer.length, 0);
- });
+ test('createWriter', () async {
+ var fileAndDir = await doDirSetup('createWriter');
+ var writer = await fileAndDir.file.createWriter();
+ expect(writer.position, 0);
+ expect(writer.readyState, FileWriter.INIT);
+ expect(writer.length, 0);
});
- test('file', () {
- return doDirSetup('file').then((fileAndDir) {
- return fileAndDir.file.file().then((fileObj) {
- expect(fileObj.name, fileAndDir.file.name);
- expect(fileObj.relativePath, '');
- expect(
- new DateTime.now()
- .difference(fileObj.lastModifiedDate)
- .inSeconds,
- lessThan(60));
- });
- });
+ test('file', () async {
+ var fileAndDir = await doDirSetup('file');
+ var fileObj = await fileAndDir.file.file();
+ expect(fileObj.name, fileAndDir.file.name);
+ expect(fileObj.relativePath, '');
+ expect(new DateTime.now().difference(fileObj.lastModifiedDate).inSeconds,
+ lessThan(60));
});
}
}
diff --git a/tests/lib_2/html/fileapi_file_test.dart b/tests/lib_2/html/fileapi_file_test.dart
index d1c9404..3511ec3 100644
--- a/tests/lib_2/html/fileapi_file_test.dart
+++ b/tests/lib_2/html/fileapi_file_test.dart
@@ -4,47 +4,43 @@
import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
-
-class FileAndDir {
- FileEntry file;
- DirectoryEntry dir;
- FileAndDir(this.file, this.dir);
-}
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
FileSystem fs;
-main() {
- useHtmlIndividualConfiguration();
+main() async {
+ useHtmlConfiguration();
- getFileSystem() {
- return window.requestFileSystem(100).then((FileSystem fileSystem) {
- fs = fileSystem;
- });
+ getFileSystem() async {
+ var fileSystem = await window.requestFileSystem(100);
+ fs = fileSystem;
}
if (FileSystem.supported) {
- test('getFileSystem', getFileSystem);
+ await getFileSystem();
- test('fileDoesntExist', () {
- return fs.root.getFile('file2').catchError((error) {
- expect(error.code, equals(FileError.NOT_FOUND_ERR));
- }, test: (e) => e is FileError);
+ test('fileDoesntExist', () async {
+ try {
+ var fileObj = await fs.root.getFile('file2');
+ fail("file found");
+ } catch (error) {
+ expect(true, error is DomException);
+ expect(DomException.NOT_FOUND, error.name);
+ }
});
- test('fileCreate', () {
- return fs.root.createFile('file4').then((Entry e) {
- expect(e.name, equals('file4'));
- expect(e.isFile, isTrue);
- return e.getMetadata();
- }).then((Metadata metadata) {
- var changeTime = metadata.modificationTime;
- // Upped because our Windows buildbots can sometimes be particularly
- // slow.
- expect(
- new DateTime.now().difference(changeTime).inMinutes, lessThan(4));
- expect(metadata.size, equals(0));
- });
+ test('fileCreate', () async {
+ var fileObj = await fs.root.createFile('file4');
+ expect(fileObj.name, equals('file4'));
+ expect(fileObj.isFile, isTrue);
+
+ var metadata = await fileObj.getMetadata();
+ var changeTime = metadata.modificationTime;
+
+ // Increased Windows buildbots can sometimes be particularly slow.
+ expect(new DateTime.now().difference(changeTime).inMinutes, lessThan(4));
+ expect(metadata.size, equals(0));
});
}
}
diff --git a/tests/lib_2/html/fileapi_supported_throws_test.dart b/tests/lib_2/html/fileapi_supported_throws_test.dart
index 53afeb7..02e1d65 100644
--- a/tests/lib_2/html/fileapi_supported_throws_test.dart
+++ b/tests/lib_2/html/fileapi_supported_throws_test.dart
@@ -1,17 +1,19 @@
library fileapi;
+import 'dart:async';
import 'dart:html';
import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:unittest/html_config.dart';
+import 'package:async_helper/async_helper.dart';
main() {
- useHtmlIndividualConfiguration();
+ useHtmlConfiguration();
- test('requestFileSystem', () {
+ test('requestFileSystem', () async {
var expectation = FileSystem.supported ? returnsNormally : throws;
- expect(() {
- window.requestFileSystem(100);
+ expect(() async {
+ await window.requestFileSystem(100);
}, expectation);
});
}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 6e09990..b909ec3 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -15,11 +15,6 @@
html/custom/entered_left_view_test/shadow_dom: Pass, Timeout # Roll 50 failure
html/custom_elements_test: Pass, Timeout # Issue 26789
html/debugger_test: CompileTimeError # Issue 30900
-html/fileapi_directory_reader_test: Pass, Timeout # Roll 50 failure
-html/fileapi_directory_test: Pass, Timeout # Roll 50 failure
-html/fileapi_entry_test: Pass, Timeout # Roll 50 failure
-html/fileapi_file_entry_test: Pass, Timeout # Roll 50 failure
-html/fileapi_file_test: Pass, Timeout # Roll 50 failure
html/indexeddb_1_test/functional: Pass, Timeout # Roll 50 failure
html/indexeddb_2_test: Pass, Timeout # Roll 50 failure
html/indexeddb_3_test: Pass, Timeout # Roll 50 failure
@@ -85,9 +80,6 @@
html/element_classes_test: RuntimeError # Issue 30291
html/element_types_keygen_test: RuntimeError # Issue 29055
html/file_sample_test: Pass, RuntimeError
-html/fileapi_directory_test: Fail # TODO(dart2js-team): Please triage this failure.
-html/fileapi_entry_test: Pass, Fail # TODO(dart2js-team): Please triage this failure.
-html/fileapi_file_test: Fail # TODO(dart2js-team): Please triage this failure.
html/media_stream_test: RuntimeError # Please triage.
html/speechrecognition_test: RuntimeError # Please triage.
isolate/function_send_test: Skip # Crashes Chrome 62: https://bugs.chromium.org/p/chromium/issues/detail?id=775506
@@ -166,7 +158,6 @@
html/dart_object_local_storage_test: Skip # sessionStorage NS_ERROR_DOM_NOT_SUPPORTED_ERR
html/element_animate_test/timing_dict: RuntimeError # Issue 26730
html/element_classes_test: RuntimeError # Issue 27535
-html/element_types_constructors4_test: RuntimeError
html/element_types_content_test: Pass, RuntimeError # Issues 28983, 29922
html/element_types_keygen_test: RuntimeError # Issue 29922
html/element_types_keygen_test: Fail
@@ -269,6 +260,7 @@
html/element_types_datalist_test: RuntimeError # Issue 29922
html/element_types_shadow_test: RuntimeError # Issue 29922
html/file_sample_test: Skip # FileSystem not supported on Safari.
+html/fileapi_supported_throws_test: skip # FileSystem not supported on Safari
isolate/cross_isolate_message_test: Skip # Issue 12627
isolate/message_test: Skip # Issue 12627
@@ -279,6 +271,7 @@
html/custom/created_callback_test: RuntimeError
html/fontface_loaded_test: Fail # Support for promises.
html/js_typed_interop_lazy_test/01: RuntimeError
+html/notification_permission_test: Timeout, Pass # Issue 32002
html/private_extension_member_test: RuntimeError
isolate/isolate_stress_test: Pass, Slow # Issue 10697
js/null_test: RuntimeError # Issue 30652
@@ -575,11 +568,6 @@
html/event_customevent_test: RuntimeError
html/event_test: RuntimeError
html/exceptions_test: RuntimeError
-html/fileapi_directory_reader_test: RuntimeError
-html/fileapi_directory_test: RuntimeError
-html/fileapi_entry_test: RuntimeError
-html/fileapi_file_entry_test: RuntimeError
-html/fileapi_file_test: RuntimeError
html/fileapi_supported_test: RuntimeError
html/filereader_test: RuntimeError
html/filteredelementlist_test: RuntimeError
@@ -772,10 +760,6 @@
isolate/kill_self_synchronously_test: RuntimeError
[ $compiler == dart2js && ($runtime == d8 || $runtime == jsshell) ]
-html/fileapi_directory_test: Fail, Pass # TODO(dart2js-team): Please triage this failure.
-html/fileapi_entry_test: Fail, Pass # TODO(dart2js-team): Please triage this failure.
-html/fileapi_file_entry_test: Fail, Pass # TODO(dart2js-team): Please triage this failure.
-html/fileapi_file_test: Fail, Pass # TODO(dart2js-team): Please triage this failure.
isolate/browser/issue_12474_test: RuntimeError # packageRoot not implemented.
[ $compiler == dart2js && ($runtime == ff || $runtime == safari || $ie) ]
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index 17f16aa..8afe594 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -4,13 +4,12 @@
[ $compiler == dartdevc ]
async/futures_test: RuntimeError # Issue 29922
+html/cross_frame_test: Skip # Issue 32039, test reloads itself (not by design - investigate)
html/xhr_test/xhr: RuntimeError # Issue 29922, strong mode cast failure
[ $compiler == dartdevk ]
-async/future_or_strong_test: RuntimeError
async/future_value_chain4_test: CompileTimeError
async/slow_consumer_test: CompileTimeError
-async/zone_run_unary_test: CompileTimeError # Issue 31537
collection/list_test: RuntimeError
convert/chunked_conversion1_test: RuntimeError
convert/chunked_conversion_utf82_test: RuntimeError
@@ -106,6 +105,7 @@
html/media_stream_test: RuntimeError # Issue 29922
html/mediasource_test: RuntimeError # Issue 29922
html/no_linked_scripts_htmltest: Skip # Issue 29919
+html/notification_permission_test: Timeout # Issue 32002
html/scripts_htmltest: Skip # Issue 29919
html/transferables_test: CompileTimeError # Issue 30975
html/transition_event_test: Pass, RuntimeError, Timeout # Issue 29922, this test seems flaky
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index de400ed..6c52840 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -45,18 +45,12 @@
# ===== dartk + vm status lines =====
[ $compiler == dartk && $runtime == vm && $strong ]
async/async_await_sync_completer_test: RuntimeError
-async/future_or_strong_test: RuntimeError
async/future_value_chain4_test: CompileTimeError # Issue 31616
async/slow_consumer2_test: CompileTimeError # Issue 31402 (Invocation arguments)
async/stream_controller_async_test: CompileTimeError # Issue 31402 (Invocation arguments)
async/stream_join_test: CompileTimeError # Issue 31402 (Invocation arguments)
async/stream_subscription_as_future_test: CompileTimeError # Issue 31402 (Invocation arguments)
-async/timer_cancel2_test: CompileTimeError # Issue 31402 (Invocation arguments)
-async/timer_cancel_test: CompileTimeError # Issue 31402 (Invocation arguments)
-async/timer_isActive_test: CompileTimeError # Issue 31402 (Invocation arguments)
async/timer_not_available_test: RuntimeError
-async/timer_repeat_test: CompileTimeError # Issue 31402 (Invocation arguments)
-async/zone_run_unary_test: CompileTimeError # Issue 31537
convert/streamed_conversion_json_utf8_decode_test: Pass, Slow # Infrequent timeouts.
html/*: SkipByDesign # dart:html not supported on VM.
isolate/compile_time_error_test/01: MissingCompileTimeError
@@ -216,11 +210,6 @@
async/stream_distinct_test: RuntimeError
async/stream_join_test: RuntimeError
async/stream_subscription_as_future_test: RuntimeError
-async/timer_cancel2_test: RuntimeError
-async/timer_cancel_test: RuntimeError
-async/timer_isActive_test: RuntimeError
-async/timer_repeat_test: RuntimeError
-async/zone_run_unary_test: RuntimeError
isolate/issue_22778_test: Crash
isolate/kill_self_synchronously_test: RuntimeError
isolate/message_test: RuntimeError
@@ -284,14 +273,13 @@
# are to be triaged. Isolate tests are skipped on purpose due to the usage of
# batch mode.
[ $compiler == dartk && $strong && ($arch == simarm || $arch == simarm64 || $arch == simdbc64) ]
-isolate/count_test: RuntimeError
isolate/cross_isolate_message_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
isolate/error_at_spawnuri_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
isolate/error_exit_at_spawnuri_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
isolate/exit_at_spawnuri_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
isolate/issue_21398_parent_isolate_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
isolate/issue_24243_parent_isolate_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
-isolate/mandel_isolate_test: RuntimeError
+isolate/mandel_isolate_test: Pass, Timeout
isolate/message2_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
isolate/nested_spawn2_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
isolate/nested_spawn_test: Skip # No support for Isolate.spawnUri in batch-mode atm.
@@ -323,7 +311,6 @@
# ===== dartkp + dart_precompiled status lines =====
[ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
async/async_await_sync_completer_test: RuntimeError
-async/future_or_strong_test: RuntimeError
async/future_test/01: RuntimeError
async/future_test/none: RuntimeError
async/future_value_chain4_test: CompileTimeError # Issue 31616
@@ -332,12 +319,7 @@
async/stream_distinct_test: RuntimeError
async/stream_join_test: RuntimeError
async/stream_subscription_as_future_test: RuntimeError
-async/timer_cancel2_test: RuntimeError
-async/timer_cancel_test: RuntimeError
-async/timer_isActive_test: RuntimeError
async/timer_not_available_test: RuntimeError
-async/timer_repeat_test: RuntimeError
-async/zone_run_unary_test: CompileTimeError # Issue 31537
html/*: SkipByDesign # dart:html not supported on VM.
isolate/compile_time_error_test/01: Crash
isolate/compile_time_error_test/01: MissingCompileTimeError
diff --git a/tools/VERSION b/tools/VERSION
index 8d5ddec..64a9361 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 0
PATCH 0
-PRERELEASE 20
+PRERELEASE 21
PRERELEASE_PATCH 0
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index f71c0a7..0d597fd 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -249,7 +249,11 @@
},
{
"name": "front-end tests",
- "arguments": ["--compiler=none", "--checked"],
+ "arguments": [
+ "--compiler=none",
+ "--checked",
+ "--timeout=120"
+ ],
"tests": ["pkg/front_end"]
},
{
@@ -731,10 +735,15 @@
"dart2js-win-x64-ie11"
],
"meta": {
- "description": "These builders are triggered by dart-sdk-linux and runs the dart2js tests."
+ "description": "These builders run dart2js tests."
},
"steps": [
{
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["create_sdk"]
+ },
+ {
"name": "dart2js tests",
"arguments": [
"--use-sdk",
@@ -852,10 +861,15 @@
{
"builders": ["dart2js-minified-linux-x64-d8"],
"meta": {
- "description": "This builder is triggered by dart-sdk-linux and runs the dart2js tests with minified."
+ "description": "This builder runs the dart2js tests in minified mode."
},
"steps": [
{
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["create_sdk"]
+ },
+ {
"name": "dart2js tests",
"arguments": [
"--use-sdk",
@@ -983,10 +997,15 @@
{
"builders": ["dart2js-csp-minified-linux-x64-drt"],
"meta": {
- "description": "This builder is triggered by dart-sdk-linux and runs the dart2js tests with csp and minified."
+ "description": "This builder runs the dart2js tests in csp and minified mode."
},
"steps": [
{
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["create_sdk"]
+ },
+ {
"name": "dart2js tests",
"arguments": [
"--use-sdk",
@@ -1135,15 +1154,6 @@
"arguments": ["--arch=ia32,x64", "create_sdk" ]
},
{
- "name": "trigger analyzer",
- "trigger": [
- "analyzer-linux-release",
- "analyzer-strong-linux-release",
- "analyzer-analysis-server-linux"
- ],
- "fileset": "analyzer"
- },
- {
"name": "generate API docs",
"script": "tools/bots/dart_sdk.py",
"arguments": [ "api_docs" ]
@@ -1153,7 +1163,7 @@
{
"builders": ["dart-sdk-mac"],
"meta": {
- "description": "This configuration is used by the sdk-builder for mac. The builder triggers the analyzer and dart2js mac builders."
+ "description": "This configuration is used by the sdk-builder for mac."
},
"steps": [
{
@@ -1166,7 +1176,7 @@
{
"builders": ["dart-sdk-win"],
"meta": {
- "description": "This configuration is used by the sdk-builder for windows. The builder triggers the analyzer and dart2js windows builders."
+ "description": "This configuration is used by the sdk-builder for windows."
},
"steps": [
{
@@ -1187,6 +1197,11 @@
},
"steps": [
{
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["create_sdk"]
+ },
+ {
"name": "analyze tests",
"arguments": ["--compiler=dart2analyzer", "--use-sdk"]
},
@@ -1261,6 +1276,11 @@
},
"steps": [
{
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["create_sdk"]
+ },
+ {
"name": "analyze tests strong",
"arguments": ["--compiler=dart2analyzer", "--use-sdk", "--strong"]
},
@@ -1279,6 +1299,11 @@
"builders": ["analyzer-analysis-server-linux"],
"steps": [
{
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["create_sdk"]
+ },
+ {
"name": "Analyze analysis_server",
"script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
"arguments": ["--no-hints","pkg/analysis_server"]
@@ -1298,10 +1323,15 @@
{
"builders": ["pkg-linux-release","pkg-win-release","pkg-mac-release"],
"meta": {
- "description": "This configuration is used by the pkg builders. The builder is triggered by the SDK builders with the pkg fileset."
+ "description": "This configuration is used by the pkg builders."
},
"steps": [
{
+ "name": "build dart",
+ "script": "tools/build.py",
+ "arguments": ["create_sdk"]
+ },
+ {
"name": "package unit tests",
"arguments": [
"--use-sdk",
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index bb824e0..8816f73 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -393,7 +393,7 @@
EOF
out/ReleaseX64/dart --profile-period=10000 --packages=.packages hello.dart
out/ReleaseX64/dart --profile-period=10000 --packages=.packages --checked hello.dart
- out/ReleaseX64/dart --profile-period=10000 --packages=.packages --dfe=out/ReleaseX64/gen/kernel-service.dart.snapshot --kernel-binaries=out/ReleaseX64 hello.dart
+ out/ReleaseX64/dart --profile-period=10000 --packages=.packages --dfe=out/ReleaseX64/gen/kernel-service.dart.snapshot hello.dart
out/ReleaseX64/dart_bootstrap --packages=.packages --use-blobs --snapshot-kind=app-aot --snapshot=blob.bin hello.dart
out/ReleaseX64/dart_precompiled_runtime --profile-period=10000 blob.bin
DART_CONFIGURATION=ReleaseX64 pkg/vm/tool/dart2 --profile-period=10000 --packages=.packages hello.dart
diff --git a/tools/dom/idl/dart/dart.idl b/tools/dom/idl/dart/dart.idl
index 77f0680..ca1993b 100644
--- a/tools/dom/idl/dart/dart.idl
+++ b/tools/dom/idl/dart/dart.idl
@@ -180,6 +180,18 @@
EntrySync getParent();
};
+// Need to add for Blob which are really File that extends a Blob when called
+// via file() method on FileEntry
+callback interface FileCallback {
+ void handleEvent(File? file);
+};
+
+[DartSupplemental]
+interface FileEntry {
+ [DartSuppress] void file(BlobCallback successCallback, optional ErrorCallback errorCallback);
+ void file(FileCallback successCallback, optional ErrorCallback errorCallback);
+};
+
[DartSupplemental,
CustomConstructor,
Constructor(Array blobParts, optional DOMString type, optional DOMString endings)
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 3e81e9b..9438b07 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -231,6 +231,9 @@
'XMLHttpRequest.open',
])
+def hasNamedFormals(full_name):
+ return full_name in _methods_with_named_formals
+
def ReturnValueConversionHack(idl_type, value, interface_name):
if idl_type == 'SVGMatrix':
return '%sTearOff::create(%s)' % (idl_type, value)
@@ -696,12 +699,12 @@
"""
return len(filter(lambda i: not i.is_optional, self.param_infos))
- def ParametersAsArgumentList(self, parameter_count=None):
+ def ParametersAsArgumentList(self, parameter_count=None, ignore_named_parameters=False):
"""Returns a string of the parameter names suitable for passing the
parameters as arguments.
"""
def param_name(param_info):
- if self.requires_named_arguments and param_info.is_optional:
+ if self.requires_named_arguments and param_info.is_optional and not ignore_named_parameters:
return '%s : %s' % (param_info.name, param_info.name)
else:
return param_info.name
@@ -744,17 +747,6 @@
# Events fired need use a JSFunction not a anonymous closure to
# insure the event can really be removed.
parameters.append('js.allowInterop(%s)' % p.name)
-# These commented out cases don't actually generate any code.
-# elif dart_js_interop and type_id == 'FontFaceSetForEachCallback':
- # forEach is supported in the DOM for FontFaceSet as it iterates
- # over the Javascript Object the callback parameters are also
- # Javascript objects and must be wrapped.
- # parameters.append('(fontFace, fontFaceAgain, set) => %s(fontFace, fontFaceAgain, wrap_jso(set))' % p.name)
-# elif dart_js_interop and type_id == 'HeadersForEachCallback':
- # forEach is supported in the DOM for Headers as it iterates
- # over the Javascript Object the callback parameters are also
- # Javascript objects and must be wrapped.
-# parameters.append('(String value, String key, map) => %s(value, key, wrap_jso(map))' % p.name)
elif dart_js_interop and type_is_callback and not(isRemoveOperation):
# Any remove operation that has a a callback doesn't need wrapping.
# TODO(terry): Kind of hacky but handles all the cases we care about
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 9a793a1..5bad37f 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -672,6 +672,9 @@
callback_info = GetCallbackInfo(
self._database.GetInterface(info.callback_args[0].type_id))
+ # Generated private members never have named arguments.
+ ignore_named_parameters = True if html_name.startswith('_') else False
+
# If more than one callback then the second argument is the error callback.
# Some error callbacks have 2 args (e.g., executeSql) where the second arg
# is the error - this is the argument we want.
@@ -687,7 +690,7 @@
error_callback = (',\n %s(%s) { completer.completeError(%s); }' %
(('%s : ' % info.callback_args[1].name
if info.requires_named_arguments and
- info.callback_args[1].is_optional else ''),
+ info.callback_args[1].is_optional and not(ignore_named_parameters) else ''),
errorCallbackVariables, errorName))
extensions = GetDDC_Extension(self._interface, info.declared_name)
@@ -717,7 +720,7 @@
completerVariable = callbackNames[-1]
future_generic = '<%s>' % self._DartType(callback_info.param_infos[-1].type_id)
- param_list = info.ParametersAsArgumentList()
+ param_list = info.ParametersAsArgumentList(None, ignore_named_parameters)
metadata = ''
if '_RenamingAnnotation' in dir(self):
metadata = (self._RenamingAnnotation(info.declared_name, html_name) +
@@ -742,7 +745,7 @@
PARAMS_LIST='' if param_list == '' else param_list + ',',
NAMED_PARAM=('%s : ' % info.callback_args[0].name
if info.requires_named_arguments and
- info.callback_args[0].is_optional else ''),
+ info.callback_args[0].is_optional and not(ignore_named_parameters) else ''),
VARIABLE_NAME=callbackVariables,
COMPLETER_NAME=completerVariable,
DDC_EXTENSION=ddc_extensions,
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 7c35719..12e2de5 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -205,12 +205,17 @@
'applyExtension(\'FileEntry\', value);',
]
},
+ 'Entry': {
+ 'getMetadata': [
+ 'applyExtension(\'Metadata\', value);',
+ ]
+ },
'FileEntry': {
'createWriter': [
'applyExtension(\'FileWriter\', value);'
],
'file': [
- 'applyExtension(\'Blob\', value);'
+ 'applyExtension(\'File\', value);'
]
},
'SQLTransaction': {
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 7218109..8ab959c 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -1125,6 +1125,7 @@
self._AddDirectNativeOperation(info, html_name)
def _AddDirectNativeOperation(self, info, html_name):
+ force_optional = True if html_name.startswith('_') else False
self._members_emitter.Emit(
'\n'
' $RENAME$METADATA$MODIFIERS$TYPE $NAME($PARAMS) native;\n',
@@ -1134,7 +1135,7 @@
MODIFIERS='static ' if info.IsStatic() else '',
TYPE=self.SecureOutputType(info.type_name, False, True),
NAME=html_name,
- PARAMS=info.ParametersAsDeclaration(self._NarrowInputType))
+ PARAMS=info.ParametersAsDeclaration(self._NarrowInputType, force_optional))
def _AddOperationWithConversions(self, info, html_name):
# Assert all operations have same return type.
@@ -1183,12 +1184,16 @@
TARGET=target,
PARAMS=', '.join(target_parameters))
+ # private methods don't need named arguments.
+ full_name = '%s.%s' % (self._interface.id, info.declared_name)
+ force_optional = False if hasNamedFormals(full_name) and not(html_name.startswith('_')) else True
+
declaration = '%s%s%s %s(%s)' % (
self._Metadata(info.type_name, info.declared_name, return_type),
'static ' if info.IsStatic() else '',
return_type,
html_name,
- info.ParametersAsDeclaration(InputType))
+ info.ParametersAsDeclaration(InputType, force_optional))
self._GenerateDispatcherBody(
info,
operations,
diff --git a/tools/gardening/lib/src/results/result_json_models.dart b/tools/gardening/lib/src/results/result_json_models.dart
index 6265cd4..5d82d62 100644
--- a/tools/gardening/lib/src/results/result_json_models.dart
+++ b/tools/gardening/lib/src/results/result_json_models.dart
@@ -93,7 +93,7 @@
_boolToArg("host-checked", hostChecked),
_boolToArg("minified", minified),
_boolToArg("csp", csp),
- _boolToArg("fasta", csp),
+ // We don't create a --fasta arg because fasta is synthesized variable.
_stringToArg("system", system),
_listToArg("vm-options", vmOptions),
_boolToArg("use-sdk", useSdk),
diff --git a/tools/gardening/lib/src/results_workflow/fix_failing_test.dart b/tools/gardening/lib/src/results_workflow/fix_failing_test.dart
index 0dbacea..262330c 100644
--- a/tools/gardening/lib/src/results_workflow/fix_failing_test.dart
+++ b/tools/gardening/lib/src/results_workflow/fix_failing_test.dart
@@ -29,10 +29,10 @@
List<FailingTest> _remainingTests;
// These fields are mutated to persist user input.
- String _lastComment = null;
+ String _lastComment;
FixWorkingItem _lastWorkingItem;
List<StatusSectionWithFile> _customSections = [];
- bool _fixIfPossible = false;
+ StatusExpectations _statusExpectations;
FixFailingTest(this._testResult);
@@ -46,45 +46,20 @@
}
// We have to compute status files on every show, because we modify the
// status files on every fix.
- var statusExpectations = new StatusExpectations(_testResult);
- await statusExpectations.loadStatusFiles();
+ _statusExpectations = new StatusExpectations(_testResult);
+ await _statusExpectations.loadStatusFiles();
_remainingTests = payload.sublist(1);
var failingTest = payload.first;
- if (!failingTest.stillFailing(statusExpectations)) {
+ if (!failingTest.stillFailing(_statusExpectations)) {
return new NavigateStepWorkflowAction(this, _remainingTests);
}
_currentWorkingItem = new FixWorkingItem(failingTest.result.name,
- failingTest, statusExpectations, _lastComment, this._customSections);
+ failingTest, _statusExpectations, _lastComment, this._customSections);
_currentWorkingItem.init();
- if (_lastWorkingItem != null && _fixIfPossible) {
- // Outcome may be larger from the previous one, but current newOutcome
- // will always be a singleton list. So we check by matching first
- // element.
- var outcomeIsSame = _currentWorkingItem.newOutcome.first ==
- _lastWorkingItem.newOutcome.first;
- var lastConfigurations =
- _lastWorkingItem.failingTest.failingConfigurations;
- var currentConfigurations =
- _currentWorkingItem.failingTest.failingConfigurations;
- var sameConfigurations = lastConfigurations.length ==
- currentConfigurations.length &&
- lastConfigurations.every(
- (configuration) => currentConfigurations.contains(configuration));
- if (outcomeIsSame && sameConfigurations) {
- _lastWorkingItem.currentSections.forEach((section) {
- addExpressionToCustomSections(
- section.section.condition, section.statusFile.path);
- });
- print("Auto-fixing ${_currentWorkingItem.name}");
- await fixFailingTest();
- return new NavigateStepWorkflowAction(this, _remainingTests);
- }
- }
-
print("");
print("${_remainingTests.length + 1} tests remaining.");
askAboutTest();
@@ -111,9 +86,8 @@
_lastComment = _currentWorkingItem.comment;
} else if (input == "f") {
// Fix failing tests and try to fix the coming ones.
- _fixIfPossible = true;
await fixFailingTest();
- return new NavigateStepWorkflowAction(this, _remainingTests);
+ return _fixAllSimilarTests();
} else if (input == "o") {
// Case change new outcome.
_currentWorkingItem.newOutcome = getNewOutcome();
@@ -139,6 +113,35 @@
return new WaitForInputWorkflowAction();
}
+ Future<WorkflowAction> _fixAllSimilarTests() async {
+ for (FailingTest similarTest in _remainingTests) {
+ _currentWorkingItem = new FixWorkingItem(similarTest.result.name,
+ similarTest, _statusExpectations, _lastComment, this._customSections);
+ _currentWorkingItem.init();
+ // Outcome may be larger from the previous one, but current newOutcome
+ // will always be a singleton list. So we check by matching first
+ // element.
+ var outcomeIsSame = _currentWorkingItem.newOutcome.first ==
+ _lastWorkingItem.newOutcome.first;
+ var lastConfigurations =
+ _lastWorkingItem.failingTest.failingConfigurations;
+ var currentConfigurations =
+ _currentWorkingItem.failingTest.failingConfigurations;
+ var sameConfigurations = lastConfigurations.length ==
+ currentConfigurations.length &&
+ lastConfigurations.every(
+ (configuration) => currentConfigurations.contains(configuration));
+ if (outcomeIsSame && sameConfigurations) {
+ _currentWorkingItem.currentSections = _lastWorkingItem.currentSections;
+ print("Auto-fixing ${_currentWorkingItem.name}");
+ var realLast = _lastWorkingItem;
+ await fixFailingTest(); // Sets _lastWorkingItem to _currentWorkingItem
+ _lastWorkingItem = realLast; // Might not be needed
+ }
+ }
+ return new NavigateStepWorkflowAction(this, const <FailingTest>[]);
+ }
+
@override
Future<bool> onLeave() {
return new Future.value(false);
@@ -164,10 +167,10 @@
/// Fixes the failing test based on the data in [_currentWorkingItem].
Future fixFailingTest() async {
// Delete all existing entries that are wrong.
- var statusFiles = new Set<StatusFile>();
+ var changedFiles = new Set<StatusFile>();
for (var statusEntry in _currentWorkingItem.statusEntries) {
statusEntry.section.entries.remove(statusEntry.entry);
- statusFiles.add(statusEntry.statusFile);
+ changedFiles.add(statusEntry.statusFile);
}
// Add new expectations to status sections.
var path = getQualifiedNameForTest(_currentWorkingItem.name);
@@ -184,12 +187,12 @@
currentSection.statusFile.sections.add(currentSection.section);
}
currentSection.section.entries.add(statusEntry);
- statusFiles.add(currentSection.statusFile);
+ changedFiles.add(currentSection.statusFile);
}
// Save the modified status files.
- for (var statusFile in statusFiles) {
- var normalized = normalizeStatusFile(statusFile);
- await new File(statusFile.path).writeAsString(normalized.toString());
+ for (var file in changedFiles) {
+ await new File(file.path)
+ .writeAsString(normalizeStatusFile(file).toString());
}
_lastWorkingItem = _currentWorkingItem;
}
@@ -210,7 +213,6 @@
orElse: () => null);
sectionToAdd ??= new StatusSection(expression, 0, []);
var section = new StatusSectionWithFile(statusFile, sectionToAdd);
- // This mutates the
_customSections.add(section);
_currentWorkingItem.currentSections.add(section);
}
@@ -237,6 +239,9 @@
/// user to pick the correct file.
StatusFile getStatusFile(FixWorkingItem workingItem) {
var statusFiles = workingItem.statusFiles();
+ if (statusFiles.length == 1) {
+ return statusFiles.first;
+ }
print("Which status file should the section be added to/exists in?");
int i = 0;
for (var statusFile in statusFiles) {
@@ -382,7 +387,6 @@
print("Sections to add the new outcome to. The selected sections are "
"marked by *:");
int groupCounter = "A".codeUnitAt(0);
- ;
int sectionCounter = 0;
suggestedSections.forEach((suggestedSection) {
print(" ${new String.fromCharCode(groupCounter++)} "
diff --git a/tools/migration/bin/run_tests.dart b/tools/migration/bin/run_tests.dart
index 8dd7cd7f..3fc8498 100644
--- a/tools/migration/bin/run_tests.dart
+++ b/tools/migration/bin/run_tests.dart
@@ -47,17 +47,10 @@
/// possibly followed by some modifier for a specific bot or annotated step on
/// a bot. The configs here are ordered the same order as the waterfall.
final allConfigs = {
- "vm": [noCompiler, vm],
"vm-checked": [noCompiler, vm, checked],
- "vm-app": [appJit, vm],
- "vm-app-product": [productMode, appJit, vm],
- "vm-kernel": [dartk, releaseMode, vm],
"vm-kernel-strong": [dartk, releaseMode, vm, strong],
- "vm-kernel-precomp": [dartkp, releaseMode, precompiled],
"vm-kernel-precomp-strong": [dartkp, releaseMode, precompiled, strong],
- "vm-precomp": [precompiler, precompiled],
"vm-precomp-checked": [precompiler, precompiled, checked],
- "vm-product": [productMode, noCompiler, vm],
// TODO(rnystrom): Add dart2js-d8-hostchecked, dart2js-d8-minified, or
// dart2js-jsshell?
"analyzer": [analyzer, noRuntime, useSdk],
@@ -80,14 +73,6 @@
useSdk,
dart2jsBatch
],
- "dart2js-d8-withkernel-checked": [
- dart2js,
- d8,
- dart2jsWithKernel,
- checked,
- useSdk,
- dart2jsBatch
- ],
"dart2js-jsshell": [dart2js, jsshell, fastStartup, useSdk, dart2jsBatch],
// TODO(rnystrom): Is it worth running dart2js on Firefox too?
"dartdevc": [dartdevc, chrome, useSdk, strong],
diff --git a/tools/sdks/linux/dart-sdk.tar.gz.sha1 b/tools/sdks/linux/dart-sdk.tar.gz.sha1
index 6411e77..249421a 100644
--- a/tools/sdks/linux/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/linux/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-49e617f9794692ed227c0722813e10c3d4196346
\ No newline at end of file
+3fde07bb67a56026714d80a368ef103dab2178c7
\ No newline at end of file
diff --git a/tools/sdks/mac/dart-sdk.tar.gz.sha1 b/tools/sdks/mac/dart-sdk.tar.gz.sha1
index 02551c5..5f44438 100644
--- a/tools/sdks/mac/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/mac/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-1874dc616540bedab2352f0e1c7b5351bc243983
\ No newline at end of file
+5aca8af43c877177661c6474900ab03a076d03a3
\ No newline at end of file
diff --git a/tools/sdks/win/dart-sdk.tar.gz.sha1 b/tools/sdks/win/dart-sdk.tar.gz.sha1
index 46075fb..a9bcb34 100644
--- a/tools/sdks/win/dart-sdk.tar.gz.sha1
+++ b/tools/sdks/win/dart-sdk.tar.gz.sha1
@@ -1 +1 @@
-78643b42a0fc10aea1409d5ce9ed10a14d128e77
\ No newline at end of file
+d205e12e82d9605639bb2f36deb7287ca84bc18e
\ No newline at end of file
diff --git a/tools/testing/dart/browser_test.dart b/tools/testing/dart/browser_test.dart
index 011aa2d..19b39a7 100644
--- a/tools/testing/dart/browser_test.dart
+++ b/tools/testing/dart/browser_test.dart
@@ -40,7 +40,8 @@
/// The [testName] is the short name of the test without any subdirectory path
/// or extension, like "math_test". The [testJSDir] is the relative path to the
/// build directory where the dartdevc-generated JS file is stored.
-String dartdevcHtml(String testName, String testJSDir, String buildDir) {
+String dartdevcHtml(String testName, String testJSDir, String buildDir,
+ {bool syncAsync}) {
var packagePaths = testPackages
.map((package) => ' "$package": "/root_dart/$buildDir/gen/utils/'
'dartdevc/pkg/$package",')
@@ -86,7 +87,7 @@
requirejs(["$testName", "dart_sdk", "async_helper"],
function($testName, sdk, async_helper) {
sdk.dart.ignoreWhitelistedErrors(false);
-
+ if ($syncAsync) sdk.dart.setStartAsyncSynchronously();
// TODO(rnystrom): This uses DDC's forked version of async_helper. Unfork
// these packages when possible.
async_helper.async_helper.asyncTestInitialize(function() {});
diff --git a/tools/testing/dart/co19_test_config.dart b/tools/testing/dart/co19_test_config.dart
index 1a2fab4..f98f7a5 100644
--- a/tools/testing/dart/co19_test_config.dart
+++ b/tools/testing/dart/co19_test_config.dart
@@ -9,14 +9,13 @@
class Co19TestSuite extends StandardTestSuite {
RegExp _testRegExp = new RegExp(r"t[0-9]{2}.dart$");
- Co19TestSuite(Configuration configuration)
- : super(configuration, "co19", new Path("tests/co19/src"), [
- "tests/co19/co19-co19.status",
- "tests/co19/co19-analyzer.status",
- "tests/co19/co19-analyzer2.status",
- "tests/co19/co19-runtime.status",
- "tests/co19/co19-dart2js.status",
- "tests/co19/co19-kernel.status"
+ Co19TestSuite(Configuration configuration, String selector)
+ : super(configuration, selector, new Path("tests/$selector/src"), [
+ "tests/$selector/$selector-co19.status",
+ "tests/$selector/$selector-analyzer.status",
+ "tests/$selector/$selector-runtime.status",
+ "tests/$selector/$selector-dart2js.status",
+ "tests/$selector/$selector-kernel.status"
]);
bool isTestFile(String filename) => _testRegExp.hasMatch(filename);
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index da1d9be..3bbb205 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -1065,6 +1065,7 @@
final args = [
_isAot ? '--aot' : '--no-aot',
_isStrong ? '--strong-mode' : '--no-strong-mode',
+ _isStrong ? '--sync-async' : '--no-sync-async',
'--platform=$vmPlatform',
'-o',
dillFile,
diff --git a/tools/testing/dart/expectation_set.dart b/tools/testing/dart/expectation_set.dart
index 60ff188..aa6247f 100644
--- a/tools/testing/dart/expectation_set.dart
+++ b/tools/testing/dart/expectation_set.dart
@@ -15,28 +15,37 @@
/// For any given file path, returns the expected test results for that file.
/// A set can be loaded from a collection of status files. A file path may
/// exist in multiple files (or even multiple sections within the file). When
-/// that happens, all of the expectations of every entry are combined.
+/// that happens, all of the expectations of every entry are unioned together
+/// and the test is considered to pass if the outcome is any of those
+/// expectations.
class ExpectationSet {
+ static final _passSet = [Expectation.pass].toSet();
+
+ /// A cache of path component glob strings (like "b*r") that we've previously
+ /// converted to regexes. This ensures we collapse multiple globs from the
+ /// same string to the same map key in [_PathNode.regExpChildren].
+ final Map<String, RegExp> _globCache = {};
+
+ /// The root of the expectation tree.
+ final _PathNode _tree = new _PathNode();
+
/// Reads the expectations defined by the status files at [statusFilePaths]
/// when in [configuration].
- static ExpectationSet read(
+ ExpectationSet.read(
List<String> statusFilePaths, Configuration configuration) {
try {
var environment = new ConfigurationEnvironment(configuration);
- var expectations = new ExpectationSet._();
for (var path in statusFilePaths) {
var file = new StatusFile.read(path);
file.validate(environment);
for (var section in file.sections) {
if (section.isEnabled(environment)) {
for (var entry in section.entries) {
- expectations.addEntry(entry);
+ addEntry(entry);
}
}
}
}
-
- return expectations;
} on SyntaxError catch (error) {
stderr.writeln(error.toString());
exit(1);
@@ -45,29 +54,21 @@
}
}
- // Only create one copy of each Set<Expectation>.
- // We just use .toString as a key, so we may make a few
- // sets that only differ in their toString element order.
- static Map<String, Set<Expectation>> _cachedSets = {};
-
- Map<String, Set<Expectation>> _map = {};
- Map<String, List<RegExp>> _keyToRegExps;
-
- /// Create a TestExpectations object. See the [expectations] method
- /// for an explanation of matching.
- ExpectationSet._();
-
/// Add [entry] to the set of expectations.
void addEntry(StatusEntry entry) {
- // Once we have started using the expectations we cannot add more
- // rules.
- if (_keyToRegExps != null) {
- throw new StateError("Cannot add entries after it is already in use.");
+ var tree = _tree;
+ for (var part in entry.path.split('/')) {
+ if (part.contains("*")) {
+ var regExp = _globCache.putIfAbsent(part, () {
+ return new RegExp("^" + part.replaceAll("*", ".*") + r"$");
+ });
+ tree = tree.regExpChildren.putIfAbsent(regExp, () => new _PathNode());
+ } else {
+ tree = tree.stringChildren.putIfAbsent(part, () => new _PathNode());
+ }
}
- _map
- .putIfAbsent(entry.path, () => new Set<Expectation>())
- .addAll(entry.expectations);
+ tree.expectations.addAll(entry.expectations);
}
/// Get the expectations for the test at [path].
@@ -80,53 +81,71 @@
/// the corresponding filename component.
Set<Expectation> expectations(String path) {
var result = new Set<Expectation>();
- var parts = path.split('/');
+ _tree.walk(path.split('/'), 0, result);
- // Create mapping from keys to list of RegExps once and for all.
- _preprocessForMatching();
+ // If no status files modified the expectation, default to the test passing.
+ if (result.isEmpty) return _passSet;
- _map.forEach((key, expectations) {
- var regExps = _keyToRegExps[key];
- if (regExps.length > parts.length) return;
-
- for (var i = 0; i < regExps.length; i++) {
- if (!regExps[i].hasMatch(parts[i])) return;
- }
-
- // If all components of the status file key matches the filename
- // add the expectations to the result.
- result.addAll(expectations);
- });
-
- // If no expectations were found the expectation is that the test
- // passes.
- if (result.isEmpty) {
- result.add(Expectation.pass);
- }
- return _cachedSets.putIfAbsent(result.toString(), () => result);
+ return result;
}
+}
- /// Preprocesses the expectations for matching against filenames. Generates
- /// lists of regular expressions once and for all for each key.
- void _preprocessForMatching() {
- if (_keyToRegExps != null) return;
+/// A single file system path component in the tree of expectations.
+///
+/// Given a list of status file entry paths (which may contain globs at various
+/// parts), we parse it into a tree of nodes. Then, later, when looking up the
+/// status for a single test, this lets us quickly consider only the status
+/// file entries that relate to that test.
+class _PathNode {
+ /// The non-glob child directory and file paths within this directory.
+ final Map<String, _PathNode> stringChildren = {};
- _keyToRegExps = {};
- var regExpCache = <String, RegExp>{};
+ /// The glob child directory and file paths within this directory.
+ final Map<RegExp, _PathNode> regExpChildren = {};
- _map.forEach((key, expectations) {
- if (_keyToRegExps[key] != null) return;
- var splitKey = key.split('/');
- var regExps = new List<RegExp>(splitKey.length);
+ /// The test expectatations that any test within this directory should
+ /// include.
+ final Set<Expectation> expectations = new Set();
- for (var i = 0; i < splitKey.length; i++) {
- var component = splitKey[i];
- var regExp = regExpCache.putIfAbsent(component,
- () => new RegExp("^${splitKey[i]}\$".replaceAll('*', '.*')));
- regExps[i] = regExp;
+ /// Walks the list of path [parts], starting at [index] adding any
+ /// expectations to [result] from this node and any of its matching children.
+ ///
+ /// We need to include all matching children because multiple children may
+ /// match a single test, as in:
+ ///
+ /// foo/bar/baz: Timeout
+ /// foo/b*r/baz: Skip
+ /// foo/*ar/baz: SkipByDesign
+ ///
+ /// Assuming this node is for "foo" and we are walking ["bar", "baz"], all
+ /// three of the above should match and the resulting expectation set should
+ /// include all three.
+ ///
+ /// Also if a status file entry is a prefix of the test's path, that matches
+ /// too:
+ ///
+ /// foo/bar: Skip
+ ///
+ /// If the test path is "foo/baz/baz", the above entry will match it.
+ void walk(List<String> parts, int index, Set<Expectation> result) {
+ // We've reached this node itself, so add its expectations.
+ result.addAll(expectations);
+
+ // If this is a leaf node, stop traversing.
+ if (index >= parts.length) return;
+
+ var part = parts[index];
+
+ // Look for a non-glob child directory.
+ if (stringChildren.containsKey(part)) {
+ stringChildren[part].walk(parts, index + 1, result);
+ }
+
+ // Look for any matching glob directories.
+ for (var regExp in regExpChildren.keys) {
+ if (regExp.hasMatch(part)) {
+ regExpChildren[regExp].walk(parts, index + 1, result);
}
-
- _keyToRegExps[key] = regExps;
- });
+ }
}
}
diff --git a/tools/testing/dart/test_configurations.dart b/tools/testing/dart/test_configurations.dart
index 77ac9f5..32c0c32 100644
--- a/tools/testing/dart/test_configurations.dart
+++ b/tools/testing/dart/test_configurations.dart
@@ -167,8 +167,8 @@
}
for (var key in configuration.selectors.keys) {
- if (key == 'co19') {
- testSuites.add(new Co19TestSuite(configuration));
+ if (['co19', 'co19_2'].contains(key)) {
+ testSuites.add(new Co19TestSuite(configuration, key));
} else if ((configuration.compiler == Compiler.none ||
configuration.compiler == Compiler.dartk) &&
configuration.runtime == Runtime.vm &&
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index 1867b2a..e82a650 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -471,7 +471,7 @@
var statusFiles =
statusFilePaths.map((statusFile) => "$dartDir/$statusFile").toList();
- var expectations = ExpectationSet.read(statusFiles, configuration);
+ var expectations = new ExpectationSet.read(statusFiles, configuration);
try {
for (var name in await _listTests(hostRunnerPath)) {
@@ -695,7 +695,7 @@
return dartDir.append(statusFilePath).toNativePath();
}).toList();
- return ExpectationSet.read(statusFiles, configuration);
+ return new ExpectationSet.read(statusFiles, configuration);
}
Future enqueueTests() {
@@ -814,6 +814,12 @@
var commonArguments =
commonArgumentsFromFile(info.filePath, info.optionsFromFile);
+ // TODO(floitsch): Hack. When running the 2.0 tests always start
+ // async functions synchronously.
+ if (suiteName.endsWith("_2")) {
+ commonArguments.insert(0, "--sync-async");
+ }
+
var vmOptionsList = getVmOptions(info.optionsFromFile);
assert(!vmOptionsList.isEmpty);
@@ -1026,13 +1032,37 @@
} else {
var jsDir =
new Path(compilationTempDir).relativeTo(Repository.dir).toString();
- content = dartdevcHtml(nameNoExt, jsDir, buildDir);
+ // Always run with synchronous starts of `async` functions.
+ // If we want to make this dependent on other parameters or flags,
+ // this flag could be become conditional.
+ content = dartdevcHtml(nameNoExt, jsDir, buildDir, syncAsync: true);
}
}
var htmlPath = '$tempDir/test.html';
new File(htmlPath).writeAsStringSync(content);
+ // TODO(floitsch): Hack. When running the 2.0 tests always start
+ // async functions synchronously.
+ if (suiteName.endsWith("_2") &&
+ configuration.compiler == Compiler.dart2js) {
+ if (optionsFromFile == null) {
+ optionsFromFile = const <String, dynamic>{
+ 'sharedOptions': const ['--sync-async']
+ };
+ } else {
+ optionsFromFile = new Map<String, dynamic>.from(optionsFromFile);
+ var sharedOptions = optionsFromFile['sharedOptions'];
+ if (sharedOptions == null) {
+ sharedOptions = const <String>['--sync-async'];
+ } else {
+ sharedOptions = sharedOptions.toList();
+ sharedOptions.insert(0, "--sync-async");
+ }
+ optionsFromFile['sharedOptions'] = sharedOptions;
+ }
+ }
+
// Construct the command(s) that compile all the inputs needed by the
// browser test. For running Dart in DRT, this will be noop commands.
var commands = <Command>[];
@@ -1377,7 +1407,7 @@
Map<String, dynamic> readOptionsFromFile(Path filePath) {
if (filePath.filename.endsWith('.dill')) {
return optionsFromKernelFile();
- } else if (filePath.segments().contains('co19')) {
+ } else if (filePath.segments().any(['co19', 'co19_2'].contains)) {
return readOptionsFromCo19File(filePath);
}
RegExp testOptionsRegExp = new RegExp(r"// VMOptions=(.*)");
@@ -1410,7 +1440,7 @@
List<String> singleListOfOptions(String name) {
var matches = new RegExp('// $name=(.*)').allMatches(contents);
- var options;
+ List<String> options;
for (var match in matches) {
if (options != null) {
throw new Exception(