Version 2.0.0-dev.50.0
Merge commit '9eb09d825b1bb0dc4312e8c7fe16bbdf1a7f567c' into dev
diff --git a/BUILD.gn b/BUILD.gn
index b2dc62f..6d24c82 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -80,7 +80,7 @@
}
group("create_sdk") {
- deps = [
+ public_deps = [
"sdk:create_sdk",
]
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de609346..83e13f6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 2.0.0-dev.50.0
+
## 2.0.0-dev.49.0
### Tool Changes
@@ -11,6 +13,28 @@
## 2.0.0-dev.48.0
+### Language
+
+#### Strong Mode
+
+### Core library changes
+
+### Dart VM
+
+### Tool Changes
+
+#### Pub
+
+#### Other Tools
+
+## 2.0.0-dev.49.0
+
+## 2.0.0-dev.47.0
+
+### Tool Changes
+
+## 2.0.0-dev.48.0
+
### Core library changes
* `dart:core`
diff --git a/DEPS b/DEPS
index 4ba2514..163bf8d 100644
--- a/DEPS
+++ b/DEPS
@@ -98,7 +98,7 @@
"intl_tag": "@0.15.2",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@2.0.6",
- "linter_tag": "@0.1.48",
+ "linter_tag": "@0.1.49",
"logging_tag": "@0.11.3+1",
"markdown_tag": "@1.1.1",
"matcher_tag": "@0.12.1+4",
diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni
index ddee618..b1acdf6 100644
--- a/build/config/sysroot.gni
+++ b/build/config/sysroot.gni
@@ -16,17 +16,17 @@
if (is_linux && dart_use_wheezy_sysroot) {
if (current_cpu == "x86") {
- target_sysroot = rebase_path("//build/linux/debian_wheezy_i386-sysroot")
+ target_sysroot = rebase_path("//build/linux/debian_wheezy_i386-sysroot", root_build_dir)
} else if (current_cpu == "x64") {
if (is_asan || is_lsan || is_msan || is_tsan) {
- target_sysroot = rebase_path("//build/linux/debian_jessie_amd64-sysroot")
+ target_sysroot = rebase_path("//build/linux/debian_jessie_amd64-sysroot", root_build_dir)
} else {
- target_sysroot = rebase_path("//build/linux/debian_wheezy_amd64-sysroot")
+ target_sysroot = rebase_path("//build/linux/debian_wheezy_amd64-sysroot", root_build_dir)
}
} else if (current_cpu == "arm") {
- target_sysroot = rebase_path("//build/linux/debian_wheezy_arm-sysroot")
+ target_sysroot = rebase_path("//build/linux/debian_wheezy_arm-sysroot", root_build_dir)
} else if (current_cpu == "arm64") {
- target_sysroot = rebase_path("//build/linux/debian_jessie_arm64-sysroot")
+ target_sysroot = rebase_path("//build/linux/debian_jessie_arm64-sysroot", root_build_dir)
} else {
print("There is no Debian wheezy sysroot present for $current_cpu")
assert(false)
@@ -38,13 +38,13 @@
} else if (is_android) {
import("//build/config/android/config.gni")
if (current_cpu == "x86") {
- sysroot = rebase_path("$android_ndk_root/$x86_android_sysroot_subdir")
+ sysroot = rebase_path("$android_ndk_root/$x86_android_sysroot_subdir", root_build_dir)
} else if (current_cpu == "arm") {
- sysroot = rebase_path("$android_ndk_root/$arm_android_sysroot_subdir")
+ sysroot = rebase_path("$android_ndk_root/$arm_android_sysroot_subdir", root_build_dir)
} else if (current_cpu == "x64") {
- sysroot = rebase_path("$android_ndk_root/$x86_64_android_sysroot_subdir")
+ sysroot = rebase_path("$android_ndk_root/$x86_64_android_sysroot_subdir", root_build_dir)
} else if (current_cpu == "arm64") {
- sysroot = rebase_path("$android_ndk_root/$arm64_android_sysroot_subdir")
+ sysroot = rebase_path("$android_ndk_root/$arm64_android_sysroot_subdir", root_build_dir)
} else {
sysroot = ""
}
diff --git a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
index 620c032..90fab47 100644
--- a/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
+++ b/pkg/analysis_server/benchmark/perf/flutter_analyze_benchmark.dart
@@ -70,6 +70,9 @@
deleteServerCache();
}
+ final String dartSdkPath =
+ path.dirname(path.dirname(Platform.resolvedExecutable));
+
final Stopwatch stopwatch = new Stopwatch()..start();
await _runProcess(
@@ -78,6 +81,8 @@
'packages/flutter_tools/bin/flutter_tools.dart',
'analyze',
'--flutter-repo',
+ '--dart-sdk',
+ dartSdkPath,
],
cwd: flutterDir.path,
failOnError: false,
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
index 1265b6b..06bbf6b 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_core.dart
@@ -2,10 +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.
-import 'dart:async';
-
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show SourceChange;
import 'package:analyzer_plugin/utilities/assist/assist.dart';
@@ -17,11 +13,6 @@
*/
class Assist {
/**
- * An empty list of assists.
- */
- static const List<Assist> EMPTY_LIST = const <Assist>[];
-
- /**
* A comparator that can be used to sort assists by their relevance. The most
* relevant assists will be sorted before assists with a lower relevance.
* Assists with the same relevance are sorted alphabetically.
@@ -53,42 +44,3 @@
return 'Assist(kind=$kind, change=$change)';
}
}
-
-/**
- * An object used to provide context information for [AssistContributor]s.
- *
- * Clients may not extend, implement or mix-in this class.
- */
-abstract class AssistContext {
- /**
- * The analysis driver used to access analysis results.
- */
- AnalysisDriver get analysisDriver;
-
- /**
- * The length of the selection.
- */
- int get selectionLength;
-
- /**
- * The start of the selection.
- */
- int get selectionOffset;
-
- /**
- * The source to get assists in.
- */
- Source get source;
-}
-
-/**
- * An object used to produce assists for a specific location.
- *
- * Clients may implement this class when implementing plugins.
- */
-abstract class AssistContributor {
- /**
- * Completes with a list of assists for the given [context].
- */
- Future<List<Assist>> computeAssists(AssistContext context);
-}
diff --git a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
index 44198cd..6e7020e 100644
--- a/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
+++ b/pkg/analysis_server/lib/plugin/edit/assist/assist_dart.dart
@@ -2,18 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'dart:async';
-
-import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
import 'package:analyzer/dart/ast/ast.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';
-import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
/**
- * An object used to provide context information for [DartAssistContributor]s.
+ * An object used to provide context information for Dart assist contributors.
*
* Clients may not extend, implement or mix-in this class.
*/
@@ -24,11 +18,6 @@
AnalysisDriver get analysisDriver;
/**
- * The provider for parsed or resolved ASTs.
- */
- AstProvider get astProvider;
-
- /**
* The length of the selection.
*/
int get selectionLength;
@@ -48,60 +37,3 @@
*/
CompilationUnit get unit;
}
-
-/**
- * An [AssistContributor] that can be used to contribute assists for Dart files.
- *
- * Clients may extend this class when implementing plugins.
- */
-abstract class DartAssistContributor implements AssistContributor {
- @override
- Future<List<Assist>> computeAssists(AssistContext context) async {
- AnalysisDriver driver = context.analysisDriver;
- Source source = context.source;
- if (!AnalysisEngine.isDartFileName(source.fullName)) {
- return Assist.EMPTY_LIST;
- }
- CompilationUnit unit = (await driver.getResult(source.fullName)).unit;
- if (unit == null) {
- return Assist.EMPTY_LIST;
- }
- DartAssistContext dartContext = new _DartAssistContextImpl(
- new AstProviderForDriver(driver), context, unit);
- return internalComputeAssists(dartContext);
- }
-
- /**
- * Completes with a list of assists for the given [context].
- */
- Future<List<Assist>> internalComputeAssists(DartAssistContext context);
-}
-
-/**
- * The implementation of [DartAssistContext].
- *
- * Clients may not extend, implement or mix-in this class.
- */
-class _DartAssistContextImpl implements DartAssistContext {
- @override
- final AstProvider astProvider;
-
- final AssistContext _context;
-
- @override
- final CompilationUnit unit;
-
- _DartAssistContextImpl(this.astProvider, this._context, this.unit);
-
- @override
- AnalysisDriver get analysisDriver => _context.analysisDriver;
-
- @override
- int get selectionLength => _context.selectionLength;
-
- @override
- int get selectionOffset => _context.selectionOffset;
-
- @override
- Source get source => _context.source;
-}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 9b4578e..1e6b8d0 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -49,7 +49,6 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
@@ -63,6 +62,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/source/pub_package_map_provider.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
@@ -294,7 +294,7 @@
* The controller for [onAnalysisSetChanged].
*/
StreamController _onAnalysisSetChangedController =
- new StreamController.broadcast();
+ new StreamController.broadcast(sync: true);
/**
* This exists as a temporary stopgap for plugins, until the official plugin
@@ -774,7 +774,8 @@
* This means that it is absolute and normalized.
*/
bool isValidFilePath(String path) {
- return resourceProvider.absolutePathContext.isValid(path);
+ return resourceProvider.pathContext.isAbsolute(path) &&
+ resourceProvider.pathContext.normalize(path) == path;
}
/**
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index a1ad9b6..e949c17 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -11,27 +11,27 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/pubspec/pubspec_validator.dart';
import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/path_filter.dart';
import 'package:analyzer/src/source/pub_package_map_provider.dart';
import 'package:analyzer/src/source/sdk_ext.dart';
import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/util/absolute_path.dart';
import 'package:analyzer/src/util/glob.dart';
import 'package:analyzer/src/util/yaml.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
@@ -441,13 +441,6 @@
final DartSdkManager sdkManager;
/**
- * The context used to work with absolute file system paths.
- *
- * TODO(scheglov) remove [pathContext].
- */
- AbsolutePathContext absolutePathContext;
-
- /**
* The context used to work with file system paths.
*/
pathos.Context pathContext;
@@ -532,7 +525,6 @@
this.analyzedFilesGlobs,
this._instrumentationService,
this.defaultContextOptions) {
- absolutePathContext = resourceProvider.absolutePathContext;
pathContext = resourceProvider.pathContext;
}
@@ -953,7 +945,7 @@
String path, ContextInfo info, Folder folder) {
// Check to see if this is the .packages file for this context and if so,
// update the context's source factory.
- if (absolutePathContext.basename(path) == PACKAGE_SPEC_NAME) {
+ if (pathContext.basename(path) == PACKAGE_SPEC_NAME) {
String contextRoot = info.folder.path;
ContextBuilder builder =
callbacks.createContextBuilder(info.folder, defaultContextOptions);
@@ -1052,8 +1044,7 @@
callbacks.computingPackageMap(true);
try {
// Try .packages first.
- if (absolutePathContext.basename(packagespecFile.path) ==
- PACKAGE_SPEC_NAME) {
+ if (pathContext.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
Packages packages = _readPackagespec(packagespecFile);
return new PackagesFileDisposition(packages);
}
@@ -1384,7 +1375,7 @@
case ChangeType.ADD:
Resource resource = resourceProvider.getResource(path);
- String directoryPath = absolutePathContext.dirname(path);
+ String directoryPath = pathContext.dirname(path);
// Check to see if we need to create a new context.
if (info.isTopLevel) {
@@ -1394,8 +1385,7 @@
if (_isPubspec(path)) {
// Check for a sibling .packages file.
if (!resourceProvider
- .getFile(absolutePathContext.append(
- directoryPath, PACKAGE_SPEC_NAME))
+ .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
.exists) {
_extractContext(info, resource);
return;
@@ -1404,8 +1394,7 @@
if (_isPackagespec(path)) {
// Check for a sibling pubspec.yaml file.
if (!resourceProvider
- .getFile(
- absolutePathContext.append(directoryPath, PUBSPEC_NAME))
+ .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
.exists) {
_extractContext(info, resource);
return;
@@ -1429,15 +1418,14 @@
// Note that it's important to verify that there is NEITHER a .packages nor a
// lingering pubspec.yaml before merging.
if (!info.isTopLevel) {
- String directoryPath = absolutePathContext.dirname(path);
+ String directoryPath = pathContext.dirname(path);
// Only merge if this is the same directory described by our info object.
if (info.folder.path == directoryPath) {
if (_isPubspec(path)) {
// Check for a sibling .packages file.
if (!resourceProvider
- .getFile(absolutePathContext.append(
- directoryPath, PACKAGE_SPEC_NAME))
+ .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
.exists) {
_mergeContext(info);
return;
@@ -1446,8 +1434,7 @@
if (_isPackagespec(path)) {
// Check for a sibling pubspec.yaml file.
if (!resourceProvider
- .getFile(
- absolutePathContext.append(directoryPath, PUBSPEC_NAME))
+ .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
.exists) {
_mergeContext(info);
return;
@@ -1479,16 +1466,14 @@
* context root [root], contains a folder whose name starts with '.'.
*/
bool _isContainedInDotFolder(String root, String path) {
- String pathDir = absolutePathContext.dirname(path);
- String suffixPath = absolutePathContext.suffix(root, pathDir);
- if (suffixPath == null) {
- return false;
- }
- for (String pathComponent in absolutePathContext.split(suffixPath)) {
- if (pathComponent.startsWith('.') &&
- pathComponent != '.' &&
- pathComponent != '..') {
- return true;
+ String pathDir = pathContext.dirname(path);
+ String rootPrefix = root + pathContext.separator;
+ if (pathDir.startsWith(rootPrefix)) {
+ String suffixPath = pathDir.substring(rootPrefix.length);
+ for (String pathComponent in pathContext.split(suffixPath)) {
+ if (pathComponent.startsWith('.')) {
+ return true;
+ }
}
}
return false;
@@ -1504,7 +1489,7 @@
*/
bool _isExcludedBy(List<String> excludedPaths, String path) {
return excludedPaths.any((excludedPath) {
- if (absolutePathContext.isWithin(excludedPath, path)) {
+ if (pathContext.isWithin(excludedPath, path)) {
return true;
}
return path == excludedPath;
@@ -1516,19 +1501,19 @@
* context root [root].
*/
bool _isInTopLevelDocDir(String root, String path) {
- String suffixPath = absolutePathContext.suffix(root, path);
- if (suffixPath == null) {
- return false;
+ String rootPrefix = root + pathContext.separator;
+ if (path.startsWith(rootPrefix)) {
+ String suffix = path.substring(rootPrefix.length);
+ return suffix == DOC_DIR_NAME ||
+ suffix.startsWith(DOC_DIR_NAME + pathContext.separator);
}
- return suffixPath == DOC_DIR_NAME ||
- suffixPath.startsWith(DOC_DIR_NAME + absolutePathContext.separator);
+ return false;
}
bool _isPackagespec(String path) =>
- absolutePathContext.basename(path) == PACKAGE_SPEC_NAME;
+ pathContext.basename(path) == PACKAGE_SPEC_NAME;
- bool _isPubspec(String path) =>
- absolutePathContext.basename(path) == PUBSPEC_NAME;
+ bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
/**
* Merges [info] context into its parent.
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 22b7f36..77fd41b 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -169,12 +169,7 @@
CompilationUnitElement compilationUnitElement =
resolutionMap.elementDeclaredByCompilationUnit(unit);
DartAssistContext dartAssistContext = new _DartAssistContextForValues(
- compilationUnitElement.source,
- offset,
- length,
- driver,
- new AstProviderForDriver(driver),
- unit);
+ compilationUnitElement.source, offset, length, driver, unit);
try {
AssistProcessor processor = new AssistProcessor(dartAssistContext);
List<Assist> assists = await processor.compute();
@@ -652,13 +647,10 @@
final AnalysisDriver analysisDriver;
@override
- final AstProvider astProvider;
-
- @override
final CompilationUnit unit;
_DartAssistContextForValues(this.source, this.selectionOffset,
- this.selectionLength, this.analysisDriver, this.astProvider, this.unit);
+ this.selectionLength, this.analysisDriver, this.unit);
}
/**
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
index 5d050de..6a96170 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_watcher.dart
@@ -7,7 +7,6 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/util/absolute_path.dart';
import 'package:front_end/src/base/source.dart';
import 'package:path/src/context.dart';
@@ -99,10 +98,9 @@
* [driver].
*/
String _getSdkPath(AnalysisDriver driver) {
- AbsolutePathContext context = resourceProvider.absolutePathContext;
String sdkRoot = driver.sourceFactory.forUri('dart:core').fullName;
- while (context.basename(sdkRoot) != 'lib') {
- String parent = context.dirname(sdkRoot);
+ while (resourceProvider.pathContext.basename(sdkRoot) != 'lib') {
+ String parent = resourceProvider.pathContext.dirname(sdkRoot);
if (parent == sdkRoot) {
break;
}
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 8ae5367..e111a67 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -17,11 +17,11 @@
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/file_instrumentation.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:args/args.dart';
import 'package:linter/src/rules.dart' as linter;
import 'package:plugin/manager.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 8902596..7767e39 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -2,37 +2,12 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analysis_server/plugin/edit/assist/assist_core.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/utilities/assist/assist.dart';
/**
- * The implementation of [AssistContext].
- */
-class AssistContextImpl implements AssistContext {
- @override
- final AnalysisDriver analysisDriver;
-
- @override
- final Source source;
-
- @override
- final int selectionOffset;
-
- @override
- final int selectionLength;
-
- AssistContextImpl(this.analysisDriver, this.source, this.selectionOffset,
- this.selectionLength);
-}
-
-/**
* An enumeration of possible assist kinds.
*/
class DartAssistKind {
- static const ADD_PART_DIRECTIVE = const AssistKind(
- 'dart.assist.addPartDirective', 30, "Add 'part' directive");
static const ADD_TYPE_ANNOTATION = const AssistKind(
'dart.assist.addTypeAnnotation', 30, "Add type annotation");
static const ASSIGN_TO_LOCAL_VARIABLE = const AssistKind(
@@ -87,8 +62,6 @@
const AssistKind('dart.assist.encapsulateField', 30, "Encapsulate field");
static const EXCHANGE_OPERANDS =
const AssistKind('dart.assist.exchangeOperands', 30, "Exchange operands");
- static const EXTRACT_CLASS = const AssistKind(
- 'dart.assist.extractClass', 30, "Extract class into file '{0}'");
static const FLUTTER_CONVERT_TO_CHILDREN = const AssistKind(
'dart.assist.flutter.convert.childToChildren',
30,
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 d7b5b78..d9ae917 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -64,8 +64,6 @@
CompilationUnitElement unitElement;
LibraryElement unitLibraryElement;
- String unitLibraryFile;
- String unitLibraryFolder;
int selectionOffset;
int selectionLength;
@@ -93,8 +91,6 @@
unitLibraryElement = resolutionMap
.elementDeclaredByCompilationUnit(dartContext.unit)
.library;
- unitLibraryFile = unitLibraryElement.source.fullName;
- unitLibraryFolder = dirname(unitLibraryFile);
// selection
selectionOffset = dartContext.selectionOffset;
selectionLength = dartContext.selectionLength;
@@ -1237,17 +1233,39 @@
}
}
}
- // add accessors
- String eol2 = eol + eol;
- String typeNameCode = variableList.type != null
- ? _getNodeText(variableList.type) + ' '
- : '';
- String getterCode = '$eol2 ${typeNameCode}get $name => _$name;';
- String setterCode = '$eol2'
- ' void set $name($typeNameCode$name) {$eol'
- ' _$name = $name;$eol'
- ' }';
- builder.addSimpleInsertion(fieldDeclaration.end, getterCode + setterCode);
+
+ // Write getter and setter.
+ builder.addInsertion(fieldDeclaration.end, (builder) {
+ String docCode;
+ if (fieldDeclaration.documentationComment != null) {
+ docCode = utils.getNodeText(fieldDeclaration.documentationComment);
+ }
+
+ String typeCode = '';
+ if (variableList.type != null) {
+ typeCode = _getNodeText(variableList.type) + ' ';
+ }
+
+ // Write getter.
+ builder.writeln();
+ builder.writeln();
+ if (docCode != null) {
+ builder.write(' ');
+ builder.writeln(docCode);
+ }
+ builder.write(' ${typeCode}get $name => _$name;');
+
+ // Write setter.
+ builder.writeln();
+ builder.writeln();
+ if (docCode != null) {
+ builder.write(' ');
+ builder.writeln(docCode);
+ }
+ builder.writeln(' set $name($typeCode$name) {');
+ builder.writeln(' _$name = $name;');
+ builder.write(' }');
+ });
});
_addAssistFromBuilder(changeBuilder, DartAssistKind.ENCAPSULATE_FIELD);
}
@@ -3132,21 +3150,6 @@
}
}
-/**
- * An [AssistContributor] that provides the default set of assists.
- */
-class DefaultAssistContributor extends DartAssistContributor {
- @override
- Future<List<Assist>> internalComputeAssists(DartAssistContext context) async {
- try {
- AssistProcessor processor = new AssistProcessor(context);
- return processor.compute();
- } on CancelCorrectionException {
- return Assist.EMPTY_LIST;
- }
- }
-}
-
class _SimpleIdentifierRecursiveAstVisitor extends RecursiveAstVisitor {
final _SimpleIdentifierVisitor visitor;
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 3cdcf21..869f385 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -2393,7 +2393,7 @@
final thisExpression = node is ThisExpression
? node
: node.getAncestor((node) => node is ThisExpression);
- final parent = thisExpression.parent;
+ final parent = thisExpression?.parent;
if (parent is PropertyAccess) {
DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index d138f3e..f64cecb 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -9,8 +9,8 @@
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/source/pub_package_map_provider.dart';
/**
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index b3050c4..ac435fd 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -22,7 +22,6 @@
import 'package:analysis_server/src/utilities/profiling.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -35,6 +34,7 @@
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/sdk_ext.dart';
import 'package:path/path.dart' as pathPackage;
diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart
index cca06da..5059a59 100644
--- a/pkg/analysis_server/lib/starter.dart
+++ b/pkg/analysis_server/lib/starter.dart
@@ -5,7 +5,7 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/server/driver.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
/**
* An object that can be used to start an analysis server. This class exists so
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 8e99e48..dccf6a6 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -9,14 +9,15 @@
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/engine.dart' as engine;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
diff --git a/pkg/analysis_server/lib/src/constants.dart b/pkg/analysis_server/test/constants.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/constants.dart
rename to pkg/analysis_server/test/constants.dart
diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart
index 0a6a543..996b070 100644
--- a/pkg/analysis_server/test/domain_completion_util.dart
+++ b/pkg/analysis_server/test/domain_completion_util.dart
@@ -7,13 +7,13 @@
import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:test/test.dart';
import 'analysis_abstract.dart';
+import 'constants.dart';
class AbstractCompletionDomainTest extends AbstractAnalysisTest {
String completionId;
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index c4aeebd..06d1c3e 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -6,13 +6,13 @@
import 'package:analysis_server/protocol/protocol_constants.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/domain_server.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:test/test.dart';
+import 'constants.dart';
import 'mocks.dart';
main() {
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 0019aa2..421000a 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -4,7 +4,6 @@
import 'dart:mirrors';
-import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analyzer/dart/ast/ast.dart' as engine;
@@ -17,6 +16,7 @@
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'constants.dart';
import 'mocks.dart';
main() {
diff --git a/pkg/analysis_server/test/protocol_test.dart b/pkg/analysis_server/test/protocol_test.dart
index 7d7e995..af72494 100644
--- a/pkg/analysis_server/test/protocol_test.dart
+++ b/pkg/analysis_server/test/protocol_test.dart
@@ -6,11 +6,12 @@
import 'package:analysis_server/protocol/protocol.dart';
import 'package:analysis_server/protocol/protocol_generated.dart';
-import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'constants.dart';
+
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NotificationTest);
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index cb974b3..6600839e 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -11,9 +11,7 @@
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/src/dart/analysis/ast_provider_driver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/element/ast_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -2564,6 +2562,33 @@
await assertNoAssistAt('test =', DartAssistKind.ENCAPSULATE_FIELD);
}
+ test_encapsulateField_OK_documentation() async {
+ await resolveTestUnit('''
+class A {
+ /// AAA
+ /// BBB
+ int test;
+}
+''');
+ await assertHasAssistAt('test;', DartAssistKind.ENCAPSULATE_FIELD, '''
+class A {
+ /// AAA
+ /// BBB
+ int _test;
+
+ /// AAA
+ /// BBB
+ int get test => _test;
+
+ /// AAA
+ /// BBB
+ set test(int test) {
+ _test = test;
+ }
+}
+''');
+ }
+
test_encapsulateField_OK_hasType() async {
await resolveTestUnit('''
class A {
@@ -2580,7 +2605,7 @@
int get test => _test;
- void set test(int test) {
+ set test(int test) {
_test = test;
}
A(this._test);
@@ -2606,7 +2631,7 @@
get test => _test;
- void set test(test) {
+ set test(test) {
_test = test;
}
}
@@ -5769,8 +5794,8 @@
CompilationUnitElement testUnitElement =
resolutionMap.elementDeclaredByCompilationUnit(testUnit);
DartAssistContext assistContext;
- assistContext = new _DartAssistContextForValues(testUnitElement.source,
- offset, length, driver, new AstProviderForDriver(driver), testUnit);
+ assistContext = new _DartAssistContextForValues(
+ testUnitElement.source, offset, length, driver, testUnit);
AssistProcessor processor = new AssistProcessor(assistContext);
return await processor.compute();
}
@@ -5809,11 +5834,8 @@
final AnalysisDriver analysisDriver;
@override
- final AstProvider astProvider;
-
- @override
final CompilationUnit unit;
_DartAssistContextForValues(this.source, this.selectionOffset,
- this.selectionLength, this.analysisDriver, this.astProvider, this.unit);
+ this.selectionLength, this.analysisDriver, this.unit);
}
diff --git a/pkg/analysis_server/test/services/correction/change_test.dart b/pkg/analysis_server/test/services/correction/change_test.dart
index 0dc019b..d11aabd 100644
--- a/pkg/analysis_server/test/services/correction/change_test.dart
+++ b/pkg/analysis_server/test/services/correction/change_test.dart
@@ -2,12 +2,13 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
+import '../../constants.dart';
+
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ChangeTest);
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 9903039..426ff09 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -12,13 +12,13 @@
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/error/error.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';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide AnalysisError;
import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
@@ -6901,6 +6901,17 @@
''');
}
+ test_removeThisExpression_notAThisExpression() async {
+ String src = '''
+void foo() {
+ final /*LINT*/this.id;
+}
+''';
+ await findLint(src, LintNames.unnecessary_this);
+
+ await assertNoFix(DartFixKind.REMOVE_THIS_EXPRESSION);
+ }
+
test_removeThisExpression_propertyAccess_oneCharacterOperator() async {
String src = '''
class A {
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 1e93e6a..bfa202a 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -7,13 +7,13 @@
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/dart/element/element.dart';
-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/dart/analysis/file_state.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 8b7669b..8c372a6 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -10,13 +10,13 @@
import 'package:analysis_server/src/plugin/plugin_watcher.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/session.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
diff --git a/pkg/analyzer/benchmark/errors_in_all_libraries.dart b/pkg/analyzer/benchmark/errors_in_all_libraries.dart
index d46edba..57b512b 100644
--- a/pkg/analyzer/benchmark/errors_in_all_libraries.dart
+++ b/pkg/analyzer/benchmark/errors_in_all_libraries.dart
@@ -11,14 +11,14 @@
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/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/source_resource.dart';
import 'package:path/path.dart' as p;
diff --git a/pkg/analyzer/example/resolver_driver.dart b/pkg/analyzer/example/resolver_driver.dart
index cf68857..6c972a8 100755
--- a/pkg/analyzer/example/resolver_driver.dart
+++ b/pkg/analyzer/example/resolver_driver.dart
@@ -8,15 +8,15 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/file_system/file_system.dart' hide File;
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/source_resource.dart';
void main(List<String> args) {
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 303cc88..ab46a8d 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -2,18 +2,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.
-library analyzer;
-
import 'dart:io';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/file_system.dart' hide File;
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/error.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/string_source.dart';
diff --git a/pkg/analyzer/lib/context/context_root.dart b/pkg/analyzer/lib/context/context_root.dart
new file mode 100644
index 0000000..7625503
--- /dev/null
+++ b/pkg/analyzer/lib/context/context_root.dart
@@ -0,0 +1,8 @@
+// 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.
+
+@deprecated
+library context.context_root;
+
+export 'package:analyzer/src/context/context_root.dart';
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 687380f..89da122 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -2,15 +2,14 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.file_system.file_system;
-
import 'dart:async';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart';
import 'package:watcher/watcher.dart';
+export 'package:analyzer/src/file_system/file_system.dart';
+
/**
* [File]s are leaf [Resource]s which contain data.
*/
@@ -226,11 +225,6 @@
*/
abstract class ResourceProvider {
/**
- * Get the absolute path context used by this resource provider.
- */
- AbsolutePathContext get absolutePathContext;
-
- /**
* Get the path context used by this resource provider.
*/
Context get pathContext;
@@ -271,41 +265,3 @@
*/
Folder getStateLocation(String pluginId);
}
-
-/**
- * A [UriResolver] for [Resource]s.
- */
-class ResourceUriResolver extends UriResolver {
- /**
- * The name of the `file` scheme.
- */
- static final String FILE_SCHEME = "file";
-
- final ResourceProvider _provider;
-
- ResourceUriResolver(this._provider);
-
- ResourceProvider get provider => _provider;
-
- @override
- Source resolveAbsolute(Uri uri, [Uri actualUri]) {
- if (!isFileUri(uri)) {
- return null;
- }
- String path = _provider.pathContext.fromUri(uri);
- Resource resource = _provider.getResource(path);
- if (resource is File) {
- return resource.createSource(actualUri ?? uri);
- }
- return null;
- }
-
- @override
- Uri restoreAbsolute(Source source) =>
- _provider.pathContext.toUri(source.fullName);
-
- /**
- * Return `true` if the given [uri] is a `file` URI.
- */
- static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
-}
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 4c05644..0c5c8b6 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/source/source_resource.dart';
-import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart' as pathos;
import 'package:watcher/watcher.dart';
@@ -31,9 +30,6 @@
final pathos.Context _pathContext;
- @override
- final AbsolutePathContext absolutePathContext;
-
MemoryResourceProvider(
{pathos.Context context, @deprecated bool isWindows: false})
: _pathContext = (context ??= pathos.style == pathos.Style.windows
@@ -41,9 +37,7 @@
// the drive inserted by MemoryResourceProvider.convertPath
// so that packages are mapped to the correct drive
? new pathos.Context(current: 'C:\\')
- : pathos.context),
- absolutePathContext =
- new AbsolutePathContext(context.style == pathos.Style.windows);
+ : pathos.context);
@override
pathos.Context get pathContext => _pathContext;
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index a5d2a99..db86404 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -11,11 +11,28 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/source/source_resource.dart';
-import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart';
import 'package:watcher/watcher.dart';
/**
+ * The name of the directory containing plugin specific subfolders used to
+ * store data across sessions.
+ */
+const String _SERVER_DIR = ".dartServer";
+
+/**
+ * Returns the path to the user's home directory.
+ */
+String _getStandardStateLocation() {
+ final home = io.Platform.isWindows
+ ? io.Platform.environment['LOCALAPPDATA']
+ : io.Platform.environment['HOME'];
+ return home != null && io.FileSystemEntity.isDirectorySync(home)
+ ? join(home, _SERVER_DIR)
+ : null;
+}
+
+/**
* Return modification times for every file path in [paths].
*
* If a path is `null`, the modification time is also `null`.
@@ -39,28 +56,10 @@
}
/**
- * The name of the directory containing plugin specific subfolders used to
- * store data across sessions.
- */
-const String _SERVER_DIR = ".dartServer";
-
-/**
- * Returns the path to the user's home directory.
- */
-String _getStandardStateLocation() {
- final home = io.Platform.isWindows
- ? io.Platform.environment['LOCALAPPDATA']
- : io.Platform.environment['HOME'];
- return home != null && io.FileSystemEntity.isDirectorySync(home)
- ? join(home, _SERVER_DIR)
- : null;
-}
-
-/**
* A `dart:io` based implementation of [ResourceProvider].
*/
class PhysicalResourceProvider implements ResourceProvider {
- static final FileReadMode NORMALIZE_EOL_ALWAYS =
+ static final String Function(String) NORMALIZE_EOL_ALWAYS =
(String string) => string.replaceAll(new RegExp('\r\n?'), '\n');
static final PhysicalResourceProvider INSTANCE =
@@ -71,11 +70,8 @@
*/
final String _stateLocation;
- @override
- final AbsolutePathContext absolutePathContext =
- new AbsolutePathContext(io.Platform.isWindows);
-
- PhysicalResourceProvider(FileReadMode fileReadMode, {String stateLocation})
+ PhysicalResourceProvider(String Function(String) fileReadMode,
+ {String stateLocation})
: _stateLocation = stateLocation ?? _getStandardStateLocation() {
if (fileReadMode != null) {
FileBasedSource.fileReadMode = fileReadMode;
@@ -256,7 +252,7 @@
@override
bool contains(String path) {
- return absolutePathContext.isWithin(this.path, path);
+ return pathContext.isWithin(this.path, path);
}
@override
@@ -345,9 +341,6 @@
_PhysicalResource(this._entry);
- AbsolutePathContext get absolutePathContext =>
- PhysicalResourceProvider.INSTANCE.absolutePathContext;
-
@override
bool get exists => _entry.existsSync();
@@ -356,7 +349,7 @@
@override
Folder get parent {
- String parentPath = absolutePathContext.dirname(path);
+ String parentPath = pathContext.dirname(path);
if (parentPath == path) {
return null;
}
@@ -372,7 +365,7 @@
Context get pathContext => io.Platform.isWindows ? windows : posix;
@override
- String get shortName => absolutePathContext.basename(path);
+ String get shortName => pathContext.basename(path);
@override
bool operator ==(other) {
diff --git a/pkg/analyzer/lib/plugin/resolver_provider.dart b/pkg/analyzer/lib/plugin/resolver_provider.dart
index 33bb366..3c22554 100644
--- a/pkg/analyzer/lib/plugin/resolver_provider.dart
+++ b/pkg/analyzer/lib/plugin/resolver_provider.dart
@@ -2,14 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+@deprecated
library analyzer.plugin.resolver_provider;
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source.dart';
-
-/**
- * A function that will return a [UriResolver] that can be used to resolve a
- * specific kind of URI within the analysis context rooted at the given
- * [folder].
- */
-typedef UriResolver ResolverProvider(Folder folder);
+export 'package:analyzer/src/plugin/resolver_provider.dart';
diff --git a/pkg/analyzer/lib/source/line_info.dart b/pkg/analyzer/lib/source/line_info.dart
index 38ac611..47661a2 100644
--- a/pkg/analyzer/lib/source/line_info.dart
+++ b/pkg/analyzer/lib/source/line_info.dart
@@ -62,8 +62,13 @@
/**
* Return the location information for the character at the given [offset].
+ *
+ * A future version of this API will return a [CharacterLocation] rather than
+ // ignore: deprecated_member_use
+ * a [LineInfo_Location].
*/
- CharacterLocation getLocation(int offset) {
+ // ignore: deprecated_member_use
+ LineInfo_Location getLocation(int offset) {
var min = 0;
var max = lineStarts.length - 1;
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 3eeda21..6a1d230 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -2,100 +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.
-library analyzer.source.package_map_resolver;
+@deprecated
+library src.source.package_map_provider;
-import 'dart:core';
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/util/asserts.dart' as asserts;
-import 'package:path/path.dart' as pathos;
-
-/**
- * A [UriResolver] implementation for the `package:` scheme that uses a map of
- * package names to their directories.
- */
-class PackageMapUriResolver extends UriResolver {
- /**
- * The name of the `package` scheme.
- */
- static const String PACKAGE_SCHEME = "package";
-
- /**
- * A table mapping package names to the path of the directories containing
- * the package.
- */
- final Map<String, List<Folder>> packageMap;
-
- /**
- * The [ResourceProvider] for this resolver.
- */
- final ResourceProvider resourceProvider;
-
- /**
- * Create a new [PackageMapUriResolver].
- *
- * [packageMap] is a table mapping package names to the paths of the
- * directories containing the package
- */
- PackageMapUriResolver(this.resourceProvider, this.packageMap) {
- asserts.notNull(resourceProvider);
- asserts.notNull(packageMap);
- packageMap.forEach((name, folders) {
- if (folders.length != 1) {
- throw new ArgumentError(
- 'Exactly one folder must be specified for a package.'
- 'Found $name = $folders');
- }
- });
- }
-
- @override
- Source resolveAbsolute(Uri uri, [Uri actualUri]) {
- if (!isPackageUri(uri)) {
- return null;
- }
- // Prepare path.
- String path = uri.path;
- // Prepare path components.
- int index = path.indexOf('/');
- if (index == -1 || index == 0) {
- return null;
- }
- // <pkgName>/<relPath>
- String pkgName = path.substring(0, index);
- String relPath = path.substring(index + 1);
- // If the package is known, return the corresponding file.
- List<Folder> packageDirs = packageMap[pkgName];
- if (packageDirs != null) {
- Folder packageDir = packageDirs.single;
- File file = packageDir.getChildAssumingFile(relPath);
- return file.createSource(uri);
- }
- return null;
- }
-
- @override
- Uri restoreAbsolute(Source source) {
- String sourcePath = source.fullName;
- pathos.Context pathContext = resourceProvider.pathContext;
- for (String pkgName in packageMap.keys) {
- Folder pkgFolder = packageMap[pkgName][0];
- String pkgFolderPath = pkgFolder.path;
- if (sourcePath.startsWith(pkgFolderPath + pathContext.separator)) {
- String relPath = sourcePath.substring(pkgFolderPath.length + 1);
- List<String> relPathComponents = pathContext.split(relPath);
- String relUriPath = pathos.posix.joinAll(relPathComponents);
- return Uri.parse('$PACKAGE_SCHEME:$pkgName/$relUriPath');
- }
- }
- return null;
- }
-
- /**
- * Returns `true` if [uri] is a `package` URI.
- */
- static bool isPackageUri(Uri uri) {
- return uri.scheme == PACKAGE_SCHEME;
- }
-}
+export 'package:analyzer/src/source/package_map_resolver.dart';
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 2aee1c4..5b3e1db 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -7,8 +7,6 @@
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/command_line/arguments.dart'
show
@@ -21,6 +19,7 @@
show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/gn.dart';
@@ -28,7 +27,9 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/workspace.dart';
import 'package:analyzer/src/lint/registry.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/sdk.dart';
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index a70c50e5..4ccf4cd 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -9,7 +9,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
import 'package:analyzer/src/context/cache.dart';
@@ -20,6 +19,7 @@
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/plugin/task.dart';
import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/api/general.dart';
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index 9ea1d7d..ad7bdaa 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -2,19 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.context.source;
-
import 'dart:collection';
import 'dart:math' show min;
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:package_config/packages.dart';
/**
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 91c19a8..d48b1d6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,7 +95,7 @@
/**
* The version of data format, should be incremented on every format change.
*/
- static const int DATA_VERSION = 56;
+ static const int DATA_VERSION = 57;
/**
* The number of exception contexts allowed to write. Once this field is
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 89b8073..e16375c 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -675,7 +675,7 @@
// TODO(scheglov) remove EnumMemberBuilder class
new TypeParameterBoundsResolver(
- _typeProvider, _libraryElement, source, errorListener)
+ _context.typeSystem, _libraryElement, source, errorListener)
.resolveTypeBounds(unit);
unit.accept(new TypeResolverVisitor(
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 56eb475..c3dba9c 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -1792,7 +1792,7 @@
isEqualTokens(node.modifierKeyword, other.modifierKeyword) &&
isEqualNodes(node.returnType, other.returnType) &&
isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
- isEqualTokens(node.propertyKeyword, other.propertyKeyword) &&
+ isEqualTokens(node.operatorKeyword, other.operatorKeyword) &&
isEqualNodes(node.name, other.name) &&
isEqualNodes(node.parameters, other.parameters) &&
isEqualNodes(node.body, other.body);
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index a651d07..5d91528 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -16,6 +16,8 @@
import 'package:analyzer/src/generated/type_system.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/resynthesize.dart'
+ show RecursiveInstantiateToBounds;
/**
* Type of callbacks used by [DeferredFunctionTypeImpl].
@@ -1691,7 +1693,11 @@
@override
List<DartType> get typeArguments {
if (_typeArguments == null) {
- _typeArguments = _typeArgumentsComputer();
+ try {
+ _typeArguments = _typeArgumentsComputer();
+ } on RecursiveInstantiateToBounds {
+ _hasTypeParameterReferenceInBound = true;
+ }
_typeArgumentsComputer = null;
}
return _typeArguments;
@@ -2597,6 +2603,11 @@
final String name;
/**
+ * The cached value for [hasTypeParameterReferenceInBound].
+ */
+ bool _hasTypeParameterReferenceInBound;
+
+ /**
* Initialize a newly created type to be declared by the given [element] and
* to have the given [name].
*/
@@ -2608,6 +2619,46 @@
@override
Element get element => _element;
+ /**
+ * Return `true` if the type is parameterized and has a type parameter with
+ * the bound that references a type parameter.
+ */
+ bool get hasTypeParameterReferenceInBound {
+ if (_hasTypeParameterReferenceInBound == null) {
+ bool hasTypeParameterReference(DartType type) {
+ if (type == this) {
+ // Cycle detection -- and cycles should be considered unboundable.
+ return true;
+ } else if (type is TypeImpl &&
+ type._hasTypeParameterReferenceInBound == true) {
+ return true;
+ } else if (type is TypeParameterType) {
+ return true;
+ } else if (type is FunctionType) {
+ return (type as TypeImpl).hasTypeParameterReferenceInBound;
+ } else if (type is ParameterizedType) {
+ return type.typeArguments.any(hasTypeParameterReference);
+ } else {
+ return false;
+ }
+ }
+
+ Element element = this.element;
+ if (element is FunctionTypedElement) {
+ _hasTypeParameterReferenceInBound = element.parameters.any(
+ (parameter) => hasTypeParameterReference(parameter.type)) ||
+ (element.returnType != null &&
+ hasTypeParameterReference(element.returnType));
+ } else if (element is TypeParameterizedElement) {
+ _hasTypeParameterReferenceInBound = element.typeParameters
+ .any((parameter) => hasTypeParameterReference(parameter.bound));
+ } else {
+ _hasTypeParameterReferenceInBound = false;
+ }
+ }
+ return _hasTypeParameterReferenceInBound;
+ }
+
@override
bool get isBottom => false;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 997767c..bb67cb9 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -22,7 +22,12 @@
import 'package:front_end/src/fasta/scanner.dart' hide StringToken;
import 'package:front_end/src/scanner/errors.dart' show translateErrorToken;
import 'package:front_end/src/scanner/token.dart'
- show StringToken, SyntheticBeginToken, SyntheticStringToken, SyntheticToken;
+ show
+ BeginToken,
+ StringToken,
+ SyntheticBeginToken,
+ SyntheticStringToken,
+ SyntheticToken;
import 'package:front_end/src/fasta/problems.dart' show unhandled;
import 'package:front_end/src/fasta/messages.dart'
@@ -2250,26 +2255,25 @@
}
if (parameters == null && (getOrSet == null || optional('set', getOrSet))) {
- Token previous = typeParameters?.endToken;
- if (previous == null) {
+ Token token = typeParameters?.endToken;
+ if (token == null) {
if (name is AstNode) {
- previous = name.endToken;
+ token = name.endToken;
} else if (name is _OperatorName) {
- previous = name.name.endToken;
+ token = name.name.endToken;
} else {
throw new UnimplementedError();
}
}
- Token leftParen =
- new SyntheticBeginToken(TokenType.OPEN_PAREN, previous.end);
+ Token next = token.next;
+ int offset = next.charOffset;
+ BeginToken leftParen =
+ new SyntheticBeginToken(TokenType.OPEN_PAREN, offset);
+ token.setNext(leftParen);
Token rightParen =
- new SyntheticToken(TokenType.CLOSE_PAREN, leftParen.offset);
- rightParen.next = previous.next;
- leftParen.next = rightParen;
- previous.next = leftParen;
- leftParen.previous = previous;
- rightParen.previous = leftParen;
- rightParen.next.previous = rightParen;
+ leftParen.setNext(new SyntheticToken(TokenType.CLOSE_PAREN, offset));
+ leftParen.endGroup = rightParen;
+ rightParen.setNext(next);
parameters = ast.formalParameterList(
leftParen, <FormalParameter>[], null, null, rightParen);
}
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 5032154..660a6b6 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -64,6 +64,12 @@
errorReporter?.reportErrorForOffset(
ParserErrorCode.COLON_IN_PLACE_OF_IN, offset, length);
return;
+ case "CONCRETE_CLASS_WITH_ABSTRACT_MEMBER":
+ errorReporter?.reportErrorForOffset(
+ StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
+ offset,
+ length);
+ return;
case "CONST_AFTER_FACTORY":
errorReporter?.reportErrorForOffset(
ParserErrorCode.CONST_AFTER_FACTORY, offset, length);
diff --git a/pkg/analyzer/lib/src/fasta/token_utils.dart b/pkg/analyzer/lib/src/fasta/token_utils.dart
index 790d04a..52f4388 100644
--- a/pkg/analyzer/lib/src/fasta/token_utils.dart
+++ b/pkg/analyzer/lib/src/fasta/token_utils.dart
@@ -24,19 +24,16 @@
/// to be an analyzer token stream by removing error tokens and reporting
/// those errors to the associated error listener.
Token convertTokens(Token firstToken) {
- Token previous = new Token.eof(-1);
- Token token = firstToken;
- token.previous = previous;
- previous.next = token;
- while (!token.isEof) {
- if (token.type.kind == BAD_INPUT_TOKEN) {
- translateErrorToken(token, reportError);
- previous.next = token.next;
- token.next.previous = previous;
+ Token token = new Token.eof(-1)..setNext(firstToken);
+ Token next = firstToken;
+ while (!next.isEof) {
+ if (next.type.kind == BAD_INPUT_TOKEN) {
+ translateErrorToken(next, reportError);
+ token.setNext(next.next);
} else {
- previous = token;
+ token = next;
}
- token = token.next;
+ next = token.next;
}
return firstToken;
}
diff --git a/pkg/analyzer/lib/src/file_system/file_system.dart b/pkg/analyzer/lib/src/file_system/file_system.dart
new file mode 100644
index 0000000..8a6ea4b
--- /dev/null
+++ b/pkg/analyzer/lib/src/file_system/file_system.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/file_system/file_system.dart';
+
+/**
+ * A [UriResolver] for [Resource]s.
+ */
+class ResourceUriResolver extends UriResolver {
+ /**
+ * The name of the `file` scheme.
+ */
+ static final String FILE_SCHEME = "file";
+
+ final ResourceProvider _provider;
+
+ ResourceUriResolver(this._provider);
+
+ ResourceProvider get provider => _provider;
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ if (!isFileUri(uri)) {
+ return null;
+ }
+ String path = _provider.pathContext.fromUri(uri);
+ Resource resource = _provider.getResource(path);
+ if (resource is File) {
+ return resource.createSource(actualUri ?? uri);
+ }
+ return null;
+ }
+
+ @override
+ Uri restoreAbsolute(Source source) =>
+ _provider.pathContext.toUri(source.fullName);
+
+ /**
+ * Return `true` if the given [uri] is a `file` URI.
+ */
+ static bool isFileUri(Uri uri) => uri.scheme == FILE_SCHEME;
+}
diff --git a/pkg/analyzer/lib/src/generated/bazel.dart b/pkg/analyzer/lib/src/generated/bazel.dart
index 89efeef..ae17e37 100644
--- a/pkg/analyzer/lib/src/generated/bazel.dart
+++ b/pkg/analyzer/lib/src/generated/bazel.dart
@@ -2,12 +2,11 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.generated.bazel;
-
import 'dart:collection';
import 'dart:core';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 30d1a57..0e14ee2 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -658,6 +658,21 @@
DartType staticType = _resolver.strongMode
? _getStaticTypeOrFunctionType(target)
: _getStaticType(target);
+
+ if (_resolver.strongMode &&
+ staticType is FunctionType &&
+ methodName.name == FunctionElement.CALL_METHOD_NAME) {
+ if (target is SimpleIdentifier) {
+ methodName.staticElement = target.staticElement;
+ }
+ methodName.staticType = target.staticType;
+ node.staticType = staticType;
+ node.staticInvokeType = staticType;
+ node.argumentList.correspondingStaticParameters =
+ _computeCorrespondingParameters(node.argumentList, staticType);
+ return null;
+ }
+
DartType propagatedType = _getPropagatedType(target);
staticElement = _resolveInvokedElementWithTarget(
target, staticType, methodName, isConditional);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 45b1794..56d147d 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
@@ -24,6 +23,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/api/model.dart';
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 4382091..281110b 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -7277,19 +7277,10 @@
return;
}
- var element = node.type.element;
- if (element is TypeParameterizedElement &&
- element.typeParameters.any((p) => p.bound != null)) {
+ final type = node.type;
+ if (type is TypeImpl && type.hasTypeParameterReferenceInBound) {
_errorReporter.reportErrorForNode(
- StrongModeCode.NOT_INSTANTIATED_BOUND, node, [node.type]);
- }
-
- var enclosingElement = element?.enclosingElement;
- if (element is GenericFunctionTypeElement &&
- enclosingElement is GenericTypeAliasElement &&
- enclosingElement.typeParameters.any((p) => p.bound != null)) {
- _errorReporter.reportErrorForNode(
- StrongModeCode.NOT_INSTANTIATED_BOUND, node, [node.type]);
+ StrongModeCode.NOT_INSTANTIATED_BOUND, node, [type]);
}
}
}
diff --git a/pkg/analyzer/lib/src/generated/gn.dart b/pkg/analyzer/lib/src/generated/gn.dart
index 51440cb..ae31823 100644
--- a/pkg/analyzer/lib/src/generated/gn.dart
+++ b/pkg/analyzer/lib/src/generated/gn.dart
@@ -2,17 +2,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.
-library analyzer.src.generated.gn;
-
import 'dart:collection';
import 'dart:core';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/workspace.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart';
import 'package:package_config/src/packages_impl.dart';
diff --git a/pkg/analyzer/lib/src/generated/package.dart b/pkg/analyzer/lib/src/generated/package.dart
index 5983dd3..fba626f 100644
--- a/pkg/analyzer/lib/src/generated/package.dart
+++ b/pkg/analyzer/lib/src/generated/package.dart
@@ -2,18 +2,17 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.src.generated.package;
-
import 'dart:collection';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:package_config/packages.dart';
import 'package:yaml/yaml.dart';
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 69583e8..5562394 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -8885,7 +8885,7 @@
* type aliases.
*/
class TypeParameterBoundsResolver {
- final TypeProvider typeProvider;
+ final TypeSystem typeSystem;
final LibraryElement library;
final Source source;
final AnalysisErrorListener errorListener;
@@ -8894,7 +8894,7 @@
TypeNameResolver typeNameResolver = null;
TypeParameterBoundsResolver(
- this.typeProvider, this.library, this.source, this.errorListener);
+ this.typeSystem, this.library, this.source, this.errorListener);
/**
* Resolve bounds of type parameters of classes, class and function type
@@ -8964,12 +8964,8 @@
} else {
libraryScope ??= new LibraryScope(library);
typeParametersScope ??= createTypeParametersScope();
- typeNameResolver ??= new TypeNameResolver(
- new TypeSystemImpl(typeProvider),
- typeProvider,
- library,
- source,
- errorListener);
+ typeNameResolver ??= new TypeNameResolver(typeSystem,
+ typeSystem.typeProvider, library, source, errorListener);
typeNameResolver.nameScope = typeParametersScope;
_resolveTypeName(bound);
typeParameterElement.bound = bound.type;
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 16ad79b..7c76550 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -358,10 +358,15 @@
}
}
- List<TypeParameterType> getFreeParameters(DartType type) {
+ List<TypeParameterType> getFreeParameters(DartType rootType) {
List<TypeParameterType> parameters = null;
+ Set<DartType> visitedTypes = new HashSet<DartType>();
void appendParameters(DartType type) {
+ if (visitedTypes.contains(type)) {
+ return;
+ }
+ visitedTypes.add(type);
if (type is TypeParameterType && all.contains(type)) {
parameters ??= <TypeParameterType>[];
parameters.add(type);
@@ -370,7 +375,7 @@
}
}
- appendParameters(type);
+ appendParameters(rootType);
return parameters;
}
diff --git a/pkg/analyzer/lib/src/lint/analysis.dart b/pkg/analyzer/lib/src/lint/analysis.dart
index 5884ac1..006ccb6 100644
--- a/pkg/analyzer/lib/src/lint/analysis.dart
+++ b/pkg/analyzer/lib/src/lint/analysis.dart
@@ -9,11 +9,11 @@
import 'package:analyzer/file_system/file_system.dart'
show File, Folder, ResourceProvider, ResourceUriResolver;
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -23,6 +23,7 @@
import 'package:analyzer/src/lint/project.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/util/sdk.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
diff --git a/pkg/analyzer/lib/src/plugin/resolver_provider.dart b/pkg/analyzer/lib/src/plugin/resolver_provider.dart
new file mode 100644
index 0000000..abbb3a8
--- /dev/null
+++ b/pkg/analyzer/lib/src/plugin/resolver_provider.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+/**
+ * A function that will return a [UriResolver] that can be used to resolve a
+ * specific kind of URI within the analysis context rooted at the given
+ * [folder].
+ */
+typedef UriResolver ResolverProvider(Folder folder);
diff --git a/pkg/analyzer/lib/src/source/package_map_resolver.dart b/pkg/analyzer/lib/src/source/package_map_resolver.dart
new file mode 100644
index 0000000..b325201
--- /dev/null
+++ b/pkg/analyzer/lib/src/source/package_map_resolver.dart
@@ -0,0 +1,99 @@
+// 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 'dart:core';
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/asserts.dart' as asserts;
+import 'package:path/path.dart' as pathos;
+
+/**
+ * A [UriResolver] implementation for the `package:` scheme that uses a map of
+ * package names to their directories.
+ */
+class PackageMapUriResolver extends UriResolver {
+ /**
+ * The name of the `package` scheme.
+ */
+ static const String PACKAGE_SCHEME = "package";
+
+ /**
+ * A table mapping package names to the path of the directories containing
+ * the package.
+ */
+ final Map<String, List<Folder>> packageMap;
+
+ /**
+ * The [ResourceProvider] for this resolver.
+ */
+ final ResourceProvider resourceProvider;
+
+ /**
+ * Create a new [PackageMapUriResolver].
+ *
+ * [packageMap] is a table mapping package names to the paths of the
+ * directories containing the package
+ */
+ PackageMapUriResolver(this.resourceProvider, this.packageMap) {
+ asserts.notNull(resourceProvider);
+ asserts.notNull(packageMap);
+ packageMap.forEach((name, folders) {
+ if (folders.length != 1) {
+ throw new ArgumentError(
+ 'Exactly one folder must be specified for a package.'
+ 'Found $name = $folders');
+ }
+ });
+ }
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ if (!isPackageUri(uri)) {
+ return null;
+ }
+ // Prepare path.
+ String path = uri.path;
+ // Prepare path components.
+ int index = path.indexOf('/');
+ if (index == -1 || index == 0) {
+ return null;
+ }
+ // <pkgName>/<relPath>
+ String pkgName = path.substring(0, index);
+ String relPath = path.substring(index + 1);
+ // If the package is known, return the corresponding file.
+ List<Folder> packageDirs = packageMap[pkgName];
+ if (packageDirs != null) {
+ Folder packageDir = packageDirs.single;
+ File file = packageDir.getChildAssumingFile(relPath);
+ return file.createSource(uri);
+ }
+ return null;
+ }
+
+ @override
+ Uri restoreAbsolute(Source source) {
+ String sourcePath = source.fullName;
+ pathos.Context pathContext = resourceProvider.pathContext;
+ for (String pkgName in packageMap.keys) {
+ Folder pkgFolder = packageMap[pkgName][0];
+ String pkgFolderPath = pkgFolder.path;
+ if (sourcePath.startsWith(pkgFolderPath + pathContext.separator)) {
+ String relPath = sourcePath.substring(pkgFolderPath.length + 1);
+ List<String> relPathComponents = pathContext.split(relPath);
+ String relUriPath = pathos.posix.joinAll(relPathComponents);
+ return Uri.parse('$PACKAGE_SCHEME:$pkgName/$relUriPath');
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns `true` if [uri] is a `package` URI.
+ */
+ static bool isPackageUri(Uri uri) {
+ return uri.scheme == PACKAGE_SCHEME;
+ }
+}
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index f15fcd2..2271c0c 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -858,6 +858,8 @@
}
}
+class RecursiveInstantiateToBounds {}
+
/// Specialization of [ReferenceInfo] for resynthesis from linked summaries.
class _ReferenceInfo extends ReferenceInfo {
/**
@@ -983,14 +985,27 @@
InterfaceTypeImpl type =
new InterfaceTypeImpl.elementWithNameAndArgs(element, name, () {
if (typeArguments == null) {
- if (libraryResynthesizer.summaryResynthesizer.strongMode &&
- instantiateToBoundsAllowed) {
- InterfaceType instantiatedToBounds = libraryResynthesizer
- .summaryResynthesizer.context.typeSystem
- .instantiateToBounds(element.type) as InterfaceType;
- return instantiatedToBounds.typeArguments;
+ if (!_isBeingInstantiatedToBounds) {
+ _isBeingInstantiatedToBounds = true;
+ _isRecursiveWhileInstantiateToBounds = false;
+ try {
+ if (libraryResynthesizer.summaryResynthesizer.strongMode) {
+ InterfaceType instantiatedToBounds = libraryResynthesizer
+ .summaryResynthesizer.context.typeSystem
+ .instantiateToBounds(element.type) as InterfaceType;
+ if (_isRecursiveWhileInstantiateToBounds) {
+ throw new RecursiveInstantiateToBounds();
+ }
+ return instantiatedToBounds.typeArguments;
+ } else {
+ return _dynamicTypeArguments;
+ }
+ } finally {
+ _isBeingInstantiatedToBounds = false;
+ }
} else {
- return _dynamicTypeArguments;
+ _isRecursiveWhileInstantiateToBounds = true;
+ typeArguments = _dynamicTypeArguments;
}
}
return typeArguments;
@@ -1352,6 +1367,7 @@
if (declaredType && !referenceInfo.isDeclarableType) {
return DynamicTypeImpl.instance;
}
+
return referenceInfo.buildType(
instantiateToBoundsAllowed,
type.typeArguments.length,
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index d117708..fd3b106 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -4927,7 +4927,7 @@
//
RecordingErrorListener errorListener = new RecordingErrorListener();
new TypeParameterBoundsResolver(
- typeProvider, library, unitElement.source, errorListener)
+ context.typeSystem, library, unitElement.source, errorListener)
.resolveTypeBounds(unit);
//
// Record outputs.
diff --git a/pkg/analyzer/lib/src/util/absolute_path.dart b/pkg/analyzer/lib/src/util/absolute_path.dart
deleted file mode 100644
index 28f5732..0000000
--- a/pkg/analyzer/lib/src/util/absolute_path.dart
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer.src.util.absolute_path;
-
-/// The class for manipulating absolute, normalized paths.
-class AbsolutePathContext {
- static const int _COLON = 0x3A;
- static const int _LOWER_A = 0x61;
- static const int _LOWER_Z = 0x7A;
- static const int _UPPER_A = 0x41;
- static const int _UPPER_Z = 0x5A;
-
- final bool _isWindows;
- String separator;
- int _separatorChar;
- String _singlePeriodComponent;
- String _doublePeriodComponent;
- String _singlePeriodEnding;
- String _doublePeriodEnding;
-
- AbsolutePathContext(this._isWindows) {
- separator = _isWindows ? r'\' : '/';
- _separatorChar = separator.codeUnitAt(0);
- _singlePeriodComponent = separator + '.' + separator;
- _doublePeriodComponent = separator + '..' + separator;
- _singlePeriodEnding = separator + '.';
- _doublePeriodEnding = separator + '..';
- }
-
- /// Append the given relative [suffix] to the given absolute [parent].
- ///
- /// context.append('/path/to', 'foo'); // -> '/path/to/foo'
- ///
- /// The given [suffix] cannot be an absolute path or use `..`.
- String append(String parent, String suffix) {
- return '$parent$separator$suffix';
- }
-
- /// Return the part of the absolute [path] after the last separator on the
- /// context's platform.
- ///
- /// context.basename('/path/to/foo.dart'); // -> 'foo.dart'
- /// context.basename('/path/to'); // -> 'to'
- /// context.basename('/path'); // -> 'path'
- /// context.basename('/'); // -> ''
- String basename(String path) {
- int index = path.lastIndexOf(separator);
- return path.substring(index + 1);
- }
-
- /// Return the part of the absolute [path] before the last separator.
- ///
- /// context.dirname('/path/to/foo.dart'); // -> '/path/to'
- /// context.dirname('/path/to'); // -> '/path'
- /// context.dirname(r'/path'); // -> '/'
- /// context.dirname(r'/'); // -> '/'
- /// context.dirname(r'C:\path'); // -> 'C:\'
- /// context.dirname(r'C:\'); // -> 'C:\'
- String dirname(String path) {
- int firstIndex = path.indexOf(separator);
- int lastIndex = path.lastIndexOf(separator);
- return lastIndex == firstIndex
- ? path.substring(0, firstIndex + 1)
- : path.substring(0, lastIndex);
- }
-
- /// Return `true` if the given [path] is valid.
- ///
- /// context.isNormalized('/foo/bar'); // -> true
- /// context.isNormalized('/foo/bar/../baz'); // -> false
- bool isValid(String path) {
- return _isAbsolute(path) && _isNormalized(path);
- }
-
- /// Return `true` if [child] is a path beneath [parent], and `false`
- /// otherwise. Both the [child] and [parent] paths must be absolute paths.
- ///
- /// context.isWithin('/root/path', '/root/path/a'); // -> true
- /// context.isWithin('/root/path', '/root/other'); // -> false
- /// context.isWithin('/root/path', '/root/path'); // -> false
- bool isWithin(String parent, String child) {
- int parentLength = parent.length;
- int childLength = child.length;
- if (parentLength >= childLength) {
- return false;
- }
- if (child.codeUnitAt(parentLength) != _separatorChar) {
- return false;
- }
- return _startsWithUnsafe(child, parent);
- }
-
- /// Split [path] into its components using [separator].
- ///
- /// context.split('/path/to/foo'); // -> ['', 'path', 'to', 'foo']
- List<String> split(String path) {
- return path.split(separator);
- }
-
- /// If the given [child] is within the given [parent], then return the
- /// relative path from [parent] to [child]. Otherwise return `null`. Both
- /// the [child] and [parent] paths must be absolute paths.
- ///
- /// context.relative('/root/path', '/root/path/a/b.dart'); // -> 'a/b.dart'
- /// context.relative('/root/path', '/root/other.dart'); // -> null
- String suffix(String parent, String child) {
- String parentPrefix = parent + separator;
- if (child.startsWith(parentPrefix)) {
- return child.substring(parentPrefix.length);
- }
- return null;
- }
-
- /// Return `true` if the given [path] is absolute.
- ///
- /// _isAbsolute('/foo/bar'); // -> true
- /// _isAbsolute('/'); // -> true
- /// _isAbsolute('foo/bar'); // -> false
- /// _isAbsolute('C:\foo\bar'); // -> true
- /// _isAbsolute('C:\'); // -> true
- /// _isAbsolute('foo\bar'); // -> false
- bool _isAbsolute(String path) {
- if (_isWindows) {
- return path.length >= 3 &&
- _isAlphabetic(path.codeUnitAt(0)) &&
- path.codeUnitAt(1) == _COLON &&
- path.codeUnitAt(2) == _separatorChar;
- } else {
- return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar;
- }
- }
-
- /// Return `true` if the given absolute [path] is normalized.
- ///
- /// _isNormalized('/foo/bar'); // -> true
- /// _isNormalized('/foo/..bar'); // -> true
- /// _isNormalized('/foo/bar..'); // -> true
- /// _isNormalized('/'); // -> true
- /// _isNormalized('/foo/bar/../baz'); // -> false
- /// _isNormalized('/foo/bar/..'); // -> false
- bool _isNormalized(String path) {
- return !path.contains(_singlePeriodComponent) &&
- !path.contains(_doublePeriodComponent) &&
- !path.endsWith(_singlePeriodEnding) &&
- !path.endsWith(_doublePeriodEnding);
- }
-
- /// Returns whether [char] is the code for an ASCII letter (uppercase or
- /// lowercase).
- static bool _isAlphabetic(int char) {
- return char >= _UPPER_A && char <= _UPPER_Z ||
- char >= _LOWER_A && char <= _LOWER_Z;
- }
-
- /// Return `true` if [str] starts with the given [prefix].
- ///
- /// The check is done from the end of [prefix], because absolute paths
- /// usually have the same prefix, e.g. the user's home directory.
- static bool _startsWithUnsafe(String str, String prefix) {
- int len = prefix.length;
- for (int i = len - 1; i >= 0; i--) {
- if (str.codeUnitAt(i) != prefix.codeUnitAt(i)) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
new file mode 100644
index 0000000..1b33bf4
--- /dev/null
+++ b/pkg/analyzer/lib/task/model.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@deprecated
+library task.model;
+
+export 'package:analyzer/src/task/api/model.dart';
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index 610048d..c08c9cd 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -2,10 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.file_system.resource_uri_resolver_test;
-
-import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index a14fde5..42664e8 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -18,6 +18,7 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart' hide SdkLibrariesReader;
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/java_io.dart';
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 5f02ed3..73eb7d3 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -15,6 +15,7 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 043f1a3..ed41c50 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -7,7 +7,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
import 'package:analyzer/src/context/cache.dart';
@@ -17,6 +16,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/string_source.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:html/dom.dart' show Document;
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index c979ff2..94c4d91 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2176,6 +2176,37 @@
expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
}
+ void test_logicalAndExpressionStatement() {
+ // Assert that `<` and `>` are not interpreted as type arguments.
+ ExpressionStatement statement = parseStatement("C<T && T>U;");
+ BinaryExpression expression = statement.expression;
+ expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
+ }
+
+ void test_methodInvocation1() {
+ // Assert that `<` and `>` are not interpreted as type arguments.
+ ExpressionStatement statement = parseStatement("f(a < b, c > 3);");
+ assertNoErrors();
+ MethodInvocation method = statement.expression;
+ expect(method.argumentList.arguments, hasLength(2));
+ }
+
+ void test_methodInvocation2() {
+ // Assert that `<` and `>` are not interpreted as type arguments.
+ ExpressionStatement statement = parseStatement("f(a < b, c >> 3);");
+ assertNoErrors();
+ MethodInvocation method = statement.expression;
+ expect(method.argumentList.arguments, hasLength(2));
+ }
+
+ void test_methodInvocation3() {
+ // Assert that `<` and `>` are not interpreted as type arguments.
+ ExpressionStatement statement = parseStatement("f(a < b, c < d >> 3);");
+ assertNoErrors();
+ MethodInvocation method = statement.expression;
+ expect(method.argumentList.arguments, hasLength(2));
+ }
+
void test_logicalAndExpression_precedence_bitwiseOr_left() {
BinaryExpression expression = parseExpression("x | y < z");
expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
@@ -3416,10 +3447,7 @@
FormalParameterList list = parser.parseFormalParameterList();
expectNotNullIfNoErrors(list);
listener.assertErrors(usingFastaParser
- ? [
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
- expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3)
- ]
+ ? [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1)]
: [
expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 1)
@@ -3587,7 +3615,12 @@
void test_functionTypedField_invalidType_class() {
if (usingFastaParser) {
parseCompilationUnit("Function(class) x = null;",
- errors: [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 9, 5)]);
+ errors: usingFastaParser
+ ? [
+ expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 9, 5),
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 9, 5)
+ ]
+ : [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 9, 5)]);
}
}
@@ -3617,7 +3650,6 @@
? [
expectedError(ScannerErrorCode.EXPECTED_TOKEN, 20, 1),
expectedError(ScannerErrorCode.EXPECTED_TOKEN, 20, 1),
- expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 8),
expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 20, 0),
]
: [
@@ -3666,14 +3698,12 @@
}''');
CompilationUnit unit = parser.parseCompilationUnit2();
expectNotNullIfNoErrors(unit);
- listener.assertErrors([
- expectedError(
- usingFastaParser
- ? ParserErrorCode.EXPECTED_TOKEN
- : ParserErrorCode.UNEXPECTED_TOKEN,
- 30,
- 1)
- ]);
+ listener.assertErrors(usingFastaParser
+ ? [
+ expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 30, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 30, 1)
+ ]
+ : [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 30, 1)]);
}
void test_getterInFunction_block_noReturnType() {
@@ -5608,7 +5638,7 @@
FormalParameterList list = parser.parseFormalParameterList();
expectNotNullIfNoErrors(list);
listener.assertErrors(usingFastaParser
- ? [expectedError(ParserErrorCode.VAR_AND_TYPE, 5, 3)]
+ ? [expectedError(ParserErrorCode.VAR_AND_TYPE, 1, 3)]
: [expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 1)]);
}
@@ -9172,15 +9202,14 @@
}
void test_parseFormalParameterList_prefixedType_partial2() {
- int errorOffset = usingFastaParser ? 4 : 3;
FormalParameterList list = parseFormalParameterList('(io.,a)', errors: [
expectedError(
usingFastaParser
? ParserErrorCode.EXPECTED_TYPE_NAME
: ParserErrorCode.MISSING_IDENTIFIER,
- errorOffset,
+ 4,
1),
- expectedError(ParserErrorCode.MISSING_IDENTIFIER, errorOffset, 1)
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 1)
]);
expect(list, isNotNull);
expect(list.leftParenthesis, isNotNull);
@@ -13146,6 +13175,20 @@
* More complex tests should be defined in the class [ComplexParserTest].
*/
abstract class SimpleParserTestMixin implements AbstractParserTestCase {
+ void test_classDeclaration_complexTypeParam() {
+ CompilationUnit unit = parseCompilationUnit('''
+class C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T> {}
+''');
+ ClassDeclaration clazz = unit.declarations[0];
+ expect(clazz.name.name, 'C');
+ expect(clazz.typeParameters.typeParameters, hasLength(1));
+ TypeParameter typeParameter = clazz.typeParameters.typeParameters[0];
+ expect(typeParameter.name.name, 'T');
+ expect(typeParameter.metadata, hasLength(1));
+ Annotation metadata = typeParameter.metadata[0];
+ expect(metadata.name.name, 'Foo.bar');
+ }
+
ConstructorName parseConstructorName(String name) {
createParser('new $name();');
Statement statement = parser.parseStatement2();
@@ -15044,6 +15087,50 @@
expect(variableList.type, new isInstanceOf<GenericFunctionType>());
}
+ void test_parseNonLabeledStatement_variableDeclaration_typeParam() {
+ VariableDeclarationStatement statement = parseStatement('C<T> v;');
+ assertNoErrors();
+ VariableDeclarationList variableList = statement.variables;
+ List<VariableDeclaration> variables = variableList.variables;
+ expect(variables, hasLength(1));
+ expect(variables[0].name.name, 'v');
+ TypeName typeName = variableList.type;
+ expect(typeName.name.name, 'C');
+ expect(typeName.typeArguments.arguments, hasLength(1));
+ TypeName typeArgument = typeName.typeArguments.arguments[0];
+ expect(typeArgument.name.name, 'T');
+ }
+
+ void test_parseNonLabeledStatement_variableDeclaration_typeParam2() {
+ VariableDeclarationStatement statement =
+ parseStatement('C<T /* ignored comment */ > v;');
+ assertNoErrors();
+ VariableDeclarationList variableList = statement.variables;
+ List<VariableDeclaration> variables = variableList.variables;
+ expect(variables, hasLength(1));
+ expect(variables[0].name.name, 'v');
+ TypeName typeName = variableList.type;
+ expect(typeName.name.name, 'C');
+ expect(typeName.typeArguments.arguments, hasLength(1));
+ TypeName typeArgument = typeName.typeArguments.arguments[0];
+ expect(typeArgument.name.name, 'T');
+ }
+
+ void test_parseNonLabeledStatement_variableDeclaration_typeParam3() {
+ VariableDeclarationStatement statement =
+ parseStatement('C<T Function(String s)> v;');
+ assertNoErrors();
+ VariableDeclarationList variableList = statement.variables;
+ List<VariableDeclaration> variables = variableList.variables;
+ expect(variables, hasLength(1));
+ expect(variables[0].name.name, 'v');
+ TypeName typeName = variableList.type;
+ expect(typeName.name.name, 'C');
+ expect(typeName.typeArguments.arguments, hasLength(1));
+ expect(typeName.typeArguments.arguments[0],
+ new isInstanceOf<GenericFunctionType>());
+ }
+
void test_invalid_typeParamAnnotation() {
parseCompilationUnit('main() { C<@Foo T> v; }',
errors: usingFastaParser
@@ -15056,6 +15143,36 @@
]);
}
+ void test_invalid_typeParamAnnotation2() {
+ parseCompilationUnit('main() { C<@Foo.bar(1) T> v; }',
+ errors: usingFastaParser
+ // TODO(danrubel): Improve this error to indicate that annotations
+ // are not valid in this context.
+ ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 1)]
+ : [
+ expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
+ expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1)
+ ]);
+ }
+
+ void test_invalid_typeParamAnnotation3() {
+ if (usingFastaParser) {
+ parseCompilationUnit('''
+main() {
+ C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T,
+ F Function<G>(int, String, {Bar b}),
+ void Function<H>(int i, [String j, K]),
+ A<B<C>>,
+ W<X<Y<Z>>>
+ > v;
+}''', errors: [
+ // TODO(danrubel): Improve this error to indicate that annotations
+ // are not valid in this context.
+ expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 13, 1)
+ ]);
+ }
+ }
+
void test_parseStatement_emptyTypeArgumentList() {
var declaration = parseStatement('C<> c;') as VariableDeclarationStatement;
assertErrorsWithCodes([ParserErrorCode.EXPECTED_TYPE_NAME]);
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 4f9f022..96b1156 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.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.test.generated.resolver_test_case;
-
import 'dart:async';
import 'package:analyzer/dart/ast/ast.dart';
@@ -14,12 +12,12 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.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/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
@@ -27,6 +25,7 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index eda1c21..d5dbae9 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -2,17 +2,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.
-library analyzer.test.generated.test.generated.source_factory;
-
import 'dart:convert';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine, Logger;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/source_resource.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart' as pkgfile show parse;
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index ea87317..f908337 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -368,6 +368,20 @@
verify([source]);
}
+ test_argumentTypeNotAssignable_call() async {
+ resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+ Source source = addSource(r'''
+typedef bool Predicate<T>(T object);
+
+Predicate<String> f() => null;
+
+void main() {
+ f().call(3);
+}''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE]);
+ }
+
test_argumentTypeNotAssignable_cascadeSecond() async {
Source source = addSource(r'''
// filler filler filler filler filler filler filler filler filler filler
diff --git a/pkg/analyzer/test/generated/strong_mode_driver_test.dart b/pkg/analyzer/test/generated/strong_mode_driver_test.dart
index 28609bb..4e83452 100644
--- a/pkg/analyzer/test/generated/strong_mode_driver_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_driver_test.dart
@@ -65,6 +65,18 @@
test_genericMethod_functionTypedParameter_tearoff() {
return super.test_genericMethod_functionTypedParameter_tearoff();
}
+
+ @override
+ test_notInstantiatedBound_class_error_recursion() {
+ // overridden because not failing
+ return super.test_notInstantiatedBound_class_error_recursion();
+ }
+
+ @override
+ test_notInstantiatedBound_class_error_recursion_less_direct() {
+ // overridden because not failing
+ return super.test_notInstantiatedBound_class_error_recursion_less_direct();
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
index 433d68c..fdd3388 100644
--- a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
@@ -392,48 +392,6 @@
@override
@failingTest
- test_notInstantiatedBound_direct_class_class() async {
- // Expected 1 errors of type StrongModeCode.STRONG_MODE_NOT_INSTANTIATED_BOUND, found 0
- await super.test_notInstantiatedBound_direct_class_class();
- }
-
- @override
- @failingTest
- test_notInstantiatedBound_direct_class_typedef() async {
- // Expected 1 errors of type StrongModeCode.STRONG_MODE_NOT_INSTANTIATED_BOUND, found 0
- await super.test_notInstantiatedBound_direct_class_typedef();
- }
-
- @override
- @failingTest
- test_notInstantiatedBound_direct_typedef_class() async {
- // Expected 1 errors of type StrongModeCode.STRONG_MODE_NOT_INSTANTIATED_BOUND, found 0
- await super.test_notInstantiatedBound_direct_typedef_class();
- }
-
- @override
- @failingTest
- test_notInstantiatedBound_functionType() async {
- // Expected 2 errors of type StrongModeCode.STRONG_MODE_NOT_INSTANTIATED_BOUND, found 0
- await super.test_notInstantiatedBound_functionType();
- }
-
- @override
- @failingTest
- test_notInstantiatedBound_indirect_class_class() async {
- // Expected 1 errors of type StrongModeCode.STRONG_MODE_NOT_INSTANTIATED_BOUND, found 0
- await super.test_notInstantiatedBound_indirect_class_class();
- }
-
- @override
- @failingTest
- test_notInstantiatedBound_indirect_class_class2() async {
- // Expected 2 errors of type StrongModeCode.STRONG_MODE_NOT_INSTANTIATED_BOUND, found 0
- await super.test_notInstantiatedBound_indirect_class_class2();
- }
-
- @override
- @failingTest
test_setterWithDynamicTypeIsError() async {
// Expected 2 errors of type StaticWarningCode.NON_VOID_RETURN_FOR_SETTER, found 0
await super.test_setterWithDynamicTypeIsError();
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index b7ead13..6a0a0b3 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -3910,42 +3910,48 @@
''');
}
- test_notInstantiatedBound_direct_class_class() async {
+ test_notInstantiatedBound_error_class_argument() async {
String code = r'''
-class A<T extends int> {}
+class A<K, V extends List<K>> {}
class C<T extends A> {}
''';
await resolveTestUnit(code, noErrors: false);
assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
}
- test_notInstantiatedBound_direct_class_typedef() async {
- // Check that if the bound of a class is an uninstantiated typedef
- // we emit an error
+ test_notInstantiatedBound_error_class_argument2() async {
String code = r'''
-typedef void F<T extends int>();
-class C<T extends F> {}
+class A<K, V extends List<List<K>>> {}
+class C<T extends A> {}
''';
await resolveTestUnit(code, noErrors: false);
assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
}
- test_notInstantiatedBound_direct_typedef_class() async {
- // Check that if the bound of a typeded is an uninstantiated class
- // we emit an error
+ test_notInstantiatedBound_error_class_direct() async {
String code = r'''
-class C<T extends int> {}
-typedef void F<T extends C>();
+class A<K, V extends K> {}
+class C<T extends A> {}
''';
await resolveTestUnit(code, noErrors: false);
assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
}
- test_notInstantiatedBound_functionType() async {
+ test_notInstantiatedBound_error_class_indirect() async {
+ String code = r'''
+class A<K, V extends K> {}
+class C<T extends List<A>> {}
+''';
+ await resolveTestUnit(code, noErrors: false);
+ assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+ }
+
+ test_notInstantiatedBound_error_functionType() async {
await resolveTestUnit(r'''
-class A<T extends int> {}
-class C<T extends Function(A)> {}
-class D<T extends A Function()> {}
+class A<T extends Function(T)> {}
+class B<T extends T Function()> {}
+class C<T extends A> {}
+class D<T extends B> {}
''', noErrors: false);
assertErrors(testSource, [
StrongModeCode.NOT_INSTANTIATED_BOUND,
@@ -3953,27 +3959,140 @@
]);
}
- test_notInstantiatedBound_indirect_class_class() async {
+ @failingTest
+ test_notInstantiatedBound_class_error_recursion() async {
String code = r'''
-class A<T> {}
-class B<T extends int> {}
-class C<T extends A<B>> {}
+class A<T extends B> {} // points to a
+class B<T extends A> {} // points to b
+class C<T extends A> {} // points to a cyclical type
+''';
+ await resolveTestUnit(code, noErrors: false);
+ assertErrors(testSource, [
+ StrongModeCode.NOT_INSTANTIATED_BOUND,
+ StrongModeCode.NOT_INSTANTIATED_BOUND,
+ StrongModeCode.NOT_INSTANTIATED_BOUND,
+ ]);
+ }
+
+ @failingTest
+ test_notInstantiatedBound_class_error_recursion_less_direct() async {
+ String code = r'''
+class A<T extends B<A>> {}
+class B<T extends A<B>> {}
+''';
+ await resolveTestUnit(code, noErrors: false);
+ assertErrors(testSource, [
+ StrongModeCode.NOT_INSTANTIATED_BOUND,
+ StrongModeCode.NOT_INSTANTIATED_BOUND,
+ ]);
+ }
+
+ test_notInstantiatedBound_error_typedef_argument() async {
+ String code = r'''
+class A<K, V extends List<K>> {}
+typedef void F<T extends A>();
''';
await resolveTestUnit(code, noErrors: false);
assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
}
- test_notInstantiatedBound_indirect_class_class2() async {
+ test_notInstantiatedBound_error_typedef_argument2() async {
+ String code = r'''
+class A<K, V extends List<List<K>>> {}
+typedef void F<T extends A>();
+''';
+ await resolveTestUnit(code, noErrors: false);
+ assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+ }
+
+ test_notInstantiatedBound_error_typedef_direct() async {
+ String code = r'''
+class A<K, V extends K> {}
+typedef void F<T extends A>();
+''';
+ await resolveTestUnit(code, noErrors: false);
+ assertErrors(testSource, [StrongModeCode.NOT_INSTANTIATED_BOUND]);
+ }
+
+ test_notInstantiatedBound_class_error_recursion_typedef() async {
+ String code = r'''
+typedef F(C value);
+class C<T extends F> {}
+class D<T extends C> {}
+''';
+ await resolveTestUnit(code, noErrors: false);
+ assertErrors(testSource, [
+ StrongModeCode.NOT_INSTANTIATED_BOUND,
+ StrongModeCode.NOT_INSTANTIATED_BOUND,
+ CompileTimeErrorCode.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF,
+ ]);
+ }
+
+ test_notInstantiatedBound_ok_class() async {
+ String code = r'''
+class A<T extends int> {}
+class C1<T extends A> {}
+class C2<T extends List<A>> {}
+''';
+ await resolveTestUnit(code);
+ assertNoErrors(testSource);
+ }
+
+ test_notInstantiatedBound_ok_class_class2() async {
+ String code = r'''
+class A<T> {}
+class C<T extends A<int>> {}
+class D<T extends C> {}
+''';
+ await resolveTestUnit(code);
+ assertNoErrors(testSource);
+ }
+
+ test_notInstantiatedBound_ok_class_class3() async {
+ String code = r'''
+class A<T> {}
+class B<T extends int> {}
+class C<T extends A<B>> {}
+''';
+ await resolveTestUnit(code);
+ assertNoErrors(testSource);
+ }
+
+ test_notInstantiatedBound_ok_class_class4() async {
String code = r'''
class A<K, V> {}
class B<T extends int> {}
class C<T extends A<B, B>> {}
''';
- await resolveTestUnit(code, noErrors: false);
- assertErrors(testSource, [
- StrongModeCode.NOT_INSTANTIATED_BOUND,
- StrongModeCode.NOT_INSTANTIATED_BOUND
- ]);
+ await resolveTestUnit(code);
+ assertNoErrors(testSource);
+ }
+
+ test_notInstantiatedBound_ok_class_typedef() async {
+ String code = r'''
+typedef void F<T extends int>();
+class C<T extends F> {}
+''';
+ await resolveTestUnit(code);
+ assertNoErrors(testSource);
+ }
+
+ test_notInstantiatedBound_ok_typedef_class() async {
+ String code = r'''
+class C<T extends int> {}
+typedef void F<T extends C>();
+''';
+ await resolveTestUnit(code);
+ assertNoErrors(testSource);
+ }
+
+ test_notInstantiatedBound_ok_class_function() async {
+ String code = r'''
+class A<T extends void Function<Z>()> {}
+class B<T extends A> {}
+''';
+ await resolveTestUnit(code);
+ assertNoErrors(testSource);
}
test_objectMethodOnFunctions_Anonymous() async {
diff --git a/pkg/analyzer/test/resource_utils.dart b/pkg/analyzer/test/resource_utils.dart
index c03eb1d..10aed70 100644
--- a/pkg/analyzer/test/resource_utils.dart
+++ b/pkg/analyzer/test/resource_utils.dart
@@ -10,7 +10,6 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
@@ -92,12 +91,7 @@
class TestResourceProvider implements ResourceProvider {
final ResourceProvider _provider;
- TestResourceProvider(this._provider) {
- expect(_provider.absolutePathContext.separator, isWindows ? '\\' : '/');
- }
-
- @override
- AbsolutePathContext get absolutePathContext => _provider.absolutePathContext;
+ TestResourceProvider(this._provider);
@override
path.Context get pathContext => _provider.pathContext;
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 00e24ad..4d376e4 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/yaml.dart';
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index 924704d..6072255 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -2,12 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.source.package_map_resolver_test;
-
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:path/path.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 103433e..6c184b3 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 01fbb86..2601fcd 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -4,11 +4,11 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/command_line/arguments.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/context/source.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
@@ -16,6 +16,7 @@
import 'package:analyzer/src/lint/linter.dart';
import 'package:analyzer/src/lint/registry.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:args/args.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/src/packages_impl.dart';
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 32b2cbd..279aef0 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -6,12 +6,12 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 14565dc..a4e112b 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -14,7 +14,6 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
@@ -23,6 +22,7 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
diff --git a/pkg/analyzer/test/src/context/source_test.dart b/pkg/analyzer/test/src/context/source_test.dart
index 5347f29..21c47ad 100644
--- a/pkg/analyzer/test/src/context/source_test.dart
+++ b/pkg/analyzer/test/src/context/source_test.dart
@@ -2,8 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/source.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:package_config/packages.dart';
import 'package:test/test.dart';
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index fff1a3c..dacd732 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -6,13 +6,14 @@
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/status.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 907139e..ab5f6b6 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -9,7 +9,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
@@ -18,6 +17,7 @@
import 'package:analyzer/src/dart/constant/evaluation.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode;
import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
index 7dc865f..3a84319 100644
--- a/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/file_state_test.dart
@@ -7,12 +7,13 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisOptions, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
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 3cbbd73..1d2917a 100644
--- a/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/extra_code_test.dart
@@ -23,19 +23,14 @@
*/
@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], '''
+''', [ParserErrorCode.UNEXPECTED_TOKEN], '''
const annotation = null;
class A<E> {}
class C {
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 1531a12..9d6e061 100644
--- a/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/missing_code_test.dart
@@ -294,6 +294,19 @@
}
@failingTest
+ void test_missingGet() {
+ testRecovery('''
+class Bar {
+ int foo => 0;
+}
+''', [ParserErrorCode.MISSING_GET], '''
+class Bar {
+ int get foo => 0;
+}
+''');
+ }
+
+ @failingTest
void test_parameterList_leftParen() {
// https://github.com/dart-lang/sdk/issues/22938
testRecovery('''
@@ -425,7 +438,6 @@
''');
}
- @failingTest
void test_extraComma_named_noLast() {
testRecovery('''
f({a, , b}) {}
@@ -443,7 +455,6 @@
''');
}
- @failingTest
void test_extraComma_positional_noLast() {
testRecovery('''
f([a, , b]) {}
@@ -461,7 +472,6 @@
''');
}
- @failingTest
void test_extraComma_required_noLast() {
testRecovery('''
f(a, , b) {}
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 b8eb3ff..56fb98f 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
@@ -35,7 +35,7 @@
'leftBrace',
'do {',
[
- ParserErrorCode.EXPECTED_TOKEN,
+ ScannerErrorCode.EXPECTED_TOKEN,
ParserErrorCode.EXPECTED_TOKEN,
ParserErrorCode.EXPECTED_TOKEN,
ParserErrorCode.MISSING_IDENTIFIER,
@@ -43,7 +43,7 @@
ParserErrorCode.EXPECTED_TOKEN
],
"do {} while (_s_);",
- allFailing: true),
+ failing: allExceptEof),
new TestDescriptor(
'rightBrace',
'do {}',
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 9cd9192..7c73192 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
@@ -32,9 +32,13 @@
new TestDescriptor(
'keyword',
'export',
- [/*ParserErrorCode.MISSING_URI,*/ ParserErrorCode.EXPECTED_TOKEN],
- "export '';",
- allFailing: true),
+ [
+ // TODO(danrubel): Consider an improved error message
+ // ParserErrorCode.MISSING_URI,
+ ParserErrorCode.EXPECTED_STRING_LITERAL,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "export '';"),
new TestDescriptor('emptyUri', "export ''",
[ParserErrorCode.EXPECTED_TOKEN], "export '';"),
new TestDescriptor('uri', "export 'a.dart'",
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 eb6dfc6..52cf298 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,17 +12,19 @@
class ImportDirectivesTest extends PartialCodeTest {
buildAll() {
- List<String> allExceptEof =
- PartialCodeTest.prePartSuffixes.map((t) => t.name).toList();
buildTests(
'import_directive',
[
new TestDescriptor(
'keyword',
'import',
- [/*ParserErrorCode.MISSING_URI,*/ ParserErrorCode.EXPECTED_TOKEN],
- "import '';",
- allFailing: true),
+ [
+ // TODO(danrubel): Consider an improved error message
+ // ParserErrorCode.MISSING_URI,
+ ParserErrorCode.EXPECTED_STRING_LITERAL,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "import '';"),
new TestDescriptor('emptyUri', "import ''",
[ParserErrorCode.EXPECTED_TOKEN], "import '';"),
new TestDescriptor('fullUri', "import 'a.dart'",
@@ -46,7 +48,7 @@
ParserErrorCode.EXPECTED_TOKEN
],
"import 'a.dart' if (_s_) '';",
- failing: allExceptEof),
+ failing: ['functionNonVoid', 'getter', 'setter']),
new TestDescriptor(
'ifId',
"import 'a.dart' if (b",
@@ -55,8 +57,7 @@
ParserErrorCode.EXPECTED_TOKEN,
ParserErrorCode.EXPECTED_STRING_LITERAL
],
- "import 'a.dart' if (b) '';",
- failing: allExceptEof),
+ "import 'a.dart' if (b) '';"),
new TestDescriptor(
'ifEquals',
"import 'a.dart' if (b ==",
@@ -66,8 +67,7 @@
ScannerErrorCode.EXPECTED_TOKEN,
ParserErrorCode.EXPECTED_STRING_LITERAL
],
- "import 'a.dart' if (b == '') '';",
- failing: allExceptEof),
+ "import 'a.dart' if (b == '') '';"),
new TestDescriptor(
'ifCondition',
"import 'a.dart' if (b)",
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 23eac88..388eec1 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
@@ -59,14 +59,8 @@
],
"const a, _s_;",
failing: <String>[
- 'assert',
- 'block',
- 'break',
- 'continue',
- 'for',
'labeled',
'localFunctionNonVoid',
- 'return',
]),
new TestDescriptor(
'constTypeNameComma',
@@ -77,14 +71,8 @@
],
"const int a, _s_;",
failing: [
- 'assert',
- 'block',
- 'break',
- 'continue',
- 'for',
'labeled',
'localFunctionNonVoid',
- 'return',
]),
new TestDescriptor('constNameCommaName', 'const a, b',
[ParserErrorCode.EXPECTED_TOKEN], "const a, b;"),
@@ -99,16 +87,10 @@
],
"final _s_;",
failing: [
- 'assert',
- 'block',
- 'break',
- 'continue',
- 'for',
'labeled',
'localFunctionNonVoid',
'localFunctionVoid',
'localVariable',
- 'return',
]),
new TestDescriptor('finalName', 'final a',
[ParserErrorCode.EXPECTED_TOKEN], "final a;",
@@ -138,16 +120,10 @@
],
"var _s_;",
failing: [
- 'assert',
- 'block',
- 'break',
- 'continue',
- 'for',
'labeled',
'localFunctionNonVoid',
'localFunctionVoid',
'localVariable',
- 'return',
]),
new TestDescriptor(
'varName', 'var a', [ParserErrorCode.EXPECTED_TOKEN], "var a;",
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 bed24e2..814cf9b 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
@@ -18,9 +18,13 @@
new TestDescriptor(
'keyword',
'part',
- [/*ParserErrorCode.MISSING_URI,*/ ParserErrorCode.EXPECTED_TOKEN],
- "part '';",
- allFailing: true),
+ [
+ // TODO(danrubel): Consider an improved error message
+ // ParserErrorCode.MISSING_URI,
+ ParserErrorCode.EXPECTED_STRING_LITERAL,
+ ParserErrorCode.EXPECTED_TOKEN
+ ],
+ "part '';"),
new TestDescriptor('emptyUri', "part ''",
[ParserErrorCode.EXPECTED_TOKEN], "part '';"),
new TestDescriptor('uri', "part 'a.dart'",
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 c555393..60b559c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
@@ -26,6 +26,7 @@
try {
validUnit =
parseCompilationUnit(validCode, codes: expectedErrorsInValidCode);
+ validateTokenStream(validUnit.beginToken);
} catch (e) {
// print('');
// print(' Errors in valid code.');
@@ -55,8 +56,14 @@
void validateTokenStream(Token token) {
while (!token.isEof) {
- expect(token.end, lessThanOrEqualTo(token.next.offset));
- token = token.next;
+ Token next = token.next;
+ expect(token.end, lessThanOrEqualTo(next.offset));
+ if (next.isSynthetic) {
+ if (const [')', ']', '}'].contains(next.lexeme)) {
+ expect(next.beforeSynthetic, token);
+ }
+ }
+ token = next;
}
}
}
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
index 29474a0..cde9868 100644
--- a/pkg/analyzer/test/src/source/source_resource_test.dart
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -2,11 +2,10 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer.test.src.source.source_resource_test;
-
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 0b6ec9f..186ab04 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/lint/linter.dart';
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 cb9db3a..44e1444 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -11,6 +11,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../../utils.dart';
+import '../../summary/element_text.dart';
import 'strong_test_helper.dart';
void main() {
@@ -3527,58 +3528,12 @@
expect(x.type.toString(), 'void');
}
- test_instantiateToBounds_generic2_hasBound_definedAfter() async {
- var unit = await checkFileElement(r'''
-class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
-class A<T extends int> {}
-B v = null;
-''');
- expect(unit.topLevelVariables[0].type.toString(), 'B<A<dynamic>>');
- }
-
- test_instantiateToBounds_generic2_hasBound_definedBefore() async {
- var unit = await checkFileElement(r'''
-class A<T extends int> {}
-class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
-B v = null;
-''');
- expect(unit.topLevelVariables[0].type.toString(), 'B<A<dynamic>>');
- }
-
- test_instantiateToBounds_generic2_noBound() async {
- var unit = await checkFileElement(r'''
-class A<T> {}
-class B<T extends A> {}
-B v = null;
-''');
- expect(unit.topLevelVariables[0].type.toString(), 'B<A<dynamic>>');
- }
-
- test_instantiateToBounds_generic_hasBound_definedAfter() async {
- var unit = await checkFileElement(r'''
-A v = null;
-class A<T extends int> {}
-''');
- expect(unit.topLevelVariables[0].type.toString(), 'A<int>');
- }
-
- test_instantiateToBounds_generic_hasBound_definedBefore() async {
- var unit = await checkFileElement(r'''
-class A<T extends int> {}
-A v = null;
-''');
- expect(unit.topLevelVariables[0].type.toString(), 'A<int>');
- }
-
test_instantiateToBounds_invokeConstructor_noBound() async {
- var unit = await checkFile('''
+ var unit = await checkFileElement('''
class C<T> {}
-main() {
- var v = new C();
-}
+var x = /*info:INFERRED_TYPE_ALLOCATION*/new C();
''');
- var v = findLocalVariable(unit, 'v');
- expect(v.type.toString(), 'C<dynamic>');
+ expect(unit.topLevelVariables[0].type.toString(), 'C<dynamic>');
}
test_instantiateToBounds_invokeConstructor_typeArgsExact() async {
@@ -3595,7 +3550,128 @@
class B<T extends A> {}
B v = null;
''');
- expect(unit.topLevelVariables[0].type.toString(), 'B<A>');
+ checkElementText(unit.library, r'''
+class A {
+}
+class B<T extends A> {
+}
+B<A> v;
+''');
+ }
+
+ test_instantiateToBounds_typeName_error1() async {
+ var unit = await checkFileElement(r'''
+class A<T1 extends int, T2 extends T1> {}
+class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
+B v = null;
+''');
+ checkElementText(unit.library, r'''
+class A<T1 extends int, T2 extends T1> {
+}
+class B<T extends A<int, int>> {
+}
+B<A<int, int>> v;
+''');
+ }
+
+ test_instantiateToBounds_typeName_error2() async {
+ var unit = await checkFileElement(r'''
+class A<T1 extends T2, T2 extends int> {}
+class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
+B v = null;
+''');
+ checkElementText(unit.library, r'''
+class A<T1 extends T2, T2 extends int> {
+}
+class B<T extends A<int, int>> {
+}
+B<A<int, int>> v;
+''');
+ }
+
+ test_instantiateToBounds_typeName_error3() async {
+ var unit = await checkFileElement(r'''
+class A<T1 extends int, T2 extends List<T1>> {}
+class B<T extends /*error:NOT_INSTANTIATED_BOUND*/A> {}
+B v = null;
+''');
+ checkElementText(unit.library, r'''
+class A<T1 extends int, T2 extends List<T1>> {
+}
+class B<T extends A<int, List<int>>> {
+}
+B<A<int, List<int>>> v;
+''');
+ }
+
+ @failingTest
+ test_instantiateToBounds_typeName_OK_hasBound_definedAfter() async {
+ var unit = await checkFileElement(r'''
+class B<T extends A> {}
+class A<T extends int> {}
+B v = null;
+''');
+ checkElementText(unit.library, r'''
+class B<T extends A<int>> {
+}
+class A<T extends int> {
+}
+B<A<int>> v;
+''');
+ }
+
+ test_instantiateToBounds_typeName_OK_hasBound_definedBefore() async {
+ var unit = await checkFileElement(r'''
+class A<T extends int> {}
+class B<T extends A> {}
+B v = null;
+''');
+ checkElementText(unit.library, r'''
+class A<T extends int> {
+}
+class B<T extends A<int>> {
+}
+B<A<int>> v;
+''');
+ }
+
+ test_instantiateToBounds_typeName_OK_inBound_hasBound_definedAfter() async {
+ var unit = await checkFileElement(r'''
+A v = null;
+class A<T extends int> {}
+''');
+ checkElementText(unit.library, r'''
+class A<T extends int> {
+}
+A<int> v;
+''');
+ }
+
+ test_instantiateToBounds_typeName_OK_inBound_hasBound_definedBefore() async {
+ var unit = await checkFileElement(r'''
+class A<T extends int> {}
+A v = null;
+''');
+ checkElementText(unit.library, r'''
+class A<T extends int> {
+}
+A<int> v;
+''');
+ }
+
+ test_instantiateToBounds_typeName_OK_noBound() async {
+ var unit = await checkFileElement(r'''
+class A<T> {}
+class B<T extends A> {}
+B v = null;
+''');
+ checkElementText(unit.library, r'''
+class A<T> {
+}
+class B<T extends A<dynamic>> {
+}
+B<A<dynamic>> v;
+''');
}
test_lambdaDoesNotHavePropagatedTypeHint() async {
@@ -4354,11 +4430,34 @@
bool get hasExtraTaskModelPass => false;
@override
+ test_instantiateToBounds_typeName_OK_hasBound_definedAfter() async {
+ await super.test_instantiateToBounds_typeName_OK_hasBound_definedAfter();
+ }
+
+ @override
+ test_listLiteralsCanInferNull_topLevel() =>
+ super.test_listLiteralsCanInferNull_topLevel();
+
+ @override
+ test_mapLiteralsCanInferNull_topLevel() =>
+ super.test_mapLiteralsCanInferNull_topLevel();
+
+ @override
+ test_nullCoalescingOperator() async {
+ await super.test_nullCoalescingOperator();
+ }
+
+ @override
test_circularReference_viaClosures() async {
await super.test_circularReference_viaClosures();
}
@override
+ test_unsafeBlockClosureInference_closureCall() async {
+ await super.test_unsafeBlockClosureInference_closureCall();
+ }
+
+ @override
test_circularReference_viaClosures_initializerTypes() async {
await super.test_circularReference_viaClosures_initializerTypes();
}
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index f1c59c2..bd0f90a 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -26,6 +26,7 @@
import 'package:front_end/src/base/performance_logger.dart';
import 'package:source_span/source_span.dart';
import 'package:test/test.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import '../../context/mock_sdk.dart';
diff --git a/pkg/analyzer/test/src/util/absolute_path_test.dart b/pkg/analyzer/test/src/util/absolute_path_test.dart
deleted file mode 100644
index 42c8449..0000000
--- a/pkg/analyzer/test/src/util/absolute_path_test.dart
+++ /dev/null
@@ -1,141 +0,0 @@
-// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library analyzer.test.src.util.absolute_path_test;
-
-import 'package:analyzer/src/util/absolute_path.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(AbsolutePathContextPosixTest);
- defineReflectiveTests(AbsolutePathContextWindowsTest);
- });
-}
-
-@reflectiveTest
-class AbsolutePathContextPosixTest {
- AbsolutePathContext context = new AbsolutePathContext(false);
-
- void test_append() {
- expect(context.append(r'/path/to', r'foo.dart'), r'/path/to/foo.dart');
- }
-
- void test_basename() {
- expect(context.basename(r'/path/to/foo.dart'), r'foo.dart');
- expect(context.basename(r'/path/to'), r'to');
- expect(context.basename(r'/path'), r'path');
- expect(context.basename(r'/'), r'');
- }
-
- void test_dirname() {
- expect(context.dirname(r'/path/to/foo.dart'), r'/path/to');
- expect(context.dirname(r'/path/to'), r'/path');
- expect(context.dirname(r'/path'), r'/');
- expect(context.dirname(r'/'), r'/');
- }
-
- void test_isValid_absolute() {
- expect(context.isValid(r'/foo/bar'), isTrue);
- expect(context.isValid(r'/foo'), isTrue);
- expect(context.isValid(r'/'), isTrue);
- expect(context.isValid(r''), isFalse);
- expect(context.isValid(r'foo/bar'), isFalse);
- }
-
- void test_isValid_normalized() {
- expect(context.isValid(r'/foo/bar'), isTrue);
- expect(context.isValid(r'/foo/..bar'), isTrue);
- expect(context.isValid(r'/foo/.bar/baz'), isTrue);
- expect(context.isValid(r'/foo/...'), isTrue);
- expect(context.isValid(r'/foo/bar..'), isTrue);
- expect(context.isValid(r'/foo/.../bar'), isTrue);
- expect(context.isValid(r'/foo/.bar/.'), isFalse);
- expect(context.isValid(r'/foo/bar/../baz'), isFalse);
- expect(context.isValid(r'/foo/bar/..'), isFalse);
- expect(context.isValid(r'/foo/./bar'), isFalse);
- expect(context.isValid(r'/.'), isFalse);
- }
-
- void test_isWithin() {
- expect(context.isWithin(r'/root/path', r'/root/path/a'), isTrue);
- expect(context.isWithin(r'/root/path', r'/root/other'), isFalse);
- expect(context.isWithin(r'/root/path', r'/root/path'), isFalse);
- }
-
- void test_split() {
- expect(context.split(r'/path/to/foo'), [r'', r'path', r'to', r'foo']);
- expect(context.split(r'/path'), [r'', r'path']);
- }
-
- void test_suffix() {
- expect(context.suffix(r'/root/path', r'/root/path/a/b.dart'), r'a/b.dart');
- expect(context.suffix(r'/root/path', r'/root/other.dart'), isNull);
- }
-}
-
-@reflectiveTest
-class AbsolutePathContextWindowsTest {
- AbsolutePathContext context = new AbsolutePathContext(true);
-
- void test_append() {
- expect(context.append(r'C:\path\to', r'foo.dart'), r'C:\path\to\foo.dart');
- }
-
- void test_basename() {
- expect(context.basename(r'C:\path\to\foo.dart'), r'foo.dart');
- expect(context.basename(r'C:\path\to'), r'to');
- expect(context.basename(r'C:\path'), r'path');
- expect(context.basename(r'C:\'), r'');
- }
-
- void test_dirname() {
- expect(context.dirname(r'C:\path\to\foo.dart'), r'C:\path\to');
- expect(context.dirname(r'C:\path\to'), r'C:\path');
- expect(context.dirname(r'C:\path'), r'C:\');
- expect(context.dirname(r'C:\'), r'C:\');
- }
-
- void test_isValid_absolute() {
- expect(context.isValid(r'C:\foo\bar'), isTrue);
- expect(context.isValid(r'c:\foo\bar'), isTrue);
- expect(context.isValid(r'D:\foo\bar'), isTrue);
- expect(context.isValid(r'C:\foo'), isTrue);
- expect(context.isValid(r'C:\'), isTrue);
- expect(context.isValid(r''), isFalse);
- expect(context.isValid(r'foo\bar'), isFalse);
- }
-
- void test_isValid_normalized() {
- expect(context.isValid(r'C:\foo\bar'), isTrue);
- expect(context.isValid(r'C:\foo\..bar'), isTrue);
- expect(context.isValid(r'C:\foo\.bar\baz'), isTrue);
- expect(context.isValid(r'C:\foo\...'), isTrue);
- expect(context.isValid(r'C:\foo\bar..'), isTrue);
- expect(context.isValid(r'C:\foo\...\bar'), isTrue);
- expect(context.isValid(r'C:\foo\.bar\.'), isFalse);
- expect(context.isValid(r'C:\foo\bar\..\baz'), isFalse);
- expect(context.isValid(r'C:\foo\bar\..'), isFalse);
- expect(context.isValid(r'C:\foo\.\bar'), isFalse);
- expect(context.isValid(r'C:\.'), isFalse);
- }
-
- void test_isWithin() {
- expect(context.isWithin(r'C:\root\path', r'C:\root\path\a'), isTrue);
- expect(context.isWithin(r'C:\root\path', r'C:\root\other'), isFalse);
- expect(context.isWithin(r'C:\root\path', r'C:\root\path'), isFalse);
- }
-
- void test_split() {
- expect(context.split(r'C:\path\to\foo'), [r'C:', r'path', r'to', r'foo']);
- expect(context.split(r'C:\path'), [r'C:', r'path']);
- }
-
- void test_suffix() {
- expect(
- context.suffix(r'C:\root\path', r'C:\root\path\a\b.dart'), r'a\b.dart');
- expect(context.suffix(r'C:\root\path', r'C:\root\other.dart'), isNull);
- }
-}
diff --git a/pkg/analyzer/test/src/util/test_all.dart b/pkg/analyzer/test/src/util/test_all.dart
index de12251..d9cd7bd 100644
--- a/pkg/analyzer/test/src/util/test_all.dart
+++ b/pkg/analyzer/test/src/util/test_all.dart
@@ -6,7 +6,6 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'absolute_path_test.dart' as absolute_path_test;
import 'asserts_test.dart' as asserts_test;
import 'glob_test.dart' as glob_test;
import 'lru_map_test.dart' as lru_map_test;
@@ -15,7 +14,6 @@
/// Utility for manually running all tests.
main() {
defineReflectiveSuite(() {
- absolute_path_test.main();
asserts_test.main();
glob_test.main();
lru_map_test.main();
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index e3ddb67..53477e1 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -15,8 +15,6 @@
* of exactly one task.
* - Convert this tool to use package_config to find the package map.
*/
-library analyzer.tool.task_dependency_graph.generate;
-
import 'dart:async';
import 'dart:io' hide File;
import 'dart:io' as io;
@@ -24,19 +22,19 @@
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
import 'package:front_end/src/codegen/tools.dart';
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index ca20983..492de93 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -9,13 +9,12 @@
import 'package:analyzer/file_system/file_system.dart' as file_system;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/plugin/resolver_provider.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/interner.dart';
@@ -25,8 +24,10 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_general.dart'
show PerformanceTag;
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/pubspec/pubspec_validator.dart';
import 'package:analyzer/src/source/package_map_provider.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/source/path_filter.dart';
import 'package:analyzer/src/source/pub_package_map_provider.dart';
import 'package:analyzer/src/source/sdk_ext.dart';
@@ -509,7 +510,7 @@
resolvers
.add(new InSummaryUriResolver(resourceProvider, summaryDataStore));
resolvers.add(resolver);
- resolvers.add(new file_system.ResourceUriResolver(resourceProvider));
+ resolvers.add(new ResourceUriResolver(resourceProvider));
return new SourceFactory(resolvers);
}
}
@@ -579,7 +580,7 @@
}
// Finally files.
- resolvers.add(new file_system.ResourceUriResolver(resourceProvider));
+ resolvers.add(new ResourceUriResolver(resourceProvider));
return new SourceFactory(resolvers, packageInfo.packages);
}
diff --git a/pkg/analyzer_cli/lib/starter.dart b/pkg/analyzer_cli/lib/starter.dart
index 206fff6..40d480c 100644
--- a/pkg/analyzer_cli/lib/starter.dart
+++ b/pkg/analyzer_cli/lib/starter.dart
@@ -2,11 +2,9 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-library analyzer_cli.starter;
-
import 'dart:async';
-import 'package:analyzer/plugin/resolver_provider.dart';
+import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer_cli/src/driver.dart';
import 'package:plugin/plugin.dart';
diff --git a/pkg/analyzer_cli/tool/perf.dart b/pkg/analyzer_cli/tool/perf.dart
index 4aa3aa6..3e622c8 100644
--- a/pkg/analyzer_cli/tool/perf.dart
+++ b/pkg/analyzer_cli/tool/perf.dart
@@ -3,25 +3,23 @@
// BSD-style license that can be found in the LICENSE file.
/// An entrypoint used to run portions of analyzer and measure its performance.
-library analyzer_cli.tool.perf;
-
import 'dart:async';
import 'dart:io' show exit;
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver;
import 'package:analyzer/file_system/physical_file_system.dart'
show PhysicalResourceProvider;
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:package_config/discovery.dart';
main(List<String> args) async {
diff --git a/pkg/analyzer_plugin/test/support/abstract_context.dart b/pkg/analyzer_plugin/test/support/abstract_context.dart
index e5b4622..844b487 100644
--- a/pkg/analyzer_plugin/test/support/abstract_context.dart
+++ b/pkg/analyzer_plugin/test/support/abstract_context.dart
@@ -11,16 +11,17 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/engine.dart' as engine;
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/element_search.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'mock_sdk.dart';
diff --git a/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart b/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
index 6bb494c..9211a5e 100644
--- a/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
+++ b/pkg/analyzer_plugin/test/utilities/completion/completion_contributor_util.dart
@@ -6,8 +6,8 @@
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_core.dart';
import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 140d9e8..04c300e 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -18,6 +18,8 @@
import 'universe/call_structure.dart' show CallStructure;
import 'universe/selector.dart' show Selector;
import 'universe/call_structure.dart';
+import 'universe/world_builder.dart';
+import 'world.dart';
/// The common elements and types in Dart.
class CommonElements {
@@ -160,11 +162,39 @@
_findConstructor(symbolImplementationClass, '');
}
+ bool _computedSymbolConstructorDependencies = false;
+ ConstructorEntity _symbolConstructorImplementationTarget;
+
+ void _ensureSymbolConstructorDependencies() {
+ if (_computedSymbolConstructorDependencies) return;
+ _computedSymbolConstructorDependencies = true;
+ if (_symbolConstructorTarget == null) {
+ if (_symbolImplementationClass == null) {
+ _symbolImplementationClass =
+ _findClass(internalLibrary, 'Symbol', required: false);
+ }
+ if (_symbolImplementationClass != null) {
+ _symbolConstructorTarget =
+ _findConstructor(_symbolImplementationClass, '', required: false);
+ }
+ }
+ if (_symbolClass == null) {
+ _symbolClass = _findClass(coreLibrary, 'Symbol', required: false);
+ }
+ if (_symbolClass == null) {
+ return;
+ }
+ _symbolConstructorImplementationTarget =
+ _findConstructor(symbolClass, '', required: false);
+ }
+
/// Whether [element] is the same as [symbolConstructor]. Used to check
/// for the constructor without computing it until it is likely to be seen.
bool isSymbolConstructor(ConstructorEntity element) {
- return element == symbolConstructorTarget ||
- element == _findConstructor(symbolClass, '', required: false);
+ assert(element != null);
+ _ensureSymbolConstructorDependencies();
+ return element == _symbolConstructorImplementationTarget ||
+ element == _symbolConstructorTarget;
}
/// The `MirrorSystem` class in dart:mirrors.
@@ -698,10 +728,13 @@
ClassEntity get jsUInt31Class =>
_jsUInt31Class ??= _findInterceptorsClass('JSUInt31');
- FunctionEntity _findIndexForNativeSubclassType;
- FunctionEntity get findIndexForNativeSubclassType =>
- _findIndexForNativeSubclassType ??= _findLibraryMember(
- interceptorsLibrary, 'findIndexForNativeSubclassType');
+ /// Returns `true` member is the 'findIndexForNativeSubclassType' method
+ /// declared in `dart:_interceptors`.
+ bool isFindIndexForNativeSubclassType(MemberEntity member) {
+ return member.name == 'findIndexForNativeSubclassType' &&
+ member.isTopLevel &&
+ member.library == interceptorsLibrary;
+ }
FunctionEntity _getInterceptorMethod;
FunctionEntity get getInterceptorMethod =>
@@ -712,9 +745,10 @@
_getNativeInterceptorMethod ??=
_findInterceptorsFunction('getNativeInterceptor');
- MemberEntity _jsIndexableLength;
- MemberEntity get jsIndexableLength =>
- _jsIndexableLength ??= _findClassMember(jsIndexableClass, 'length');
+ /// Returns `true` if [selector] applies to `JSIndexable.length`.
+ bool appliesToJsIndexableLength(Selector selector) {
+ return selector.name == 'length' && (selector.isGetter || selector.isCall);
+ }
ConstructorEntity _jsArrayTypedConstructor;
ConstructorEntity get jsArrayTypedConstructor =>
@@ -728,6 +762,33 @@
FunctionEntity get jsArrayAdd =>
_jsArrayAdd ??= _findClassMember(jsArrayClass, 'add');
+ bool isJsStringClass(ClassEntity cls) {
+ return cls.name == 'JSString' && cls.library == interceptorsLibrary;
+ }
+
+ bool isJsStringSplit(MemberEntity member) {
+ return member.name == 'split' &&
+ member.isInstanceMember &&
+ isJsStringClass(member.enclosingClass);
+ }
+
+ /// Returns `true` if [selector] applies to `JSString.split` on [receiver]
+ /// in the given [world].
+ ///
+ /// Returns `false` if `JSString.split` is not available.
+ bool appliesToJsStringSplit(
+ Selector selector, ReceiverConstraint receiver, World world) {
+ if (_jsStringSplit == null) {
+ ClassEntity cls =
+ _findClass(interceptorsLibrary, 'JSString', required: false);
+ if (cls == null) return false;
+ _jsStringSplit = _findClassMember(cls, 'split', required: false);
+ if (_jsStringSplit == null) return false;
+ }
+ return selector.applies(_jsStringSplit) &&
+ (receiver == null || receiver.canHit(jsStringSplit, selector, world));
+ }
+
FunctionEntity _jsStringSplit;
FunctionEntity get jsStringSplit =>
_jsStringSplit ??= _findClassMember(jsStringClass, 'split');
@@ -1122,6 +1183,12 @@
_env.lookupLibrary(Uris.dart__native_typed_data, required: true),
'NativeTypedArrayOfInt');
+ ClassEntity _typedArrayOfDoubleClass;
+ ClassEntity get typedArrayOfDoubleClass =>
+ _typedArrayOfDoubleClass ??= _findClass(
+ _env.lookupLibrary(Uris.dart__native_typed_data, required: true),
+ 'NativeTypedArrayOfDouble');
+
// From dart:_js_embedded_names
/// Holds the class for the [JsGetName] enum.
@@ -1420,6 +1487,11 @@
/// Returns the function type variables defined on [function].
List<TypeVariableType> getFunctionTypeVariables(FunctionEntity function);
+ /// Returns the 'element' type of a function with an async, async* ot sync*
+ /// marker. The return type of the method is inspected to determine the type
+ /// parameter of the Future, Stream or Iterable.
+ DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function);
+
/// Returns the type of [field].
DartType getFieldType(FieldEntity field);
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index e63edc3..7bc310e 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -170,6 +170,12 @@
bool compilationFailed = false;
+ // Callback function used for testing resolution enqueuing.
+ void Function() onResolutionQueueEmptyForTesting;
+
+ // Callback function used for testing codegen enqueuing.
+ void Function() onCodegenQueueEmptyForTesting;
+
Compiler(
{CompilerOptions options,
api.CompilerOutput outputProvider,
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index ad5e6f2..e97726c 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -128,7 +128,9 @@
compiler.globalInference.results.resultOfParameter(e);
FieldInfo visitField(FieldEntity field) {
- if (!_hasBeenResolved(field)) return null;
+ if (!_hasBeenResolved(field)) {
+ return null;
+ }
TypeMask inferredType = _resultOfMember(field).type;
// If a field has an empty inferred type it is never used.
if (inferredType == null || inferredType.isEmpty) return null;
@@ -163,6 +165,12 @@
return info;
}
+ bool _hasBeenResolved(MemberEntity entity) {
+ return compiler.globalInference.typesInferrerInternal.inferrer.types
+ .memberTypeInformations
+ .containsKey(entity);
+ }
+
ClassInfo visitClass(ClassEntity clazz) {
// Omit class if it is not needed.
if (!_hasClassBeenResolved(clazz)) return null;
@@ -372,11 +380,6 @@
return _infoFromOutputUnit(outputUnit);
}
- bool _hasBeenResolved(Entity entity) {
- return compiler.enqueuer.codegenEnqueuerForTesting.processedEntities
- .contains(entity);
- }
-
bool _hasClassBeenResolved(ClassEntity cls) {
return compiler.backend.mirrorsData.isClassResolved(cls);
}
diff --git a/pkg/compiler/lib/src/elements/resolution_types.dart b/pkg/compiler/lib/src/elements/resolution_types.dart
index 2ae43fa..4b80a11 100644
--- a/pkg/compiler/lib/src/elements/resolution_types.dart
+++ b/pkg/compiler/lib/src/elements/resolution_types.dart
@@ -162,6 +162,12 @@
/// Is [: true :] if this type contains any type variables.
bool get containsTypeVariables => typeVariableOccurrence != null;
+ bool get containsFreeTypeVariables {
+ assert(!containsMethodTypeVariableType,
+ 'Used only after removing method type variables');
+ return containsTypeVariables;
+ }
+
/// Returns a textual representation of this type as if it was the type
/// of a member named [name].
String getStringAsDeclared(String name) {
@@ -1233,10 +1239,12 @@
}
bool isPotentialSubtype(
- covariant ResolutionDartType t, covariant ResolutionDartType s) {
+ covariant ResolutionDartType t, covariant ResolutionDartType s,
+ {bool assumeInstantiations: true}) {
// TODO(johnniwinther): Return a set of variable points in the positive
// cases.
- return potentialSubtypeVisitor.isSubtype(t, s);
+ return potentialSubtypeVisitor.isPotentialSubtype(t, s,
+ assumeInstantiations: assumeInstantiations);
}
@override
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index c2110c7..b60700f 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -74,6 +74,12 @@
/// Whether this type contains a type variable.
bool get containsTypeVariables => false;
+ /// Whether this type contains a free class type variable or function type
+ /// variable.
+ // TODO(sra): Review uses of [containsTypeVariables] for update with
+ // [containsFreeTypeVariables].
+ bool get containsFreeTypeVariables => _containsFreeTypeVariables(null);
+
/// Is `true` if this type is the 'Object' type defined in 'dart:core'.
bool get isObject => false;
@@ -96,6 +102,8 @@
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument);
bool _equals(DartType other, _Assumptions assumptions);
+
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) => false;
}
/// Pairs of [FunctionTypeVariable]s that are currently assumed to be equivalent.
@@ -173,6 +181,11 @@
typeArguments.forEach((type) => type.forEachTypeVariable(f));
}
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
+ return typeArguments
+ .any((type) => type._containsFreeTypeVariables(bindings));
+ }
+
InterfaceType subst(List<DartType> arguments, List<DartType> parameters) {
if (typeArguments.isEmpty) {
// Return fast on non-generic types.
@@ -263,6 +276,9 @@
typeArguments.forEach((type) => type.forEachTypeVariable(f));
}
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) =>
+ typeArguments.any((type) => type._containsFreeTypeVariables(bindings));
+
TypedefType subst(List<DartType> arguments, List<DartType> parameters) {
if (typeArguments.isEmpty) {
// Return fast on non-generic types.
@@ -350,6 +366,8 @@
@override
bool get isMalformed => true;
+
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) => false;
}
class TypeVariableType extends DartType {
@@ -365,6 +383,8 @@
f(this);
}
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) => true;
+
DartType subst(List<DartType> arguments, List<DartType> parameters) {
assert(arguments.length == parameters.length);
if (parameters.isEmpty) {
@@ -433,6 +453,12 @@
@override
bool get isFunctionTypeVariable => true;
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
+ if (bindings == null) return true;
+ if (bindings.indexOf(this) >= 0) return false;
+ return true;
+ }
+
DartType subst(List<DartType> arguments, List<DartType> parameters) {
assert(arguments.length == parameters.length);
if (parameters.isEmpty) {
@@ -564,6 +590,29 @@
namedParameterTypes.forEach((type) => type.forEachTypeVariable(f));
}
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) {
+ int restore;
+ if (typeVariables.isNotEmpty) {
+ if (bindings == null) {
+ bindings = <FunctionTypeVariable>[];
+ } else {
+ restore = bindings.length;
+ }
+ bindings.addAll(typeVariables);
+ }
+
+ bool hasFree(DartType type) => type._containsFreeTypeVariables(bindings);
+
+ bool result = hasFree(returnType) ||
+ typeVariables.any((type) => hasFree(type.bound)) ||
+ parameterTypes.any(hasFree) ||
+ optionalParameterTypes.any(hasFree) ||
+ namedParameterTypes.any(hasFree);
+
+ if (restore != null) bindings.length = restore;
+ return result;
+ }
+
bool get isFunctionType => true;
DartType subst(List<DartType> arguments, List<DartType> parameters) {
@@ -674,7 +723,7 @@
}
}
}
- bool result = returnType == other.returnType &&
+ bool result = returnType._equals(other.returnType, assumptions) &&
_equalTypes(parameterTypes, other.parameterTypes, assumptions) &&
_equalTypes(optionalParameterTypes, other.optionalParameterTypes,
assumptions) &&
@@ -778,6 +827,9 @@
typeArgument.forEachTypeVariable(f);
}
+ bool _containsFreeTypeVariables(List<FunctionTypeVariable> bindings) =>
+ typeArgument._containsFreeTypeVariables(bindings);
+
R accept<R, A>(DartTypeVisitor<R, A> visitor, A argument) =>
visitor.visitFutureOrType(this, argument);
@@ -981,29 +1033,37 @@
if (s is! FunctionType) return false;
FunctionType tf = t;
FunctionType sf = s;
- if (invalidFunctionReturnTypes(tf.returnType, sf.returnType)) {
+ int typeVariablesCount = getCommonTypeVariablesCount(tf, sf);
+ if (typeVariablesCount == null) {
return false;
}
-
- if (tf.typeVariables.length != sf.typeVariables.length) {
- return false;
- }
- for (int i = 0; i < tf.typeVariables.length; i++) {
+ for (int i = 0; i < typeVariablesCount; i++) {
assumptions.assume(tf.typeVariables[i], sf.typeVariables[i]);
}
- for (int i = 0; i < tf.typeVariables.length; i++) {
+ for (int i = 0; i < typeVariablesCount; i++) {
if (!tf.typeVariables[i].bound
._equals(sf.typeVariables[i].bound, assumptions)) {
return false;
}
}
+ if (invalidFunctionReturnTypes(tf.returnType, sf.returnType)) {
+ return false;
+ }
+
bool result = visitFunctionTypeInternal(tf, sf);
- for (int i = 0; i < tf.typeVariables.length; i++) {
+ for (int i = 0; i < typeVariablesCount; i++) {
assumptions.forget(tf.typeVariables[i], sf.typeVariables[i]);
}
return result;
}
+ int getCommonTypeVariablesCount(FunctionType t, FunctionType s) {
+ if (t.typeVariables.length == s.typeVariables.length) {
+ return t.typeVariables.length;
+ }
+ return null;
+ }
+
bool visitFunctionTypeInternal(FunctionType tf, FunctionType sf) {
// TODO(johnniwinther): Rewrite the function subtyping to be more readable
// but still as efficient.
@@ -1249,12 +1309,34 @@
/// `false` only if we are sure no such substitution exists.
abstract class PotentialSubtypeVisitor<T extends DartType>
extends SubtypeVisitor<T> {
+ bool _assumeInstantiations = true;
+
bool isSubtype(DartType t, DartType s) {
if (t is TypeVariableType || s is TypeVariableType) {
return true;
}
+ if ((t is FunctionTypeVariable || s is FunctionTypeVariable) &&
+ _assumeInstantiations) {
+ return true;
+ }
return super.isSubtype(t, s);
}
+
+ int getCommonTypeVariablesCount(FunctionType t, FunctionType s) {
+ if (t.typeVariables.length == s.typeVariables.length) {
+ return t.typeVariables.length;
+ }
+ if (_assumeInstantiations && s.typeVariables.length == 0) {
+ return 0;
+ }
+ return null;
+ }
+
+ bool isPotentialSubtype(DartType t, DartType s,
+ {bool assumeInstantiations: true}) {
+ _assumeInstantiations = assumeInstantiations;
+ return isSubtype(t, s);
+ }
}
/// Basic interface for the Dart type system.
@@ -1270,7 +1352,11 @@
/// Returns `true` if [t] might be a subtype of [s] for some values of
/// type variables in [s] and [t].
- bool isPotentialSubtype(DartType t, DartType s);
+ ///
+ /// If [assumeInstantiations], generic function types are assumed to be
+ /// potentially instantiated.
+ bool isPotentialSubtype(DartType t, DartType s,
+ {bool assumeInstantiations: true});
static const int IS_SUBTYPE = 1;
static const int MAYBE_SUBTYPE = 0;
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 6fa0f01..0abf135 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -55,13 +55,15 @@
}
ResolutionEnqueuer createResolutionEnqueuer() {
- return _resolution ??=
- compiler.backend.createResolutionEnqueuer(this, compiler);
+ return _resolution ??= compiler.backend
+ .createResolutionEnqueuer(this, compiler)
+ ..onEmptyForTesting = compiler.onResolutionQueueEmptyForTesting;
}
Enqueuer createCodegenEnqueuer(ClosedWorld closedWorld) {
- return codegenEnqueuerForTesting =
- compiler.backend.createCodegenEnqueuer(this, compiler, closedWorld);
+ return codegenEnqueuerForTesting = compiler.backend
+ .createCodegenEnqueuer(this, compiler, closedWorld)
+ ..onEmptyForTesting = compiler.onCodegenQueueEmptyForTesting;
}
}
@@ -213,6 +215,10 @@
/// has been emptied.
final Queue<DeferredAction> _deferredQueue = new Queue<DeferredAction>();
+ // If not `null` this is called when the queue has been emptied. It allows for
+ // applying additional impacts before re-emptying the queue.
+ void Function() onEmptyForTesting;
+
ResolutionEnqueuer(this.task, this._options, this._reporter, this.strategy,
this.listener, this._worldBuilder, this._workItemBuilder,
[this.name = 'resolution enqueuer']) {
@@ -396,7 +402,7 @@
_worldBuilder.registerClosurizedMember(element);
}
- void forEach(void f(WorkItem work)) {
+ void _forEach(void f(WorkItem work)) {
do {
while (_queue.isNotEmpty) {
// TODO(johnniwinther): Find an optimal process order.
@@ -418,6 +424,14 @@
_recentConstants);
}
+ void forEach(void f(WorkItem work)) {
+ _forEach(f);
+ if (onEmptyForTesting != null) {
+ onEmptyForTesting();
+ _forEach(f);
+ }
+ }
+
void logSummary(void log(String message)) {
log('Resolved ${processedEntities.length} elements.');
listener.logSummary(log);
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index 100fbdb..6d6b2f5 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1634,7 +1634,8 @@
TypeInformation rhsType = visit(node.value);
MemberEntity member = _elementMap.getSuperMember(
- _analyzedMember, node.name, node.interfaceTarget);
+ _analyzedMember, node.name, node.interfaceTarget,
+ setter: true);
TypeMask mask = _memberData.typeOfSend(node);
Selector selector = new Selector.setter(_elementMap.getName(node.name));
ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
diff --git a/pkg/compiler/lib/src/js/js_debug.dart b/pkg/compiler/lib/src/js/js_debug.dart
index 8851aa6..f58853e 100644
--- a/pkg/compiler/lib/src/js/js_debug.dart
+++ b/pkg/compiler/lib/src/js/js_debug.dart
@@ -12,10 +12,10 @@
import '../util/util.dart' show Indentation, Tagging;
/// Unparse the JavaScript [node].
-String nodeToString(Node node) {
+String nodeToString(Node node, {bool pretty: false}) {
JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(
- shouldCompressOutput: true,
- preferSemicolonToNewlineInMinifiedOutput: true);
+ shouldCompressOutput: !pretty,
+ preferSemicolonToNewlineInMinifiedOutput: !pretty);
LenientPrintingContext printingContext = new LenientPrintingContext();
new Printer(options, printingContext).visit(node);
return printingContext.getText();
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index b69771e..c26521e 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -1739,6 +1739,7 @@
///
/// Specific to async methods.
final js.Expression completerFactory;
+ final js.Expression completerFactoryTypeArgument;
final js.Expression wrapBody;
@@ -1748,6 +1749,7 @@
this.asyncReturn,
this.asyncRethrow,
this.completerFactory,
+ this.completerFactoryTypeArgument,
this.wrapBody,
String safeVariableName(String proposedName),
js.Name bodyName})
@@ -1799,8 +1801,10 @@
List<js.VariableInitialization> variables = <js.VariableInitialization>[];
variables.add(_makeVariableInitializer(
completer,
- new js.Call(completerFactory, [])
- .withSourceInformation(sourceInformation),
+ js.js('#(#)', [
+ completerFactory,
+ completerFactoryTypeArgument
+ ]).withSourceInformation(sourceInformation),
sourceInformation));
if (analysis.hasExplicitReturns) {
variables
@@ -1900,6 +1904,7 @@
/// Constructor creating the Iterable for a sync* method. Called with
/// [bodyName].
final js.Expression iterableFactory;
+ final js.Expression iterableFactoryTypeArgument;
/// A JS Expression that creates a marker showing that iteration is over.
///
@@ -1917,6 +1922,7 @@
SyncStarRewriter(DiagnosticReporter diagnosticListener, spannable,
{this.endOfIteration,
this.iterableFactory,
+ this.iterableFactoryTypeArgument,
this.yieldStarExpression,
this.uncaughtErrorExpression,
String safeVariableName(String proposedName),
@@ -2009,8 +2015,9 @@
"returnInnerInnerFunction": returnInnerInnerFunction,
}).withSourceInformation(functionSourceInformation);
js.Expression callIterableFactory =
- js.js("#iterableFactory(#innerFunction)", {
+ js.js("#iterableFactory(#innerFunction, #type)", {
"iterableFactory": iterableFactory,
+ "type": iterableFactoryTypeArgument,
"innerFunction": innerFunction,
}).withSourceInformation(bodySourceInformation);
js.Statement returnCallIterableFactory = new js.Return(callIterableFactory)
@@ -2108,6 +2115,7 @@
///
/// Specific to async* methods.
final js.Expression newController;
+ final js.Expression newControllerTypeArgument;
/// Used to get the `Stream` out of the [controllerName] variable.
final js.Expression streamOfController;
@@ -2128,6 +2136,7 @@
{this.asyncStarHelper,
this.streamOfController,
this.newController,
+ this.newControllerTypeArgument,
this.yieldExpression,
this.yieldStarExpression,
this.wrapBody,
@@ -2317,8 +2326,11 @@
List<js.VariableInitialization> variables = <js.VariableInitialization>[];
variables.add(_makeVariableInitializer(
controller,
- js.js('#(#)', [newController, bodyName]).withSourceInformation(
- sourceInformation),
+ js.js('#(#, #)', [
+ newController,
+ bodyName,
+ newControllerTypeArgument
+ ]).withSourceInformation(sourceInformation),
sourceInformation));
if (analysis.hasYield) {
variables.add(
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 4043360..dd73a35 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -764,7 +764,9 @@
rtiNeedBuilder,
_nativeResolutionEnqueuer,
noSuchMethodRegistry,
- const OpenWorldStrategy(),
+ compiler.options.strongMode && useStrongModeWorldStrategy
+ ? const StrongModeWorldStrategy()
+ : const OpenWorldStrategy(),
classHierarchyBuilder,
classQueries),
compiler.frontendStrategy.createResolutionWorkItemBuilder(
@@ -1154,35 +1156,20 @@
jsAst.Expression rewriteAsync(
CommonElements commonElements,
+ ElementEnvironment elementEnvironment,
FunctionEntity element,
jsAst.Expression code,
SourceInformation bodySourceInformation,
SourceInformation exitSourceInformation) {
- bool startAsyncSynchronously = compiler.options.startAsyncSynchronously;
+ if (element.asyncMarker == AsyncMarker.SYNC) return code;
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(startFunction),
- asyncAwait:
- emitter.staticFunctionAccess(commonElements.asyncHelperAwait),
- asyncReturn:
- emitter.staticFunctionAccess(commonElements.asyncHelperReturn),
- asyncRethrow:
- emitter.staticFunctionAccess(commonElements.asyncHelperRethrow),
- wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
- completerFactory:
- emitter.staticFunctionAccess(completerConstructor),
- safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
- bodyName: namer.deriveAsyncBodyName(name));
+ rewriter = _makeAsyncRewriter(
+ commonElements, elementEnvironment, element, code, name);
break;
case AsyncMarker.SYNC_STAR:
rewriter = new SyncStarRewriter(reporter, element,
@@ -1190,6 +1177,8 @@
emitter.staticFunctionAccess(commonElements.endOfIteration),
iterableFactory: emitter.staticFunctionAccess(
commonElements.syncStarIterableConstructor),
+ iterableFactoryTypeArgument:
+ _fetchItemType(element, elementEnvironment),
yieldStarExpression:
emitter.staticFunctionAccess(commonElements.yieldStar),
uncaughtErrorExpression: emitter
@@ -1206,6 +1195,8 @@
wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
newController: emitter.staticFunctionAccess(
commonElements.asyncStarControllerConstructor),
+ newControllerTypeArgument:
+ _fetchItemType(element, elementEnvironment),
safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
yieldExpression:
emitter.staticFunctionAccess(commonElements.yieldSingle),
@@ -1213,13 +1204,60 @@
emitter.staticFunctionAccess(commonElements.yieldStar),
bodyName: namer.deriveAsyncBodyName(name));
break;
- default:
- assert(element.asyncMarker == AsyncMarker.SYNC);
- return code;
}
return rewriter.rewrite(code, bodySourceInformation, exitSourceInformation);
}
+ /// Returns an expression that evaluates the type argument to the
+ /// Future/Stream/Iterable.
+ jsAst.Expression _fetchItemType(
+ FunctionEntity element, ElementEnvironment elementEnvironment) {
+ DartType type =
+ elementEnvironment.getFunctionAsyncOrSyncStarElementType(element);
+
+ if (!type.containsFreeTypeVariables) {
+ return rtiEncoder.getTypeRepresentation(emitter.emitter, type, null);
+ }
+
+ // TODO(sra): Handle types that have type variables.
+ return js('null');
+ }
+
+ AsyncRewriter _makeAsyncRewriter(
+ CommonElements commonElements,
+ ElementEnvironment elementEnvironment,
+ FunctionEntity element,
+ jsAst.Expression code,
+ jsAst.Name name) {
+ bool startAsyncSynchronously = compiler.options.startAsyncSynchronously;
+
+ var startFunction = startAsyncSynchronously
+ ? commonElements.asyncHelperStartSync
+ : commonElements.asyncHelperStart;
+ var completerConstructor = startAsyncSynchronously
+ ? commonElements.asyncAwaitCompleterConstructor
+ : commonElements.syncCompleterConstructor;
+
+ jsAst.Expression itemTypeExpression =
+ _fetchItemType(element, elementEnvironment);
+
+ var rewriter = new AsyncRewriter(reporter, element,
+ asyncStart: emitter.staticFunctionAccess(startFunction),
+ asyncAwait:
+ emitter.staticFunctionAccess(commonElements.asyncHelperAwait),
+ asyncReturn:
+ emitter.staticFunctionAccess(commonElements.asyncHelperReturn),
+ asyncRethrow:
+ emitter.staticFunctionAccess(commonElements.asyncHelperRethrow),
+ wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
+ completerFactory: emitter.staticFunctionAccess(completerConstructor),
+ completerFactoryTypeArgument: itemTypeExpression,
+ safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
+ bodyName: namer.deriveAsyncBodyName(name));
+
+ return rewriter;
+ }
+
/// Creates an impact strategy to use for compilation.
ImpactStrategy createImpactStrategy(
{bool supportDeferredLoad: true, bool supportDumpInfo: true}) {
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index 056757e..c69a632 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -47,6 +47,9 @@
/// `true` if `noSuchMethod` is used.
bool get isNoSuchMethodUsed;
+
+ /// `true` if generic instantiation is used.
+ bool get isGenericInstantiationUsed;
}
abstract class BackendUsageBuilder {
@@ -87,6 +90,9 @@
/// `true` if `noSuchMethod` is used.
bool isNoSuchMethodUsed;
+ /// `true` if generic instantiation is used.
+ bool isGenericInstantiationUsed;
+
BackendUsage close();
}
@@ -126,6 +132,9 @@
/// `true` if `noSuchMethod` is used.
bool isNoSuchMethodUsed = false;
+ /// `true` if generic instantiation is used.
+ bool isGenericInstantiationUsed = false;
+
BackendUsageBuilderImpl(this._commonElements);
@override
@@ -284,7 +293,8 @@
isIsolateInUse: isIsolateInUse,
isFunctionApplyUsed: isFunctionApplyUsed,
isMirrorsUsed: isMirrorsUsed,
- isNoSuchMethodUsed: isNoSuchMethodUsed);
+ isNoSuchMethodUsed: isNoSuchMethodUsed,
+ isGenericInstantiationUsed: isGenericInstantiationUsed);
}
}
@@ -323,6 +333,9 @@
/// `true` if `noSuchMethod` is used.
final bool isNoSuchMethodUsed;
+ /// `true` if generic instantiation is used.
+ final bool isGenericInstantiationUsed;
+
BackendUsageImpl(
{Set<FunctionEntity> globalFunctionDependencies,
Set<ClassEntity> globalClassDependencies,
@@ -336,7 +349,8 @@
this.isIsolateInUse,
this.isFunctionApplyUsed,
this.isMirrorsUsed,
- this.isNoSuchMethodUsed})
+ this.isNoSuchMethodUsed,
+ this.isGenericInstantiationUsed})
: this._globalFunctionDependencies = globalFunctionDependencies,
this._globalClassDependencies = globalClassDependencies,
this._helperFunctionsUsed = helperFunctionsUsed,
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
index c2c7d83..4aec501 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -296,7 +296,7 @@
return 'list$suffix';
}
- if (commonElements.isListSupertype(element)) {
+ if (commonElements.isListSupertype(element) && type.treatAsRaw) {
return nativeCheck ? 'listSuperNative$suffix' : 'listSuper$suffix';
}
diff --git a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
index 29c6db8..4b27e24 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -73,7 +73,7 @@
void registerStaticUse(MemberEntity element) {
assert(element != null);
- if (element == _commonElements.findIndexForNativeSubclassType) {
+ if (_commonElements.isFindIndexForNativeSubclassType(element)) {
join.demanded = true;
}
}
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index ae9ab20..4e72531 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -50,6 +50,10 @@
/// All declaration elements that have been processed by codegen.
final Set<MemberEntity> _processedEntities = new Set<MemberEntity>();
+ // If not `null` this is called when the queue has been emptied. It allows for
+ // applying additional impacts before re-emptying the queue.
+ void Function() onEmptyForTesting;
+
static const ImpactUseCase IMPACT_USE =
const ImpactUseCase('CodegenEnqueuer');
@@ -228,7 +232,7 @@
_worldBuilder.registerClosurizedMember(element);
}
- void forEach(void f(WorkItem work)) {
+ void _forEach(void f(WorkItem work)) {
do {
while (_queue.isNotEmpty) {
// TODO(johnniwinther): Find an optimal process order.
@@ -248,6 +252,14 @@
_queue.isNotEmpty || _recentClasses.isNotEmpty || _recentConstants);
}
+ void forEach(void f(WorkItem work)) {
+ _forEach(f);
+ if (onEmptyForTesting != null) {
+ onEmptyForTesting();
+ _forEach(f);
+ }
+ }
+
/// [_onQueueEmpty] is called whenever the queue is drained. [recentClasses]
/// contains the set of all classes seen for the first time since
/// [_onQueueEmpty] was called last. A return value of [true] indicates that
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index 32282b9..27b074b 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -41,7 +41,7 @@
final BackendImpacts _impacts;
final NativeBasicData _nativeBasicData;
final NativeResolutionEnqueuer _nativeResolutionEnqueuer;
- final BackendUsageBuilder _backendUsageBuider;
+ final BackendUsageBuilder _backendUsageBuilder;
final MirrorsDataBuilder _mirrorsDataBuilder;
final CustomElementsResolutionAnalysis _customElementsResolutionAnalysis;
final RuntimeTypesNeedBuilder _rtiNeedBuilder;
@@ -54,7 +54,7 @@
this._impacts,
this._nativeBasicData,
this._nativeResolutionEnqueuer,
- this._backendUsageBuider,
+ this._backendUsageBuilder,
this._mirrorsDataBuilder,
this._customElementsResolutionAnalysis,
this._rtiNeedBuilder,
@@ -67,7 +67,7 @@
void registerImpact(BackendImpact impact) {
impact.registerImpact(transformed, _elementEnvironment);
- _backendUsageBuider.processBackendImpact(impact);
+ _backendUsageBuilder.processBackendImpact(impact);
}
for (Feature feature in worldImpact.features) {
@@ -110,6 +110,7 @@
break;
case Feature.GENERIC_INSTANTIATION:
registerImpact(_impacts.genericInstantiation);
+ _backendUsageBuilder.isGenericInstantiationUsed = true;
break;
case Feature.LAZY_FIELD:
registerImpact(_impacts.lazyField);
@@ -251,7 +252,9 @@
Local closure = staticUse.element;
FunctionType type = _elementEnvironment.getLocalFunctionType(closure);
if (type.containsTypeVariables ||
- (_options.strongMode && !optimizeLocalSignaturesForStrongMode)) {
+ // TODO(johnniwinther): Can we avoid the need for signatures in
+ // Dart 2?
+ _options.strongMode) {
registerImpact(_impacts.computeSignature);
}
break;
@@ -300,7 +303,7 @@
void onIsCheck(DartType type, TransformedWorldImpact transformed) {
void registerImpact(BackendImpact impact) {
impact.registerImpact(transformed, _elementEnvironment);
- _backendUsageBuider.processBackendImpact(impact);
+ _backendUsageBuilder.processBackendImpact(impact);
}
type = _elementEnvironment.getUnaliasedType(type);
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 813ea76..9c3dd7b 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -27,10 +27,6 @@
bool cacheRtiDataForTesting = false;
-// TODO(johnniwinther): Remove this when local signatures are optimized for
-// Dart 2.
-const bool optimizeLocalSignaturesForStrongMode = false;
-
/// For each class, stores the possible class subtype tests that could succeed.
abstract class TypeChecks {
/// Get the set of checks required for class [element].
@@ -1412,6 +1408,12 @@
});
}
+ Set<Local> localFunctions = strongMode
+ ? resolutionWorldBuilder.localFunctions.toSet()
+ : resolutionWorldBuilder.localFunctionsWithFreeTypeVariables.toSet();
+ Set<FunctionEntity> closurizedMembers =
+ resolutionWorldBuilder.closurizedMembersWithFreeTypeVariables.toSet();
+
// Check local functions and closurized members.
void checkClosures({DartType potentialSubtypeOf}) {
bool checkFunctionType(FunctionType functionType) {
@@ -1426,32 +1428,51 @@
return false;
}
+ Set<Local> localFunctionsToRemove;
+ Set<FunctionEntity> closurizedMembersToRemove;
if (strongMode) {
- assert(!optimizeLocalSignaturesForStrongMode);
- // TODO(johnniwinther): Optimize generation of signatures for Dart 2.
- for (Local function in resolutionWorldBuilder.localFunctions) {
+ for (Local function in localFunctions) {
FunctionType functionType =
_elementEnvironment.getLocalFunctionType(function);
- functionType.forEachTypeVariable((TypeVariableType typeVariable) {
- potentiallyNeedTypeArguments(typeVariable.element.typeDeclaration);
- });
- localFunctionsNeedingSignature.add(function);
+ if (potentialSubtypeOf == null ||
+ closedWorld.dartTypes.isPotentialSubtype(
+ functionType, potentialSubtypeOf,
+ assumeInstantiations:
+ closedWorld.backendUsage.isGenericInstantiationUsed)) {
+ functionType.forEachTypeVariable((TypeVariableType typeVariable) {
+ Entity typeDeclaration = typeVariable.element.typeDeclaration;
+ if (!processedEntities.contains(typeDeclaration)) {
+ potentiallyNeedTypeArguments(typeDeclaration);
+ }
+ });
+ localFunctionsNeedingSignature.add(function);
+ localFunctionsToRemove ??= new Set<Local>();
+ localFunctionsToRemove.add(function);
+ }
}
} else {
- for (Local function
- in resolutionWorldBuilder.localFunctionsWithFreeTypeVariables) {
+ for (Local function in localFunctions) {
if (checkFunctionType(
_elementEnvironment.getLocalFunctionType(function))) {
localFunctionsNeedingSignature.add(function);
+ localFunctionsToRemove ??= new Set<Local>();
+ localFunctionsToRemove.add(function);
}
}
}
- for (FunctionEntity function
- in resolutionWorldBuilder.closurizedMembersWithFreeTypeVariables) {
+ for (FunctionEntity function in closurizedMembers) {
if (checkFunctionType(_elementEnvironment.getFunctionType(function))) {
methodsNeedingSignature.add(function);
+ closurizedMembersToRemove ??= new Set<FunctionEntity>();
+ closurizedMembersToRemove.add(function);
}
}
+ if (localFunctionsToRemove != null) {
+ localFunctions.removeAll(localFunctionsToRemove);
+ }
+ if (closurizedMembersToRemove != null) {
+ closurizedMembers.removeAll(closurizedMembersToRemove);
+ }
}
// Compute the set of all classes and methods that need runtime type
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 14177b0..eae6858 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -315,7 +315,10 @@
return null;
}
jsAst.Expression arrayCheck = js('receiver.constructor == Array');
- jsAst.Expression indexableCheck =
+
+ // Lazy generation of the indexable check. If indexable behavior isn't
+ // used, the isJsIndexable function isn't part of the closed world.
+ jsAst.Expression genericIndexableCheck() =>
_generateIsJsIndexableCall(js('receiver'), js('receiver'));
jsAst.Expression orExp(left, right) {
@@ -333,7 +336,7 @@
}
if (containsJsIndexable) {
- typeCheck = orExp(typeCheck, indexableCheck);
+ typeCheck = orExp(typeCheck, genericIndexableCheck());
}
return js.statement('''
@@ -349,7 +352,7 @@
}
if (containsJsIndexable) {
- typeCheck = orExp(typeCheck, indexableCheck);
+ typeCheck = orExp(typeCheck, genericIndexableCheck());
}
return js.statement(r'''
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index ad8f33b..5e3279f 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -635,6 +635,7 @@
List<StaticMethod> statics = memberElements
.where((e) => !e.isField)
+ .cast<FunctionEntity>()
.map(_buildStaticMethod)
.toList();
diff --git a/pkg/compiler/lib/src/js_emitter/sorter.dart b/pkg/compiler/lib/src/js_emitter/sorter.dart
index d3cfff6..70fbd51 100644
--- a/pkg/compiler/lib/src/js_emitter/sorter.dart
+++ b/pkg/compiler/lib/src/js_emitter/sorter.dart
@@ -19,7 +19,7 @@
Iterable<TypedefEntity> sortTypedefs(Iterable<TypedefEntity> typedefs);
/// Returns a sorted list of [members].
- Iterable<MemberEntity> sortMembers(Iterable<MemberEntity> members);
+ Iterable<T> sortMembers<T extends MemberEntity>(Iterable<T> members);
int compareLibrariesByLocation(LibraryEntity a, LibraryEntity b);
int compareClassesByLocation(ClassEntity a, ClassEntity b);
@@ -63,7 +63,7 @@
}
@override
- List<MemberEntity> sortMembers(Iterable<MemberEntity> members) {
+ Iterable<T> sortMembers<T extends MemberEntity>(Iterable<T> members) {
return Elements.sortedByPosition(new List.from(members, growable: false));
}
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index a56afcf..9334b52 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -16,6 +16,7 @@
import '../kernel/env.dart';
import '../options.dart';
import '../ssa/type_builder.dart';
+import '../universe/selector.dart';
import '../world.dart';
import 'elements.dart';
import 'closure_visitors.dart';
@@ -77,6 +78,7 @@
class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
final KernelToElementMapForBuilding _elementMap;
final GlobalLocalsMap _globalLocalsMap;
+ final CompilerOptions _options;
/// Map of the scoping information that corresponds to a particular entity.
Map<MemberEntity, ScopeInfo> _scopeMap = <MemberEntity, ScopeInfo>{};
@@ -93,19 +95,8 @@
Map<ir.TreeNode, ClosureRepresentationInfo> _localClosureRepresentationMap =
<ir.TreeNode, ClosureRepresentationInfo>{};
- /// If true add type assertions to assert that at runtime the type is in line
- /// with the stated type.
- final bool _addTypeChecks;
-
- /// If true, we are compiling using strong mode, and therefore we will create
- /// a "signatureMethod" for a closure that can output the type. In this
- /// instance, we may need access to a type variable that has not otherwise
- /// been captured, and therefore we need to mark it as being used so that the
- /// RTI optimization doesn't optimize it away..
- final bool _strongMode;
-
- KernelClosureConversionTask(Measurer measurer, this._elementMap,
- this._globalLocalsMap, this._addTypeChecks, this._strongMode)
+ KernelClosureConversionTask(
+ Measurer measurer, this._elementMap, this._globalLocalsMap, this._options)
: super(measurer);
/// The combined steps of generating our intermediate representation of
@@ -118,68 +109,127 @@
void convertClosures(Iterable<MemberEntity> processedEntities,
ClosedWorldRefiner closedWorldRefiner) {}
- void _updateScopeBasedOnRtiNeed(
- KernelScopeInfo scope,
- bool Function(ClassEntity) classNeedsTypeArguments,
- bool Function(MemberEntity) methodNeedsTypeArguments,
- bool Function(ir.Node) localFunctionNeedsTypeArguments,
+ void _updateScopeBasedOnRtiNeed(KernelScopeInfo scope, ClosureRtiNeed rtiNeed,
MemberEntity outermostEntity) {
- if (scope.thisUsedAsFreeVariableIfNeedsRti &&
- (classNeedsTypeArguments(outermostEntity.enclosingClass) ||
- // TODO(johnniwinther): Instead of _strongMode, make this branch test
- // if an added signature method needs type arguments (see comment in
- // TypeVariableKind.method branch below.
- _strongMode)) {
- scope.thisUsedAsFreeVariable = true;
- }
- if (_addTypeChecks) {
- scope.freeVariables.addAll(scope.freeVariablesForRti);
- } else {
- for (TypeVariableTypeWithContext typeVariable
- in scope.freeVariablesForRti) {
- switch (typeVariable.kind) {
- case TypeVariableKind.cls:
- if (classNeedsTypeArguments(
- _elementMap.getClass(typeVariable.typeDeclaration))) {
- scope.freeVariables.add(typeVariable);
+ bool includeForRti(Set<VariableUse> useSet) {
+ for (VariableUse usage in useSet) {
+ switch (usage.kind) {
+ case VariableUseKind.explicit:
+ return true;
+ break;
+ case VariableUseKind.implicitCast:
+ if (_options.implicitDowncastCheckPolicy.isEmitted) {
+ return true;
}
break;
- case TypeVariableKind.method:
- if (methodNeedsTypeArguments(
- _elementMap.getMember(typeVariable.typeDeclaration)) ||
- // In Dart 2, we have the notion of generic methods. This is
- // partly implemented by adding a "method signature" function to
- // closure classes. This signature reports the type of the
- // method, and therefore may access the type variable of the
- // parameter, which might otherwise not be used (and therefore
- // isn't captured in the set that `methodNeedsTypeArguments`
- // compares against.
- // TODO(johnniwinther): Include this reasoning inside
- // [methodNeedsTypeArguments] rather than an add on here.
- _strongMode &&
- scope.freeVariablesForRti.contains(typeVariable)) {
- scope.freeVariables.add(typeVariable);
+ case VariableUseKind.localType:
+ if (_options.assignmentCheckPolicy.isEmitted) {
+ return true;
}
break;
- case TypeVariableKind.local:
- if (localFunctionNeedsTypeArguments(typeVariable.typeDeclaration)) {
- scope.freeVariables.add(typeVariable);
+
+ case VariableUseKind.constructorTypeArgument:
+ ConstructorEntity constructor =
+ _elementMap.getConstructor(usage.member);
+ if (rtiNeed.classNeedsTypeArguments(constructor.enclosingClass)) {
+ return true;
}
break;
- case TypeVariableKind.function:
+ case VariableUseKind.staticTypeArgument:
+ FunctionEntity method = _elementMap.getMethod(usage.member);
+ if (rtiNeed.methodNeedsTypeArguments(method)) {
+ return true;
+ }
+ break;
+ case VariableUseKind.instanceTypeArgument:
+ Selector selector = _elementMap.getSelector(usage.invocation);
+ if (rtiNeed.selectorNeedsTypeArguments(selector)) {
+ return true;
+ }
+ break;
+ case VariableUseKind.localTypeArgument:
+ // TODO(johnniwinther): We should be able to track direct local
+ // function invocations and not have to use the selector here.
+ Selector selector = _elementMap.getSelector(usage.invocation);
+ if (rtiNeed.localFunctionNeedsTypeArguments(usage.localFunction) ||
+ rtiNeed.selectorNeedsTypeArguments(selector)) {
+ return true;
+ }
+ break;
+ case VariableUseKind.memberParameter:
+ if (_options.parameterCheckPolicy.isEmitted) {
+ return true;
+ } else {
+ FunctionEntity method = _elementMap.getMethod(usage.member);
+ if (rtiNeed.methodNeedsSignature(method)) {
+ return true;
+ }
+ }
+ break;
+ case VariableUseKind.localParameter:
+ if (_options.parameterCheckPolicy.isEmitted) {
+ return true;
+ } else if (rtiNeed
+ .localFunctionNeedsSignature(usage.localFunction)) {
+ return true;
+ }
+ break;
+ case VariableUseKind.memberReturnType:
+ if (_options.assignmentCheckPolicy.isEmitted) {
+ return true;
+ } else {
+ FunctionEntity method = _elementMap.getMethod(usage.member);
+ if (rtiNeed.methodNeedsSignature(method)) {
+ return true;
+ }
+ }
+ break;
+ case VariableUseKind.localReturnType:
+ if (_options.assignmentCheckPolicy.isEmitted) {
+ return true;
+ } else if (rtiNeed
+ .localFunctionNeedsSignature(usage.localFunction)) {
+ return true;
+ }
+ break;
+ case VariableUseKind.fieldType:
+ if (_options.assignmentCheckPolicy.isEmitted ||
+ _options.parameterCheckPolicy.isEmitted) {
+ return true;
+ }
+ break;
+ case VariableUseKind.listLiteral:
+ if (rtiNeed.classNeedsTypeArguments(
+ _elementMap.commonElements.jsArrayClass)) {
+ return true;
+ }
+ break;
+ case VariableUseKind.mapLiteral:
+ if (rtiNeed.classNeedsTypeArguments(
+ _elementMap.commonElements.mapLiteralClass)) {
+ return true;
+ }
break;
}
}
+ return false;
}
+
+ if (includeForRti(scope.thisUsedAsFreeVariableIfNeedsRti)) {
+ scope.thisUsedAsFreeVariable = true;
+ }
+ scope.freeVariablesForRti.forEach(
+ (TypeVariableTypeWithContext typeVariable, Set<VariableUse> useSet) {
+ if (includeForRti(useSet)) {
+ scope.freeVariables.add(typeVariable);
+ }
+ });
}
Iterable<FunctionEntity> createClosureEntities(
JsClosedWorldBuilder closedWorldBuilder,
Map<MemberEntity, ScopeModel> closureModels,
- {bool Function(ir.Node) localFunctionNeedsSignature,
- bool Function(ClassEntity) classNeedsTypeArguments,
- bool Function(FunctionEntity) methodNeedsTypeArguments,
- bool Function(ir.Node) localFunctionNeedsTypeArguments}) {
+ ClosureRtiNeed rtiNeed) {
List<FunctionEntity> callMethods = <FunctionEntity>[];
closureModels.forEach((MemberEntity member, ScopeModel model) {
KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member);
@@ -192,8 +242,7 @@
.forEach((ir.Node node, KernelCapturedScope scope) {
Map<Local, JRecordField> boxedVariables =
_elementMap.makeRecordContainer(scope, member, localsMap);
- _updateScopeBasedOnRtiNeed(scope, classNeedsTypeArguments,
- methodNeedsTypeArguments, localFunctionNeedsTypeArguments, member);
+ _updateScopeBasedOnRtiNeed(scope, rtiNeed, member);
if (scope is KernelCapturedLoopScope) {
_capturedScopesMap[node] = new JsCapturedLoopScope.from(
@@ -222,11 +271,9 @@
functionNode,
closuresToGenerate[node],
allBoxedVariables,
- classNeedsTypeArguments,
- methodNeedsTypeArguments,
- localFunctionNeedsTypeArguments,
+ rtiNeed,
createSignatureMethod:
- localFunctionNeedsSignature(functionNode.parent));
+ rtiNeed.localFunctionNeedsSignature(functionNode.parent));
// Add also for the call method.
_scopeMap[closureClassInfo.callMethod] = closureClassInfo;
_scopeMap[closureClassInfo.signatureMethod] = closureClassInfo;
@@ -234,19 +281,14 @@
// Set up capturedScope for signature method. This is distinct from
// _capturedScopesMap because there is no corresponding ir.Node for the
// signature.
- if (localFunctionNeedsSignature(functionNode.parent) &&
+ if (rtiNeed.localFunctionNeedsSignature(functionNode.parent) &&
model.capturedScopesMap[functionNode] != null) {
KernelCapturedScope capturedScope =
model.capturedScopesMap[functionNode];
assert(capturedScope is! KernelCapturedLoopScope);
KernelCapturedScope signatureCapturedScope =
new KernelCapturedScope.forSignature(capturedScope);
- _updateScopeBasedOnRtiNeed(
- signatureCapturedScope,
- classNeedsTypeArguments,
- methodNeedsTypeArguments,
- localFunctionNeedsTypeArguments,
- member);
+ _updateScopeBasedOnRtiNeed(signatureCapturedScope, rtiNeed, member);
_capturedScopeForSignatureMap[closureClassInfo.signatureMethod] =
new JsCapturedScope.from(
{}, signatureCapturedScope, localsMap, _elementMap);
@@ -269,12 +311,9 @@
ir.FunctionNode node,
KernelScopeInfo info,
Map<Local, JRecordField> boxedVariables,
- bool Function(ClassEntity) classNeedsTypeArguments,
- bool Function(FunctionEntity) methodNeedsTypeArguments,
- bool Function(ir.Node) localFunctionNeedsTypeArguments,
+ ClosureRtiNeed rtiNeed,
{bool createSignatureMethod}) {
- _updateScopeBasedOnRtiNeed(info, classNeedsTypeArguments,
- methodNeedsTypeArguments, localFunctionNeedsTypeArguments, member);
+ _updateScopeBasedOnRtiNeed(info, rtiNeed, member);
KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member);
KernelClosureClassInfo closureClassInfo =
closedWorldBuilder.buildClosureClass(
@@ -355,6 +394,150 @@
}
}
+enum VariableUseKind {
+ /// An explicit variable use.
+ ///
+ /// For type variable this is an explicit as-cast, an is-test or a type
+ /// literal.
+ explicit,
+
+ /// A type variable used in the type of a local variable.
+ localType,
+
+ /// A type variable used in an implicit cast.
+ implicitCast,
+
+ /// A type variable passed as the type argument of a list literal.
+ listLiteral,
+
+ /// A type variable passed as the type argument of a map literal.
+ mapLiteral,
+
+ /// A type variable passed as a type argument to a constructor.
+ constructorTypeArgument,
+
+ /// A type variable passed as a type argument to a static method.
+ staticTypeArgument,
+
+ /// A type variable passed as a type argument to an instance method.
+ instanceTypeArgument,
+
+ /// A type variable passed as a type argument to a local function.
+ localTypeArgument,
+
+ /// A type variable in a parameter type of a member.
+ memberParameter,
+
+ /// A type variable in a parameter type of a local function.
+ localParameter,
+
+ /// A type variable used in a return type of a member.
+ memberReturnType,
+
+ /// A type variable used in a return type of a local function.
+ localReturnType,
+
+ /// A type variable in a field type.
+ fieldType,
+}
+
+class VariableUse {
+ final VariableUseKind kind;
+ final ir.Member member;
+ final ir.TreeNode /*ir.FunctionDeclaration|ir.FunctionExpression*/
+ localFunction;
+ final ir.MethodInvocation invocation;
+
+ const VariableUse._simple(this.kind)
+ : this.member = null,
+ this.localFunction = null,
+ this.invocation = null;
+
+ VariableUse.memberParameter(this.member)
+ : this.kind = VariableUseKind.memberParameter,
+ this.localFunction = null,
+ this.invocation = null;
+
+ VariableUse.localParameter(this.localFunction)
+ : this.kind = VariableUseKind.localParameter,
+ this.member = null,
+ this.invocation = null {
+ assert(localFunction is ir.FunctionDeclaration ||
+ localFunction is ir.FunctionExpression);
+ }
+
+ VariableUse.memberReturnType(this.member)
+ : this.kind = VariableUseKind.memberReturnType,
+ this.localFunction = null,
+ this.invocation = null;
+
+ VariableUse.localReturnType(this.localFunction)
+ : this.kind = VariableUseKind.localReturnType,
+ this.member = null,
+ this.invocation = null {
+ assert(localFunction is ir.FunctionDeclaration ||
+ localFunction is ir.FunctionExpression);
+ }
+
+ VariableUse.constructorTypeArgument(this.member)
+ : this.kind = VariableUseKind.constructorTypeArgument,
+ this.localFunction = null,
+ this.invocation = null;
+
+ VariableUse.staticTypeArgument(this.member)
+ : this.kind = VariableUseKind.staticTypeArgument,
+ this.localFunction = null,
+ this.invocation = null;
+
+ VariableUse.instanceTypeArgument(this.invocation)
+ : this.kind = VariableUseKind.instanceTypeArgument,
+ this.member = null,
+ this.localFunction = null;
+
+ VariableUse.localTypeArgument(this.localFunction, this.invocation)
+ : this.kind = VariableUseKind.localTypeArgument,
+ this.member = null {
+ assert(localFunction is ir.FunctionDeclaration ||
+ localFunction is ir.FunctionExpression);
+ }
+
+ static const VariableUse explicit =
+ const VariableUse._simple(VariableUseKind.explicit);
+
+ static const VariableUse localType =
+ const VariableUse._simple(VariableUseKind.localType);
+
+ static const VariableUse implicitCast =
+ const VariableUse._simple(VariableUseKind.implicitCast);
+
+ static const VariableUse listLiteral =
+ const VariableUse._simple(VariableUseKind.listLiteral);
+
+ static const VariableUse mapLiteral =
+ const VariableUse._simple(VariableUseKind.mapLiteral);
+
+ static const VariableUse fieldType =
+ const VariableUse._simple(VariableUseKind.fieldType);
+
+ int get hashCode =>
+ kind.hashCode * 11 +
+ member.hashCode * 13 +
+ localFunction.hashCode * 17 +
+ invocation.hashCode * 19;
+
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! VariableUse) return false;
+ return kind == other.kind &&
+ member == other.member &&
+ localFunction == other.localFunction &&
+ invocation == other.invocation;
+ }
+
+ String toString() => 'VariableUse(kind=$kind,member=$member,'
+ 'localFunction=$localFunction,invocation=$invocation)';
+}
+
class KernelScopeInfo {
final Set<ir.VariableDeclaration> localsUsedInTryOrSync;
final bool hasThisLocal;
@@ -375,8 +558,8 @@
/// freeVariables set. Whether these variables are actually used as
/// freeVariables will be set by the time this structure is converted to a
/// JsScopeInfo, so JsScopeInfo does not need to use them.
- Set<TypeVariableTypeWithContext> freeVariablesForRti =
- new Set<TypeVariableTypeWithContext>();
+ Map<TypeVariableTypeWithContext, Set<VariableUse>> freeVariablesForRti =
+ <TypeVariableTypeWithContext, Set<VariableUse>>{};
/// If true, `this` is used as a free variable, in this scope. It is stored
/// separately from [freeVariables] because there is no single
@@ -387,7 +570,7 @@
/// performing runtime type checks. It is stored
/// separately from [thisUsedAsFreeVariable] because we don't know at this
/// stage if we will be needing type checks for this scope.
- bool thisUsedAsFreeVariableIfNeedsRti = false;
+ Set<VariableUse> thisUsedAsFreeVariableIfNeedsRti = new Set<VariableUse>();
KernelScopeInfo(this.hasThisLocal)
: localsUsedInTryOrSync = new Set<ir.VariableDeclaration>(),
@@ -411,10 +594,16 @@
String toString() {
StringBuffer sb = new StringBuffer();
- sb.write('this=$hasThisLocal,');
+ sb.write('KernelScopeInfo(this=$hasThisLocal,');
sb.write('freeVriables=$freeVariables,');
sb.write('localsUsedInTryOrSync={${localsUsedInTryOrSync.join(', ')}}');
- sb.write('freeVariablesForRti={${freeVariablesForRti.join(', ')}}');
+ String comma = '';
+ sb.write('freeVariablesForRti={');
+ freeVariablesForRti.forEach((key, value) {
+ sb.write('$comma$key:$value');
+ comma = ',';
+ });
+ sb.write('})');
return sb.toString();
}
}
@@ -482,11 +671,11 @@
Set<ir.VariableDeclaration> boxedVariables,
NodeBox capturedVariablesAccessor,
Set<ir.VariableDeclaration> localsUsedInTryOrSync,
- Set<ir.Node /* VariableDeclaration | TypeParameterTypeWithContext */ >
+ Set<ir.Node /* VariableDeclaration | TypeVariableTypeWithContext */ >
freeVariables,
- Set<TypeVariableTypeWithContext> freeVariablesForRti,
+ Map<TypeVariableTypeWithContext, Set<VariableUse>> freeVariablesForRti,
bool thisUsedAsFreeVariable,
- bool thisUsedAsFreeVariableIfNeedsRti,
+ Set<VariableUse> thisUsedAsFreeVariableIfNeedsRti,
bool hasThisLocal)
: super.withBoxedVariables(
boxedVariables,
@@ -541,11 +730,11 @@
NodeBox capturedVariablesAccessor,
this.boxedLoopVariables,
Set<ir.VariableDeclaration> localsUsedInTryOrSync,
- Set<ir.Node /* VariableDeclaration | TypeParameterTypeWithContext */ >
+ Set<ir.Node /* VariableDeclaration | TypeVariableTypeWithContext */ >
freeVariables,
- Set<TypeVariableTypeWithContext> freeVariablesForRti,
+ Map<TypeVariableTypeWithContext, Set<VariableUse>> freeVariablesForRti,
bool thisUsedAsFreeVariable,
- bool thisUsedAsFreeVariableIfNeedsRti,
+ Set<VariableUse> thisUsedAsFreeVariableIfNeedsRti,
bool hasThisLocal)
: super(
boxedVariables,
@@ -959,3 +1148,17 @@
'TypeVariableTypeWithContext(type=$type,context=$context,'
'kind=$kind,typeDeclaration=$typeDeclaration)';
}
+
+abstract class ClosureRtiNeed {
+ bool classNeedsTypeArguments(ClassEntity cls);
+
+ bool methodNeedsTypeArguments(FunctionEntity method);
+
+ bool methodNeedsSignature(MemberEntity method);
+
+ bool localFunctionNeedsTypeArguments(ir.Node node);
+
+ bool localFunctionNeedsSignature(ir.Node node);
+
+ bool selectorNeedsTypeArguments(Selector selector);
+}
diff --git a/pkg/compiler/lib/src/js_model/closure_visitors.dart b/pkg/compiler/lib/src/js_model/closure_visitors.dart
index 28bd0f1..ea35aaf 100644
--- a/pkg/compiler/lib/src/js_model/closure_visitors.dart
+++ b/pkg/compiler/lib/src/js_model/closure_visitors.dart
@@ -68,18 +68,16 @@
/// have unique names.
int _boxCounter = 0;
- /// Set to `true` in the visitor if a type annotation is always needed.
+ /// The current usage of a type annotation.
///
- /// This is for instance the case for expressions like `o is T` and `o as T`.
- bool _contextNeedsType = false;
+ /// This is updated in the visitor to distinguish between unconditional
+ /// type variable usage, such as type literals and is tests, and conditional
+ /// type variable usage, such as type argument in method invocations.
+ VariableUse _currentTypeUsage;
CapturedScopeBuilder(this._model, this._options, {bool hasThisLocal})
: this._hasThisLocal = hasThisLocal;
- /// If true add type assetions to assert that at runtime the type is in line
- /// with the stated type.
- bool get _addTypeChecks => _options.enableTypeAssertions;
-
/// Update the [CapturedScope] object corresponding to
/// this node if any variables are captured.
void attachCapturedScopeVariables(ir.TreeNode node) {
@@ -179,25 +177,31 @@
@override
visitVariableGet(ir.VariableGet node) {
- _markVariableAsUsed(node.variable);
- node.visitChildren(this);
+ _markVariableAsUsed(node.variable, VariableUse.explicit);
+ // Don't visit `node.promotedType`.
}
@override
visitVariableSet(ir.VariableSet node) {
_mutatedVariables.add(node.variable);
- _markVariableAsUsed(node.variable);
- if (_addTypeChecks) node.variable.type.accept(this);
+ _markVariableAsUsed(node.variable, VariableUse.explicit);
+ visitInContext(node.variable.type, VariableUse.localType);
node.visitChildren(this);
}
- @override
- visitVariableDeclaration(ir.VariableDeclaration declaration) {
- if (!declaration.isFieldFormal) {
- _scopeVariables.add(declaration);
+ void handleVariableDeclaration(
+ ir.VariableDeclaration node, VariableUse usage) {
+ if (!node.isFieldFormal) {
+ _scopeVariables.add(node);
}
- declaration.visitChildren(this);
+ visitInContext(node.type, usage);
+ node.initializer?.accept(this);
+ }
+
+ @override
+ visitVariableDeclaration(ir.VariableDeclaration node) {
+ handleVariableDeclaration(node, VariableUse.localType);
}
/// Add this variable to the set of free variables if appropriate and add to
@@ -207,9 +211,10 @@
/// checked.
void _markVariableAsUsed(
ir.Node /* VariableDeclaration | TypeParameterTypeWithContext */ variable,
- {bool onlyForRtiChecks = false}) {
+ VariableUse usage) {
assert(variable is ir.VariableDeclaration ||
variable is TypeVariableTypeWithContext);
+ assert(usage != null);
if (_isInsideClosure && !_inCurrentContext(variable)) {
// If the element is not declared in the current function and the element
// is not the closure itself we need to mark the element as free variable.
@@ -217,10 +222,12 @@
// optimization: factories have type parameters as function
// parameters, and type parameters are declared in the class, not
// the factory.
- if (!onlyForRtiChecks) {
+ if (usage == VariableUse.explicit) {
_currentScopeInfo.freeVariables.add(variable);
} else {
- _currentScopeInfo.freeVariablesForRti.add(variable);
+ _currentScopeInfo.freeVariablesForRti
+ .putIfAbsent(variable, () => new Set<VariableUse>())
+ .add(usage);
}
}
if (_inTry && variable is ir.VariableDeclaration) {
@@ -230,41 +237,36 @@
@override
void visitThisExpression(ir.ThisExpression thisExpression) {
- if (_hasThisLocal) _registerNeedsThis();
+ if (_hasThisLocal) _registerNeedsThis(VariableUse.explicit);
}
@override
void visitTypeParameter(ir.TypeParameter typeParameter) {
- if (_addTypeChecks) {
- ir.TreeNode context = _executableContext;
- TypeVariableTypeWithContext typeVariable =
- new TypeVariableTypeWithContext(
- new ir.TypeParameterType(typeParameter),
- // If this typeParameter is part of a typedef then its parent is
- // null because it has no context. Just pass in null for the
- // context in that case.
- typeParameter.parent != null
- ? typeParameter.parent.parent
- : null);
- if (_isInsideClosure && context is ir.Procedure && context.isFactory) {
- // This is a closure in a factory constructor. Since there is no
- // [:this:], we have to mark the type arguments as free variables to
- // capture them in the closure.
- _useTypeVariableAsLocal(typeVariable);
- }
+ ir.TreeNode context = _executableContext;
+ TypeVariableTypeWithContext typeVariable = new TypeVariableTypeWithContext(
+ new ir.TypeParameterType(typeParameter),
+ // If this typeParameter is part of a typedef then its parent is
+ // null because it has no context. Just pass in null for the
+ // context in that case.
+ typeParameter.parent != null ? typeParameter.parent.parent : null);
+ if (_isInsideClosure && context is ir.Procedure && context.isFactory) {
+ // This is a closure in a factory constructor. Since there is no
+ // [:this:], we have to mark the type arguments as free variables to
+ // capture them in the closure.
+ _useTypeVariableAsLocal(typeVariable, _currentTypeUsage);
+ }
- if (_executableContext is ir.Member && _executableContext is! ir.Field) {
- // In checked mode, using a type variable in a type annotation may lead
- // to a runtime type check that needs to access the type argument and
- // therefore the closure needs a this-element, if it is not in a field
- // initializer; field initializers are evaluated in a context where
- // the type arguments are available in locals.
+ if (_executableContext is ir.Member && _executableContext is! ir.Field) {
+ // In checked mode, using a type variable in a type annotation may lead
+ // to a runtime type check that needs to access the type argument and
+ // therefore the closure needs a this-element, if it is not in a field
+ // initializer; field initializers are evaluated in a context where
+ // the type arguments are available in locals.
- if (_hasThisLocal) {
- _registerNeedsThis();
- } else {
- _useTypeVariableAsLocal(typeVariable);
- }
+ if (_hasThisLocal) {
+ _registerNeedsThis(_currentTypeUsage);
+ } else {
+ _useTypeVariableAsLocal(typeVariable, _currentTypeUsage);
}
}
}
@@ -274,12 +276,12 @@
/// If [onlyIfNeedsRti] is true, set thisUsedAsFreeVariableIfNeedsRti to true
/// instead of thisUsedAsFreeVariable as we will only use `this` if runtime
/// type information is checked.
- void _registerNeedsThis({bool onlyIfNeedsRti = false}) {
+ void _registerNeedsThis(VariableUse usage) {
if (_isInsideClosure) {
- if (!onlyIfNeedsRti) {
+ if (usage == VariableUse.explicit) {
_currentScopeInfo.thisUsedAsFreeVariable = true;
} else {
- _currentScopeInfo.thisUsedAsFreeVariableIfNeedsRti = true;
+ _currentScopeInfo.thisUsedAsFreeVariableIfNeedsRti.add(usage);
}
}
}
@@ -362,19 +364,30 @@
scope.hasThisLocal);
}
- void visitSuperMethodInvocation(ir.SuperMethodInvocation invocation) {
- if (_hasThisLocal) _registerNeedsThis();
- invocation.visitChildren(this);
+ void visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
+ if (_hasThisLocal) {
+ _registerNeedsThis(VariableUse.explicit);
+ }
+ if (node.arguments.types.isNotEmpty) {
+ visitListInContext(node.arguments.types,
+ new VariableUse.staticTypeArgument(node.interfaceTarget));
+ }
+ ir.visitList(node.arguments.positional, this);
+ ir.visitList(node.arguments.named, this);
}
- void visitSuperPropertySet(ir.SuperPropertySet propertySet) {
- if (_hasThisLocal) _registerNeedsThis();
- propertySet.visitChildren(this);
+ void visitSuperPropertySet(ir.SuperPropertySet node) {
+ if (_hasThisLocal) {
+ _registerNeedsThis(VariableUse.explicit);
+ }
+ node.visitChildren(this);
}
- void visitSuperPropertyGet(ir.SuperPropertyGet propertyGet) {
- if (_hasThisLocal) _registerNeedsThis();
- propertyGet.visitChildren(this);
+ void visitSuperPropertyGet(ir.SuperPropertyGet node) {
+ if (_hasThisLocal) {
+ _registerNeedsThis(VariableUse.explicit);
+ }
+ node.visitChildren(this);
}
void visitInvokable(ir.TreeNode node) {
@@ -417,16 +430,21 @@
assert(freeVariables.isEmpty || savedIsInsideClosure);
for (ir.Node freeVariable in freeVariables) {
_capturedVariables.add(freeVariable);
- _markVariableAsUsed(freeVariable);
+ _markVariableAsUsed(freeVariable, VariableUse.explicit);
}
- for (ir.Node freeVariableForRti in savedScopeInfo.freeVariablesForRti) {
- _markVariableAsUsed(freeVariableForRti, onlyForRtiChecks: true);
- }
+ savedScopeInfo.freeVariablesForRti.forEach(
+ (TypeVariableTypeWithContext freeVariableForRti,
+ Set<VariableUse> useSet) {
+ for (VariableUse usage in useSet) {
+ _markVariableAsUsed(freeVariableForRti, usage);
+ }
+ });
if (_isInsideClosure && savedScopeInfo.thisUsedAsFreeVariable) {
_currentScopeInfo.thisUsedAsFreeVariable = true;
}
- if (_isInsideClosure && savedScopeInfo.thisUsedAsFreeVariableIfNeedsRti) {
- _currentScopeInfo.thisUsedAsFreeVariableIfNeedsRti = true;
+ if (_isInsideClosure) {
+ _currentScopeInfo.thisUsedAsFreeVariableIfNeedsRti
+ .addAll(savedScopeInfo.thisUsedAsFreeVariableIfNeedsRti);
}
}
@@ -447,7 +465,9 @@
@override
void visitField(ir.Field field) {
+ _currentTypeUsage = VariableUse.fieldType;
visitInvokable(field);
+ _currentTypeUsage = null;
}
@override
@@ -472,32 +492,141 @@
@override
visitTypeParameterType(ir.TypeParameterType type) {
- _analyzeTypeVariable(type, onlyIfNeedsRti: !_contextNeedsType);
+ _analyzeTypeVariable(type, _currentTypeUsage);
+ }
+
+ visitInContext(ir.Node node, VariableUse use) {
+ VariableUse oldCurrentTypeUsage = _currentTypeUsage;
+ _currentTypeUsage = use;
+ node?.accept(this);
+ _currentTypeUsage = oldCurrentTypeUsage;
+ }
+
+ visitListInContext(List<ir.Node> nodes, VariableUse use) {
+ VariableUse oldCurrentTypeUsage = _currentTypeUsage;
+ _currentTypeUsage = use;
+ ir.visitList(nodes, this);
+ _currentTypeUsage = oldCurrentTypeUsage;
+ }
+
+ visitChildrenInContext(ir.Node node, VariableUse use) {
+ VariableUse oldCurrentTypeUsage = _currentTypeUsage;
+ _currentTypeUsage = use;
+ node.visitChildren(this);
+ _currentTypeUsage = oldCurrentTypeUsage;
}
@override
visitTypeLiteral(ir.TypeLiteral node) {
- bool oldContextNeedsType = _contextNeedsType;
- _contextNeedsType = true;
- node.visitChildren(this);
- _contextNeedsType = oldContextNeedsType;
+ visitChildrenInContext(node, VariableUse.explicit);
}
@override
visitIsExpression(ir.IsExpression node) {
- bool oldContextNeedsType = _contextNeedsType;
- _contextNeedsType = true;
- node.visitChildren(this);
- _contextNeedsType = oldContextNeedsType;
+ node.operand.accept(this);
+ visitInContext(node.type, VariableUse.explicit);
}
@override
visitAsExpression(ir.AsExpression node) {
- bool oldContextNeedsType = _contextNeedsType;
- _contextNeedsType =
- !node.isTypeError || _options.implicitDowncastCheckPolicy.isEmitted;
- node.visitChildren(this);
- _contextNeedsType = oldContextNeedsType;
+ node.operand.accept(this);
+ visitInContext(node.type,
+ node.isTypeError ? VariableUse.implicitCast : VariableUse.explicit);
+ }
+
+ @override
+ visitFunctionNode(ir.FunctionNode node) {
+ VariableUse parameterUsage = node.parent is ir.Member
+ ? new VariableUse.memberParameter(node.parent)
+ : new VariableUse.localParameter(node.parent);
+ visitListInContext(node.typeParameters, parameterUsage);
+ for (ir.VariableDeclaration declaration in node.positionalParameters) {
+ handleVariableDeclaration(declaration, parameterUsage);
+ }
+ for (ir.VariableDeclaration declaration in node.namedParameters) {
+ handleVariableDeclaration(declaration, parameterUsage);
+ }
+ visitInContext(
+ node.returnType,
+ node.parent is ir.Member
+ ? new VariableUse.memberReturnType(node.parent)
+ : new VariableUse.localReturnType(node.parent));
+ node.body?.accept(this);
+ }
+
+ @override
+ visitListLiteral(ir.ListLiteral node) {
+ visitInContext(node.typeArgument, VariableUse.listLiteral);
+ ir.visitList(node.expressions, this);
+ }
+
+ @override
+ visitMapLiteral(ir.MapLiteral node) {
+ visitInContext(node.keyType, VariableUse.mapLiteral);
+ visitInContext(node.valueType, VariableUse.mapLiteral);
+ ir.visitList(node.entries, this);
+ }
+
+ @override
+ visitStaticInvocation(ir.StaticInvocation node) {
+ if (node.arguments.types.isNotEmpty) {
+ VariableUse usage;
+ if (node.target.kind == ir.ProcedureKind.Factory) {
+ usage = new VariableUse.constructorTypeArgument(node.target);
+ } else {
+ usage = new VariableUse.staticTypeArgument(node.target);
+ }
+
+ visitListInContext(node.arguments.types, usage);
+ }
+ ir.visitList(node.arguments.positional, this);
+ ir.visitList(node.arguments.named, this);
+ }
+
+ @override
+ visitConstructorInvocation(ir.ConstructorInvocation node) {
+ if (node.arguments.types.isNotEmpty) {
+ visitListInContext(node.arguments.types,
+ new VariableUse.constructorTypeArgument(node.target));
+ }
+ ir.visitList(node.arguments.positional, this);
+ ir.visitList(node.arguments.named, this);
+ }
+
+ @override
+ visitConditionalExpression(ir.ConditionalExpression node) {
+ node.condition.accept(this);
+ node.then.accept(this);
+ node.otherwise.accept(this);
+ // Don't visit `node.staticType`.
+ }
+
+ @override
+ visitMethodInvocation(ir.MethodInvocation node) {
+ ir.TreeNode receiver = node.receiver;
+ receiver.accept(this);
+ if (node.arguments.types.isNotEmpty) {
+ VariableUse usage;
+ if (receiver is ir.VariableGet &&
+ (receiver.variable.parent is ir.FunctionDeclaration ||
+ receiver.variable.parent is ir.FunctionExpression)) {
+ usage =
+ new VariableUse.localTypeArgument(receiver.variable.parent, node);
+ } else {
+ usage = new VariableUse.instanceTypeArgument(node);
+ }
+ visitListInContext(node.arguments.types, usage);
+ }
+ ir.visitList(node.arguments.positional, this);
+ ir.visitList(node.arguments.named, this);
+ }
+
+ @override
+ visitCatch(ir.Catch node) {
+ visitInContext(node.guard, VariableUse.explicit);
+ node.exception?.accept(this);
+ node.stackTrace?.accept(this);
+ node.body.accept(this);
}
/// Returns true if the node is a field, or a constructor (factory or
@@ -507,8 +636,8 @@
node is ir.Field ||
(node is ir.Procedure && node.isFactory);
- void _analyzeTypeVariable(ir.TypeParameterType type,
- {bool onlyIfNeedsRti: true}) {
+ void _analyzeTypeVariable(ir.TypeParameterType type, VariableUse usage) {
+ assert(usage != null);
if (_outermostNode is ir.Member) {
TypeVariableTypeWithContext typeVariable =
new TypeVariableTypeWithContext(type, _outermostNode);
@@ -516,17 +645,15 @@
case TypeVariableKind.cls:
if (_isFieldOrConstructor(_outermostNode)) {
// Class type variable used in a field or constructor.
- _useTypeVariableAsLocal(typeVariable,
- onlyForRtiChecks: onlyIfNeedsRti);
+ _useTypeVariableAsLocal(typeVariable, usage);
} else {
// Class type variable used in a method.
- _registerNeedsThis(onlyIfNeedsRti: onlyIfNeedsRti);
+ _registerNeedsThis(usage);
}
break;
case TypeVariableKind.method:
case TypeVariableKind.local:
- _useTypeVariableAsLocal(typeVariable,
- onlyForRtiChecks: onlyIfNeedsRti);
+ _useTypeVariableAsLocal(typeVariable, usage);
break;
case TypeVariableKind.function:
// The type variable is a function type variable, like `T` in
@@ -540,11 +667,11 @@
/// If [onlyForRtiChecks] is true, the variable will be added to a list
/// indicating it *may* be used only if runtime type information is checked.
- void _useTypeVariableAsLocal(TypeVariableTypeWithContext typeVariable,
- {bool onlyForRtiChecks: false}) {
+ void _useTypeVariableAsLocal(
+ TypeVariableTypeWithContext typeVariable, VariableUse usage) {
if (typeVariable.kind != TypeVariableKind.cls && !_options.strongMode) {
return;
}
- _markVariableAsUsed(typeVariable, onlyForRtiChecks: onlyForRtiChecks);
+ _markVariableAsUsed(typeVariable, usage);
}
}
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 3e762b9..fdda596 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -18,31 +18,42 @@
///
/// Querying for the frontend element for a backend-only element throws an
/// exception.
-class JsToFrontendMap {
- LibraryEntity toBackendLibrary(LibraryEntity library) => library;
+abstract class JsToFrontendMap {
+ LibraryEntity toBackendLibrary(LibraryEntity library);
- ClassEntity toBackendClass(ClassEntity cls) => cls;
+ ClassEntity toBackendClass(ClassEntity cls);
- MemberEntity toBackendMember(MemberEntity member) => member;
+ /// Returns the backend member corresponding to [member]. If a member isn't
+ /// live, it doesn't have a corresponding backend member and `null` is
+ /// returned instead.
+ MemberEntity toBackendMember(MemberEntity member);
- DartType toBackendType(DartType type) => type;
+ DartType toBackendType(DartType type);
Set<LibraryEntity> toBackendLibrarySet(Iterable<LibraryEntity> set) {
return set.map(toBackendLibrary).toSet();
}
Set<ClassEntity> toBackendClassSet(Iterable<ClassEntity> set) {
+ // TODO(johnniwinther): Filter unused classes.
return set.map(toBackendClass).toSet();
}
Set<MemberEntity> toBackendMemberSet(Iterable<MemberEntity> set) {
- return set.map(toBackendMember).toSet();
+ return set.map(toBackendMember).where((MemberEntity member) {
+ // Members that are not live don't have a corresponding backend member.
+ return member != null;
+ }).toSet();
}
Set<FunctionEntity> toBackendFunctionSet(Iterable<FunctionEntity> set) {
Set<FunctionEntity> newSet = new Set<FunctionEntity>();
for (FunctionEntity element in set) {
- newSet.add(toBackendMember(element));
+ FunctionEntity backendFunction = toBackendMember(element);
+ if (backendFunction != null) {
+ // Members that are not live don't have a corresponding backend member.
+ newSet.add(backendFunction);
+ }
}
return newSet;
}
@@ -69,7 +80,12 @@
Map<K, V> map, K convertKey(K key), V convertValue(V value)) {
Map<K, V> newMap = <K, V>{};
map.forEach((K key, V value) {
- newMap[convertKey(key)] = convertValue(value);
+ K newKey = convertKey(key);
+ V newValue = convertValue(value);
+ if (newKey != null && newValue != null) {
+ // Entities that are not used don't have a corresponding backend entity.
+ newMap[newKey] = newValue;
+ }
});
return newMap;
}
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 888b04b..9572c32 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -72,15 +72,14 @@
ClosedWorldRefiner createClosedWorldRefiner(ClosedWorld closedWorld) {
KernelFrontEndStrategy strategy = _compiler.frontendStrategy;
_elementMap = new JsKernelToElementMap(
- _compiler.reporter, _compiler.environment, strategy.elementMap);
+ _compiler.reporter,
+ _compiler.environment,
+ strategy.elementMap,
+ closedWorld.processedMembers);
_elementEnvironment = _elementMap.elementEnvironment;
_commonElements = _elementMap.commonElements;
_closureDataLookup = new KernelClosureConversionTask(
- _compiler.measurer,
- _elementMap,
- _globalLocalsMap,
- _compiler.options.enableTypeAssertions,
- _compiler.options.strongMode);
+ _compiler.measurer, _elementMap, _globalLocalsMap, _compiler.options);
JsClosedWorldBuilder closedWorldBuilder = new JsClosedWorldBuilder(
_elementMap, _closureDataLookup, _compiler.options);
return closedWorldBuilder._convertClosedWorld(
@@ -115,7 +114,12 @@
result[closureInfo.closureClassEntity] = unit;
result[closureInfo.callMethod] = unit;
} else {
- result[toBackendEntity(entity)] = unit;
+ Entity backendEntity = toBackendEntity(entity);
+ if (backendEntity != null) {
+ // If [entity] isn't used it doesn't have a corresponding backend
+ // entity.
+ result[backendEntity] = unit;
+ }
}
});
return result;
@@ -281,11 +285,9 @@
if (_options.disableRtiOptimization) {
rtiNeed = new TrivialRuntimeTypesNeed();
callMethods = _closureConversionTask.createClosureEntities(
- this, map.toBackendMemberMap(closureModels, identity),
- localFunctionNeedsSignature: (_) => true,
- classNeedsTypeArguments: (_) => true,
- methodNeedsTypeArguments: (_) => true,
- localFunctionNeedsTypeArguments: (_) => true);
+ this,
+ map.toBackendMemberMap(closureModels, identity),
+ const TrivialClosureRtiNeed());
} else {
RuntimeTypesNeedImpl kernelRtiNeed = closedWorld.rtiNeed;
Set<ir.Node> localFunctionsNodesNeedingSignature = new Set<ir.Node>();
@@ -308,23 +310,14 @@
RuntimeTypesNeedImpl jRtiNeed =
_convertRuntimeTypesNeed(map, backendUsage, kernelRtiNeed);
callMethods = _closureConversionTask.createClosureEntities(
- this, map.toBackendMemberMap(closureModels, identity),
- localFunctionNeedsSignature: (ir.Node node) {
- assert(node is ir.FunctionDeclaration ||
- node is ir.FunctionExpression);
- return backendUsage.isRuntimeTypeUsed
- ? true
- : localFunctionsNodesNeedingSignature.contains(node);
- },
- classNeedsTypeArguments: jRtiNeed.classNeedsTypeArguments,
- methodNeedsTypeArguments: jRtiNeed.methodNeedsTypeArguments,
- localFunctionNeedsTypeArguments: (ir.Node node) {
- assert(node is ir.FunctionDeclaration ||
- node is ir.FunctionExpression);
- return backendUsage.isRuntimeTypeUsed
- ? true
- : localFunctionsNodesNeedingTypeArguments.contains(node);
- });
+ this,
+ map.toBackendMemberMap(closureModels, identity),
+ new JsClosureRtiNeed(
+ backendUsage,
+ jRtiNeed,
+ localFunctionsNodesNeedingTypeArguments,
+ localFunctionsNodesNeedingSignature,
+ ));
List<FunctionEntity> callMethodsNeedingSignature = <FunctionEntity>[];
for (ir.Node node in localFunctionsNodesNeedingSignature) {
@@ -463,8 +456,12 @@
<FunctionEntity, NativeBehavior>{};
nativeData.nativeMethodBehavior
.forEach((FunctionEntity method, NativeBehavior behavior) {
- nativeMethodBehavior[map.toBackendMember(method)] =
- convertNativeBehavior(behavior);
+ FunctionEntity backendMethod = map.toBackendMember(method);
+ if (backendMethod != null) {
+ // If [method] isn't used it doesn't have a corresponding backend
+ // method.
+ nativeMethodBehavior[backendMethod] = convertNativeBehavior(behavior);
+ }
});
Map<MemberEntity, NativeBehavior> nativeFieldLoadBehavior =
map.toBackendMemberMap(
@@ -773,3 +770,53 @@
List<DartType> _visitList(List<DartType> list) =>
list.map<DartType>((t) => t.accept(this, null)).toList();
}
+
+class TrivialClosureRtiNeed implements ClosureRtiNeed {
+ const TrivialClosureRtiNeed();
+
+ bool localFunctionNeedsSignature(ir.Node node) => true;
+ bool classNeedsTypeArguments(ClassEntity cls) => true;
+ bool methodNeedsTypeArguments(FunctionEntity method) => true;
+ bool localFunctionNeedsTypeArguments(ir.Node node) => true;
+ bool selectorNeedsTypeArguments(Selector selector) => true;
+ bool methodNeedsSignature(MemberEntity method) => true;
+}
+
+class JsClosureRtiNeed implements ClosureRtiNeed {
+ final BackendUsage backendUsage;
+ final RuntimeTypesNeed rtiNeed;
+ final Set<ir.Node> localFunctionsNodesNeedingTypeArguments;
+ final Set<ir.Node> localFunctionsNodesNeedingSignature;
+
+ JsClosureRtiNeed(
+ this.backendUsage,
+ this.rtiNeed,
+ this.localFunctionsNodesNeedingTypeArguments,
+ this.localFunctionsNodesNeedingSignature);
+
+ bool localFunctionNeedsSignature(ir.Node node) {
+ assert(node is ir.FunctionDeclaration || node is ir.FunctionExpression);
+ return backendUsage.isRuntimeTypeUsed
+ ? true
+ : localFunctionsNodesNeedingSignature.contains(node);
+ }
+
+ bool classNeedsTypeArguments(ClassEntity cls) =>
+ rtiNeed.classNeedsTypeArguments(cls);
+
+ bool methodNeedsTypeArguments(FunctionEntity method) =>
+ rtiNeed.methodNeedsTypeArguments(method);
+
+ bool localFunctionNeedsTypeArguments(ir.Node node) {
+ assert(node is ir.FunctionDeclaration || node is ir.FunctionExpression);
+ return backendUsage.isRuntimeTypeUsed
+ ? true
+ : localFunctionsNodesNeedingTypeArguments.contains(node);
+ }
+
+ bool selectorNeedsTypeArguments(Selector selector) =>
+ rtiNeed.selectorNeedsTypeArguments(selector);
+
+ bool methodNeedsSignature(MemberEntity method) =>
+ rtiNeed.methodNeedsSignature(method);
+}
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index af6f30a..8c7e543 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -223,6 +223,29 @@
JJumpTarget target;
ir.TreeNode body = node.target.body;
ir.TreeNode parent = node.target.parent;
+
+ // TODO(johnniwinther): Coordinate with CFE-team to avoid such arbitrary
+ // reverse engineering mismatches:
+ if (parent is ir.Block && parent.statements.last == node.target) {
+ // In strong mode for code like this:
+ //
+ // for (int i in list) {
+ // continue;
+ // }
+ //
+ // an implicit cast may be inserted before the label statement, resulting
+ // in code like this:
+ //
+ // for (var i in list) {
+ // var #1 = i as int;
+ // l1: {
+ // break l1:
+ // }
+ // }
+ //
+ // for which we should still use the for loop as a continue target.
+ parent = parent.parent;
+ }
if (canBeBreakTarget(body)) {
// We have code like
//
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 48a25e7..d9c3e7a 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -185,6 +185,10 @@
/// Returns the definition information for [cls].
ClassDefinition getClassDefinition(covariant ClassEntity cls);
+
+ /// Returns the static type of [node].
+ // TODO(johnniwinther): This should be provided directly from kernel.
+ DartType getStaticType(ir.Expression node);
}
/// Interface that translates between Kernel IR nodes and entities used for
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index ecf8d0a..e7791c6 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -5,6 +5,9 @@
library dart2js.kernel.element_map;
import 'package:kernel/ast.dart' as ir;
+import 'package:kernel/class_hierarchy.dart' as ir;
+import 'package:kernel/core_types.dart' as ir;
+import 'package:kernel/type_environment.dart' as ir;
import '../closure.dart' show BoxLocal, ThisLocal;
import '../common.dart';
@@ -202,6 +205,10 @@
});
}
+ void ensureClassMembers(ir.Class node) {
+ _classes.getEnv(_getClass(node)).ensureMembers(this);
+ }
+
MemberEntity lookupClassMember(IndexedClass cls, String name,
{bool setter: false}) {
assert(checkFamily(cls));
@@ -342,17 +349,24 @@
MemberEntity getSuperMember(
MemberEntity context, ir.Name name, ir.Member target,
{bool setter: false}) {
- if (target != null) {
+ if (target != null && !target.isAbstract && target.isInstanceMember) {
return getMember(target);
}
ClassEntity cls = context.enclosingClass;
+ assert(
+ cls != null,
+ failedAt(context,
+ "No enclosing class for super member access in $context."));
IndexedClass superclass = _getSuperType(cls)?.element;
while (superclass != null) {
ClassEnv env = _classes.getEnv(superclass);
MemberEntity superMember =
env.lookupMember(this, name.name, setter: setter);
- if (superMember != null && !superMember.isAbstract) {
- return superMember;
+ if (superMember != null) {
+ if (!superMember.isInstanceMember) return null;
+ if (!superMember.isAbstract) {
+ return superMember;
+ }
}
superclass = _getSuperType(superclass)?.element;
}
@@ -1187,11 +1201,37 @@
KElementCreatorMixin {
native.BehaviorBuilder _nativeBehaviorBuilder;
FrontendStrategy _frontendStrategy;
+ ir.TypeEnvironment _typeEnvironment;
+ bool _isStaticTypePrepared = false;
KernelToElementMapForImpactImpl(DiagnosticReporter reporter,
Environment environment, this._frontendStrategy, CompilerOptions options)
: super(options, reporter, environment);
+ DartType getStaticType(ir.Expression node) {
+ if (!_isStaticTypePrepared) {
+ _isStaticTypePrepared = true;
+ try {
+ _typeEnvironment ??= new ir.TypeEnvironment(
+ new ir.CoreTypes(_env.mainComponent),
+ new ir.ClassHierarchy(_env.mainComponent),
+ strongMode: options.strongMode);
+ } catch (e) {}
+ }
+ if (_typeEnvironment == null) {
+ // The class hierarchy crashes on multiple inheritance. Use `dynamic`
+ // as static type.
+ return commonElements.dynamicType;
+ }
+ ir.TreeNode enclosingClass = node;
+ while (enclosingClass != null && enclosingClass is! ir.Class) {
+ enclosingClass = enclosingClass.parent;
+ }
+ _typeEnvironment.thisType =
+ enclosingClass is ir.Class ? enclosingClass.thisType : null;
+ return getDartType(node.getStaticType(_typeEnvironment));
+ }
+
@override
bool checkFamily(Entity entity) {
assert(
@@ -1409,6 +1449,39 @@
}
@override
+ DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function) {
+ DartType returnType = getFunctionType(function).returnType;
+ switch (function.asyncMarker) {
+ case AsyncMarker.SYNC:
+ return returnType;
+ case AsyncMarker.SYNC_STAR:
+ if (returnType is InterfaceType) {
+ if (returnType.element == elementMap.commonElements.iterableClass) {
+ return returnType.typeArguments.first;
+ }
+ }
+ return dynamicType;
+ case AsyncMarker.ASYNC:
+ if (returnType is FutureOrType) return returnType.typeArgument;
+ if (returnType is InterfaceType) {
+ if (returnType.element == elementMap.commonElements.futureClass) {
+ return returnType.typeArguments.first;
+ }
+ }
+ return dynamicType;
+ case AsyncMarker.ASYNC_STAR:
+ if (returnType is InterfaceType) {
+ if (returnType.element == elementMap.commonElements.streamClass) {
+ return returnType.typeArguments.first;
+ }
+ }
+ return dynamicType;
+ }
+ assert(false, 'Unexpected marker ${function.asyncMarker}');
+ return null;
+ }
+
+ @override
DartType getFieldType(FieldEntity field) {
return elementMap._getFieldType(field);
}
@@ -2159,8 +2232,11 @@
NativeBasicData nativeBasicData;
- JsKernelToElementMap(DiagnosticReporter reporter, Environment environment,
- KernelToElementMapForImpactImpl _elementMap)
+ JsKernelToElementMap(
+ DiagnosticReporter reporter,
+ Environment environment,
+ KernelToElementMapForImpactImpl _elementMap,
+ Iterable<MemberEntity> liveMembers)
: super(_elementMap.options, reporter, environment) {
_env = _elementMap._env;
for (int libraryIndex = 0;
@@ -2173,7 +2249,11 @@
IndexedLibrary newLibrary = convertLibrary(oldLibrary);
_libraryMap[env.library] =
_libraries.register<IndexedLibrary, LibraryData, LibraryEnv>(
- newLibrary, data.copy(), env);
+ newLibrary,
+ data.copy(),
+ options.strongMode && useStrongModeWorldStrategy
+ ? env.copyLive(_elementMap, liveMembers)
+ : env);
assert(newLibrary.libraryIndex == oldLibrary.libraryIndex);
}
for (int classIndex = 0;
@@ -2185,7 +2265,12 @@
IndexedLibrary oldLibrary = oldClass.library;
LibraryEntity newLibrary = _libraries.getEntity(oldLibrary.libraryIndex);
IndexedClass newClass = convertClass(newLibrary, oldClass);
- _classMap[env.cls] = _classes.register(newClass, data.copy(), env);
+ _classMap[env.cls] = _classes.register(
+ newClass,
+ data.copy(),
+ options.strongMode && useStrongModeWorldStrategy
+ ? env.copyLive(_elementMap, liveMembers)
+ : env);
assert(newClass.classIndex == oldClass.classIndex);
}
for (int typedefIndex = 0;
@@ -2211,6 +2296,12 @@
memberIndex < _elementMap._members.length;
memberIndex++) {
IndexedMember oldMember = _elementMap._members.getEntity(memberIndex);
+ if (options.strongMode &&
+ useStrongModeWorldStrategy &&
+ !liveMembers.contains(oldMember)) {
+ _members.skipIndex(oldMember.memberIndex);
+ continue;
+ }
MemberDataImpl data = _elementMap._members.getData(oldMember);
IndexedLibrary oldLibrary = oldMember.library;
IndexedClass oldClass = oldMember.enclosingClass;
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 90077cb..da925b6 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -32,6 +32,8 @@
/// TODO(johnniwinther): Handle arbitrary load order if needed.
ir.Member get mainMethod => _components.first?.mainMethod;
+ ir.Component get mainComponent => _components.first;
+
void addComponent(ir.Component component) {
if (_components.add(component)) {
if (_libraryMap != null) {
@@ -84,6 +86,9 @@
LibraryEnv(this.library);
+ LibraryEnv.internal(
+ this.library, this._classMap, this._memberMap, this._setterMap);
+
void _ensureClassMap() {
if (_classMap == null) {
_classMap = <String, ClassEnv>{};
@@ -150,6 +155,45 @@
}
}
}
+
+ /// Creates a new [LibraryEnv] containing only the members in [liveMembers].
+ ///
+ /// Currently all classes are copied.
+ // TODO(johnniwinther): Filter unused classes.
+ LibraryEnv copyLive(
+ KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+ Map<String, ClassEnv> classMap;
+ Map<String, ir.Member> memberMap;
+ Map<String, ir.Member> setterMap;
+ if (_classMap == null) {
+ classMap = const <String, ClassEnv>{};
+ } else {
+ classMap = _classMap;
+ }
+ if (_memberMap == null) {
+ memberMap = const <String, ir.Member>{};
+ } else {
+ memberMap = <String, ir.Member>{};
+ _memberMap.forEach((String name, ir.Member node) {
+ MemberEntity member = elementMap.getMember(node);
+ if (liveMembers.contains(member)) {
+ memberMap[name] = node;
+ }
+ });
+ }
+ if (_setterMap == null) {
+ setterMap = const <String, ir.Member>{};
+ } else {
+ setterMap = <String, ir.Member>{};
+ _setterMap.forEach((String name, ir.Member node) {
+ MemberEntity member = elementMap.getMember(node);
+ if (liveMembers.contains(member)) {
+ setterMap[name] = node;
+ }
+ });
+ }
+ return new LibraryEnv.internal(library, classMap, memberMap, setterMap);
+ }
}
class LibraryData {
@@ -196,6 +240,9 @@
/// Whether the class is an unnamed mixin application.
bool get isUnnamedMixinApplication;
+ /// Ensures that all members have been computed for [cls].
+ void ensureMembers(KernelToElementMapBase elementMap);
+
/// Return the [MemberEntity] for the member [name] in the class. If [setter]
/// is `true`, the setter or assignable field corresponding to [name] is
/// returned.
@@ -217,6 +264,10 @@
/// Calls [f] for each constructor body for the live constructors in the
/// class.
void forEachConstructorBody(void f(ConstructorBodyEntity constructor));
+
+ /// Creates a new [ClassEnv] containing only the members in [liveMembers].
+ ClassEnv copyLive(
+ KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers);
}
int orderByFileOffset(ir.TreeNode a, ir.TreeNode b) {
@@ -243,6 +294,9 @@
ClassEnvImpl(this.cls);
+ ClassEnvImpl.internal(this.cls, this._constructorMap, this._memberMap,
+ this._setterMap, this._members);
+
bool get isUnnamedMixinApplication => cls.isSyntheticMixinImplementation;
/// Copied from 'package:kernel/transformations/mixin_full_resolution.dart'.
@@ -291,6 +345,10 @@
initializers: <ir.Initializer>[superInitializer]);
}
+ void ensureMembers(KernelToElementMapBase elementMap) {
+ _ensureMaps(elementMap);
+ }
+
void _ensureMaps(KernelToElementMapBase elementMap) {
if (_memberMap != null) return;
@@ -364,6 +422,7 @@
int mixinMemberCount = 0;
if (cls.mixedInClass != null) {
+ elementMap.ensureClassMembers(cls.mixedInClass);
addFields(cls.mixedInClass.mixin, includeStatic: false);
addProcedures(cls.mixedInClass.mixin, includeStatic: false);
mergeSort(members, compare: orderByFileOffset);
@@ -446,6 +505,60 @@
void forEachConstructorBody(void f(ConstructorBodyEntity constructor)) {
_constructorBodyList?.forEach(f);
}
+
+ ClassEnv copyLive(
+ KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+ Map<String, ir.Member> constructorMap;
+ Map<String, ir.Member> memberMap;
+ Map<String, ir.Member> setterMap;
+ List<ir.Member> members;
+ if (_constructorMap == null) {
+ constructorMap = const <String, ir.Member>{};
+ } else {
+ constructorMap = <String, ir.Member>{};
+ _constructorMap.forEach((String name, ir.Member node) {
+ MemberEntity member = elementMap.getMember(node);
+ if (liveMembers.contains(member)) {
+ constructorMap[name] = node;
+ }
+ });
+ }
+ if (_memberMap == null) {
+ memberMap = const <String, ir.Member>{};
+ } else {
+ memberMap = <String, ir.Member>{};
+ _memberMap.forEach((String name, ir.Member node) {
+ MemberEntity member = elementMap.getMember(node);
+ if (liveMembers.contains(member)) {
+ memberMap[name] = node;
+ }
+ });
+ }
+ if (_setterMap == null) {
+ setterMap = const <String, ir.Member>{};
+ } else {
+ setterMap = <String, ir.Member>{};
+ _setterMap.forEach((String name, ir.Member node) {
+ MemberEntity member = elementMap.getMember(node);
+ if (liveMembers.contains(member)) {
+ setterMap[name] = node;
+ }
+ });
+ }
+ if (_members == null) {
+ members = const <ir.Member>[];
+ } else {
+ members = <ir.Member>[];
+ _members.forEach((ir.Member node) {
+ MemberEntity member = elementMap.getMember(node);
+ if (liveMembers.contains(member)) {
+ members.add(node);
+ }
+ });
+ }
+ return new ClassEnvImpl.internal(
+ cls, constructorMap, memberMap, setterMap, members);
+ }
}
class ClosureClassEnv extends RecordEnv {
@@ -460,6 +573,11 @@
}
return super.lookupMember(elementMap, name, setter: setter);
}
+
+ @override
+ ClassEnv copyLive(
+ KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) =>
+ this;
}
class RecordEnv implements ClassEnv {
@@ -468,6 +586,11 @@
RecordEnv(this._memberMap);
@override
+ void ensureMembers(KernelToElementMapBase elementMap) {
+ // All members have been computed at creation.
+ }
+
+ @override
void forEachConstructorBody(void f(ConstructorBodyEntity constructor)) {
// We do not create constructor bodies for containers.
}
@@ -502,6 +625,12 @@
@override
ir.Class get cls => null;
+
+ @override
+ ClassEnv copyLive(
+ KernelToElementMap elementMap, Iterable<MemberEntity> liveMembers) {
+ return this;
+ }
}
class ClassData {
diff --git a/pkg/compiler/lib/src/kernel/indexed.dart b/pkg/compiler/lib/src/kernel/indexed.dart
index bf7be15..28545af 100644
--- a/pkg/compiler/lib/src/kernel/indexed.dart
+++ b/pkg/compiler/lib/src/kernel/indexed.dart
@@ -61,9 +61,10 @@
/// Index based map of entities of type [E].
class EntityMap<E extends _Indexed> extends EntityMapBase<E> {
- /// Registers a new entity.
+ /// Registers a new [entity].
///
- /// [createEntity] is called to create the entity with the given index.
+ /// The index of [entity] is set to match its index in the entity list in this
+ /// map.
E0 register<E0 extends E>(E0 entity) {
assert(entity != null);
assert(entity._index == null);
@@ -93,11 +94,17 @@
/// Index based map of entities of type [E] with a corresponding data object
/// of type [D].
class EntityDataMap<E extends _Indexed, D> extends EntityDataMapBase<E, D> {
- /// Registers a new entity with an associated data object.
+ /// Mark entity [index] as missing
+ void skipIndex(int index) {
+ assert(index == _list.length);
+ _list.add(null);
+ _data.add(null);
+ }
+
+ /// Registers a new [entity] with an associated [data] object.
///
- /// Firstly, [createEntity] is called to create the entity with the given
- /// index. Secondly, [createData] is called with the newly created entity to
- /// create the associated data object.
+ /// The index of [entity] is set to match its index in the entity and data
+ /// lists in this map.
E0 register<E0 extends E, D0 extends D>(E0 entity, D0 data) {
assert(entity != null);
assert(entity._index == null);
@@ -130,12 +137,11 @@
/// type [D] and an environment of type [V].
class EntityDataEnvMap<E extends _Indexed, D, V>
extends EntityDataEnvMapBase<E, D, V> {
- /// Registers a new entity with an associated data object and environment.
+ /// Registers a new [entity] with an associated [data] object and environment
+ /// [env].
///
- /// Firstly, [createEntity] is called to create the entity with the given
- /// index. Secondly, [createData] is called with the newly created entity to
- /// create the associated data object. Thirdly, [createEnv] is called with
- /// the newly created entity to create the associated environment object.
+ /// The index of [entity] is set to match its index in the entity, data and
+ /// environment lists in this map.
E0 register<E0 extends E, D0 extends D, V0 extends V>(
E0 entity, D0 data, V0 env) {
assert(entity != null);
diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
index d0de459..b575680 100644
--- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
@@ -238,7 +238,7 @@
}
@override
- Iterable<MemberEntity> sortMembers(Iterable<MemberEntity> members) {
+ Iterable<T> sortMembers<T extends MemberEntity>(Iterable<T> members) {
return members.toList()..sort(compareMembersByLocation);
}
diff --git a/pkg/compiler/lib/src/kernel/types.dart b/pkg/compiler/lib/src/kernel/types.dart
index 3f6a1a6..9f6efde 100644
--- a/pkg/compiler/lib/src/kernel/types.dart
+++ b/pkg/compiler/lib/src/kernel/types.dart
@@ -16,8 +16,10 @@
new _KernelPotentialSubtypeVisitor(elementMap);
@override
- bool isPotentialSubtype(DartType t, DartType s) {
- return potentialSubtypeVisitor.isSubtype(t, s);
+ bool isPotentialSubtype(DartType t, DartType s,
+ {bool assumeInstantiations: true}) {
+ return potentialSubtypeVisitor.isPotentialSubtype(t, s,
+ assumeInstantiations: assumeInstantiations);
}
@override
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 71ea505..081a066 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -852,7 +852,7 @@
Token synthesizeIdentifier(Token token) {
Token synthesizedToken =
new StringToken.fromString(TokenType.IDENTIFIER, '?', token.charOffset);
- synthesizedToken.next = token.next;
+ synthesizedToken.setNext(token.next);
return synthesizedToken;
}
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index e50aede..abda55c 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -4328,6 +4328,7 @@
MessageKind.INVALID_AWAIT_FOR_IN);
}
registry.registerFeature(Feature.ASYNC_FOR_IN);
+ registry.registerDynamicUse(new DynamicUse(Selectors.cancel));
registry.registerDynamicUse(new DynamicUse(Selectors.current));
registry.registerDynamicUse(new DynamicUse(Selectors.moveNext));
}
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
index c4bfb96..b73f923 100644
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
@@ -737,6 +737,11 @@
}
@override
+ DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function) {
+ return dynamicType;
+ }
+
+ @override
DartType getFieldType(covariant FieldElement field) {
field.computeType(_resolution);
return field.type;
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 37c4541..23353e6 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -4126,7 +4126,7 @@
}
}
- bool isOptimizableOperation(Selector selector, Element element) {
+ bool isOptimizableOperation(Selector selector, MemberElement element) {
ClassElement cls = element.enclosingClass;
if (isOptimizableOperationOnIndexable(selector, element)) return true;
if (!interceptorData.interceptedClasses.contains(cls)) return false;
@@ -4136,7 +4136,7 @@
if (selector.isIndexSet) return true;
if (element == commonElements.jsArrayAdd ||
element == commonElements.jsArrayRemoveLast ||
- element == commonElements.jsStringSplit) {
+ commonElements.isJsStringSplit(element)) {
return true;
}
return false;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index efed6ee..06ebbe7 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -2787,14 +2787,17 @@
node.value.accept(this);
HInstruction value = pop();
- if (node.interfaceTarget == null) {
+ MemberEntity member = _elementMap.getSuperMember(
+ _currentFrame.member, node.name, node.interfaceTarget,
+ setter: true);
+ if (member == null) {
_generateSuperNoSuchMethod(node, _elementMap.getSelector(node).name + "=",
<HInstruction>[value], const <DartType>[], sourceInformation);
} else {
_buildInvokeSuper(
_elementMap.getSelector(node),
_elementMap.getClass(_containingClass(node)),
- _elementMap.getMember(node.interfaceTarget),
+ member,
<HInstruction>[value],
const <DartType>[],
sourceInformation);
@@ -3811,7 +3814,7 @@
if (selector.isIndexSet) return true;
if (element == commonElements.jsArrayAdd ||
element == commonElements.jsArrayRemoveLast ||
- element == commonElements.jsStringSplit) {
+ commonElements.isJsStringSplit(element)) {
return true;
}
return false;
@@ -4170,14 +4173,16 @@
void visitSuperPropertyGet(ir.SuperPropertyGet node) {
SourceInformation sourceInformation =
_sourceInformationBuilder.buildGet(node);
- if (node.interfaceTarget == null) {
+ MemberEntity member = _elementMap.getSuperMember(
+ _currentFrame.member, node.name, node.interfaceTarget);
+ if (member == null) {
_generateSuperNoSuchMethod(node, _elementMap.getSelector(node).name,
const <HInstruction>[], const <DartType>[], sourceInformation);
} else {
_buildInvokeSuper(
_elementMap.getSelector(node),
_elementMap.getClass(_containingClass(node)),
- _elementMap.getMember(node.interfaceTarget),
+ member,
const <HInstruction>[],
const <DartType>[],
sourceInformation);
@@ -4188,7 +4193,9 @@
void visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
SourceInformation sourceInformation =
_sourceInformationBuilder.buildCall(node, node);
- if (node.interfaceTarget == null) {
+ MemberEntity member = _elementMap.getSuperMember(
+ _currentFrame.member, node.name, node.interfaceTarget);
+ if (member == null) {
Selector selector = _elementMap.getSelector(node);
List<DartType> typeArguments = <DartType>[];
selector =
@@ -4199,9 +4206,8 @@
node, selector.name, arguments, typeArguments, sourceInformation);
return;
}
- FunctionEntity function = _elementMap.getMethod(node.interfaceTarget);
List<DartType> typeArguments =
- _getStaticTypeArguments(function, node.arguments);
+ _getStaticTypeArguments(member, node.arguments);
List<HInstruction> arguments = _visitArgumentsForStaticTarget(
node.interfaceTarget.function,
node.arguments,
@@ -4210,7 +4216,7 @@
_buildInvokeSuper(
_elementMap.getSelector(node),
_elementMap.getClass(_containingClass(node)),
- function,
+ member,
arguments,
typeArguments,
sourceInformation);
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index f108912..2e4c056 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -1738,7 +1738,7 @@
methodName = 'push';
} else if (target == _commonElements.jsArrayRemoveLast) {
methodName = 'pop';
- } else if (target == _commonElements.jsStringSplit) {
+ } else if (_commonElements.isJsStringSplit(target)) {
methodName = 'split';
// Split returns a List, so we make sure the backend knows the
// list class is instantiated.
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index c476754..f02b6c6 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -122,16 +122,52 @@
CompilerOptions options,
CommonElements commonElements,
ClosedWorld closedWorld) {
- if (instruction.inputs[1].isMutableIndexable(closedWorld)) {
- if (!instruction.inputs[2].isInteger(closedWorld) &&
- options.enableTypeAssertions) {
- // We want the right checked mode error.
+ HInstruction receiver = instruction.inputs[1];
+ HInstruction index = instruction.inputs[2];
+ if (!receiver.isMutableIndexable(closedWorld)) return null;
+ if (!index.isInteger(closedWorld) && options.enableTypeAssertions) {
+ // We want the right checked mode error.
+ return null;
+ }
+
+ HInstruction value = instruction.inputs[3];
+ if (options.parameterCheckPolicy.isEmitted) {
+ if (!_valueParameterCheckAlwaysSucceeds(
+ instruction, receiver, value, commonElements, closedWorld)) {
return null;
}
- return new HIndexAssign(instruction.inputs[1], instruction.inputs[2],
- instruction.inputs[3], instruction.selector);
}
- return null;
+ return new HIndexAssign(receiver, index, value, instruction.selector);
+ }
+
+ /// Returns [true] if [value] meets the requirements for being stored into
+ /// indexable [receiver].
+ bool _valueParameterCheckAlwaysSucceeds(
+ HInvokeDynamic instruction,
+ HInstruction receiver,
+ HInstruction value,
+ CommonElements commonElements,
+ ClosedWorld closedWorld) {
+ // Handle typed arrays by recognizing the exact implementation of `[]=` and
+ // checking if [value] has the appropriate type.
+ if (instruction.element != null) {
+ ClassEntity cls = instruction.element.enclosingClass;
+ if (cls == commonElements.typedArrayOfIntClass) {
+ return value.isInteger(closedWorld);
+ } else if (cls == commonElements.typedArrayOfDoubleClass) {
+ return value.isNumber(closedWorld);
+ }
+ }
+
+ // The type check will pass if it passed before. We know it passed before if
+ // the value was loaded from the same indexable.
+ if (value is HIndex) {
+ if (value.receiver.nonCheck() == receiver.nonCheck()) {
+ return true;
+ }
+ }
+
+ return false;
}
}
@@ -212,8 +248,18 @@
GlobalTypeInferenceResults results,
CompilerOptions options,
ClosedWorld closedWorld) {
- TypeMask operandType = instruction.inputs[1].instructionType;
- if (instruction.inputs[1].isNumberOrNull(closedWorld)) return operandType;
+ HInstruction operand = instruction.inputs[1];
+ if (operand.isNumberOrNull(closedWorld)) {
+ // We have integer subclasses that represent ranges, so widen any int
+ // subclass to full integer.
+ if (operand.isIntegerOrNull(closedWorld)) {
+ return closedWorld.commonMasks.intType;
+ }
+ if (operand.isDoubleOrNull(closedWorld)) {
+ return closedWorld.commonMasks.doubleType;
+ }
+ return closedWorld.commonMasks.numType;
+ }
return super
.computeTypeFromInputTypes(instruction, results, options, closedWorld);
}
@@ -227,7 +273,11 @@
ClosedWorld closedWorld) {
HInstruction input = instruction.inputs[1];
if (input.isNumber(closedWorld)) {
- return new HNegate(input, instruction.selector, input.instructionType);
+ return new HNegate(
+ input,
+ instruction.selector,
+ computeTypeFromInputTypes(
+ instruction, results, options, closedWorld));
}
return null;
}
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index 3e93ba2..6f96104 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -19,6 +19,7 @@
import '../universe/feature.dart';
import '../universe/selector.dart';
import '../universe/use.dart';
+import '../universe/world_builder.dart';
ResolutionImpact buildKernelImpact(
ir.Member member,
@@ -438,9 +439,16 @@
List<DartType> typeArguments = _visitArguments(node.arguments);
// TODO(johnniwinther): Restrict the dynamic use to only match the known
// target.
- impactBuilder.registerDynamicUse(new GenericDynamicUse(
- new Selector.call(elementMap.getMember(node.target).memberName,
- elementMap.getCallStructure(node.arguments)),
+ ReceiverConstraint constraint;
+ MemberEntity member = elementMap.getMember(node.target);
+ if (_options.strongMode && useStrongModeWorldStrategy) {
+ // TODO(johnniwinther): Restrict this to subclasses?
+ constraint = new StrongModeConstraint(member.enclosingClass);
+ }
+ impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+ new Selector.call(
+ member.memberName, elementMap.getCallStructure(node.arguments)),
+ constraint,
typeArguments));
}
@@ -514,10 +522,10 @@
}
@override
- void visitMethodInvocation(ir.MethodInvocation invocation) {
- Selector selector = elementMap.getSelector(invocation);
- List<DartType> typeArguments = _visitArguments(invocation.arguments);
- var receiver = invocation.receiver;
+ void visitMethodInvocation(ir.MethodInvocation node) {
+ Selector selector = elementMap.getSelector(node);
+ List<DartType> typeArguments = _visitArguments(node.arguments);
+ var receiver = node.receiver;
if (receiver is ir.VariableGet &&
receiver.variable.isFinal &&
receiver.variable.parent is ir.FunctionDeclaration) {
@@ -530,25 +538,49 @@
localFunction, selector.callStructure, typeArguments));
}
} else {
- visitNode(invocation.receiver);
- impactBuilder
- .registerDynamicUse(new GenericDynamicUse(selector, typeArguments));
+ visitNode(node.receiver);
+ ReceiverConstraint constraint;
+ if (_options.strongMode && useStrongModeWorldStrategy) {
+ DartType receiverType = elementMap.getStaticType(node.receiver);
+ if (receiverType is InterfaceType) {
+ constraint = new StrongModeConstraint(receiverType.element);
+ }
+ }
+
+ impactBuilder.registerDynamicUse(
+ new ConstrainedDynamicUse(selector, constraint, typeArguments));
}
}
@override
void visitPropertyGet(ir.PropertyGet node) {
visitNode(node.receiver);
- impactBuilder.registerDynamicUse(
- new DynamicUse(new Selector.getter(elementMap.getName(node.name))));
+ ReceiverConstraint constraint;
+ if (_options.strongMode && useStrongModeWorldStrategy) {
+ DartType receiverType = elementMap.getStaticType(node.receiver);
+ if (receiverType is InterfaceType) {
+ constraint = new StrongModeConstraint(receiverType.element);
+ }
+ }
+ impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+ new Selector.getter(elementMap.getName(node.name)),
+ constraint, const <DartType>[]));
}
@override
void visitPropertySet(ir.PropertySet node) {
visitNode(node.receiver);
visitNode(node.value);
- impactBuilder.registerDynamicUse(
- new DynamicUse(new Selector.setter(elementMap.getName(node.name))));
+ ReceiverConstraint constraint;
+ if (_options.strongMode && useStrongModeWorldStrategy) {
+ DartType receiverType = elementMap.getStaticType(node.receiver);
+ if (receiverType is InterfaceType) {
+ constraint = new StrongModeConstraint(receiverType.element);
+ }
+ }
+ impactBuilder.registerDynamicUse(new ConstrainedDynamicUse(
+ new Selector.setter(elementMap.getName(node.name)),
+ constraint, const <DartType>[]));
}
@override
@@ -561,6 +593,7 @@
@override
void visitInstantiation(ir.Instantiation node) {
+ // TODO(johnniwinther): Track which arities are used in instantiation.
impactBuilder.registerFeature(Feature.GENERIC_INSTANTIATION);
node.visitChildren(this);
}
@@ -632,8 +665,11 @@
visitNode(node.variable);
visitNode(node.iterable);
visitNode(node.body);
+ // TODO(johnniwinther): Use receiver constraints for the dynamic uses in
+ // strong mode.
if (node.isAsync) {
impactBuilder.registerFeature(Feature.ASYNC_FOR_IN);
+ impactBuilder.registerDynamicUse(new DynamicUse(Selectors.cancel));
} else {
impactBuilder.registerFeature(Feature.SYNC_FOR_IN);
impactBuilder.registerDynamicUse(new DynamicUse(Selectors.iterator));
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 40c6687..5aa3fc6 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -420,7 +420,8 @@
}
}
} else if (input.isStringOrNull(_closedWorld)) {
- if (applies(commonElements.jsStringSplit)) {
+ if (commonElements.appliesToJsStringSplit(
+ selector, mask, _closedWorld)) {
return handleStringSplit(node);
} else if (applies(commonElements.jsStringOperatorAdd)) {
// `operator+` is turned into a JavaScript '+' so we need to
@@ -456,7 +457,7 @@
return result;
}
} else if (selector.isGetter) {
- if (selector.applies(commonElements.jsIndexableLength)) {
+ if (commonElements.appliesToJsIndexableLength(selector)) {
HInstruction optimized = tryOptimizeLengthInterceptedGetter(node);
if (optimized != null) return optimized;
}
@@ -2672,12 +2673,20 @@
}
void visitGetLength(HGetLength instruction) {
- _visitFieldGet(closedWorld.commonElements.jsIndexableLength,
- instruction.receiver.nonCheck(), instruction);
+ HInstruction receiver = instruction.receiver.nonCheck();
+ HInstruction existing =
+ memorySet.lookupFieldValue(MemoryFeature.length, receiver);
+ if (existing != null) {
+ checkNewGvnCandidates(instruction, existing);
+ instruction.block.rewriteWithBetterUser(instruction, existing);
+ instruction.block.remove(instruction);
+ } else {
+ memorySet.registerFieldValue(MemoryFeature.length, receiver, instruction);
+ }
}
void _visitFieldGet(
- MemberEntity element, HInstruction receiver, HInstruction instruction) {
+ FieldEntity element, HInstruction receiver, HInstruction instruction) {
HInstruction existing = memorySet.lookupFieldValue(element, receiver);
if (existing != null) {
checkNewGvnCandidates(instruction, existing);
@@ -2831,50 +2840,48 @@
void visitTypeInfoExpression(HTypeInfoExpression instruction) {}
}
-/**
- * Holds values of memory places.
- *
- * Generally, values that name a place (a receiver) have type refinements and
- * other checks removed to ensure that checks and type refinements do not
- * confuse aliasing. Values stored into a memory place keep the type
- * refinements to help further optimizations.
- */
+/// A non-field based feature of an object.
+enum MemoryFeature {
+ // Access to the `length` property of a `JSIndexable`.
+ length,
+}
+
+/// Holds values of memory places.
+///
+/// Generally, values that name a place (a receiver) have type refinements and
+/// other checks removed to ensure that checks and type refinements do not
+/// confuse aliasing. Values stored into a memory place keep the type
+/// refinements to help further optimizations.
class MemorySet {
final ClosedWorld closedWorld;
- /**
- * Maps a field to a map of receiver to value.
- */
- // The key is [MemberEntity] rather than [FieldEntity] so that HGetLength can
- // be modeled as the JSIndexable.length abstract getter.
+ /// Maps a field to a map of receivers to their current field values.
+ ///
+ /// The field is either a [FieldEntity], a [FunctionEntity] in case of
+ /// instance methods, or a [MemoryFeature] for `length` access on
+ /// `JSIndexable`.
+ ///
// TODO(25544): Split length effects from other effects and model lengths
// separately.
- final Map<MemberEntity, Map<HInstruction, HInstruction>> fieldValues =
- <MemberEntity, Map<HInstruction, HInstruction>>{};
+ final Map<Object /*MemberEntity|MemoryFeature*/,
+ Map<HInstruction, HInstruction>>
+ fieldValues = <Object, Map<HInstruction, HInstruction>>{};
- /**
- * Maps a receiver to a map of keys to value.
- */
+ /// Maps a receiver to a map of keys to value.
final Map<HInstruction, Map<HInstruction, HInstruction>> keyedValues =
<HInstruction, Map<HInstruction, HInstruction>>{};
- /**
- * Set of objects that we know don't escape the current function.
- */
+ /// Set of objects that we know don't escape the current function.
final Setlet<HInstruction> nonEscapingReceivers = new Setlet<HInstruction>();
MemorySet(this.closedWorld);
- /**
- * Returns whether [first] and [second] always alias to the same object.
- */
+ /// Returns whether [first] and [second] always alias to the same object.
bool mustAlias(HInstruction first, HInstruction second) {
return first == second;
}
- /**
- * Returns whether [first] and [second] may alias to the same object.
- */
+ /// Returns whether [first] and [second] may alias to the same object.
bool mayAlias(HInstruction first, HInstruction second) {
if (mustAlias(first, second)) return true;
if (isConcrete(first) && isConcrete(second)) return false;
@@ -2886,8 +2893,8 @@
.isDisjoint(second.instructionType, closedWorld);
}
- bool isFinal(MemberEntity element) {
- return closedWorld.fieldNeverChanges(element);
+ bool isFinal(Object element) {
+ return element is MemberEntity && closedWorld.fieldNeverChanges(element);
}
bool isConcrete(HInstruction instruction) {
@@ -2900,9 +2907,7 @@
return closedWorld.commonMasks.couldBeTypedArray(receiver.instructionType);
}
- /**
- * Returns whether [receiver] escapes the current function.
- */
+ /// Returns whether [receiver] escapes the current function.
bool escapes(HInstruction receiver) {
assert(receiver == null || receiver == receiver.nonCheck());
return !nonEscapingReceivers.contains(receiver);
@@ -2913,21 +2918,22 @@
nonEscapingReceivers.add(instruction);
}
- /**
- * Sets `receiver.element` to contain [value]. Kills all potential places that
- * may be affected by this update. Returns `true` if the update is redundant.
- */
+ /// Sets the [field] on [receiver] to contain [value]. Kills all potential
+ /// places that may be affected by this update. Returns `true` if the update
+ /// is redundant.
bool registerFieldValueUpdate(
- MemberEntity element, HInstruction receiver, HInstruction value) {
+ Object field, HInstruction receiver, HInstruction value) {
+ assert(field is MemberEntity || field is MemoryFeature,
+ "Unexpected member/feature: $field");
assert(receiver == null || receiver == receiver.nonCheck());
- if (closedWorld.nativeData.isNativeMember(element)) {
+ if (closedWorld.nativeData.isNativeMember(field)) {
return false; // TODO(14955): Remove this restriction?
}
// [value] is being set in some place in memory, we remove it from the
// non-escaping set.
nonEscapingReceivers.remove(value.nonCheck());
Map<HInstruction, HInstruction> map =
- fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{});
+ fieldValues.putIfAbsent(field, () => <HInstruction, HInstruction>{});
bool isRedundant = map[receiver] == value;
map.forEach((key, value) {
if (mayAlias(receiver, key)) map[key] = null;
@@ -2936,35 +2942,33 @@
return isRedundant;
}
- /**
- * Registers that `receiver.element` is now [value].
- */
+ /// Registers that the [field] on [receiver] is now [value].
void registerFieldValue(
- MemberEntity element, HInstruction receiver, HInstruction value) {
+ Object field, HInstruction receiver, HInstruction value) {
+ assert(field is MemberEntity || field is MemoryFeature,
+ "Unexpected member/feature: $field");
assert(receiver == null || receiver == receiver.nonCheck());
- if (closedWorld.nativeData.isNativeMember(element)) {
+ if (field is MemberEntity && closedWorld.nativeData.isNativeMember(field)) {
return; // TODO(14955): Remove this restriction?
}
Map<HInstruction, HInstruction> map =
- fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{});
+ fieldValues.putIfAbsent(field, () => <HInstruction, HInstruction>{});
map[receiver] = value;
}
- /**
- * Returns the value stored in `receiver.element`. Returns `null` if we don't
- * know.
- */
- HInstruction lookupFieldValue(MemberEntity element, HInstruction receiver) {
+ /// Returns the value stored for [field] on [receiver]. Returns `null` if we
+ /// don't know.
+ HInstruction lookupFieldValue(Object field, HInstruction receiver) {
+ assert(field is MemberEntity || field is MemoryFeature,
+ "Unexpected member/feature: $field");
assert(receiver == null || receiver == receiver.nonCheck());
- Map<HInstruction, HInstruction> map = fieldValues[element];
+ Map<HInstruction, HInstruction> map = fieldValues[field];
return (map == null) ? null : map[receiver];
}
- /**
- * Kill all places that may be affected by this [instruction]. Also update the
- * set of non-escaping objects in case [instruction] has non-escaping objects
- * in its inputs.
- */
+ /// Kill all places that may be affected by this [instruction]. Also update
+ /// the set of non-escaping objects in case [instruction] has non-escaping
+ /// objects in its inputs.
void killAffectedBy(HInstruction instruction) {
// Even if [instruction] does not have side effects, it may use non-escaping
// objects and store them in a new object, which make these objects
@@ -2975,9 +2979,10 @@
if (instruction.sideEffects.changesInstanceProperty() ||
instruction.sideEffects.changesStaticProperty()) {
- List<MemberEntity> fieldsToRemove;
List<HInstruction> receiversToRemove = <HInstruction>[];
- fieldValues.forEach((MemberEntity element, map) {
+
+ List<Object> fieldsToRemove;
+ fieldValues.forEach((Object element, map) {
if (isFinal(element)) return;
map.forEach((receiver, value) {
if (escapes(receiver)) {
@@ -2986,7 +2991,7 @@
});
if (receiversToRemove.length == map.length) {
// Remove them all by removing the entire map.
- (fieldsToRemove ??= <MemberEntity>[]).add(element);
+ (fieldsToRemove ??= <Object>[]).add(element);
} else {
receiversToRemove.forEach(map.remove);
}
@@ -3006,18 +3011,14 @@
}
}
- /**
- * Returns the value stored in `receiver[index]`. Returns null if
- * we don't know.
- */
+ /// Returns the value stored in `receiver[index]`. Returns null if we don't
+ /// know.
HInstruction lookupKeyedValue(HInstruction receiver, HInstruction index) {
Map<HInstruction, HInstruction> map = keyedValues[receiver];
return (map == null) ? null : map[index];
}
- /**
- * Registers that `receiver[index]` is now [value].
- */
+ /// Registers that `receiver[index]` is now [value].
void registerKeyedValue(
HInstruction receiver, HInstruction index, HInstruction value) {
Map<HInstruction, HInstruction> map =
@@ -3025,10 +3026,8 @@
map[index] = value;
}
- /**
- * Sets `receiver[index]` to contain [value]. Kills all potential
- * places that may be affected by this update.
- */
+ /// Sets `receiver[index]` to contain [value]. Kills all potential places that
+ /// may be affected by this update.
void registerKeyedValueUpdate(
HInstruction receiver, HInstruction index, HInstruction value) {
nonEscapingReceivers.remove(value.nonCheck());
@@ -3053,11 +3052,11 @@
map[index] = value;
}
- /**
- * Returns null if either [first] or [second] is null. Otherwise
- * returns [first] if [first] and [second] are equal. Otherwise
- * creates or re-uses a phi in [block] that holds [first] and [second].
- */
+ /// Returns a common instruction for [first] and [second].
+ ///
+ /// Returns `null` if either [first] or [second] is null. Returns [first] if
+ /// [first] and [second] are equal. Otherwise creates or re-uses a phi in
+ /// [block] that holds [first] and [second].
HInstruction findCommonInstruction(HInstruction first, HInstruction second,
HBasicBlock block, int predecessorIndex) {
if (first == null || second == null) return null;
@@ -3110,9 +3109,7 @@
}
}
- /**
- * Returns the intersection between [this] and [other].
- */
+ /// Returns the intersection between [this] and the [other] memory set.
MemorySet intersectionFor(
MemorySet other, HBasicBlock block, int predecessorIndex) {
MemorySet result = new MemorySet(closedWorld);
@@ -3195,9 +3192,7 @@
return result;
}
- /**
- * Returns a copy of [this].
- */
+ /// Returns a copy of [this] memory set.
MemorySet clone() {
MemorySet result = new MemorySet(closedWorld);
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index c87eae7..4dd04bc 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -48,9 +48,9 @@
if (element is FunctionEntity) {
SourceInformationBuilder sourceInformationBuilder =
backend.sourceInformationStrategy.createBuilderForContext(element);
-
result = backend.rewriteAsync(
closedWorld.commonElements,
+ closedWorld.elementEnvironment,
element,
result,
sourceInformationBuilder.buildAsyncBody(),
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index 7af49b4..bf79fb9 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -44,9 +44,7 @@
_masks = null;
return true;
}
- if (_masks == null) {
- _masks = new Setlet<TypeMask>();
- }
+ _masks ??= new Set<TypeMask>();
return _masks.add(mask);
}
diff --git a/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart b/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
index e45c3ac..c6cf563 100644
--- a/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
+++ b/pkg/compiler/lib/src/universe/class_hierarchy_builder.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import '../common.dart';
import '../common_elements.dart';
import '../elements/elements.dart' show ClassElement, MixinApplicationElement;
import '../elements/entities.dart';
@@ -53,11 +54,21 @@
}
ClassEntity appliedMixin = _classQueries.getAppliedMixin(cls);
- if (appliedMixin != null) {
- // TODO(johnniwinther): Store this in the [ClassSet].
+ while (appliedMixin != null) {
+ // TODO(johnniwinther): Use the data stored in [ClassSet].
registerMixinUse(cls, appliedMixin);
- }
+ ClassSet mixinSet = _ensureClassSet(appliedMixin);
+ mixinSet.addMixinApplication(node);
+ // In case of
+ //
+ // class A {}
+ // class B = Object with A;
+ // class C = Object with B;
+ //
+ // we need to register that C not only mixes in B but also A.
+ appliedMixin = _classQueries.getAppliedMixin(appliedMixin);
+ }
return classSet;
});
}
@@ -78,7 +89,7 @@
void updateClassHierarchyNodeForClass(ClassEntity cls,
{bool directlyInstantiated: false, bool abstractlyInstantiated: false}) {
- ClassHierarchyNode node = _ensureClassHierarchyNode(cls);
+ ClassHierarchyNode node = _ensureClassSet(cls).node;
_updateSuperClassHierarchyNodeForClass(node);
if (directlyInstantiated) {
node.isDirectlyInstantiated = true;
@@ -95,6 +106,50 @@
mixinUses.putIfAbsent(mixin, () => new Set<ClassEntity>());
users.add(mixinApplication);
}
+
+ bool _isSubtypeOf(ClassEntity x, ClassEntity y) {
+ assert(
+ classSets.containsKey(x), "ClassSet for $x has not been computed yet.");
+ ClassSet classSet = classSets[y];
+ assert(classSet != null,
+ failedAt(y, "No ClassSet for $y (${y.runtimeType}): ${classSets}"));
+ ClassHierarchyNode classHierarchyNode = classHierarchyNodes[x];
+ assert(classHierarchyNode != null,
+ failedAt(x, "No ClassHierarchyNode for $x"));
+ return classSet.hasSubtype(classHierarchyNode);
+ }
+
+ bool isInheritedInSubtypeOf(ClassEntity x, ClassEntity y) {
+ ClassSet classSet = classSets[x];
+ assert(classSet != null,
+ failedAt(x, "No ClassSet for $x (${x.runtimeType}): ${classSets}"));
+
+ if (_isSubtypeOf(x, y)) {
+ // [x] implements [y] itself, possible through supertypes.
+ return true;
+ }
+
+ /// Returns `true` if any live subclass of [node] implements [y].
+ bool subclassImplements(ClassHierarchyNode node, {bool strict}) {
+ return node.anySubclass((ClassEntity z) => _isSubtypeOf(z, y),
+ ClassHierarchyNode.INSTANTIATED,
+ strict: strict);
+ }
+
+ if (subclassImplements(classSet.node, strict: true)) {
+ // A subclass of [x] implements [y].
+ return true;
+ }
+
+ for (ClassHierarchyNode mixinApplication
+ in classSet.mixinApplicationNodes) {
+ if (subclassImplements(mixinApplication, strict: false)) {
+ // A subclass of [mixinApplication] implements [y].
+ return true;
+ }
+ }
+ return false;
+ }
}
abstract class ClassQueries {
@@ -105,6 +160,11 @@
ClassEntity getDeclaration(covariant ClassEntity cls);
/// Returns the class mixed into [cls] if any.
+ // TODO(johnniwinther): Replace this by a `getAppliedMixins` function that
+ // return transitively mixed in classes like in:
+ // class A {}
+ // class B = Object with A;
+ // class C = Object with B;
ClassEntity getAppliedMixin(covariant ClassEntity cls);
/// Returns the hierarchy depth of [cls].
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index 13a0cdb..c5a4869 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -482,6 +482,22 @@
///
List<ClassHierarchyNode> _subtypes;
+ /// A list of the class hierarchy nodes for the class that directly mix in
+ /// [cls].
+ ///
+ /// For instance
+ ///
+ /// class A {}
+ /// class B extends Object with A {}
+ /// class C = Object with A;
+ /// class D extends B {}
+ /// class E extends C {}
+ ///
+ /// The class hierarchy nodes for the unnamed mixin application `Object+A` and
+ /// the named mixin application `C` are in [_mixinApplications].
+ ///
+ List<ClassHierarchyNode> _mixinApplications;
+
ClassSet(this.node);
ClassEntity get cls => node.cls;
@@ -531,6 +547,10 @@
return _subtypes ?? const <ClassHierarchyNode>[];
}
+ Iterable<ClassHierarchyNode> get mixinApplicationNodes {
+ return _mixinApplications ?? const <ClassHierarchyNode>[];
+ }
+
/// Returns an [Iterable] of the subclasses of [cls] possibly including [cls].
///
/// Subclasses are included if their instantiation properties intersect with
@@ -701,6 +721,15 @@
}
}
+ /// Adds [mixinApplication] as a class that mixes in [cls].
+ void addMixinApplication(ClassHierarchyNode mixinApplication) {
+ if (_mixinApplications == null) {
+ _mixinApplications = <ClassHierarchyNode>[mixinApplication];
+ } else {
+ _mixinApplications.add(mixinApplication);
+ }
+ }
+
/// Returns the most specific subtype of [cls] (including [cls]) that is
/// directly instantiated or a superclass of all directly instantiated
/// subtypes. If no subtypes of [cls] are instantiated, `null` is returned.
@@ -743,11 +772,19 @@
node.printOn(sb, ' ');
sb.write('\n');
if (_subtypes != null) {
+ sb.write(' subtypes:\n');
for (ClassHierarchyNode node in _subtypes) {
node.printOn(sb, ' ');
sb.write('\n');
}
}
+ if (_mixinApplications != null) {
+ sb.write(' mixin-applications:\n');
+ for (ClassHierarchyNode node in _mixinApplications) {
+ node.printOn(sb, ' ');
+ sb.write('\n');
+ }
+ }
sb.write(']');
return sb.toString();
}
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index fa33d69..d679a67 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -463,6 +463,9 @@
_MemberUsage _getMemberUsage(
covariant MemberEntity member, MemberUsedCallback memberUsed) {
+ // TODO(johnniwinther): Change [TypeMask] to not apply to a superclass
+ // member unless the class has been instantiated. Similar to
+ // [StrongModeConstraint].
return _instanceMemberUsage.putIfAbsent(member, () {
String memberName = member.name;
ClassEntity cls = member.enclosingClass;
@@ -470,13 +473,13 @@
_MemberUsage usage = new _MemberUsage(member, isNative: isNative);
EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
useSet.addAll(usage.appliedUse);
- if (hasInvokedGetter(member, _world)) {
+ if (!usage.hasRead && hasInvokedGetter(member, _world)) {
useSet.addAll(usage.read());
}
- if (hasInvokedSetter(member, _world)) {
+ if (!usage.hasWrite && hasInvokedSetter(member, _world)) {
useSet.addAll(usage.write());
}
- if (hasInvocation(member, _world)) {
+ if (!usage.hasInvoke && hasInvocation(member, _world)) {
useSet.addAll(usage.invoke());
}
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index 160f196..fc3502f 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -520,10 +520,17 @@
} else {
kind = Instantiation.DIRECTLY_INSTANTIATED;
}
- _processInstantiatedClass(cls, classUsed);
}
info.addInstantiation(constructor, type, kind,
isRedirection: isRedirection);
+ if (kind != Instantiation.UNINSTANTIATED) {
+ if (_options.strongMode) {
+ classHierarchyBuilder.updateClassHierarchyNodeForClass(cls,
+ directlyInstantiated: info.isDirectlyInstantiated,
+ abstractlyInstantiated: info.isAbstractlyInstantiated);
+ }
+ _processInstantiatedClass(cls, classUsed);
+ }
// TODO(johnniwinther): Use [_instantiationInfo] to compute this information
// instead.
@@ -617,14 +624,14 @@
Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
Selector selector = dynamicUse.selector;
String name = selector.name;
- ReceiverConstraint mask = dynamicUse.mask;
+ ReceiverConstraint constraint = dynamicUse.mask;
Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
name, () => new Maplet<Selector, SelectorConstraints>());
UniverseSelectorConstraints constraints =
selectors.putIfAbsent(selector, () {
return selectorConstraintsStrategy.createSelectorConstraints(selector);
});
- return constraints.addReceiverConstraint(mask);
+ return constraints.addReceiverConstraint(constraint);
}
void registerIsCheck(covariant DartType type) {
@@ -799,10 +806,12 @@
// its metadata parsed and analyzed.
// Note: this assumes that there are no non-native fields on native
// classes, which may not be the case when a native class is subclassed.
- _memberUsage.putIfAbsent(member, () {
+ bool newUsage = false;
+ _MemberUsage usage = _memberUsage.putIfAbsent(member, () {
+ newUsage = true;
bool isNative = _nativeBasicData.isNativeClass(cls);
- _MemberUsage usage = new _MemberUsage(member, isNative: isNative);
EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
+ _MemberUsage usage = new _MemberUsage(member, isNative: isNative);
useSet.addAll(usage.appliedUse);
if (member.isField && isNative) {
registerUsedElement(member);
@@ -813,13 +822,13 @@
closurizedMembersWithFreeTypeVariables.add(member);
}
- if (_hasInvokedGetter(member)) {
+ if (!usage.hasRead && _hasInvokedGetter(member)) {
useSet.addAll(usage.read());
}
- if (_hasInvocation(member)) {
+ if (!usage.hasInvoke && _hasInvocation(member)) {
useSet.addAll(usage.invoke());
}
- if (hasInvokedSetter(member)) {
+ if (!usage.hasWrite && hasInvokedSetter(member)) {
useSet.addAll(usage.write());
}
@@ -837,10 +846,28 @@
.putIfAbsent(memberName, () => new Set<_MemberUsage>())
.add(usage);
}
-
memberUsed(usage.entity, useSet);
return usage;
});
+ if (!newUsage) {
+ EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
+ if (!usage.hasRead && _hasInvokedGetter(member)) {
+ useSet.addAll(usage.read());
+ }
+ if (!usage.hasInvoke && _hasInvocation(member)) {
+ useSet.addAll(usage.invoke());
+ }
+ if (!usage.hasWrite && hasInvokedSetter(member)) {
+ useSet.addAll(usage.write());
+ }
+ if (!usage.pendingUse.contains(MemberUse.NORMAL)) {
+ _instanceMembersByName[memberName]?.remove(usage);
+ }
+ if (!usage.pendingUse.contains(MemberUse.CLOSURIZE_INSTANCE)) {
+ _instanceFunctionsByName[memberName]?.remove(usage);
+ }
+ memberUsed(usage.entity, useSet);
+ }
}
/// Returns an iterable over all mixin applications that mixin [cls].
@@ -926,6 +953,15 @@
void registerClass(ClassEntity cls) {
classHierarchyBuilder.registerClass(cls);
}
+
+ bool isInheritedInSubtypeOf(MemberEntity member, ClassEntity type) {
+ // TODO(johnniwinther): Use the [member] itself to avoid enqueueing members
+ // that are overridden.
+ classHierarchyBuilder.registerClass(member.enclosingClass);
+ classHierarchyBuilder.registerClass(type);
+ return classHierarchyBuilder.isInheritedInSubtypeOf(
+ member.enclosingClass, type);
+ }
}
abstract class KernelResolutionWorldBuilderBase
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 4feb2a8..031baf2 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -169,6 +169,98 @@
}
}
+bool useStrongModeWorldStrategy = false;
+
+/// Open world strategy that constrains instance member access to subtypes of
+/// the static type of the receiver.
+///
+/// This strategy is used for Dart 2.
+class StrongModeWorldStrategy implements SelectorConstraintsStrategy {
+ const StrongModeWorldStrategy();
+
+ StrongModeWorldConstraints createSelectorConstraints(Selector selector) {
+ return new StrongModeWorldConstraints();
+ }
+}
+
+class StrongModeWorldConstraints extends UniverseSelectorConstraints {
+ bool isAll = false;
+ Set<StrongModeConstraint> _constraints;
+
+ @override
+ bool applies(MemberEntity element, Selector selector, World world) {
+ if (isAll) return true;
+ if (_constraints == null) return false;
+ for (StrongModeConstraint constraint in _constraints) {
+ if (constraint.canHit(element, selector, world)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @override
+ bool needsNoSuchMethodHandling(Selector selector, World world) {
+ if (isAll) {
+ return true;
+ }
+ if (_constraints != null) {
+ for (StrongModeConstraint constraint in _constraints) {
+ if (constraint.needsNoSuchMethodHandling(selector, world)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ @override
+ bool addReceiverConstraint(StrongModeConstraint constraint) {
+ if (isAll) return false;
+ if (constraint?.cls == null) {
+ isAll = true;
+ _constraints = null;
+ return true;
+ }
+ _constraints ??= new Set<StrongModeConstraint>();
+ return _constraints.add(constraint);
+ }
+
+ String toString() {
+ if (isAll) {
+ return '<all>';
+ } else if (_constraints != null) {
+ return '<${_constraints.map((c) => c.cls).join(',')}>';
+ } else {
+ return '<none>';
+ }
+ }
+}
+
+class StrongModeConstraint implements ReceiverConstraint {
+ final ClassEntity cls;
+
+ const StrongModeConstraint(this.cls);
+
+ @override
+ bool needsNoSuchMethodHandling(Selector selector, World world) => true;
+
+ @override
+ bool canHit(MemberEntity element, Selector selector, OpenWorld world) {
+ return world.isInheritedInSubtypeOf(element, cls);
+ }
+
+ bool operator ==(other) {
+ if (identical(this, other)) return true;
+ if (other is! StrongModeConstraint) return false;
+ return cls == other.cls;
+ }
+
+ int get hashCode => cls.hashCode * 13;
+
+ String toString() => 'StrongModeConstraint($cls)';
+}
+
/// The [WorldBuilder] is an auxiliary class used in the process of computing
/// the [ClosedWorld].
// TODO(johnniwinther): Move common implementation to a [WorldBuilderBase] when
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 183575c..bfe1a5d 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -404,6 +404,21 @@
/// Returns an iterable over all mixin applications that mixin [cls].
Iterable<ClassEntity> allMixinUsesOf(ClassEntity cls);
+
+ /// Returns `true` if [member] is inherited into a subtype of [type].
+ ///
+ /// For instance:
+ ///
+ /// class A { m() {} }
+ /// class B extends A implements I {}
+ /// class C extends Object with A implements I {}
+ /// abstract class I { m(); }
+ /// abstract class J implements A { }
+ ///
+ /// Here `A.m` is inherited into `A`, `B`, and `C`. Becausec `B` and
+ /// `C` implement `I`, `isInheritedInSubtypeOf(A.M, I)` is true, but
+ /// `isInheritedInSubtypeOf(A.M, J)` is false.
+ bool isInheritedInSubtypeOf(MemberEntity member, ClassEntity type);
}
/// Enum values defining subset of classes included in queries.
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 d8f20d7..e6cfecf 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
@@ -13,8 +13,8 @@
// TODO(vsm): Remove once this flag is the default.
bool startAsyncSynchronously = false;
-void setStartAsyncSynchronously() {
- startAsyncSynchronously = true;
+void setStartAsyncSynchronously([bool value = true]) {
+ startAsyncSynchronously = value;
}
final _jsIterator = JS('', 'Symbol("_jsIterator")');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
index 3facf9e..dec36ce 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
@@ -35,13 +35,13 @@
if (args == null) args = <String>[];
if (args is List) {
if (args is! List<String>) args = new List<String>.from(args);
- if (main is _MainFunction) {
- main();
- } else if (main is _MainFunctionArgs) {
- main(args);
- } else if (main is _MainFunctionArgsMessage) {
- main(args, null);
+ // DDC attaches signatures only when torn off, and the typical way of
+ // getting `main` via the JS ABI won't do this. So use JS to invoke main.
+ if (JS<bool>('!', 'typeof # == "function"', main)) {
+ // JS will ignore extra arguments.
+ JS('', '#(#, #)', main, args, null);
} else {
+ // Not a function. Use a dynamic call to throw an error.
(main as dynamic)(args);
}
} else {
@@ -53,10 +53,6 @@
// those uses to just refer to the one in dart:runtime.
final global = dart.global_;
-typedef _MainFunction();
-typedef _MainFunctionArgs(List<String> args);
-typedef _MainFunctionArgsMessage(List<String> args, Null message);
-
class TimerImpl implements Timer {
final bool _once;
int _handle;
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 41f5b16..1513772 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -3656,6 +3656,69 @@
tip: r"""Try adding a parameter list to the function declaration.""");
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+ templateMissingImplementationCause =
+ const Template<Message Function(String name)>(
+ messageTemplate: r"""'#name' is defined here.""",
+ withArguments: _withArgumentsMissingImplementationCause);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeMissingImplementationCause =
+ const Code<Message Function(String name)>(
+ "MissingImplementationCause", templateMissingImplementationCause,
+ severity: Severity.context);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsMissingImplementationCause(String name) {
+ return new Message(codeMissingImplementationCause,
+ message: """'$name' is defined here.""", arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ String name,
+ String
+ string)> templateMissingImplementationNotAbstract = const Template<
+ Message Function(String name, String string)>(
+ messageTemplate:
+ r"""The non-abstract class '#name' is missing implementations for these members:
+ #string.""",
+ tipTemplate: r"""Try to either
+ - provide an implementation,
+ - inherit an implementation from a superclass or mixin,
+ - mark the class as abstract, or
+ - provide a 'noSuchMethod' implementation.
+""",
+ withArguments: _withArgumentsMissingImplementationNotAbstract);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String string)>
+ codeMissingImplementationNotAbstract =
+ const Code<Message Function(String name, String string)>(
+ "MissingImplementationNotAbstract",
+ templateMissingImplementationNotAbstract,
+ analyzerCode: "CONCRETE_CLASS_WITH_ABSTRACT_MEMBER",
+ dart2jsCode: "*fatal*",
+ severity: Severity.errorLegacyWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsMissingImplementationNotAbstract(
+ String name, String string) {
+ return new Message(codeMissingImplementationNotAbstract,
+ message:
+ """The non-abstract class '$name' is missing implementations for these members:
+ $string.""",
+ tip: """Try to either
+ - provide an implementation,
+ - inherit an implementation from a superclass or mixin,
+ - mark the class as abstract, or
+ - provide a 'noSuchMethod' implementation.
+""",
+ arguments: {'name': name, 'string': string});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeMissingInput = messageMissingInput;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index be422f2..6584f7c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -29,6 +29,8 @@
import 'package:kernel/clone.dart' show CloneWithoutBody;
+import 'package:kernel/core_types.dart' show CoreTypes;
+
import 'package:kernel/type_algebra.dart' show Substitution, getSubstitutionMap;
import 'package:kernel/type_environment.dart' show TypeEnvironment;
@@ -37,12 +39,15 @@
import '../fasta_codes.dart'
show
+ LocatedMessage,
Message,
messagePatchClassOrigin,
messagePatchClassTypeVariablesMismatch,
messagePatchDeclarationMismatch,
messagePatchDeclarationOrigin,
noLength,
+ templateMissingImplementationCause,
+ templateMissingImplementationNotAbstract,
templateOverriddenMethodCause,
templateOverrideFewerNamedArguments,
templateOverrideFewerPositionalArguments,
@@ -288,6 +293,66 @@
});
}
+ void checkAbstractMembers(CoreTypes coreTypes, ClassHierarchy hierarchy) {
+ if (isAbstract ||
+ hierarchy.getDispatchTarget(cls, noSuchMethodName).enclosingClass !=
+ coreTypes.objectClass) {
+ // Unimplemented members allowed
+ // TODO(dmitryas): Call hasUserDefinedNoSuchMethod instead when ready.
+ return;
+ }
+
+ List<LocatedMessage> context = null;
+
+ void findMissingImplementations({bool setters}) {
+ List<Member> dispatchTargets =
+ hierarchy.getDispatchTargets(cls, setters: setters);
+ int targetIndex = 0;
+ for (Member interfaceMember
+ in hierarchy.getInterfaceMembers(cls, setters: setters)) {
+ // Is this either a public member or a visible private member?
+ if (!interfaceMember.name.isPrivate ||
+ (interfaceMember.enclosingLibrary == cls.enclosingLibrary &&
+ interfaceMember.fileUri ==
+ interfaceMember.enclosingClass.fileUri)) {
+ while (targetIndex < dispatchTargets.length &&
+ ClassHierarchy.compareMembers(
+ dispatchTargets[targetIndex], interfaceMember) <
+ 0) {
+ targetIndex++;
+ }
+ if (targetIndex >= dispatchTargets.length ||
+ ClassHierarchy.compareMembers(
+ dispatchTargets[targetIndex], interfaceMember) >
+ 0) {
+ Name name = interfaceMember.name;
+ String displayName = name.name + (setters ? "=" : "");
+ context ??= <LocatedMessage>[];
+ context.add(templateMissingImplementationCause
+ .withArguments(displayName)
+ .withLocation(interfaceMember.fileUri,
+ interfaceMember.fileOffset, name.name.length));
+ }
+ }
+ }
+ }
+
+ findMissingImplementations(setters: false);
+ findMissingImplementations(setters: true);
+
+ if (context?.isNotEmpty ?? false) {
+ String memberString =
+ context.map((message) => "'${message.arguments["name"]}'").join(", ");
+ library.addProblem(
+ templateMissingImplementationNotAbstract.withArguments(
+ cls.name, memberString),
+ cls.fileOffset,
+ cls.name.length,
+ cls.fileUri,
+ context: context);
+ }
+ }
+
// TODO(dmitryas): Find a better place for this routine.
static bool hasUserDefinedNoSuchMethod(
Class klass, ClassHierarchy hierarchy) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index cfeaeab..4255dbc 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -262,6 +262,7 @@
loader.performTopLevelInference(myClasses);
}
loader.checkOverrides(myClasses);
+ loader.checkAbstractMembers(myClasses);
loader.addNoSuchMethodForwarders(myClasses);
} on deprecated_InputError catch (e) {
ticker.logMs("Got deprecated_InputError");
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index b72575b..b2969e2 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -64,8 +64,7 @@
/// Identifier is a field initializer in a formal parameter list (i.e. it
/// appears directly after `this.`).
- static const fieldInitializer =
- const IdentifierContext('fieldInitializer', isContinuation: true);
+ static const fieldInitializer = const FieldInitializerIdentifierContext();
/// Identifier is a formal parameter being declared as part of a function,
/// method, or typedef declaration.
@@ -246,7 +245,7 @@
/// Identifier is a name being declared by a local variable declaration.
static const localVariableDeclaration =
- const IdentifierContext('localVariableDeclaration', inDeclaration: true);
+ const LocalVariableDeclarationIdentifierContext();
/// Identifier is a reference to a label (e.g. `foo` in `break foo;`).
/// Labels have their own scope.
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 8922d33..a5e4efa 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -63,12 +63,21 @@
Token ensureIdentifier(Token token, Parser parser) {
Token identifier = token.next;
assert(identifier.kind != IDENTIFIER_TOKEN);
+ const followingValues = const ['.', '==', ')'];
+
if (identifier.isIdentifier) {
- return identifier;
+ // DottedNameIdentifierContext are only used in conditional import
+ // expressions. Although some top level keywords such as `import` can be
+ // used as identifiers, they are more likely the start of the next
+ // directive or declaration.
+ if (!identifier.isTopLevelKeyword ||
+ isOneOfOrEof(identifier.next, followingValues)) {
+ return identifier;
+ }
}
if (looksLikeStartOfNextDeclaration(identifier) ||
- isOneOfOrEof(identifier, const ['.', '==', ')'])) {
+ isOneOfOrEof(identifier, followingValues)) {
identifier = parser.insertSyntheticIdentifier(token, this,
message: fasta.templateExpectedIdentifier.withArguments(identifier));
} else {
@@ -94,50 +103,64 @@
@override
Token ensureIdentifier(Token token, Parser parser) {
- Token next = token.next;
- assert(next.kind != IDENTIFIER_TOKEN);
- if (next.isIdentifier) {
- if (optional('await', next) && next.next.isIdentifier) {
+ Token identifier = token.next;
+ assert(identifier.kind != IDENTIFIER_TOKEN);
+ if (identifier.isIdentifier) {
+ if (optional('await', identifier) && identifier.next.isIdentifier) {
// Although the `await` can be used in an expression,
// it is followed by another identifier which does not form
// a valid expression. Report an error on the `await` token
// rather than the token following it.
parser.reportRecoverableErrorWithToken(
- next, fasta.templateUnexpectedToken);
+ identifier, fasta.templateUnexpectedToken);
// TODO(danrubel) Consider a new listener event so that analyzer
// can represent this as an await expression in a context that does
// not allow await.
- return next.next;
- } else if (!parser.inPlainSync && next.type.isPseudo) {
- if (optional('await', next)) {
- parser.reportRecoverableError(next, fasta.messageAwaitAsIdentifier);
- } else if (optional('yield', next)) {
- parser.reportRecoverableError(next, fasta.messageYieldAsIdentifier);
- } else if (optional('async', next)) {
- parser.reportRecoverableError(next, fasta.messageAsyncAsIdentifier);
- }
+ return identifier.next;
+ } else {
+ checkAsyncAwaitYieldAsIdentifier(identifier, parser);
}
- return next;
+ return identifier;
}
parser.reportRecoverableErrorWithToken(
- next, fasta.templateExpectedIdentifier);
- if (next.isKeywordOrIdentifier) {
- if (!isOneOfOrEof(next, const ['as', 'is'])) {
- return next;
+ identifier, fasta.templateExpectedIdentifier);
+ if (identifier.isKeywordOrIdentifier) {
+ if (!isOneOfOrEof(identifier, const ['as', 'is'])) {
+ return identifier;
}
- } else if (!next.isOperator &&
- !isOneOfOrEof(
- next, const ['.', ',', '(', ')', '[', ']', '}', '?', ':', ';'])) {
+ } else if (!identifier.isOperator &&
+ !isOneOfOrEof(identifier,
+ const ['.', ',', '(', ')', '[', ']', '}', '?', ':', ';'])) {
// When in doubt, consume the token to ensure we make progress
- token = next;
- next = token.next;
+ token = identifier;
+ identifier = token.next;
}
// Insert a synthetic identifier to satisfy listeners.
return insertSyntheticIdentifierAfter(token, parser);
}
}
+/// See [IdentifierContext].fieldInitializer
+class FieldInitializerIdentifierContext extends IdentifierContext {
+ const FieldInitializerIdentifierContext()
+ : super('fieldInitializer', isContinuation: true);
+
+ @override
+ Token ensureIdentifier(Token token, Parser parser) {
+ assert(optional('.', token));
+ Token identifier = token.next;
+ assert(identifier.kind != IDENTIFIER_TOKEN);
+ if (identifier.isIdentifier) {
+ return identifier;
+ }
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateExpectedIdentifier);
+ // Insert a synthetic identifier to satisfy listeners.
+ return insertSyntheticIdentifierAfter(token, parser);
+ }
+}
+
/// See [IdentifierContext].libraryName
class LibraryIdentifierContext extends IdentifierContext {
const LibraryIdentifierContext()
@@ -178,6 +201,36 @@
}
}
+/// See [IdentifierContext].localVariableDeclaration
+class LocalVariableDeclarationIdentifierContext extends IdentifierContext {
+ const LocalVariableDeclarationIdentifierContext()
+ : super('localVariableDeclaration', inDeclaration: true);
+
+ @override
+ Token ensureIdentifier(Token token, Parser parser) {
+ Token identifier = token.next;
+ assert(identifier.kind != IDENTIFIER_TOKEN);
+ if (identifier.isIdentifier) {
+ checkAsyncAwaitYieldAsIdentifier(identifier, parser);
+ return identifier;
+ }
+ if (isOneOfOrEof(identifier, const [';', '=', ',', '{', '}']) ||
+ looksLikeStartOfNextStatement(identifier)) {
+ identifier = parser.insertSyntheticIdentifier(token, this,
+ message: fasta.templateExpectedIdentifier.withArguments(identifier));
+ } else {
+ parser.reportRecoverableErrorWithToken(
+ identifier, fasta.templateExpectedIdentifier);
+ if (!identifier.isKeywordOrIdentifier) {
+ // When in doubt, consume the token to ensure we make progress
+ // but insert a synthetic identifier to satisfy listeners.
+ identifier = insertSyntheticIdentifierAfter(identifier, parser);
+ }
+ }
+ return identifier;
+ }
+}
+
/// See [IdentifierContext].typeReference
class TypeReferenceIdentifierContext extends IdentifierContext {
const TypeReferenceIdentifierContext()
@@ -210,20 +263,10 @@
// annotation is not allowed before type arguments.
parser.reportRecoverableErrorWithToken(
next, fasta.templateUnexpectedToken);
-
- Token annotation = next.next;
- if (annotation.isIdentifier) {
- if (optional('(', annotation.next)) {
- if (annotation.next.endGroup.next.isIdentifier) {
- token = annotation.next.endGroup;
- next = token.next;
- }
- } else if (annotation.next.isIdentifier) {
- token = annotation;
- next = token.next;
- }
- }
+ token = skipMetadata(next);
+ next = token.next;
}
+
if (isValidTypeReference(next)) {
return next;
} else if (next.isKeywordOrIdentifier) {
@@ -251,6 +294,18 @@
}
}
+void checkAsyncAwaitYieldAsIdentifier(Token identifier, Parser parser) {
+ if (!parser.inPlainSync && identifier.type.isPseudo) {
+ if (optional('await', identifier)) {
+ parser.reportRecoverableError(identifier, fasta.messageAwaitAsIdentifier);
+ } else if (optional('yield', identifier)) {
+ parser.reportRecoverableError(identifier, fasta.messageYieldAsIdentifier);
+ } else if (optional('async', identifier)) {
+ parser.reportRecoverableError(identifier, fasta.messageAsyncAsIdentifier);
+ }
+ }
+}
+
bool isOneOfOrEof(Token token, Iterable<String> followingValues) {
for (String tokenValue in followingValues) {
if (optional(tokenValue, token)) {
@@ -263,3 +318,42 @@
bool looksLikeStartOfNextDeclaration(Token token) =>
token.isTopLevelKeyword ||
isOneOfOrEof(token, const ['const', 'get', 'final', 'set', 'var', 'void']);
+
+bool looksLikeStartOfNextStatement(Token token) => isOneOfOrEof(token, const [
+ 'assert',
+ 'break',
+ 'const',
+ 'continue',
+ 'do',
+ 'final',
+ 'for',
+ 'if',
+ 'return',
+ 'switch',
+ 'try',
+ 'var',
+ 'void',
+ 'while'
+ ]);
+
+Token skipMetadata(Token token) {
+ assert(optional('@', token));
+ Token next = token.next;
+ if (next.isIdentifier) {
+ token = next;
+ next = token.next;
+ while (optional('.', next)) {
+ token = next;
+ next = token.next;
+ if (next.isIdentifier) {
+ token = next;
+ next = token.next;
+ }
+ }
+ if (optional('(', next)) {
+ token = next.endGroup;
+ next = token.next;
+ }
+ }
+ return token;
+}
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index 9bf2da1..83d9a8d 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -4,8 +4,8 @@
import '../../scanner/token.dart' show Token;
import '../messages.dart' as fasta;
+import 'member_kind.dart' show MemberKind;
import 'parser.dart' show Parser;
-import 'type_continuation.dart' show TypeContinuation;
import 'util.dart' show optional;
bool isModifier(Token token) {
@@ -28,25 +28,6 @@
return true;
}
-TypeContinuation typeContinuationAfterVar(TypeContinuation typeContinuation) {
- switch (typeContinuation) {
- case TypeContinuation.NormalFormalParameter:
- case TypeContinuation.NormalFormalParameterAfterVar:
- return TypeContinuation.NormalFormalParameterAfterVar;
-
- case TypeContinuation.OptionalPositionalFormalParameter:
- case TypeContinuation.OptionalPositionalFormalParameterAfterVar:
- return TypeContinuation.OptionalPositionalFormalParameterAfterVar;
-
- case TypeContinuation.NamedFormalParameter:
- case TypeContinuation.NamedFormalParameterAfterVar:
- return TypeContinuation.NamedFormalParameterAfterVar;
-
- default:
- return TypeContinuation.OptionalAfterVar;
- }
-}
-
/// This class is used to parse modifiers in most locations where modifiers
/// can occur, but does not call handleModifier or handleModifiers.
class ModifierRecoveryContext {
@@ -88,18 +69,27 @@
}
/// Parse modifiers for formal parameters.
- Token parseFormalParameterModifiers(Token token, bool isStaticOrTopLevel,
+ Token parseFormalParameterModifiers(Token token, MemberKind memberKind,
{Token covariantToken, Token varFinalOrConst}) {
token = parseModifiers(token,
covariantToken: covariantToken, varFinalOrConst: varFinalOrConst);
- if (isStaticOrTopLevel) {
+ if (memberKind == MemberKind.StaticMethod ||
+ memberKind == MemberKind.TopLevelMethod) {
reportExtraneousModifier(this.covariantToken);
this.covariantToken = null;
}
if (constToken != null) {
reportExtraneousModifier(constToken);
varFinalOrConst = null;
+ } else if (memberKind == MemberKind.GeneralizedFunctionType) {
+ if (varFinalOrConst != null) {
+ parser.reportRecoverableError(
+ varFinalOrConst, fasta.messageFunctionTypedParameterVar);
+ varFinalOrConst = null;
+ finalToken = null;
+ varToken = null;
+ }
}
reportExtraneousModifier(abstractToken);
reportExtraneousModifier(externalToken);
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 394e0d5..a23beb1 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -77,16 +77,14 @@
import 'member_kind.dart' show MemberKind;
-import 'modifier_context.dart'
- show ModifierRecoveryContext, isModifier, typeContinuationAfterVar;
+import 'modifier_context.dart' show ModifierRecoveryContext, isModifier;
import 'recovery_listeners.dart'
show ClassHeaderRecoveryListener, ImportRecoveryListener;
import 'token_stream_rewriter.dart' show TokenStreamRewriter;
-import 'type_continuation.dart'
- show TypeContinuation, typeContinuationFromFormalParameterKind;
+import 'type_continuation.dart' show TypeContinuation;
import 'type_info.dart'
show
@@ -94,7 +92,7 @@
computeType,
isGeneralizedFunctionType,
isValidTypeReference,
- noTypeInfo;
+ noType;
import 'util.dart' show optional;
@@ -772,8 +770,7 @@
next.setNext(leftParen);
leftParen = openParen;
}
- token = leftParen;
- token = parseDottedName(token);
+ token = parseDottedName(leftParen);
Token next = token.next;
Token equalitySign;
if (optional('==', next)) {
@@ -782,17 +779,14 @@
next = token.next;
}
if (next != leftParen.endGroup) {
- reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
Token endGroup = leftParen.endGroup;
if (endGroup.isSynthetic) {
// The scanner did not place the synthetic ')' correctly, so move it.
-
- // TODO(danrubel): Its costly to find the token before the endGroup.
- // Consider beforeSynthetic field that points to the previous token
- // only for synthetic tokens such as ')', '}', ']' so that the parser
- // can easily move these to the correct location.
+ next = rewriter.moveSynthetic(token, endGroup);
+ } else {
+ reportRecoverableErrorWithToken(next, fasta.templateUnexpectedToken);
+ next = endGroup;
}
- next = endGroup;
}
token = next;
assert(optional(')', token));
@@ -1221,9 +1215,11 @@
assert(parameterKind != null);
token = parseMetadataStar(token);
Token next = token.next;
+ Token start = next;
- TypeContinuation typeContinuation =
- typeContinuationFromFormalParameterKind(parameterKind);
+ final bool inFunctionType =
+ memberKind == MemberKind.GeneralizedFunctionType;
+
Token covariantToken;
Token varFinalOrConst;
if (isModifier(next)) {
@@ -1236,38 +1232,171 @@
}
if (isModifier(next)) {
- if (optional('var', next)) {
- typeContinuation = typeContinuationAfterVar(typeContinuation);
- varFinalOrConst = token = next;
- next = token.next;
- } else if (optional('final', next)) {
- varFinalOrConst = token = next;
- next = token.next;
+ if (!inFunctionType) {
+ if (optional('var', next)) {
+ varFinalOrConst = token = next;
+ next = token.next;
+ } else if (optional('final', next)) {
+ varFinalOrConst = token = next;
+ next = token.next;
+ }
}
if (isModifier(next)) {
// Recovery
ModifierRecoveryContext context = new ModifierRecoveryContext(this);
- token = context.parseFormalParameterModifiers(
- token,
- memberKind == MemberKind.StaticMethod ||
- memberKind == MemberKind.TopLevelMethod,
- covariantToken: covariantToken,
- varFinalOrConst: varFinalOrConst);
+ token = context.parseFormalParameterModifiers(token, memberKind,
+ covariantToken: covariantToken, varFinalOrConst: varFinalOrConst);
covariantToken = context.covariantToken;
varFinalOrConst = context.varFinalOrConst;
- if (varFinalOrConst != null && optional('var', varFinalOrConst)) {
- typeContinuation = typeContinuationAfterVar(typeContinuation);
- }
context = null;
}
}
}
- listener.beginFormalParameter(
- next, memberKind, covariantToken, varFinalOrConst);
- return parseType(
- token, typeContinuation, null, memberKind, varFinalOrConst);
+ listener.beginFormalParameter(
+ start, memberKind, covariantToken, varFinalOrConst);
+
+ // Type is required in a generalized function type, but optional otherwise.
+ final Token beforeType = token;
+ TypeInfo typeInfo = computeType(token, inFunctionType);
+ token = typeInfo.skipType(token);
+ next = token.next;
+ if (typeInfo == noType &&
+ (optional('.', next) ||
+ (next.isIdentifier && optional('.', next.next)))) {
+ // Recovery: Malformed type reference.
+ typeInfo = computeType(beforeType, true);
+ token = typeInfo.skipType(beforeType);
+ next = token.next;
+ }
+
+ final bool isNamedParameter =
+ parameterKind == FormalParameterKind.optionalNamed;
+
+ Token thisKeyword;
+ Token periodAfterThis;
+ IdentifierContext nameContext =
+ IdentifierContext.formalParameterDeclaration;
+
+ if (!inFunctionType && optional('this', next)) {
+ thisKeyword = token = next;
+ next = token.next;
+ if (!optional('.', next)) {
+ // Recover from a missing period by inserting one.
+ next = rewriteAndRecover(
+ token,
+ fasta.templateExpectedButGot.withArguments('.'),
+ new SyntheticToken(TokenType.PERIOD, next.charOffset))
+ .next;
+ }
+ periodAfterThis = token = next;
+ next = token.next;
+ nameContext = IdentifierContext.fieldInitializer;
+ }
+
+ if (next.isIdentifier) {
+ token = next;
+ next = token.next;
+ }
+ Token beforeInlineFunctionType;
+ if (optional("<", next)) {
+ Token closer = next.endGroup;
+ if (closer != null) {
+ if (optional("(", closer.next)) {
+ if (varFinalOrConst != null) {
+ reportRecoverableError(
+ varFinalOrConst, fasta.messageFunctionTypedParameterVar);
+ }
+ beforeInlineFunctionType = token;
+ token = closer.next.endGroup;
+ next = token.next;
+ }
+ }
+ } else if (optional("(", next)) {
+ if (varFinalOrConst != null) {
+ reportRecoverableError(
+ varFinalOrConst, fasta.messageFunctionTypedParameterVar);
+ }
+ beforeInlineFunctionType = token;
+ token = next.endGroup;
+ next = token.next;
+ }
+ if (typeInfo != noType &&
+ varFinalOrConst != null &&
+ optional('var', varFinalOrConst)) {
+ reportRecoverableError(varFinalOrConst, fasta.messageTypeAfterVar);
+ }
+
+ Token endInlineFunctionType;
+ if (beforeInlineFunctionType != null) {
+ endInlineFunctionType = parseTypeVariablesOpt(beforeInlineFunctionType);
+ listener.beginFunctionTypedFormalParameter(beforeInlineFunctionType.next);
+ token = typeInfo.parseType(beforeType, this);
+ endInlineFunctionType = parseFormalParametersRequiredOpt(
+ endInlineFunctionType, MemberKind.FunctionTypedParameter);
+ listener.endFunctionTypedFormalParameter();
+
+ // Generalized function types don't allow inline function types.
+ // The following isn't allowed:
+ // int Function(int bar(String x)).
+ if (inFunctionType) {
+ reportRecoverableError(beforeInlineFunctionType.next,
+ fasta.messageInvalidInlineFunctionType);
+ }
+ } else if (inFunctionType) {
+ token = typeInfo.ensureTypeOrVoid(beforeType, this);
+ } else {
+ token = typeInfo.parseType(beforeType, this);
+ }
+
+ Token nameToken;
+ if (periodAfterThis != null) {
+ token = periodAfterThis;
+ }
+ next = token.next;
+ if (inFunctionType && !isNamedParameter && !next.isKeywordOrIdentifier) {
+ nameToken = token.next;
+ listener.handleNoName(nameToken);
+ } else {
+ nameToken = token = ensureIdentifier(token, nameContext);
+ if (isNamedParameter && nameToken.lexeme.startsWith("_")) {
+ reportRecoverableError(nameToken, fasta.messagePrivateNamedParameter);
+ }
+ }
+ if (endInlineFunctionType != null) {
+ token = endInlineFunctionType;
+ }
+ next = token.next;
+
+ String value = next.stringValue;
+ if ((identical('=', value)) || (identical(':', value))) {
+ Token equal = next;
+ listener.beginFormalParameterDefaultValueExpression();
+ token = parseExpression(equal);
+ next = token.next;
+ listener.endFormalParameterDefaultValueExpression();
+ // TODO(danrubel): Consider removing the last parameter from the
+ // handleValuedFormalParameter event... it appears to be unused.
+ listener.handleValuedFormalParameter(equal, next);
+ if (isMandatoryFormalParameterKind(parameterKind)) {
+ reportRecoverableError(
+ equal, fasta.messageRequiredParameterWithDefault);
+ } else if (isOptionalPositionalFormalParameterKind(parameterKind) &&
+ identical(':', value)) {
+ reportRecoverableError(
+ equal, fasta.messagePositionalParameterWithEquals);
+ } else if (inFunctionType ||
+ memberKind == MemberKind.FunctionTypeAlias ||
+ memberKind == MemberKind.FunctionTypedParameter) {
+ reportRecoverableError(equal, fasta.messageFunctionTypeDefaultValue);
+ }
+ } else {
+ listener.handleFormalParameterWithoutValue(next);
+ }
+ listener.endFormalParameter(
+ thisKeyword, periodAfterThis, nameToken, parameterKind, memberKind);
+ return token;
}
/// ```
@@ -1371,37 +1500,6 @@
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;
- }
- }
-
/// Returns `true` if [token] matches '<' type (',' type)* '>' '(', and
/// otherwise returns `false`. The final '(' is not part of the grammar
/// construct `typeArguments`, but it is required here such that type
@@ -1999,8 +2097,6 @@
} else if (context == IdentifierContext.localFunctionDeclaration ||
context == IdentifierContext.localFunctionDeclarationContinuation) {
followingValues = ['.', '(', '{', '=>'];
- } else if (context == IdentifierContext.localVariableDeclaration) {
- followingValues = [';', '=', ',', '}'];
} else if (context == IdentifierContext.methodDeclaration ||
context == IdentifierContext.methodDeclarationContinuation) {
followingValues = ['.', '(', '{', '=>'];
@@ -2084,8 +2180,6 @@
} else if (context ==
IdentifierContext.localFunctionDeclarationContinuation) {
initialKeywords = statementKeywords();
- } else if (context == IdentifierContext.localVariableDeclaration) {
- initialKeywords = statementKeywords();
} else if (context == IdentifierContext.methodDeclaration) {
initialKeywords = classMemberKeywords();
} else if (context == IdentifierContext.methodDeclarationContinuation) {
@@ -2143,26 +2237,6 @@
return token;
}
- /// Returns `true` if the stringValue of the [token] is either [value1],
- /// [value2], or [value3].
- bool isOneOf3(Token token, String value1, String value2, String value3) {
- String stringValue = token.stringValue;
- return identical(value1, stringValue) ||
- identical(value2, stringValue) ||
- identical(value3, stringValue);
- }
-
- /// Returns `true` if the stringValue of the [token] is either [value1],
- /// [value2], [value3], or [value4].
- bool isOneOf4(
- Token token, String value1, String value2, String value3, String value4) {
- String stringValue = token.stringValue;
- return identical(value1, stringValue) ||
- identical(value2, stringValue) ||
- identical(value3, stringValue) ||
- identical(value4, stringValue);
- }
-
bool notEofOrValue(String value, Token token) {
return !identical(token.kind, EOF_TOKEN) &&
!identical(value, token.stringValue);
@@ -2361,7 +2435,6 @@
return false;
}
- FormalParameterKind parameterKind;
switch (continuation) {
case TypeContinuation.Required:
// If the token after the type is not an identifier,
@@ -2440,224 +2513,6 @@
if (beforeName.next != name)
throw new StateError("beforeName.next != name");
return parseNamedFunctionRest(beforeName, begin, formals, true);
-
- case TypeContinuation.NormalFormalParameter:
- case TypeContinuation.NormalFormalParameterAfterVar:
- parameterKind = FormalParameterKind.mandatory;
- hasVar = continuation == TypeContinuation.NormalFormalParameterAfterVar;
- continue handleParameters;
-
- case TypeContinuation.OptionalPositionalFormalParameter:
- case TypeContinuation.OptionalPositionalFormalParameterAfterVar:
- parameterKind = FormalParameterKind.optionalPositional;
- hasVar = continuation ==
- TypeContinuation.OptionalPositionalFormalParameterAfterVar;
- continue handleParameters;
-
- case TypeContinuation.NamedFormalParameterAfterVar:
- hasVar = true;
- continue handleParameters;
-
- handleParameters:
- case TypeContinuation.NamedFormalParameter:
- parameterKind ??= FormalParameterKind.optionalNamed;
- bool inFunctionType = memberKind == MemberKind.GeneralizedFunctionType;
- bool isNamedParameter =
- parameterKind == FormalParameterKind.optionalNamed;
-
- bool untyped = false;
- if (!looksLikeType || optional("this", begin)) {
- untyped = true;
- beforeToken = beforeBegin;
- token = begin;
- }
-
- Token thisKeyword;
- Token periodAfterThis;
- Token beforeNameToken = beforeToken;
- Token nameToken = token;
- IdentifierContext nameContext =
- IdentifierContext.formalParameterDeclaration;
- beforeToken = token;
- token = token.next;
- if (inFunctionType) {
- if (isNamedParameter) {
- nameContext = IdentifierContext.formalParameterDeclaration;
- if (!nameToken.isKeywordOrIdentifier) {
- beforeToken = beforeNameToken;
- token = nameToken;
- }
- } else if (nameToken.isKeywordOrIdentifier) {
- if (untyped) {
- // Type is required in a function type but name is not.
- untyped = false;
- nameContext = null;
- beforeNameToken = nameToken;
- nameToken = nameToken.next;
- } else {
- nameContext = IdentifierContext.formalParameterDeclaration;
- }
- } else {
- // No name required in a function type.
- nameContext = null;
- beforeToken = beforeNameToken;
- token = nameToken;
- }
- } else if (optional('this', nameToken)) {
- thisKeyword = nameToken;
- if (!optional('.', token)) {
- // Recover from a missing period by inserting one.
- Message message = fasta.templateExpectedButGot.withArguments('.');
- Token newToken =
- new SyntheticToken(TokenType.PERIOD, token.charOffset);
- periodAfterThis =
- rewriteAndRecover(thisKeyword, message, newToken).next;
- } else {
- periodAfterThis = token;
- }
- beforeToken = periodAfterThis;
- token = periodAfterThis.next;
- nameContext = IdentifierContext.fieldInitializer;
- if (!token.isIdentifier) {
- // Recover from a missing identifier by inserting one.
- token = insertSyntheticIdentifier(beforeToken, nameContext);
- }
- beforeNameToken = beforeToken;
- beforeToken = nameToken = token;
- token = token.next;
- } else if (!nameToken.isIdentifier) {
- if (optional('.', nameToken)) {
- // Recovery:
- // Looks like a prefixed type, but missing the type and param names.
- // Set the nameToken so that a synthetic identifier is inserted
- // after the `.` token.
- beforeToken = beforeNameToken = nameToken;
- token = nameToken = nameToken.next;
- } else if (context == IdentifierContext.prefixedTypeReference) {
- // Recovery:
- // Looks like a prefixed type, but missing the parameter name.
- beforeToken = nameToken =
- insertSyntheticIdentifier(beforeNameToken, nameContext);
- token = beforeToken.next;
- } else {
- untyped = true;
- beforeNameToken = beforeBegin;
- beforeToken = nameToken = begin;
- token = nameToken.next;
- }
- }
- if (isNamedParameter && nameToken.lexeme.startsWith("_")) {
- // TODO(ahe): Move this to after committing the type.
- reportRecoverableError(nameToken, fasta.messagePrivateNamedParameter);
- }
-
- Token inlineFunctionTypeStart;
- if (optional("<", token)) {
- Token closer = token.endGroup;
- if (closer != null) {
- if (optional("(", closer.next)) {
- if (varFinalOrConst != null) {
- reportRecoverableError(
- varFinalOrConst, fasta.messageFunctionTypedParameterVar);
- }
- inlineFunctionTypeStart = beforeToken;
- beforeToken = token;
- token = token.next;
- }
- }
- } else if (optional("(", token)) {
- if (varFinalOrConst != null) {
- reportRecoverableError(
- varFinalOrConst, fasta.messageFunctionTypedParameterVar);
- }
- inlineFunctionTypeStart = beforeToken;
- beforeToken = token.endGroup;
- token = beforeToken.next;
- }
-
- if (inlineFunctionTypeStart != null) {
- token = parseTypeVariablesOpt(inlineFunctionTypeStart);
- // TODO(brianwilkerson): Figure out how to remove the invocation of
- // `previous`. The method `parseTypeVariablesOpt` returns the last
- // consumed token.
- beforeToken = token.previous;
- listener
- .beginFunctionTypedFormalParameter(inlineFunctionTypeStart.next);
- if (!untyped) {
- if (voidToken != null) {
- listener.handleVoidKeyword(voidToken);
- } else {
- Token saved = token;
- commitType();
- token = saved;
- // We need to recompute the before tokens because [commitType] can
- // cause synthetic tokens to be inserted.
- beforeToken = previousToken(beforeToken, token);
- beforeNameToken = previousToken(beforeNameToken, nameToken);
- }
- } else {
- listener.handleNoType(beforeToken);
- }
- beforeToken = parseFormalParametersRequiredOpt(
- token, MemberKind.FunctionTypedParameter);
- token = beforeToken.next;
- listener.endFunctionTypedFormalParameter();
-
- // Generalized function types don't allow inline function types.
- // The following isn't allowed:
- // int Function(int bar(String x)).
- if (memberKind == MemberKind.GeneralizedFunctionType) {
- reportRecoverableError(inlineFunctionTypeStart.next,
- fasta.messageInvalidInlineFunctionType);
- }
- } else if (untyped) {
- listener.handleNoType(token);
- } else {
- Token saved = token;
- commitType();
- token = saved;
- // We need to recompute the before tokens because [commitType] can
- // cause synthetic tokens to be inserted.
- beforeToken = previousToken(beforeToken, token);
- beforeNameToken = previousToken(beforeNameToken, nameToken);
- }
-
- if (nameContext != null) {
- nameToken = ensureIdentifier(beforeNameToken, nameContext);
- // We need to recompute the before tokens because [ensureIdentifier]
- // can cause synthetic tokens to be inserted.
- beforeToken = previousToken(beforeToken, token);
- } else {
- listener.handleNoName(nameToken);
- }
-
- String value = token.stringValue;
- if ((identical('=', value)) || (identical(':', value))) {
- Token equal = token;
- listener.beginFormalParameterDefaultValueExpression();
- beforeToken = parseExpression(token);
- listener.endFormalParameterDefaultValueExpression();
- token = beforeToken.next;
- listener.handleValuedFormalParameter(equal, token);
- if (isMandatoryFormalParameterKind(parameterKind)) {
- reportRecoverableError(
- equal, fasta.messageRequiredParameterWithDefault);
- } else if (isOptionalPositionalFormalParameterKind(parameterKind) &&
- identical(':', value)) {
- reportRecoverableError(
- equal, fasta.messagePositionalParameterWithEquals);
- } else if (inFunctionType ||
- memberKind == MemberKind.FunctionTypeAlias ||
- memberKind == MemberKind.FunctionTypedParameter) {
- reportRecoverableError(
- equal, fasta.messageFunctionTypeDefaultValue);
- }
- } else {
- listener.handleFormalParameterWithoutValue(token);
- }
- listener.endFormalParameter(
- thisKeyword, periodAfterThis, nameToken, parameterKind, memberKind);
- return beforeToken;
}
throw "Internal error: Unhandled continuation '$continuation'.";
@@ -2884,7 +2739,7 @@
covariantToken = null;
}
}
- if (typeInfo == noTypeInfo) {
+ if (typeInfo == noType) {
if (varFinalOrConst == null) {
reportRecoverableError(
beforeName.next, fasta.messageMissingConstFinalVarOrType);
@@ -3252,12 +3107,12 @@
assert(value != '>');
Token replacement = new Token(TokenType.GT, next.charOffset);
if (identical(value, '>>')) {
- replacement.next = new Token(TokenType.GT, next.charOffset + 1);
+ replacement.setNext(new Token(TokenType.GT, next.charOffset + 1));
} else if (identical(value, '>=')) {
- replacement.next = new Token(TokenType.EQ, next.charOffset + 1);
+ replacement.setNext(new Token(TokenType.EQ, next.charOffset + 1));
} else if (identical(value, '>>=')) {
- replacement.next = new Token(TokenType.GT, next.charOffset + 1);
- replacement.next.next = new Token(TokenType.EQ, next.charOffset + 2);
+ replacement.setNext(new Token(TokenType.GT, next.charOffset + 1));
+ replacement.next.setNext(new Token(TokenType.EQ, next.charOffset + 2));
} else {
// Recovery
rewriteAndRecover(token, fasta.templateExpectedToken.withArguments('>'),
@@ -3298,30 +3153,6 @@
return expect(';', token);
}
- /// Provides a partial order on modifiers.
- ///
- /// The order is based on the order modifiers must appear in according to the
- /// grammar. For example, `external` must come before `static`.
- ///
- /// In addition, if two modifiers have the same order, they can't both be
- /// used together, for example, `final` and `var` can't be used together.
- ///
- /// If [token] isn't a modifier, 127 is returned.
- int modifierOrder(Token token) {
- final String value = token.stringValue;
- if (identical('external', value)) return 0;
- if (identical('static', value) || identical('covariant', value)) {
- return 1;
- }
- if (identical('final', value) ||
- identical('var', value) ||
- identical('const', value)) {
- return 2;
- }
- if (identical('abstract', value)) return 3;
- return 127;
- }
-
Token parseNativeClause(Token token) {
Token nativeToken = token = token.next;
assert(optional('native', nativeToken));
@@ -3370,14 +3201,6 @@
return token;
}
- bool isGetOrSet(Token token) {
- final String value = token.stringValue;
- return (identical(value, 'get')) || (identical(value, 'set'));
- }
-
- bool isModifierOrFactory(Token next) =>
- optional('factory', next) || isModifier(next);
-
bool isUnaryMinus(Token token) =>
token.kind == IDENTIFIER_TOKEN &&
token.lexeme == 'unary' &&
@@ -3533,7 +3356,7 @@
typeInfo,
getOrSet);
}
- } else if (typeInfo == noTypeInfo && varFinalOrConst == null) {
+ } else if (typeInfo == noType && varFinalOrConst == null) {
Token next2 = next.next;
if (next2.isUserDefinableOperator && next2.endGroup == null) {
String value = next2.next.stringValue;
@@ -5358,7 +5181,7 @@
assert(optional('const', constToken));
if (!isModifier(constToken.next)) {
TypeInfo typeInfo = computeType(constToken, false);
- if (typeInfo == noTypeInfo) {
+ if (typeInfo == noType) {
Token next = constToken.next;
if (!next.isIdentifier) {
return parseExpressionStatement(start);
@@ -5489,11 +5312,11 @@
// identifier, then allow ensureIdentifier to report an error
// and don't report errors here.
if (varFinalOrConst == null) {
- if (typeInfo == noTypeInfo) {
+ if (typeInfo == noType) {
reportRecoverableError(next, fasta.messageMissingConstFinalVarOrType);
}
} else if (optional('var', varFinalOrConst)) {
- if (typeInfo != noTypeInfo) {
+ if (typeInfo != noType) {
reportRecoverableError(varFinalOrConst, fasta.messageTypeAfterVar);
}
}
@@ -6600,7 +6423,7 @@
/// Create a short token chain from the [beginToken] and [endToken] and return
/// the [beginToken].
Token link(BeginToken beginToken, Token endToken) {
- beginToken.next = endToken;
+ beginToken.setNext(endToken);
beginToken.endGroup = endToken;
return beginToken;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
index aa850f9..eb7f4d5 100644
--- a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
+++ b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
@@ -34,30 +34,38 @@
/// after the [previousToken]. Return the [previousToken].
Token insertTokenAfter(Token previousToken, Token insertedToken) {
Token afterToken = previousToken.next;
- previousToken.next = insertedToken;
- insertedToken.previous = previousToken;
+ previousToken.setNext(insertedToken);
Token lastReplacement = _lastTokenInChain(insertedToken);
- lastReplacement.next = afterToken;
- afterToken.previous = lastReplacement;
+ lastReplacement.setNext(afterToken);
return previousToken;
}
+ /// Move [endGroup] (a synthetic `)`, `]`, `}`, or `>` token) after [token]
+ /// in the token stream and return [endGroup].
+ Token moveSynthetic(Token token, Token endGroup) {
+ assert(endGroup.beforeSynthetic != null);
+
+ Token next = token.next;
+ endGroup.beforeSynthetic.setNext(endGroup.next);
+ token.setNext(endGroup);
+ endGroup.setNext(next);
+ endGroup.offset = next.offset;
+ return endGroup;
+ }
+
/// Replace the single token immediately following the [previousToken] with
/// the chain of tokens starting at the [replacementToken]. Return the
/// [replacementToken].
Token replaceTokenFollowing(Token previousToken, Token replacementToken) {
Token replacedToken = previousToken.next;
- previousToken.next = replacementToken;
- replacementToken.previous = previousToken;
+ previousToken.setNext(replacementToken);
(replacementToken as SimpleToken).precedingComments =
replacedToken.precedingComments;
- Token lastReplacement = _lastTokenInChain(replacementToken);
- lastReplacement.next = replacedToken.next;
- replacedToken.next.previous = lastReplacement;
+ _lastTokenInChain(replacementToken).setNext(replacedToken.next);
return replacementToken;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/type_continuation.dart b/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
index a825ae5..a8aafd2 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_continuation.dart
@@ -4,8 +4,6 @@
library fasta.parser.type_continuation;
-import 'formal_parameter_kind.dart' show FormalParameterKind;
-
/// Indication of how the parser should continue after (attempting) to parse a
/// type.
///
@@ -34,42 +32,4 @@
/// Indicates that the parser is parsing an expression and has just seen an
/// identifier.
SendOrFunctionLiteral,
-
- /// Indicates that an optional type followed by a normal formal parameter is
- /// expected.
- NormalFormalParameter,
-
- /// Indicates that an optional type followed by an optional positional formal
- /// parameter is expected.
- OptionalPositionalFormalParameter,
-
- /// Indicates that an optional type followed by a named formal parameter is
- /// expected.
- NamedFormalParameter,
-
- /// Same as [NormalFormalParameter], but we have seen `var`.
- NormalFormalParameterAfterVar,
-
- /// Same as [OptionalPositionalFormalParameter], but we have seen `var`.
- OptionalPositionalFormalParameterAfterVar,
-
- /// Same as [NamedFormalParameter], but we have seen `var`.
- NamedFormalParameterAfterVar,
-}
-
-TypeContinuation typeContinuationFromFormalParameterKind(
- FormalParameterKind type) {
- if (type != null) {
- switch (type) {
- case FormalParameterKind.mandatory:
- return TypeContinuation.NormalFormalParameter;
-
- case FormalParameterKind.optionalNamed:
- return TypeContinuation.NamedFormalParameter;
-
- case FormalParameterKind.optionalPositional:
- return TypeContinuation.OptionalPositionalFormalParameter;
- }
- }
- return null;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index 01e6edb..29a6a7a 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -10,15 +10,7 @@
import 'parser.dart' show Parser;
-import 'type_info_impl.dart'
- show
- ComplexTypeInfo,
- NoTypeInfo,
- PrefixedTypeInfo,
- SimpleTypeArgumentsInfo,
- SimpleTypeInfo,
- VoidTypeInfo,
- looksLikeName;
+import 'type_info_impl.dart';
import 'util.dart' show optional;
@@ -63,26 +55,26 @@
Token skipType(Token token);
}
-/// [NoTypeInfo] is a specialized [TypeInfo] returned by [computeType] when
+/// [NoType] is a specialized [TypeInfo] returned by [computeType] when
/// there is no type information in the source.
-const TypeInfo noTypeInfo = const NoTypeInfo();
+const TypeInfo noType = const NoType();
-/// [VoidTypeInfo] is a specialized [TypeInfo] returned by [computeType] when
+/// [VoidType] is a specialized [TypeInfo] returned by [computeType] when
/// there is a single identifier as the type reference.
-const TypeInfo voidTypeInfo = const VoidTypeInfo();
+const TypeInfo voidType = const VoidType();
-/// [SimpleTypeInfo] is a specialized [TypeInfo] returned by [computeType]
+/// [SimpleType] is a specialized [TypeInfo] returned by [computeType]
/// when there is a single identifier as the type reference.
-const TypeInfo simpleTypeInfo = const SimpleTypeInfo();
+const TypeInfo simpleType = const SimpleType();
-/// [PrefixedTypeInfo] is a specialized [TypeInfo] returned by [computeType]
+/// [PrefixedType] is a specialized [TypeInfo] returned by [computeType]
/// when the type reference is of the form: identifier `.` identifier.
-const TypeInfo prefixedTypeInfo = const PrefixedTypeInfo();
+const TypeInfo prefixedType = const PrefixedType();
-/// [SimpleTypeArgumentsInfo] is a specialized [TypeInfo] returned by
+/// [SimpleTypeWith1Argument] is a specialized [TypeInfo] returned by
/// [computeType] when the type reference is of the form:
/// identifier `<` identifier `>`.
-const TypeInfo simpleTypeArgumentsInfo = const SimpleTypeArgumentsInfo();
+const TypeInfo simpleTypeWith1Argument = const SimpleTypeWith1Argument();
Token insertSyntheticIdentifierAfter(Token token, Parser parser) {
Token identifier = new SyntheticStringToken(
@@ -138,8 +130,11 @@
}
}
}
+ } else if (required && optional('.', next)) {
+ // Recovery: looks like prefixed type missing the prefix
+ return new ComplexTypeInfo(token).computePrefixedType(required);
}
- return noTypeInfo;
+ return noType;
}
if (optional('void', next)) {
@@ -149,7 +144,7 @@
return new ComplexTypeInfo(token).computeVoidGFT(required);
}
// `void`
- return voidTypeInfo;
+ return voidType;
}
if (isGeneralizedFunctionType(next)) {
@@ -173,10 +168,10 @@
if (!isGeneralizedFunctionType(next)) {
if (required || looksLikeName(next)) {
// identifier `<` identifier `>` identifier
- return simpleTypeArgumentsInfo;
+ return simpleTypeWith1Argument;
} else {
// identifier `<` identifier `>` non-identifier
- return noTypeInfo;
+ return noType;
}
}
}
@@ -190,7 +185,7 @@
.computeSimpleWithTypeArguments(required);
}
// identifier `<`
- return required ? simpleTypeInfo : noTypeInfo;
+ return required ? simpleType : noType;
}
if (optional('.', next)) {
@@ -201,17 +196,19 @@
if (!optional('<', next) && !isGeneralizedFunctionType(next)) {
if (required || looksLikeName(next)) {
// identifier `.` identifier identifier
- return prefixedTypeInfo;
+ return prefixedType;
} else {
// identifier `.` identifier non-identifier
- return noTypeInfo;
+ return noType;
}
}
// identifier `.` identifier
return new ComplexTypeInfo(token).computePrefixedType(required);
}
// identifier `.` non-identifier
- return required ? simpleTypeInfo : noTypeInfo;
+ return required
+ ? new ComplexTypeInfo(token).computePrefixedType(required)
+ : noType;
}
if (isGeneralizedFunctionType(next)) {
@@ -221,7 +218,7 @@
if (required || looksLikeName(next)) {
// identifier identifier
- return simpleTypeInfo;
+ return simpleType;
}
- return noTypeInfo;
+ return noType;
}
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 08b2cce..f0e77fb 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -22,9 +22,9 @@
import 'util.dart' show optional;
-/// See documentation on the [noTypeInfo] const.
-class NoTypeInfo implements TypeInfo {
- const NoTypeInfo();
+/// See documentation on the [noType] const.
+class NoType implements TypeInfo {
+ const NoType();
@override
bool get couldBeExpression => false;
@@ -34,7 +34,7 @@
parser.reportRecoverableErrorWithToken(
token.next, fasta.templateExpectedType);
insertSyntheticIdentifierAfter(token, parser);
- return simpleTypeInfo.parseType(token, parser);
+ return simpleType.parseType(token, parser);
}
@override
@@ -57,9 +57,9 @@
}
}
-/// See documentation on the [prefixedTypeInfo] const.
-class PrefixedTypeInfo implements TypeInfo {
- const PrefixedTypeInfo();
+/// See documentation on the [prefixedType] const.
+class PrefixedType implements TypeInfo {
+ const PrefixedType();
@override
bool get couldBeExpression => true;
@@ -103,9 +103,9 @@
}
}
-/// See documentation on the [simpleTypeArgumentsInfo] const.
-class SimpleTypeArgumentsInfo implements TypeInfo {
- const SimpleTypeArgumentsInfo();
+/// See documentation on the [simpleTypeWith1Argument] const.
+class SimpleTypeWith1Argument implements TypeInfo {
+ const SimpleTypeWith1Argument();
@override
bool get couldBeExpression => false;
@@ -133,7 +133,7 @@
assert(optional('<', token));
listener.beginTypeArguments(token);
- token = simpleTypeInfo.parseTypeNotVoid(token, parser);
+ token = simpleType.parseTypeNotVoid(token, parser);
token = token.next;
assert(optional('>', token));
@@ -150,9 +150,9 @@
}
}
-/// See documentation on the [simpleTypeInfo] const.
-class SimpleTypeInfo implements TypeInfo {
- const SimpleTypeInfo();
+/// See documentation on the [simpleType] const.
+class SimpleType implements TypeInfo {
+ const SimpleType();
@override
bool get couldBeExpression => true;
@@ -186,9 +186,9 @@
}
}
-/// See documentation on the [voidTypeInfo] const.
-class VoidTypeInfo implements TypeInfo {
- const VoidTypeInfo();
+/// See documentation on the [voidType] const.
+class VoidType implements TypeInfo {
+ const VoidType();
@override
bool get couldBeExpression => false;
@@ -197,7 +197,7 @@
Token ensureTypeNotVoid(Token token, Parser parser) {
// Report an error, then parse `void` as if it were a type name.
parser.reportRecoverableError(token.next, fasta.messageInvalidVoid);
- return simpleTypeInfo.parseTypeNotVoid(token, parser);
+ return simpleType.parseTypeNotVoid(token, parser);
}
@override
@@ -224,28 +224,33 @@
bool looksLikeName(Token token) =>
token.isIdentifier || optional('this', token);
-Token skipTypeArguments(Token token) {
+Token skipTypeVariables(Token token) {
assert(optional('<', token));
Token endGroup = token.endGroup;
+ if (endGroup == null) {
+ return null;
+ }
// The scanner sets the endGroup in situations like this: C<T && T>U;
// Scan the type arguments to assert there are no operators.
- // TODO(danrubel) Fix the scanner and remove this code.
- if (endGroup != null) {
- token = token.next;
- while (token != endGroup) {
- if (token.isOperator) {
- String value = token.stringValue;
- if (!identical(value, '<') &&
- !identical(value, '>') &&
- !identical(value, '>>')) {
- return null;
- }
- }
- token = token.next;
+ // TODO(danrubel): Fix the scanner to do this scanning.
+ token = token.next;
+ while (token != endGroup) {
+ if (token.isKeywordOrIdentifier ||
+ optional(',', token) ||
+ optional('.', token) ||
+ optional('<', token) ||
+ optional('>', token) ||
+ optional('>>', token) ||
+ optional('@', token)) {
+ // ok
+ } else if (optional('(', token)) {
+ token = token.endGroup;
+ } else {
+ return null;
}
+ token = token.next;
}
-
return endGroup;
}
@@ -253,7 +258,7 @@
/// type references that cannot be represented by the constants above.
class ComplexTypeInfo implements TypeInfo {
/// The first token in the type reference.
- final Token start;
+ Token start;
/// The last token in the type reference.
Token end;
@@ -291,6 +296,12 @@
Token parseType(Token token, Parser parser) {
assert(identical(token.next, start));
+ if (optional('.', start)) {
+ // Recovery: Insert missing identifier without sending events
+ start = parser.insertSyntheticIdentifier(
+ token, IdentifierContext.prefixedTypeReference);
+ }
+
for (Link<Token> t = typeVariableStarters; t.isNotEmpty; t = t.tail) {
parser.parseTypeVariablesOpt(t.head);
parser.listener.beginFunctionType(start);
@@ -300,13 +311,14 @@
// A function type without return type.
// Push the non-existing return type first. The loop below will
// generate the full type.
- noTypeInfo.parseTypeNotVoid(token, parser);
+ noType.parseTypeNotVoid(token, parser);
} else {
- Token start = token.next;
- if (optional('void', start)) {
- token = voidTypeInfo.parseType(token, parser);
+ Token typeRefOrPrefix = token.next;
+ if (optional('void', typeRefOrPrefix)) {
+ token = voidType.parseType(token, parser);
} else {
- if (!optional('.', start.next)) {
+ if (!optional('.', typeRefOrPrefix) &&
+ !optional('.', typeRefOrPrefix.next)) {
token =
parser.ensureIdentifier(token, IdentifierContext.typeReference);
} else {
@@ -314,9 +326,12 @@
token, IdentifierContext.prefixedTypeReference);
token = parser.parseQualifiedRest(
token, IdentifierContext.typeReferenceContinuation);
+ if (token.isSynthetic && end == typeRefOrPrefix.next) {
+ end = token;
+ }
}
token = parser.parseTypeArgumentsOpt(token);
- parser.listener.handleType(start, token.next);
+ parser.listener.handleType(typeRefOrPrefix, token.next);
}
}
@@ -358,7 +373,7 @@
computeRest(start, required);
if (gftHasReturnType == null) {
- return required ? simpleTypeInfo : noTypeInfo;
+ return required ? simpleType : noType;
}
assert(end != null);
return this;
@@ -372,7 +387,7 @@
computeRest(start.next, required);
if (gftHasReturnType == null) {
- return voidTypeInfo;
+ return voidType;
}
assert(end != null);
return this;
@@ -386,7 +401,7 @@
Token token = start.next;
if (optional('<', token)) {
typeArguments = token;
- token = skipTypeArguments(typeArguments);
+ token = skipTypeVariables(typeArguments);
if (token == null) {
token = typeArguments;
typeArguments = null;
@@ -408,7 +423,7 @@
computeRest(start.next, required);
if (gftHasReturnType == null) {
- return simpleTypeInfo;
+ return simpleType;
}
assert(end != null);
return this;
@@ -421,15 +436,15 @@
typeArguments = start.next;
assert(optional('<', typeArguments));
- Token token = skipTypeArguments(typeArguments);
+ Token token = skipTypeVariables(typeArguments);
if (token == null) {
- return required ? simpleTypeInfo : noTypeInfo;
+ return required ? simpleType : noType;
}
end = token;
computeRest(token.next, required);
if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
- return noTypeInfo;
+ return noType;
}
assert(end != null);
return this;
@@ -438,19 +453,23 @@
/// Given identifier `.` identifier, compute the type
/// and return the receiver or one of the [TypeInfo] constants.
TypeInfo computePrefixedType(bool required) {
- assert(isValidTypeReference(start));
- Token token = start.next;
+ Token token = start;
+ if (!optional('.', token)) {
+ assert(isValidTypeReference(token));
+ token = token.next;
+ }
assert(optional('.', token));
- token = token.next;
- assert(isValidTypeReference(token));
+ if (isValidTypeReference(token.next)) {
+ token = token.next;
+ }
end = token;
token = token.next;
if (optional('<', token)) {
typeArguments = token;
- token = skipTypeArguments(token);
+ token = skipTypeVariables(token);
if (token == null) {
- return required ? prefixedTypeInfo : noTypeInfo;
+ return required ? prefixedType : noType;
}
end = token;
token = token.next;
@@ -458,7 +477,7 @@
computeRest(token, required);
if (!required && !looksLikeName(end.next) && gftHasReturnType == null) {
- return noTypeInfo;
+ return noType;
}
assert(end != null);
return this;
@@ -469,7 +488,7 @@
Token typeVariableStart = token;
token = token.next;
if (optional('<', token)) {
- token = token.endGroup;
+ token = skipTypeVariables(token);
if (token == null) {
break; // Not a function type.
}
diff --git a/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart b/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart
index 8f7100b..5d8487a 100644
--- a/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/array_based_scanner.dart
@@ -361,7 +361,7 @@
// v
// EOF
TokenType type = closeBraceInfoFor(begin);
- appendToken(new SyntheticToken(type, tokenStart));
+ appendToken(new SyntheticToken(type, tokenStart)..beforeSynthetic = tail);
begin.endGroup = tail;
appendErrorToken(new UnmatchedToken(begin));
}
diff --git a/pkg/front_end/lib/src/fasta/scanner/recover.dart b/pkg/front_end/lib/src/fasta/scanner/recover.dart
index 5341f1b..d969362 100644
--- a/pkg/front_end/lib/src/fasta/scanner/recover.dart
+++ b/pkg/front_end/lib/src/fasta/scanner/recover.dart
@@ -124,7 +124,7 @@
}
String value = new String.fromCharCodes(codeUnits);
return synthesizeToken(charOffset, value, TokenType.IDENTIFIER)
- ..next = next;
+ ..setNext(next);
}
recoverExponent() {
@@ -137,7 +137,7 @@
recoverHexDigit() {
return synthesizeToken(errorTail.charOffset, "0", TokenType.INT)
- ..next = errorTail.next;
+ ..setNext(errorTail.next);
}
recoverStringInterpolation() {
@@ -164,8 +164,7 @@
if (errorTail == null) {
error = next;
} else {
- errorTail.next = next;
- next.previous = errorTail;
+ errorTail.setNext(next);
}
errorTail = next;
next = next.next;
@@ -204,23 +203,21 @@
if (goodTail == null) {
good = current;
} else {
- goodTail.next = current;
- current.previous = goodTail;
+ goodTail.setNext(current);
}
beforeGoodTail = goodTail;
goodTail = current;
}
- error.previous = new Token.eof(-1)..next = error;
+ new Token.eof(-1).setNext(error);
Token tail;
if (good != null) {
- errorTail.next = good;
- good.previous = errorTail;
+ errorTail.setNext(good);
tail = goodTail;
} else {
tail = errorTail;
}
- if (!tail.isEof) tail.next = new Token.eof(tail.end)..previous = tail;
+ if (!tail.isEof) tail.setNext(new Token.eof(tail.end));
return error;
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 79676d4..687a738 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -636,6 +636,17 @@
ticker.logMs("Checked overrides");
}
+ void checkAbstractMembers(List<SourceClassBuilder> sourceClasses) {
+ if (!target.strongMode) return;
+ assert(hierarchy != null);
+ for (SourceClassBuilder builder in sourceClasses) {
+ if (builder.library.loader == this) {
+ builder.checkAbstractMembers(coreTypes, hierarchy);
+ }
+ }
+ ticker.logMs("Checked abstract members");
+ }
+
void addNoSuchMethodForwarders(List<SourceClassBuilder> sourceClasses) {
if (!target.backendTarget.enableNoSuchMethodForwarders) return;
diff --git a/pkg/front_end/lib/src/incremental/unlinked_unit.dart b/pkg/front_end/lib/src/incremental/unlinked_unit.dart
index 0b5753a..8d38da3 100644
--- a/pkg/front_end/lib/src/incremental/unlinked_unit.dart
+++ b/pkg/front_end/lib/src/incremental/unlinked_unit.dart
@@ -61,12 +61,15 @@
/// Exclude all `native 'xyz';` token sequences.
void _excludeNativeClauses(Token token) {
- for (; token.kind != EOF_TOKEN; token = token.next) {
- if (optional('native', token) &&
- token.next.kind == STRING_TOKEN &&
- optional(';', token.next.next)) {
- token.previous.next = token.next.next;
+ while (token.kind != EOF_TOKEN) {
+ Token next = token.next;
+ if (optional('native', next) &&
+ next.next.kind == STRING_TOKEN &&
+ optional(';', next.next.next)) {
+ next = next.next.next;
+ token.setNext(next);
}
+ token = next;
}
}
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index 4e858ff..530b6f0 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -493,6 +493,14 @@
int get charEnd => end;
@override
+ Token get beforeSynthetic => null;
+
+ @override
+ set beforeSynthetic(Token previous) {
+ // ignored
+ }
+
+ @override
int get end => offset + length;
@override
@@ -581,6 +589,7 @@
Token setNext(Token token) {
next = token;
token.previous = this;
+ token.beforeSynthetic = this;
return token;
}
@@ -712,6 +721,12 @@
SyntheticToken(TokenType type, int offset) : super(type, offset);
@override
+ Token beforeSynthetic;
+
+ @override
+ bool get isSynthetic => true;
+
+ @override
int get length => 0;
@override
@@ -757,6 +772,18 @@
*/
int get charEnd;
+ /**
+ * The token before this synthetic token,
+ * or `null` if this is not a synthetic `)`, `]`, `}`, or `>` token.
+ */
+ Token get beforeSynthetic;
+
+ /**
+ * Set token before this synthetic `)`, `]`, `}`, or `>` token,
+ * and ignored otherwise.
+ */
+ set beforeSynthetic(Token previous);
+
@override
int get end;
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 25bcdaa..bf341d7 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -338,7 +338,7 @@
analyzerCode: TYPEDEF_IN_CLASS
dart2jsCode: "*fatal*"
script:
- - "class C { typedef int F(int x); }"
+ - "abstract class C { typedef int F(int x); }"
CovariantMember:
template: "Getters, setters and methods can't be declared to be 'covariant'."
@@ -1071,6 +1071,26 @@
template: "Factory redirects to class '#name', which is abstract and can't be instantiated."
severity: ERROR_LEGACY_WARNING
+MissingImplementationNotAbstract:
+ template: |
+ The non-abstract class '#name' is missing implementations for these members:
+ #string.
+ tip: |
+ Try to either
+ - provide an implementation,
+ - inherit an implementation from a superclass or mixin,
+ - mark the class as abstract, or
+ - provide a 'noSuchMethod' implementation.
+ severity: ERROR_LEGACY_WARNING
+ analyzerCode: CONCRETE_CLASS_WITH_ABSTRACT_MEMBER
+ dart2jsCode: "*fatal*"
+ script:
+ - "class C {foo();}"
+
+MissingImplementationCause:
+ template: "'#name' is defined here."
+ severity: CONTEXT
+
ListLiteralTooManyTypeArguments:
template: "Too many type arguments on List literal."
severity: ERROR_LEGACY_WARNING
diff --git a/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart b/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart
index 6a5ddce..ed8df9c 100644
--- a/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart
+++ b/pkg/front_end/test/fasta/parser/token_stream_rewriter_test.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:front_end/src/fasta/parser/token_stream_rewriter.dart';
+import 'package:front_end/src/fasta/scanner.dart'
+ show ScannerResult, scanString;
import 'package:front_end/src/fasta/scanner/token.dart';
import 'package:front_end/src/scanner/token.dart' show Token;
import 'package:test/test.dart';
@@ -77,6 +79,23 @@
expect(b.next, same(c));
}
+ void test_moveSynthetic() {
+ ScannerResult scanResult = scanString('Foo(bar; baz=0;');
+ expect(scanResult.hasErrors, isTrue);
+ Token open = scanResult.tokens.next.next;
+ expect(open.lexeme, '(');
+ Token close = open.endGroup;
+ expect(close.isSynthetic, isTrue);
+ expect(close.next.isEof, isTrue);
+ var rewriter = new TokenStreamRewriter();
+
+ Token result = rewriter.moveSynthetic(open.next, close);
+ expect(result, close);
+ expect(open.endGroup, close);
+ expect(open.next.next, close);
+ expect(close.next.isEof, isFalse);
+ }
+
void test_replaceTokenFollowing_multiple() {
var a = _makeToken(0, 'a');
var b = _makeToken(1, 'b');
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index b02c547..d09b895 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -22,15 +22,15 @@
void test_noType() {
final Token start = scanString('before ;').tokens;
- expect(noTypeInfo.couldBeExpression, isFalse);
- expect(noTypeInfo.skipType(start), start);
+ expect(noType.couldBeExpression, isFalse);
+ expect(noType.skipType(start), start);
}
void test_noType_ensureTypeNotVoid() {
final Token start = scanString('before ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(noTypeInfo.ensureTypeNotVoid(start, new Parser(listener)),
+ expect(noType.ensureTypeNotVoid(start, new Parser(listener)),
new isInstanceOf<SyntheticStringToken>());
expect(listener.calls, [
'handleIdentifier typeReference',
@@ -44,7 +44,7 @@
final Token start = scanString('before ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(noTypeInfo.ensureTypeOrVoid(start, new Parser(listener)),
+ expect(noType.ensureTypeOrVoid(start, new Parser(listener)),
new isInstanceOf<SyntheticStringToken>());
expect(listener.calls, [
'handleIdentifier typeReference',
@@ -58,7 +58,7 @@
final Token start = scanString('before ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(noTypeInfo.parseType(start, new Parser(listener)), start);
+ expect(noType.parseType(start, new Parser(listener)), start);
expect(listener.calls, ['handleNoType before']);
expect(listener.errors, isNull);
}
@@ -67,7 +67,7 @@
final Token start = scanString('before ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(noTypeInfo.parseTypeNotVoid(start, new Parser(listener)), start);
+ expect(noType.parseTypeNotVoid(start, new Parser(listener)), start);
expect(listener.calls, ['handleNoType before']);
expect(listener.errors, isNull);
}
@@ -75,16 +75,15 @@
void test_voidType() {
final Token start = scanString('before void ;').tokens;
- expect(voidTypeInfo.skipType(start), start.next);
- expect(voidTypeInfo.couldBeExpression, isFalse);
+ expect(voidType.skipType(start), start.next);
+ expect(voidType.couldBeExpression, isFalse);
}
void test_voidType_ensureTypeNotVoid() {
final Token start = scanString('before void ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(voidTypeInfo.ensureTypeNotVoid(start, new Parser(listener)),
- start.next);
+ expect(voidType.ensureTypeNotVoid(start, new Parser(listener)), start.next);
expect(listener.calls, [
'handleIdentifier void typeReference',
'handleNoTypeArguments ;',
@@ -97,7 +96,7 @@
final Token start = scanString('before void ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(voidTypeInfo.parseType(start, new Parser(listener)), start.next);
+ expect(voidType.parseType(start, new Parser(listener)), start.next);
expect(listener.calls, ['handleVoidKeyword void']);
expect(listener.errors, isNull);
}
@@ -106,7 +105,7 @@
final Token start = scanString('before void ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(voidTypeInfo.parseType(start, new Parser(listener)), start.next);
+ expect(voidType.parseType(start, new Parser(listener)), start.next);
expect(listener.calls, ['handleVoidKeyword void']);
expect(listener.errors, isNull);
}
@@ -115,8 +114,7 @@
final Token start = scanString('before void ;').tokens;
final TypeInfoListener listener = new TypeInfoListener();
- expect(
- voidTypeInfo.parseTypeNotVoid(start, new Parser(listener)), start.next);
+ expect(voidType.parseTypeNotVoid(start, new Parser(listener)), start.next);
expect(listener.calls, [
'handleIdentifier void typeReference',
'handleNoTypeArguments ;',
@@ -129,8 +127,8 @@
final Token start = scanString('before C.a ;').tokens;
final Token expectedEnd = start.next.next.next;
- expect(prefixedTypeInfo.skipType(start), expectedEnd);
- expect(prefixedTypeInfo.couldBeExpression, isTrue);
+ expect(prefixedType.skipType(start), expectedEnd);
+ expect(prefixedType.couldBeExpression, isTrue);
TypeInfoListener listener;
assertResult(Token actualEnd) {
@@ -146,27 +144,24 @@
}
listener = new TypeInfoListener();
- assertResult(
- prefixedTypeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+ assertResult(prefixedType.ensureTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(
- prefixedTypeInfo.ensureTypeOrVoid(start, new Parser(listener)));
+ assertResult(prefixedType.ensureTypeOrVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(
- prefixedTypeInfo.parseTypeNotVoid(start, new Parser(listener)));
+ assertResult(prefixedType.parseTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(prefixedTypeInfo.parseType(start, new Parser(listener)));
+ assertResult(prefixedType.parseType(start, new Parser(listener)));
}
void test_simpleTypeInfo() {
final Token start = scanString('before C ;').tokens;
final Token expectedEnd = start.next;
- expect(simpleTypeInfo.skipType(start), expectedEnd);
- expect(simpleTypeInfo.couldBeExpression, isTrue);
+ expect(simpleType.skipType(start), expectedEnd);
+ expect(simpleType.couldBeExpression, isTrue);
TypeInfoListener listener;
assertResult(Token actualEnd) {
@@ -180,24 +175,24 @@
}
listener = new TypeInfoListener();
- assertResult(simpleTypeInfo.ensureTypeNotVoid(start, new Parser(listener)));
+ assertResult(simpleType.ensureTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(simpleTypeInfo.ensureTypeOrVoid(start, new Parser(listener)));
+ assertResult(simpleType.ensureTypeOrVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(simpleTypeInfo.parseTypeNotVoid(start, new Parser(listener)));
+ assertResult(simpleType.parseTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
- assertResult(simpleTypeInfo.parseType(start, new Parser(listener)));
+ assertResult(simpleType.parseType(start, new Parser(listener)));
}
void test_simpleTypeArgumentsInfo() {
final Token start = scanString('before C<T> ;').tokens;
final Token expectedEnd = start.next.next.next.next;
- expect(simpleTypeArgumentsInfo.skipType(start), expectedEnd);
- expect(simpleTypeArgumentsInfo.couldBeExpression, isFalse);
+ expect(simpleTypeWith1Argument.skipType(start), expectedEnd);
+ expect(simpleTypeWith1Argument.couldBeExpression, isFalse);
TypeInfoListener listener;
assertResult(Token actualEnd) {
@@ -216,32 +211,42 @@
listener = new TypeInfoListener();
assertResult(
- simpleTypeArgumentsInfo.ensureTypeNotVoid(start, new Parser(listener)));
+ simpleTypeWith1Argument.ensureTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
assertResult(
- simpleTypeArgumentsInfo.ensureTypeOrVoid(start, new Parser(listener)));
+ simpleTypeWith1Argument.ensureTypeOrVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
assertResult(
- simpleTypeArgumentsInfo.parseTypeNotVoid(start, new Parser(listener)));
+ simpleTypeWith1Argument.parseTypeNotVoid(start, new Parser(listener)));
listener = new TypeInfoListener();
assertResult(
- simpleTypeArgumentsInfo.parseType(start, new Parser(listener)));
+ simpleTypeWith1Argument.parseType(start, new Parser(listener)));
}
void test_computeType_basic() {
- expectInfo(noTypeInfo, '');
- expectInfo(noTypeInfo, ';');
- expectInfo(noTypeInfo, '( foo');
- expectInfo(noTypeInfo, '< foo');
- expectInfo(noTypeInfo, '= foo');
- expectInfo(noTypeInfo, '* foo');
- expectInfo(noTypeInfo, 'do foo');
- expectInfo(noTypeInfo, 'get foo');
- expectInfo(noTypeInfo, 'set foo');
- expectInfo(noTypeInfo, 'operator *');
+ expectInfo(noType, '');
+ expectInfo(noType, ';');
+ expectInfo(noType, '( foo');
+ expectInfo(noType, '< foo');
+ expectInfo(noType, '= foo');
+ expectInfo(noType, '* foo');
+ expectInfo(noType, 'do foo');
+ expectInfo(noType, 'get foo');
+ expectInfo(noType, 'set foo');
+ expectInfo(noType, 'operator *');
+
+ expectInfo(noType, '.', required: false);
+ expectComplexInfo('.', required: true, expectedErrors: [
+ error(codeExpectedType, 0, 1),
+ error(codeExpectedType, 1, 0)
+ ]);
+
+ expectInfo(noType, '.Foo', required: false);
+ expectComplexInfo('.Foo',
+ required: true, expectedErrors: [error(codeExpectedType, 0, 1)]);
}
void test_computeType_builtin() {
@@ -330,8 +335,8 @@
'endFunctionType Function m',
]);
- expectInfo(noTypeInfo, 'Function(int x)', required: false);
- expectInfo(noTypeInfo, 'Function<T>(int x)', required: false);
+ expectInfo(noType, 'Function(int x)', required: false);
+ expectInfo(noType, 'Function<T>(int x)', required: false);
expectComplexInfo('Function(int x)', required: true);
expectComplexInfo('Function<T>(int x)', required: true);
@@ -346,39 +351,40 @@
}
void test_computeType_identifier() {
- expectInfo(noTypeInfo, 'C', required: false);
- expectInfo(noTypeInfo, 'C;', required: false);
- expectInfo(noTypeInfo, 'C(', required: false);
- expectInfo(noTypeInfo, 'C<', required: false);
- expectInfo(noTypeInfo, 'C.', required: false);
- expectInfo(noTypeInfo, 'C=', required: false);
- expectInfo(noTypeInfo, 'C*', required: false);
- expectInfo(noTypeInfo, 'C do', required: false);
+ expectInfo(noType, 'C', required: false);
+ expectInfo(noType, 'C;', required: false);
+ expectInfo(noType, 'C(', required: false);
+ expectInfo(noType, 'C<', required: false);
+ expectInfo(noType, 'C.', required: false);
+ expectInfo(noType, 'C=', required: false);
+ expectInfo(noType, 'C*', required: false);
+ expectInfo(noType, 'C do', required: false);
- expectInfo(simpleTypeInfo, 'C', required: true);
- expectInfo(simpleTypeInfo, 'C;', required: true);
- expectInfo(simpleTypeInfo, 'C(', required: true);
- expectInfo(simpleTypeInfo, 'C<', required: true);
- expectInfo(simpleTypeInfo, 'C.', required: true);
- expectInfo(simpleTypeInfo, 'C=', required: true);
- expectInfo(simpleTypeInfo, 'C*', required: true);
- expectInfo(simpleTypeInfo, 'C do', required: true);
+ expectInfo(simpleType, 'C', required: true);
+ expectInfo(simpleType, 'C;', required: true);
+ expectInfo(simpleType, 'C(', required: true);
+ expectInfo(simpleType, 'C<', required: true);
+ expectComplexInfo('C.',
+ required: true, expectedErrors: [error(codeExpectedType, 2, 0)]);
+ expectInfo(simpleType, 'C=', required: true);
+ expectInfo(simpleType, 'C*', required: true);
+ expectInfo(simpleType, 'C do', required: true);
- expectInfo(simpleTypeInfo, 'C foo');
- expectInfo(simpleTypeInfo, 'C get');
- expectInfo(simpleTypeInfo, 'C set');
- expectInfo(simpleTypeInfo, 'C operator');
- expectInfo(simpleTypeInfo, 'C this');
- expectInfo(simpleTypeInfo, 'C Function');
+ expectInfo(simpleType, 'C foo');
+ expectInfo(simpleType, 'C get');
+ expectInfo(simpleType, 'C set');
+ expectInfo(simpleType, 'C operator');
+ expectInfo(simpleType, 'C this');
+ expectInfo(simpleType, 'C Function');
}
void test_computeType_identifierComplex() {
- expectInfo(simpleTypeInfo, 'C Function()', required: false);
- expectInfo(simpleTypeInfo, 'C Function<T>()', required: false);
- expectInfo(simpleTypeInfo, 'C Function(int)', required: false);
- expectInfo(simpleTypeInfo, 'C Function<T>(int)', required: false);
- expectInfo(simpleTypeInfo, 'C Function(int x)', required: false);
- expectInfo(simpleTypeInfo, 'C Function<T>(int x)', required: false);
+ expectInfo(simpleType, 'C Function()', required: false);
+ expectInfo(simpleType, 'C Function<T>()', required: false);
+ expectInfo(simpleType, 'C Function(int)', required: false);
+ expectInfo(simpleType, 'C Function<T>(int)', required: false);
+ expectInfo(simpleType, 'C Function(int x)', required: false);
+ expectInfo(simpleType, 'C Function<T>(int x)', required: false);
expectComplexInfo('C Function()', required: true);
expectComplexInfo('C Function<T>()', required: true);
@@ -405,16 +411,16 @@
}
void test_computeType_identifierTypeArg() {
- expectInfo(noTypeInfo, 'C<T>', required: false);
- expectInfo(noTypeInfo, 'C<T>;', required: false);
- expectInfo(noTypeInfo, 'C<T>(', required: false);
- expectInfo(noTypeInfo, 'C<T> do', required: false);
- expectInfo(noTypeInfo, 'C<void>', required: false);
+ expectInfo(noType, 'C<T>', required: false);
+ expectInfo(noType, 'C<T>;', required: false);
+ expectInfo(noType, 'C<T>(', required: false);
+ expectInfo(noType, 'C<T> do', required: false);
+ expectInfo(noType, 'C<void>', required: false);
- expectInfo(simpleTypeArgumentsInfo, 'C<T>', required: true);
- expectInfo(simpleTypeArgumentsInfo, 'C<T>;', required: true);
- expectInfo(simpleTypeArgumentsInfo, 'C<T>(', required: true);
- expectInfo(simpleTypeArgumentsInfo, 'C<T> do', required: true);
+ expectInfo(simpleTypeWith1Argument, 'C<T>', required: true);
+ expectInfo(simpleTypeWith1Argument, 'C<T>;', required: true);
+ expectInfo(simpleTypeWith1Argument, 'C<T>(', required: true);
+ expectInfo(simpleTypeWith1Argument, 'C<T> do', required: true);
expectComplexInfo('C<void>', required: true, expectedCalls: [
'handleIdentifier C typeReference',
'beginTypeArguments <',
@@ -423,17 +429,17 @@
'handleType C ',
]);
- expectInfo(simpleTypeArgumentsInfo, 'C<T> foo');
- expectInfo(simpleTypeArgumentsInfo, 'C<T> get');
- expectInfo(simpleTypeArgumentsInfo, 'C<T> set');
- expectInfo(simpleTypeArgumentsInfo, 'C<T> operator');
- expectInfo(simpleTypeArgumentsInfo, 'C<T> Function');
+ expectInfo(simpleTypeWith1Argument, 'C<T> foo');
+ expectInfo(simpleTypeWith1Argument, 'C<T> get');
+ expectInfo(simpleTypeWith1Argument, 'C<T> set');
+ expectInfo(simpleTypeWith1Argument, 'C<T> operator');
+ expectInfo(simpleTypeWith1Argument, 'C<T> Function');
}
void test_computeType_identifierTypeArgComplex() {
- expectInfo(noTypeInfo, 'C<S,T>', required: false);
- expectInfo(noTypeInfo, 'C<S<T>>', required: false);
- expectInfo(noTypeInfo, 'C.a<T>', required: false);
+ expectInfo(noType, 'C<S,T>', required: false);
+ expectInfo(noType, 'C<S<T>>', required: false);
+ expectInfo(noType, 'C.a<T>', required: false);
expectComplexInfo('C<S,T>', required: true, expectedCalls: [
'handleIdentifier C typeReference',
@@ -530,7 +536,7 @@
error(codeExpectedToken, 6, 6)
]);
- expectInfo(noTypeInfo, 'C<>', required: false);
+ expectInfo(noType, 'C<>', required: false);
expectComplexInfo('C<>', required: true, expectedCalls: [
'handleIdentifier C typeReference',
'beginTypeArguments <',
@@ -555,32 +561,32 @@
]);
// Statements that should not have a type
- expectInfo(noTypeInfo, 'C<T ; T>U;', required: false);
- expectInfo(noTypeInfo, 'C<T && T>U;', required: false);
+ expectInfo(noType, 'C<T ; T>U;', required: false);
+ expectInfo(noType, 'C<T && T>U;', required: false);
}
void test_computeType_prefixed() {
- expectInfo(noTypeInfo, 'C.a', required: false);
- expectInfo(noTypeInfo, 'C.a;', required: false);
- expectInfo(noTypeInfo, 'C.a(', required: false);
- expectInfo(noTypeInfo, 'C.a<', required: false);
- expectInfo(noTypeInfo, 'C.a=', required: false);
- expectInfo(noTypeInfo, 'C.a*', required: false);
- expectInfo(noTypeInfo, 'C.a do', required: false);
+ expectInfo(noType, 'C.a', required: false);
+ expectInfo(noType, 'C.a;', required: false);
+ expectInfo(noType, 'C.a(', required: false);
+ expectInfo(noType, 'C.a<', required: false);
+ expectInfo(noType, 'C.a=', required: false);
+ expectInfo(noType, 'C.a*', required: false);
+ expectInfo(noType, 'C.a do', required: false);
- expectInfo(prefixedTypeInfo, 'C.a', required: true);
- expectInfo(prefixedTypeInfo, 'C.a;', required: true);
- expectInfo(prefixedTypeInfo, 'C.a(', required: true);
- expectInfo(prefixedTypeInfo, 'C.a<', required: true);
- expectInfo(prefixedTypeInfo, 'C.a=', required: true);
- expectInfo(prefixedTypeInfo, 'C.a*', required: true);
- expectInfo(prefixedTypeInfo, 'C.a do', required: true);
+ expectInfo(prefixedType, 'C.a', required: true);
+ expectInfo(prefixedType, 'C.a;', required: true);
+ expectInfo(prefixedType, 'C.a(', required: true);
+ expectInfo(prefixedType, 'C.a<', required: true);
+ expectInfo(prefixedType, 'C.a=', required: true);
+ expectInfo(prefixedType, 'C.a*', required: true);
+ expectInfo(prefixedType, 'C.a do', required: true);
- expectInfo(prefixedTypeInfo, 'C.a foo');
- expectInfo(prefixedTypeInfo, 'C.a get');
- expectInfo(prefixedTypeInfo, 'C.a set');
- expectInfo(prefixedTypeInfo, 'C.a operator');
- expectInfo(prefixedTypeInfo, 'C.a Function');
+ expectInfo(prefixedType, 'C.a foo');
+ expectInfo(prefixedType, 'C.a get');
+ expectInfo(prefixedType, 'C.a set');
+ expectInfo(prefixedType, 'C.a operator');
+ expectInfo(prefixedType, 'C.a Function');
}
void test_computeType_prefixedGFT() {
@@ -691,19 +697,19 @@
}
void test_computeType_void() {
- expectInfo(voidTypeInfo, 'void');
- expectInfo(voidTypeInfo, 'void;');
- expectInfo(voidTypeInfo, 'void(');
- expectInfo(voidTypeInfo, 'void<');
- expectInfo(voidTypeInfo, 'void=');
- expectInfo(voidTypeInfo, 'void*');
- expectInfo(voidTypeInfo, 'void<T>');
- expectInfo(voidTypeInfo, 'void do');
- expectInfo(voidTypeInfo, 'void foo');
- expectInfo(voidTypeInfo, 'void get');
- expectInfo(voidTypeInfo, 'void set');
- expectInfo(voidTypeInfo, 'void operator');
- expectInfo(voidTypeInfo, 'void Function');
+ expectInfo(voidType, 'void');
+ expectInfo(voidType, 'void;');
+ expectInfo(voidType, 'void(');
+ expectInfo(voidType, 'void<');
+ expectInfo(voidType, 'void=');
+ expectInfo(voidType, 'void*');
+ expectInfo(voidType, 'void<T>');
+ expectInfo(voidType, 'void do');
+ expectInfo(voidType, 'void foo');
+ expectInfo(voidType, 'void get');
+ expectInfo(voidType, 'void set');
+ expectInfo(voidType, 'void operator');
+ expectInfo(voidType, 'void Function');
expectComplexInfo('void Function(', // Scanner inserts synthetic ')'.
required: true,
expectedCalls: [
@@ -717,7 +723,7 @@
}
void test_computeType_voidComplex() {
- expectInfo(voidTypeInfo, 'void Function()', required: false);
+ expectInfo(voidType, 'void Function()', required: false);
expectComplexInfo('void Function()', required: true, expectedCalls: [
'handleNoTypeVariables (',
'beginFunctionType void',
@@ -727,11 +733,11 @@
'endFunctionType Function ',
]);
- expectInfo(voidTypeInfo, 'void Function<T>()', required: false);
- expectInfo(voidTypeInfo, 'void Function(int)', required: false);
- expectInfo(voidTypeInfo, 'void Function<T>(int)', required: false);
- expectInfo(voidTypeInfo, 'void Function(int x)', required: false);
- expectInfo(voidTypeInfo, 'void Function<T>(int x)', required: false);
+ expectInfo(voidType, 'void Function<T>()', required: false);
+ expectInfo(voidType, 'void Function(int)', required: false);
+ expectInfo(voidType, 'void Function<T>(int)', required: false);
+ expectInfo(voidType, 'void Function(int x)', required: false);
+ expectInfo(voidType, 'void Function<T>(int x)', required: false);
expectComplexInfo('void Function<T>()', required: true);
expectComplexInfo('void Function(int)', required: true);
diff --git a/pkg/front_end/test/fasta/super_mixins_test.dart b/pkg/front_end/test/fasta/super_mixins_test.dart
index d0ad9eb..17a4f92 100644
--- a/pkg/front_end/test/fasta/super_mixins_test.dart
+++ b/pkg/front_end/test/fasta/super_mixins_test.dart
@@ -60,6 +60,8 @@
super.foo(value);
super.quux();
}
+
+ void foo(String value) {}
}
void main() {
diff --git a/pkg/front_end/test/scanner_fasta_test.dart b/pkg/front_end/test/scanner_fasta_test.dart
index 0000f0c..2d01af9 100644
--- a/pkg/front_end/test/scanner_fasta_test.dart
+++ b/pkg/front_end/test/scanner_fasta_test.dart
@@ -727,7 +727,18 @@
@override
Token scan(String source) {
- return createScanner(source, includeComments: true).tokenize();
+ final Token first = createScanner(source, includeComments: true).tokenize();
+ Token token = first;
+ while (!token.isEof) {
+ Token next = token.next;
+ expect(token.next, next);
+ expect(next.previous, token);
+ if (next.isSynthetic && [')', ']', '}'].contains(next.lexeme)) {
+ expect(next.beforeSynthetic, token);
+ }
+ token = next;
+ }
+ return first;
}
void test_linestarts() {
diff --git a/pkg/front_end/test/scanner_replacement_test.dart b/pkg/front_end/test/scanner_replacement_test.dart
index 984c877..c13663a 100644
--- a/pkg/front_end/test/scanner_replacement_test.dart
+++ b/pkg/front_end/test/scanner_replacement_test.dart
@@ -229,9 +229,7 @@
token = token.next;
}
if (!token.previous.isEof) {
- var head = new analyzer.Token.eof(-1);
- token.previous = head;
- head.next = token;
+ new analyzer.Token.eof(-1).setNext(token);
}
return token;
}
diff --git a/pkg/front_end/testcases/inference/future_then.dart b/pkg/front_end/testcases/inference/future_then.dart
index 6b9527f..75782a4 100644
--- a/pkg/front_end/testcases/inference/future_then.dart
+++ b/pkg/front_end/testcases/inference/future_then.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.expect
index 10b7eb2..d9c0e0e 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
index 2ea9110..80a20d3 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.outline.expect b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
index 1089564..b7c6c22 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
index 82803df..5caa1e0 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart b/pkg/front_end/testcases/inference/future_then_2.dart
index b8dc5ff..f5f9def 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart
+++ b/pkg/front_end/testcases/inference/future_then_2.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
index acb9122..3290595 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
index 920eb54..93b4078 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
index 6e10646..264f452 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
index abf3ad2..8989332 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart b/pkg/front_end/testcases/inference/future_then_3.dart
index ca18c4f..1b4bfac 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart
+++ b/pkg/front_end/testcases/inference/future_then_3.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
index 62054d0..fc2ec41 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
index 752fb03..a94ad9c 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
index 66f74c0..496a434 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
index 2678694..78a4a61 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart b/pkg/front_end/testcases/inference/future_then_4.dart
index 25a1a92..afc672d 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart
+++ b/pkg/front_end/testcases/inference/future_then_4.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
index 6a85bd4..627469a9 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
index c1da628..ee00df9 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
index 077aa15..0e9ab26 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
index 4b747e7..03446f5 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart b/pkg/front_end/testcases/inference/future_then_5.dart
index 84fbc39..2fa4ef8 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart
+++ b/pkg/front_end/testcases/inference/future_then_5.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
index 49a21d8..cf8341b 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
index e7a0114..2c79488 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
index 248c940..60a45b2 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
index e8a77dc..495a584 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart b/pkg/front_end/testcases/inference/future_then_6.dart
index cd5877d..25cb27f 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart
+++ b/pkg/front_end/testcases/inference/future_then_6.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
index 784211b..59eca7d 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
index c04938b..470f6c1 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
index 6293827..03a4550 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
index fba912b..01b2db8 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<dynamic> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart b/pkg/front_end/testcases/inference/future_then_conditional.dart
index 84451ed..32f7cf2 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
index 2492740..6352e0d 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
index 61e4088..8b8e2a7 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
index b5a4ef4..08ec64a 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
index d83bae2..ff77eeb 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart b/pkg/front_end/testcases/inference/future_then_conditional_2.dart
index 2dcdf3f..9fb812d 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
index c8a5b9b..4884c6c 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
index bc86cdc..77323ea 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
index 213e538a..13b1486 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
index 27c0cd2..f272bfc 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart b/pkg/front_end/testcases/inference/future_then_conditional_3.dart
index f06ef6b..6a68194 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
index 6d9b472..477583e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
index 88cca73..4fc92fe 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
index 95d159a..af297a2 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
index 008dad4..f2c3a2a 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart b/pkg/front_end/testcases/inference/future_then_conditional_4.dart
index 8049974..f99855b 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
index 1603dff..73ac5c0 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
index c248a6d3..dc2f85e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
index d84c298..b3e8ccc 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
index 5db216e..6c4ab09 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart b/pkg/front_end/testcases/inference/future_then_conditional_5.dart
index 4660443..7520121 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
index bd54b84..32dbcf8 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
index eb4fbef..d7bf2f2 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
index d010e60..8425b11 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
index 4ab3d5f..f1cb720 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart b/pkg/front_end/testcases/inference/future_then_conditional_6.dart
index e843c57..b5d6508 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
index 82773ea..2fb57b2 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
index ca97197..93c7048 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
new file mode 100644
index 0000000..bf89d40
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
index eb9edd0..47e72b3 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
index 14029ba..48d5198 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::bool> f;
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.outline.expect
new file mode 100644
index 0000000..8e85697
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.outline.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_explicit_future.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.outline.expect
new file mode 100644
index 0000000..50d546c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_explicit_future.dart.outline.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static method m1() → dynamic
+ ;
+static method m2() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart b/pkg/front_end/testcases/inference/future_then_ifNull.dart
index f79997e..96695d4 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
index 2104ba8..3f7d35c 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
index 98e506f..f0608c1 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
index abbb36f..bf89d40 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.outline.expect
@@ -8,9 +8,14 @@
;
constructor value(self::MyFuture::T x) → void
;
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void
;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
index 636b65e..0b16167 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
index c0b8a92..186d1fe 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
self::MyFuture<core::int> f;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart b/pkg/front_end/testcases/inference/future_then_upwards.dart
index 34290072..1a770e9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
index ef2dc93..ad86cf9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
index ef2dc93..ad86cf9 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
new file mode 100644
index 0000000..dd8d84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method main() → void
+ ;
+static method foo() → self::MyFuture<dynamic>
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
index 82a1eea..e70813f 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
index d15cb1a..5f33f15 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart b/pkg/front_end/testcases/inference/future_then_upwards_2.dart
index 8db4acd..b9d340e 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
index d4901ef..a47a67c 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
index d4901ef..a47a67c 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
new file mode 100644
index 0000000..dd8d84a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.outline.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method main() → void
+ ;
+static method foo() → self::MyFuture<dynamic>
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
index 93e4a01..7a3e3e5 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
index 3ff32da..c45f7a3 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method main() → void {
self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart b/pkg/front_end/testcases/inference/future_then_upwards_3.dart
index 809f9ce..f57ee71 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(T x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
index 8be59eb..e107ab2 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
index 8be59eb..e107ab2 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
new file mode 100644
index 0000000..f9939e0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.outline.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(self::MyFuture::T x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method test() → void
+ ;
+static method foo() → asy::Future<dynamic>
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
index d31aa187..d0de61c 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::double> f = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
index 87ba016..7784c77 100644
--- a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(self::MyFuture::T x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method test() → void {
asy::Future<core::double> f = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.outline.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.outline.expect
new file mode 100644
index 0000000..8e85697
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.outline.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart b/pkg/front_end/testcases/inference/future_union_async_conditional.dart
index 345ed22..e1f0f8c 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
index ee695a6..2f01968 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return x ? 42 : asy::Future::value<dynamic>(42);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
index 911e233..5fc5f19 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
new file mode 100644
index 0000000..353c1be
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.outline.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(dynamic x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method g1(core::bool x) → asy::Future<core::int>
+ ;
+static method g2(core::bool x) → asy::Future<core::int>
+ ;
+static method g3(core::bool x) → asy::Future<core::int>
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
index 85ff010..722f2d6 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return (x ?{core::Object} 42 : asy::Future::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
index 7c803fd..260e803 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart
index 3523226..41e7cb0 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value(x) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
index 82e5e2a..e4c0c12 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return x ? 42 : new self::MyFuture::value<dynamic>(42);
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
index 00559fd..3010ada 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
new file mode 100644
index 0000000..353c1be
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.outline.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value(dynamic x) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static method g1(core::bool x) → asy::Future<core::int>
+ ;
+static method g2(core::bool x) → asy::Future<core::int>
+ ;
+static method g3(core::bool x) → asy::Future<core::int>
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
index b235cc7..c539bcd 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> async {
return (x ?{core::Object} 42 : new self::MyFuture::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
index 10fb0f8..ee81fa3 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value(dynamic x) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart b/pkg/front_end/testcases/inference/future_union_downwards.dart
index 75043bd..5622782 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value([x]) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
index 23bf82d..2bdcc03 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
index 859cda9..5db5ef3 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
new file mode 100644
index 0000000..203722c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.outline.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value([dynamic x]) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static field self::MyFuture<dynamic> f;
+static field asy::Future<core::int> t1;
+static field asy::Future<core::List<core::int>> t2;
+static method g2() → asy::Future<core::List<core::int>>
+ ;
+static method g3() → asy::Future<core::List<core::int>>
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
index 68b4bb8..c6c4632 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
index 2081070..e8e745e 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart b/pkg/front_end/testcases/inference/future_union_downwards_2.dart
index 8f83ae1..7ff20a9 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value([x]) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
index 55196f7..c76f12a 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
index 793eefb..87b4be0eb 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
new file mode 100644
index 0000000..203722c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.outline.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value([dynamic x]) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static field self::MyFuture<dynamic> f;
+static field asy::Future<core::int> t1;
+static field asy::Future<core::List<core::int>> t2;
+static method g2() → asy::Future<core::List<core::int>>
+ ;
+static method g3() → asy::Future<core::List<core::int>>
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
index 7200164..5c9ecaf 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
index d4ffd12..7eae3ec 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field self::MyFuture<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart b/pkg/front_end/testcases/inference/future_union_downwards_3.dart
index c00a4b5..3cd6687 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value([x]) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
index b63f083..7e03996 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
index 9d94cef..665f3ee 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
new file mode 100644
index 0000000..64f58e3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.outline.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value([dynamic x]) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static field asy::Future<dynamic> f;
+static field asy::Future<core::int> t1;
+static field asy::Future<core::List<core::int>> t2;
+static method g2() → asy::Future<core::List<core::int>>
+ ;
+static method g3() → asy::Future<core::List<core::int>>
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
index 4faa367..a78fef7 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
index 8f591b2..ff49091 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final dynamic #t1 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart b/pkg/front_end/testcases/inference/future_union_downwards_4.dart
index 7fa2acf..0bf7b5c 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart
@@ -10,7 +10,7 @@
class MyFuture<T> implements Future<T> {
MyFuture() {}
MyFuture.value([x]) {}
- dynamic noSuchMethod(/*@topType=Invocation*/ invocation);
+ dynamic noSuchMethod(/*@topType=Invocation*/ invocation) => null;
MyFuture<S> then<S>(FutureOr<S> f(T x), {Function onError}) => null;
}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
index 6eff123..a80ae91 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
index 306af4b..b952431 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(dynamic invocation) → dynamic;
+ method noSuchMethod(dynamic invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
new file mode 100644
index 0000000..64f58e3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.outline.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+ constructor •() → void
+ ;
+ constructor value([dynamic x]) → void
+ ;
+ method noSuchMethod(dynamic invocation) → dynamic
+ ;
+ method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError}) → self::MyFuture<self::MyFuture::then::S>
+ ;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {() → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
+}
+static field asy::Future<dynamic> f;
+static field asy::Future<core::int> t1;
+static field asy::Future<core::List<core::int>> t2;
+static method g2() → asy::Future<core::List<core::int>>
+ ;
+static method g3() → asy::Future<core::List<core::int>>
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
index 1b9b482..d62bc1b 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
index 58bf77e..f3bd417 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
@@ -8,9 +8,14 @@
: super core::Object::•() {}
constructor value([dynamic x = null]) → void
: super core::Object::•() {}
- abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return null;
method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
return null;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+ abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
}
static field asy::Future<dynamic> f;
static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.outline.expect
new file mode 100644
index 0000000..5c21b43
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.outline.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ ;
+}
+static method foo() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.outline.expect
new file mode 100644
index 0000000..a323d38
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.outline.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method id<T extends core::Object>(self::id::T x) → self::id::T
+ ;
+static method test() → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.outline.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.outline.expect
new file mode 100644
index 0000000..fbafd9f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.outline.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ synthetic constructor •() → void
+ ;
+}
+class B extends self::A {
+ synthetic constructor •() → void
+ ;
+}
+class C extends self::A {
+ synthetic constructor •() → void
+ ;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart
index 1cd1300..185cb96 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart
@@ -7,7 +7,7 @@
abstract class A {
int get x;
- void set x(double value);
+ void set x(double value) {}
}
class B extends A {
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.expect
index ade9351..84b8120b 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
abstract get x() → core::int;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field dynamic x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.transformed.expect
index ade9351..84b8120b 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.transformed.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
abstract get x() → core::int;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field dynamic x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
index 4b932ab..e843722 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.outline.expect
@@ -6,7 +6,8 @@
synthetic constructor •() → void
;
abstract get x() → core::int;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void
+ ;
}
class B extends self::A {
final field dynamic x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.expect
index e5bc744..f27336bc 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
abstract get x() → core::int;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field core::int x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.transformed.expect
index e5bc744..f27336bc 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.transformed.expect
@@ -7,7 +7,7 @@
: super core::Object::•()
;
abstract get x() → core::int;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field core::int x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart
index cf037f2..39ed20b 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart
@@ -6,7 +6,7 @@
library test;
abstract class A {
- void set x(double value);
+ void set x(double value) {}
}
class B extends A {
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.expect
index eaabbd8..1e77979 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field dynamic x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.transformed.expect
index eaabbd8..1e77979 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field dynamic x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
index b89d2f3..8c26438 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.outline.expect
@@ -5,7 +5,8 @@
abstract class A extends core::Object {
synthetic constructor •() → void
;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void
+ ;
}
class B extends self::A {
final field dynamic x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.expect
index e666cdd..9054ebc 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field core::double x;
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.transformed.expect
index e666cdd..9054ebc 100644
--- a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(core::double value) → void;
+ set x(core::double value) → void {}
}
class B extends self::A {
final field core::double x;
diff --git a/pkg/front_end/testcases/native_as_name.dart b/pkg/front_end/testcases/native_as_name.dart
index 8bd1047..d4b6837 100644
--- a/pkg/front_end/testcases/native_as_name.dart
+++ b/pkg/front_end/testcases/native_as_name.dart
@@ -18,11 +18,11 @@
String native() => "method";
}
-class Y1 {
+abstract class Y1 {
String get native;
}
-class Y2 {
+class Y2 extends Y1 {
@override
String get native => "getter";
}
diff --git a/pkg/front_end/testcases/native_as_name.dart.direct.expect b/pkg/front_end/testcases/native_as_name.dart.direct.expect
index 93e5e80..d982aee 100644
--- a/pkg/front_end/testcases/native_as_name.dart.direct.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.direct.expect
@@ -15,15 +15,15 @@
method native() → core::String
return "method";
}
-class Y1 extends core::Object {
+abstract class Y1 extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
abstract get native() → core::String;
}
-class Y2 extends core::Object {
+class Y2 extends self::Y1 {
synthetic constructor •() → void
- : super core::Object::•()
+ : super self::Y1::•()
;
@core::override
get native() → core::String
diff --git a/pkg/front_end/testcases/native_as_name.dart.direct.transformed.expect b/pkg/front_end/testcases/native_as_name.dart.direct.transformed.expect
index 93e5e80..d982aee 100644
--- a/pkg/front_end/testcases/native_as_name.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.direct.transformed.expect
@@ -15,15 +15,15 @@
method native() → core::String
return "method";
}
-class Y1 extends core::Object {
+abstract class Y1 extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
abstract get native() → core::String;
}
-class Y2 extends core::Object {
+class Y2 extends self::Y1 {
synthetic constructor •() → void
- : super core::Object::•()
+ : super self::Y1::•()
;
@core::override
get native() → core::String
diff --git a/pkg/front_end/testcases/native_as_name.dart.outline.expect b/pkg/front_end/testcases/native_as_name.dart.outline.expect
index 80a1780..0ee8d2d 100644
--- a/pkg/front_end/testcases/native_as_name.dart.outline.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.outline.expect
@@ -13,12 +13,12 @@
method native() → core::String
;
}
-class Y1 extends core::Object {
+abstract class Y1 extends core::Object {
synthetic constructor •() → void
;
abstract get native() → core::String;
}
-class Y2 extends core::Object {
+class Y2 extends self::Y1 {
synthetic constructor •() → void
;
get native() → core::String
diff --git a/pkg/front_end/testcases/native_as_name.dart.strong.expect b/pkg/front_end/testcases/native_as_name.dart.strong.expect
index 4b3cf16..e667fad 100644
--- a/pkg/front_end/testcases/native_as_name.dart.strong.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.strong.expect
@@ -15,15 +15,15 @@
method native() → core::String
return "method";
}
-class Y1 extends core::Object {
+abstract class Y1 extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
abstract get native() → core::String;
}
-class Y2 extends core::Object {
+class Y2 extends self::Y1 {
synthetic constructor •() → void
- : super core::Object::•()
+ : super self::Y1::•()
;
@core::override
get native() → core::String
diff --git a/pkg/front_end/testcases/native_as_name.dart.strong.transformed.expect b/pkg/front_end/testcases/native_as_name.dart.strong.transformed.expect
index 39a0b89..a502052 100644
--- a/pkg/front_end/testcases/native_as_name.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/native_as_name.dart.strong.transformed.expect
@@ -15,15 +15,15 @@
method native() → core::String
return "method";
}
-class Y1 extends core::Object {
+abstract class Y1 extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
abstract get native() → core::String;
}
-class Y2 extends core::Object {
+class Y2 extends self::Y1 {
synthetic constructor •() → void
- : super core::Object::•()
+ : super self::Y1::•()
;
@core::override
get native() → core::String
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart
index f461405..8879c0e 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart
@@ -6,7 +6,7 @@
// non-implemented abstract method has all the references to the type variables
// in its signature replaced with the appropriate types.
-class I<T> {
+abstract class I<T> {
T foo();
}
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
index ffa2406..bf9c46c 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-class I<T extends core::Object> extends core::Object {
+abstract class I<T extends core::Object> extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
index 41aef5e..32ef81f 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.direct.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-class I<T extends core::Object> extends core::Object {
+abstract class I<T extends core::Object> extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
index 6a7ca94..969a34b 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.outline.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-class I<T extends core::Object> extends core::Object {
+abstract class I<T extends core::Object> extends core::Object {
synthetic constructor •() → void
;
abstract method foo() → self::I::T;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
index ffa2406..bf9c46c 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-class I<T extends core::Object> extends core::Object {
+abstract class I<T extends core::Object> extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
index 41aef5e..32ef81f 100644
--- a/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/no_such_method_forwarders/subst_on_forwarder.dart.strong.transformed.expect
@@ -2,7 +2,7 @@
import self as self;
import "dart:core" as core;
-class I<T extends core::Object> extends core::Object {
+abstract class I<T extends core::Object> extends core::Object {
synthetic constructor •() → void
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/outline.status b/pkg/front_end/testcases/outline.status
index 80f615e..ae45e4b 100644
--- a/pkg/front_end/testcases/outline.status
+++ b/pkg/front_end/testcases/outline.status
@@ -74,33 +74,6 @@
inference/field_refers_to_static_getter: Fail
inference/field_refers_to_top_level_getter: Fail
inference/future_or_subtyping: Fail
-inference/future_then: Fail
-inference/future_then_2: Fail
-inference/future_then_3: Fail
-inference/future_then_4: Fail
-inference/future_then_5: Fail
-inference/future_then_6: Fail
-inference/future_then_conditional: Fail
-inference/future_then_conditional_2: Fail
-inference/future_then_conditional_3: Fail
-inference/future_then_conditional_4: Fail
-inference/future_then_conditional_5: Fail
-inference/future_then_conditional_6: Fail
-inference/future_then_downwards_method_target: Fail
-inference/future_then_explicit_future: Fail
-inference/future_then_upwards: Fail
-inference/future_then_upwards_2: Fail
-inference/future_then_upwards_3: Fail
-inference/future_then_upwards_from_block: Fail
-inference/future_union_async_conditional: Fail
-inference/future_union_async_conditional_2: Fail
-inference/future_union_downwards: Fail
-inference/future_union_downwards_2: Fail
-inference/future_union_downwards_3: Fail
-inference/future_union_downwards_4: Fail
-inference/future_union_downwards_generic_method_with_future_return: Fail
-inference/future_union_downwards_generic_method_with_generic_return: Fail
-inference/future_union_upwards_generic_methods: Fail
inference/generic_functions_return_typedef: Fail
inference/generic_methods_basic_downward_inference: Fail
inference/generic_methods_correctly_recognize_generic_upper_bound: Fail
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart
index eea4d0b..0030a53 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart
@@ -13,7 +13,7 @@
// This class inherits genericImpl annotations from its superclass, but doesn't
// have any members marked genericInterface because the inferred types of x and
// y do not depend on the type parameter T.
-class C<T> implements B<num> {
+abstract class C<T> implements B<num> {
var /*@covariance=genericImpl*/ x;
get y;
set y(/*@covariance=genericImpl*/ value);
@@ -21,7 +21,7 @@
// This class also has members marked genericInterface, since the inferred types
// of x and y *do* depend on the type parameter T.
-class D<T> implements B<T> {
+abstract class D<T> implements B<T> {
var /*@covariance=genericInterface, genericImpl*/ x;
get y;
set y(/*@covariance=genericInterface, genericImpl*/ value);
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.expect
index a69ba21..2582858 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.expect
@@ -9,7 +9,7 @@
: super core::Object::•()
;
}
-class C<T extends core::Object> extends core::Object implements self::B<core::num> {
+abstract class C<T extends core::Object> extends core::Object implements self::B<core::num> {
field dynamic x = null;
synthetic constructor •() → void
: super core::Object::•()
@@ -17,7 +17,7 @@
abstract get y() → dynamic;
abstract set y(dynamic value) → dynamic;
}
-class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
+abstract class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
field dynamic x = null;
synthetic constructor •() → void
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.transformed.expect
index a69ba21..2582858 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.transformed.expect
@@ -9,7 +9,7 @@
: super core::Object::•()
;
}
-class C<T extends core::Object> extends core::Object implements self::B<core::num> {
+abstract class C<T extends core::Object> extends core::Object implements self::B<core::num> {
field dynamic x = null;
synthetic constructor •() → void
: super core::Object::•()
@@ -17,7 +17,7 @@
abstract get y() → dynamic;
abstract set y(dynamic value) → dynamic;
}
-class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
+abstract class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
field dynamic x = null;
synthetic constructor •() → void
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
index 0c10d85..6ae5d4d 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.outline.expect
@@ -8,14 +8,14 @@
synthetic constructor •() → void
;
}
-class C<T extends core::Object> extends core::Object implements self::B<core::num> {
+abstract class C<T extends core::Object> extends core::Object implements self::B<core::num> {
field dynamic x;
synthetic constructor •() → void
;
abstract get y() → dynamic;
abstract set y(dynamic value) → dynamic;
}
-class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
+abstract class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
field dynamic x;
synthetic constructor •() → void
;
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.expect
index 7a67ecc..d32e1ab 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.expect
@@ -9,7 +9,7 @@
: super core::Object::•()
;
}
-class C<T extends core::Object> extends core::Object implements self::B<core::num> {
+abstract class C<T extends core::Object> extends core::Object implements self::B<core::num> {
generic-covariant-impl field core::num x = null;
synthetic constructor •() → void
: super core::Object::•()
@@ -17,7 +17,7 @@
abstract get y() → core::num;
abstract set y(generic-covariant-impl core::num value) → void;
}
-class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
+abstract class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
generic-covariant-impl generic-covariant-interface field self::D::T x = null;
synthetic constructor •() → void
: super core::Object::•()
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.transformed.expect
index 7a67ecc..d32e1ab 100644
--- a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
: super core::Object::•()
;
}
-class C<T extends core::Object> extends core::Object implements self::B<core::num> {
+abstract class C<T extends core::Object> extends core::Object implements self::B<core::num> {
generic-covariant-impl field core::num x = null;
synthetic constructor •() → void
: super core::Object::•()
@@ -17,7 +17,7 @@
abstract get y() → core::num;
abstract set y(generic-covariant-impl core::num value) → void;
}
-class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
+abstract class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
generic-covariant-impl generic-covariant-interface field self::D::T x = null;
synthetic constructor •() → void
: super core::Object::•()
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart
index b107e62..1da15ad 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart
@@ -5,7 +5,7 @@
/*@testedFeatures=error*/
class C {
- void set x(value);
+ void set x(value) {}
}
void test(C c) {
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.expect
index ceea877..8fbca83 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ set x(dynamic value) → void {}
}
static method test(self::C c) → void {
c.x = 1;
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.transformed.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.transformed.expect
index ceea877..8fbca83 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ set x(dynamic value) → void {}
}
static method test(self::C c) → void {
c.x = 1;
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.outline.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.outline.expect
index af37326..36f9321 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.outline.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.outline.expect
@@ -5,7 +5,8 @@
class C extends core::Object {
synthetic constructor •() → void
;
- abstract set x(dynamic value) → void;
+ set x(dynamic value) → void
+ ;
}
static method test(self::C c) → void
;
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
index 639d3c2..052b332 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ set x(dynamic value) → void {}
}
static method test(self::C c) → void {
c.{self::C::x} = 1;
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
index c1dd51a..bb3271b 100644
--- a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
@@ -6,7 +6,7 @@
synthetic constructor •() → void
: super core::Object::•()
;
- abstract set x(dynamic value) → void;
+ set x(dynamic value) → void {}
}
static method test(self::C c) → void {
c.{self::C::x} = 1;
diff --git a/pkg/front_end/tool/_fasta/compile_platform.dart b/pkg/front_end/tool/_fasta/compile_platform.dart
index b2bf572..7dcf8b4 100644
--- a/pkg/front_end/tool/_fasta/compile_platform.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform.dart
@@ -10,6 +10,9 @@
import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
+import 'package:vm/bytecode/gen_bytecode.dart'
+ show generateBytecode, kEnableKernelBytecodeForPlatform;
+
import 'package:vm/target/dart_runner.dart' show DartRunnerTarget;
import 'package:vm/target/flutter_runner.dart' show FlutterRunnerTarget;
@@ -85,6 +88,11 @@
}
new File.fromUri(outlineOutput).writeAsBytesSync(result.summary);
c.options.ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");
+
+ if (kEnableKernelBytecodeForPlatform) {
+ generateBytecode(result.component, strongMode: c.options.strongMode);
+ }
+
await writeComponentToFile(result.component, fullOutput,
filter: (lib) => !lib.isExternal);
diff --git a/pkg/front_end/tool/perf.dart b/pkg/front_end/tool/perf.dart
index 02b9283..b25a5b6 100644
--- a/pkg/front_end/tool/perf.dart
+++ b/pkg/front_end/tool/perf.dart
@@ -20,12 +20,12 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/file_system/file_system.dart' show ResourceUriResolver;
import 'package:analyzer/file_system/physical_file_system.dart'
show PhysicalResourceProvider;
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
+import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index e50b62d..d4983da 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -3650,9 +3650,23 @@
}
}
-/// Expression of the form `MakeClosure(f, c, t)` where `f` is a name of a
-/// closed top-level function, `c` is a Vector representing closure context, and
-/// `t` is the type of the resulting closure.
+/// Expression of the form `MakeClosure<T>(f, c, t)` where `f` is a name of a
+/// closed top-level function, `c` is a Vector representing closure context, `t`
+/// is the type of the resulting closure and `T` is a vector of type arguments
+/// to be passed to `f`.
+///
+/// Note these restrictions on its usage:
+///
+/// 1. `f` must reference a statically-resolved top-level function.
+///
+/// 2. The length of `T` must be less than or equal to the number of type
+/// parameters on `f`.
+///
+/// 3. It is disallowed to use `MakeClosure` on the same function twice with
+/// different numbers of type arguments.
+///
+/// 4. The type arguments `T` must be guaranteed to satisfy the bounds of the
+/// corresponding type parameters on `f`.
class ClosureCreation extends Expression {
Reference topLevelFunctionReference;
Expression contextVector;
@@ -5103,6 +5117,8 @@
/// Returns a possibly synthesized name for this type parameter, consistent
/// with the names used across all [toString] calls.
String toString() => debugQualifiedTypeParameterName(this);
+
+ bool get isFunctionTypeTypeParameter => parent == null;
}
class Supertype extends Node {
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index ae840c7..6749c74 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -182,7 +182,7 @@
final DartType valueType = readDartType();
final int length = readUInt();
final List<ConstantMapEntry> entries =
- new List<ConstantMapEntry>(length);
+ new List<ConstantMapEntry>.filled(length, null, growable: true);
for (int i = 0; i < length; i++) {
final Constant key = readConstantReference();
final Constant value = readConstantReference();
@@ -192,7 +192,8 @@
case ConstantTag.ListConstant:
final DartType typeArgument = readDartType();
final int length = readUInt();
- final List<Constant> entries = new List<Constant>(length);
+ final List<Constant> entries =
+ new List<Constant>.filled(length, null, growable: true);
for (int i = 0; i < length; i++) {
entries[i] = readConstantReference();
}
@@ -201,7 +202,7 @@
final Reference classReference = readClassReference();
final int typeArgumentCount = readUInt();
final List<DartType> typeArguments =
- new List<DartType>(typeArgumentCount);
+ new List<DartType>.filled(typeArgumentCount, null, growable: true);
for (int i = 0; i < typeArgumentCount; i++) {
typeArguments[i] = readDartType();
}
@@ -242,7 +243,7 @@
List<String> readStringReferenceList() {
int length = readUInt();
- List<String> result = new List<String>(length);
+ List<String> result = new List<String>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readStringReference();
}
@@ -268,7 +269,8 @@
List<Expression> readAnnotationList(TreeNode parent) {
int length = readUInt();
if (length == 0) return const <Expression>[];
- List<Expression> list = new List<Expression>(length);
+ List<Expression> list =
+ new List<Expression>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
list[i] = readExpression()..parent = parent;
}
@@ -699,7 +701,8 @@
List<Combinator> readCombinatorList() {
int length = readUInt();
- List<Combinator> result = new List<Combinator>(length);
+ List<Combinator> result =
+ new List<Combinator>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readCombinator();
}
@@ -1164,7 +1167,8 @@
List<Expression> readExpressionList() {
int length = readUInt();
- List<Expression> result = new List<Expression>(length);
+ List<Expression> result =
+ new List<Expression>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readExpression();
}
@@ -1418,7 +1422,8 @@
List<MapEntry> readMapEntryList() {
int length = readUInt();
- List<MapEntry> result = new List<MapEntry>(length);
+ List<MapEntry> result =
+ new List<MapEntry>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readMapEntry();
}
@@ -1431,8 +1436,8 @@
List<Statement> readStatementList() {
int length = readUInt();
- List<Statement> result = <Statement>[];
- result.length = length;
+ List<Statement> result =
+ new List<Statement>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readStatement();
}
@@ -1514,7 +1519,8 @@
var offset = readOffset();
var expression = readExpression();
int count = readUInt();
- List<SwitchCase> cases = new List<SwitchCase>(count);
+ List<SwitchCase> cases =
+ new List<SwitchCase>.filled(count, null, growable: true);
for (int i = 0; i < count; ++i) {
cases[i] = new SwitchCase.empty();
}
@@ -1579,7 +1585,7 @@
List<Catch> readCatchList() {
int length = readUInt();
- List<Catch> result = new List<Catch>(length);
+ List<Catch> result = new List<Catch>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readCatch();
}
@@ -1623,7 +1629,8 @@
List<Supertype> readSupertypeList() {
int length = readUInt();
- List<Supertype> result = new List<Supertype>(length);
+ List<Supertype> result =
+ new List<Supertype>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readSupertype();
}
@@ -1632,7 +1639,8 @@
List<DartType> readDartTypeList() {
int length = readUInt();
- List<DartType> result = new List<DartType>(length);
+ List<DartType> result =
+ new List<DartType>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readDartType();
}
@@ -1641,7 +1649,8 @@
List<NamedType> readNamedTypeList() {
int length = readUInt();
- List<NamedType> result = new List<NamedType>(length);
+ List<NamedType> result =
+ new List<NamedType>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readNamedType();
}
@@ -1716,7 +1725,7 @@
int length = readUInt();
if (length == 0) return list ?? <TypeParameter>[];
if (list == null) {
- list = new List<TypeParameter>(length);
+ list = new List<TypeParameter>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
list[i] = new TypeParameter(null, null)..parent = parent;
}
@@ -1752,7 +1761,8 @@
List<NamedExpression> readNamedExpressionList() {
int length = readUInt();
- List<NamedExpression> result = new List<NamedExpression>(length);
+ List<NamedExpression> result =
+ new List<NamedExpression>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readNamedExpression();
}
@@ -1765,7 +1775,8 @@
List<VariableDeclaration> readAndPushVariableDeclarationList() {
int length = readUInt();
- List<VariableDeclaration> result = new List<VariableDeclaration>(length);
+ List<VariableDeclaration> result =
+ new List<VariableDeclaration>.filled(length, null, growable: true);
for (int i = 0; i < length; ++i) {
result[i] = readAndPushVariableDeclaration();
}
@@ -1860,7 +1871,8 @@
final nodeOffset = readUint32();
offsetToReferenceId[nodeOffset] = j;
}
- referencedNodes = new List<Node>(referencesLength);
+ referencedNodes =
+ new List<Node>.filled(referencesLength, null, growable: true);
containsNodeReferences = true;
}
diff --git a/pkg/kernel/lib/transformations/closure/info.dart b/pkg/kernel/lib/transformations/closure/info.dart
index 6d0a288..ffa5fd7 100644
--- a/pkg/kernel/lib/transformations/closure/info.dart
+++ b/pkg/kernel/lib/transformations/closure/info.dart
@@ -233,7 +233,9 @@
}
visitTypeParameterType(TypeParameterType node) {
- if (!isOuterMostContext && node.parameter.parent != currentFunction) {
+ if (!isOuterMostContext &&
+ node.parameter.parent != currentFunction &&
+ !node.parameter.isFunctionTypeTypeParameter) {
typeVariables
.putIfAbsent(currentFunction, () => new Set<TypeParameter>())
.add(node.parameter);
diff --git a/pkg/vm/bin/dump_kernel.dart b/pkg/vm/bin/dump_kernel.dart
index 0f95c9ce..2add763 100644
--- a/pkg/vm/bin/dump_kernel.dart
+++ b/pkg/vm/bin/dump_kernel.dart
@@ -8,6 +8,7 @@
import 'package:kernel/binary/ast_from_binary.dart'
show BinaryBuilderWithMetadata;
+import 'package:vm/metadata/bytecode.dart' show BytecodeMetadataRepository;
import 'package:vm/metadata/direct_call.dart' show DirectCallMetadataRepository;
import 'package:vm/metadata/inferred_type.dart'
show InferredTypeMetadataRepository;
@@ -37,6 +38,7 @@
component.addMetadataRepository(new InferredTypeMetadataRepository());
component.addMetadataRepository(new ProcedureAttributesMetadataRepository());
component.addMetadataRepository(new UnreachableNodeMetadataRepository());
+ component.addMetadataRepository(new BytecodeMetadataRepository());
final List<int> bytes = new File(input).readAsBytesSync();
new BinaryBuilderWithMetadata(bytes).readComponent(component);
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index 5c17f8f..d845a2d 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -14,6 +14,7 @@
import 'package:kernel/target/vm.dart' show VmTarget;
import 'package:kernel/text/ast_to_text.dart'
show globalDebuggingNames, NameSystem;
+import 'package:vm/bytecode/gen_bytecode.dart' show kEnableKernelBytecode;
import 'package:vm/kernel_front_end.dart' show compileToKernel, ErrorDetector;
final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
@@ -36,7 +37,9 @@
'Enable global type flow analysis and related transformations in AOT mode.',
defaultsTo: true)
..addMultiOption('entry-points',
- help: 'Path to JSON file with the list of entry points');
+ help: 'Path to JSON file with the list of entry points')
+ ..addFlag('gen-bytecode',
+ help: 'Generate bytecode', defaultsTo: kEnableKernelBytecode);
final String _usage = '''
Usage: dart pkg/vm/bin/gen_kernel.dart --platform vm_platform_strong.dill [options] input.dart
@@ -73,6 +76,7 @@
final bool aot = options['aot'];
final bool syncAsync = options['sync-async'];
final bool tfa = options['tfa'];
+ final bool genBytecode = options['gen-bytecode'];
final List<String> entryPoints = options['entry-points'] ?? <String>[];
if (entryPoints.isEmpty) {
@@ -100,7 +104,10 @@
Component component = await compileToKernel(
Uri.base.resolveUri(new Uri.file(filename)), compilerOptions,
- aot: aot, useGlobalTypeFlowAnalysis: tfa, entryPoints: entryPoints);
+ aot: aot,
+ useGlobalTypeFlowAnalysis: tfa,
+ entryPoints: entryPoints,
+ genBytecode: genBytecode);
if (errorDetector.hasCompilationErrors || (component == null)) {
return _compileTimeErrorExitCode;
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
new file mode 100644
index 0000000..ac3b157
--- /dev/null
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -0,0 +1,921 @@
+// 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 vm.bytecode.assembler;
+
+import 'dart:typed_data';
+
+import 'package:vm/bytecode/dbc.dart';
+
+class Label {
+ List<int> _jumps = <int>[];
+ int offset = -1;
+
+ Label();
+
+ bool get isBound => offset >= 0;
+
+ int jumpOperand(int jumpOffset) {
+ if (isBound) {
+ // Jump instruction takes an offset in DBC words.
+ return (offset - jumpOffset) >> BytecodeAssembler.kLog2BytesPerBytecode;
+ }
+ _jumps.add(jumpOffset);
+ return 0;
+ }
+
+ List<int> bind(int offset) {
+ assert(!isBound);
+ this.offset = offset;
+ final jumps = _jumps;
+ _jumps = null;
+ return jumps;
+ }
+}
+
+class BytecodeAssembler {
+ static const int kBitsPerInt = 64;
+ static const int kLog2BytesPerBytecode = 2;
+
+ // TODO(alexmarkov): figure out more efficient storage for generated bytecode.
+ final List<int> bytecode = new List<int>();
+ final Uint32List _encodeBufferIn;
+ final Uint8List _encodeBufferOut;
+
+ BytecodeAssembler._(this._encodeBufferIn, this._encodeBufferOut);
+
+ factory BytecodeAssembler() {
+ final buf = new Uint32List(1);
+ return new BytecodeAssembler._(buf, new Uint8List.view(buf.buffer));
+ }
+
+ int get offset => bytecode.length;
+
+ void bind(Label label) {
+ final List<int> jumps = label.bind(offset);
+ for (int jumpOffset in jumps) {
+ patchJump(jumpOffset, label.jumpOperand(jumpOffset));
+ }
+ }
+
+ void emitWord(int word) {
+ _encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
+ bytecode.addAll(_encodeBufferOut);
+ }
+
+ void _setWord(int pos, int word) {
+ _encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
+ bytecode.setRange(pos, pos + _encodeBufferOut.length, _encodeBufferOut);
+ }
+
+ int _unsigned(int v, int bits) {
+ assert(bits < kBitsPerInt);
+ final int mask = (1 << bits) - 1;
+ if ((v & mask) != v) {
+ throw 'Value $v is out of unsigned $bits-bit range';
+ }
+ return v;
+ }
+
+ int _signed(int v, int bits) {
+ assert(bits < kBitsPerInt);
+ final int shift = kBitsPerInt - bits;
+ if (((v << shift) >> shift) != v) {
+ throw 'Value $v is out of signed $bits-bit range';
+ }
+ final int mask = (1 << bits) - 1;
+ return v & mask;
+ }
+
+ int _uint8(int v) => _unsigned(v, 8);
+ int _uint16(int v) => _unsigned(v, 16);
+
+ int _int8(int v) => _signed(v, 8);
+ int _int16(int v) => _signed(v, 16);
+ int _int24(int v) => _signed(v, 24);
+
+ int _encode0(Opcode opcode) => _uint8(opcode.index);
+
+ int _encodeA(Opcode opcode, int ra) =>
+ _uint8(opcode.index) | (_uint8(ra) << 8);
+
+ int _encodeAD(Opcode opcode, int ra, int rd) =>
+ _uint8(opcode.index) | (_uint8(ra) << 8) | (_uint16(rd) << 16);
+
+ int _encodeAX(Opcode opcode, int ra, int rx) =>
+ _uint8(opcode.index) | (_uint8(ra) << 8) | (_int16(rx) << 16);
+
+ int _encodeD(Opcode opcode, int rd) =>
+ _uint8(opcode.index) | (_uint16(rd) << 16);
+
+ int _encodeX(Opcode opcode, int rx) =>
+ _uint8(opcode.index) | (_int16(rx) << 16);
+
+ int _encodeABC(Opcode opcode, int ra, int rb, int rc) =>
+ _uint8(opcode.index) |
+ (_uint8(ra) << 8) |
+ (_uint8(rb) << 16) |
+ (_uint8(rc) << 24);
+
+ int _encodeABY(Opcode opcode, int ra, int rb, int ry) =>
+ _uint8(opcode.index) |
+ (_uint8(ra) << 8) |
+ (_uint8(rb) << 16) |
+ (_int8(ry) << 24);
+
+ int _encodeT(Opcode opcode, int rt) =>
+ _uint8(opcode.index) | (_int24(rt) << 8);
+
+ void emitTrap() {
+ emitWord(_encode0(Opcode.kTrap));
+ }
+
+ void emitNop(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kNop, ra, rd));
+ }
+
+ void emitCompile() {
+ emitWord(_encode0(Opcode.kCompile));
+ }
+
+ void emitHotCheck(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kHotCheck, ra, rd));
+ }
+
+ void emitIntrinsic(int ra) {
+ emitWord(_encodeA(Opcode.kIntrinsic, ra));
+ }
+
+ void emitDrop1() {
+ emitWord(_encode0(Opcode.kDrop1));
+ }
+
+ void emitDropR(int ra) {
+ emitWord(_encodeA(Opcode.kDropR, ra));
+ }
+
+ void emitDrop(int ra) {
+ emitWord(_encodeA(Opcode.kDrop, ra));
+ }
+
+ void emitJump(Label label) {
+ emitWord(_encodeT(Opcode.kJump, label.jumpOperand(offset)));
+ }
+
+ void patchJump(int pos, int rt) {
+ _setWord(pos, _encodeT(Opcode.kJump, rt));
+ }
+
+ void emitReturn(int ra) {
+ emitWord(_encodeA(Opcode.kReturn, ra));
+ }
+
+ void emitReturnTOS() {
+ emitWord(_encode0(Opcode.kReturnTOS));
+ }
+
+ void emitMove(int ra, int rx) {
+ emitWord(_encodeAX(Opcode.kMove, ra, rx));
+ }
+
+ void emitSwap(int ra, int rx) {
+ emitWord(_encodeAX(Opcode.kSwap, ra, rx));
+ }
+
+ void emitPush(int rx) {
+ emitWord(_encodeX(Opcode.kPush, rx));
+ }
+
+ void emitLoadConstant(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kLoadConstant, ra, rd));
+ }
+
+ void emitLoadClassId(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kLoadClassId, ra, rd));
+ }
+
+ void emitLoadClassIdTOS() {
+ emitWord(_encode0(Opcode.kLoadClassIdTOS));
+ }
+
+ void emitPushConstant(int rd) {
+ emitWord(_encodeD(Opcode.kPushConstant, rd));
+ }
+
+ void emitStoreLocal(int rx) {
+ emitWord(_encodeX(Opcode.kStoreLocal, rx));
+ }
+
+ void emitPopLocal(int rx) {
+ emitWord(_encodeX(Opcode.kPopLocal, rx));
+ }
+
+ void emitIndirectStaticCall(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIndirectStaticCall, ra, rd));
+ }
+
+ void emitStaticCall(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kStaticCall, ra, rd));
+ }
+
+ void emitInstanceCall1(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kInstanceCall1, ra, rd));
+ }
+
+ void emitInstanceCall2(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kInstanceCall2, ra, rd));
+ }
+
+ void emitInstanceCall1Opt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kInstanceCall1Opt, ra, rd));
+ }
+
+ void emitInstanceCall2Opt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kInstanceCall2Opt, ra, rd));
+ }
+
+ void emitPushPolymorphicInstanceCall(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kPushPolymorphicInstanceCall, ra, rd));
+ }
+
+ void emitPushPolymorphicInstanceCallByRange(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kPushPolymorphicInstanceCallByRange, ra, rd));
+ }
+
+ void emitNativeCall(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kNativeCall, ra, rb, rc));
+ }
+
+ void emitOneByteStringFromCharCode(int ra, int rx) {
+ emitWord(_encodeAX(Opcode.kOneByteStringFromCharCode, ra, rx));
+ }
+
+ void emitStringToCharCode(int ra, int rx) {
+ emitWord(_encodeAX(Opcode.kStringToCharCode, ra, rx));
+ }
+
+ void emitAddTOS() {
+ emitWord(_encode0(Opcode.kAddTOS));
+ }
+
+ void emitSubTOS() {
+ emitWord(_encode0(Opcode.kSubTOS));
+ }
+
+ void emitMulTOS() {
+ emitWord(_encode0(Opcode.kMulTOS));
+ }
+
+ void emitBitOrTOS() {
+ emitWord(_encode0(Opcode.kBitOrTOS));
+ }
+
+ void emitBitAndTOS() {
+ emitWord(_encode0(Opcode.kBitAndTOS));
+ }
+
+ void emitEqualTOS() {
+ emitWord(_encode0(Opcode.kEqualTOS));
+ }
+
+ void emitLessThanTOS() {
+ emitWord(_encode0(Opcode.kLessThanTOS));
+ }
+
+ void emitGreaterThanTOS() {
+ emitWord(_encode0(Opcode.kGreaterThanTOS));
+ }
+
+ void emitSmiAddTOS() {
+ emitWord(_encode0(Opcode.kSmiAddTOS));
+ }
+
+ void emitSmiSubTOS() {
+ emitWord(_encode0(Opcode.kSmiSubTOS));
+ }
+
+ void emitSmiMulTOS() {
+ emitWord(_encode0(Opcode.kSmiMulTOS));
+ }
+
+ void emitSmiBitAndTOS() {
+ emitWord(_encode0(Opcode.kSmiBitAndTOS));
+ }
+
+ void emitAdd(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kAdd, ra, rb, rc));
+ }
+
+ void emitSub(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kSub, ra, rb, rc));
+ }
+
+ void emitMul(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kMul, ra, rb, rc));
+ }
+
+ void emitDiv(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDiv, ra, rb, rc));
+ }
+
+ void emitMod(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kMod, ra, rb, rc));
+ }
+
+ void emitShl(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kShl, ra, rb, rc));
+ }
+
+ void emitShr(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kShr, ra, rb, rc));
+ }
+
+ void emitShlImm(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kShlImm, ra, rb, rc));
+ }
+
+ void emitNeg(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kNeg, ra, rd));
+ }
+
+ void emitBitOr(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kBitOr, ra, rb, rc));
+ }
+
+ void emitBitAnd(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kBitAnd, ra, rb, rc));
+ }
+
+ void emitBitXor(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kBitXor, ra, rb, rc));
+ }
+
+ void emitBitNot(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kBitNot, ra, rd));
+ }
+
+ void emitMin(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kMin, ra, rb, rc));
+ }
+
+ void emitMax(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kMax, ra, rb, rc));
+ }
+
+ void emitWriteIntoDouble(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kWriteIntoDouble, ra, rd));
+ }
+
+ void emitUnboxDouble(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kUnboxDouble, ra, rd));
+ }
+
+ void emitCheckedUnboxDouble(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kCheckedUnboxDouble, ra, rd));
+ }
+
+ void emitUnboxInt32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kUnboxInt32, ra, rb, rc));
+ }
+
+ void emitBoxInt32(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kBoxInt32, ra, rd));
+ }
+
+ void emitBoxUint32(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kBoxUint32, ra, rd));
+ }
+
+ void emitSmiToDouble(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kSmiToDouble, ra, rd));
+ }
+
+ void emitDoubleToSmi(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDoubleToSmi, ra, rd));
+ }
+
+ void emitDAdd(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDAdd, ra, rb, rc));
+ }
+
+ void emitDSub(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDSub, ra, rb, rc));
+ }
+
+ void emitDMul(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDMul, ra, rb, rc));
+ }
+
+ void emitDDiv(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDDiv, ra, rb, rc));
+ }
+
+ void emitDNeg(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDNeg, ra, rd));
+ }
+
+ void emitDSqrt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDSqrt, ra, rd));
+ }
+
+ void emitDMin(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDMin, ra, rb, rc));
+ }
+
+ void emitDMax(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDMax, ra, rb, rc));
+ }
+
+ void emitDCos(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDCos, ra, rd));
+ }
+
+ void emitDSin(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDSin, ra, rd));
+ }
+
+ void emitDPow(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDPow, ra, rb, rc));
+ }
+
+ void emitDMod(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kDMod, ra, rb, rc));
+ }
+
+ void emitDTruncate(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDTruncate, ra, rd));
+ }
+
+ void emitDFloor(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDFloor, ra, rd));
+ }
+
+ void emitDCeil(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDCeil, ra, rd));
+ }
+
+ void emitDoubleToFloat(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDoubleToFloat, ra, rd));
+ }
+
+ void emitFloatToDouble(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kFloatToDouble, ra, rd));
+ }
+
+ void emitDoubleIsNaN(int ra) {
+ emitWord(_encodeA(Opcode.kDoubleIsNaN, ra));
+ }
+
+ void emitDoubleIsInfinite(int ra) {
+ emitWord(_encodeA(Opcode.kDoubleIsInfinite, ra));
+ }
+
+ void emitStoreStaticTOS(int rd) {
+ emitWord(_encodeD(Opcode.kStoreStaticTOS, rd));
+ }
+
+ void emitPushStatic(int rd) {
+ emitWord(_encodeD(Opcode.kPushStatic, rd));
+ }
+
+ void emitInitStaticTOS() {
+ emitWord(_encode0(Opcode.kInitStaticTOS));
+ }
+
+ void emitIfNeStrictTOS() {
+ emitWord(_encode0(Opcode.kIfNeStrictTOS));
+ }
+
+ void emitIfEqStrictTOS() {
+ emitWord(_encode0(Opcode.kIfEqStrictTOS));
+ }
+
+ void emitIfNeStrictNumTOS() {
+ emitWord(_encode0(Opcode.kIfNeStrictNumTOS));
+ }
+
+ void emitIfEqStrictNumTOS() {
+ emitWord(_encode0(Opcode.kIfEqStrictNumTOS));
+ }
+
+ void emitIfSmiLtTOS() {
+ emitWord(_encode0(Opcode.kIfSmiLtTOS));
+ }
+
+ void emitIfSmiLeTOS() {
+ emitWord(_encode0(Opcode.kIfSmiLeTOS));
+ }
+
+ void emitIfSmiGeTOS() {
+ emitWord(_encode0(Opcode.kIfSmiGeTOS));
+ }
+
+ void emitIfSmiGtTOS() {
+ emitWord(_encode0(Opcode.kIfSmiGtTOS));
+ }
+
+ void emitIfNeStrict(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfNeStrict, ra, rd));
+ }
+
+ void emitIfEqStrict(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfEqStrict, ra, rd));
+ }
+
+ void emitIfLe(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfLe, ra, rd));
+ }
+
+ void emitIfLt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfLt, ra, rd));
+ }
+
+ void emitIfGe(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfGe, ra, rd));
+ }
+
+ void emitIfGt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfGt, ra, rd));
+ }
+
+ void emitIfULe(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfULe, ra, rd));
+ }
+
+ void emitIfULt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfULt, ra, rd));
+ }
+
+ void emitIfUGe(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfUGe, ra, rd));
+ }
+
+ void emitIfUGt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfUGt, ra, rd));
+ }
+
+ void emitIfDNe(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfDNe, ra, rd));
+ }
+
+ void emitIfDEq(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfDEq, ra, rd));
+ }
+
+ void emitIfDLe(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfDLe, ra, rd));
+ }
+
+ void emitIfDLt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfDLt, ra, rd));
+ }
+
+ void emitIfDGe(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfDGe, ra, rd));
+ }
+
+ void emitIfDGt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfDGt, ra, rd));
+ }
+
+ void emitIfNeStrictNum(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfNeStrictNum, ra, rd));
+ }
+
+ void emitIfEqStrictNum(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kIfEqStrictNum, ra, rd));
+ }
+
+ void emitIfEqNull(int ra) {
+ emitWord(_encodeA(Opcode.kIfEqNull, ra));
+ }
+
+ void emitIfNeNull(int ra) {
+ emitWord(_encodeA(Opcode.kIfNeNull, ra));
+ }
+
+ void emitCreateArrayTOS() {
+ emitWord(_encode0(Opcode.kCreateArrayTOS));
+ }
+
+ void emitCreateArrayOpt(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kCreateArrayOpt, ra, rb, rc));
+ }
+
+ void emitAllocate(int rd) {
+ emitWord(_encodeD(Opcode.kAllocate, rd));
+ }
+
+ void emitAllocateT() {
+ emitWord(_encode0(Opcode.kAllocateT));
+ }
+
+ void emitAllocateOpt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kAllocateOpt, ra, rd));
+ }
+
+ void emitAllocateTOpt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kAllocateTOpt, ra, rd));
+ }
+
+ void emitStoreIndexedTOS() {
+ emitWord(_encode0(Opcode.kStoreIndexedTOS));
+ }
+
+ void emitStoreIndexed(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexed, ra, rb, rc));
+ }
+
+ void emitStoreIndexedUint8(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexedUint8, ra, rb, rc));
+ }
+
+ void emitStoreIndexedExternalUint8(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexedExternalUint8, ra, rb, rc));
+ }
+
+ void emitStoreIndexedOneByteString(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexedOneByteString, ra, rb, rc));
+ }
+
+ void emitStoreIndexedUint32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexedUint32, ra, rb, rc));
+ }
+
+ void emitStoreIndexedFloat32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexedFloat32, ra, rb, rc));
+ }
+
+ void emitStoreIndexed4Float32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexed4Float32, ra, rb, rc));
+ }
+
+ void emitStoreIndexedFloat64(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexedFloat64, ra, rb, rc));
+ }
+
+ void emitStoreIndexed8Float64(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreIndexed8Float64, ra, rb, rc));
+ }
+
+ void emitNoSuchMethod() {
+ emitWord(_encode0(Opcode.kNoSuchMethod));
+ }
+
+ void emitTailCall() {
+ emitWord(_encode0(Opcode.kTailCall));
+ }
+
+ void emitTailCallOpt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kTailCallOpt, ra, rd));
+ }
+
+ void emitLoadArgDescriptor() {
+ emitWord(_encode0(Opcode.kLoadArgDescriptor));
+ }
+
+ void emitLoadArgDescriptorOpt(int ra) {
+ emitWord(_encodeA(Opcode.kLoadArgDescriptorOpt, ra));
+ }
+
+ void emitLoadFpRelativeSlot(int rx) {
+ emitWord(_encodeX(Opcode.kLoadFpRelativeSlot, rx));
+ }
+
+ void emitLoadFpRelativeSlotOpt(int ra, int rb, int ry) {
+ emitWord(_encodeABY(Opcode.kLoadFpRelativeSlotOpt, ra, rb, ry));
+ }
+
+ void emitStoreFpRelativeSlot(int rx) {
+ emitWord(_encodeX(Opcode.kStoreFpRelativeSlot, rx));
+ }
+
+ void emitStoreFpRelativeSlotOpt(int ra, int rb, int ry) {
+ emitWord(_encodeABY(Opcode.kStoreFpRelativeSlotOpt, ra, rb, ry));
+ }
+
+ void emitLoadIndexedTOS() {
+ emitWord(_encode0(Opcode.kLoadIndexedTOS));
+ }
+
+ void emitLoadIndexed(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexed, ra, rb, rc));
+ }
+
+ void emitLoadIndexedUint8(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedUint8, ra, rb, rc));
+ }
+
+ void emitLoadIndexedInt8(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedInt8, ra, rb, rc));
+ }
+
+ void emitLoadIndexedInt32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedInt32, ra, rb, rc));
+ }
+
+ void emitLoadIndexedUint32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedUint32, ra, rb, rc));
+ }
+
+ void emitLoadIndexedExternalUint8(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedExternalUint8, ra, rb, rc));
+ }
+
+ void emitLoadIndexedExternalInt8(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedExternalInt8, ra, rb, rc));
+ }
+
+ void emitLoadIndexedFloat32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedFloat32, ra, rb, rc));
+ }
+
+ void emitLoadIndexed4Float32(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexed4Float32, ra, rb, rc));
+ }
+
+ void emitLoadIndexedFloat64(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedFloat64, ra, rb, rc));
+ }
+
+ void emitLoadIndexed8Float64(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexed8Float64, ra, rb, rc));
+ }
+
+ void emitLoadIndexedOneByteString(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedOneByteString, ra, rb, rc));
+ }
+
+ void emitLoadIndexedTwoByteString(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadIndexedTwoByteString, ra, rb, rc));
+ }
+
+ void emitStoreField(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kStoreField, ra, rb, rc));
+ }
+
+ void emitStoreFieldExt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kStoreFieldExt, ra, rd));
+ }
+
+ void emitStoreFieldTOS(int rd) {
+ emitWord(_encodeD(Opcode.kStoreFieldTOS, rd));
+ }
+
+ void emitLoadField(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadField, ra, rb, rc));
+ }
+
+ void emitLoadFieldExt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kLoadFieldExt, ra, rd));
+ }
+
+ void emitLoadUntagged(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kLoadUntagged, ra, rb, rc));
+ }
+
+ void emitLoadFieldTOS(int rd) {
+ emitWord(_encodeD(Opcode.kLoadFieldTOS, rd));
+ }
+
+ void emitBooleanNegateTOS() {
+ emitWord(_encode0(Opcode.kBooleanNegateTOS));
+ }
+
+ void emitBooleanNegate(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kBooleanNegate, ra, rd));
+ }
+
+ void emitThrow(int ra) {
+ emitWord(_encodeA(Opcode.kThrow, ra));
+ }
+
+ void emitEntry(int rd) {
+ emitWord(_encodeD(Opcode.kEntry, rd));
+ }
+
+ void emitEntryOptimized(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kEntryOptimized, ra, rd));
+ }
+
+ void emitFrame(int rd) {
+ emitWord(_encodeD(Opcode.kFrame, rd));
+ }
+
+ void emitSetFrame(int ra) {
+ emitWord(_encodeA(Opcode.kSetFrame, ra));
+ }
+
+ void emitAllocateContext(int rd) {
+ emitWord(_encodeD(Opcode.kAllocateContext, rd));
+ }
+
+ void emitAllocateUninitializedContext(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kAllocateUninitializedContext, ra, rd));
+ }
+
+ void emitCloneContext() {
+ emitWord(_encode0(Opcode.kCloneContext));
+ }
+
+ void emitMoveSpecial(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kMoveSpecial, ra, rd));
+ }
+
+ void emitInstantiateType(int rd) {
+ emitWord(_encodeD(Opcode.kInstantiateType, rd));
+ }
+
+ void emitInstantiateTypeArgumentsTOS(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kInstantiateTypeArgumentsTOS, ra, rd));
+ }
+
+ void emitInstanceOf() {
+ emitWord(_encode0(Opcode.kInstanceOf));
+ }
+
+ void emitBadTypeError() {
+ emitWord(_encode0(Opcode.kBadTypeError));
+ }
+
+ void emitAssertAssignable(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kAssertAssignable, ra, rd));
+ }
+
+ void emitAssertSubtype() {
+ emitWord(_encode0(Opcode.kAssertSubtype));
+ }
+
+ void emitAssertBoolean(int ra) {
+ emitWord(_encodeA(Opcode.kAssertBoolean, ra));
+ }
+
+ void emitTestSmi(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kTestSmi, ra, rd));
+ }
+
+ void emitTestCids(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kTestCids, ra, rd));
+ }
+
+ void emitCheckSmi(int ra) {
+ emitWord(_encodeA(Opcode.kCheckSmi, ra));
+ }
+
+ void emitCheckEitherNonSmi(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kCheckEitherNonSmi, ra, rd));
+ }
+
+ void emitCheckClassId(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kCheckClassId, ra, rd));
+ }
+
+ void emitCheckClassIdRange(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kCheckClassIdRange, ra, rd));
+ }
+
+ void emitCheckBitTest(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kCheckBitTest, ra, rd));
+ }
+
+ void emitCheckCids(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kCheckCids, ra, rb, rc));
+ }
+
+ void emitCheckCidsByRange(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kCheckCidsByRange, ra, rb, rc));
+ }
+
+ void emitCheckStack() {
+ emitWord(_encode0(Opcode.kCheckStack));
+ }
+
+ void emitCheckStackAlwaysExit() {
+ emitWord(_encode0(Opcode.kCheckStackAlwaysExit));
+ }
+
+ void emitCheckFunctionTypeArgs(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kCheckFunctionTypeArgs, ra, rd));
+ }
+
+ void emitDebugStep() {
+ emitWord(_encode0(Opcode.kDebugStep));
+ }
+
+ void emitDebugBreak(int ra) {
+ emitWord(_encodeA(Opcode.kDebugBreak, ra));
+ }
+
+ void emitDeopt(int ra, int rd) {
+ emitWord(_encodeAD(Opcode.kDeopt, ra, rd));
+ }
+
+ void emitDeoptRewind() {
+ emitWord(_encode0(Opcode.kDeoptRewind));
+ }
+
+ void emitEntryOptional(int ra, int rb, int rc) {
+ emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc));
+ }
+}
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
new file mode 100644
index 0000000..770ff55
--- /dev/null
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -0,0 +1,840 @@
+// 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 vm.bytecode.constant_pool;
+
+import 'dart:typed_data';
+
+import 'package:kernel/ast.dart' hide MapEntry;
+
+/*
+
+In kernel binary, constant pool is encoded in the following way
+(using notation from pkg/kernel/binary.md):
+
+type ConstantPool {
+ List<ConstantPoolEntry>
+}
+
+abstract type ConstantPoolEntry {
+ Byte tag;
+}
+
+type ConstantNull extends ConstantPoolEntry {
+ Byte tag = 1;
+}
+
+type ConstantString extends ConstantPoolEntry {
+ Byte tag = 2;
+ StringReference value;
+}
+
+type ConstantInt extends ConstantPoolEntry {
+ Byte tag = 3;
+ UInt32 low;
+ UInt32 high;
+}
+
+type ConstantDouble extends ConstantPoolEntry {
+ Byte tag = 4;
+ UInt32 low;
+ UInt32 high;
+}
+
+type ConstantBool extends ConstantPoolEntry {
+ Byte tag = 5;
+ UInt flag;
+}
+
+type ConstantArgDesc extends ConstantPoolEntry {
+ Byte tag = 6;
+ UInt numArguments;
+ UInt numTypeArgs;
+ List<StringReference> names;
+}
+
+type ConstantICData extends ConstantPoolEntry {
+ Byte tag = 7;
+ StringReference targetName;
+ UInt argDescConstantIndex;
+}
+
+type ConstantStaticICData extends ConstantPoolEntry {
+ Byte tag = 8;
+ CanonicalNameReference target;
+ UInt argDescConstantIndex;
+}
+
+type ConstantField extends ConstantPoolEntry {
+ Byte tag = 9;
+ CanonicalNameReference field;
+}
+
+type ConstantFieldOffset extends ConstantPoolEntry {
+ Byte tag = 10;
+ CanonicalNameReference field;
+}
+
+type ConstantClass extends ConstantPoolEntry {
+ Byte tag = 11;
+ CanonicalNameReference class;
+}
+
+type ConstantTypeArgumentsFieldOffset extends ConstantPoolEntry {
+ Byte tag = 12;
+ CanonicalNameReference class;
+}
+
+type ConstantTearOff extends ConstantPoolEntry {
+ Byte tag = 13;
+ CanonicalNameReference target;
+}
+
+type ConstantType extends ConstantPoolEntry {
+ Byte tag = 14;
+ NodeReference type;
+}
+
+type ConstantTypeArguments extends ConstantPoolEntry {
+ Byte tag = 15;
+ List<NodeReference> types;
+}
+
+type ConstantList extends ConstantPoolEntry {
+ Byte tag = 16;
+ NodeReference typeArg;
+ List<UInt> entries;
+}
+
+type ConstantInstance extends ConstantPoolEntry {
+ Byte tag = 17;
+ CanonicalNameReference class;
+ UInt typeArgumentsConstantIndex;
+ List<Pair<CanonicalNameReference, UInt>> fieldValues;
+}
+
+type ConstantSymbol extends ConstantPoolEntry {
+ Byte tag = 18;
+ StringReference value;
+}
+
+*/
+
+enum ConstantTag {
+ kInvalid,
+ kNull,
+ kString,
+ kInt,
+ kDouble,
+ kBool,
+ kArgDesc,
+ kICData,
+ kStaticICData,
+ kField,
+ kFieldOffset,
+ kClass,
+ kTypeArgumentsFieldOffset,
+ kTearOff,
+ kType,
+ kTypeArguments,
+ kList,
+ kInstance,
+ kSymbol,
+}
+
+abstract class ConstantPoolEntry {
+ const ConstantPoolEntry();
+
+ ConstantTag get tag;
+
+ void writeToBinary(BinarySink sink) {
+ sink.writeUInt30(tag.index);
+ writeValueToBinary(sink);
+ }
+
+ void writeValueToBinary(BinarySink sink);
+
+ factory ConstantPoolEntry.readFromBinary(BinarySource source) {
+ ConstantTag tag = ConstantTag.values[source.readUInt()];
+ switch (tag) {
+ case ConstantTag.kInvalid:
+ break;
+ case ConstantTag.kNull:
+ return new ConstantNull.readFromBinary(source);
+ case ConstantTag.kString:
+ return new ConstantString.readFromBinary(source);
+ case ConstantTag.kInt:
+ return new ConstantInt.readFromBinary(source);
+ case ConstantTag.kDouble:
+ return new ConstantDouble.readFromBinary(source);
+ case ConstantTag.kBool:
+ return new ConstantBool.readFromBinary(source);
+ case ConstantTag.kICData:
+ return new ConstantICData.readFromBinary(source);
+ case ConstantTag.kStaticICData:
+ return new ConstantStaticICData.readFromBinary(source);
+ case ConstantTag.kArgDesc:
+ return new ConstantArgDesc.readFromBinary(source);
+ case ConstantTag.kField:
+ return new ConstantField.readFromBinary(source);
+ case ConstantTag.kFieldOffset:
+ return new ConstantFieldOffset.readFromBinary(source);
+ case ConstantTag.kClass:
+ return new ConstantClass.readFromBinary(source);
+ case ConstantTag.kTypeArgumentsFieldOffset:
+ return new ConstantTypeArgumentsFieldOffset.readFromBinary(source);
+ case ConstantTag.kTearOff:
+ return new ConstantTearOff.readFromBinary(source);
+ case ConstantTag.kType:
+ return new ConstantType.readFromBinary(source);
+ case ConstantTag.kTypeArguments:
+ return new ConstantTypeArguments.readFromBinary(source);
+ case ConstantTag.kList:
+ return new ConstantList.readFromBinary(source);
+ case ConstantTag.kInstance:
+ return new ConstantInstance.readFromBinary(source);
+ case ConstantTag.kSymbol:
+ return new ConstantSymbol.readFromBinary(source);
+ }
+ throw 'Unexpected constant tag $tag';
+ }
+}
+
+class ConstantNull extends ConstantPoolEntry {
+ const ConstantNull();
+
+ @override
+ ConstantTag get tag => ConstantTag.kNull;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {}
+
+ ConstantNull.readFromBinary(BinarySource source);
+
+ @override
+ String toString() => 'Null';
+
+ @override
+ int get hashCode => 1961;
+
+ @override
+ bool operator ==(other) => other is ConstantNull;
+}
+
+class ConstantString extends ConstantPoolEntry {
+ final String value;
+
+ ConstantString(this.value);
+ ConstantString.fromLiteral(StringLiteral literal) : this(literal.value);
+
+ @override
+ ConstantTag get tag => ConstantTag.kString;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeStringReference(value);
+ }
+
+ ConstantString.readFromBinary(BinarySource source)
+ : value = source.readStringReference();
+
+ @override
+ String toString() => 'String \'$value\'';
+
+ @override
+ int get hashCode => value.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantString && this.value == other.value;
+}
+
+class ConstantInt extends ConstantPoolEntry {
+ final int value;
+
+ ConstantInt(this.value);
+ ConstantInt.fromLiteral(IntLiteral literal) : this(literal.value);
+
+ @override
+ ConstantTag get tag => ConstantTag.kInt;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ // TODO(alexmarkov): more efficient encoding
+ sink.writeUInt32(value & 0xffffffff);
+ sink.writeUInt32((value >> 32) & 0xffffffff);
+ }
+
+ ConstantInt.readFromBinary(BinarySource source)
+ : value = source.readUint32() | (source.readUint32() << 32);
+
+ @override
+ String toString() => 'Int $value';
+
+ @override
+ int get hashCode => value;
+
+ @override
+ bool operator ==(other) => other is ConstantInt && this.value == other.value;
+}
+
+class ConstantDouble extends ConstantPoolEntry {
+ final double value;
+
+ ConstantDouble(this.value);
+ ConstantDouble.fromLiteral(DoubleLiteral literal) : this(literal.value);
+
+ @override
+ ConstantTag get tag => ConstantTag.kDouble;
+
+ static int doubleToIntBits(double value) {
+ final buf = new ByteData(8);
+ buf.setFloat64(0, value, Endian.host);
+ return buf.getInt64(0, Endian.host);
+ }
+
+ static double intBitsToDouble(int bits) {
+ final buf = new ByteData(8);
+ buf.setInt64(0, bits, Endian.host);
+ return buf.getFloat64(0, Endian.host);
+ }
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ // TODO(alexmarkov): more efficient encoding
+ int bits = doubleToIntBits(value);
+ sink.writeUInt32(bits & 0xffffffff);
+ sink.writeUInt32((bits >> 32) & 0xffffffff);
+ }
+
+ ConstantDouble.readFromBinary(BinarySource source)
+ : value =
+ intBitsToDouble(source.readUint32() | (source.readUint32() << 32));
+
+ @override
+ String toString() => 'Double $value';
+
+ @override
+ int get hashCode => value.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantDouble && value.compareTo(other.value) == 0;
+}
+
+class ConstantBool extends ConstantPoolEntry {
+ final bool value;
+
+ ConstantBool(this.value);
+ ConstantBool.fromLiteral(BoolLiteral literal) : this(literal.value);
+
+ @override
+ ConstantTag get tag => ConstantTag.kBool;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeUInt30(value ? 1 : 0);
+ }
+
+ ConstantBool.readFromBinary(BinarySource source)
+ : value = source.readUInt() != 0;
+
+ @override
+ String toString() => 'Bool $value';
+
+ @override
+ int get hashCode => value.hashCode;
+
+ @override
+ bool operator ==(other) => other is ConstantBool && this.value == other.value;
+}
+
+class ConstantArgDesc extends ConstantPoolEntry {
+ final int numArguments;
+ final int numTypeArgs;
+ final List<String> argNames;
+
+ ConstantArgDesc(this.numArguments,
+ {this.numTypeArgs = 0, this.argNames = const <String>[]});
+
+ ConstantArgDesc.fromArguments(Arguments args, {bool hasReceiver: false})
+ : this(args.positional.length + args.named.length + (hasReceiver ? 1 : 0),
+ numTypeArgs: args.types.length,
+ argNames: new List<String>.from(args.named.map((ne) => ne.name)));
+
+ @override
+ ConstantTag get tag => ConstantTag.kArgDesc;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeUInt30(numArguments);
+ sink.writeUInt30(numTypeArgs);
+ sink.writeUInt30(argNames.length);
+ argNames.forEach(sink.writeStringReference);
+ }
+
+ ConstantArgDesc.readFromBinary(BinarySource source)
+ : numArguments = source.readUInt(),
+ numTypeArgs = source.readUInt(),
+ argNames = new List<String>.generate(
+ source.readUInt(), (_) => source.readStringReference());
+
+ @override
+ String toString() =>
+ 'ArgDesc num-args $numArguments, num-type-args $numTypeArgs, names $argNames';
+
+ @override
+ int get hashCode =>
+ (numArguments * 31 + numTypeArgs) * 31 + listHashCode(argNames);
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantArgDesc &&
+ this.numArguments == other.numArguments &&
+ this.numTypeArgs == other.numTypeArgs &&
+ listEquals(this.argNames, other.argNames);
+}
+
+class ConstantICData extends ConstantPoolEntry {
+ final String targetName;
+ final int argDescConstantIndex;
+
+ ConstantICData(this.targetName, this.argDescConstantIndex);
+
+ @override
+ ConstantTag get tag => ConstantTag.kICData;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeStringReference(targetName);
+ sink.writeUInt30(argDescConstantIndex);
+ }
+
+ ConstantICData.readFromBinary(BinarySource source)
+ : targetName = source.readStringReference(),
+ argDescConstantIndex = source.readUInt();
+
+ @override
+ String toString() =>
+ 'ICData target-name \'$targetName\', arg-desc CP#$argDescConstantIndex';
+
+ // ConstantICData entries are created per call site and should not be merged,
+ // so ConstantICData class uses identity [hashCode] and [operator ==].
+
+ @override
+ int get hashCode => identityHashCode(this);
+
+ @override
+ bool operator ==(other) => identical(this, other);
+}
+
+class ConstantStaticICData extends ConstantPoolEntry {
+ final Reference _reference;
+ final int argDescConstantIndex;
+
+ ConstantStaticICData(Member member, int argDescConstantIndex)
+ : this.byReference(member.reference, argDescConstantIndex);
+ ConstantStaticICData.byReference(this._reference, this.argDescConstantIndex);
+
+ Member get target => _reference.asMember;
+
+ @override
+ ConstantTag get tag => ConstantTag.kStaticICData;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeCanonicalNameReference(getCanonicalNameOfMember(target));
+ sink.writeUInt30(argDescConstantIndex);
+ }
+
+ ConstantStaticICData.readFromBinary(BinarySource source)
+ : _reference = source.readCanonicalNameReference().getReference(),
+ argDescConstantIndex = source.readUInt();
+
+ @override
+ String toString() =>
+ 'StaticICData target \'$target\', arg-desc CP#$argDescConstantIndex';
+
+ // ConstantStaticICData entries are created per call site and should not be
+ // merged, so ConstantStaticICData class uses identity [hashCode] and
+ // [operator ==].
+
+ @override
+ int get hashCode => identityHashCode(this);
+
+ @override
+ bool operator ==(other) => identical(this, other);
+}
+
+class ConstantField extends ConstantPoolEntry {
+ final Reference _reference;
+
+ Field get field => _reference.asField;
+
+ ConstantField(Field field) : this.byReference(field.reference);
+ ConstantField.byReference(this._reference);
+
+ @override
+ ConstantTag get tag => ConstantTag.kField;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeCanonicalNameReference(getCanonicalNameOfMember(field));
+ }
+
+ ConstantField.readFromBinary(BinarySource source)
+ : _reference = source.readCanonicalNameReference().getReference();
+
+ @override
+ String toString() => 'Field $field';
+
+ @override
+ int get hashCode => field.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantField && this.field == other.field;
+}
+
+class ConstantFieldOffset extends ConstantPoolEntry {
+ final Reference _reference;
+
+ Field get field => _reference.asField;
+
+ ConstantFieldOffset(Field field) : this.byReference(field.reference);
+ ConstantFieldOffset.byReference(this._reference);
+
+ @override
+ ConstantTag get tag => ConstantTag.kFieldOffset;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeCanonicalNameReference(getCanonicalNameOfMember(field));
+ }
+
+ ConstantFieldOffset.readFromBinary(BinarySource source)
+ : _reference = source.readCanonicalNameReference().getReference();
+
+ @override
+ String toString() => 'FieldOffset $field';
+
+ @override
+ int get hashCode => field.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantFieldOffset && this.field == other.field;
+}
+
+class ConstantClass extends ConstantPoolEntry {
+ final Reference _reference;
+
+ Class get classNode => _reference.asClass;
+
+ ConstantClass(Class class_) : this.byReference(class_.reference);
+ ConstantClass.byReference(this._reference);
+
+ @override
+ ConstantTag get tag => ConstantTag.kClass;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeCanonicalNameReference(getCanonicalNameOfClass(classNode));
+ }
+
+ ConstantClass.readFromBinary(BinarySource source)
+ : _reference = source.readCanonicalNameReference().getReference();
+
+ @override
+ String toString() => 'Class $classNode';
+
+ @override
+ int get hashCode => classNode.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantClass && this.classNode == other.classNode;
+}
+
+class ConstantTypeArgumentsFieldOffset extends ConstantPoolEntry {
+ final Reference _reference;
+
+ Class get classNode => _reference.asClass;
+
+ ConstantTypeArgumentsFieldOffset(Class class_)
+ : this.byReference(class_.reference);
+ ConstantTypeArgumentsFieldOffset.byReference(this._reference);
+
+ @override
+ ConstantTag get tag => ConstantTag.kTypeArgumentsFieldOffset;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeCanonicalNameReference(getCanonicalNameOfClass(classNode));
+ }
+
+ ConstantTypeArgumentsFieldOffset.readFromBinary(BinarySource source)
+ : _reference = source.readCanonicalNameReference().getReference();
+
+ @override
+ String toString() => 'TypeArgumentsFieldOffset $classNode';
+
+ @override
+ int get hashCode => classNode.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantTypeArgumentsFieldOffset &&
+ this.classNode == other.classNode;
+}
+
+class ConstantTearOff extends ConstantPoolEntry {
+ final Reference _reference;
+
+ Procedure get procedure => _reference.asProcedure;
+
+ ConstantTearOff(Procedure procedure) : this.byReference(procedure.reference);
+ ConstantTearOff.byReference(this._reference);
+
+ @override
+ ConstantTag get tag => ConstantTag.kTearOff;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeCanonicalNameReference(getCanonicalNameOfMember(procedure));
+ }
+
+ ConstantTearOff.readFromBinary(BinarySource source)
+ : _reference = source.readCanonicalNameReference().getReference();
+
+ @override
+ String toString() => 'TearOff $procedure';
+
+ @override
+ int get hashCode => procedure.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantTearOff && this.procedure == other.procedure;
+}
+
+class ConstantType extends ConstantPoolEntry {
+ final DartType type;
+
+ ConstantType(this.type);
+
+ @override
+ ConstantTag get tag => ConstantTag.kType;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeNodeReference(type);
+ }
+
+ ConstantType.readFromBinary(BinarySource source)
+ : type = source.readNodeReference() as DartType;
+
+ @override
+ String toString() => 'Type $type';
+
+ @override
+ int get hashCode => type.hashCode;
+
+ @override
+ bool operator ==(other) => other is ConstantType && this.type == other.type;
+}
+
+class ConstantTypeArguments extends ConstantPoolEntry {
+ final List<DartType> typeArgs;
+
+ ConstantTypeArguments(this.typeArgs);
+
+ @override
+ ConstantTag get tag => ConstantTag.kTypeArguments;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeUInt30(typeArgs.length);
+ typeArgs.forEach(sink.writeNodeReference);
+ }
+
+ ConstantTypeArguments.readFromBinary(BinarySource source)
+ : typeArgs = new List<DartType>.generate(
+ source.readUInt(), (_) => source.readNodeReference() as DartType);
+
+ @override
+ String toString() => 'TypeArgs $typeArgs';
+
+ @override
+ int get hashCode => listHashCode(typeArgs);
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantTypeArguments &&
+ listEquals(this.typeArgs, other.typeArgs);
+}
+
+class ConstantList extends ConstantPoolEntry {
+ final DartType typeArg;
+ final List<int> entries;
+
+ ConstantList(this.typeArg, this.entries);
+
+ @override
+ ConstantTag get tag => ConstantTag.kList;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeNodeReference(typeArg);
+ sink.writeUInt30(entries.length);
+ entries.forEach(sink.writeUInt30);
+ }
+
+ ConstantList.readFromBinary(BinarySource source)
+ : typeArg = source.readNodeReference() as DartType,
+ entries =
+ new List<int>.generate(source.readUInt(), (_) => source.readUInt());
+
+ @override
+ String toString() => 'List type-arg $typeArg, entries CP# $entries';
+
+ @override
+ int get hashCode => typeArg.hashCode ^ listHashCode(entries);
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantList &&
+ this.typeArg == other.typeArg &&
+ listEquals(this.entries, other.entries);
+}
+
+class ConstantInstance extends ConstantPoolEntry {
+ final Reference _classReference;
+ final int _typeArgumentsConstantIndex;
+ final Map<Reference, int> _fieldValues;
+
+ ConstantInstance(Class class_, int typeArgumentsConstantIndex,
+ Map<Reference, int> fieldValues)
+ : this.byReference(
+ class_.reference, typeArgumentsConstantIndex, fieldValues);
+
+ ConstantInstance.byReference(this._classReference,
+ this._typeArgumentsConstantIndex, this._fieldValues);
+
+ @override
+ ConstantTag get tag => ConstantTag.kInstance;
+
+ Class get classNode => _classReference.asClass;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeCanonicalNameReference(getCanonicalNameOfClass(classNode));
+ sink.writeUInt30(_typeArgumentsConstantIndex);
+ sink.writeUInt30(_fieldValues.length);
+ _fieldValues.forEach((Reference fieldRef, int valueIndex) {
+ sink.writeCanonicalNameReference(
+ getCanonicalNameOfMember(fieldRef.asField));
+ sink.writeUInt30(valueIndex);
+ });
+ }
+
+ ConstantInstance.readFromBinary(BinarySource source)
+ : _classReference = source.readCanonicalNameReference().getReference(),
+ _typeArgumentsConstantIndex = source.readUInt(),
+ _fieldValues = new Map<Reference, int>() {
+ final fieldValuesLen = source.readUInt();
+ for (int i = 0; i < fieldValuesLen; i++) {
+ final fieldRef = source.readCanonicalNameReference().getReference();
+ final valueIndex = source.readUInt();
+ _fieldValues[fieldRef] = valueIndex;
+ }
+ }
+
+ @override
+ String toString() =>
+ 'Instance $classNode type-args CP#$_typeArgumentsConstantIndex'
+ ' ${_fieldValues.map<String, int>((Reference fieldRef, int valueIndex) =>
+ new MapEntry(fieldRef.asField.name.name, valueIndex))}';
+
+ @override
+ int get hashCode =>
+ (classNode.hashCode * 31 + _typeArgumentsConstantIndex) * 31 +
+ mapHashCode(_fieldValues);
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantInstance &&
+ this.classNode == other.classNode &&
+ this._typeArgumentsConstantIndex == other._typeArgumentsConstantIndex &&
+ mapEquals(this._fieldValues, other._fieldValues);
+}
+
+class ConstantSymbol extends ConstantPoolEntry {
+ final String value;
+
+ ConstantSymbol(this.value);
+ ConstantSymbol.fromLiteral(SymbolLiteral literal) : this(literal.value);
+
+ @override
+ ConstantTag get tag => ConstantTag.kSymbol;
+
+ @override
+ void writeValueToBinary(BinarySink sink) {
+ sink.writeStringReference(value);
+ }
+
+ ConstantSymbol.readFromBinary(BinarySource source)
+ : value = source.readStringReference();
+
+ @override
+ String toString() => 'Symbol \'$value\'';
+
+ @override
+ int get hashCode => value.hashCode;
+
+ @override
+ bool operator ==(other) =>
+ other is ConstantSymbol && this.value == other.value;
+}
+
+class ConstantPool {
+ final List<ConstantPoolEntry> entries = <ConstantPoolEntry>[];
+ final Map<ConstantPoolEntry, int> _canonicalizationCache =
+ <ConstantPoolEntry, int>{};
+
+ ConstantPool();
+
+ int add(ConstantPoolEntry entry) {
+ return _canonicalizationCache.putIfAbsent(entry, () {
+ int index = entries.length;
+ entries.add(entry);
+ return index;
+ });
+ }
+
+ void writeToBinary(BinarySink sink) {
+ sink.writeUInt30(entries.length);
+ entries.forEach((e) {
+ e.writeToBinary(sink);
+ });
+ }
+
+ ConstantPool.readFromBinary(BinarySource source) {
+ int len = source.readUInt();
+ for (int i = 0; i < len; i++) {
+ entries.add(new ConstantPoolEntry.readFromBinary(source));
+ }
+ }
+
+ @override
+ String toString() {
+ StringBuffer sb = new StringBuffer();
+ sb.writeln('ConstantPool {');
+ for (int i = 0; i < entries.length; i++) {
+ sb.writeln(' [$i] = ${entries[i]}');
+ }
+ sb.writeln('}');
+ return sb.toString();
+ }
+}
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
new file mode 100644
index 0000000..17c68c3
--- /dev/null
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -0,0 +1,651 @@
+// 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 vm.bytecode.dbc;
+
+// List of changes from original DBC (described in runtime/vm/constants_dbc.h):
+//
+// 1. StoreFieldTOS, LoadFieldTOS instructions:
+// D = index of constant pool entry with FieldOffset or
+// TypeArgumentsFieldOffset tags (instead of field offset in words).
+//
+// 2. EntryOptional instruction is revived in order to re-shuffle optional
+// parameters. This DBC instruction was removed at
+// https://github.com/dart-lang/sdk/commit/cf1de7d46cd88e204380e8f96a993439be56b24c
+//
+
+enum Opcode {
+ kTrap,
+ kNop,
+ kCompile,
+ kHotCheck,
+ kIntrinsic,
+ kDrop1,
+ kDropR,
+ kDrop,
+ kJump,
+ kReturn,
+ kReturnTOS,
+ kMove,
+ kSwap,
+ kPush,
+ kLoadConstant,
+ kLoadClassId,
+ kLoadClassIdTOS,
+ kPushConstant,
+ kStoreLocal,
+ kPopLocal,
+ kIndirectStaticCall,
+ kStaticCall,
+ kInstanceCall1,
+ kInstanceCall2,
+ kInstanceCall1Opt,
+ kInstanceCall2Opt,
+ kPushPolymorphicInstanceCall,
+ kPushPolymorphicInstanceCallByRange,
+ kNativeCall,
+ kOneByteStringFromCharCode,
+ kStringToCharCode,
+ kAddTOS,
+ kSubTOS,
+ kMulTOS,
+ kBitOrTOS,
+ kBitAndTOS,
+ kEqualTOS,
+ kLessThanTOS,
+ kGreaterThanTOS,
+ kSmiAddTOS,
+ kSmiSubTOS,
+ kSmiMulTOS,
+ kSmiBitAndTOS,
+ kAdd,
+ kSub,
+ kMul,
+ kDiv,
+ kMod,
+ kShl,
+ kShr,
+ kShlImm,
+ kNeg,
+ kBitOr,
+ kBitAnd,
+ kBitXor,
+ kBitNot,
+ kMin,
+ kMax,
+ kWriteIntoDouble,
+ kUnboxDouble,
+ kCheckedUnboxDouble,
+ kUnboxInt32,
+ kBoxInt32,
+ kBoxUint32,
+ kSmiToDouble,
+ kDoubleToSmi,
+ kDAdd,
+ kDSub,
+ kDMul,
+ kDDiv,
+ kDNeg,
+ kDSqrt,
+ kDMin,
+ kDMax,
+ kDCos,
+ kDSin,
+ kDPow,
+ kDMod,
+ kDTruncate,
+ kDFloor,
+ kDCeil,
+ kDoubleToFloat,
+ kFloatToDouble,
+ kDoubleIsNaN,
+ kDoubleIsInfinite,
+ kStoreStaticTOS,
+ kPushStatic,
+ kInitStaticTOS,
+ kIfNeStrictTOS,
+ kIfEqStrictTOS,
+ kIfNeStrictNumTOS,
+ kIfEqStrictNumTOS,
+ kIfSmiLtTOS,
+ kIfSmiLeTOS,
+ kIfSmiGeTOS,
+ kIfSmiGtTOS,
+ kIfNeStrict,
+ kIfEqStrict,
+ kIfLe,
+ kIfLt,
+ kIfGe,
+ kIfGt,
+ kIfULe,
+ kIfULt,
+ kIfUGe,
+ kIfUGt,
+ kIfDNe,
+ kIfDEq,
+ kIfDLe,
+ kIfDLt,
+ kIfDGe,
+ kIfDGt,
+ kIfNeStrictNum,
+ kIfEqStrictNum,
+ kIfEqNull,
+ kIfNeNull,
+ kCreateArrayTOS,
+ kCreateArrayOpt,
+ kAllocate,
+ kAllocateT,
+ kAllocateOpt,
+ kAllocateTOpt,
+ kStoreIndexedTOS,
+ kStoreIndexed,
+ kStoreIndexedUint8,
+ kStoreIndexedExternalUint8,
+ kStoreIndexedOneByteString,
+ kStoreIndexedUint32,
+ kStoreIndexedFloat32,
+ kStoreIndexed4Float32,
+ kStoreIndexedFloat64,
+ kStoreIndexed8Float64,
+ kNoSuchMethod,
+ kTailCall,
+ kTailCallOpt,
+ kLoadArgDescriptor,
+ kLoadArgDescriptorOpt,
+ kLoadFpRelativeSlot,
+ kLoadFpRelativeSlotOpt,
+ kStoreFpRelativeSlot,
+ kStoreFpRelativeSlotOpt,
+ kLoadIndexedTOS,
+ kLoadIndexed,
+ kLoadIndexedUint8,
+ kLoadIndexedInt8,
+ kLoadIndexedInt32,
+ kLoadIndexedUint32,
+ kLoadIndexedExternalUint8,
+ kLoadIndexedExternalInt8,
+ kLoadIndexedFloat32,
+ kLoadIndexed4Float32,
+ kLoadIndexedFloat64,
+ kLoadIndexed8Float64,
+ kLoadIndexedOneByteString,
+ kLoadIndexedTwoByteString,
+ kStoreField,
+ kStoreFieldExt,
+ kStoreFieldTOS,
+ kLoadField,
+ kLoadFieldExt,
+ kLoadUntagged,
+ kLoadFieldTOS,
+ kBooleanNegateTOS,
+ kBooleanNegate,
+ kThrow,
+ kEntry,
+ kEntryOptimized,
+ kFrame,
+ kSetFrame,
+ kAllocateContext,
+ kAllocateUninitializedContext,
+ kCloneContext,
+ kMoveSpecial,
+ kInstantiateType,
+ kInstantiateTypeArgumentsTOS,
+ kInstanceOf,
+ kBadTypeError,
+ kAssertAssignable,
+ kAssertSubtype,
+ kAssertBoolean,
+ kTestSmi,
+ kTestCids,
+ kCheckSmi,
+ kCheckEitherNonSmi,
+ kCheckClassId,
+ kCheckClassIdRange,
+ kCheckBitTest,
+ kCheckCids,
+ kCheckCidsByRange,
+ kCheckStack,
+ kCheckStackAlwaysExit,
+ kCheckFunctionTypeArgs,
+ kDebugStep,
+ kDebugBreak,
+ kDeopt,
+ kDeoptRewind,
+ kEntryOptional,
+}
+
+enum Encoding {
+ k0,
+ kA,
+ kAD,
+ kAX,
+ kD,
+ kX,
+ kABC,
+ kABY,
+ kT,
+}
+
+enum Operand {
+ none, // ignored / non-existent operand
+ imm, // immediate operand
+ lit, // constant literal from object pool
+ reg, // register (unsigned FP relative local)
+ xeg, // x-register (signed FP relative local)
+ tgt, // jump target relative to the PC of the current instruction
+}
+
+class Format {
+ final Encoding encoding;
+ final List<Operand> operands;
+ const Format(this.encoding, this.operands);
+}
+
+const Map<Opcode, Format> BytecodeFormats = const {
+ Opcode.kTrap: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kNop: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kCompile: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kHotCheck: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+ Opcode.kIntrinsic: const Format(
+ Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kDrop1: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kDropR: const Format(
+ Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kDrop: const Format(
+ Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kJump: const Format(
+ Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
+ Opcode.kReturn: const Format(
+ Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kReturnTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kMove: const Format(
+ Encoding.kAX, const [Operand.reg, Operand.xeg, Operand.none]),
+ Opcode.kSwap: const Format(
+ Encoding.kAX, const [Operand.reg, Operand.xeg, Operand.none]),
+ Opcode.kPush: const Format(
+ Encoding.kX, const [Operand.xeg, Operand.none, Operand.none]),
+ Opcode.kLoadConstant: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.lit, Operand.none]),
+ Opcode.kLoadClassId: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kLoadClassIdTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kPushConstant: const Format(
+ Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kStoreLocal: const Format(
+ Encoding.kX, const [Operand.xeg, Operand.none, Operand.none]),
+ Opcode.kPopLocal: const Format(
+ Encoding.kX, const [Operand.xeg, Operand.none, Operand.none]),
+ Opcode.kIndirectStaticCall: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kStaticCall: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+ Opcode.kInstanceCall1: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kInstanceCall2: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kInstanceCall1Opt: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kInstanceCall2Opt: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kPushPolymorphicInstanceCall: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+ Opcode.kPushPolymorphicInstanceCallByRange: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+ Opcode.kNativeCall: const Format(
+ Encoding.kABC, const [Operand.imm, Operand.imm, Operand.imm]),
+ Opcode.kOneByteStringFromCharCode: const Format(
+ Encoding.kAX, const [Operand.reg, Operand.xeg, Operand.none]),
+ Opcode.kStringToCharCode: const Format(
+ Encoding.kAX, const [Operand.reg, Operand.xeg, Operand.none]),
+ Opcode.kAddTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kSubTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kMulTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kBitOrTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kBitAndTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kEqualTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kLessThanTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kGreaterThanTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kSmiAddTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kSmiSubTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kSmiMulTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kSmiBitAndTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kAdd: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kSub: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kMul: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDiv: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kMod: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kShl: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kShr: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kShlImm: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.imm]),
+ Opcode.kNeg: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kBitOr: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kBitAnd: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kBitXor: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kBitNot: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kMin: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kMax: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kWriteIntoDouble: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kUnboxDouble: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kCheckedUnboxDouble: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kUnboxInt32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.imm]),
+ Opcode.kBoxInt32: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kBoxUint32: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kSmiToDouble: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDoubleToSmi: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDAdd: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDSub: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDMul: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDDiv: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDNeg: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDSqrt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDMin: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDMax: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDCos: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDSin: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDPow: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDMod: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kDTruncate: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDFloor: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDCeil: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDoubleToFloat: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kFloatToDouble: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kDoubleIsNaN: const Format(
+ Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kDoubleIsInfinite: const Format(
+ Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kStoreStaticTOS: const Format(
+ Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kPushStatic: const Format(
+ Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kInitStaticTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfNeStrictTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfEqStrictTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfNeStrictNumTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfEqStrictNumTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfSmiLtTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfSmiLeTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfSmiGeTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfSmiGtTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kIfNeStrict: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfEqStrict: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfLe: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfLt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfGe: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfGt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfULe: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfULt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfUGe: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfUGt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfDNe: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfDEq: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfDLe: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfDLt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfDGe: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfDGt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfNeStrictNum: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfEqStrictNum: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kIfEqNull: const Format(
+ Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kIfNeNull: const Format(
+ Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kCreateArrayTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCreateArrayOpt: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kAllocate: const Format(
+ Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kAllocateT: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kAllocateOpt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.lit, Operand.none]),
+ Opcode.kAllocateTOpt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.lit, Operand.none]),
+ Opcode.kStoreIndexedTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kStoreIndexed: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexedUint8: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexedExternalUint8: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexedOneByteString: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexedUint32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexedFloat32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexed4Float32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexedFloat64: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreIndexed8Float64: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kNoSuchMethod: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kTailCall: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kTailCallOpt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kLoadArgDescriptor: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kLoadArgDescriptorOpt: const Format(
+ Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kLoadFpRelativeSlot: const Format(
+ Encoding.kX, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kLoadFpRelativeSlotOpt: const Format(
+ Encoding.kABY, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreFpRelativeSlot: const Format(
+ Encoding.kX, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kStoreFpRelativeSlotOpt: const Format(
+ Encoding.kABY, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kLoadIndexed: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedUint8: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedInt8: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedInt32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedUint32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedExternalUint8: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedExternalInt8: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedFloat32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexed4Float32: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedFloat64: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexed8Float64: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedOneByteString: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kLoadIndexedTwoByteString: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.reg]),
+ Opcode.kStoreField: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.imm, Operand.reg]),
+ Opcode.kStoreFieldExt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kStoreFieldTOS: const Format(
+ Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kLoadField: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.imm]),
+ Opcode.kLoadFieldExt: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kLoadUntagged: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.reg, Operand.imm]),
+ Opcode.kLoadFieldTOS: const Format(
+ Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kBooleanNegateTOS: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kBooleanNegate: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kThrow: const Format(
+ Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kEntry: const Format(
+ Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kEntryOptimized: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+ Opcode.kFrame: const Format(
+ Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kSetFrame: const Format(
+ Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kAllocateContext: const Format(
+ Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kAllocateUninitializedContext: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+ Opcode.kCloneContext: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kMoveSpecial: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+ Opcode.kInstantiateType: const Format(
+ Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
+ Opcode.kInstantiateTypeArgumentsTOS: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kInstanceOf: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kBadTypeError: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kAssertAssignable: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+ Opcode.kAssertSubtype: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kAssertBoolean: const Format(
+ Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kTestSmi: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kTestCids: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+ Opcode.kCheckSmi: const Format(
+ Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
+ Opcode.kCheckEitherNonSmi: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.reg, Operand.none]),
+ Opcode.kCheckClassId: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+ Opcode.kCheckClassIdRange: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+ Opcode.kCheckBitTest: const Format(
+ Encoding.kAD, const [Operand.reg, Operand.imm, Operand.none]),
+ Opcode.kCheckCids: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.imm, Operand.imm]),
+ Opcode.kCheckCidsByRange: const Format(
+ Encoding.kABC, const [Operand.reg, Operand.imm, Operand.imm]),
+ Opcode.kCheckStack: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCheckStackAlwaysExit: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kCheckFunctionTypeArgs: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+ Opcode.kDebugStep: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kDebugBreak: const Format(
+ Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
+ Opcode.kDeopt: const Format(
+ Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+ Opcode.kDeoptRewind: const Format(
+ Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
+ Opcode.kEntryOptional: const Format(
+ Encoding.kABC, const [Operand.imm, Operand.imm, Operand.imm]),
+};
+
+// Should match constant in runtime/vm/stack_frame_dbc.h.
+const int kParamEndSlotFromFp = 4;
+
+// Prefix used to distinguish getters in ICData target names.
+// Should match constant in runtime/vm/object.cc.
+const String kGetterPrefix = 'get:';
+
+// Prefix used to distinguish setters in ICData target names.
+// Should match constant in runtime/vm/object.cc.
+const String kSetterPrefix = 'set:';
diff --git a/pkg/vm/lib/bytecode/disassembler.dart b/pkg/vm/lib/bytecode/disassembler.dart
new file mode 100644
index 0000000..9230268
--- /dev/null
+++ b/pkg/vm/lib/bytecode/disassembler.dart
@@ -0,0 +1,165 @@
+// 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 vm.bytecode.disassembler;
+
+import 'dart:typed_data';
+
+import 'package:vm/bytecode/dbc.dart';
+
+class _Instruction {
+ final Opcode opcode;
+ final List<int> operands;
+ _Instruction(this.opcode, this.operands);
+}
+
+class BytecodeDisassembler {
+ static const int kOpcodeMask = 0xFF;
+ static const int kBitsPerInt = 64;
+
+ List<_Instruction> _instructions;
+ int _labelCount;
+ Map<int, int> _labels;
+
+ String disassemble(List<int> bytecode) {
+ _init(bytecode);
+ _scanForJumpTargets();
+ return _disasm();
+ }
+
+ void _init(List<int> bytecode) {
+ final uint8list = new Uint8List.fromList(bytecode);
+ // TODO(alexmarkov): endianness?
+ Uint32List words = uint8list.buffer.asUint32List();
+
+ _instructions = new List<_Instruction>(words.length);
+ for (int i = 0; i < words.length; i++) {
+ _instructions[i] = _decodeInstruction(words[i]);
+ }
+
+ _labelCount = 0;
+ _labels = <int, int>{};
+ }
+
+ _Instruction _decodeInstruction(int word) {
+ final opcode = Opcode.values[word & kOpcodeMask];
+ final format = BytecodeFormats[opcode];
+ return new _Instruction(opcode, _decodeOperands(format, word));
+ }
+
+ List<int> _decodeOperands(Format format, int word) {
+ switch (format.encoding) {
+ case Encoding.k0:
+ return const [];
+ case Encoding.kA:
+ return [_unsigned(word, 8, 8)];
+ case Encoding.kAD:
+ return [_unsigned(word, 8, 8), _unsigned(word, 16, 16)];
+ case Encoding.kAX:
+ return [_unsigned(word, 8, 8), _signed(word, 16, 16)];
+ case Encoding.kD:
+ return [_unsigned(word, 16, 16)];
+ case Encoding.kX:
+ return [_signed(word, 16, 16)];
+ case Encoding.kABC:
+ return [
+ _unsigned(word, 8, 8),
+ _unsigned(word, 16, 8),
+ _unsigned(word, 24, 8)
+ ];
+ case Encoding.kABY:
+ return [
+ _unsigned(word, 8, 8),
+ _unsigned(word, 16, 8),
+ _signed(word, 24, 8)
+ ];
+ case Encoding.kT:
+ return [_signed(word, 8, 24)];
+ }
+ throw 'Unexpected format $format';
+ }
+
+ int _unsigned(int word, int pos, int bits) =>
+ (word >> pos) & ((1 << bits) - 1);
+
+ int _signed(int word, int pos, int bits) =>
+ _unsigned(word, pos, bits) <<
+ (kBitsPerInt - bits) >>
+ (kBitsPerInt - bits);
+
+ void _scanForJumpTargets() {
+ for (int i = 0; i < _instructions.length; i++) {
+ final instr = _instructions[i];
+ if (instr.opcode == Opcode.kJump) {
+ final target = i + instr.operands[0];
+ assert(0 <= target && target < _instructions.length);
+ _labels[target] ??= (++_labelCount);
+ }
+ }
+ }
+
+ String _disasm() {
+ StringBuffer out = new StringBuffer();
+ for (int i = 0; i < _instructions.length; i++) {
+ int label = _labels[i];
+ if (label != null) {
+ out.writeln('L$label:');
+ }
+ _writeInstruction(out, i, _instructions[i]);
+ }
+ return out.toString();
+ }
+
+ void _writeInstruction(StringBuffer out, int bci, _Instruction instr) {
+ final format = BytecodeFormats[instr.opcode];
+ assert(format != null);
+
+ out.write(' ');
+
+ const int kOpcodeWidth = 20;
+ const String kOpcodePrefix = 'Opcode.k';
+
+ String opcode = instr.opcode.toString();
+ assert(opcode.startsWith(kOpcodePrefix));
+ opcode = opcode.substring(kOpcodePrefix.length);
+
+ if (instr.operands.isEmpty) {
+ out.writeln(opcode);
+ return;
+ }
+
+ out.write(opcode.padRight(kOpcodeWidth));
+
+ for (int i = 0; i < instr.operands.length; i++) {
+ if (i == 0) {
+ out.write(' ');
+ } else {
+ out.write(', ');
+ }
+ final operand =
+ _formatOperand(bci, format.operands[i], instr.operands[i]);
+ out.write(operand);
+ }
+
+ out.writeln();
+ }
+
+ String _formatOperand(int bci, Operand fmt, int value) {
+ switch (fmt) {
+ case Operand.none:
+ break;
+ case Operand.imm:
+ return '$value';
+ case Operand.lit:
+ return 'CP#$value';
+ case Operand.reg:
+ return 'r$value';
+ case Operand.xeg:
+ return (value < 0) ? 'FP[$value]' : 'r$value';
+ case Operand.tgt:
+ return 'L${_labels[bci + value] ?? (throw 'Label not found')}';
+ }
+ throw 'Unexpected operand format $fmt';
+ }
+}
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
new file mode 100644
index 0000000..1fd4ebe
--- /dev/null
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -0,0 +1,1332 @@
+// 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 vm.bytecode.gen_bytecode;
+
+import 'package:kernel/ast.dart' hide MapEntry;
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/core_types.dart' show CoreTypes;
+import 'package:kernel/library_index.dart' show LibraryIndex;
+import 'package:kernel/transformations/constants.dart'
+ show ConstantEvaluator, ConstantsBackend, EvaluationEnvironment;
+import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/vm/constants_native_effects.dart'
+ show VmConstantsBackend;
+import 'package:vm/bytecode/assembler.dart';
+import 'package:vm/bytecode/constant_pool.dart';
+import 'package:vm/bytecode/dbc.dart';
+import 'package:vm/bytecode/local_vars.dart' show LocalVariables;
+import 'package:vm/metadata/bytecode.dart';
+
+/// Flag to toggle generation of bytecode in kernel files.
+const bool kEnableKernelBytecode = false;
+
+/// Flag to toggle generation of bytecode in platform kernel files.
+const bool kEnableKernelBytecodeForPlatform = kEnableKernelBytecode;
+
+const bool kTrace = false;
+
+void generateBytecode(Component component, {bool strongMode: true}) {
+ final coreTypes = new CoreTypes(component);
+ void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
+ final hierarchy = new ClassHierarchy(component,
+ onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
+ final typeEnvironment =
+ new TypeEnvironment(coreTypes, hierarchy, strongMode: strongMode);
+ final constantsBackend = new VmConstantsBackend(null, coreTypes);
+ new BytecodeGenerator(component, coreTypes, hierarchy, typeEnvironment,
+ constantsBackend, strongMode)
+ .visitComponent(component);
+}
+
+class BytecodeGenerator extends RecursiveVisitor<Null> {
+ final Component component;
+ final CoreTypes coreTypes;
+ final ClassHierarchy hierarchy;
+ final TypeEnvironment typeEnvironment;
+ final ConstantsBackend constantsBackend;
+ final bool strongMode;
+ final BytecodeMetadataRepository metadata = new BytecodeMetadataRepository();
+
+ Class enclosingClass;
+ Member enclosingMember;
+ BytecodeAssembler asm;
+ ConstantPool cp;
+ LocalVariables locals;
+ ConstantEmitter constantEmitter;
+ ConstantEvaluator constantEvaluator;
+ Map<LabeledStatement, Label> labeledStatements;
+ Map<SwitchCase, Label> switchCases;
+
+ BytecodeGenerator(this.component, this.coreTypes, this.hierarchy,
+ this.typeEnvironment, this.constantsBackend, this.strongMode) {
+ component.addMetadataRepository(metadata);
+ }
+
+ @override
+ visitComponent(Component node) => node.visitChildren(this);
+
+ @override
+ visitLibrary(Library node) {
+ if (node.isExternal) {
+ return;
+ }
+ visitList(node.classes, this);
+ visitList(node.procedures, this);
+ visitList(node.fields, this);
+ }
+
+ @override
+ visitClass(Class node) {
+ visitList(node.constructors, this);
+ visitList(node.procedures, this);
+ visitList(node.fields, this);
+ }
+
+ @override
+ defaultMember(Member node) {
+ if (node.isAbstract) {
+ return;
+ }
+ try {
+ if (node is Field) {
+ if (node.isStatic && node.initializer != null) {
+ start(node);
+ if (node.isConst) {
+ _genPushConstExpr(node.initializer);
+ } else {
+ node.initializer.accept(this);
+ }
+ _genReturnTOS();
+ end(node);
+ }
+ } else if ((node is Procedure && !node.isRedirectingFactoryConstructor) ||
+ (node is Constructor)) {
+ start(node);
+ if (node is Constructor) {
+ _genConstructorInitializers(node);
+ }
+ node.function?.body?.accept(this);
+ // TODO(alexmarkov): figure out when 'return null' should be generated.
+ _genPushNull();
+ _genReturnTOS();
+ end(node);
+ }
+ } on UnsupportedOperationError catch (e) {
+ if (kTrace) {
+ print('Unable to generate bytecode for $node: $e');
+ }
+ }
+ }
+
+ LibraryIndex _libraryIndex;
+ LibraryIndex get libraryIndex =>
+ _libraryIndex ??= new LibraryIndex.coreLibraries(component);
+
+ Procedure _listFromLiteral;
+ Procedure get listFromLiteral => _listFromLiteral ??=
+ libraryIndex.getMember('dart:core', 'List', '_fromLiteral');
+
+ Procedure _mapFromLiteral;
+ Procedure get mapFromLiteral => _mapFromLiteral ??=
+ libraryIndex.getMember('dart:core', 'Map', '_fromLiteral');
+
+ Procedure _interpolateSingle;
+ Procedure get interpolateSingle => _interpolateSingle ??=
+ libraryIndex.getMember('dart:core', '_StringBase', '_interpolateSingle');
+
+ Procedure _interpolate;
+ Procedure get interpolate => _interpolate ??=
+ libraryIndex.getMember('dart:core', '_StringBase', '_interpolate');
+
+ void _genConstructorInitializers(Constructor node) {
+ bool isRedirecting =
+ node.initializers.any((init) => init is RedirectingInitializer);
+ if (!isRedirecting) {
+ for (var field in node.enclosingClass.fields) {
+ if (!field.isStatic &&
+ field.initializer != null &&
+ !node.initializers.any(
+ (init) => init is FieldInitializer && init.field == field)) {
+ _genFieldInitializer(field, field.initializer);
+ }
+ }
+ }
+ visitList(node.initializers, this);
+ }
+
+ void _genFieldInitializer(Field field, Expression initializer) {
+ if (initializer is NullLiteral) {
+ return;
+ }
+
+ asm.emitPush(locals.thisVarIndex);
+ initializer.accept(this);
+
+ // TODO(alexmarkov): field guards?
+ // TODO(alexmarkov): assignability check
+
+ final int cpIndex = cp.add(new ConstantFieldOffset(field));
+ asm.emitStoreFieldTOS(cpIndex);
+ }
+
+ void _genArguments(Expression receiver, Arguments arguments) {
+ if (arguments.types.isNotEmpty) {
+ _genTypeArguments(arguments.types);
+ }
+ receiver?.accept(this);
+ visitList(arguments.positional, this);
+ arguments.named.forEach((NamedExpression ne) => ne.value.accept(this));
+ }
+
+ void _genPushNull() {
+ final cpIndex = cp.add(const ConstantNull());
+ asm.emitPushConstant(cpIndex);
+ }
+
+ void _genPushInt(int value) {
+ int cpIndex = cp.add(new ConstantInt(value));
+ asm.emitPushConstant(cpIndex);
+ }
+
+ void _genPushConstExpr(Expression expr) {
+ final constant = constantEvaluator.evaluate(expr);
+ asm.emitPushConstant(constant.accept(constantEmitter));
+ }
+
+ void _genReturnTOS() {
+ asm.emitReturnTOS();
+ }
+
+ void _genStaticCall(
+ Member target, ConstantArgDesc argDesc, int totalArgCount) {
+ final argDescIndex = cp.add(argDesc);
+ final icdataIndex = cp.add(new ConstantStaticICData(target, argDescIndex));
+
+ asm.emitPushConstant(icdataIndex);
+ asm.emitIndirectStaticCall(totalArgCount, argDescIndex);
+ }
+
+ void _genStaticCallWithArgs(Member target, Arguments args,
+ {bool hasReceiver: false, bool alwaysPassTypeArgs: false}) {
+ final ConstantArgDesc argDesc =
+ new ConstantArgDesc.fromArguments(args, hasReceiver: hasReceiver);
+
+ int totalArgCount = args.positional.length + args.named.length;
+ if (hasReceiver) {
+ totalArgCount++;
+ }
+ if (args.types.isNotEmpty || alwaysPassTypeArgs) {
+ totalArgCount++;
+ }
+
+ _genStaticCall(target, argDesc, totalArgCount);
+ }
+
+ bool hasTypeParameters(List<DartType> typeArgs) {
+ final findTypeParams = new FindTypeParametersVisitor();
+ return typeArgs.any((t) => t.accept(findTypeParams));
+ }
+
+ bool hasInstantiatorTypeArguments(Class c) {
+ return c.typeParameters.isNotEmpty ||
+ (c.superclass != null && hasInstantiatorTypeArguments(c.superclass));
+ }
+
+ bool isGenericFunction(Member member) {
+ final function = member.function;
+ return function != null && function.typeParameters.isNotEmpty;
+ }
+
+ void _genTypeArguments(List<DartType> typeArgs) {
+ final int typeArgsCPIndex = cp.add(new ConstantTypeArguments(typeArgs));
+ if (typeArgs.isEmpty || !hasTypeParameters(typeArgs)) {
+ asm.emitPushConstant(typeArgsCPIndex);
+ } else {
+ // TODO(alexmarkov): try to reuse instantiator type arguments
+ // TODO(alexmarkov): do not load instantiator type arguments / function type
+ // arguments if they are not needed for these particular [typeArgs].
+ _genPushInstantiatorTypeArguments();
+ _genPushFunctionTypeArguments();
+ asm.emitInstantiateTypeArgumentsTOS(1, typeArgsCPIndex);
+ }
+ }
+
+ void _genPushInstantiatorTypeArguments() {
+ // TODO(alexmarkov): access from closures to up-level type arguments.
+ if ((enclosingMember.isInstanceMember || enclosingMember is Constructor) &&
+ hasInstantiatorTypeArguments(enclosingClass)) {
+ asm.emitPush(locals.thisVarIndex);
+ final int cpIndex =
+ cp.add(new ConstantTypeArgumentsFieldOffset(enclosingClass));
+ asm.emitLoadFieldTOS(cpIndex);
+ } else {
+ _genPushNull();
+ }
+ }
+
+ void _genPushFunctionTypeArguments() {
+ // TODO(alexmarkov): closures
+ if (isGenericFunction(enclosingMember)) {
+ asm.emitPush(locals.functionTypeArgsVarIndex);
+ } else {
+ _genPushNull();
+ }
+ }
+
+ List<DartType> _flattenTypeArgumentsForInstantiation(
+ Class instantiatedClass, List<DartType> typeArgs) {
+ assert(typeArgs.length == instantiatedClass.typeParameters.length);
+
+ List<DartType> flatTypeArgs;
+ final supertype = instantiatedClass.supertype;
+ if (supertype == null) {
+ flatTypeArgs = <DartType>[];
+ } else {
+ final substitution =
+ Substitution.fromPairs(instantiatedClass.typeParameters, typeArgs);
+ flatTypeArgs = _flattenTypeArgumentsForInstantiation(supertype.classNode,
+ substitution.substituteSupertype(supertype).typeArguments);
+ }
+ flatTypeArgs.addAll(typeArgs);
+ return flatTypeArgs;
+ }
+
+ /// Generates bool condition. Returns `true` if condition is negated.
+ bool _genCondition(Node condition) {
+ bool negated = false;
+ if (condition is Not) {
+ condition = (condition as Not).operand;
+ negated = true;
+ }
+ condition.accept(this);
+ // TODO(alexmarkov): bool check
+ return negated;
+ }
+
+ void _genJumpIfFalse(bool negated, Label dest) {
+ asm.emitPushConstant(cp.add(new ConstantBool(true)));
+ if (negated) {
+ asm.emitIfEqStrictTOS(); // if ((!condition) == true) ...
+ } else {
+ asm.emitIfNeStrictTOS(); // if (condition != true) ...
+ }
+ asm.emitJump(dest); // ... then jump dest
+ }
+
+ // Duplicates value on top of the stack using temporary variable
+ // corresponding to [node].
+ void _genDupTOS(TreeNode node) {
+ // TODO(alexmarkov): Consider introducing Dup bytecode or keeping track of
+ // expression stack depth.
+ final int temp = locals.tempIndex(node);
+ asm.emitStoreLocal(temp);
+ asm.emitPush(temp);
+ }
+
+ void start(Member node) {
+ enclosingMember = node;
+ enclosingClass = node.enclosingClass;
+ asm = new BytecodeAssembler();
+ cp = new ConstantPool();
+ locals = new LocalVariables();
+ constantEmitter = new ConstantEmitter(cp);
+ // TODO(alexmarkov): improve caching in ConstantEvaluator and reuse it
+ constantEvaluator = new ConstantEvaluator(constantsBackend, typeEnvironment,
+ coreTypes, strongMode, /* enableAsserts = */ true)
+ ..env = new EvaluationEnvironment();
+ labeledStatements = <LabeledStatement, Label>{};
+ switchCases = <SwitchCase, Label>{};
+
+ node.accept(locals);
+
+ if (locals.hasOptionalParameters) {
+ final function = node.function;
+ final int numOptionalPositional = function.positionalParameters.length -
+ function.requiredParameterCount;
+ final int numOptionalNamed = function.namedParameters.length;
+ final int numFixed =
+ locals.numParameters - (numOptionalPositional + numOptionalNamed);
+
+ asm.emitEntryOptional(numFixed, numOptionalPositional, numOptionalNamed);
+
+ if (numOptionalPositional != 0) {
+ assert(numOptionalNamed == 0);
+ for (int i = 0; i < numOptionalPositional; i++) {
+ final param = function
+ .positionalParameters[function.requiredParameterCount + i];
+ asm.emitLoadConstant(numFixed + i, _getDefaultParamConstIndex(param));
+ }
+ } else {
+ assert(numOptionalNamed != 0);
+ for (int i = 0; i < numOptionalNamed; i++) {
+ final param = function.namedParameters[i];
+ asm.emitLoadConstant(
+ numFixed + i, cp.add(new ConstantString(param.name)));
+ asm.emitLoadConstant(numFixed + i, _getDefaultParamConstIndex(param));
+ }
+ }
+
+ asm.emitFrame(locals.frameSize - locals.numParameters);
+ } else {
+ asm.emitEntry(locals.frameSize);
+ }
+ asm.emitCheckStack();
+
+ // TODO(alexmarkov): add type checks for parameters
+ }
+
+ int _getDefaultParamConstIndex(VariableDeclaration param) {
+ if (param.initializer == null) {
+ return cp.add(const ConstantNull());
+ }
+ final constant = constantEvaluator.evaluate(param.initializer);
+ return constant.accept(constantEmitter);
+ }
+
+ void _genJumpIfTrue(bool negated, Label dest) {
+ _genJumpIfFalse(!negated, dest);
+ }
+
+ void end(Member node) {
+ enclosingMember = null;
+ enclosingClass = null;
+ metadata.mapping[node] = new BytecodeMetadata(asm.bytecode, cp);
+ if (kTrace) {
+ print('Generated bytecode for $node');
+ }
+ }
+
+ @override
+ defaultTreeNode(Node node) => throw new UnsupportedOperationError(
+ 'Unsupported node ${node.runtimeType}');
+
+ @override
+ visitAsExpression(AsExpression node) {
+ node.operand.accept(this);
+
+ if (node.type == const DynamicType()) {
+ return;
+ }
+ if (node.isTypeError) {
+ // TODO(alexmarkov): type checks
+ return;
+ }
+ if (hasTypeParameters([node.type])) {
+ // TODO(alexmarkov): do not load instantiator type arguments / function
+ // type arguments if they are not needed for this particular type.
+ _genPushInstantiatorTypeArguments();
+ _genPushFunctionTypeArguments();
+ } else {
+ _genPushNull(); // Instantiator type arguments.
+ _genPushNull(); // Function type arguments.
+ }
+ final typeIndex = cp.add(new ConstantType(node.type));
+ asm.emitPushConstant(typeIndex);
+ final argDescIndex = cp.add(new ConstantArgDesc(4));
+ final icdataIndex = cp.add(new ConstantICData('_as', argDescIndex));
+ asm.emitInstanceCall1(4, icdataIndex);
+ }
+
+ @override
+ visitBoolLiteral(BoolLiteral node) {
+ final cpIndex = cp.add(new ConstantBool.fromLiteral(node));
+ asm.emitPushConstant(cpIndex);
+ }
+
+ @override
+ visitIntLiteral(IntLiteral node) {
+ final cpIndex = cp.add(new ConstantInt.fromLiteral(node));
+ asm.emitPushConstant(cpIndex);
+ }
+
+ @override
+ visitDoubleLiteral(DoubleLiteral node) {
+ final cpIndex = cp.add(new ConstantDouble.fromLiteral(node));
+ asm.emitPushConstant(cpIndex);
+ }
+
+ @override
+ visitConditionalExpression(ConditionalExpression node) {
+ final Label otherwisePart = new Label();
+ final Label done = new Label();
+ final int temp = locals.tempIndex(node);
+
+ final bool negated = _genCondition(node.condition);
+ _genJumpIfFalse(negated, otherwisePart);
+
+ node.then.accept(this);
+ asm.emitPopLocal(temp);
+ asm.emitJump(done);
+
+ asm.bind(otherwisePart);
+ node.otherwise.accept(this);
+ asm.emitPopLocal(temp);
+
+ asm.bind(done);
+ asm.emitPush(temp);
+ }
+
+ @override
+ visitConstructorInvocation(ConstructorInvocation node) {
+ if (node.isConst) {
+ _genPushConstExpr(node);
+ return;
+ }
+
+ final constructedClass = node.constructedType.classNode;
+ final classIndex = cp.add(new ConstantClass(constructedClass));
+
+ if (hasInstantiatorTypeArguments(constructedClass)) {
+ List<DartType> flatTypeArgs = _flattenTypeArgumentsForInstantiation(
+ constructedClass, node.arguments.types);
+ _genTypeArguments(flatTypeArgs);
+ asm.emitPushConstant(cp.add(new ConstantClass(constructedClass)));
+ asm.emitAllocateT();
+ } else {
+ assert(node.arguments.types.isEmpty);
+ asm.emitAllocate(classIndex);
+ }
+
+ _genDupTOS(node);
+
+ // Remove type arguments as they are only passed to instance allocation,
+ // and not passed to a constructor.
+ final args =
+ new Arguments(node.arguments.positional, named: node.arguments.named);
+ _genArguments(null, args);
+ _genStaticCallWithArgs(node.target, args, hasReceiver: true);
+ asm.emitDrop1();
+ }
+
+// @override
+// visitDirectMethodInvocation(DirectMethodInvocation node) {
+// }
+
+ @override
+ visitDirectPropertyGet(DirectPropertyGet node) {
+ node.receiver.accept(this);
+ final target = node.target;
+ if (target is Field || (target is Procedure && target.isGetter)) {
+ _genStaticCall(target, new ConstantArgDesc(1), 1);
+ } else {
+ throw new UnsupportedOperationError(
+ 'Unsupported DirectPropertyGet with ${target.runtimeType} $target');
+ }
+ }
+
+// @override
+// visitDirectPropertySet(DirectPropertySet node) {
+// }
+//
+// @override
+// visitFunctionExpression(FunctionExpression node) {
+// }
+//
+// @override
+// visitInstantiation(Instantiation node) {
+// }
+//
+// @override
+// visitInvalidExpression(InvalidExpression node) {
+// }
+
+ @override
+ visitIsExpression(IsExpression node) {
+ node.operand.accept(this);
+
+ // TODO(alexmarkov): generate _simpleInstanceOf if possible
+
+ if (hasTypeParameters([node.type])) {
+ // TODO(alexmarkov): do not load instantiator type arguments / function type
+ // arguments if they are not needed for this particular type.
+ _genPushInstantiatorTypeArguments();
+ _genPushFunctionTypeArguments();
+ } else {
+ _genPushNull(); // Instantiator type arguments.
+ _genPushNull(); // Function type arguments.
+ }
+ final typeIndex = cp.add(new ConstantType(node.type));
+ asm.emitPushConstant(typeIndex);
+ final argDescIndex = cp.add(new ConstantArgDesc(4));
+ final icdataIndex = cp.add(new ConstantICData('_instanceOf', argDescIndex));
+ asm.emitInstanceCall1(4, icdataIndex);
+ }
+
+ @override
+ visitLet(Let node) {
+ node.variable.accept(this);
+ node.body.accept(this);
+ }
+
+ @override
+ visitListLiteral(ListLiteral node) {
+ if (node.isConst) {
+ _genPushConstExpr(node);
+ return;
+ }
+
+ _genTypeArguments([node.typeArgument]);
+
+ _genDupTOS(node);
+
+ // TODO(alexmarkov): gen more efficient code for empty array
+ _genPushInt(node.expressions.length);
+ asm.emitCreateArrayTOS();
+ final int temp = locals.tempIndex(node);
+ asm.emitStoreLocal(temp);
+
+ for (int i = 0; i < node.expressions.length; i++) {
+ asm.emitPush(temp);
+ _genPushInt(i);
+ node.expressions[i].accept(this);
+ // TODO(alexmarkov): assignable check
+ asm.emitStoreIndexedTOS();
+ }
+
+ _genStaticCall(listFromLiteral, new ConstantArgDesc(1, numTypeArgs: 1), 2);
+ }
+
+ @override
+ visitLogicalExpression(LogicalExpression node) {
+ assert(node.operator == '||' || node.operator == '&&');
+
+ final Label shortCircuit = new Label();
+ final Label done = new Label();
+ final int temp = locals.tempIndex(node);
+ final isOR = (node.operator == '||');
+
+ bool negated = _genCondition(node.left);
+ asm.emitPushConstant(cp.add(new ConstantBool(true)));
+ if (negated != isOR) {
+ // OR: if (condition == true)
+ // AND: if ((!condition) == true)
+ asm.emitIfEqStrictTOS();
+ } else {
+ // OR: if ((!condition) != true)
+ // AND: if (condition != true)
+ asm.emitIfNeStrictTOS();
+ }
+ asm.emitJump(shortCircuit);
+
+ negated = _genCondition(node.right);
+ if (negated) {
+ asm.emitBooleanNegateTOS();
+ }
+ asm.emitPopLocal(temp);
+ asm.emitJump(done);
+
+ asm.bind(shortCircuit);
+ asm.emitPushConstant(cp.add(new ConstantBool(isOR)));
+ asm.emitPopLocal(temp);
+
+ asm.bind(done);
+ asm.emitPush(temp);
+ }
+
+ @override
+ visitMapLiteral(MapLiteral node) {
+ if (node.isConst) {
+ _genPushConstExpr(node);
+ return;
+ }
+
+ _genTypeArguments([node.keyType, node.valueType]);
+
+ if (node.entries.isEmpty) {
+ asm.emitPushConstant(
+ cp.add(new ConstantList(const DynamicType(), const [])));
+ } else {
+ _genTypeArguments([const DynamicType()]);
+ _genPushInt(node.entries.length * 2);
+ asm.emitCreateArrayTOS();
+
+ final int temp = locals.tempIndex(node);
+ asm.emitStoreLocal(temp);
+
+ for (int i = 0; i < node.entries.length; i++) {
+ // key
+ asm.emitPush(temp);
+ _genPushInt(i * 2);
+ node.entries[i].key.accept(this);
+ asm.emitStoreIndexedTOS();
+ // value
+ asm.emitPush(temp);
+ _genPushInt(i * 2 + 1);
+ node.entries[i].value.accept(this);
+ asm.emitStoreIndexedTOS();
+ }
+ }
+
+ _genStaticCall(mapFromLiteral, new ConstantArgDesc(1, numTypeArgs: 1), 2);
+ }
+
+ @override
+ visitMethodInvocation(MethodInvocation node) {
+ final args = node.arguments;
+ _genArguments(node.receiver, args);
+ // TODO(alexmarkov): fast path smi ops
+ final argDescIndex =
+ cp.add(new ConstantArgDesc.fromArguments(args, hasReceiver: true));
+ final icdataIndex =
+ cp.add(new ConstantICData(node.name.name, argDescIndex));
+ // TODO(alexmarkov): figure out when generate InstanceCall2 (2 checked arguments).
+ asm.emitInstanceCall1(
+ args.positional.length + args.named.length + 1, icdataIndex);
+ }
+
+ @override
+ visitPropertyGet(PropertyGet node) {
+ node.receiver.accept(this);
+ final argDescIndex = cp.add(new ConstantArgDesc(1));
+ final icdataIndex = cp.add(
+ new ConstantICData('$kGetterPrefix${node.name.name}', argDescIndex));
+ asm.emitInstanceCall1(1, icdataIndex);
+ }
+
+ @override
+ visitPropertySet(PropertySet node) {
+ final int temp = locals.tempIndex(node);
+ node.receiver.accept(this);
+ node.value.accept(this);
+ asm.emitStoreLocal(temp);
+ final argDescIndex = cp.add(new ConstantArgDesc(2));
+ final icdataIndex = cp.add(
+ new ConstantICData('$kSetterPrefix${node.name.name}', argDescIndex));
+ asm.emitInstanceCall1(2, icdataIndex);
+ asm.emitDrop1();
+ asm.emitPush(temp);
+ }
+
+ @override
+ visitSuperMethodInvocation(SuperMethodInvocation node) {
+ final args = node.arguments;
+ _genArguments(new ThisExpression(), args);
+ Member target =
+ hierarchy.getDispatchTarget(enclosingClass.superclass, node.name);
+ if (target == null) {
+ throw new UnsupportedOperationError(
+ 'Unsupported SuperMethodInvocation without target');
+ }
+ if (target is Procedure && !target.isGetter) {
+ _genStaticCallWithArgs(target, args);
+ } else {
+ throw new UnsupportedOperationError(
+ 'Unsupported SuperMethodInvocation with target ${target.runtimeType} $target');
+ }
+ }
+
+ @override
+ visitSuperPropertyGet(SuperPropertyGet node) {
+ asm.emitPush(locals.thisVarIndex);
+ Member target =
+ hierarchy.getDispatchTarget(enclosingClass.superclass, node.name);
+ if (target == null) {
+ throw new UnsupportedOperationError(
+ 'Unsupported SuperPropertyGet without target');
+ }
+ if (target is Field || (target is Procedure && target.isGetter)) {
+ _genStaticCall(target, new ConstantArgDesc(1), 1);
+ } else {
+ throw new UnsupportedOperationError(
+ 'Unsupported SuperPropertyGet with target ${target.runtimeType} $target');
+ }
+ }
+
+// @override
+// visitSuperPropertySet(SuperPropertySet node) {
+// }
+
+ @override
+ visitNot(Not node) {
+ bool negated = _genCondition(node.operand);
+ if (!negated) {
+ asm.emitBooleanNegateTOS();
+ }
+ }
+
+ @override
+ visitNullLiteral(NullLiteral node) {
+ final cpIndex = cp.add(const ConstantNull());
+ asm.emitPushConstant(cpIndex);
+ }
+
+// @override
+// visitRethrow(Rethrow node) {
+// }
+
+ bool _hasTrivialInitializer(Field field) =>
+ (field.initializer == null) ||
+ (field.initializer is StringLiteral) ||
+ (field.initializer is BoolLiteral) ||
+ (field.initializer is IntLiteral) ||
+ (field.initializer is NullLiteral);
+
+ @override
+ visitStaticGet(StaticGet node) {
+ final target = node.target;
+ if (target is Field) {
+ if (target.isConst) {
+ _genPushConstExpr(target.initializer);
+ } else if (_hasTrivialInitializer(target)) {
+ final fieldIndex = cp.add(new ConstantField(target));
+ asm.emitPushConstant(
+ fieldIndex); // TODO(alexmarkov): do we really need this?
+ asm.emitPushStatic(fieldIndex);
+ } else {
+ _genStaticCall(target, new ConstantArgDesc(0), 0);
+ }
+ } else if (target is Procedure) {
+ if (target.isGetter) {
+ _genStaticCall(target, new ConstantArgDesc(0), 0);
+ } else {
+ final tearOffIndex = cp.add(new ConstantTearOff(target));
+ asm.emitPushConstant(tearOffIndex);
+ }
+ } else {
+ throw 'Unexpected target for StaticGet: ${target.runtimeType} $target';
+ }
+ }
+
+ @override
+ visitStaticInvocation(StaticInvocation node) {
+ final args = node.arguments;
+ bool alwaysPassTypeArgs = false;
+ if (node.target.isFactory && args.types.isEmpty) {
+ // VM needs type arguments for every invocation of a factory constructor.
+ // TODO(alexmarkov): Why? Clean this up.
+ _genPushNull();
+ alwaysPassTypeArgs = true;
+ }
+ _genArguments(null, args);
+ _genStaticCallWithArgs(node.target, args,
+ alwaysPassTypeArgs: alwaysPassTypeArgs);
+ }
+
+ @override
+ visitStaticSet(StaticSet node) {
+ node.value.accept(this);
+ final target = node.target;
+ if (target is Field) {
+ // TODO(alexmarkov): assignable check
+ int cpIndex = cp.add(new ConstantField(target));
+ asm.emitStoreStaticTOS(cpIndex);
+ } else {
+ _genStaticCall(target, new ConstantArgDesc(1), 1);
+ }
+ }
+
+ @override
+ visitStringConcatenation(StringConcatenation node) {
+ if (node.expressions.length == 1) {
+ node.expressions.single.accept(this);
+ _genStaticCall(interpolateSingle, new ConstantArgDesc(1), 1);
+ } else {
+ _genPushNull();
+ _genPushInt(node.expressions.length);
+ asm.emitCreateArrayTOS();
+
+ final int temp = locals.tempIndex(node);
+ asm.emitStoreLocal(temp);
+
+ for (int i = 0; i < node.expressions.length; i++) {
+ asm.emitPush(temp);
+ _genPushInt(i);
+ node.expressions[i].accept(this);
+ asm.emitStoreIndexedTOS();
+ }
+
+ _genStaticCall(interpolate, new ConstantArgDesc(1), 1);
+ }
+ }
+
+ @override
+ visitStringLiteral(StringLiteral node) {
+ final cpIndex = cp.add(new ConstantString.fromLiteral(node));
+ asm.emitPushConstant(cpIndex);
+ }
+
+ @override
+ visitSymbolLiteral(SymbolLiteral node) {
+ final cpIndex = cp.add(new ConstantSymbol.fromLiteral(node));
+ asm.emitPushConstant(cpIndex);
+ }
+
+ @override
+ visitThisExpression(ThisExpression node) {
+ // TODO(alexmarkov): access to captured this from closures.
+ asm.emitPush(locals.thisVarIndex);
+ }
+
+ @override
+ visitThrow(Throw node) {
+ node.expression.accept(this);
+ asm.emitThrow(0);
+ }
+
+ @override
+ visitTypeLiteral(TypeLiteral node) {
+ final DartType type = node.type;
+ final int typeCPIndex = cp.add(new ConstantType(type));
+ if (!hasTypeParameters([type])) {
+ asm.emitPushConstant(typeCPIndex);
+ } else {
+ // TODO(alexmarkov): do not load instantiator type arguments / function type
+ // arguments if they are not needed for this particular [type].
+ _genPushInstantiatorTypeArguments();
+ _genPushFunctionTypeArguments();
+ asm.emitInstantiateType(typeCPIndex);
+ }
+ }
+
+ @override
+ visitVariableGet(VariableGet node) {
+ if (node.variable.isConst) {
+ _genPushConstExpr(node.variable.initializer);
+ } else {
+ // TODO(alexmarkov): access to captured variables.
+ asm.emitPush(locals.varIndex(node.variable));
+ }
+ }
+
+ @override
+ visitVariableSet(VariableSet node) {
+ node.value.accept(this);
+ // TODO(alexmarkov): access to captured variables.
+ asm.emitStoreLocal(locals.varIndex(node.variable));
+ }
+
+// @override
+// visitLoadLibrary(LoadLibrary node) {
+// }
+//
+// @override
+// visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) {
+// }
+//
+// @override
+// visitVectorCreation(VectorCreation node) {
+// }
+//
+// @override
+// visitVectorGet(VectorGet node) {
+// }
+//
+// @override
+// visitVectorSet(VectorSet node) {
+// }
+//
+// @override
+// visitVectorCopy(VectorCopy node) {
+// }
+//
+// @override
+// visitClosureCreation(ClosureCreation node) {
+// }
+
+ @override
+ visitAssertStatement(AssertStatement node) {
+ // TODO(alexmarkov): support asserts
+ }
+
+ @override
+ visitBlock(Block node) {
+ visitList(node.statements, this);
+ }
+
+ @override
+ visitAssertBlock(AssertBlock node) {
+ // TODO(alexmarkov): support asserts
+ }
+
+ @override
+ visitBreakStatement(BreakStatement node) {
+ // TODO(alexmarkov): execute all finally blocks on the way out.
+ final label = labeledStatements[node.target] ??
+ (throw 'Target label ${node.target} was not registered for break $node');
+ asm.emitJump(label);
+ }
+
+ @override
+ visitContinueSwitchStatement(ContinueSwitchStatement node) {
+ // TODO(alexmarkov): execute all finally blocks on the way out.
+ final label = switchCases[node.target] ??
+ (throw 'Target label ${node.target} was not registered for continue-switch $node');
+ asm.emitJump(label);
+ }
+
+ @override
+ visitDoStatement(DoStatement node) {
+ final Label join = new Label();
+ asm.bind(join);
+
+ asm.emitCheckStack();
+
+ node.body.accept(this);
+
+ // TODO(alexmarkov): do we need to break this critical edge in CFG?
+ bool negated = _genCondition(node.condition);
+ _genJumpIfTrue(negated, join);
+ }
+
+ @override
+ visitEmptyStatement(EmptyStatement node) {
+ // no-op
+ }
+
+ @override
+ visitExpressionStatement(ExpressionStatement node) {
+ node.expression.accept(this);
+ asm.emitDrop1();
+ }
+
+ @override
+ visitForInStatement(ForInStatement node) {
+ node.iterable.accept(this);
+
+ const kIterator = 'iterator'; // Iterable.iterator
+ const kMoveNext = 'moveNext'; // Iterator.moveNext
+ const kCurrent = 'current'; // Iterator.current
+
+ asm.emitInstanceCall1(
+ 1,
+ cp.add(new ConstantICData(
+ '$kGetterPrefix$kIterator', cp.add(new ConstantArgDesc(1)))));
+
+ final iteratorTemp = locals.tempIndex(node);
+ asm.emitPopLocal(iteratorTemp);
+
+ final Label done = new Label();
+ final Label join = new Label();
+ asm.bind(join);
+
+ asm.emitCheckStack();
+
+ asm.emitPush(iteratorTemp);
+ asm.emitInstanceCall1(1,
+ cp.add(new ConstantICData(kMoveNext, cp.add(new ConstantArgDesc(1)))));
+ _genJumpIfFalse(/* negated = */ false, done);
+
+ asm.emitPush(iteratorTemp);
+ asm.emitInstanceCall1(1,
+ cp.add(new ConstantICData(kCurrent, cp.add(new ConstantArgDesc(1)))));
+ asm.emitPopLocal(locals.varIndex(node.variable));
+
+ node.body.accept(this);
+
+ asm.emitJump(join);
+
+ asm.bind(done);
+ }
+
+ @override
+ visitForStatement(ForStatement node) {
+ visitList(node.variables, this);
+
+ final Label done = new Label();
+ final Label join = new Label();
+ asm.bind(join);
+
+ asm.emitCheckStack();
+
+ if (node.condition != null) {
+ bool negated = _genCondition(node.condition);
+ _genJumpIfFalse(negated, done);
+ }
+
+ node.body.accept(this);
+
+ for (var update in node.updates) {
+ update.accept(this);
+ asm.emitDrop1();
+ }
+
+ asm.emitJump(join);
+
+ asm.bind(done);
+ }
+
+// @override
+// visitFunctionDeclaration(FunctionDeclaration node) {
+// }
+
+ @override
+ visitIfStatement(IfStatement node) {
+ final Label otherwisePart = new Label();
+
+ final bool negated = _genCondition(node.condition);
+ _genJumpIfFalse(negated, otherwisePart);
+
+ node.then.accept(this);
+
+ if (node.otherwise != null) {
+ final Label done = new Label();
+ asm.emitJump(done);
+ asm.bind(otherwisePart);
+ node.otherwise.accept(this);
+ asm.bind(done);
+ } else {
+ asm.bind(otherwisePart);
+ }
+ }
+
+ @override
+ visitLabeledStatement(LabeledStatement node) {
+ final label = new Label();
+ labeledStatements[node] = label;
+ node.body.accept(this);
+ asm.bind(label);
+ labeledStatements[node] = null;
+ }
+
+ @override
+ visitReturnStatement(ReturnStatement node) {
+ if (node.expression != null) {
+ node.expression.accept(this);
+ } else {
+ _genPushNull();
+ }
+ asm.emitReturnTOS();
+ }
+
+ @override
+ visitSwitchStatement(SwitchStatement node) {
+ node.expression.accept(this);
+
+ final int temp = locals.tempIndex(node);
+ asm.emitPopLocal(temp);
+
+ final Label done = new Label();
+ final List<Label> caseLabels =
+ new List<Label>.generate(node.cases.length, (_) => new Label());
+ final equalsArgDesc = cp.add(new ConstantArgDesc(2));
+
+ Label defaultLabel = done;
+ for (int i = 0; i < node.cases.length; i++) {
+ final SwitchCase switchCase = node.cases[i];
+ final Label caseLabel = caseLabels[i];
+ switchCases[switchCase] = caseLabel;
+
+ if (switchCase.isDefault) {
+ defaultLabel = caseLabel;
+ } else {
+ for (var expr in switchCase.expressions) {
+ asm.emitPush(temp);
+ _genPushConstExpr(expr);
+ asm.emitInstanceCall2(
+ 2, cp.add(new ConstantICData('==', equalsArgDesc)));
+ _genJumpIfTrue(/* negated = */ false, caseLabel);
+ }
+ }
+ }
+
+ asm.emitJump(defaultLabel);
+
+ for (int i = 0; i < node.cases.length; i++) {
+ final SwitchCase switchCase = node.cases[i];
+ final Label caseLabel = caseLabels[i];
+
+ asm.bind(caseLabel);
+ switchCase.body.accept(this);
+
+ // Front-end issues a compile-time error if there is a fallthrough
+ // between cases. Also, default case should be the last one.
+ }
+
+ asm.bind(done);
+ node.cases.forEach(switchCases.remove);
+ }
+
+// @override
+// visitTryCatch(TryCatch node) {
+// }
+//
+// @override
+// visitTryFinally(TryFinally node) {
+// }
+
+ @override
+ visitVariableDeclaration(VariableDeclaration node) {
+ if (node.isConst) {
+ final Constant constant = constantEvaluator.evaluate(node.initializer);
+ constantEvaluator.env.addVariableValue(node, constant);
+ } else {
+ if (node.initializer != null) {
+ node.initializer.accept(this);
+ } else {
+ _genPushNull();
+ }
+ asm.emitPopLocal(locals.varIndex(node));
+ }
+ }
+
+ @override
+ visitWhileStatement(WhileStatement node) {
+ final Label done = new Label();
+ final Label join = new Label();
+ asm.bind(join);
+
+ asm.emitCheckStack();
+
+ bool negated = _genCondition(node.condition);
+ _genJumpIfFalse(negated, done);
+
+ node.body.accept(this);
+
+ asm.emitJump(join);
+
+ asm.bind(done);
+ }
+
+// @override
+// visitYieldStatement(YieldStatement node) {
+// }
+
+ @override
+ visitFieldInitializer(FieldInitializer node) {
+ _genFieldInitializer(node.field, node.value);
+ }
+
+ @override
+ visitRedirectingInitializer(RedirectingInitializer node) {
+ final args = node.arguments;
+ assert(args.types.isEmpty);
+ _genArguments(new ThisExpression(), args);
+ _genStaticCallWithArgs(node.target, args, hasReceiver: true);
+ asm.emitDrop1();
+ }
+
+ @override
+ visitSuperInitializer(SuperInitializer node) {
+ final args = node.arguments;
+ assert(args.types.isEmpty);
+ _genArguments(new ThisExpression(), args);
+ // Re-resolve target due to partial mixin resolution.
+ Member target;
+ for (var replacement in enclosingClass.superclass.constructors) {
+ if (node.target.name == replacement.name) {
+ target = replacement;
+ break;
+ }
+ }
+ assert(target != null);
+ _genStaticCallWithArgs(target, args, hasReceiver: true);
+ asm.emitDrop1();
+ }
+
+// @override
+// visitLocalInitializer(LocalInitializer node) {
+// }
+//
+// @override
+// visitAssertInitializer(AssertInitializer node) {
+// }
+//
+// @override
+// visitInvalidInitializer(InvalidInitializer node) {}
+
+ @override
+ visitConstantExpression(ConstantExpression node) {
+ int cpIndex = node.constant.accept(constantEmitter);
+ asm.emitPushConstant(cpIndex);
+ }
+}
+
+class ConstantEmitter extends ConstantVisitor<int> {
+ final ConstantPool cp;
+
+ ConstantEmitter(this.cp);
+
+ @override
+ int defaultConstant(Constant node) => throw new UnsupportedOperationError(
+ 'Unsupported constant node ${node.runtimeType}');
+
+ @override
+ int visitNullConstant(NullConstant node) => cp.add(const ConstantNull());
+
+ @override
+ int visitBoolConstant(BoolConstant node) =>
+ cp.add(new ConstantBool(node.value));
+
+ @override
+ int visitIntConstant(IntConstant node) => cp.add(new ConstantInt(node.value));
+
+ @override
+ int visitDoubleConstant(DoubleConstant node) =>
+ cp.add(new ConstantDouble(node.value));
+
+ @override
+ int visitStringConstant(StringConstant node) =>
+ cp.add(new ConstantString(node.value));
+
+ @override
+ int visitListConstant(ListConstant node) => cp.add(new ConstantList(
+ node.typeArgument,
+ new List<int>.from(node.entries.map((Constant c) => c.accept(this)))));
+
+ @override
+ int visitInstanceConstant(InstanceConstant node) =>
+ cp.add(new ConstantInstance(
+ node.klass,
+ cp.add(new ConstantTypeArguments(node.typeArguments)),
+ node.fieldValues.map<Reference, int>(
+ (Reference fieldRef, Constant value) =>
+ new MapEntry(fieldRef, value.accept(this)))));
+
+ @override
+ int visitTearOffConstant(TearOffConstant node) =>
+ cp.add(new ConstantTearOff(node.procedure));
+
+// @override
+// int visitTypeLiteralConstant(TypeLiteralConstant node) => defaultConstant(node);
+}
+
+class UnsupportedOperationError {
+ final String message;
+ UnsupportedOperationError(this.message);
+
+ @override
+ String toString() => message;
+}
+
+class FindTypeParametersVisitor extends DartTypeVisitor<bool> {
+ bool visit(DartType type) => type.accept(this);
+
+ @override
+ bool defaultDartType(DartType node) =>
+ throw 'Unexpected type ${node.runtimeType} $node';
+
+ @override
+ bool visitInvalidType(InvalidType node) => false;
+
+ @override
+ bool visitDynamicType(DynamicType node) => false;
+
+ @override
+ bool visitVoidType(VoidType node) => false;
+
+ @override
+ bool visitBottomType(BottomType node) => false;
+
+ @override
+ bool visitVectorType(VectorType node) => false;
+
+ @override
+ bool visitTypeParameterType(TypeParameterType node) => true;
+
+ @override
+ bool visitInterfaceType(InterfaceType node) =>
+ node.typeArguments.any((t) => t.accept(this));
+
+ @override
+ bool visitTypedefType(TypedefType node) =>
+ node.typeArguments.any((t) => t.accept(this));
+
+ @override
+ bool visitFunctionType(FunctionType node) =>
+ node.typeParameters.isNotEmpty ||
+ node.positionalParameters.any((t) => t.accept(this)) ||
+ node.namedParameters.any((p) => p.type.accept(this));
+}
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
new file mode 100644
index 0000000..578cbc6
--- /dev/null
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -0,0 +1,238 @@
+// 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 vm.bytecode.local_vars;
+
+import 'dart:math' show max;
+
+import 'package:kernel/ast.dart';
+import 'package:vm/bytecode/dbc.dart';
+
+class LocalVariables extends RecursiveVisitor<Null> {
+ final Map<VariableDeclaration, int> _vars = <VariableDeclaration, int>{};
+ final Map<TreeNode, int> _temps = <TreeNode, int>{};
+ final List<int> _scopes = <int>[];
+ int _localVars = 0;
+ int _frameSize = 0;
+ int _numParameters = 0;
+ bool _hasOptionalParameters = false;
+ int _thisVarIndex;
+ int _functionTypeArgsVarIndex;
+
+ int get thisVarIndex =>
+ _thisVarIndex ?? (throw '\'this\' variable is not allocated');
+
+ int get functionTypeArgsVarIndex =>
+ _functionTypeArgsVarIndex ??
+ (throw '\'functionTypeArgs\' variable is not allocated');
+
+ int get frameSize => _frameSize;
+
+ int get numParameters => _numParameters;
+
+ bool get hasOptionalParameters => _hasOptionalParameters;
+
+ int varIndex(VariableDeclaration variable) =>
+ _vars[variable] ?? (throw '\'$variable\' variable is not allocated');
+
+ int tempIndex(TreeNode node) =>
+ _temps[node] ??
+ (throw 'Temp is not allocated for node ${node.runtimeType} $node');
+
+ int _allocateVar(VariableDeclaration node, {int index}) {
+ if (index == null) {
+ index = _localVars++;
+ } else {
+ // Should be a parameter.
+ assert(index < 0 || (_hasOptionalParameters && index < _numParameters));
+ }
+ _frameSize = max(_frameSize, _localVars);
+ if (node != null) {
+ assert(_vars[node] == null);
+ _vars[node] = index;
+ }
+ return index;
+ }
+
+ // TODO(alexmarkov): allocate temporaries more efficiently.
+ void _allocateTemp(TreeNode node) {
+ _temps[node] = _allocateVar(null);
+ }
+
+ int _allocateParameter(VariableDeclaration node, int i) {
+ assert(0 <= i && i < _numParameters);
+ int paramSlotIndex =
+ _hasOptionalParameters ? i : -kParamEndSlotFromFp - _numParameters + i;
+ return _allocateVar(node, index: paramSlotIndex);
+ }
+
+ void _enterScope() {
+ _scopes.add(_localVars);
+ }
+
+ void _leaveScope() {
+ final int enclosingScopeLocalVars = _scopes.removeLast();
+ assert(_localVars >= enclosingScopeLocalVars);
+ _localVars = enclosingScopeLocalVars;
+ }
+
+ @override
+ visitField(Field node) {
+ if (node.initializer != null) {
+ assert(_vars.isEmpty);
+ assert(_localVars == 0);
+
+ _enterScope();
+ node.initializer.accept(this);
+ _leaveScope();
+
+ assert(_scopes.isEmpty);
+ }
+ }
+
+ @override
+ defaultMember(Member node) {
+ assert(_vars.isEmpty);
+ assert(_localVars == 0);
+
+ final function = node.function;
+ final bool hasTypeArgs = function.typeParameters.isNotEmpty;
+ final bool hasReceiver =
+ node is Constructor || ((node is Procedure) && !node.isStatic);
+ _numParameters = function.positionalParameters.length +
+ function.namedParameters.length +
+ (hasTypeArgs ? 1 : 0) +
+ (hasReceiver ? 1 : 0);
+ _hasOptionalParameters = function.requiredParameterCount <
+ function.positionalParameters.length ||
+ function.namedParameters.isNotEmpty;
+ int count = 0;
+
+ if (hasTypeArgs) {
+ _functionTypeArgsVarIndex = _allocateParameter(null, count++);
+ }
+
+ if (hasReceiver) {
+ _thisVarIndex = _allocateParameter(null, count++);
+ }
+
+ for (var param in function.positionalParameters) {
+ _allocateParameter(param, count++);
+ }
+
+ List<VariableDeclaration> namedParams = function.namedParameters;
+ namedParams.sort((VariableDeclaration a, VariableDeclaration b) =>
+ a.name.compareTo(b.name));
+ for (var param in namedParams) {
+ _allocateParameter(param, count++);
+ }
+
+ if (_hasOptionalParameters) {
+ _localVars = _numParameters;
+ _frameSize = _numParameters;
+ }
+
+ _enterScope();
+ if (node is Constructor) {
+ _enterScope();
+ for (var field in node.enclosingClass.fields) {
+ if (!field.isStatic && field.initializer != null) {
+ field.initializer.accept(this);
+ }
+ }
+ visitList(node.initializers, this);
+ _leaveScope();
+ }
+ function.body?.accept(this);
+ _leaveScope();
+
+ assert(_scopes.isEmpty);
+ }
+
+ @override
+ visitBlock(Block node) {
+ _enterScope();
+ node.visitChildren(this);
+ _leaveScope();
+ }
+
+ @override
+ visitVariableDeclaration(VariableDeclaration node) {
+ _allocateVar(node);
+ node.visitChildren(this);
+ }
+
+ @override
+ visitLet(Let node) {
+ _enterScope();
+ node.variable.accept(this);
+ node.body.accept(this);
+ _leaveScope();
+ }
+
+ // -------------- Allocation of temporaries --------------
+
+ @override
+ visitConstructorInvocation(ConstructorInvocation node) {
+ if (node.isConst) {
+ return;
+ }
+ _allocateTemp(node);
+ super.visitConstructorInvocation(node);
+ }
+
+ @override
+ visitListLiteral(ListLiteral node) {
+ if (node.isConst) {
+ return;
+ }
+ _allocateTemp(node);
+ super.visitListLiteral(node);
+ }
+
+ @override
+ visitMapLiteral(MapLiteral node) {
+ if (node.isConst) {
+ return;
+ }
+ _allocateTemp(node);
+ super.visitMapLiteral(node);
+ }
+
+ @override
+ visitStringConcatenation(StringConcatenation node) {
+ _allocateTemp(node);
+ super.visitStringConcatenation(node);
+ }
+
+ @override
+ visitConditionalExpression(ConditionalExpression node) {
+ _allocateTemp(node);
+ super.visitConditionalExpression(node);
+ }
+
+ @override
+ visitLogicalExpression(LogicalExpression node) {
+ _allocateTemp(node);
+ super.visitLogicalExpression(node);
+ }
+
+ @override
+ visitPropertySet(PropertySet node) {
+ _allocateTemp(node);
+ super.visitPropertySet(node);
+ }
+
+ @override
+ visitForInStatement(ForInStatement node) {
+ _allocateTemp(node);
+ super.visitForInStatement(node);
+ }
+
+ @override
+ visitSwitchStatement(SwitchStatement node) {
+ _allocateTemp(node);
+ super.visitSwitchStatement(node);
+ }
+}
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 026a99e..8bf56e0 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -16,6 +16,7 @@
import 'package:front_end/src/fasta/severity.dart' show Severity;
import 'package:kernel/ast.dart' show Component, StaticGet, Field;
import 'package:kernel/core_types.dart' show CoreTypes;
+import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
import 'transformations/devirtualization.dart' as devirtualization
show transformComponent;
@@ -34,7 +35,8 @@
Future<Component> compileToKernel(Uri source, CompilerOptions options,
{bool aot: false,
bool useGlobalTypeFlowAnalysis: false,
- List<String> entryPoints}) async {
+ List<String> entryPoints,
+ bool genBytecode: false}) async {
// Replace error handler to detect if there are compilation errors.
final errorDetector =
new ErrorDetector(previousErrorHandler: options.onError);
@@ -51,6 +53,10 @@
component, options.strongMode, useGlobalTypeFlowAnalysis, entryPoints);
}
+ if (genBytecode && component != null) {
+ generateBytecode(component, strongMode: options.strongMode);
+ }
+
return component;
}
diff --git a/pkg/vm/lib/metadata/bytecode.dart b/pkg/vm/lib/metadata/bytecode.dart
new file mode 100644
index 0000000..1c28c0e
--- /dev/null
+++ b/pkg/vm/lib/metadata/bytecode.dart
@@ -0,0 +1,44 @@
+// 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 vm.metadata.bytecode;
+
+import 'package:kernel/ast.dart';
+import 'package:vm/bytecode/constant_pool.dart' show ConstantPool;
+import 'package:vm/bytecode/disassembler.dart' show BytecodeDisassembler;
+
+/// Metadata containing bytecode.
+class BytecodeMetadata {
+ final List<int> bytecodes;
+ final ConstantPool constantPool;
+
+ BytecodeMetadata(this.bytecodes, this.constantPool);
+
+ @override
+ String toString() =>
+ "\nBytecode {\n${new BytecodeDisassembler().disassemble(bytecodes)}}\n$constantPool";
+}
+
+/// Repository for [BytecodeMetadata].
+class BytecodeMetadataRepository extends MetadataRepository<BytecodeMetadata> {
+ @override
+ final String tag = 'vm.bytecode';
+
+ @override
+ final Map<TreeNode, BytecodeMetadata> mapping =
+ <TreeNode, BytecodeMetadata>{};
+
+ @override
+ void writeToBinary(BytecodeMetadata metadata, BinarySink sink) {
+ sink.writeByteList(metadata.bytecodes);
+ metadata.constantPool.writeToBinary(sink);
+ }
+
+ @override
+ BytecodeMetadata readFromBinary(BinarySource source) {
+ final List<int> bytecodes = source.readByteList();
+ final ConstantPool constantPool = new ConstantPool.readFromBinary(source);
+ return new BytecodeMetadata(bytecodes, constantPool);
+ }
+}
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 4d4ce33..0ff8ba4 100644
--- a/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
+++ b/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
@@ -95,6 +95,12 @@
{
"library": "dart:core",
"class": "_Closure",
+ "name": "_delayed_type_arguments",
+ "action": "get"
+ },
+ {
+ "library": "dart:core",
+ "class": "_Closure",
"name": "_function",
"action": "get"
},
diff --git a/pkg/vm/test/bytecode/gen_bytecode_test.dart b/pkg/vm/test/bytecode/gen_bytecode_test.dart
new file mode 100644
index 0000000..3ee9d45
--- /dev/null
+++ b/pkg/vm/test/bytecode/gen_bytecode_test.dart
@@ -0,0 +1,36 @@
+// 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:io';
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/kernel.dart';
+import 'package:test/test.dart';
+import 'package:vm/bytecode/gen_bytecode.dart' show generateBytecode;
+
+import '../common_test_utils.dart';
+
+final String pkgVmDir = Platform.script.resolve('../..').toFilePath();
+
+runTestCase(Uri source) async {
+ Component component = await compileTestCaseToKernelProgram(source);
+
+ generateBytecode(component, strongMode: true);
+
+ final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
+ compareResultWithExpectationsFile(source, actual);
+}
+
+main() {
+ group('gen-bytecode', () {
+ final testCasesDir = new Directory(pkgVmDir + '/testcases/bytecode');
+
+ for (var entry
+ in testCasesDir.listSync(recursive: true, followLinks: false)) {
+ if (entry.path.endsWith(".dart")) {
+ test(entry.path, () => runTestCase(entry.uri));
+ }
+ }
+ });
+}
diff --git a/pkg/vm/test/transformations/type_flow/common_test_utils.dart b/pkg/vm/test/common_test_utils.dart
similarity index 74%
rename from pkg/vm/test/transformations/type_flow/common_test_utils.dart
rename to pkg/vm/test/common_test_utils.dart
index cdac3b9..20b0126 100644
--- a/pkg/vm/test/transformations/type_flow/common_test_utils.dart
+++ b/pkg/vm/test/common_test_utils.dart
@@ -9,6 +9,7 @@
import 'package:front_end/src/compute_platform_binaries_location.dart'
show computePlatformBinariesLocation;
import 'package:kernel/ast.dart';
+import 'package:kernel/text/ast_to_text.dart' show Printer;
import 'package:kernel/target/targets.dart';
import 'package:kernel/target/vm.dart';
import 'package:test/test.dart';
@@ -26,7 +27,21 @@
..onError = (CompilationMessage error) {
fail("Compilation error: ${error}");
};
- return kernelForProgram(sourceUri, options);
+
+ final Component component = await kernelForProgram(sourceUri, options);
+
+ // Make sure the library name is the same and does not depend on the order
+ // of test cases.
+ component.mainMethod.enclosingLibrary.name = '#lib';
+
+ return component;
+}
+
+String kernelLibraryToString(Library library) {
+ final StringBuffer buffer = new StringBuffer();
+ new Printer(buffer, showExternal: false, showMetadata: true)
+ .writeLibraryFile(library);
+ return buffer.toString();
}
void compareResultWithExpectationsFile(Uri source, String actual) {
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index 9d4499b..369c421 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -12,7 +12,7 @@
import 'package:vm/transformations/type_flow/native_code.dart';
import 'package:vm/transformations/type_flow/summary_collector.dart';
-import 'common_test_utils.dart';
+import '../../common_test_utils.dart';
final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
@@ -43,10 +43,6 @@
final Component component = await compileTestCaseToKernelProgram(source);
final Library library = component.mainMethod.enclosingLibrary;
- // Make sure the library name is the same and does not depend on the order
- // of test cases.
- library.name = '#lib';
-
final typeEnvironment = new TypeEnvironment(
new CoreTypes(component), new ClassHierarchy(component));
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 45a1855..07dcb37 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -7,22 +7,17 @@
import 'package:kernel/ast.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
-import 'package:kernel/text/ast_to_text.dart';
import 'package:test/test.dart';
import 'package:vm/transformations/type_flow/transformer.dart'
show transformComponent;
-import 'common_test_utils.dart';
+import '../../common_test_utils.dart';
final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
runTestCase(Uri source) async {
Component component = await compileTestCaseToKernelProgram(source);
- // Make sure the library name is the same and does not depend on the order
- // of test cases.
- component.mainMethod.enclosingLibrary.name = '#lib';
-
final coreTypes = new CoreTypes(component);
final entryPoints = [
@@ -32,10 +27,7 @@
component = transformComponent(coreTypes, component, entryPoints);
- final StringBuffer buffer = new StringBuffer();
- new Printer(buffer, showExternal: false, showMetadata: true)
- .writeLibraryFile(component.mainMethod.enclosingLibrary);
- final actual = buffer.toString();
+ final actual = kernelLibraryToString(component.mainMethod.enclosingLibrary);
compareResultWithExpectationsFile(source, actual);
}
diff --git a/pkg/vm/testcases/bytecode/boostrapping.dart b/pkg/vm/testcases/bytecode/boostrapping.dart
new file mode 100644
index 0000000..8f79be8
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/boostrapping.dart
@@ -0,0 +1,142 @@
+// 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.
+
+// Selection of methods used during bootstrapping.
+
+// ignore_for_file: native_function_body_in_non_sdk_code
+// ignore_for_file: unused_element, unused_field
+
+// -----------------------------------------------------------------
+
+void _printString(String s) native "Builtin_PrintString";
+
+void _print(arg) {
+ _printString(arg.toString());
+}
+
+_getPrintClosure() => _print;
+
+// -----------------------------------------------------------------
+
+typedef void _ScheduleImmediateClosure(void callback());
+
+class _ScheduleImmediate {
+ static _ScheduleImmediateClosure _closure;
+}
+
+void _setScheduleImmediateClosure(_ScheduleImmediateClosure closure) {
+ _ScheduleImmediate._closure = closure;
+}
+
+// -----------------------------------------------------------------
+
+class _NamespaceImpl implements _Namespace {
+ _NamespaceImpl._();
+
+ static _NamespaceImpl _create(_NamespaceImpl namespace, var n)
+ native "Namespace_Create";
+ static int _getPointer(_NamespaceImpl namespace)
+ native "Namespace_GetPointer";
+ static int _getDefault() native "Namespace_GetDefault";
+
+ // If the platform supports "namespaces", this method is called by the
+ // embedder with the platform-specific namespace information.
+ static _NamespaceImpl _cachedNamespace = null;
+ static void _setupNamespace(var namespace) {
+ _cachedNamespace = _create(new _NamespaceImpl._(), namespace);
+ }
+
+ static _NamespaceImpl get _namespace {
+ if (_cachedNamespace == null) {
+ // The embedder has not supplied a namespace before one is needed, so
+ // instead use a safe-ish default value.
+ _cachedNamespace = _create(new _NamespaceImpl._(), _getDefault());
+ }
+ return _cachedNamespace;
+ }
+
+ static int get _namespacePointer => _getPointer(_namespace);
+}
+
+class _Namespace {
+ static void _setupNamespace(var namespace) {
+ _NamespaceImpl._setupNamespace(namespace);
+ }
+
+ static _Namespace get _namespace => _NamespaceImpl._namespace;
+
+ static int get _namespacePointer => _NamespaceImpl._namespacePointer;
+}
+
+// -----------------------------------------------------------------
+
+// These may be set to different values by the embedder by calling
+// _setStdioFDs when initializing dart:io.
+int _stdinFD = 0;
+int _stdoutFD = 1;
+int _stderrFD = 2;
+
+// This is an embedder entrypoint.
+void _setStdioFDs(int stdin, int stdout, int stderr) {
+ _stdinFD = stdin;
+ _stdoutFD = stdout;
+ _stderrFD = stderr;
+}
+
+// -----------------------------------------------------------------
+
+class VMLibraryHooks {
+ // Example: "dart:isolate _Timer._factory"
+ static var timerFactory;
+
+ // Example: "dart:io _EventHandler._sendData"
+ static var eventHandlerSendData;
+
+ // A nullary closure that answers the current clock value in milliseconds.
+ // Example: "dart:io _EventHandler._timerMillisecondClock"
+ static var timerMillisecondClock;
+
+ // Implementation of Resource.readAsBytes.
+ static var resourceReadAsBytes;
+
+ // Implementation of package root/map provision.
+ static var packageRootString;
+ static var packageConfigString;
+ static var packageRootUriFuture;
+ static var packageConfigUriFuture;
+ static var resolvePackageUriFuture;
+
+ static var _computeScriptUri;
+ static var _cachedScript;
+ static set platformScript(var f) {
+ _computeScriptUri = f;
+ _cachedScript = null;
+ }
+
+ static get platformScript {
+ if (_cachedScript == null && _computeScriptUri != null) {
+ _cachedScript = _computeScriptUri();
+ }
+ return _cachedScript;
+ }
+}
+
+String _rawScript;
+Uri _scriptUri() {
+ if (_rawScript.startsWith('http:') ||
+ _rawScript.startsWith('https:') ||
+ _rawScript.startsWith('file:')) {
+ return Uri.parse(_rawScript);
+ } else {
+ return Uri.base.resolveUri(new Uri.file(_rawScript));
+ }
+}
+
+_setupHooks() {
+ VMLibraryHooks.platformScript = _scriptUri;
+}
+
+// -----------------------------------------------------------------
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/boostrapping.dart.expect b/pkg/vm/testcases/bytecode/boostrapping.dart.expect
new file mode 100644
index 0000000..8070f3e
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/boostrapping.dart.expect
@@ -0,0 +1,742 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:_internal" as _in;
+
+typedef _ScheduleImmediateClosure = (() → void) → void;
+class _ScheduleImmediate extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field (() → void) → void _closure = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class _NamespaceImpl extends core::Object implements self::_Namespace {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field self::_NamespaceImpl _cachedNamespace = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] constructor _() → void
+ : super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] @_in::ExternalName::•("Namespace_Create")
+ external static method _create(self::_NamespaceImpl namespace, dynamic n) → self::_NamespaceImpl;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] @_in::ExternalName::•("Namespace_GetPointer")
+ external static method _getPointer(self::_NamespaceImpl namespace) → core::int;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] @_in::ExternalName::•("Namespace_GetDefault")
+ external static method _getDefault() → core::int;
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ Allocate CP#0
+ StoreLocal r0
+ Push r0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ Push FP[-5]
+ PushConstant CP#4
+ IndirectStaticCall 2, CP#3
+ StoreStaticTOS CP#5
+ Drop1
+ PushConstant CP#6
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Class #lib::_NamespaceImpl
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target '#lib::_NamespaceImpl::_', arg-desc CP#1
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#3
+ [5] = Field #lib::_NamespaceImpl::_cachedNamespace
+ [6] = Null
+}
+] static method _setupNamespace(dynamic namespace) → void {
+ self::_NamespaceImpl::_cachedNamespace = self::_NamespaceImpl::_create(new self::_NamespaceImpl::_(), namespace);
+ }
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ PushConstant CP#0
+ PushStatic CP#0
+ PushConstant CP#1
+ InstanceCall1 2, CP#3
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L1
+ Allocate CP#5
+ StoreLocal r0
+ Push r0
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#6
+ Drop1
+ PushConstant CP#9
+ IndirectStaticCall 0, CP#8
+ PushConstant CP#10
+ IndirectStaticCall 2, CP#2
+ StoreStaticTOS CP#0
+ Drop1
+L1:
+ PushConstant CP#0
+ PushStatic CP#0
+ ReturnTOS
+ PushConstant CP#1
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Field #lib::_NamespaceImpl::_cachedNamespace
+ [1] = Null
+ [2] = ArgDesc num-args 2, num-type-args 0, names []
+ [3] = ICData target-name '==', arg-desc CP#2
+ [4] = Bool true
+ [5] = Class #lib::_NamespaceImpl
+ [6] = ArgDesc num-args 1, num-type-args 0, names []
+ [7] = StaticICData target '#lib::_NamespaceImpl::_', arg-desc CP#6
+ [8] = ArgDesc num-args 0, num-type-args 0, names []
+ [9] = StaticICData target '#lib::_NamespaceImpl::_getDefault', arg-desc CP#8
+ [10] = StaticICData target '#lib::_NamespaceImpl::_create', arg-desc CP#2
+}
+] static get _namespace() → self::_NamespaceImpl {
+ if(self::_NamespaceImpl::_cachedNamespace.{core::Object::==}(null)) {
+ self::_NamespaceImpl::_cachedNamespace = self::_NamespaceImpl::_create(new self::_NamespaceImpl::_(), self::_NamespaceImpl::_getDefault());
+ }
+ return self::_NamespaceImpl::_cachedNamespace;
+ }
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#1
+ IndirectStaticCall 0, CP#0
+ PushConstant CP#3
+ IndirectStaticCall 1, CP#2
+ ReturnTOS
+ PushConstant CP#4
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 0, num-type-args 0, names []
+ [1] = StaticICData target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
+ [2] = ArgDesc num-args 1, num-type-args 0, names []
+ [3] = StaticICData target '#lib::_NamespaceImpl::_getPointer', arg-desc CP#2
+ [4] = Null
+}
+] static get _namespacePointer() → core::int
+ return self::_NamespaceImpl::_getPointer(self::_NamespaceImpl::_namespace);
+}
+class _Namespace extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target '#lib::_NamespaceImpl::_setupNamespace', arg-desc CP#0
+ [2] = Null
+}
+] static method _setupNamespace(dynamic namespace) → void {
+ self::_NamespaceImpl::_setupNamespace(namespace);
+ }
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#1
+ IndirectStaticCall 0, CP#0
+ ReturnTOS
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 0, num-type-args 0, names []
+ [1] = StaticICData target '#lib::_NamespaceImpl::_namespace', arg-desc CP#0
+ [2] = Null
+}
+] static get _namespace() → self::_Namespace
+ return self::_NamespaceImpl::_namespace;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#1
+ IndirectStaticCall 0, CP#0
+ ReturnTOS
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 0, num-type-args 0, names []
+ [1] = StaticICData target '#lib::_NamespaceImpl::_namespacePointer', arg-desc CP#0
+ [2] = Null
+}
+] static get _namespacePointer() → core::int
+ return self::_NamespaceImpl::_namespacePointer;
+}
+class VMLibraryHooks extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic timerFactory = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic eventHandlerSendData = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic timerMillisecondClock = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic resourceReadAsBytes = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic packageRootString = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic packageConfigString = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic packageRootUriFuture = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic packageConfigUriFuture = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic resolvePackageUriFuture = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic _computeScriptUri = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+] static field dynamic _cachedScript = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ StoreStaticTOS CP#0
+ Drop1
+ PushConstant CP#1
+ StoreStaticTOS CP#2
+ Drop1
+ PushConstant CP#1
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Field #lib::VMLibraryHooks::_computeScriptUri
+ [1] = Null
+ [2] = Field #lib::VMLibraryHooks::_cachedScript
+}
+] static set platformScript(dynamic f) → void {
+ self::VMLibraryHooks::_computeScriptUri = f;
+ self::VMLibraryHooks::_cachedScript = null;
+ }
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ PushConstant CP#0
+ PushStatic CP#0
+ PushConstant CP#1
+ InstanceCall1 2, CP#3
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L1
+ PushConstant CP#5
+ PushStatic CP#5
+ PushConstant CP#1
+ InstanceCall1 2, CP#6
+ BooleanNegateTOS
+ PopLocal r0
+ Jump L2
+L1:
+ PushConstant CP#7
+ PopLocal r0
+L2:
+ Push r0
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L3
+ PushConstant CP#5
+ PushStatic CP#5
+ InstanceCall1 1, CP#9
+ StoreStaticTOS CP#0
+ Drop1
+L3:
+ PushConstant CP#0
+ PushStatic CP#0
+ ReturnTOS
+ PushConstant CP#1
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Field #lib::VMLibraryHooks::_cachedScript
+ [1] = Null
+ [2] = ArgDesc num-args 2, num-type-args 0, names []
+ [3] = ICData target-name '==', arg-desc CP#2
+ [4] = Bool true
+ [5] = Field #lib::VMLibraryHooks::_computeScriptUri
+ [6] = ICData target-name '==', arg-desc CP#2
+ [7] = Bool false
+ [8] = ArgDesc num-args 1, num-type-args 0, names []
+ [9] = ICData target-name 'call', arg-desc CP#8
+}
+] static get platformScript() → dynamic {
+ if(self::VMLibraryHooks::_cachedScript.==(null) && !self::VMLibraryHooks::_computeScriptUri.==(null)) {
+ self::VMLibraryHooks::_cachedScript = self::VMLibraryHooks::_computeScriptUri.call();
+ }
+ return self::VMLibraryHooks::_cachedScript;
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+}
+]static field core::int _stdinFD = 0;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 1
+}
+]static field core::int _stdoutFD = 1;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 2
+}
+]static field core::int _stderrFD = 2;
+static field core::String _rawScript;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]@_in::ExternalName::•("Builtin_PrintString")
+external static method _printString(core::String s) → void;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ InstanceCall1 1, CP#1
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = ICData target-name 'toString', arg-desc CP#0
+ [2] = StaticICData target '#lib::_printString', arg-desc CP#0
+ [3] = Null
+}
+]static method _print(dynamic arg) → void {
+ self::_printString(arg.toString() as{TypeError} core::String);
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+ PushConstant CP#1
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TearOff #lib::_print
+ [1] = Null
+}
+]static method _getPrintClosure() → dynamic
+ return self::_print;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ StoreStaticTOS CP#0
+ Drop1
+ PushConstant CP#1
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Field #lib::_ScheduleImmediate::_closure
+ [1] = Null
+}
+]static method _setScheduleImmediateClosure((() → void) → void closure) → void {
+ self::_ScheduleImmediate::_closure = closure;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-7]
+ StoreStaticTOS CP#0
+ Drop1
+ Push FP[-6]
+ StoreStaticTOS CP#1
+ Drop1
+ Push FP[-5]
+ StoreStaticTOS CP#2
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Field #lib::_stdinFD
+ [1] = Field #lib::_stdoutFD
+ [2] = Field #lib::_stderrFD
+ [3] = Null
+}
+]static method _setStdioFDs(core::int stdin, core::int stdout, core::int stderr) → void {
+ self::_stdinFD = stdin;
+ self::_stdoutFD = stdout;
+ self::_stderrFD = stderr;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PushStatic CP#0
+ PushConstant CP#1
+ InstanceCall1 2, CP#3
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ PushConstant CP#0
+ PushStatic CP#0
+ PushConstant CP#5
+ InstanceCall1 2, CP#6
+ PopLocal r1
+ Jump L2
+L1:
+ PushConstant CP#4
+ PopLocal r1
+L2:
+ Push r1
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L3
+ PushConstant CP#0
+ PushStatic CP#0
+ PushConstant CP#7
+ InstanceCall1 2, CP#8
+ PopLocal r0
+ Jump L4
+L3:
+ PushConstant CP#4
+ PopLocal r0
+L4:
+ Push r0
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L5
+ PushConstant CP#0
+ PushStatic CP#0
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#9
+ ReturnTOS
+ Jump L6
+L5:
+ PushConstant CP#12
+ IndirectStaticCall 0, CP#11
+ PushConstant CP#13
+ PushConstant CP#0
+ PushStatic CP#0
+ PushConstant CP#14
+ IndirectStaticCall 2, CP#9
+ InstanceCall1 2, CP#15
+ ReturnTOS
+L6:
+ PushConstant CP#13
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Field #lib::_rawScript
+ [1] = String 'http:'
+ [2] = ArgDesc num-args 2, num-type-args 0, names []
+ [3] = ICData target-name 'startsWith', arg-desc CP#2
+ [4] = Bool true
+ [5] = String 'https:'
+ [6] = ICData target-name 'startsWith', arg-desc CP#2
+ [7] = String 'file:'
+ [8] = ICData target-name 'startsWith', arg-desc CP#2
+ [9] = ArgDesc num-args 1, num-type-args 0, names []
+ [10] = StaticICData target 'dart.core::Uri::parse', arg-desc CP#9
+ [11] = ArgDesc num-args 0, num-type-args 0, names []
+ [12] = StaticICData target 'dart.core::Uri::base', arg-desc CP#11
+ [13] = Null
+ [14] = StaticICData target 'dart.core::_Uri::file', arg-desc CP#9
+ [15] = ICData target-name 'resolveUri', arg-desc CP#2
+}
+]static method _scriptUri() → core::Uri {
+ if(self::_rawScript.{core::String::startsWith}("http:") || self::_rawScript.{core::String::startsWith}("https:") || self::_rawScript.{core::String::startsWith}("file:")) {
+ return core::Uri::parse(self::_rawScript);
+ }
+ else {
+ return core::Uri::base.{core::Uri::resolveUri}(core::_Uri::file(self::_rawScript));
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TearOff #lib::_scriptUri
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target '#lib::VMLibraryHooks::platformScript', arg-desc CP#1
+ [3] = Null
+}
+]static method _setupHooks() → dynamic {
+ self::VMLibraryHooks::platformScript = self::_scriptUri;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/field_initializers.dart b/pkg/vm/testcases/bytecode/field_initializers.dart
new file mode 100644
index 0000000..6d9f57e
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/field_initializers.dart
@@ -0,0 +1,32 @@
+// 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 foo1;
+ int foo2 = null;
+ int foo3 = 42;
+ int foo4;
+ int foo5 = 43;
+
+ A(this.foo4) : foo5 = 44;
+ A.constr2(int x, int y)
+ : foo1 = x,
+ foo5 = y + 1;
+
+ A.redirecting1() : this(45);
+ A.redirecting2(int a, int b, int c) : this.constr2(a, b * c);
+}
+
+class B extends A {
+ int foo6 = 46;
+ static int foo7 = 47;
+ static const int foo8 = 48;
+
+ B() : super(49);
+ B.c2(int i, int j)
+ : foo6 = 50,
+ super.redirecting2(i, j, 51);
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/field_initializers.dart.expect b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
new file mode 100644
index 0000000..b11ce7f
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/field_initializers.dart.expect
@@ -0,0 +1,217 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ field core::int foo1;
+ field core::int foo2 = null;
+ field core::int foo3 = 42;
+ field core::int foo4;
+ field core::int foo5 = 43;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-6]
+ PushConstant CP#0
+ StoreFieldTOS CP#1
+ Push FP[-6]
+ Push FP[-5]
+ StoreFieldTOS CP#2
+ Push FP[-6]
+ PushConstant CP#3
+ StoreFieldTOS CP#4
+ Push FP[-6]
+ PushConstant CP#6
+ IndirectStaticCall 1, CP#5
+ Drop1
+ PushConstant CP#7
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 42
+ [1] = FieldOffset #lib::A::foo3
+ [2] = FieldOffset #lib::A::foo4
+ [3] = Int 44
+ [4] = FieldOffset #lib::A::foo5
+ [5] = ArgDesc num-args 1, num-type-args 0, names []
+ [6] = StaticICData target 'dart.core::Object::', arg-desc CP#5
+ [7] = Null
+}
+] constructor •(core::int foo4) → void
+ : self::A::foo1 = null, self::A::foo4 = foo4, self::A::foo5 = 44, super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-7]
+ PushConstant CP#0
+ StoreFieldTOS CP#1
+ Push FP[-7]
+ Push FP[-6]
+ StoreFieldTOS CP#2
+ Push FP[-7]
+ Push FP[-5]
+ PushConstant CP#3
+ InstanceCall1 2, CP#5
+ StoreFieldTOS CP#6
+ Push FP[-7]
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#7
+ Drop1
+ PushConstant CP#9
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 42
+ [1] = FieldOffset #lib::A::foo3
+ [2] = FieldOffset #lib::A::foo1
+ [3] = Int 1
+ [4] = ArgDesc num-args 2, num-type-args 0, names []
+ [5] = ICData target-name '+', arg-desc CP#4
+ [6] = FieldOffset #lib::A::foo5
+ [7] = ArgDesc num-args 1, num-type-args 0, names []
+ [8] = StaticICData target 'dart.core::Object::', arg-desc CP#7
+ [9] = Null
+}
+] constructor constr2(core::int x, core::int y) → void
+ : self::A::foo4 = null, self::A::foo1 = x, self::A::foo5 = y.{core::num::+}(1), super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 2, CP#1
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 45
+ [1] = ArgDesc num-args 2, num-type-args 0, names []
+ [2] = StaticICData target '#lib::A::', arg-desc CP#1
+ [3] = Null
+}
+] constructor redirecting1() → void
+ : this self::A::•(45)
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-8]
+ Push FP[-7]
+ Push FP[-6]
+ Push FP[-5]
+ InstanceCall1 2, CP#1
+ PushConstant CP#3
+ IndirectStaticCall 3, CP#2
+ Drop1
+ PushConstant CP#4
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 2, num-type-args 0, names []
+ [1] = ICData target-name '*', arg-desc CP#0
+ [2] = ArgDesc num-args 3, num-type-args 0, names []
+ [3] = StaticICData target '#lib::A::constr2', arg-desc CP#2
+ [4] = Null
+}
+] constructor redirecting2(core::int a, core::int b, core::int c) → void
+ : this self::A::constr2(a, b.{core::num::*}(c))
+ ;
+}
+class B extends self::A {
+ field core::int foo6 = 46;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 47
+}
+] static field core::int foo7 = 47;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 48
+}
+] static const field core::int foo8 = 48;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#0
+ StoreFieldTOS CP#1
+ Push FP[-5]
+ PushConstant CP#2
+ PushConstant CP#4
+ IndirectStaticCall 2, CP#3
+ Drop1
+ PushConstant CP#5
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 46
+ [1] = FieldOffset #lib::B::foo6
+ [2] = Int 49
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = StaticICData target '#lib::A::', arg-desc CP#3
+ [5] = Null
+}
+] constructor •() → void
+ : super self::A::•(49)
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-7]
+ PushConstant CP#0
+ StoreFieldTOS CP#1
+ Push FP[-7]
+ Push FP[-6]
+ Push FP[-5]
+ PushConstant CP#2
+ PushConstant CP#4
+ IndirectStaticCall 4, CP#3
+ Drop1
+ PushConstant CP#5
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 50
+ [1] = FieldOffset #lib::B::foo6
+ [2] = Int 51
+ [3] = ArgDesc num-args 4, num-type-args 0, names []
+ [4] = StaticICData target '#lib::A::redirecting2', arg-desc CP#3
+ [5] = Null
+}
+] constructor c2(core::int i, core::int j) → void
+ : self::B::foo6 = 50, super self::A::redirecting2(i, j, 51)
+ ;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/hello.dart b/pkg/vm/testcases/bytecode/hello.dart
new file mode 100644
index 0000000..65a1a2a
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/hello.dart
@@ -0,0 +1,7 @@
+// 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.
+
+main() {
+ print('Hello, Dart Bytecode!');
+}
diff --git a/pkg/vm/testcases/bytecode/hello.dart.expect b/pkg/vm/testcases/bytecode/hello.dart.expect
new file mode 100644
index 0000000..7147dbc
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/hello.dart.expect
@@ -0,0 +1,24 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = String 'Hello, Dart Bytecode!'
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = Null
+}
+]static method main() → dynamic {
+ core::print("Hello, Dart Bytecode!");
+}
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart b/pkg/vm/testcases/bytecode/instance_creation.dart
new file mode 100644
index 0000000..98259da
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart
@@ -0,0 +1,45 @@
+// 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 Base<T1, T2> {
+ T1 t1;
+ T2 t2;
+
+ Base() {
+ print('Base: $T1, $T2');
+ }
+}
+
+class A extends Base<int, String> {
+ A(String s);
+}
+
+class B<T> extends Base<List<T>, String> {
+ B() {
+ print('B: $T');
+ }
+}
+
+class C {
+ C(String s) {
+ print('C: $s');
+ }
+}
+
+foo1() => new C('hello');
+
+void foo2() {
+ new A('hi');
+ new B<int>();
+}
+
+void foo3<T>() {
+ new B<List<T>>();
+}
+
+main() {
+ foo1();
+ foo2();
+ foo3<String>();
+}
diff --git a/pkg/vm/testcases/bytecode/instance_creation.dart.expect b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
new file mode 100644
index 0000000..e4dca47
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/instance_creation.dart.expect
@@ -0,0 +1,315 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class Base<T1 extends core::Object, T2 extends core::Object> extends core::Object {
+ generic-covariant-impl generic-covariant-interface field self::Base::T1 t1 = null;
+ generic-covariant-impl generic-covariant-interface field self::Base::T2 t2 = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ PushConstant CP#3
+ CreateArrayTOS
+ StoreLocal r0
+ Push r0
+ PushConstant CP#4
+ PushConstant CP#5
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#6
+ Push FP[-5]
+ LoadFieldTOS CP#8
+ PushConstant CP#2
+ InstantiateType CP#7
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#9
+ PushConstant CP#10
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#11
+ Push FP[-5]
+ LoadFieldTOS CP#8
+ PushConstant CP#2
+ InstantiateType CP#12
+ StoreIndexedTOS
+ PushConstant CP#13
+ IndirectStaticCall 1, CP#0
+ PushConstant CP#14
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+ [3] = Int 4
+ [4] = Int 0
+ [5] = String 'Base: '
+ [6] = Int 1
+ [7] = Type #lib::Base::T1
+ [8] = TypeArgumentsFieldOffset #lib::Base
+ [9] = Int 2
+ [10] = String ', '
+ [11] = Int 3
+ [12] = Type #lib::Base::T2
+ [13] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
+ [14] = StaticICData target 'dart.core::print', arg-desc CP#0
+}
+] constructor •() → void
+ : super core::Object::•() {
+ core::print("Base: ${self::Base::T1}, ${self::Base::T2}");
+ }
+}
+class A extends self::Base<core::int, core::String> {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-6]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target '#lib::Base::', arg-desc CP#0
+ [2] = Null
+}
+] constructor •(core::String s) → void
+ : super self::Base::•()
+ ;
+ abstract forwarding-stub set t1(generic-covariant-impl core::int _) → void;
+ abstract forwarding-stub set t2(generic-covariant-impl core::String _) → void;
+}
+class B<T extends core::Object> extends self::Base<core::List<self::B::T>, core::String> {
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ PushConstant CP#3
+ CreateArrayTOS
+ StoreLocal r0
+ Push r0
+ PushConstant CP#4
+ PushConstant CP#5
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#6
+ Push FP[-5]
+ LoadFieldTOS CP#8
+ PushConstant CP#2
+ InstantiateType CP#7
+ StoreIndexedTOS
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#0
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target '#lib::Base::', arg-desc CP#0
+ [2] = Null
+ [3] = Int 2
+ [4] = Int 0
+ [5] = String 'B: '
+ [6] = Int 1
+ [7] = Type #lib::B::T
+ [8] = TypeArgumentsFieldOffset #lib::B
+ [9] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
+ [10] = StaticICData target 'dart.core::print', arg-desc CP#0
+}
+] constructor •() → void
+ : super self::Base::•() {
+ core::print("B: ${self::B::T}");
+ }
+ abstract forwarding-stub set t2(generic-covariant-impl core::String _) → void;
+}
+class C extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ Push FP[-6]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ PushConstant CP#3
+ CreateArrayTOS
+ StoreLocal r0
+ Push r0
+ PushConstant CP#4
+ PushConstant CP#5
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#6
+ Push FP[-5]
+ StoreIndexedTOS
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#0
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+ [3] = Int 2
+ [4] = Int 0
+ [5] = String 'C: '
+ [6] = Int 1
+ [7] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#0
+ [8] = StaticICData target 'dart.core::print', arg-desc CP#0
+}
+] constructor •(core::String s) → void
+ : super core::Object::•() {
+ core::print("C: ${s}");
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ Allocate CP#0
+ StoreLocal r0
+ Push r0
+ PushConstant CP#1
+ PushConstant CP#3
+ IndirectStaticCall 2, CP#2
+ Drop1
+ ReturnTOS
+ PushConstant CP#4
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Class #lib::C
+ [1] = String 'hello'
+ [2] = ArgDesc num-args 2, num-type-args 0, names []
+ [3] = StaticICData target '#lib::C::', arg-desc CP#2
+ [4] = Null
+}
+]static method foo1() → dynamic
+ return new self::C::•("hello");
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#1
+ PushConstant CP#0
+ AllocateT
+ StoreLocal r0
+ Push r0
+ PushConstant CP#2
+ PushConstant CP#4
+ IndirectStaticCall 2, CP#3
+ Drop1
+ Drop1
+ PushConstant CP#6
+ PushConstant CP#5
+ AllocateT
+ StoreLocal r1
+ Push r1
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#7
+ Drop1
+ Drop1
+ PushConstant CP#9
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Class #lib::A
+ [1] = TypeArgs [dart.core::int, dart.core::String]
+ [2] = String 'hi'
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = StaticICData target '#lib::A::', arg-desc CP#3
+ [5] = Class #lib::B
+ [6] = TypeArgs [dart.core::List<dart.core::int>, dart.core::String, dart.core::int]
+ [7] = ArgDesc num-args 1, num-type-args 0, names []
+ [8] = StaticICData target '#lib::B::', arg-desc CP#7
+ [9] = Null
+}
+]static method foo2() → void {
+ new self::A::•("hi");
+ new self::B::•<core::int>();
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ PushConstant CP#2
+ Push FP[-5]
+ InstantiateTypeArgumentsTOS 1, CP#1
+ PushConstant CP#0
+ AllocateT
+ StoreLocal r0
+ Push r0
+ PushConstant CP#4
+ IndirectStaticCall 1, CP#3
+ Drop1
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Class #lib::B
+ [1] = TypeArgs [dart.core::List<dart.core::List<#lib::foo3::T>>, dart.core::String, dart.core::List<#lib::foo3::T>]
+ [2] = Null
+ [3] = ArgDesc num-args 1, num-type-args 0, names []
+ [4] = StaticICData target '#lib::B::', arg-desc CP#3
+}
+]static method foo3<T extends core::Object>() → void {
+ new self::B::•<core::List<self::foo3::T>>();
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#1
+ IndirectStaticCall 0, CP#0
+ Drop1
+ PushConstant CP#2
+ IndirectStaticCall 0, CP#0
+ Drop1
+ PushConstant CP#3
+ PushConstant CP#5
+ IndirectStaticCall 1, CP#4
+ Drop1
+ PushConstant CP#6
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 0, num-type-args 0, names []
+ [1] = StaticICData target '#lib::foo1', arg-desc CP#0
+ [2] = StaticICData target '#lib::foo2', arg-desc CP#0
+ [3] = TypeArgs [dart.core::String]
+ [4] = ArgDesc num-args 0, num-type-args 1, names []
+ [5] = StaticICData target '#lib::foo3', arg-desc CP#4
+ [6] = Null
+}
+]static method main() → dynamic {
+ self::foo1();
+ self::foo2();
+ self::foo3<core::String>();
+}
diff --git a/pkg/vm/testcases/bytecode/literals.dart b/pkg/vm/testcases/bytecode/literals.dart
new file mode 100644
index 0000000..69a0e85
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/literals.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.
+
+enum A {
+ elem1,
+ elem2,
+ elem3,
+ elem4,
+}
+
+class B {
+ final int i;
+ const B(this.i);
+}
+
+class C extends B {
+ final int j;
+ const C(int a, int b, int c)
+ : j = a + b,
+ super(c * 5);
+}
+
+class D {
+ final x;
+ final y;
+ const D(this.x, [this.y]);
+}
+
+const c1 = A.elem3;
+const c2 = 'hello!';
+const c3 = c2.length;
+const c4 = const C(1, 2, 3);
+const c5 = const D(const B(4));
+
+void test_constants1() {
+ print(c1);
+ print(c2);
+ print(c3);
+ print(c4);
+ print(c5);
+}
+
+void test_constants2() {
+ print(42);
+ print('foo');
+ print(A.elem2);
+ print(const [42, 'foo']);
+ print(const <String, A>{'E2': A.elem2, 'E4': A.elem4});
+ print(
+ const D(const C(4, 5, 6), const {'foo': 42, 'bar': const B(c2.length)}));
+}
+
+void test_list_literal(int a) {
+ print([1, a, 3]);
+ print(<String>['a', a.toString(), 'b']);
+}
+
+void test_map_literal<T>(int a, int b, T c) {
+ print({1: a, b: 2});
+ print(<String, int>{'foo': a, b.toString(): 3});
+ print(<String, T>{});
+ print(<T, int>{c: 4});
+}
+
+void test_symbol() {
+ print(#test_symbol);
+}
+
+void test_type_literal<T>() {
+ print(String);
+ print(T);
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/literals.dart.expect b/pkg/vm/testcases/bytecode/literals.dart.expect
new file mode 100644
index 0000000..b56cae6
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/literals.dart.expect
@@ -0,0 +1,677 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+ final field core::int index;
+ final field core::String _name;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#13
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 0
+ [2] = String 'A.elem1'
+ [3] = Instance #lib::A type-args CP#0 {index: 1, _name: 2}
+ [4] = Int 1
+ [5] = String 'A.elem2'
+ [6] = Instance #lib::A type-args CP#0 {index: 4, _name: 5}
+ [7] = Int 2
+ [8] = String 'A.elem3'
+ [9] = Instance #lib::A type-args CP#0 {index: 7, _name: 8}
+ [10] = Int 3
+ [11] = String 'A.elem4'
+ [12] = Instance #lib::A type-args CP#0 {index: 10, _name: 11}
+ [13] = List type-arg #lib::A, entries CP# [3, 6, 9, 12]
+}
+] static const field core::List<self::A> values = const <self::A>[self::A::elem1, self::A::elem2, self::A::elem3, self::A::elem4];
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 0
+ [2] = String 'A.elem1'
+ [3] = Instance #lib::A type-args CP#0 {index: 1, _name: 2}
+}
+] static const field self::A elem1 = const self::A::•(0, "A.elem1");
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 1
+ [2] = String 'A.elem2'
+ [3] = Instance #lib::A type-args CP#0 {index: 1, _name: 2}
+}
+] static const field self::A elem2 = const self::A::•(1, "A.elem2");
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 2
+ [2] = String 'A.elem3'
+ [3] = Instance #lib::A type-args CP#0 {index: 1, _name: 2}
+}
+] static const field self::A elem3 = const self::A::•(2, "A.elem3");
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 3
+ [2] = String 'A.elem4'
+ [3] = Instance #lib::A type-args CP#0 {index: 1, _name: 2}
+}
+] static const field self::A elem4 = const self::A::•(3, "A.elem4");
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-7]
+ Push FP[-6]
+ StoreFieldTOS CP#0
+ Push FP[-7]
+ Push FP[-5]
+ StoreFieldTOS CP#1
+ Push FP[-7]
+ PushConstant CP#3
+ IndirectStaticCall 1, CP#2
+ Drop1
+ PushConstant CP#4
+ ReturnTOS
+}
+ConstantPool {
+ [0] = FieldOffset #lib::A::index
+ [1] = FieldOffset #lib::A::_name
+ [2] = ArgDesc num-args 1, num-type-args 0, names []
+ [3] = StaticICData target 'dart.core::Object::', arg-desc CP#2
+ [4] = Null
+}
+] const constructor •(core::int index, core::String _name) → void
+ : self::A::index = index, self::A::_name = _name, super core::Object::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ ReturnTOS
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target '#lib::A::_name', arg-desc CP#0
+ [2] = Null
+}
+] method toString() → core::String
+ return this.{=self::A::_name};
+}
+class B extends core::Object {
+ final field core::int i;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-6]
+ Push FP[-5]
+ StoreFieldTOS CP#0
+ Push FP[-6]
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = FieldOffset #lib::B::i
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::Object::', arg-desc CP#1
+ [3] = Null
+}
+] const constructor •(core::int i) → void
+ : self::B::i = i, super core::Object::•()
+ ;
+}
+class C extends self::B {
+ final field core::int j;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-8]
+ Push FP[-7]
+ Push FP[-6]
+ InstanceCall1 2, CP#1
+ StoreFieldTOS CP#2
+ Push FP[-8]
+ Push FP[-5]
+ PushConstant CP#3
+ InstanceCall1 2, CP#4
+ PushConstant CP#5
+ IndirectStaticCall 2, CP#0
+ Drop1
+ PushConstant CP#6
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 2, num-type-args 0, names []
+ [1] = ICData target-name '+', arg-desc CP#0
+ [2] = FieldOffset #lib::C::j
+ [3] = Int 5
+ [4] = ICData target-name '*', arg-desc CP#0
+ [5] = StaticICData target '#lib::B::', arg-desc CP#0
+ [6] = Null
+}
+] const constructor •(core::int a, core::int b, core::int c) → void
+ : self::C::j = a.{core::num::+}(b), super self::B::•(c.{core::num::*}(5))
+ ;
+}
+class D extends core::Object {
+ final field dynamic x;
+ final field dynamic y;
+[@vm.bytecode=
+Bytecode {
+ EntryOptional 2, 1, 0
+ LoadConstant r2, CP#0
+ Frame 0
+ CheckStack
+ Push r0
+ Push r1
+ StoreFieldTOS CP#1
+ Push r0
+ Push r2
+ StoreFieldTOS CP#2
+ Push r0
+ PushConstant CP#4
+ IndirectStaticCall 1, CP#3
+ Drop1
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+ [1] = FieldOffset #lib::D::x
+ [2] = FieldOffset #lib::D::y
+ [3] = ArgDesc num-args 1, num-type-args 0, names []
+ [4] = StaticICData target 'dart.core::Object::', arg-desc CP#3
+}
+] const constructor •(dynamic x, [dynamic y = null]) → void
+ : self::D::x = x, self::D::y = y, super core::Object::•()
+ ;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 2
+ [2] = String 'A.elem3'
+ [3] = Instance #lib::A type-args CP#0 {index: 1, _name: 2}
+}
+]static const field self::A c1 = self::A::elem3;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = String 'hello!'
+}
+]static const field core::String c2 = "hello!";
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 6
+}
+]static const field core::int c3 = self::c2.{core::String::length};
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 3
+ [2] = Int 15
+ [3] = Instance #lib::C type-args CP#0 {j: 1, i: 2}
+}
+]static const field self::C c4 = const self::C::•(1, 2, 3);
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#4
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 4
+ [2] = Instance #lib::B type-args CP#0 {i: 1}
+ [3] = Null
+ [4] = Instance #lib::D type-args CP#0 {x: 2, y: 3}
+}
+]static const field self::D c5 = const self::D::•(const self::B::•(4));
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#3
+ PushConstant CP#5
+ IndirectStaticCall 1, CP#4
+ Drop1
+ PushConstant CP#6
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#4
+ Drop1
+ PushConstant CP#8
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#4
+ Drop1
+ PushConstant CP#12
+ PushConstant CP#13
+ IndirectStaticCall 1, CP#4
+ Drop1
+ PushConstant CP#17
+ PushConstant CP#18
+ IndirectStaticCall 1, CP#4
+ Drop1
+ PushConstant CP#16
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs []
+ [1] = Int 2
+ [2] = String 'A.elem3'
+ [3] = Instance #lib::A type-args CP#0 {index: 1, _name: 2}
+ [4] = ArgDesc num-args 1, num-type-args 0, names []
+ [5] = StaticICData target 'dart.core::print', arg-desc CP#4
+ [6] = String 'hello!'
+ [7] = StaticICData target 'dart.core::print', arg-desc CP#4
+ [8] = Int 6
+ [9] = StaticICData target 'dart.core::print', arg-desc CP#4
+ [10] = Int 3
+ [11] = Int 15
+ [12] = Instance #lib::C type-args CP#0 {j: 10, i: 11}
+ [13] = StaticICData target 'dart.core::print', arg-desc CP#4
+ [14] = Int 4
+ [15] = Instance #lib::B type-args CP#0 {i: 14}
+ [16] = Null
+ [17] = Instance #lib::D type-args CP#0 {x: 15, y: 16}
+ [18] = StaticICData target 'dart.core::print', arg-desc CP#4
+}
+]static method test_constants1() → void {
+ core::print(self::c1);
+ core::print(self::c2);
+ core::print(self::c3);
+ core::print(self::c4);
+ core::print(self::c5);
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#3
+ PushConstant CP#4
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#8
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#10
+ PushConstant CP#11
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#19
+ PushConstant CP#20
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#30
+ PushConstant CP#31
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#32
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 42
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = String 'foo'
+ [4] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [5] = TypeArgs []
+ [6] = Int 1
+ [7] = String 'A.elem2'
+ [8] = Instance #lib::A type-args CP#5 {index: 6, _name: 7}
+ [9] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [10] = List type-arg dart.core::Object, entries CP# [0, 3]
+ [11] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [12] = TypeArgs [dart.core::String, #lib::A]
+ [13] = String 'E2'
+ [14] = String 'E4'
+ [15] = Int 3
+ [16] = String 'A.elem4'
+ [17] = Instance #lib::A type-args CP#5 {index: 15, _name: 16}
+ [18] = List type-arg dynamic, entries CP# [13, 8, 14, 17]
+ [19] = Instance dart.core::_ImmutableMap type-args CP#12 {_kvPairs: 18}
+ [20] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [21] = Int 9
+ [22] = Int 30
+ [23] = Instance #lib::C type-args CP#5 {j: 21, i: 22}
+ [24] = TypeArgs [dart.core::String, dart.core::Object]
+ [25] = String 'bar'
+ [26] = Int 6
+ [27] = Instance #lib::B type-args CP#5 {i: 26}
+ [28] = List type-arg dynamic, entries CP# [3, 0, 25, 27]
+ [29] = Instance dart.core::_ImmutableMap type-args CP#24 {_kvPairs: 28}
+ [30] = Instance #lib::D type-args CP#5 {x: 23, y: 29}
+ [31] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [32] = Null
+}
+]static method test_constants2() → void {
+ core::print(42);
+ core::print("foo");
+ core::print(self::A::elem2);
+ core::print(const <core::Object>[42, "foo"]);
+ core::print(const <core::String, self::A>{"E2": self::A::elem2, "E4": self::A::elem4});
+ core::print(const self::D::•(const self::C::•(4, 5, 6), const <core::String, core::Object>{"foo": 42, "bar": const self::B::•(self::c2.{core::String::length})}));
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ StoreLocal r0
+ Push r0
+ PushConstant CP#1
+ CreateArrayTOS
+ StoreLocal r0
+ Push r0
+ PushConstant CP#2
+ PushConstant CP#3
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#3
+ Push FP[-5]
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#4
+ PushConstant CP#1
+ StoreIndexedTOS
+ PushConstant CP#6
+ IndirectStaticCall 2, CP#5
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#7
+ Drop1
+ PushConstant CP#9
+ StoreLocal r1
+ Push r1
+ PushConstant CP#1
+ CreateArrayTOS
+ StoreLocal r1
+ Push r1
+ PushConstant CP#2
+ PushConstant CP#10
+ StoreIndexedTOS
+ Push r1
+ PushConstant CP#3
+ Push FP[-5]
+ InstanceCall1 1, CP#11
+ StoreIndexedTOS
+ Push r1
+ PushConstant CP#4
+ PushConstant CP#12
+ StoreIndexedTOS
+ PushConstant CP#13
+ IndirectStaticCall 2, CP#5
+ PushConstant CP#14
+ IndirectStaticCall 1, CP#7
+ Drop1
+ PushConstant CP#15
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs [dart.core::int]
+ [1] = Int 3
+ [2] = Int 0
+ [3] = Int 1
+ [4] = Int 2
+ [5] = ArgDesc num-args 1, num-type-args 1, names []
+ [6] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#5
+ [7] = ArgDesc num-args 1, num-type-args 0, names []
+ [8] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [9] = TypeArgs [dart.core::String]
+ [10] = String 'a'
+ [11] = ICData target-name 'toString', arg-desc CP#7
+ [12] = String 'b'
+ [13] = StaticICData target 'dart.core::List::_fromLiteral', arg-desc CP#5
+ [14] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [15] = Null
+}
+]static method test_list_literal(core::int a) → void {
+ core::print(<core::int>[1, a, 3]);
+ core::print(<core::String>["a", a.{core::int::toString}(), "b"]);
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 4
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#1
+ PushConstant CP#2
+ CreateArrayTOS
+ StoreLocal r0
+ Push r0
+ PushConstant CP#3
+ PushConstant CP#4
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#4
+ Push FP[-7]
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#5
+ Push FP[-6]
+ StoreIndexedTOS
+ Push r0
+ PushConstant CP#6
+ PushConstant CP#5
+ StoreIndexedTOS
+ PushConstant CP#8
+ IndirectStaticCall 2, CP#7
+ PushConstant CP#10
+ IndirectStaticCall 1, CP#9
+ Drop1
+ PushConstant CP#11
+ PushConstant CP#1
+ PushConstant CP#2
+ CreateArrayTOS
+ StoreLocal r1
+ Push r1
+ PushConstant CP#3
+ PushConstant CP#12
+ StoreIndexedTOS
+ Push r1
+ PushConstant CP#4
+ Push FP[-7]
+ StoreIndexedTOS
+ Push r1
+ PushConstant CP#5
+ Push FP[-6]
+ InstanceCall1 1, CP#13
+ StoreIndexedTOS
+ Push r1
+ PushConstant CP#6
+ PushConstant CP#6
+ StoreIndexedTOS
+ PushConstant CP#14
+ IndirectStaticCall 2, CP#7
+ PushConstant CP#15
+ IndirectStaticCall 1, CP#9
+ Drop1
+ PushConstant CP#17
+ Push FP[-8]
+ InstantiateTypeArgumentsTOS 1, CP#16
+ PushConstant CP#18
+ PushConstant CP#19
+ IndirectStaticCall 2, CP#7
+ PushConstant CP#20
+ IndirectStaticCall 1, CP#9
+ Drop1
+ PushConstant CP#17
+ Push FP[-8]
+ InstantiateTypeArgumentsTOS 1, CP#21
+ PushConstant CP#1
+ PushConstant CP#5
+ CreateArrayTOS
+ StoreLocal r3
+ Push r3
+ PushConstant CP#3
+ Push FP[-5]
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#4
+ PushConstant CP#2
+ StoreIndexedTOS
+ PushConstant CP#22
+ IndirectStaticCall 2, CP#7
+ PushConstant CP#23
+ IndirectStaticCall 1, CP#9
+ Drop1
+ PushConstant CP#17
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgs [dart.core::int, dart.core::int]
+ [1] = TypeArgs [dynamic]
+ [2] = Int 4
+ [3] = Int 0
+ [4] = Int 1
+ [5] = Int 2
+ [6] = Int 3
+ [7] = ArgDesc num-args 1, num-type-args 1, names []
+ [8] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
+ [9] = ArgDesc num-args 1, num-type-args 0, names []
+ [10] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [11] = TypeArgs [dart.core::String, dart.core::int]
+ [12] = String 'foo'
+ [13] = ICData target-name 'toString', arg-desc CP#9
+ [14] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
+ [15] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [16] = TypeArgs [dart.core::String, #lib::test_map_literal::T]
+ [17] = Null
+ [18] = List type-arg dynamic, entries CP# []
+ [19] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
+ [20] = StaticICData target 'dart.core::print', arg-desc CP#9
+ [21] = TypeArgs [#lib::test_map_literal::T, dart.core::int]
+ [22] = StaticICData target 'dart.core::Map::_fromLiteral', arg-desc CP#7
+ [23] = StaticICData target 'dart.core::print', arg-desc CP#9
+}
+]static method test_map_literal<T extends core::Object>(core::int a, core::int b, self::test_map_literal::T c) → void {
+ core::print(<core::int, core::int>{1: a, b: 2});
+ core::print(<core::String, core::int>{"foo": a, b.{core::int::toString}(): 3});
+ core::print(<core::String, self::test_map_literal::T>{});
+ core::print(<self::test_map_literal::T, core::int>{c: 4});
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#3
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Symbol 'test_symbol'
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = Null
+}
+]static method test_symbol() → void {
+ core::print(#test_symbol);
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#2
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#4
+ Push FP[-5]
+ InstantiateType CP#3
+ PushConstant CP#5
+ IndirectStaticCall 1, CP#1
+ Drop1
+ PushConstant CP#4
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Type dart.core::String
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = StaticICData target 'dart.core::print', arg-desc CP#1
+ [3] = Type #lib::test_type_literal::T
+ [4] = Null
+ [5] = StaticICData target 'dart.core::print', arg-desc CP#1
+}
+]static method test_type_literal<T extends core::Object>() → void {
+ core::print(core::String);
+ core::print(self::test_type_literal::T);
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/loops.dart b/pkg/vm/testcases/bytecode/loops.dart
new file mode 100644
index 0000000..a2d2d10
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/loops.dart
@@ -0,0 +1,62 @@
+// 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.
+
+int test_for(List<int> list) {
+ int sum = 0;
+ for (int i = 0; i < list.length; i++) {
+ sum = sum + list[i];
+ }
+ return sum;
+}
+
+int test_for_break(List<int> list) {
+ int sum = 0;
+ for (int i = 0; i >= 0; i++) {
+ if (i >= list.length) {
+ break;
+ }
+ sum = sum + list[i];
+ }
+ return sum;
+}
+
+int test_for_continue(List<int> list) {
+ int sum = 0;
+ for (int i = -100; i < list.length; i++) {
+ if (i < 0) {
+ continue;
+ }
+ sum = sum + list[i];
+ }
+ return sum;
+}
+
+int test_while(List<int> list) {
+ int sum = 0;
+ int i = 0;
+ while (i < list.length) {
+ sum = sum + list[i++];
+ }
+ return sum;
+}
+
+int test_do_while(List<int> list) {
+ int sum = 0;
+ int i = 0;
+ do {
+ sum = sum + list[i];
+ ++i;
+ } while (i < list.length);
+ return sum;
+}
+
+int test_for_in(List<int> list) {
+ int sum = 0;
+ for (var e in list) {
+ sum = sum + e;
+ }
+ return sum;
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/loops.dart.expect b/pkg/vm/testcases/bytecode/loops.dart.expect
new file mode 100644
index 0000000..a23aa00
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/loops.dart.expect
@@ -0,0 +1,379 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ PushConstant CP#0
+ PopLocal r1
+L2:
+ CheckStack
+ Push r1
+ Push FP[-5]
+ InstanceCall1 1, CP#2
+ InstanceCall1 2, CP#4
+ PushConstant CP#5
+ IfNeStrictTOS
+ Jump L1
+ Push r0
+ Push FP[-5]
+ Push r1
+ InstanceCall1 2, CP#6
+ InstanceCall1 2, CP#7
+ StoreLocal r0
+ Drop1
+ Push r1
+ PushConstant CP#8
+ InstanceCall1 2, CP#9
+ StoreLocal r1
+ Drop1
+ Jump L2
+L1:
+ Push r0
+ ReturnTOS
+ PushConstant CP#10
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = ICData target-name 'get:length', arg-desc CP#1
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = ICData target-name '<', arg-desc CP#3
+ [5] = Bool true
+ [6] = ICData target-name '[]', arg-desc CP#3
+ [7] = ICData target-name '+', arg-desc CP#3
+ [8] = Int 1
+ [9] = ICData target-name '+', arg-desc CP#3
+ [10] = Null
+}
+]static method test_for(core::List<core::int> list) → core::int {
+ core::int sum = 0;
+ for (core::int i = 0; i.{core::num::<}(list.{core::List::length}); i = i.{core::num::+}(1)) {
+ sum = sum.{core::num::+}(list.{core::List::[]}(i));
+ }
+ return sum;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ PushConstant CP#0
+ PopLocal r1
+L3:
+ CheckStack
+ Push r1
+ PushConstant CP#0
+ InstanceCall1 2, CP#2
+ PushConstant CP#3
+ IfNeStrictTOS
+ Jump L1
+ Push r1
+ Push FP[-5]
+ InstanceCall1 1, CP#5
+ InstanceCall1 2, CP#6
+ PushConstant CP#3
+ IfNeStrictTOS
+ Jump L2
+ Jump L1
+L2:
+ Push r0
+ Push FP[-5]
+ Push r1
+ InstanceCall1 2, CP#7
+ InstanceCall1 2, CP#8
+ StoreLocal r0
+ Drop1
+ Push r1
+ PushConstant CP#9
+ InstanceCall1 2, CP#10
+ StoreLocal r1
+ Drop1
+ Jump L3
+L1:
+ Push r0
+ ReturnTOS
+ PushConstant CP#11
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = ArgDesc num-args 2, num-type-args 0, names []
+ [2] = ICData target-name '>=', arg-desc CP#1
+ [3] = Bool true
+ [4] = ArgDesc num-args 1, num-type-args 0, names []
+ [5] = ICData target-name 'get:length', arg-desc CP#4
+ [6] = ICData target-name '>=', arg-desc CP#1
+ [7] = ICData target-name '[]', arg-desc CP#1
+ [8] = ICData target-name '+', arg-desc CP#1
+ [9] = Int 1
+ [10] = ICData target-name '+', arg-desc CP#1
+ [11] = Null
+}
+]static method test_for_break(core::List<core::int> list) → core::int {
+ core::int sum = 0;
+ #L1:
+ for (core::int i = 0; i.{core::num::>=}(0); i = i.{core::num::+}(1)) {
+ if(i.{core::num::>=}(list.{core::List::length})) {
+ break #L1;
+ }
+ sum = sum.{core::num::+}(list.{core::List::[]}(i));
+ }
+ return sum;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ PushConstant CP#1
+ InstanceCall1 1, CP#3
+ PopLocal r1
+L4:
+ CheckStack
+ Push r1
+ Push FP[-5]
+ InstanceCall1 1, CP#4
+ InstanceCall1 2, CP#6
+ PushConstant CP#7
+ IfNeStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#0
+ InstanceCall1 2, CP#8
+ PushConstant CP#7
+ IfNeStrictTOS
+ Jump L2
+ Jump L3
+L2:
+ Push r0
+ Push FP[-5]
+ Push r1
+ InstanceCall1 2, CP#9
+ InstanceCall1 2, CP#10
+ StoreLocal r0
+ Drop1
+L3:
+ Push r1
+ PushConstant CP#11
+ InstanceCall1 2, CP#12
+ StoreLocal r1
+ Drop1
+ Jump L4
+L1:
+ Push r0
+ ReturnTOS
+ PushConstant CP#13
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = Int 100
+ [2] = ArgDesc num-args 1, num-type-args 0, names []
+ [3] = ICData target-name 'unary-', arg-desc CP#2
+ [4] = ICData target-name 'get:length', arg-desc CP#2
+ [5] = ArgDesc num-args 2, num-type-args 0, names []
+ [6] = ICData target-name '<', arg-desc CP#5
+ [7] = Bool true
+ [8] = ICData target-name '<', arg-desc CP#5
+ [9] = ICData target-name '[]', arg-desc CP#5
+ [10] = ICData target-name '+', arg-desc CP#5
+ [11] = Int 1
+ [12] = ICData target-name '+', arg-desc CP#5
+ [13] = Null
+}
+]static method test_for_continue(core::List<core::int> list) → core::int {
+ core::int sum = 0;
+ for (core::int i = 100.{core::int::unary-}(); i.{core::num::<}(list.{core::List::length}); i = i.{core::num::+}(1))
+ #L2:
+ {
+ if(i.{core::num::<}(0)) {
+ break #L2;
+ }
+ sum = sum.{core::num::+}(list.{core::List::[]}(i));
+ }
+ return sum;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 4
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ PushConstant CP#0
+ PopLocal r1
+L2:
+ CheckStack
+ Push r1
+ Push FP[-5]
+ InstanceCall1 1, CP#2
+ InstanceCall1 2, CP#4
+ PushConstant CP#5
+ IfNeStrictTOS
+ Jump L1
+ Push r0
+ Push FP[-5]
+ Push r1
+ PopLocal r2
+ Push r2
+ PushConstant CP#6
+ InstanceCall1 2, CP#7
+ StoreLocal r1
+ PopLocal r3
+ Push r2
+ InstanceCall1 2, CP#8
+ InstanceCall1 2, CP#9
+ StoreLocal r0
+ Drop1
+ Jump L2
+L1:
+ Push r0
+ ReturnTOS
+ PushConstant CP#10
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = ICData target-name 'get:length', arg-desc CP#1
+ [3] = ArgDesc num-args 2, num-type-args 0, names []
+ [4] = ICData target-name '<', arg-desc CP#3
+ [5] = Bool true
+ [6] = Int 1
+ [7] = ICData target-name '+', arg-desc CP#3
+ [8] = ICData target-name '[]', arg-desc CP#3
+ [9] = ICData target-name '+', arg-desc CP#3
+ [10] = Null
+}
+]static method test_while(core::List<core::int> list) → core::int {
+ core::int sum = 0;
+ core::int i = 0;
+ while (i.{core::num::<}(list.{core::List::length})) {
+ sum = sum.{core::num::+}(list.{core::List::[]}(let final core::int #t1 = i in let final core::int #t2 = i = #t1.{core::num::+}(1) in #t1));
+ }
+ return sum;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ PushConstant CP#0
+ PopLocal r1
+L1:
+ CheckStack
+ Push r0
+ Push FP[-5]
+ Push r1
+ InstanceCall1 2, CP#2
+ InstanceCall1 2, CP#3
+ StoreLocal r0
+ Drop1
+ Push r1
+ PushConstant CP#4
+ InstanceCall1 2, CP#5
+ StoreLocal r1
+ Drop1
+ Push r1
+ Push FP[-5]
+ InstanceCall1 1, CP#7
+ InstanceCall1 2, CP#8
+ PushConstant CP#9
+ IfEqStrictTOS
+ Jump L1
+ Push r0
+ ReturnTOS
+ PushConstant CP#10
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = ArgDesc num-args 2, num-type-args 0, names []
+ [2] = ICData target-name '[]', arg-desc CP#1
+ [3] = ICData target-name '+', arg-desc CP#1
+ [4] = Int 1
+ [5] = ICData target-name '+', arg-desc CP#1
+ [6] = ArgDesc num-args 1, num-type-args 0, names []
+ [7] = ICData target-name 'get:length', arg-desc CP#6
+ [8] = ICData target-name '<', arg-desc CP#1
+ [9] = Bool true
+ [10] = Null
+}
+]static method test_do_while(core::List<core::int> list) → core::int {
+ core::int sum = 0;
+ core::int i = 0;
+ do {
+ sum = sum.{core::num::+}(list.{core::List::[]}(i));
+ i = i.{core::num::+}(1);
+ }
+ while (i.{core::num::<}(list.{core::List::length}))
+ return sum;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 3
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ Push FP[-5]
+ InstanceCall1 1, CP#2
+ PopLocal r1
+L2:
+ CheckStack
+ Push r1
+ InstanceCall1 1, CP#3
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L1
+ Push r1
+ InstanceCall1 1, CP#5
+ PopLocal r2
+ Push r0
+ Push r2
+ InstanceCall1 2, CP#7
+ StoreLocal r0
+ Drop1
+ Jump L2
+L1:
+ Push r0
+ ReturnTOS
+ PushConstant CP#8
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Int 0
+ [1] = ArgDesc num-args 1, num-type-args 0, names []
+ [2] = ICData target-name 'get:iterator', arg-desc CP#1
+ [3] = ICData target-name 'moveNext', arg-desc CP#1
+ [4] = Bool true
+ [5] = ICData target-name 'current', arg-desc CP#1
+ [6] = ArgDesc num-args 2, num-type-args 0, names []
+ [7] = ICData target-name '+', arg-desc CP#6
+ [8] = Null
+}
+]static method test_for_in(core::List<core::int> list) → core::int {
+ core::int sum = 0;
+ for (core::int e in list) {
+ sum = sum.{core::num::+}(e);
+ }
+ return sum;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart b/pkg/vm/testcases/bytecode/optional_params.dart
new file mode 100644
index 0000000..b41298a
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/optional_params.dart
@@ -0,0 +1,22 @@
+// 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.
+
+void foo1(x, [a = 'default_a', b = 'default_b']) {
+ print('x = $x');
+ print('a = $a');
+ print('b = $b');
+}
+
+void foo2(y, z, {c = 'default_c', a = 42, b = const ['default_b']}) {
+ print('y = $y');
+ print('z = $z');
+ print('a = $a');
+ print('b = $b');
+ print('c = $c');
+}
+
+main() {
+ foo1('fixed_x', 'concrete_a');
+ foo2('fixed_y', 'fixed_z', a: 'concrete_a');
+}
diff --git a/pkg/vm/testcases/bytecode/optional_params.dart.expect b/pkg/vm/testcases/bytecode/optional_params.dart.expect
new file mode 100644
index 0000000..36b3b1a
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/optional_params.dart.expect
@@ -0,0 +1,256 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+[@vm.bytecode=
+Bytecode {
+ EntryOptional 1, 2, 0
+ LoadConstant r1, CP#0
+ LoadConstant r2, CP#1
+ Frame 3
+ CheckStack
+ PushConstant CP#2
+ PushConstant CP#3
+ CreateArrayTOS
+ StoreLocal r3
+ Push r3
+ PushConstant CP#4
+ PushConstant CP#5
+ StoreIndexedTOS
+ Push r3
+ PushConstant CP#6
+ Push r0
+ StoreIndexedTOS
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#7
+ PushConstant CP#9
+ IndirectStaticCall 1, CP#7
+ Drop1
+ PushConstant CP#2
+ PushConstant CP#3
+ CreateArrayTOS
+ StoreLocal r4
+ Push r4
+ PushConstant CP#4
+ PushConstant CP#10
+ StoreIndexedTOS
+ Push r4
+ PushConstant CP#6
+ Push r1
+ StoreIndexedTOS
+ PushConstant CP#11
+ IndirectStaticCall 1, CP#7
+ PushConstant CP#12
+ IndirectStaticCall 1, CP#7
+ Drop1
+ PushConstant CP#2
+ PushConstant CP#3
+ CreateArrayTOS
+ StoreLocal r5
+ Push r5
+ PushConstant CP#4
+ PushConstant CP#13
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#6
+ Push r2
+ StoreIndexedTOS
+ PushConstant CP#14
+ IndirectStaticCall 1, CP#7
+ PushConstant CP#15
+ IndirectStaticCall 1, CP#7
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = String 'default_a'
+ [1] = String 'default_b'
+ [2] = Null
+ [3] = Int 2
+ [4] = Int 0
+ [5] = String 'x = '
+ [6] = Int 1
+ [7] = ArgDesc num-args 1, num-type-args 0, names []
+ [8] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
+ [9] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [10] = String 'a = '
+ [11] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
+ [12] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [13] = String 'b = '
+ [14] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#7
+ [15] = StaticICData target 'dart.core::print', arg-desc CP#7
+}
+]static method foo1(dynamic x, [dynamic a = "default_a", dynamic b = "default_b"]) → void {
+ core::print("x = ${x}");
+ core::print("a = ${a}");
+ core::print("b = ${b}");
+}
+[@vm.bytecode=
+Bytecode {
+ EntryOptional 2, 0, 3
+ LoadConstant r2, CP#0
+ LoadConstant r2, CP#1
+ LoadConstant r3, CP#2
+ LoadConstant r3, CP#4
+ LoadConstant r4, CP#5
+ LoadConstant r4, CP#6
+ Frame 5
+ CheckStack
+ PushConstant CP#7
+ PushConstant CP#8
+ CreateArrayTOS
+ StoreLocal r5
+ Push r5
+ PushConstant CP#9
+ PushConstant CP#10
+ StoreIndexedTOS
+ Push r5
+ PushConstant CP#11
+ Push r0
+ StoreIndexedTOS
+ PushConstant CP#13
+ IndirectStaticCall 1, CP#12
+ PushConstant CP#14
+ IndirectStaticCall 1, CP#12
+ Drop1
+ PushConstant CP#7
+ PushConstant CP#8
+ CreateArrayTOS
+ StoreLocal r6
+ Push r6
+ PushConstant CP#9
+ PushConstant CP#15
+ StoreIndexedTOS
+ Push r6
+ PushConstant CP#11
+ Push r1
+ StoreIndexedTOS
+ PushConstant CP#16
+ IndirectStaticCall 1, CP#12
+ PushConstant CP#17
+ IndirectStaticCall 1, CP#12
+ Drop1
+ PushConstant CP#7
+ PushConstant CP#8
+ CreateArrayTOS
+ StoreLocal r7
+ Push r7
+ PushConstant CP#9
+ PushConstant CP#18
+ StoreIndexedTOS
+ Push r7
+ PushConstant CP#11
+ Push r2
+ StoreIndexedTOS
+ PushConstant CP#19
+ IndirectStaticCall 1, CP#12
+ PushConstant CP#20
+ IndirectStaticCall 1, CP#12
+ Drop1
+ PushConstant CP#7
+ PushConstant CP#8
+ CreateArrayTOS
+ StoreLocal r8
+ Push r8
+ PushConstant CP#9
+ PushConstant CP#21
+ StoreIndexedTOS
+ Push r8
+ PushConstant CP#11
+ Push r3
+ StoreIndexedTOS
+ PushConstant CP#22
+ IndirectStaticCall 1, CP#12
+ PushConstant CP#23
+ IndirectStaticCall 1, CP#12
+ Drop1
+ PushConstant CP#7
+ PushConstant CP#8
+ CreateArrayTOS
+ StoreLocal r9
+ Push r9
+ PushConstant CP#9
+ PushConstant CP#24
+ StoreIndexedTOS
+ Push r9
+ PushConstant CP#11
+ Push r4
+ StoreIndexedTOS
+ PushConstant CP#25
+ IndirectStaticCall 1, CP#12
+ PushConstant CP#26
+ IndirectStaticCall 1, CP#12
+ Drop1
+ PushConstant CP#7
+ ReturnTOS
+}
+ConstantPool {
+ [0] = String 'a'
+ [1] = Int 42
+ [2] = String 'b'
+ [3] = String 'default_b'
+ [4] = List type-arg dart.core::String, entries CP# [3]
+ [5] = String 'c'
+ [6] = String 'default_c'
+ [7] = Null
+ [8] = Int 2
+ [9] = Int 0
+ [10] = String 'y = '
+ [11] = Int 1
+ [12] = ArgDesc num-args 1, num-type-args 0, names []
+ [13] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
+ [14] = StaticICData target 'dart.core::print', arg-desc CP#12
+ [15] = String 'z = '
+ [16] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
+ [17] = StaticICData target 'dart.core::print', arg-desc CP#12
+ [18] = String 'a = '
+ [19] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
+ [20] = StaticICData target 'dart.core::print', arg-desc CP#12
+ [21] = String 'b = '
+ [22] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
+ [23] = StaticICData target 'dart.core::print', arg-desc CP#12
+ [24] = String 'c = '
+ [25] = StaticICData target 'dart.core::_StringBase::_interpolate', arg-desc CP#12
+ [26] = StaticICData target 'dart.core::print', arg-desc CP#12
+}
+]static method foo2(dynamic y, dynamic z, {dynamic a = 42, dynamic b = const <core::String>["default_b"], dynamic c = "default_c"}) → void {
+ core::print("y = ${y}");
+ core::print("z = ${z}");
+ core::print("a = ${a}");
+ core::print("b = ${b}");
+ core::print("c = ${c}");
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ PushConstant CP#1
+ PushConstant CP#3
+ IndirectStaticCall 2, CP#2
+ Drop1
+ PushConstant CP#4
+ PushConstant CP#5
+ PushConstant CP#1
+ PushConstant CP#7
+ IndirectStaticCall 3, CP#6
+ Drop1
+ PushConstant CP#8
+ ReturnTOS
+}
+ConstantPool {
+ [0] = String 'fixed_x'
+ [1] = String 'concrete_a'
+ [2] = ArgDesc num-args 2, num-type-args 0, names []
+ [3] = StaticICData target '#lib::foo1', arg-desc CP#2
+ [4] = String 'fixed_y'
+ [5] = String 'fixed_z'
+ [6] = ArgDesc num-args 3, num-type-args 0, names [a]
+ [7] = StaticICData target '#lib::foo2', arg-desc CP#6
+ [8] = Null
+}
+]static method main() → dynamic {
+ self::foo1("fixed_x", "concrete_a");
+ self::foo2("fixed_y", "fixed_z", a: "concrete_a");
+}
diff --git a/pkg/vm/testcases/bytecode/switch.dart b/pkg/vm/testcases/bytecode/switch.dart
new file mode 100644
index 0000000..da20adb
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/switch.dart
@@ -0,0 +1,60 @@
+// 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.
+
+int foo1(int x) {
+ int y;
+ switch (x) {
+ case 1:
+ y = 11;
+ break;
+ case 2:
+ y = 22;
+ break;
+ case 3:
+ y = 33;
+ break;
+ }
+ return y;
+}
+
+int foo2(int x) {
+ int y;
+ switch (x) {
+ case 1:
+ case 2:
+ case 3:
+ y = 11;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ y = 22;
+ break;
+ default:
+ y = 33;
+ }
+ return y;
+}
+
+int foo3(int x) {
+ int y;
+ switch (x) {
+ case 1:
+ case 2:
+ case 3:
+ y = 11;
+ continue L5;
+ case 4:
+ L5:
+ case 5:
+ case 6:
+ y = 22;
+ return 42;
+ default:
+ y = 33;
+ }
+ return y;
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/switch.dart.expect b/pkg/vm/testcases/bytecode/switch.dart.expect
new file mode 100644
index 0000000..cf87dfd
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/switch.dart.expect
@@ -0,0 +1,328 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ Push FP[-5]
+ PopLocal r1
+ Push r1
+ PushConstant CP#2
+ InstanceCall2 2, CP#3
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#5
+ InstanceCall2 2, CP#6
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L2
+ Push r1
+ PushConstant CP#7
+ InstanceCall2 2, CP#8
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L3
+ Jump L4
+L1:
+ PushConstant CP#9
+ StoreLocal r0
+ Drop1
+ Jump L4
+L2:
+ PushConstant CP#10
+ StoreLocal r0
+ Drop1
+ Jump L4
+L3:
+ PushConstant CP#11
+ StoreLocal r0
+ Drop1
+ Jump L4
+L4:
+ Push r0
+ ReturnTOS
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+ [1] = ArgDesc num-args 2, num-type-args 0, names []
+ [2] = Int 1
+ [3] = ICData target-name '==', arg-desc CP#1
+ [4] = Bool true
+ [5] = Int 2
+ [6] = ICData target-name '==', arg-desc CP#1
+ [7] = Int 3
+ [8] = ICData target-name '==', arg-desc CP#1
+ [9] = Int 11
+ [10] = Int 22
+ [11] = Int 33
+}
+]static method foo1(core::int x) → core::int {
+ core::int y;
+ #L1:
+ switch(x) {
+ #L2:
+ case 1:
+ {
+ y = 11;
+ break #L1;
+ }
+ #L3:
+ case 2:
+ {
+ y = 22;
+ break #L1;
+ }
+ #L4:
+ case 3:
+ {
+ y = 33;
+ break #L1;
+ }
+ }
+ return y;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ Push FP[-5]
+ PopLocal r1
+ Push r1
+ PushConstant CP#2
+ InstanceCall2 2, CP#3
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#5
+ InstanceCall2 2, CP#6
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#7
+ InstanceCall2 2, CP#8
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#9
+ InstanceCall2 2, CP#10
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L2
+ Push r1
+ PushConstant CP#11
+ InstanceCall2 2, CP#12
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L2
+ Push r1
+ PushConstant CP#13
+ InstanceCall2 2, CP#14
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L2
+ Jump L3
+L1:
+ PushConstant CP#15
+ StoreLocal r0
+ Drop1
+ Jump L4
+L2:
+ PushConstant CP#16
+ StoreLocal r0
+ Drop1
+ Jump L4
+L3:
+ PushConstant CP#17
+ StoreLocal r0
+ Drop1
+L4:
+ Push r0
+ ReturnTOS
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+ [1] = ArgDesc num-args 2, num-type-args 0, names []
+ [2] = Int 1
+ [3] = ICData target-name '==', arg-desc CP#1
+ [4] = Bool true
+ [5] = Int 2
+ [6] = ICData target-name '==', arg-desc CP#1
+ [7] = Int 3
+ [8] = ICData target-name '==', arg-desc CP#1
+ [9] = Int 4
+ [10] = ICData target-name '==', arg-desc CP#1
+ [11] = Int 5
+ [12] = ICData target-name '==', arg-desc CP#1
+ [13] = Int 6
+ [14] = ICData target-name '==', arg-desc CP#1
+ [15] = Int 11
+ [16] = Int 22
+ [17] = Int 33
+}
+]static method foo2(core::int x) → core::int {
+ core::int y;
+ #L5:
+ switch(x) {
+ #L6:
+ case 1:
+ case 2:
+ case 3:
+ {
+ y = 11;
+ break #L5;
+ }
+ #L7:
+ case 4:
+ case 5:
+ case 6:
+ {
+ y = 22;
+ break #L5;
+ }
+ #L8:
+ default:
+ {
+ y = 33;
+ }
+ }
+ return y;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 2
+ CheckStack
+ PushConstant CP#0
+ PopLocal r0
+ Push FP[-5]
+ PopLocal r1
+ Push r1
+ PushConstant CP#2
+ InstanceCall2 2, CP#3
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#5
+ InstanceCall2 2, CP#6
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#7
+ InstanceCall2 2, CP#8
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L1
+ Push r1
+ PushConstant CP#9
+ InstanceCall2 2, CP#10
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L2
+ Push r1
+ PushConstant CP#11
+ InstanceCall2 2, CP#12
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L2
+ Push r1
+ PushConstant CP#13
+ InstanceCall2 2, CP#14
+ PushConstant CP#4
+ IfEqStrictTOS
+ Jump L2
+ Jump L3
+L1:
+ PushConstant CP#15
+ StoreLocal r0
+ Drop1
+ Jump L2
+L2:
+ PushConstant CP#16
+ StoreLocal r0
+ Drop1
+ PushConstant CP#17
+ ReturnTOS
+L3:
+ PushConstant CP#18
+ StoreLocal r0
+ Drop1
+ Push r0
+ ReturnTOS
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+ [1] = ArgDesc num-args 2, num-type-args 0, names []
+ [2] = Int 1
+ [3] = ICData target-name '==', arg-desc CP#1
+ [4] = Bool true
+ [5] = Int 2
+ [6] = ICData target-name '==', arg-desc CP#1
+ [7] = Int 3
+ [8] = ICData target-name '==', arg-desc CP#1
+ [9] = Int 4
+ [10] = ICData target-name '==', arg-desc CP#1
+ [11] = Int 5
+ [12] = ICData target-name '==', arg-desc CP#1
+ [13] = Int 6
+ [14] = ICData target-name '==', arg-desc CP#1
+ [15] = Int 11
+ [16] = Int 22
+ [17] = Int 42
+ [18] = Int 33
+}
+]static method foo3(core::int x) → core::int {
+ core::int y;
+ switch(x) {
+ #L9:
+ case 1:
+ case 2:
+ case 3:
+ {
+ y = 11;
+ continue #L10;
+ }
+ #L10:
+ case 4:
+ case 5:
+ case 6:
+ {
+ y = 22;
+ return 42;
+ }
+ #L11:
+ default:
+ {
+ y = 33;
+ }
+ }
+ return y;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart b/pkg/vm/testcases/bytecode/type_ops.dart
new file mode 100644
index 0000000..664dc6e
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/type_ops.dart
@@ -0,0 +1,45 @@
+// 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<T> {}
+
+class B extends A<String> {}
+
+class C<T1, T2, T3> extends B {}
+
+foo1(x) {
+ if (x is B) {
+ print('11');
+ }
+ if (x is C<int, Object, dynamic>) {
+ print('12');
+ }
+ return x as A<int>;
+}
+
+class D<P, Q> extends C<int, Q, P> {
+ Map<P, Q> foo;
+
+ foo2(y) {
+ if (y is A<P>) {
+ print('21');
+ }
+ if (y is C<dynamic, Q, List<P>>) {
+ print('22');
+ }
+ foo = y;
+ }
+
+ foo3<T1, T2>(z) {
+ if (z is A<T1>) {
+ print('31');
+ }
+ if (z is C<Map<T1, P>, List<T2>, Q>) {
+ print('32');
+ }
+ return (z as Map<T2, Q>).values;
+ }
+}
+
+main() {}
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
new file mode 100644
index 0000000..f53ec42
--- /dev/null
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -0,0 +1,302 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target 'dart.core::Object::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<core::String> {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target '#lib::A::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super self::A::•()
+ ;
+}
+class C<T1 extends core::Object, T2 extends core::Object, T3 extends core::Object> extends self::B {
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target '#lib::B::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super self::B::•()
+ ;
+}
+class D<P extends core::Object, Q extends core::Object> extends self::C<core::int, self::D::Q, self::D::P> {
+ generic-covariant-impl generic-covariant-interface field core::Map<self::D::P, self::D::Q> foo = null;
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#1
+ IndirectStaticCall 1, CP#0
+ Drop1
+ PushConstant CP#2
+ ReturnTOS
+}
+ConstantPool {
+ [0] = ArgDesc num-args 1, num-type-args 0, names []
+ [1] = StaticICData target '#lib::C::', arg-desc CP#0
+ [2] = Null
+}
+] synthetic constructor •() → void
+ : super self::C::•()
+ ;
+[@vm.bytecode=
+Bytecode {
+ Entry 1
+ CheckStack
+ Push FP[-5]
+ Push FP[-6]
+ LoadFieldTOS CP#0
+ PushConstant CP#1
+ PushConstant CP#2
+ InstanceCall1 4, CP#4
+ PushConstant CP#5
+ IfNeStrictTOS
+ Jump L1
+ PushConstant CP#6
+ PushConstant CP#8
+ IndirectStaticCall 1, CP#7
+ Drop1
+L1:
+ Push FP[-5]
+ Push FP[-6]
+ LoadFieldTOS CP#0
+ PushConstant CP#1
+ PushConstant CP#9
+ InstanceCall1 4, CP#10
+ PushConstant CP#5
+ IfNeStrictTOS
+ Jump L2
+ PushConstant CP#11
+ PushConstant CP#12
+ IndirectStaticCall 1, CP#7
+ Drop1
+L2:
+ Push FP[-6]
+ Push FP[-5]
+ StoreLocal r0
+ InstanceCall1 2, CP#14
+ Drop1
+ Push r0
+ Drop1
+ PushConstant CP#1
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgumentsFieldOffset #lib::D
+ [1] = Null
+ [2] = Type #lib::A<#lib::D::P>
+ [3] = ArgDesc num-args 4, num-type-args 0, names []
+ [4] = ICData target-name '_instanceOf', arg-desc CP#3
+ [5] = Bool true
+ [6] = String '21'
+ [7] = ArgDesc num-args 1, num-type-args 0, names []
+ [8] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [9] = Type #lib::C<dynamic, #lib::D::Q, dart.core::List<#lib::D::P>>
+ [10] = ICData target-name '_instanceOf', arg-desc CP#3
+ [11] = String '22'
+ [12] = StaticICData target 'dart.core::print', arg-desc CP#7
+ [13] = ArgDesc num-args 2, num-type-args 0, names []
+ [14] = ICData target-name 'set:foo', arg-desc CP#13
+}
+] method foo2(dynamic y) → dynamic {
+ if(y is self::A<self::D::P>) {
+ core::print("21");
+ }
+ if(y is self::C<dynamic, self::D::Q, core::List<self::D::P>>) {
+ core::print("22");
+ }
+ this.{self::D::foo} = y as{TypeError} core::Map<self::D::P, self::D::Q>;
+ }
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ Push FP[-6]
+ LoadFieldTOS CP#0
+ Push FP[-7]
+ PushConstant CP#1
+ InstanceCall1 4, CP#3
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L1
+ PushConstant CP#5
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#6
+ Drop1
+L1:
+ Push FP[-5]
+ Push FP[-6]
+ LoadFieldTOS CP#0
+ Push FP[-7]
+ PushConstant CP#8
+ InstanceCall1 4, CP#9
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L2
+ PushConstant CP#10
+ PushConstant CP#11
+ IndirectStaticCall 1, CP#6
+ Drop1
+L2:
+ Push FP[-5]
+ Push FP[-6]
+ LoadFieldTOS CP#0
+ Push FP[-7]
+ PushConstant CP#12
+ InstanceCall1 4, CP#13
+ InstanceCall1 1, CP#14
+ ReturnTOS
+ PushConstant CP#15
+ ReturnTOS
+}
+ConstantPool {
+ [0] = TypeArgumentsFieldOffset #lib::D
+ [1] = Type #lib::A<#lib::D::foo3::T1>
+ [2] = ArgDesc num-args 4, num-type-args 0, names []
+ [3] = ICData target-name '_instanceOf', arg-desc CP#2
+ [4] = Bool true
+ [5] = String '31'
+ [6] = ArgDesc num-args 1, num-type-args 0, names []
+ [7] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [8] = Type #lib::C<dart.core::Map<#lib::D::foo3::T1, #lib::D::P>, dart.core::List<#lib::D::foo3::T2>, #lib::D::Q>
+ [9] = ICData target-name '_instanceOf', arg-desc CP#2
+ [10] = String '32'
+ [11] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [12] = Type dart.core::Map<#lib::D::foo3::T2, #lib::D::Q>
+ [13] = ICData target-name '_as', arg-desc CP#2
+ [14] = ICData target-name 'get:values', arg-desc CP#6
+ [15] = Null
+}
+] method foo3<T1 extends core::Object, T2 extends core::Object>(dynamic z) → dynamic {
+ if(z is self::A<self::D::foo3::T1>) {
+ core::print("31");
+ }
+ if(z is self::C<core::Map<self::D::foo3::T1, self::D::P>, core::List<self::D::foo3::T2>, self::D::Q>) {
+ core::print("32");
+ }
+ return (z as core::Map<self::D::foo3::T2, self::D::Q>).{core::Map::values};
+ }
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ Push FP[-5]
+ PushConstant CP#0
+ PushConstant CP#0
+ PushConstant CP#1
+ InstanceCall1 4, CP#3
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L1
+ PushConstant CP#5
+ PushConstant CP#7
+ IndirectStaticCall 1, CP#6
+ Drop1
+L1:
+ Push FP[-5]
+ PushConstant CP#0
+ PushConstant CP#0
+ PushConstant CP#8
+ InstanceCall1 4, CP#9
+ PushConstant CP#4
+ IfNeStrictTOS
+ Jump L2
+ PushConstant CP#10
+ PushConstant CP#11
+ IndirectStaticCall 1, CP#6
+ Drop1
+L2:
+ Push FP[-5]
+ PushConstant CP#0
+ PushConstant CP#0
+ PushConstant CP#12
+ InstanceCall1 4, CP#13
+ ReturnTOS
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+ [1] = Type #lib::B
+ [2] = ArgDesc num-args 4, num-type-args 0, names []
+ [3] = ICData target-name '_instanceOf', arg-desc CP#2
+ [4] = Bool true
+ [5] = String '11'
+ [6] = ArgDesc num-args 1, num-type-args 0, names []
+ [7] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [8] = Type #lib::C<dart.core::int, dart.core::Object, dynamic>
+ [9] = ICData target-name '_instanceOf', arg-desc CP#2
+ [10] = String '12'
+ [11] = StaticICData target 'dart.core::print', arg-desc CP#6
+ [12] = Type #lib::A<dart.core::int>
+ [13] = ICData target-name '_as', arg-desc CP#2
+}
+]static method foo1(dynamic x) → dynamic {
+ if(x is self::B) {
+ core::print("11");
+ }
+ if(x is self::C<core::int, core::Object, dynamic>) {
+ core::print("12");
+ }
+ return x as self::A<core::int>;
+}
+[@vm.bytecode=
+Bytecode {
+ Entry 0
+ CheckStack
+ PushConstant CP#0
+ ReturnTOS
+}
+ConstantPool {
+ [0] = Null
+}
+]static method main() → dynamic {}
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index a735862..db2fa71 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -1132,7 +1132,7 @@
import("//build/package.gni")
package("package") {
- system_image = true
+ deprecated_system_image = true
package_name = "dart"
@@ -1152,7 +1152,7 @@
}
package("dart_tests") {
- system_image = true
+ deprecated_system_image = true
deps = [
":hello_fuchsia",
diff --git a/runtime/bin/namespace_fuchsia.cc b/runtime/bin/namespace_fuchsia.cc
index b8bb20a..384aa9d 100644
--- a/runtime/bin/namespace_fuchsia.cc
+++ b/runtime/bin/namespace_fuchsia.cc
@@ -11,6 +11,7 @@
#include <fcntl.h>
#include <fdio/namespace.h>
#include <fdio/private.h>
+#include <zircon/status.h>
#include "bin/file.h"
#include "platform/signal_blocker.h"
@@ -42,7 +43,9 @@
~NamespaceImpl() {
if (fdio_ns_ != NULL) {
zx_status_t status = fdio_ns_destroy(fdio_ns_);
- ASSERT(status == ZX_OK);
+ if (status != ZX_OK) {
+ Log::PrintErr("fdio_ns_destroy: %s\n", zx_status_get_string(status));
+ }
}
NO_RETRY_EXPECTED(close(rootfd_));
free(cwd_);
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index b14fb90..a7afafe 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -26,7 +26,7 @@
static void segv_handler(int signal, siginfo_t* siginfo, void* context) {
Log::PrintErr(
- "\n===== DART STANDALONE VM CRASH =====\n"
+ "\n===== CRASH =====\n"
"version=%s\n"
"si_signo=%s(%d), si_code=%d, si_addr=%p\n",
Dart_VersionString(), strsignal(siginfo->si_signo), siginfo->si_signo,
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index 9cd4f71..a8dccc5 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -26,7 +26,7 @@
static void segv_handler(int signal, siginfo_t* siginfo, void* context) {
Log::PrintErr(
- "\n===== DART STANDALONE VM CRASH =====\n"
+ "\n===== CRASH =====\n"
"version=%s\n"
"si_signo=%s(%d), si_code=%d, si_addr=%p\n",
Dart_VersionString(), strsignal(siginfo->si_signo), siginfo->si_signo,
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 3dfe9e5..1cf7f46 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -34,7 +34,7 @@
static void segv_handler(int signal, siginfo_t* siginfo, void* context) {
Log::PrintErr(
- "\n===== DART STANDALONE VM CRASH =====\n"
+ "\n===== CRASH =====\n"
"version=%s\n"
"si_signo=%s(%d), si_code=%d, si_addr=%p\n",
Dart_VersionString(), strsignal(siginfo->si_signo), siginfo->si_signo,
diff --git a/runtime/bin/platform_win.cc b/runtime/bin/platform_win.cc
index 796f250..069b9e5 100644
--- a/runtime/bin/platform_win.cc
+++ b/runtime/bin/platform_win.cc
@@ -64,7 +64,7 @@
(ExceptionInfo->ExceptionRecord->ExceptionCode ==
EXCEPTION_ILLEGAL_INSTRUCTION)) {
Log::PrintErr(
- "\n===== DART STANDALONE VM CRASH =====\n"
+ "\n===== CRASH =====\n"
"version=%s\n"
"ExceptionCode=%d, ExceptionFlags=%d, ExceptionAddress=%p\n",
Dart_VersionString(), ExceptionInfo->ExceptionRecord->ExceptionCode,
diff --git a/runtime/bin/secure_socket_filter.h b/runtime/bin/secure_socket_filter.h
index dda69eb..e09f0e6 100644
--- a/runtime/bin/secure_socket_filter.h
+++ b/runtime/bin/secure_socket_filter.h
@@ -49,6 +49,10 @@
~SSLFilter();
+ char* hostname() const { return hostname_; }
+ bool is_server() const { return is_server_; }
+ bool is_client() const { return !is_server_; }
+
Dart_Handle Init(Dart_Handle dart_this);
void Connect(const char* hostname,
SSLCertContext* context,
diff --git a/runtime/bin/security_context.cc b/runtime/bin/security_context.cc
index 397ed30..56d99e4 100644
--- a/runtime/bin/security_context.cc
+++ b/runtime/bin/security_context.cc
@@ -661,7 +661,6 @@
}
Dart_Handle X509Helper::GetIssuer(Dart_NativeArguments args) {
- fprintf(stdout, "Getting issuer!\n");
X509* certificate = GetX509Certificate(args);
X509_NAME* issuer = X509_get_issuer_name(certificate);
char* issuer_string = X509_NAME_oneline(issuer, NULL, 0);
diff --git a/runtime/bin/security_context_macos.cc b/runtime/bin/security_context_macos.cc
index 1f7a3bb..8dbb43e 100644
--- a/runtime/bin/security_context_macos.cc
+++ b/runtime/bin/security_context_macos.cc
@@ -28,7 +28,11 @@
public:
explicit ScopedCFType(T obj) : obj_(obj) {}
- ~ScopedCFType() { CFRelease(obj_); }
+ ~ScopedCFType() {
+ if (obj_ != NULL) {
+ CFRelease(obj_);
+ }
+ }
T get() { return obj_; }
T* ptr() { return &obj_; }
@@ -45,6 +49,7 @@
typedef ScopedCFType<CFMutableArrayRef> ScopedCFMutableArrayRef;
typedef ScopedCFType<CFDataRef> ScopedCFDataRef;
+typedef ScopedCFType<CFStringRef> ScopedCFStringRef;
typedef ScopedCFType<SecPolicyRef> ScopedSecPolicyRef;
typedef ScopedCFType<SecCertificateRef> ScopedSecCertificateRef;
typedef ScopedCFType<SecTrustRef> ScopedSecTrustRef;
@@ -112,8 +117,19 @@
}
}
- // Generate a generic X509 verification policy.
- ScopedSecPolicyRef policy(SecPolicyCreateBasicX509());
+ // Generate a policy for validating chains for SSL.
+ const int ssl_index = SSL_get_ex_data_X509_STORE_CTX_idx();
+ SSL* ssl = static_cast<SSL*>(X509_STORE_CTX_get_ex_data(ctx, ssl_index));
+ SSLFilter* filter = static_cast<SSLFilter*>(
+ SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
+ CFStringRef cfhostname = NULL;
+ if (filter->hostname() != NULL) {
+ cfhostname = CFStringCreateWithCString(NULL, filter->hostname(),
+ kCFStringEncodingUTF8);
+ }
+ ScopedCFStringRef hostname(cfhostname);
+ ScopedSecPolicyRef policy(
+ SecPolicyCreateSSL(filter->is_client(), hostname.get()));
// Create the trust object with the certificates provided by the user.
ScopedSecTrustRef trust(NULL);
diff --git a/runtime/lib/function.dart b/runtime/lib/function.dart
index ebaa3ec..341758e 100644
--- a/runtime/lib/function.dart
+++ b/runtime/lib/function.dart
@@ -20,7 +20,7 @@
int _computeHash() native "Closure_computeHash";
- // No instance fields should be declared before the following 4 fields whose
+ // No instance fields should be declared before the following fields whose
// offsets must be identical in Dart and C++.
// The following fields are declared both in raw_object.h (for direct access
@@ -30,6 +30,7 @@
// names do not need to match the C++ names, but they must be private.
var _instantiator_type_arguments;
var _function_type_arguments;
+ var _delayed_type_arguments;
var _function;
var _context;
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 43ff9094..5e29999 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -199,7 +199,7 @@
#if defined(DEBUG)
Context& ctx = Context::Handle();
ctx = Closure::Cast(closure).context();
- ASSERT(ctx.num_variables() == 0);
+ ASSERT(ctx.IsNull());
#endif
// Get the parent function so that we get the right function name.
func = func.parent_function();
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index d586dc0..fe0711f 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -462,29 +462,9 @@
TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(0));
const TypeArguments& parent_type_arguments =
TypeArguments::CheckedHandle(zone, arguments->NativeArgAt(1));
- if (function_type_arguments.IsNull() && parent_type_arguments.IsNull()) {
- return TypeArguments::null();
- }
GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_len, arguments->NativeArgAt(2));
const intptr_t len = smi_len.Value();
- const TypeArguments& result =
- TypeArguments::Handle(zone, TypeArguments::New(len, Heap::kNew));
- AbstractType& type = AbstractType::Handle(zone);
- const intptr_t split = parent_type_arguments.IsNull()
- ? len - function_type_arguments.Length()
- : parent_type_arguments.Length();
- for (intptr_t i = 0; i < split; i++) {
- type = parent_type_arguments.IsNull() ? Type::DynamicType()
- : parent_type_arguments.TypeAt(i);
- result.SetTypeAt(i, type);
- }
- for (intptr_t i = split; i < len; i++) {
- type = function_type_arguments.IsNull()
- ? Type::DynamicType()
- : function_type_arguments.TypeAt(i - split);
- result.SetTypeAt(i, type);
- }
- return result.Canonicalize();
+ return function_type_arguments.Prepend(zone, parent_type_arguments, len);
}
DEFINE_NATIVE_ENTRY(InvocationMirror_unpackTypeArguments, 1) {
diff --git a/runtime/lib/typed_data_patch.dart b/runtime/lib/typed_data_patch.dart
index 83a4f54..383bfcd 100644
--- a/runtime/lib/typed_data_patch.dart
+++ b/runtime/lib/typed_data_patch.dart
@@ -3487,7 +3487,7 @@
E get current => _current;
}
-class _TypedListView extends _TypedListBase implements TypedData {
+abstract class _TypedListView extends _TypedListBase implements TypedData {
_TypedListView(_ByteBuffer _buffer, int _offset, int _length)
: _typedData = _buffer._data,
offsetInBytes = _offset,
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index a10cfaa..29800f7 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -2073,6 +2073,9 @@
Iterable get values => _map.values;
int get length => _map.length;
+ // Suppress compile-time error about missing Map methods.
+ noSuchMethod(_) => throw "Unimplemented ServiceMap method";
+
String toString() => "ServiceMap($_map)";
}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 35c3305..07ba355 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -155,7 +155,6 @@
cc/Debugger_PrintBreakpointsToJSONArray: Fail
cc/Debugger_Rewind_Optimized: SkipSlow
cc/Debugger_SetBreakpointInPartOfLibrary: Crash
-cc/FunctionSourceFingerprint: Fail # Issue 30756
cc/IsolateReload_NotTypedefToTypedef: Fail
cc/IsolateReload_TypedefToNotTypedef: Fail
cc/Profiler_BasicSourcePositionOptimized: Skip
@@ -208,6 +207,9 @@
cc/IsolateReload_LibraryImportAdded: Crash # Issue 32190
cc/IsolateReload_LibraryImportRemoved: Fail # Issue 32190
cc/IsolateReload_LibraryLookup: Fail, Crash # Issue 32190
+cc/MismatchedSnapshotKinds: Fail, Crash, OK # Script snapshots not supported in Dart 2
+cc/ScriptSnapshot1: Fail, Crash, OK # Script snapshots not supported in Dart 2
+cc/ScriptSnapshotsUpdateSubclasses: Fail, Crash, OK # Script snapshots not supported in Dart 2
# Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which
# are to be triaged. Isolate tests are skipped on purpose due to the usage of
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 52b7a3b..2bd04fa 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -239,17 +239,19 @@
#if defined(DEBUG)
// Verify that closure field offsets are identical in Dart and C++.
const Array& fields = Array::Handle(zone, cls.fields());
- ASSERT(fields.Length() == 5);
+ ASSERT(fields.Length() == 6);
Field& field = Field::Handle(zone);
field ^= fields.At(0);
ASSERT(field.Offset() == Closure::instantiator_type_arguments_offset());
field ^= fields.At(1);
ASSERT(field.Offset() == Closure::function_type_arguments_offset());
field ^= fields.At(2);
- ASSERT(field.Offset() == Closure::function_offset());
+ ASSERT(field.Offset() == Closure::delayed_type_arguments_offset());
field ^= fields.At(3);
- ASSERT(field.Offset() == Closure::context_offset());
+ ASSERT(field.Offset() == Closure::function_offset());
field ^= fields.At(4);
+ ASSERT(field.Offset() == Closure::context_offset());
+ field ^= fields.At(5);
ASSERT(field.Offset() == Closure::hash_offset());
#endif // defined(DEBUG)
diff --git a/runtime/vm/bootstrap_nocore.cc b/runtime/vm/bootstrap_nocore.cc
index 2a3e095..679c41f 100644
--- a/runtime/vm/bootstrap_nocore.cc
+++ b/runtime/vm/bootstrap_nocore.cc
@@ -49,17 +49,19 @@
#if defined(DEBUG)
// Verify that closure field offsets are identical in Dart and C++.
const Array& fields = Array::Handle(zone, cls.fields());
- ASSERT(fields.Length() == 5);
+ ASSERT(fields.Length() == 6);
Field& field = Field::Handle(zone);
field ^= fields.At(0);
ASSERT(field.Offset() == Closure::instantiator_type_arguments_offset());
field ^= fields.At(1);
ASSERT(field.Offset() == Closure::function_type_arguments_offset());
field ^= fields.At(2);
- ASSERT(field.Offset() == Closure::function_offset());
+ ASSERT(field.Offset() == Closure::delayed_type_arguments_offset());
field ^= fields.At(3);
- ASSERT(field.Offset() == Closure::context_offset());
+ ASSERT(field.Offset() == Closure::function_offset());
field ^= fields.At(4);
+ ASSERT(field.Offset() == Closure::context_offset());
+ field ^= fields.At(5);
ASSERT(field.Offset() == Closure::hash_offset());
#endif // defined(DEBUG)
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 03dbd3b..6243d52 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -5062,13 +5062,13 @@
AddBaseObject(Object::zero_array().raw());
AddBaseObject(Object::dynamic_type().raw());
AddBaseObject(Object::void_type().raw());
+ AddBaseObject(Object::empty_type_arguments().raw());
AddBaseObject(Bool::True().raw());
AddBaseObject(Bool::False().raw());
ASSERT(Object::extractor_parameter_types().raw() != Object::null());
AddBaseObject(Object::extractor_parameter_types().raw());
ASSERT(Object::extractor_parameter_names().raw() != Object::null());
AddBaseObject(Object::extractor_parameter_names().raw());
- AddBaseObject(Object::empty_context().raw());
AddBaseObject(Object::empty_context_scope().raw());
AddBaseObject(Object::empty_descriptors().raw());
AddBaseObject(Object::empty_var_descriptors().raw());
@@ -5507,13 +5507,13 @@
AddBaseObject(Object::zero_array().raw());
AddBaseObject(Object::dynamic_type().raw());
AddBaseObject(Object::void_type().raw());
+ AddBaseObject(Object::empty_type_arguments().raw());
AddBaseObject(Bool::True().raw());
AddBaseObject(Bool::False().raw());
ASSERT(Object::extractor_parameter_types().raw() != Object::null());
AddBaseObject(Object::extractor_parameter_types().raw());
ASSERT(Object::extractor_parameter_names().raw() != Object::null());
AddBaseObject(Object::extractor_parameter_names().raw());
- AddBaseObject(Object::empty_context().raw());
AddBaseObject(Object::empty_context_scope().raw());
AddBaseObject(Object::empty_descriptors().raw());
AddBaseObject(Object::empty_var_descriptors().raw());
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 5d30eda..66f0543 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -26,6 +26,7 @@
// Quick access to the current zone and isolate.
#define I (isolate())
#define Z (graph_->zone())
+#define T (graph_->thread())
ConstantPropagator::ConstantPropagator(
FlowGraph* graph,
@@ -1321,6 +1322,7 @@
// instructions, previous pointers, predecessors, etc. after eliminating
// unreachable code. We do not maintain those properties during the
// transformation.
+ auto& value = Object::Handle(Z);
for (BlockIterator b = graph_->reverse_postorder_iterator(); !b.Done();
b.Advance()) {
BlockEntryInstr* block = b.Current();
@@ -1398,7 +1400,14 @@
THR_Print("Constant v%" Pd " = %s\n", defn->ssa_temp_index(),
defn->constant_value().ToCString());
}
- ConstantInstr* constant = graph_->GetConstant(defn->constant_value());
+ value = defn->constant_value().raw();
+ if ((value.IsString() || value.IsMint() || value.IsDouble()) &&
+ !value.IsCanonical()) {
+ const char* error_str = nullptr;
+ value = Instance::Cast(value).CheckAndCanonicalize(T, &error_str);
+ ASSERT(!value.IsNull() && (error_str == nullptr));
+ }
+ ConstantInstr* constant = graph_->GetConstant(value);
defn->ReplaceUsesWith(constant);
i.RemoveCurrentFromGraph();
}
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index cd4d8f0..9b5729c 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -2898,21 +2898,21 @@
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
- __ LoadFromOffset(kWord, CTX, FP, closure_parameter->index() * kWordSize);
- __ LoadFieldFromOffset(kWord, CTX, CTX, Closure::context_offset());
+ __ LoadFromOffset(kWord, R6, FP, closure_parameter->index() * kWordSize);
+ __ LoadFieldFromOffset(kWord, R6, R6, Closure::context_offset());
const intptr_t context_index =
parsed_function.current_context_var()->index();
- __ StoreToOffset(kWord, CTX, FP, context_index * kWordSize);
+ __ StoreToOffset(kWord, R6, FP, context_index * kWordSize);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
- __ StoreIntoObjectOffset(CTX,
+ __ StoreIntoObjectOffset(R6,
Context::variable_offset(exception_var().index()),
kExceptionObjectReg);
- __ StoreIntoObjectOffset(CTX,
+ __ StoreIntoObjectOffset(R6,
Context::variable_offset(stacktrace_var().index()),
kStackTraceObjectReg);
} else {
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index 595c61a..9c0a698 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -2647,21 +2647,21 @@
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
- __ LoadFromOffset(CTX, FP, closure_parameter->index() * kWordSize);
- __ LoadFieldFromOffset(CTX, CTX, Closure::context_offset());
+ __ LoadFromOffset(R28, FP, closure_parameter->index() * kWordSize);
+ __ LoadFieldFromOffset(R28, R28, Closure::context_offset());
const intptr_t context_index =
parsed_function.current_context_var()->index();
- __ StoreToOffset(CTX, FP, context_index * kWordSize);
+ __ StoreToOffset(R28, FP, context_index * kWordSize);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
- __ StoreIntoObjectOffset(CTX,
+ __ StoreIntoObjectOffset(R28,
Context::variable_offset(exception_var().index()),
kExceptionObjectReg);
- __ StoreIntoObjectOffset(CTX,
+ __ StoreIntoObjectOffset(R28,
Context::variable_offset(stacktrace_var().index()),
kStackTraceObjectReg);
} else {
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 68ba62f..c92b517 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -2506,12 +2506,12 @@
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
- __ movl(CTX, Address(EBP, closure_parameter->index() * kWordSize));
- __ movl(CTX, FieldAddress(CTX, Closure::context_offset()));
+ __ movl(EDI, Address(EBP, closure_parameter->index() * kWordSize));
+ __ movl(EDI, FieldAddress(EDI, Closure::context_offset()));
#ifdef DEBUG
Label ok;
- __ LoadClassId(EBX, CTX);
+ __ LoadClassId(EBX, EDI);
__ cmpl(EBX, Immediate(kContextCid));
__ j(EQUAL, &ok, Assembler::kNearJump);
__ Stop("Incorrect context at entry");
@@ -2520,19 +2520,19 @@
const intptr_t context_index =
parsed_function.current_context_var()->index();
- __ movl(Address(EBP, context_index * kWordSize), CTX);
+ __ movl(Address(EBP, context_index * kWordSize), EDI);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
__ StoreIntoObject(
- CTX,
- FieldAddress(CTX, Context::variable_offset(exception_var().index())),
+ EDI,
+ FieldAddress(EDI, Context::variable_offset(exception_var().index())),
kExceptionObjectReg);
__ StoreIntoObject(
- CTX,
- FieldAddress(CTX, Context::variable_offset(stacktrace_var().index())),
+ EDI,
+ FieldAddress(EDI, Context::variable_offset(stacktrace_var().index())),
kStackTraceObjectReg);
} else {
// Restore stack and initialize the two exception variables:
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 20495f3..b44d650 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -2581,12 +2581,12 @@
LocalVariable* closure_parameter = scope->VariableAt(0);
ASSERT(!closure_parameter->is_captured());
- __ movq(CTX, Address(RBP, closure_parameter->index() * kWordSize));
- __ movq(CTX, FieldAddress(CTX, Closure::context_offset()));
+ __ movq(R12, Address(RBP, closure_parameter->index() * kWordSize));
+ __ movq(R12, FieldAddress(R12, Closure::context_offset()));
#ifdef DEBUG
Label ok;
- __ LoadClassId(RBX, CTX);
+ __ LoadClassId(RBX, R12);
__ cmpq(RBX, Immediate(kContextCid));
__ j(EQUAL, &ok, Assembler::kNearJump);
__ Stop("Incorrect context at entry");
@@ -2595,19 +2595,19 @@
const intptr_t context_index =
parsed_function.current_context_var()->index();
- __ movq(Address(RBP, context_index * kWordSize), CTX);
+ __ movq(Address(RBP, context_index * kWordSize), R12);
}
// Initialize exception and stack trace variables.
if (exception_var().is_captured()) {
ASSERT(stacktrace_var().is_captured());
__ StoreIntoObject(
- CTX,
- FieldAddress(CTX, Context::variable_offset(exception_var().index())),
+ R12,
+ FieldAddress(R12, Context::variable_offset(exception_var().index())),
kExceptionObjectReg);
__ StoreIntoObject(
- CTX,
- FieldAddress(CTX, Context::variable_offset(stacktrace_var().index())),
+ R12,
+ FieldAddress(R12, Context::variable_offset(stacktrace_var().index())),
kStackTraceObjectReg);
} else {
__ movq(Address(RBP, exception_var().index() * kWordSize),
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 7ddfd0c..5c82158 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -2318,6 +2318,17 @@
type_arguments, kEmitStoreBarrier, node->token_pos()));
}
+ // Mark that there are no delayed type arguments.
+ {
+ Value* closure_tmp_val =
+ Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
+ Value* type_arguments =
+ Bind(new (Z) ConstantInstr(Object::empty_type_arguments()));
+ Do(new (Z) StoreInstanceFieldInstr(
+ Closure::delayed_type_arguments_offset(), closure_tmp_val,
+ type_arguments, kEmitStoreBarrier, node->token_pos()));
+ }
+
// Store function.
Value* closure_tmp_val =
Bind(new (Z) LoadLocalInstr(*closure_tmp_var, node->token_pos()));
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index a0cb2ef..4b86b49 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -34,46 +34,46 @@
// Ordered with fall-through.
switch (next_read_) {
case kStart: {
- Tag tag = builder_->ReadTag(); // read tag.
+ Tag tag = helper_->ReadTag(); // read tag.
ASSERT(tag == kFunctionNode);
if (++next_read_ == field) return;
}
case kPosition:
- position_ = builder_->ReadPosition(); // read position.
+ position_ = helper_->ReadPosition(); // read position.
if (++next_read_ == field) return;
case kEndPosition:
- end_position_ = builder_->ReadPosition(); // read end position.
+ end_position_ = helper_->ReadPosition(); // read end position.
if (++next_read_ == field) return;
case kAsyncMarker:
- async_marker_ = static_cast<AsyncMarker>(builder_->ReadByte());
+ async_marker_ = static_cast<AsyncMarker>(helper_->ReadByte());
if (++next_read_ == field) return;
case kDartAsyncMarker:
dart_async_marker_ = static_cast<AsyncMarker>(
- builder_->ReadByte()); // read dart async marker.
+ helper_->ReadByte()); // read dart async marker.
if (++next_read_ == field) return;
case kTypeParameters:
- builder_->SkipTypeParametersList(); // read type parameters.
+ helper_->SkipTypeParametersList(); // read type parameters.
if (++next_read_ == field) return;
case kTotalParameterCount:
total_parameter_count_ =
- builder_->ReadUInt(); // read total parameter count.
+ helper_->ReadUInt(); // read total parameter count.
if (++next_read_ == field) return;
case kRequiredParameterCount:
required_parameter_count_ =
- builder_->ReadUInt(); // read required parameter count.
+ helper_->ReadUInt(); // read required parameter count.
if (++next_read_ == field) return;
case kPositionalParameters:
- builder_->SkipListOfVariableDeclarations(); // read positionals.
+ helper_->SkipListOfVariableDeclarations(); // read positionals.
if (++next_read_ == field) return;
case kNamedParameters:
- builder_->SkipListOfVariableDeclarations(); // read named.
+ helper_->SkipListOfVariableDeclarations(); // read named.
if (++next_read_ == field) return;
case kReturnType:
- builder_->SkipDartType(); // read return type.
+ helper_->SkipDartType(); // read return type.
if (++next_read_ == field) return;
case kBody:
- if (builder_->ReadTag() == kSomething)
- builder_->SkipStatement(); // read body.
+ if (helper_->ReadTag() == kSomething)
+ helper_->SkipStatement(); // read body.
if (++next_read_ == field) return;
case kEnd:
return;
@@ -84,20 +84,20 @@
for (; next_read_ < field; ++next_read_) {
switch (next_read_) {
case kFlags:
- flags_ = builder_->ReadFlags();
+ flags_ = helper_->ReadFlags();
break;
case kAnnotations:
- builder_->SkipListOfExpressions(); // read annotations.
+ helper_->SkipListOfExpressions(); // read annotations.
break;
case kName:
- name_index_ = builder_->ReadStringReference(); // read name index.
+ name_index_ = helper_->ReadStringReference(); // read name index.
break;
case kBound:
- builder_->SkipDartType();
+ helper_->SkipDartType();
break;
case kDefaultType:
- if (builder_->ReadTag() == kSomething) {
- builder_->SkipDartType();
+ if (helper_->ReadTag() == kSomething) {
+ helper_->SkipDartType();
}
break;
case kEnd:
@@ -112,37 +112,37 @@
// Ordered with fall-through.
switch (next_read_) {
case kPosition:
- position_ = builder_->ReadPosition(); // read position.
+ position_ = helper_->ReadPosition(); // read position.
if (++next_read_ == field) return;
case kEqualPosition:
- equals_position_ = builder_->ReadPosition(); // read equals position.
+ equals_position_ = helper_->ReadPosition(); // read equals position.
if (++next_read_ == field) return;
case kAnnotations:
- builder_->SkipListOfExpressions(); // read annotations.
+ helper_->SkipListOfExpressions(); // read annotations.
if (++next_read_ == field) return;
case kFlags:
- flags_ = builder_->ReadFlags();
+ flags_ = helper_->ReadFlags();
if (++next_read_ == field) return;
case kNameIndex:
- name_index_ = builder_->ReadStringReference(); // read name index.
+ name_index_ = helper_->ReadStringReference(); // read name index.
if (++next_read_ == field) return;
case kType:
- builder_->SkipDartType(); // read type.
+ helper_->SkipDartType(); // read type.
if (++next_read_ == field) return;
case kInitializer:
- if (builder_->ReadTag() == kSomething)
- builder_->SkipExpression(); // read initializer.
+ if (helper_->ReadTag() == kSomething)
+ helper_->SkipExpression(); // read initializer.
if (++next_read_ == field) return;
case kEnd:
return;
}
}
-FieldHelper::FieldHelper(StreamingFlowGraphBuilder* builder, intptr_t offset)
- : builder_(builder),
+FieldHelper::FieldHelper(KernelReaderHelper* helper, intptr_t offset)
+ : helper_(helper),
next_read_(kStart),
has_function_literal_initializer_(false) {
- builder_->SetOffset(offset);
+ helper_->SetOffset(offset);
}
void FieldHelper::ReadUntilExcluding(Field field,
@@ -152,62 +152,62 @@
// Ordered with fall-through.
switch (next_read_) {
case kStart: {
- Tag tag = builder_->ReadTag(); // read tag.
+ Tag tag = helper_->ReadTag(); // read tag.
ASSERT(tag == kField);
if (++next_read_ == field) return;
}
case kCanonicalName:
canonical_name_ =
- builder_->ReadCanonicalNameReference(); // read canonical_name.
+ helper_->ReadCanonicalNameReference(); // read canonical_name.
if (++next_read_ == field) return;
case kSourceUriIndex:
- source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
- builder_->current_script_id_ = source_uri_index_;
+ source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
+ helper_->set_current_script_id(source_uri_index_);
if (++next_read_ == field) return;
case kPosition:
- position_ = builder_->ReadPosition(false); // read position.
- builder_->record_token_position(position_);
+ position_ = helper_->ReadPosition(false); // read position.
+ helper_->RecordTokenPosition(position_);
if (++next_read_ == field) return;
case kEndPosition:
- end_position_ = builder_->ReadPosition(false); // read end position.
- builder_->record_token_position(end_position_);
+ end_position_ = helper_->ReadPosition(false); // read end position.
+ helper_->RecordTokenPosition(end_position_);
if (++next_read_ == field) return;
case kFlags:
- flags_ = builder_->ReadFlags();
+ flags_ = helper_->ReadFlags();
if (++next_read_ == field) return;
case kFlags2:
- builder_->ReadFlags();
+ secondary_flags_ = helper_->ReadFlags();
if (++next_read_ == field) return;
case kName:
- builder_->SkipName(); // read name.
+ helper_->SkipName(); // read name.
if (++next_read_ == field) return;
case kAnnotations: {
- annotation_count_ = builder_->ReadListLength(); // read list length.
+ annotation_count_ = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < annotation_count_; ++i) {
- builder_->SkipExpression(); // read ith expression.
+ helper_->SkipExpression(); // read ith expression.
}
if (++next_read_ == field) return;
}
case kType:
- builder_->SkipDartType(); // read type.
+ helper_->SkipDartType(); // read type.
if (++next_read_ == field) return;
case kInitializer:
- if (builder_->ReadTag() == kSomething) {
+ if (helper_->ReadTag() == kSomething) {
if (detect_function_literal_initializer &&
- builder_->PeekTag() == kFunctionExpression) {
- AlternativeReadingScope alt(&builder_->reader_);
- Tag tag = builder_->ReadTag();
+ helper_->PeekTag() == kFunctionExpression) {
+ AlternativeReadingScope alt(&helper_->reader_);
+ Tag tag = helper_->ReadTag();
ASSERT(tag == kFunctionExpression);
- builder_->ReadPosition(); // read position.
+ helper_->ReadPosition(); // read position.
- FunctionNodeHelper helper(builder_);
+ FunctionNodeHelper helper(helper_);
helper.ReadUntilIncluding(FunctionNodeHelper::kEndPosition);
has_function_literal_initializer_ = true;
function_literal_start_ = helper.position_;
function_literal_end_ = helper.end_position_;
}
- builder_->SkipExpression(); // read initializer.
+ helper_->SkipExpression(); // read initializer.
}
if (++next_read_ == field) return;
case kEnd:
@@ -221,56 +221,56 @@
// Ordered with fall-through.
switch (next_read_) {
case kStart: {
- Tag tag = builder_->ReadTag(); // read tag.
+ Tag tag = helper_->ReadTag(); // read tag.
ASSERT(tag == kProcedure);
if (++next_read_ == field) return;
}
case kCanonicalName:
canonical_name_ =
- builder_->ReadCanonicalNameReference(); // read canonical_name.
+ helper_->ReadCanonicalNameReference(); // read canonical_name.
if (++next_read_ == field) return;
case kSourceUriIndex:
- source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
- builder_->current_script_id_ = source_uri_index_;
+ source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
+ helper_->set_current_script_id(source_uri_index_);
if (++next_read_ == field) return;
case kPosition:
- position_ = builder_->ReadPosition(false); // read position.
- builder_->record_token_position(position_);
+ position_ = helper_->ReadPosition(false); // read position.
+ helper_->RecordTokenPosition(position_);
if (++next_read_ == field) return;
case kEndPosition:
- end_position_ = builder_->ReadPosition(false); // read end position.
- builder_->record_token_position(end_position_);
+ end_position_ = helper_->ReadPosition(false); // read end position.
+ helper_->RecordTokenPosition(end_position_);
if (++next_read_ == field) return;
case kKind:
- kind_ = static_cast<Kind>(builder_->ReadByte());
+ kind_ = static_cast<Kind>(helper_->ReadByte());
if (++next_read_ == field) return;
case kFlags:
- flags_ = builder_->ReadFlags();
- flags2_ = builder_->ReadFlags();
+ flags_ = helper_->ReadFlags();
+ flags2_ = helper_->ReadFlags();
if (++next_read_ == field) return;
case kName:
- builder_->SkipName(); // read name.
+ helper_->SkipName(); // read name.
if (++next_read_ == field) return;
case kAnnotations: {
- annotation_count_ = builder_->ReadListLength(); // read list length.
+ annotation_count_ = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < annotation_count_; ++i) {
- builder_->SkipExpression(); // read ith expression.
+ helper_->SkipExpression(); // read ith expression.
}
if (++next_read_ == field) return;
}
case kForwardingStubSuperTarget:
- if (builder_->ReadTag() == kSomething) {
- forwarding_stub_super_target_ = builder_->ReadCanonicalNameReference();
+ if (helper_->ReadTag() == kSomething) {
+ forwarding_stub_super_target_ = helper_->ReadCanonicalNameReference();
}
if (++next_read_ == field) return;
case kForwardingStubInterfaceTarget:
- if (builder_->ReadTag() == kSomething) {
- builder_->ReadCanonicalNameReference();
+ if (helper_->ReadTag() == kSomething) {
+ helper_->ReadCanonicalNameReference();
}
if (++next_read_ == field) return;
case kFunction:
- if (builder_->ReadTag() == kSomething)
- builder_->SkipFunctionNode(); // read function node.
+ if (helper_->ReadTag() == kSomething)
+ helper_->SkipFunctionNode(); // read function node.
if (++next_read_ == field) return;
case kEnd:
return;
@@ -283,47 +283,47 @@
// Ordered with fall-through.
switch (next_read_) {
case kStart: {
- Tag tag = builder_->ReadTag(); // read tag.
+ Tag tag = helper_->ReadTag(); // read tag.
ASSERT(tag == kConstructor);
if (++next_read_ == field) return;
}
case kCanonicalName:
canonical_name_ =
- builder_->ReadCanonicalNameReference(); // read canonical_name.
+ helper_->ReadCanonicalNameReference(); // read canonical_name.
if (++next_read_ == field) return;
case kSourceUriIndex:
- source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
- builder_->current_script_id_ = source_uri_index_;
+ source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
+ helper_->set_current_script_id(source_uri_index_);
if (++next_read_ == field) return;
case kPosition:
- position_ = builder_->ReadPosition(); // read position.
- builder_->record_token_position(position_);
+ position_ = helper_->ReadPosition(); // read position.
+ helper_->RecordTokenPosition(position_);
if (++next_read_ == field) return;
case kEndPosition:
- end_position_ = builder_->ReadPosition(); // read end position.
- builder_->record_token_position(end_position_);
+ end_position_ = helper_->ReadPosition(); // read end position.
+ helper_->RecordTokenPosition(end_position_);
if (++next_read_ == field) return;
case kFlags:
- flags_ = builder_->ReadFlags();
+ flags_ = helper_->ReadFlags();
if (++next_read_ == field) return;
case kName:
- builder_->SkipName(); // read name.
+ helper_->SkipName(); // read name.
if (++next_read_ == field) return;
case kAnnotations: {
- annotation_count_ = builder_->ReadListLength(); // read list length.
+ annotation_count_ = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < annotation_count_; ++i) {
- builder_->SkipExpression(); // read ith expression.
+ helper_->SkipExpression(); // read ith expression.
}
if (++next_read_ == field) return;
}
case kFunction:
- builder_->SkipFunctionNode(); // read function.
+ helper_->SkipFunctionNode(); // read function.
if (++next_read_ == field) return;
case kInitializers: {
intptr_t list_length =
- builder_->ReadListLength(); // read initializers list length.
+ helper_->ReadListLength(); // read initializers list length.
for (intptr_t i = 0; i < list_length; i++) {
- builder_->SkipInitializer();
+ helper_->SkipInitializer();
}
if (++next_read_ == field) return;
}
@@ -338,82 +338,82 @@
// Ordered with fall-through.
switch (next_read_) {
case kStart: {
- Tag tag = builder_->ReadTag(); // read tag.
+ Tag tag = helper_->ReadTag(); // read tag.
ASSERT(tag == kClass);
if (++next_read_ == field) return;
}
case kCanonicalName:
canonical_name_ =
- builder_->ReadCanonicalNameReference(); // read canonical_name.
+ helper_->ReadCanonicalNameReference(); // read canonical_name.
if (++next_read_ == field) return;
case kSourceUriIndex:
- source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
- builder_->current_script_id_ = source_uri_index_;
+ source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
+ helper_->set_current_script_id(source_uri_index_);
if (++next_read_ == field) return;
case kPosition:
- position_ = builder_->ReadPosition(false); // read position.
- builder_->record_token_position(position_);
+ position_ = helper_->ReadPosition(false); // read position.
+ helper_->RecordTokenPosition(position_);
if (++next_read_ == field) return;
case kEndPosition:
- end_position_ = builder_->ReadPosition(); // read end position.
- builder_->record_token_position(end_position_);
+ end_position_ = helper_->ReadPosition(); // read end position.
+ helper_->RecordTokenPosition(end_position_);
if (++next_read_ == field) return;
case kFlags:
- flags_ = builder_->ReadFlags(); // read flags.
+ flags_ = helper_->ReadFlags(); // read flags.
if (++next_read_ == field) return;
case kNameIndex:
- name_index_ = builder_->ReadStringReference(); // read name index.
+ name_index_ = helper_->ReadStringReference(); // read name index.
if (++next_read_ == field) return;
case kAnnotations: {
- annotation_count_ = builder_->ReadListLength(); // read list length.
+ annotation_count_ = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < annotation_count_; ++i) {
- builder_->SkipExpression(); // read ith expression.
+ helper_->SkipExpression(); // read ith expression.
}
if (++next_read_ == field) return;
}
case kTypeParameters:
- builder_->SkipTypeParametersList(); // read type parameters.
+ helper_->SkipTypeParametersList(); // read type parameters.
if (++next_read_ == field) return;
case kSuperClass: {
- Tag type_tag = builder_->ReadTag(); // read super class type (part 1).
+ Tag type_tag = helper_->ReadTag(); // read super class type (part 1).
if (type_tag == kSomething) {
- builder_->SkipDartType(); // read super class type (part 2).
+ helper_->SkipDartType(); // read super class type (part 2).
}
if (++next_read_ == field) return;
}
case kMixinType: {
- Tag type_tag = builder_->ReadTag(); // read mixin type (part 1).
+ Tag type_tag = helper_->ReadTag(); // read mixin type (part 1).
if (type_tag == kSomething) {
- builder_->SkipDartType(); // read mixin type (part 2).
+ helper_->SkipDartType(); // read mixin type (part 2).
}
if (++next_read_ == field) return;
}
case kImplementedClasses:
- builder_->SkipListOfDartTypes(); // read implemented_classes.
+ helper_->SkipListOfDartTypes(); // read implemented_classes.
if (++next_read_ == field) return;
case kFields: {
intptr_t list_length =
- builder_->ReadListLength(); // read fields list length.
+ helper_->ReadListLength(); // read fields list length.
for (intptr_t i = 0; i < list_length; i++) {
- FieldHelper field_helper(builder_);
+ FieldHelper field_helper(helper_);
field_helper.ReadUntilExcluding(FieldHelper::kEnd); // read field.
}
if (++next_read_ == field) return;
}
case kConstructors: {
intptr_t list_length =
- builder_->ReadListLength(); // read constructors list length.
+ helper_->ReadListLength(); // read constructors list length.
for (intptr_t i = 0; i < list_length; i++) {
- ConstructorHelper constructor_helper(builder_);
+ ConstructorHelper constructor_helper(helper_);
constructor_helper.ReadUntilExcluding(
ConstructorHelper::kEnd); // read constructor.
}
if (++next_read_ == field) return;
}
case kProcedures: {
- procedure_count_ = builder_->ReadListLength(); // read procedures #.
+ procedure_count_ = helper_->ReadListLength(); // read procedures #.
for (intptr_t i = 0; i < procedure_count_; i++) {
- ProcedureHelper procedure_helper(builder_);
+ ProcedureHelper procedure_helper(helper_);
procedure_helper.ReadUntilExcluding(
ProcedureHelper::kEnd); // read procedure.
}
@@ -422,10 +422,10 @@
case kClassIndex:
// Read class index.
for (intptr_t i = 0; i < procedure_count_; ++i) {
- builder_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
}
- builder_->reader_.ReadUInt32();
- builder_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
if (++next_read_ == field) return;
case kEnd:
return;
@@ -438,71 +438,71 @@
// Ordered with fall-through.
switch (next_read_) {
case kFlags: {
- flags_ = builder_->ReadFlags();
+ flags_ = helper_->ReadFlags();
if (++next_read_ == field) return;
}
case kCanonicalName:
canonical_name_ =
- builder_->ReadCanonicalNameReference(); // read canonical_name.
+ helper_->ReadCanonicalNameReference(); // read canonical_name.
if (++next_read_ == field) return;
case kName:
- name_index_ = builder_->ReadStringReference(); // read name index.
+ name_index_ = helper_->ReadStringReference(); // read name index.
if (++next_read_ == field) return;
case kSourceUriIndex:
- source_uri_index_ = builder_->ReadUInt(); // read source_uri_index.
- builder_->current_script_id_ = source_uri_index_;
+ source_uri_index_ = helper_->ReadUInt(); // read source_uri_index.
+ helper_->set_current_script_id(source_uri_index_);
if (++next_read_ == field) return;
case kAnnotations:
- builder_->SkipListOfExpressions(); // read annotations.
+ helper_->SkipListOfExpressions(); // read annotations.
if (++next_read_ == field) return;
case kDependencies: {
- intptr_t dependency_count = builder_->ReadUInt(); // read list length.
+ intptr_t dependency_count = helper_->ReadUInt(); // read list length.
for (intptr_t i = 0; i < dependency_count; ++i) {
- builder_->SkipLibraryDependency();
+ helper_->SkipLibraryDependency();
}
if (++next_read_ == field) return;
}
case kAdditionalExports: {
- intptr_t name_count = builder_->ReadUInt();
+ intptr_t name_count = helper_->ReadUInt();
for (intptr_t i = 0; i < name_count; ++i) {
- builder_->SkipCanonicalNameReference();
+ helper_->SkipCanonicalNameReference();
}
if (++next_read_ == field) return;
}
case kParts: {
- intptr_t part_count = builder_->ReadUInt(); // read list length.
+ intptr_t part_count = helper_->ReadUInt(); // read list length.
for (intptr_t i = 0; i < part_count; ++i) {
- builder_->SkipLibraryPart();
+ helper_->SkipLibraryPart();
}
if (++next_read_ == field) return;
}
case kTypedefs: {
- intptr_t typedef_count = builder_->ReadListLength(); // read list length.
+ intptr_t typedef_count = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < typedef_count; i++) {
- builder_->SkipLibraryTypedef();
+ helper_->SkipLibraryTypedef();
}
if (++next_read_ == field) return;
}
case kClasses: {
- class_count_ = builder_->ReadListLength(); // read list length.
+ class_count_ = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < class_count_; ++i) {
- ClassHelper class_helper(builder_);
+ ClassHelper class_helper(helper_);
class_helper.ReadUntilExcluding(ClassHelper::kEnd);
}
if (++next_read_ == field) return;
}
case kToplevelField: {
- intptr_t field_count = builder_->ReadListLength(); // read list length.
+ intptr_t field_count = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < field_count; ++i) {
- FieldHelper field_helper(builder_);
+ FieldHelper field_helper(helper_);
field_helper.ReadUntilExcluding(FieldHelper::kEnd);
}
if (++next_read_ == field) return;
}
case kToplevelProcedures: {
- procedure_count_ = builder_->ReadListLength(); // read list length.
+ procedure_count_ = helper_->ReadListLength(); // read list length.
for (intptr_t i = 0; i < procedure_count_; ++i) {
- ProcedureHelper procedure_helper(builder_);
+ ProcedureHelper procedure_helper(helper_);
procedure_helper.ReadUntilExcluding(ProcedureHelper::kEnd);
}
if (++next_read_ == field) return;
@@ -510,15 +510,15 @@
case kLibraryIndex:
// Read library index.
for (intptr_t i = 0; i < class_count_; ++i) {
- builder_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
}
- builder_->reader_.ReadUInt32();
- builder_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
for (intptr_t i = 0; i < procedure_count_; ++i) {
- builder_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
}
- builder_->reader_.ReadUInt32();
- builder_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
+ helper_->reader_.ReadUInt32();
if (++next_read_ == field) return;
case kEnd:
return;
@@ -531,32 +531,32 @@
// Ordered with fall-through.
switch (next_read_) {
case kFileOffset: {
- builder_->ReadPosition();
+ helper_->ReadPosition();
if (++next_read_ == field) return;
}
case kFlags: {
- flags_ = builder_->ReadFlags();
+ flags_ = helper_->ReadFlags();
if (++next_read_ == field) return;
}
case kAnnotations: {
- builder_->SkipListOfExpressions();
+ helper_->SkipListOfExpressions();
if (++next_read_ == field) return;
}
case kTargetLibrary: {
- target_library_canonical_name_ = builder_->ReadCanonicalNameReference();
+ target_library_canonical_name_ = helper_->ReadCanonicalNameReference();
if (++next_read_ == field) return;
}
case kName: {
- name_index_ = builder_->ReadStringReference();
+ name_index_ = helper_->ReadStringReference();
if (++next_read_ == field) return;
}
case kCombinators: {
- intptr_t count = builder_->ReadListLength();
+ intptr_t count = helper_->ReadListLength();
for (intptr_t i = 0; i < count; ++i) {
// Skip flags
- builder_->SkipBytes(1);
+ helper_->SkipBytes(1);
// Skip list of names.
- builder_->SkipListOfStrings();
+ helper_->SkipListOfStrings();
}
if (++next_read_ == field) return;
}
@@ -894,7 +894,8 @@
scope_->set_end_token_pos(function.end_token_pos());
// Add function type arguments variable before current context variable.
- if (I->reify_generic_functions() && function.IsGeneric()) {
+ if (I->reify_generic_functions() &&
+ (function.IsGeneric() || function.HasGenericParent())) {
LocalVariable* type_args_var = MakeVariable(
TokenPosition::kNoSource, TokenPosition::kNoSource,
Symbols::FunctionTypeArgumentsVar(), AbstractType::dynamic_type());
@@ -3775,6 +3776,705 @@
}
}
+void KernelFingerprintHelper::BuildHash(uint32_t val) {
+ hash_ = CalculateHash(hash_, val);
+}
+
+void KernelFingerprintHelper::CalculateConstructorFingerprint() {
+ ConstructorHelper helper(this);
+
+ helper.ReadUntilExcluding(ConstructorHelper::kAnnotations);
+ CalculateListOfExpressionsFingerprint();
+ CalculateFunctionNodeFingerprint();
+ intptr_t len = ReadListLength();
+ for (intptr_t i = 0; i < len; ++i) {
+ CalculateInitializerFingerprint();
+ }
+ helper.SetJustRead(ConstructorHelper::kInitializers);
+ BuildHash(helper.flags_);
+ BuildHash(helper.annotation_count_);
+}
+
+void KernelFingerprintHelper::CalculateArgumentsFingerprint() {
+ BuildHash(ReadUInt()); // read argument count.
+
+ CalculateListOfDartTypesFingerprint(); // read list of types.
+ CalculateListOfExpressionsFingerprint(); // read positionals.
+
+ // List of named.
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ CalculateStringReferenceFingerprint(); // read ith name index.
+ CalculateExpressionFingerprint(); // read ith expression.
+ }
+}
+
+void KernelFingerprintHelper::CalculateVariableDeclarationFingerprint() {
+ VariableDeclarationHelper helper(this);
+
+ helper.ReadUntilExcluding(VariableDeclarationHelper::kAnnotations);
+ CalculateListOfExpressionsFingerprint();
+ helper.SetJustRead(VariableDeclarationHelper::kAnnotations);
+
+ helper.ReadUntilExcluding(VariableDeclarationHelper::kType);
+ // We don't need to use the helper after this point.
+ CalculateDartTypeFingerprint();
+ if (ReadTag() == kSomething) {
+ CalculateExpressionFingerprint();
+ }
+
+ BuildHash(helper.flags_);
+}
+
+void KernelFingerprintHelper::CalculateStatementListFingerprint() {
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ CalculateStatementFingerprint(); // read ith expression.
+ }
+}
+
+void KernelFingerprintHelper::CalculateListOfExpressionsFingerprint() {
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ CalculateExpressionFingerprint(); // read ith expression.
+ }
+}
+
+void KernelFingerprintHelper::CalculateListOfDartTypesFingerprint() {
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ CalculateDartTypeFingerprint(); // read ith type.
+ }
+}
+
+void KernelFingerprintHelper::CalculateStringReferenceFingerprint() {
+ BuildHash(
+ H.DartString(ReadStringReference()).Hash()); // read ith string index.
+}
+
+void KernelFingerprintHelper::CalculateListOfStringsFingerprint() {
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ CalculateStringReferenceFingerprint(); // read ith string index.
+ }
+}
+
+void KernelFingerprintHelper::CalculateListOfVariableDeclarationsFingerprint() {
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ // read ith variable declaration.
+ CalculateVariableDeclarationFingerprint();
+ }
+}
+
+void KernelFingerprintHelper::CalculateTypeParameterFingerprint() {
+ TypeParameterHelper helper(this);
+
+ helper.ReadUntilExcluding(TypeParameterHelper::kAnnotations);
+ CalculateListOfExpressionsFingerprint();
+ helper.SetJustRead(TypeParameterHelper::kAnnotations);
+
+ helper.ReadUntilExcluding(TypeParameterHelper::kBound);
+ // The helper isn't needed after this point.
+ CalculateDartTypeFingerprint();
+ if (ReadTag() == kSomething) {
+ CalculateDartTypeFingerprint();
+ }
+ BuildHash(helper.flags_);
+}
+
+void KernelFingerprintHelper::CalculateTypeParametersListFingerprint() {
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ CalculateTypeParameterFingerprint();
+ }
+}
+
+void KernelFingerprintHelper::CalculateCanonicalNameFingerprint() {
+ const StringIndex i = H.CanonicalNameString(ReadCanonicalNameReference());
+ BuildHash(H.DartString(i).Hash());
+}
+
+void KernelFingerprintHelper::CalculateInitializerFingerprint() {
+ Tag tag = ReadTag();
+ ReadByte(); // read isSynthetic flag.
+ switch (tag) {
+ case kInvalidInitializer:
+ return;
+ case kFieldInitializer:
+ BuildHash(H.DartFieldName(ReadCanonicalNameReference()).Hash());
+ CalculateExpressionFingerprint(); // read value.
+ return;
+ case kSuperInitializer:
+ CalculateCanonicalNameFingerprint(); // read target_reference
+ CalculateArgumentsFingerprint(); // read arguments.
+ return;
+ case kRedirectingInitializer:
+ CalculateCanonicalNameFingerprint(); // read target_reference
+ CalculateArgumentsFingerprint(); // read arguments.
+ return;
+ case kLocalInitializer:
+ CalculateVariableDeclarationFingerprint(); // read variable.
+ return;
+ case kAssertInitializer:
+ CalculateStatementFingerprint();
+ return;
+ default:
+ ReportUnexpectedTag("initializer", tag);
+ UNREACHABLE();
+ }
+}
+
+void KernelFingerprintHelper::CalculateDartTypeFingerprint() {
+ Tag tag = ReadTag();
+ BuildHash(tag);
+ switch (tag) {
+ case kInvalidType:
+ case kDynamicType:
+ case kVoidType:
+ case kBottomType:
+ case kVectorType:
+ // those contain nothing.
+ break;
+ case kInterfaceType:
+ CalculateInterfaceTypeFingerprint(false);
+ break;
+ case kSimpleInterfaceType:
+ CalculateInterfaceTypeFingerprint(true);
+ break;
+ case kFunctionType:
+ CalculateFunctionTypeFingerprint(false);
+ break;
+ case kSimpleFunctionType:
+ CalculateFunctionTypeFingerprint(true);
+ break;
+ case kTypeParameterType:
+ ReadUInt(); // read index for parameter.
+ CalculateOptionalDartTypeFingerprint(); // read bound bound.
+ break;
+ default:
+ ReportUnexpectedTag("type", tag);
+ UNREACHABLE();
+ }
+}
+
+void KernelFingerprintHelper::CalculateOptionalDartTypeFingerprint() {
+ Tag tag = ReadTag(); // read tag.
+ BuildHash(tag);
+ if (tag == kNothing) {
+ return;
+ }
+ ASSERT(tag == kSomething);
+ CalculateDartTypeFingerprint(); // read type.
+}
+
+void KernelFingerprintHelper::CalculateInterfaceTypeFingerprint(bool simple) {
+ BuildHash(ReadUInt()); // read klass_name.
+ if (!simple) {
+ CalculateListOfDartTypesFingerprint(); // read list of types.
+ }
+}
+
+void KernelFingerprintHelper::CalculateFunctionTypeFingerprint(bool simple) {
+ if (!simple) {
+ CalculateTypeParametersListFingerprint(); // read type_parameters.
+ BuildHash(ReadUInt()); // read required parameter count.
+ BuildHash(ReadUInt()); // read total parameter count.
+ }
+
+ CalculateListOfDartTypesFingerprint(); // read positional_parameters types.
+
+ if (!simple) {
+ const intptr_t named_count =
+ ReadListLength(); // read named_parameters list length.
+ BuildHash(named_count);
+ for (intptr_t i = 0; i < named_count; ++i) {
+ // read string reference (i.e. named_parameters[i].name).
+ CalculateStringReferenceFingerprint();
+ CalculateDartTypeFingerprint(); // read named_parameters[i].type.
+ }
+ }
+
+ CalculateListOfStringsFingerprint(); // read positional parameter names.
+
+ if (!simple) {
+ // TODO(bkonyi): include in hash.
+ SkipCanonicalNameReference(); // read typedef reference.
+ }
+
+ CalculateDartTypeFingerprint(); // read return type.
+}
+
+void KernelFingerprintHelper::CalculateGetterNameFingerprint() {
+ const NameIndex name = ReadCanonicalNameReference();
+ if (I->strong() && !H.IsRoot(name) && (H.IsGetter(name) || H.IsField(name))) {
+ BuildHash(H.DartGetterName(name).Hash());
+ }
+}
+
+void KernelFingerprintHelper::CalculateSetterNameFingerprint() {
+ const NameIndex name = ReadCanonicalNameReference();
+ if (I->strong() && !H.IsRoot(name)) {
+ BuildHash(H.DartSetterName(name).Hash());
+ }
+}
+
+void KernelFingerprintHelper::CalculateMethodNameFingerprint() {
+ const NameIndex name =
+ ReadCanonicalNameReference(); // read interface_target_reference.
+ if (I->strong() && !H.IsRoot(name) && !H.IsField(name)) {
+ BuildHash(H.DartProcedureName(name).Hash());
+ }
+}
+
+void KernelFingerprintHelper::CalculateExpressionFingerprint() {
+ uint8_t payload = 0;
+ Tag tag = ReadTag(&payload);
+ BuildHash(tag);
+ switch (tag) {
+ case kInvalidExpression:
+ ReadPosition();
+ CalculateStringReferenceFingerprint();
+ return;
+ case kVariableGet:
+ ReadPosition(); // read position.
+ ReadUInt(); // read kernel position.
+ ReadUInt(); // read relative variable index.
+ CalculateOptionalDartTypeFingerprint(); // read promoted type.
+ return;
+ case kSpecializedVariableGet:
+ ReadPosition(); // read position.
+ ReadUInt(); // read kernel position.
+ return;
+ case kVariableSet:
+ ReadPosition(); // read position.
+ ReadUInt(); // read kernel position.
+ ReadUInt(); // read relative variable index.
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ case kSpecializedVariableSet:
+ ReadPosition(); // read position.
+ ReadUInt(); // read kernel position.
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ case kPropertyGet:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read receiver.
+ BuildHash(ReadNameAsGetterName().Hash()); // read name.
+ CalculateGetterNameFingerprint(); // read interface_target_reference.
+ return;
+ case kPropertySet:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read receiver.
+ BuildHash(ReadNameAsSetterName().Hash()); // read name.
+ CalculateExpressionFingerprint(); // read value.
+ CalculateSetterNameFingerprint(); // read interface_target_reference.
+ return;
+ case kSuperPropertyGet:
+ ReadPosition(); // read position.
+ BuildHash(ReadNameAsGetterName().Hash()); // read name.
+ CalculateGetterNameFingerprint(); // read interface_target_reference.
+ return;
+ case kSuperPropertySet:
+ ReadPosition(); // read position.
+ BuildHash(ReadNameAsSetterName().Hash()); // read name.
+ CalculateExpressionFingerprint(); // read value.
+ CalculateSetterNameFingerprint(); // read interface_target_reference.
+ return;
+ case kDirectPropertyGet:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read receiver.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ return;
+ case kDirectPropertySet:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read receiver.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ CalculateExpressionFingerprint(); // read value·
+ return;
+ case kStaticGet:
+ ReadPosition(); // read position.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ return;
+ case kStaticSet:
+ ReadPosition(); // read position.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ case kMethodInvocation:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read receiver.
+ BuildHash(ReadNameAsMethodName().Hash()); // read name.
+ CalculateArgumentsFingerprint(); // read arguments.
+ CalculateMethodNameFingerprint(); // read interface_target_reference.
+ return;
+ case kSuperMethodInvocation:
+ ReadPosition(); // read position.
+ BuildHash(ReadNameAsMethodName().Hash()); // read name.
+ CalculateArgumentsFingerprint(); // read arguments.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ return;
+ case kDirectMethodInvocation:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read receiver.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ CalculateArgumentsFingerprint(); // read arguments.
+ return;
+ case kStaticInvocation:
+ case kConstStaticInvocation:
+ ReadPosition(); // read position.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ CalculateArgumentsFingerprint(); // read arguments.
+ return;
+ case kConstructorInvocation:
+ case kConstConstructorInvocation:
+ ReadPosition(); // read position.
+ CalculateCanonicalNameFingerprint(); // read target_reference.
+ CalculateArgumentsFingerprint(); // read arguments.
+ return;
+ case kNot:
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ case kLogicalExpression:
+ CalculateExpressionFingerprint(); // read left.
+ SkipBytes(1); // read operator.
+ CalculateExpressionFingerprint(); // read right.
+ return;
+ case kConditionalExpression:
+ CalculateExpressionFingerprint(); // read condition.
+ CalculateExpressionFingerprint(); // read then.
+ CalculateExpressionFingerprint(); // read otherwise.
+ CalculateOptionalDartTypeFingerprint(); // read unused static type.
+ return;
+ case kStringConcatenation:
+ ReadPosition(); // read position.
+ CalculateListOfExpressionsFingerprint(); // read list of expressions.
+ return;
+ case kIsExpression:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read operand.
+ CalculateDartTypeFingerprint(); // read type.
+ return;
+ case kAsExpression:
+ ReadPosition(); // read position.
+ BuildHash(ReadFlags()); // read flags.
+ CalculateExpressionFingerprint(); // read operand.
+ CalculateDartTypeFingerprint(); // read type.
+ return;
+ case kSymbolLiteral:
+ CalculateStringReferenceFingerprint(); // read index into string table.
+ return;
+ case kTypeLiteral:
+ CalculateDartTypeFingerprint(); // read type.
+ return;
+ case kThisExpression:
+ return;
+ case kRethrow:
+ ReadPosition(); // read position.
+ return;
+ case kThrow:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ case kListLiteral:
+ case kConstListLiteral:
+ ReadPosition(); // read position.
+ CalculateDartTypeFingerprint(); // read type.
+ CalculateListOfExpressionsFingerprint(); // read list of expressions.
+ return;
+ case kMapLiteral:
+ case kConstMapLiteral: {
+ ReadPosition(); // read position.
+ CalculateDartTypeFingerprint(); // read type.
+ CalculateDartTypeFingerprint(); // read value type.
+ intptr_t list_length = ReadListLength(); // read list length.
+ for (intptr_t i = 0; i < list_length; ++i) {
+ CalculateExpressionFingerprint(); // read ith key.
+ CalculateExpressionFingerprint(); // read ith value.
+ }
+ return;
+ }
+ case kFunctionExpression:
+ ReadPosition(); // read position.
+ CalculateFunctionNodeFingerprint(); // read function node.
+ return;
+ case kLet:
+ CalculateVariableDeclarationFingerprint(); // read variable declaration.
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ case kInstantiation:
+ CalculateExpressionFingerprint(); // read expression.
+ CalculateListOfDartTypesFingerprint(); // read type arguments.
+ return;
+ case kVectorCreation:
+ BuildHash(ReadUInt()); // read value.
+ return;
+ case kVectorGet:
+ CalculateExpressionFingerprint(); // read vector expression.
+ BuildHash(ReadUInt()); // read index.
+ return;
+ case kVectorSet:
+ CalculateExpressionFingerprint(); // read vector expression.
+ BuildHash(ReadUInt()); // read index.
+ CalculateExpressionFingerprint(); // read value.
+ return;
+ case kVectorCopy:
+ CalculateExpressionFingerprint(); // read vector expression.
+ return;
+ case kClosureCreation:
+ // read top-level function reference.
+ CalculateCanonicalNameFingerprint();
+ CalculateExpressionFingerprint(); // read context vector.
+ CalculateDartTypeFingerprint(); // read function type.
+ CalculateListOfDartTypesFingerprint(); // read type arguments.
+ return;
+ case kBigIntLiteral:
+ CalculateStringReferenceFingerprint(); // read string reference.
+ return;
+ case kStringLiteral:
+ CalculateStringReferenceFingerprint(); // read string reference.
+ return;
+ case kSpecializedIntLiteral:
+ return;
+ case kNegativeIntLiteral:
+ BuildHash(ReadUInt()); // read value.
+ return;
+ case kPositiveIntLiteral:
+ BuildHash(ReadUInt()); // read value.
+ return;
+ case kDoubleLiteral:
+ CalculateStringReferenceFingerprint(); // read index into string table.
+ return;
+ case kTrueLiteral:
+ return;
+ case kFalseLiteral:
+ return;
+ case kNullLiteral:
+ return;
+ case kConstantExpression:
+ SkipConstantReference();
+ return;
+ case kLoadLibrary:
+ case kCheckLibraryIsLoaded:
+ ReadUInt(); // skip library index
+ return;
+ default:
+ ReportUnexpectedTag("expression", tag);
+ UNREACHABLE();
+ }
+}
+
+void KernelFingerprintHelper::CalculateStatementFingerprint() {
+ Tag tag = ReadTag(); // read tag.
+ BuildHash(tag);
+ switch (tag) {
+ case kExpressionStatement:
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ case kBlock:
+ CalculateStatementListFingerprint();
+ return;
+ case kEmptyStatement:
+ return;
+ case kAssertBlock:
+ CalculateStatementListFingerprint();
+ return;
+ case kAssertStatement:
+ CalculateExpressionFingerprint(); // Read condition.
+ ReadPosition(); // read condition start offset.
+ ReadPosition(); // read condition end offset.
+ if (ReadTag() == kSomething) {
+ CalculateExpressionFingerprint(); // read (rest of) message.
+ }
+ return;
+ case kLabeledStatement:
+ CalculateStatementFingerprint(); // read body.
+ return;
+ case kBreakStatement:
+ ReadPosition(); // read position.
+ ReadUInt(); // read target_index.
+ return;
+ case kWhileStatement:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read condition.
+ CalculateStatementFingerprint(); // read body.
+ return;
+ case kDoStatement:
+ ReadPosition(); // read position.
+ CalculateStatementFingerprint(); // read body.
+ CalculateExpressionFingerprint(); // read condition.
+ return;
+ case kForStatement: {
+ ReadPosition(); // read position.
+ CalculateListOfVariableDeclarationsFingerprint(); // read variables.
+ Tag tag = ReadTag(); // Read first part of condition.
+ if (tag == kSomething) {
+ CalculateExpressionFingerprint(); // read rest of condition.
+ }
+ CalculateListOfExpressionsFingerprint(); // read updates.
+ CalculateStatementFingerprint(); // read body.
+ return;
+ }
+ case kForInStatement:
+ case kAsyncForInStatement:
+ ReadPosition(); // read position.
+ ReadPosition(); // read body position.
+ CalculateVariableDeclarationFingerprint(); // read variable.
+ CalculateExpressionFingerprint(); // read iterable.
+ CalculateStatementFingerprint(); // read body.
+ return;
+ case kSwitchStatement: {
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read condition.
+ int case_count = ReadListLength(); // read number of cases.
+ for (intptr_t i = 0; i < case_count; ++i) {
+ int expression_count = ReadListLength(); // read number of expressions.
+ for (intptr_t j = 0; j < expression_count; ++j) {
+ ReadPosition(); // read jth position.
+ CalculateExpressionFingerprint(); // read jth expression.
+ }
+ BuildHash(ReadBool()); // read is_default.
+ CalculateStatementFingerprint(); // read body.
+ }
+ return;
+ }
+ case kContinueSwitchStatement:
+ ReadPosition(); // read position.
+ ReadUInt(); // read target_index.
+ return;
+ case kIfStatement:
+ ReadPosition(); // read position.
+ CalculateExpressionFingerprint(); // read condition.
+ CalculateStatementFingerprint(); // read then.
+ CalculateStatementFingerprint(); // read otherwise.
+ return;
+ case kReturnStatement: {
+ ReadPosition(); // read position
+ Tag tag = ReadTag(); // read (first part of) expression.
+ BuildHash(tag);
+ if (tag == kSomething) {
+ CalculateExpressionFingerprint(); // read (rest of) expression.
+ }
+ return;
+ }
+ case kTryCatch: {
+ CalculateStatementFingerprint(); // read body.
+ BuildHash(ReadBool()); // read any_catch_needs_stack_trace.
+ intptr_t catch_count = ReadListLength(); // read number of catches.
+ for (intptr_t i = 0; i < catch_count; ++i) {
+ ReadPosition(); // read position.
+ CalculateDartTypeFingerprint(); // read guard.
+ tag = ReadTag(); // read first part of exception.
+ BuildHash(tag);
+ if (tag == kSomething) {
+ CalculateVariableDeclarationFingerprint(); // read exception.
+ }
+ tag = ReadTag(); // read first part of stack trace.
+ BuildHash(tag);
+ if (tag == kSomething) {
+ CalculateVariableDeclarationFingerprint(); // read stack trace.
+ }
+ CalculateStatementFingerprint(); // read body.
+ }
+ return;
+ }
+ case kTryFinally:
+ CalculateStatementFingerprint(); // read body.
+ CalculateStatementFingerprint(); // read finalizer.
+ return;
+ case kYieldStatement: {
+ ReadPosition(); // read position.
+ BuildHash(ReadByte()); // read flags.
+ CalculateExpressionFingerprint(); // read expression.
+ return;
+ }
+ case kVariableDeclaration:
+ CalculateVariableDeclarationFingerprint(); // read variable declaration.
+ return;
+ case kFunctionDeclaration:
+ ReadPosition(); // read position.
+ CalculateVariableDeclarationFingerprint(); // read variable.
+ CalculateFunctionNodeFingerprint(); // read function node.
+ return;
+ default:
+ ReportUnexpectedTag("statement", tag);
+ UNREACHABLE();
+ }
+}
+
+uint32_t KernelFingerprintHelper::CalculateFieldFingerprint() {
+ hash_ = 0;
+ FieldHelper field_helper(this);
+
+ field_helper.ReadUntilExcluding(FieldHelper::kName);
+ const String& name = ReadNameAsFieldName(); // read name.
+ field_helper.SetJustRead(FieldHelper::kName);
+
+ field_helper.ReadUntilExcluding(FieldHelper::kType);
+ CalculateDartTypeFingerprint(); // read type.
+ field_helper.SetJustRead(FieldHelper::kType);
+
+ if (ReadTag() == kSomething) {
+ if (PeekTag() == kFunctionExpression) {
+ AlternativeReadingScope alt(&reader_);
+ CalculateExpressionFingerprint();
+ }
+ SkipExpression();
+ }
+
+ BuildHash(name.Hash());
+ BuildHash((field_helper.flags_ << 8) | field_helper.secondary_flags_);
+ BuildHash(field_helper.annotation_count_);
+ return hash_;
+}
+
+void KernelFingerprintHelper::CalculateFunctionNodeFingerprint() {
+ FunctionNodeHelper function_node_helper(this);
+
+ function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
+ CalculateTypeParametersListFingerprint();
+ function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
+
+ function_node_helper.ReadUntilExcluding(
+ FunctionNodeHelper::kPositionalParameters);
+ CalculateListOfVariableDeclarationsFingerprint(); // read positionals
+ CalculateListOfVariableDeclarationsFingerprint(); // read named
+ CalculateDartTypeFingerprint(); // read return type.
+
+ if (ReadTag() == kSomething) {
+ CalculateStatementFingerprint(); // Read body.
+ }
+ BuildHash(function_node_helper.total_parameter_count_);
+ BuildHash(function_node_helper.required_parameter_count_);
+}
+
+uint32_t KernelFingerprintHelper::CalculateFunctionFingerprint() {
+ hash_ = 0;
+ Tag tag = PeekTag();
+ if (tag == kField) {
+ return CalculateFieldFingerprint();
+ } else if (tag == kConstructor) {
+ CalculateConstructorFingerprint();
+ return hash_;
+ }
+ ProcedureHelper procedure_helper(this);
+ procedure_helper.ReadUntilExcluding(ProcedureHelper::kName);
+ const String& name = ReadNameAsMethodName(); // Read name.
+ procedure_helper.SetJustRead(ProcedureHelper::kName);
+
+ procedure_helper.ReadUntilExcluding(ProcedureHelper::kFunction);
+ if (ReadTag() == kSomething) {
+ CalculateFunctionNodeFingerprint();
+ }
+
+ BuildHash(procedure_helper.kind_);
+ BuildHash(procedure_helper.flags_);
+ BuildHash(procedure_helper.flags2_);
+ BuildHash(procedure_helper.annotation_count_);
+ BuildHash(name.Hash());
+ return hash_;
+}
+
void StreamingFlowGraphBuilder::ReadUntilFunctionNode(
ParsedFunction* parsed_function) {
const Tag tag = PeekTag();
@@ -4229,63 +4929,10 @@
body +=
flow_graph_builder_->CheckStackOverflowInPrologue(function.token_pos());
- // Forwarding the type parameters is complicated by our approach to
- // implementing the partial tearoff instantiation.
- //
- // When a tearoff is partially applied to a set of type arguments, the type
- // arguments are saved in the closure's "function_type_arguments" field. The
- // partial type application operator is guaranteed to provide arguments for
- // all of a generic tearoff's type parameters, so we will only have to forward
- // type arguments from the caller or from the closure object. In other words,
- // if there are type arguments saved on the tearoff, we must throw
- // NoSuchMethod.
intptr_t type_args_len = 0;
if (I->reify_generic_functions() && function.IsGeneric()) {
+ type_args_len = function.NumTypeParameters();
ASSERT(parsed_function()->function_type_arguments() != NULL);
- type_args_len = target.NumTypeParameters();
-
- Fragment copy_type_args;
-
- LocalVariable* closure =
- parsed_function()->node_sequence()->scope()->VariableAt(0);
- copy_type_args += LoadLocal(closure);
- copy_type_args += LoadField(Closure::function_type_arguments_offset());
-
- TargetEntryInstr *is_instantiated, *is_not_instantiated;
- copy_type_args +=
- BranchIfNull(&is_not_instantiated, &is_instantiated, /*negate=*/false);
- JoinEntryInstr* join = BuildJoinEntry();
-
- // We found type arguments saved on the tearoff to be provided to the
- // function.
-
- Fragment copy_instantiated_args(is_instantiated);
-
- copy_instantiated_args +=
- LoadLocal(parsed_function()->function_type_arguments());
-
- TargetEntryInstr *no_type_args, *passed_type_args;
- copy_instantiated_args +=
- BranchIfNull(&no_type_args, &passed_type_args, /*negate=*/false);
-
- Fragment use_instantiated_args(no_type_args);
- use_instantiated_args += LoadLocal(closure);
- use_instantiated_args +=
- LoadField(Closure::function_type_arguments_offset());
- use_instantiated_args += StoreLocal(
- TokenPosition::kNoSource, parsed_function()->function_type_arguments());
- use_instantiated_args += Drop();
- use_instantiated_args += Goto(join);
-
- Fragment goto_nsm(passed_type_args);
- goto_nsm += Goto(flow_graph_builder_->BuildThrowNoSuchMethod());
-
- // The tearoff was not partially applied, so we forward type arguments from
- // the caller.
- Fragment forward_caller_args(is_not_instantiated);
- forward_caller_args += Goto(join);
-
- body += Fragment(copy_type_args.entry, join);
body += LoadLocal(parsed_function()->function_type_arguments());
body += PushArgument();
}
@@ -4766,55 +5413,58 @@
Fragment body;
- if (dart_function.IsConvertedClosureFunction()) {
- LocalVariable* closure = new (Z) LocalVariable(
+ LocalVariable* closure = NULL;
+ if (dart_function.IsClosureFunction()) {
+ closure = parsed_function()->node_sequence()->scope()->VariableAt(0);
+ } else if (dart_function.IsConvertedClosureFunction()) {
+ closure = new (Z) LocalVariable(
TokenPosition::kNoSource, TokenPosition::kNoSource,
Symbols::TempParam(), AbstractType::ZoneHandle(Z, Type::DynamicType()));
closure->set_index(parsed_function()->first_parameter_index());
closure->set_is_captured_parameter(true);
+ }
+
+ if ((dart_function.IsClosureFunction() ||
+ dart_function.IsConvertedClosureFunction()) &&
+ dart_function.NumParentTypeParameters() > 0 &&
+ I->reify_generic_functions()) {
+ LocalVariable* fn_type_args = parsed_function()->function_type_arguments();
+ ASSERT(fn_type_args != NULL && closure != NULL);
+
+ if (dart_function.IsGeneric()) {
+ body += LoadLocal(fn_type_args);
+ body += PushArgument();
+ body += LoadLocal(closure);
+ body += LoadField(Closure::function_type_arguments_offset());
+ body += PushArgument();
+ body += IntConstant(dart_function.NumTypeParameters() +
+ dart_function.NumParentTypeParameters());
+ body += PushArgument();
+
+ const Library& dart_internal =
+ Library::Handle(Z, Library::InternalLibrary());
+ const Function& prepend_function =
+ Function::ZoneHandle(Z, dart_internal.LookupFunctionAllowPrivate(
+ Symbols::PrependTypeArguments()));
+ ASSERT(!prepend_function.IsNull());
+
+ body += StaticCall(TokenPosition::kNoSource, prepend_function, 3,
+ ICData::kStatic);
+ body += StoreLocal(TokenPosition::kNoSource, fn_type_args);
+ body += Drop();
+ } else {
+ body += LoadLocal(closure);
+ body += LoadField(Closure::function_type_arguments_offset());
+ body += StoreLocal(TokenPosition::kNoSource, fn_type_args);
+ body += Drop();
+ }
+ }
+
+ if (dart_function.IsConvertedClosureFunction()) {
body += LoadLocal(closure);
body += LoadField(Closure::context_offset());
LocalVariable* context = closure;
body += StoreLocal(TokenPosition::kNoSource, context);
-
- // TODO(30455): Kernel generic methods undone. When generic closures are
- // supported, the type arguments passed by the caller will actually need to
- // be used here.
- if (dart_function.IsGeneric() && I->reify_generic_functions()) {
- LocalVariable* type_args_slot =
- parsed_function()->function_type_arguments();
- ASSERT(type_args_slot != NULL);
- body += LoadField(Context::variable_offset(0));
- body += StoreLocal(TokenPosition::kNoSource, type_args_slot);
- }
- body += Drop();
- } else if (dart_function.IsClosureFunction() && dart_function.IsGeneric() &&
- dart_function.NumParentTypeParameters() > 0 &&
- I->reify_generic_functions()) {
- LocalVariable* closure =
- parsed_function()->node_sequence()->scope()->VariableAt(0);
- LocalVariable* fn_type_args = parsed_function()->function_type_arguments();
- ASSERT(fn_type_args != NULL && closure != NULL);
-
- body += LoadLocal(fn_type_args);
- body += PushArgument();
- body += LoadLocal(closure);
- body += LoadField(Closure::function_type_arguments_offset());
- body += PushArgument();
- body += IntConstant(dart_function.NumTypeParameters() +
- dart_function.NumParentTypeParameters());
- body += PushArgument();
-
- const Library& dart_internal =
- Library::Handle(Z, Library::InternalLibrary());
- const Function& prepend_function =
- Function::ZoneHandle(Z, dart_internal.LookupFunctionAllowPrivate(
- Symbols::PrependTypeArguments()));
- ASSERT(!prepend_function.IsNull());
-
- body += StaticCall(TokenPosition::kNoSource, prepend_function, 3,
- ICData::kStatic);
- body += StoreLocal(TokenPosition::kNoSource, fn_type_args);
body += Drop();
}
@@ -5344,57 +5994,57 @@
return Fragment();
}
-intptr_t StreamingFlowGraphBuilder::ReaderOffset() {
+intptr_t KernelReaderHelper::ReaderOffset() const {
return reader_.offset();
}
-void StreamingFlowGraphBuilder::SetOffset(intptr_t offset) {
+void KernelReaderHelper::SetOffset(intptr_t offset) {
reader_.set_offset(offset);
}
-void StreamingFlowGraphBuilder::SkipBytes(intptr_t bytes) {
+void KernelReaderHelper::SkipBytes(intptr_t bytes) {
reader_.set_offset(ReaderOffset() + bytes);
}
-bool StreamingFlowGraphBuilder::ReadBool() {
+bool KernelReaderHelper::ReadBool() {
return reader_.ReadBool();
}
-uint8_t StreamingFlowGraphBuilder::ReadByte() {
+uint8_t KernelReaderHelper::ReadByte() {
return reader_.ReadByte();
}
-uint32_t StreamingFlowGraphBuilder::ReadUInt() {
+uint32_t KernelReaderHelper::ReadUInt() {
return reader_.ReadUInt();
}
-uint32_t StreamingFlowGraphBuilder::ReadUInt32() {
+uint32_t KernelReaderHelper::ReadUInt32() {
return reader_.ReadUInt32();
}
-uint32_t StreamingFlowGraphBuilder::PeekUInt() {
+uint32_t KernelReaderHelper::PeekUInt() {
AlternativeReadingScope alt(&reader_);
return reader_.ReadUInt();
}
-uint32_t StreamingFlowGraphBuilder::PeekListLength() {
+uint32_t KernelReaderHelper::PeekListLength() {
AlternativeReadingScope alt(&reader_);
return reader_.ReadListLength();
}
-intptr_t StreamingFlowGraphBuilder::ReadListLength() {
+intptr_t KernelReaderHelper::ReadListLength() {
return reader_.ReadListLength();
}
-StringIndex StreamingFlowGraphBuilder::ReadStringReference() {
+StringIndex KernelReaderHelper::ReadStringReference() {
return StringIndex(ReadUInt());
}
-NameIndex StreamingFlowGraphBuilder::ReadCanonicalNameReference() {
+NameIndex KernelReaderHelper::ReadCanonicalNameReference() {
return reader_.ReadCanonicalNameReference();
}
-StringIndex StreamingFlowGraphBuilder::ReadNameAsStringIndex() {
+StringIndex KernelReaderHelper::ReadNameAsStringIndex() {
StringIndex name_index = ReadStringReference(); // read name index.
if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
ReadUInt(); // read library index.
@@ -5402,7 +6052,7 @@
return name_index;
}
-const String& StreamingFlowGraphBuilder::ReadNameAsMethodName() {
+const String& KernelReaderHelper::ReadNameAsMethodName() {
StringIndex name_index = ReadStringReference(); // read name index.
if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
NameIndex library_reference =
@@ -5413,7 +6063,7 @@
}
}
-const String& StreamingFlowGraphBuilder::ReadNameAsSetterName() {
+const String& KernelReaderHelper::ReadNameAsSetterName() {
StringIndex name_index = ReadStringReference(); // read name index.
if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
NameIndex library_reference =
@@ -5424,7 +6074,7 @@
}
}
-const String& StreamingFlowGraphBuilder::ReadNameAsGetterName() {
+const String& KernelReaderHelper::ReadNameAsGetterName() {
StringIndex name_index = ReadStringReference(); // read name index.
if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
NameIndex library_reference =
@@ -5435,7 +6085,7 @@
}
}
-const String& StreamingFlowGraphBuilder::ReadNameAsFieldName() {
+const String& KernelReaderHelper::ReadNameAsFieldName() {
StringIndex name_index = ReadStringReference(); // read name index.
if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
NameIndex library_reference =
@@ -5446,34 +6096,41 @@
}
}
-void StreamingFlowGraphBuilder::SkipFlags() {
+void KernelReaderHelper::SkipFlags() {
ReadFlags();
}
-void StreamingFlowGraphBuilder::SkipStringReference() {
+void KernelReaderHelper::SkipStringReference() {
ReadUInt();
}
-void StreamingFlowGraphBuilder::SkipConstantReference() {
+void KernelReaderHelper::SkipConstantReference() {
ReadUInt();
}
-void StreamingFlowGraphBuilder::SkipCanonicalNameReference() {
+void KernelReaderHelper::SkipCanonicalNameReference() {
ReadUInt();
}
+void KernelReaderHelper::ReportUnexpectedTag(const char* variant, Tag tag) {
+ H.ReportError(script_, TokenPosition::kNoSource,
+ "Unexpected tag %d (%s) in ?, expected %s", tag,
+ Reader::TagName(tag), variant);
+}
+
void StreamingFlowGraphBuilder::ReportUnexpectedTag(const char* variant,
Tag tag) {
- H.ReportError(script_, TokenPosition::kNoSource,
- "Unexpected tag %d (%s) in %s, expected %s", tag,
- Reader::TagName(tag),
- flow_graph_builder_ != NULL && parsed_function() != NULL
- ? parsed_function()->function().ToQualifiedCString()
- : "?",
- variant);
+ if ((flow_graph_builder_ == NULL) || (parsed_function() == NULL)) {
+ KernelReaderHelper::ReportUnexpectedTag(variant, tag);
+ } else {
+ H.ReportError(script_, TokenPosition::kNoSource,
+ "Unexpected tag %d (%s) in %s, expected %s", tag,
+ Reader::TagName(tag),
+ parsed_function()->function().ToQualifiedCString(), variant);
+ }
}
-void StreamingFlowGraphBuilder::SkipDartType() {
+void KernelReaderHelper::SkipDartType() {
Tag tag = ReadTag();
switch (tag) {
case kInvalidType:
@@ -5505,7 +6162,7 @@
}
}
-void StreamingFlowGraphBuilder::SkipOptionalDartType() {
+void KernelReaderHelper::SkipOptionalDartType() {
Tag tag = ReadTag(); // read tag.
if (tag == kNothing) {
return;
@@ -5515,14 +6172,14 @@
SkipDartType(); // read type.
}
-void StreamingFlowGraphBuilder::SkipInterfaceType(bool simple) {
+void KernelReaderHelper::SkipInterfaceType(bool simple) {
ReadUInt(); // read klass_name.
if (!simple) {
SkipListOfDartTypes(); // read list of types.
}
}
-void StreamingFlowGraphBuilder::SkipFunctionType(bool simple) {
+void KernelReaderHelper::SkipFunctionType(bool simple) {
if (!simple) {
SkipTypeParametersList(); // read type_parameters.
ReadUInt(); // read required parameter count.
@@ -5550,42 +6207,42 @@
SkipDartType(); // read return type.
}
-void StreamingFlowGraphBuilder::SkipStatementList() {
+void KernelReaderHelper::SkipStatementList() {
intptr_t list_length = ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
SkipStatement(); // read ith expression.
}
}
-void StreamingFlowGraphBuilder::SkipListOfExpressions() {
+void KernelReaderHelper::SkipListOfExpressions() {
intptr_t list_length = ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
SkipExpression(); // read ith expression.
}
}
-void StreamingFlowGraphBuilder::SkipListOfDartTypes() {
+void KernelReaderHelper::SkipListOfDartTypes() {
intptr_t list_length = ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
SkipDartType(); // read ith type.
}
}
-void StreamingFlowGraphBuilder::SkipListOfStrings() {
+void KernelReaderHelper::SkipListOfStrings() {
intptr_t list_length = ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
SkipStringReference(); // read ith string index.
}
}
-void StreamingFlowGraphBuilder::SkipListOfVariableDeclarations() {
+void KernelReaderHelper::SkipListOfVariableDeclarations() {
intptr_t list_length = ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
SkipVariableDeclaration(); // read ith variable declaration.
}
}
-void StreamingFlowGraphBuilder::SkipTypeParametersList() {
+void KernelReaderHelper::SkipTypeParametersList() {
intptr_t list_length = ReadListLength(); // read list length.
for (intptr_t i = 0; i < list_length; ++i) {
TypeParameterHelper helper(this);
@@ -5593,7 +6250,7 @@
}
}
-void StreamingFlowGraphBuilder::SkipInitializer() {
+void KernelReaderHelper::SkipInitializer() {
Tag tag = ReadTag();
ReadByte(); // read isSynthetic flag.
switch (tag) {
@@ -5623,7 +6280,7 @@
}
}
-void StreamingFlowGraphBuilder::SkipExpression() {
+void KernelReaderHelper::SkipExpression() {
uint8_t payload = 0;
Tag tag = ReadTag(&payload);
switch (tag) {
@@ -5858,7 +6515,7 @@
}
}
-void StreamingFlowGraphBuilder::SkipStatement() {
+void KernelReaderHelper::SkipStatement() {
Tag tag = ReadTag(); // read tag.
switch (tag) {
case kExpressionStatement:
@@ -5974,7 +6631,7 @@
return;
case kYieldStatement: {
TokenPosition position = ReadPosition(); // read position.
- record_yield_position(position);
+ RecordYieldPosition(position);
ReadByte(); // read flags.
SkipExpression(); // read expression.
return;
@@ -5993,19 +6650,19 @@
}
}
-void StreamingFlowGraphBuilder::SkipFunctionNode() {
+void KernelReaderHelper::SkipFunctionNode() {
FunctionNodeHelper function_node_helper(this);
function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
}
-void StreamingFlowGraphBuilder::SkipName() {
+void KernelReaderHelper::SkipName() {
StringIndex name_index = ReadStringReference(); // read name index.
if ((H.StringSize(name_index) >= 1) && H.CharacterAt(name_index, 0) == '_') {
SkipCanonicalNameReference(); // read library index.
}
}
-void StreamingFlowGraphBuilder::SkipArguments() {
+void KernelReaderHelper::SkipArguments() {
ReadUInt(); // read argument count.
SkipListOfDartTypes(); // read list of types.
@@ -6019,12 +6676,12 @@
}
}
-void StreamingFlowGraphBuilder::SkipVariableDeclaration() {
+void KernelReaderHelper::SkipVariableDeclaration() {
VariableDeclarationHelper helper(this);
helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd);
}
-void StreamingFlowGraphBuilder::SkipLibraryCombinator() {
+void KernelReaderHelper::SkipLibraryCombinator() {
ReadBool(); // read is_show.
intptr_t name_count = ReadUInt(); // read list length.
for (intptr_t j = 0; j < name_count; ++j) {
@@ -6032,7 +6689,7 @@
}
}
-void StreamingFlowGraphBuilder::SkipLibraryDependency() {
+void KernelReaderHelper::SkipLibraryDependency() {
ReadPosition(); // read file offset.
ReadFlags();
SkipListOfExpressions(); // Annotations.
@@ -6044,12 +6701,12 @@
}
}
-void StreamingFlowGraphBuilder::SkipLibraryPart() {
+void KernelReaderHelper::SkipLibraryPart() {
SkipListOfExpressions(); // Read annotations.
SkipStringReference(); // Read part URI index.
}
-void StreamingFlowGraphBuilder::SkipLibraryTypedef() {
+void KernelReaderHelper::SkipLibraryTypedef() {
SkipCanonicalNameReference(); // read canonical name.
ReadUInt(); // read source_uri_index.
ReadPosition(); // read position.
@@ -6059,33 +6716,33 @@
SkipDartType(); // read type.
}
-TokenPosition StreamingFlowGraphBuilder::ReadPosition(bool record) {
+TokenPosition KernelReaderHelper::ReadPosition(bool record) {
TokenPosition position = reader_.ReadPosition();
if (record) {
- record_token_position(position);
+ RecordTokenPosition(position);
}
return position;
}
-void StreamingFlowGraphBuilder::record_token_position(TokenPosition position) {
+void StreamingFlowGraphBuilder::RecordTokenPosition(TokenPosition position) {
if (record_for_script_id_ == current_script_id_ &&
record_token_positions_into_ != NULL && position.IsReal()) {
record_token_positions_into_->Add(position.value());
}
}
-void StreamingFlowGraphBuilder::record_yield_position(TokenPosition position) {
+void StreamingFlowGraphBuilder::RecordYieldPosition(TokenPosition position) {
if (record_for_script_id_ == current_script_id_ &&
record_yield_positions_into_ != NULL && position.IsReal()) {
record_yield_positions_into_->Add(position.value());
}
}
-Tag StreamingFlowGraphBuilder::ReadTag(uint8_t* payload) {
+Tag KernelReaderHelper::ReadTag(uint8_t* payload) {
return reader_.ReadTag(payload);
}
-Tag StreamingFlowGraphBuilder::PeekTag(uint8_t* payload) {
+Tag KernelReaderHelper::PeekTag(uint8_t* payload) {
return reader_.PeekTag(payload);
}
@@ -8328,9 +8985,9 @@
TokenPosition* position) {
if (position != NULL) *position = TokenPosition::kNoSource;
- Double& constant =
- Double::ZoneHandle(Z, Double::New(H.DartString(ReadStringReference()),
- Heap::kOld)); // read string reference.
+ Double& constant = Double::ZoneHandle(
+ Z, Double::NewCanonical(
+ H.DartString(ReadStringReference()))); // read string reference.
return Constant(constant);
}
@@ -8423,7 +9080,15 @@
ReadCanonicalNameReference(); // read function reference.
Function& function = Function::ZoneHandle(
Z, H.LookupStaticMethodByKernelProcedure(function_reference));
- function = function.ConvertedClosureFunction();
+
+ intptr_t num_type_parameters;
+ {
+ AlternativeReadingScope _(&reader_);
+ SkipExpression(); // context vector
+ SkipDartType(); // skip function type
+ num_type_parameters = ReadListLength();
+ }
+ function = function.ConvertedClosureFunction(num_type_parameters);
ASSERT(!function.IsNull());
const Class& closure_class =
@@ -8444,34 +9109,25 @@
instructions +=
StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset());
- SkipDartType(); // skip function type of the closure.
+ // Skip the function type of the closure (it's predicable from the
+ // target and the supplied type arguments).
+ SkipDartType();
- // TODO(30455): Kernel generic methods undone. When generic methods are
- // fully supported in kernel, we'll need to store a NULL in the type arguments
- // slot when type arguments are absent, so the wrapper for the target function
- // can tell how many type args are captured vs. provided by the caller of the
- // closure.
-
- intptr_t types_count = ReadListLength(); // read type count.
- if (types_count > 0) {
- const TypeArguments& type_args =
- T.BuildTypeArguments(types_count); // read list of type arguments.
- instructions += TranslateInstantiatedTypeArguments(type_args);
- LocalVariable* type_args_slot = MakeTemporary();
-
- instructions += LoadLocal(context);
- instructions += LoadLocal(type_args_slot);
- instructions += StoreInstanceField(TokenPosition::kNoSource,
- Context::variable_offset(0));
-
+ ReadListLength(); // type parameter count
+ if (num_type_parameters > 0) {
instructions += LoadLocal(closure);
- instructions += LoadLocal(type_args_slot);
+ const TypeArguments& type_args = T.BuildTypeArguments(
+ num_type_parameters); // read list of type arguments.
+ instructions += TranslateInstantiatedTypeArguments(type_args);
instructions += StoreInstanceField(
TokenPosition::kNoSource, Closure::function_type_arguments_offset());
-
- instructions += Drop(); // type args
}
+ instructions += LoadLocal(closure);
+ instructions += Constant(Object::empty_type_arguments());
+ instructions += StoreInstanceField(TokenPosition::kNoSource,
+ Closure::delayed_type_arguments_offset());
+
instructions += Drop(); // context
return instructions;
}
@@ -8500,23 +9156,10 @@
instructions += LoadLocal(new_closure);
intptr_t num_type_args = ReadListLength();
- const TypeArguments* type_args = &T.BuildTypeArguments(num_type_args);
-
- // Even if all dynamic types are passed in, we need to put a vector in here to
- // distinguish this partially applied tearoff from a normal tearoff. This is
- // necessary because the tearoff wrapper (BuildGraphOfImplicitClosureFunction)
- // needs to throw NSM if type arguments are passed to a partially applied
- // tearoff.
- if (type_args->IsNull()) {
- type_args =
- &TypeArguments::ZoneHandle(Z, TypeArguments::New(num_type_args));
- for (intptr_t i = 0; i < num_type_args; ++i) {
- type_args->SetTypeAt(i, Type::ZoneHandle(Z, Type::DynamicType()));
- }
- }
- instructions += TranslateInstantiatedTypeArguments(*type_args);
+ const TypeArguments& type_args = T.BuildTypeArguments(num_type_args);
+ instructions += TranslateInstantiatedTypeArguments(type_args);
instructions += StoreInstanceField(TokenPosition::kNoSource,
- Closure::function_type_arguments_offset());
+ Closure::delayed_type_arguments_offset());
// Copy over the target function.
instructions += LoadLocal(new_closure);
@@ -8532,6 +9175,13 @@
instructions += StoreInstanceField(
TokenPosition::kNoSource, Closure::instantiator_type_arguments_offset());
+ // Copy over the function type arguments.
+ instructions += LoadLocal(new_closure);
+ instructions += LoadLocal(original_closure);
+ instructions += LoadField(Closure::function_type_arguments_offset());
+ instructions += StoreInstanceField(TokenPosition::kNoSource,
+ Closure::function_type_arguments_offset());
+
// Copy over the context.
instructions += LoadLocal(new_closure);
instructions += LoadLocal(original_closure);
@@ -9647,6 +10297,11 @@
instructions += flow_graph_builder_->StoreInstanceField(
TokenPosition::kNoSource, Closure::function_type_arguments_offset());
+ instructions += LoadLocal(closure);
+ instructions += Constant(Object::empty_type_arguments());
+ instructions += flow_graph_builder_->StoreInstanceField(
+ TokenPosition::kNoSource, Closure::delayed_type_arguments_offset());
+
// Store the function and the context in the closure.
instructions += LoadLocal(closure);
instructions += Constant(function);
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 722e9ab..337c045d6 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -17,6 +17,8 @@
namespace dart {
namespace kernel {
+class KernelReaderHelper;
+
// Helper class that reads a kernel FunctionNode from binary.
//
// Use ReadUntilExcluding to read up to but not including a field.
@@ -50,8 +52,8 @@
kSyncYielding = 4,
};
- explicit FunctionNodeHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
+ explicit FunctionNodeHelper(KernelReaderHelper* helper) {
+ helper_ = helper;
next_read_ = kStart;
}
@@ -72,7 +74,7 @@
intptr_t required_parameter_count_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -93,8 +95,8 @@
kIsGenericCovariantInterface = 1 << 1
};
- explicit TypeParameterHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
+ explicit TypeParameterHelper(KernelReaderHelper* helper) {
+ helper_ = helper;
next_read_ = kStart;
}
@@ -119,7 +121,7 @@
StringIndex name_index_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -151,10 +153,8 @@
kIsGenericCovariantInterface = 1 << 6
};
- explicit VariableDeclarationHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kPosition;
- }
+ explicit VariableDeclarationHelper(KernelReaderHelper* helper)
+ : helper_(helper), next_read_(kPosition) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -182,7 +182,7 @@
StringIndex name_index_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -219,12 +219,12 @@
kIsGenericCovariantInterface = 1 << 7
};
- explicit FieldHelper(StreamingFlowGraphBuilder* builder)
- : builder_(builder),
+ explicit FieldHelper(KernelReaderHelper* helper)
+ : helper_(helper),
next_read_(kStart),
has_function_literal_initializer_(false) {}
- FieldHelper(StreamingFlowGraphBuilder* builder, intptr_t offset);
+ FieldHelper(KernelReaderHelper* helper, intptr_t offset);
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -260,11 +260,12 @@
TokenPosition position_;
TokenPosition end_position_;
uint8_t flags_;
+ uint8_t secondary_flags_;
intptr_t source_uri_index_;
intptr_t annotation_count_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
bool has_function_literal_initializer_;
@@ -320,10 +321,8 @@
kNoSuchMethodForwarder = 1 << 0,
};
- explicit ProcedureHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kStart;
- }
+ explicit ProcedureHelper(KernelReaderHelper* helper)
+ : helper_(helper), next_read_(kStart) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -359,7 +358,7 @@
NameIndex forwarding_stub_super_target_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -392,10 +391,8 @@
kSynthetic = 1 << 2,
};
- explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kStart;
- }
+ explicit ConstructorHelper(KernelReaderHelper* helper)
+ : helper_(helper), next_read_(kStart) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -418,7 +415,7 @@
intptr_t annotation_count_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -456,10 +453,8 @@
kIsEnumClass = 2,
};
- explicit ClassHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kStart;
- }
+ explicit ClassHelper(KernelReaderHelper* helper)
+ : helper_(helper), next_read_(kStart) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -484,7 +479,7 @@
uint8_t flags_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -518,10 +513,8 @@
kExternal = 1,
};
- explicit LibraryHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kFlags;
- }
+ explicit LibraryHelper(KernelReaderHelper* helper)
+ : helper_(helper), next_read_(kFlags) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -542,7 +535,7 @@
intptr_t procedure_count_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -567,10 +560,8 @@
Show = 1 << 0,
};
- explicit LibraryDependencyHelper(StreamingFlowGraphBuilder* builder) {
- builder_ = builder;
- next_read_ = kFileOffset;
- }
+ explicit LibraryDependencyHelper(KernelReaderHelper* helper)
+ : helper_(helper), next_read_(kFileOffset) {}
void ReadUntilIncluding(Field field) {
ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
@@ -583,7 +574,7 @@
NameIndex target_library_canonical_name_;
private:
- StreamingFlowGraphBuilder* builder_;
+ KernelReaderHelper* helper_;
intptr_t next_read_;
};
@@ -792,7 +783,7 @@
void EnterScope(intptr_t kernel_offset);
void ExitScope(TokenPosition start_position, TokenPosition end_position);
- void ReportUnexpectedTag(const char* variant, Tag tag);
+ virtual void ReportUnexpectedTag(const char* variant, Tag tag);
// This enum controls which parameters would be marked as requring type
// check on the callee side.
@@ -1002,132 +993,56 @@
Instance& result_;
};
-class StreamingFlowGraphBuilder {
+class KernelReaderHelper {
public:
- StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
- const TypedData& data,
- intptr_t data_program_offset)
- : flow_graph_builder_(flow_graph_builder),
- translation_helper_(flow_graph_builder->translation_helper_),
- zone_(flow_graph_builder->zone_),
- reader_(data),
- script_(Script::Handle(zone_, parsed_function()->function().script())),
- constant_evaluator_(this),
- type_translator_(this, /* finalize= */ true),
- data_program_offset_(data_program_offset),
- current_script_id_(-1),
- record_for_script_id_(-1),
- record_token_positions_into_(NULL),
- 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,
- Zone* zone,
- const uint8_t* data_buffer,
- intptr_t buffer_length,
- intptr_t data_program_offset)
- : flow_graph_builder_(NULL),
+ KernelReaderHelper(Zone* zone,
+ TranslationHelper* translation_helper,
+ const Script& script,
+ const TypedData& data,
+ intptr_t data_program_offset)
+ : zone_(zone),
translation_helper_(*translation_helper),
- zone_(zone),
- reader_(data_buffer, buffer_length),
- script_(Script::Handle(zone_)),
- constant_evaluator_(this),
- type_translator_(this, /* finalize= */ true),
- data_program_offset_(data_program_offset),
- current_script_id_(-1),
- record_for_script_id_(-1),
- record_token_positions_into_(NULL),
- 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,
- const Script& script,
- Zone* zone,
- const TypedData& data,
- intptr_t data_program_offset)
- : flow_graph_builder_(NULL),
- translation_helper_(*translation_helper),
- zone_(zone),
reader_(data),
script_(script),
- constant_evaluator_(this),
- type_translator_(this, /* finalize= */ true),
- data_program_offset_(data_program_offset),
- current_script_id_(-1),
- record_for_script_id_(-1),
- record_token_positions_into_(NULL),
- record_yield_positions_into_(NULL),
- direct_call_metadata_helper_(this),
- inferred_type_metadata_helper_(this),
- procedure_attributes_metadata_helper_(this),
- metadata_scanned_(false) {}
+ data_program_offset_(data_program_offset) {}
- ~StreamingFlowGraphBuilder() {}
+ KernelReaderHelper(Zone* zone,
+ TranslationHelper* translation_helper,
+ const uint8_t* data_buffer,
+ intptr_t buffer_length,
+ intptr_t data_program_offset)
+ : zone_(zone),
+ translation_helper_(*translation_helper),
+ reader_(data_buffer, buffer_length),
+ script_(Script::Handle(zone_)),
+ data_program_offset_(data_program_offset) {}
- FlowGraph* BuildGraph(intptr_t kernel_offset);
+ virtual ~KernelReaderHelper() {}
- Fragment BuildStatementAt(intptr_t kernel_offset);
- RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
- RawObject* EvaluateMetadata(intptr_t kernel_offset);
- void CollectTokenPositionsFor(
- intptr_t script_index,
- intptr_t initial_script_index,
- intptr_t kernel_offset,
- GrowableArray<intptr_t>* record_token_positions_in,
- GrowableArray<intptr_t>* record_yield_positions_in);
- intptr_t SourceTableSize();
- String& SourceTableUriFor(intptr_t index);
- String& GetSourceFor(intptr_t index);
- RawTypedData* GetLineStartsFor(intptr_t index);
void SetOffset(intptr_t offset);
- // If a 'ParsedFunction' is provided for 'set_forwarding_stub', this method
- // will attach the forwarding stub target reference to the parsed function if
- // it crosses a procedure node for a concrete forwarding stub.
- void ReadUntilFunctionNode(ParsedFunction* set_forwarding_stub = NULL);
intptr_t ReadListLength();
+ virtual void ReportUnexpectedTag(const char* variant, Tag tag);
- void ReportUnexpectedTag(const char* variant, Tag tag);
+ protected:
+ const Script& script() const { return script_; }
- private:
- void LoadAndSetupTypeParameters(ActiveClass* active_class,
- const Object& set_on,
- intptr_t type_parameter_count,
- const Function& parameterized_function);
+ virtual void set_current_script_id(intptr_t id) {
+ // Do nothing by default. This is overridden in StreamingFlowGraphBuilder.
+ USE(id);
+ }
- void DiscoverEnclosingElements(Zone* zone,
- const Function& function,
- Function* outermost_function);
+ virtual void RecordYieldPosition(TokenPosition position) {
+ // Do nothing by default. This is overridden in StreamingFlowGraphBuilder.
+ USE(position);
+ }
- StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
- const Function& function);
+ virtual void RecordTokenPosition(TokenPosition position) {
+ // Do nothing by default. This is overridden in StreamingFlowGraphBuilder.
+ USE(position);
+ }
- bool optimizing();
-
- FlowGraph* BuildGraphOfFieldInitializer();
- FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
- void SetupDefaultParameterValues();
- Fragment BuildFieldInitializer(NameIndex canonical_name);
- Fragment BuildInitializers(const Class& parent_class);
- FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
- FlowGraph* BuildGraphOfFunction(bool constructor);
- FlowGraph* BuildGraphOfNoSuchMethodForwarder(
- const Function& function,
- bool is_implicit_closure_function,
- bool throw_no_such_method_error = false);
-
- intptr_t GetOffsetForSourceInfo(intptr_t index);
-
- Fragment BuildExpression(TokenPosition* position = NULL);
- Fragment BuildStatement();
-
- intptr_t ReaderOffset();
+ intptr_t ReaderOffset() const;
void SkipBytes(intptr_t skip);
bool ReadBool();
uint8_t ReadByte();
@@ -1168,12 +1083,222 @@
void SkipLibraryPart();
void SkipLibraryTypedef();
TokenPosition ReadPosition(bool record = true);
- void record_token_position(TokenPosition position);
- void record_yield_position(TokenPosition position);
Tag ReadTag(uint8_t* payload = NULL);
Tag PeekTag(uint8_t* payload = NULL);
uint8_t ReadFlags() { return reader_.ReadFlags(); }
+ Zone* zone_;
+ TranslationHelper& translation_helper_;
+ Reader reader_;
+ const Script& script_;
+ // Some items like variables are specified in the kernel binary as
+ // absolute offsets (as in, offsets within the whole kernel program)
+ // of their declaration nodes. Hence, to cache and/or access them
+ // uniquely from within a function's kernel data, we need to
+ // add/subtract the offset of the kernel data in the over all
+ // kernel program.
+ intptr_t data_program_offset_;
+
+ friend class ClassHelper;
+ friend class ConstantHelper;
+ friend class ConstructorHelper;
+ friend class DirectCallMetadataHelper;
+ friend class ProcedureAttributesMetadataHelper;
+ friend class FieldHelper;
+ friend class FunctionNodeHelper;
+ friend class InferredTypeMetadataHelper;
+ friend class KernelLoader;
+ friend class LibraryDependencyHelper;
+ friend class LibraryHelper;
+ friend class MetadataHelper;
+ friend class ProcedureHelper;
+ friend class SimpleExpressionConverter;
+ friend class StreamingConstantEvaluator;
+ friend class StreamingDartTypeTranslator;
+ friend class StreamingScopeBuilder;
+ friend class VariableDeclarationHelper;
+ friend class TypeParameterHelper;
+};
+
+class KernelFingerprintHelper : public KernelReaderHelper {
+ public:
+ KernelFingerprintHelper(Zone* zone,
+ TranslationHelper* translation_helper,
+ const Script& script,
+ const TypedData& data,
+ intptr_t data_program_offset)
+ : KernelReaderHelper(zone,
+ translation_helper,
+ script,
+ data,
+ data_program_offset),
+ hash_(0) {}
+
+ virtual ~KernelFingerprintHelper() {}
+ uint32_t CalculateFieldFingerprint();
+ uint32_t CalculateFunctionFingerprint();
+
+ static uint32_t CalculateHash(uint32_t current, uint32_t val) {
+ return current * 31 + val;
+ }
+
+ private:
+ void BuildHash(uint32_t val);
+ void CalculateConstructorFingerprint();
+ void CalculateArgumentsFingerprint();
+ void CalculateVariableDeclarationFingerprint();
+ void CalculateStatementListFingerprint();
+ void CalculateListOfExpressionsFingerprint();
+ void CalculateListOfDartTypesFingerprint();
+ void CalculateListOfVariableDeclarationsFingerprint();
+ void CalculateStringReferenceFingerprint();
+ void CalculateListOfStringsFingerprint();
+ void CalculateTypeParameterFingerprint();
+ void CalculateTypeParametersListFingerprint();
+ void CalculateCanonicalNameFingerprint();
+ void CalculateInitializerFingerprint();
+ void CalculateDartTypeFingerprint();
+ void CalculateOptionalDartTypeFingerprint();
+ void CalculateInterfaceTypeFingerprint(bool simple);
+ void CalculateFunctionTypeFingerprint(bool simple);
+ void CalculateGetterNameFingerprint();
+ void CalculateSetterNameFingerprint();
+ void CalculateMethodNameFingerprint();
+ void CalculateExpressionFingerprint();
+ void CalculateStatementFingerprint();
+ void CalculateFunctionNodeFingerprint();
+
+ uint32_t hash_;
+};
+
+class StreamingFlowGraphBuilder : public KernelReaderHelper {
+ public:
+ StreamingFlowGraphBuilder(FlowGraphBuilder* flow_graph_builder,
+ const TypedData& data,
+ intptr_t data_program_offset)
+ : KernelReaderHelper(
+ flow_graph_builder->zone_,
+ &flow_graph_builder->translation_helper_,
+ Script::Handle(
+ flow_graph_builder->zone_,
+ flow_graph_builder->parsed_function_->function().script()),
+ data,
+ data_program_offset),
+ flow_graph_builder_(flow_graph_builder),
+ constant_evaluator_(this),
+ type_translator_(this, /* finalize= */ true),
+ current_script_id_(-1),
+ record_for_script_id_(-1),
+ record_token_positions_into_(NULL),
+ 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,
+ Zone* zone,
+ const uint8_t* data_buffer,
+ intptr_t buffer_length,
+ intptr_t data_program_offset)
+ : KernelReaderHelper(zone,
+ translation_helper,
+ data_buffer,
+ buffer_length,
+ data_program_offset),
+ flow_graph_builder_(NULL),
+ constant_evaluator_(this),
+ type_translator_(this, /* finalize= */ true),
+ current_script_id_(-1),
+ record_for_script_id_(-1),
+ record_token_positions_into_(NULL),
+ 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,
+ const Script& script,
+ Zone* zone,
+ const TypedData& data,
+ intptr_t data_program_offset)
+ : KernelReaderHelper(zone,
+ translation_helper,
+ script,
+ data,
+ data_program_offset),
+ flow_graph_builder_(NULL),
+ constant_evaluator_(this),
+ type_translator_(this, /* finalize= */ true),
+ current_script_id_(-1),
+ record_for_script_id_(-1),
+ record_token_positions_into_(NULL),
+ record_yield_positions_into_(NULL),
+ direct_call_metadata_helper_(this),
+ inferred_type_metadata_helper_(this),
+ procedure_attributes_metadata_helper_(this),
+ metadata_scanned_(false) {}
+
+ virtual ~StreamingFlowGraphBuilder() {}
+
+ FlowGraph* BuildGraph(intptr_t kernel_offset);
+
+ void ReportUnexpectedTag(const char* variant, Tag tag) override;
+
+ Fragment BuildStatementAt(intptr_t kernel_offset);
+ RawObject* BuildParameterDescriptor(intptr_t kernel_offset);
+ RawObject* EvaluateMetadata(intptr_t kernel_offset);
+ void CollectTokenPositionsFor(
+ intptr_t script_index,
+ intptr_t initial_script_index,
+ intptr_t kernel_offset,
+ GrowableArray<intptr_t>* record_token_positions_in,
+ GrowableArray<intptr_t>* record_yield_positions_in);
+ intptr_t SourceTableSize();
+ String& SourceTableUriFor(intptr_t index);
+ String& GetSourceFor(intptr_t index);
+ RawTypedData* GetLineStartsFor(intptr_t index);
+
+ // If a 'ParsedFunction' is provided for 'set_forwarding_stub', this method
+ // will attach the forwarding stub target reference to the parsed function if
+ // it crosses a procedure node for a concrete forwarding stub.
+ void ReadUntilFunctionNode(ParsedFunction* set_forwarding_stub = NULL);
+
+ enum DispatchCategory { Interface, ViaThis, Closure, DynamicDispatch };
+
+ private:
+ void LoadAndSetupTypeParameters(ActiveClass* active_class,
+ const Object& set_on,
+ intptr_t type_parameter_count,
+ const Function& parameterized_function);
+
+ void DiscoverEnclosingElements(Zone* zone,
+ const Function& function,
+ Function* outermost_function);
+
+ StringIndex GetNameFromVariableDeclaration(intptr_t kernel_offset,
+ const Function& function);
+
+ bool optimizing();
+
+ FlowGraph* BuildGraphOfFieldInitializer();
+ FlowGraph* BuildGraphOfFieldAccessor(LocalVariable* setter_value);
+ void SetupDefaultParameterValues();
+ Fragment BuildFieldInitializer(NameIndex canonical_name);
+ Fragment BuildInitializers(const Class& parent_class);
+ FlowGraph* BuildGraphOfImplicitClosureFunction(const Function& function);
+ FlowGraph* BuildGraphOfFunction(bool constructor);
+ FlowGraph* BuildGraphOfNoSuchMethodForwarder(
+ const Function& function,
+ bool is_implicit_closure_function,
+ bool throw_no_such_method_error = false);
+
+ intptr_t GetOffsetForSourceInfo(intptr_t index);
+
+ Fragment BuildExpression(TokenPosition* position = NULL);
+ Fragment BuildStatement();
+
void loop_depth_inc();
void loop_depth_dec();
intptr_t for_in_depth();
@@ -1425,26 +1550,18 @@
bool is_closure,
FunctionNodeHelper* function_node_helper);
- const Script& script() { return script_; }
+ void set_current_script_id(intptr_t id) override { current_script_id_ = id; }
+
+ void RecordTokenPosition(TokenPosition position) override;
+ void RecordYieldPosition(TokenPosition position) override;
// Scan through metadata mappings section and cache offsets for recognized
// metadata kinds.
void EnsureMetadataIsScanned();
FlowGraphBuilder* flow_graph_builder_;
- TranslationHelper& translation_helper_;
- Zone* zone_;
- Reader reader_;
- const Script& script_;
StreamingConstantEvaluator constant_evaluator_;
StreamingDartTypeTranslator type_translator_;
- // Some items like variables are specified in the kernel binary as
- // absolute offsets (as in, offsets within the whole kernel program)
- // of their declaration nodes. Hence, to cache and/or access them
- // uniquely from within a function's kernel data, we need to
- // add/subtract the offset of the kernel data in the over all
- // kernel program.
- intptr_t data_program_offset_;
intptr_t current_script_id_;
intptr_t record_for_script_id_;
GrowableArray<intptr_t>* record_token_positions_into_;
@@ -1463,7 +1580,7 @@
friend class FunctionNodeHelper;
friend class InferredTypeMetadataHelper;
friend class KernelLoader;
- friend class KernelReader;
+ friend class KernelReaderHelper;
friend class LibraryDependencyHelper;
friend class LibraryHelper;
friend class MetadataHelper;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 5cb1b88..5d91b40 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -111,6 +111,15 @@
return *this;
}
+void Fragment::Prepend(Instruction* start) {
+ if (entry == NULL) {
+ entry = current = start;
+ } else {
+ start->LinkTo(entry);
+ entry = start;
+ }
+}
+
Fragment Fragment::closed() {
ASSERT(entry != NULL);
return Fragment(entry, NULL);
@@ -547,6 +556,10 @@
return name;
}
+const String& TranslationHelper::DartFieldName(NameIndex field) {
+ return DartFieldName(CanonicalNameParent(field), CanonicalNameString(field));
+}
+
const String& TranslationHelper::DartFieldName(NameIndex parent,
StringIndex field) {
String& name = DartString(field);
@@ -1001,17 +1014,9 @@
const Function& function = parsed_function_->function();
- if (function.IsClosureFunction() && !function.IsGeneric()) {
- LocalScope* scope = parsed_function_->node_sequence()->scope();
- LocalVariable* closure = scope->VariableAt(0);
- ASSERT(closure != NULL);
- instructions += LoadLocal(closure);
- instructions += LoadField(Closure::function_type_arguments_offset());
-
- } else if (function.IsGeneric()) {
+ if (function.IsGeneric() || function.HasGenericParent()) {
ASSERT(parsed_function_->function_type_arguments() != NULL);
instructions += LoadLocal(parsed_function_->function_type_arguments());
-
} else {
instructions += NullConstant();
}
@@ -1333,6 +1338,52 @@
return Fragment(new (Z) TailCallInstr(code, arg_desc));
}
+Fragment BaseFlowGraphBuilder::TestTypeArgsLen(Fragment eq_branch,
+ Fragment neq_branch,
+ intptr_t num_type_args) {
+ Fragment test;
+
+ TargetEntryInstr* eq_entry;
+ TargetEntryInstr* neq_entry;
+
+ test += LoadArgDescriptor();
+ test += LoadField(ArgumentsDescriptor::type_args_len_offset());
+ test += IntConstant(num_type_args);
+ test += BranchIfEqual(&eq_entry, &neq_entry);
+
+ eq_branch.Prepend(eq_entry);
+ neq_branch.Prepend(neq_entry);
+
+ JoinEntryInstr* join = BuildJoinEntry();
+ eq_branch += Goto(join);
+ neq_branch += Goto(join);
+
+ return Fragment(test.entry, join);
+}
+
+Fragment BaseFlowGraphBuilder::TestDelayedTypeArgs(LocalVariable* closure,
+ Fragment present,
+ Fragment absent) {
+ Fragment test;
+
+ TargetEntryInstr* absent_entry;
+ TargetEntryInstr* present_entry;
+
+ test += LoadLocal(closure);
+ test += LoadField(Closure::delayed_type_arguments_offset());
+ test += Constant(Object::empty_type_arguments());
+ test += BranchIfEqual(&absent_entry, &present_entry);
+
+ present.Prepend(present_entry);
+ absent.Prepend(absent_entry);
+
+ JoinEntryInstr* join = BuildJoinEntry();
+ absent += Goto(join);
+ present += Goto(join);
+
+ return Fragment(test.entry, join);
+}
+
Fragment FlowGraphBuilder::RethrowException(TokenPosition position,
int catch_try_index) {
Fragment instructions;
@@ -2156,6 +2207,11 @@
fragment +=
StoreInstanceField(TokenPosition::kNoSource, Closure::context_offset());
+ fragment += LoadLocal(closure);
+ fragment += Constant(Object::empty_type_arguments());
+ fragment += StoreInstanceField(TokenPosition::kNoSource,
+ Closure::delayed_type_arguments_offset());
+
// The context is on top of the operand stack. Store `this`. The context
// doesn't need a parent pointer because it doesn't close over anything
// else.
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index eacb8c0..abdf092 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -7,6 +7,8 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
+#include <initializer_list>
+
#include "vm/growable_array.h"
#include "vm/hash_map.h"
@@ -169,6 +171,12 @@
Fragment() : entry(NULL), current(NULL) {}
+ Fragment(std::initializer_list<Fragment> list) : entry(NULL), current(NULL) {
+ for (Fragment i : list) {
+ *this += i;
+ }
+ }
+
explicit Fragment(Instruction* instruction)
: entry(instruction), current(instruction) {}
@@ -178,6 +186,8 @@
bool is_open() { return entry == NULL || current != NULL; }
bool is_closed() { return !is_open(); }
+ void Prepend(Instruction* start);
+
Fragment& operator+=(const Fragment& other);
Fragment& operator<<=(Instruction* next);
@@ -396,6 +406,7 @@
const String& DartGetterName(NameIndex getter);
const String& DartGetterName(NameIndex parent, StringIndex getter);
+ const String& DartFieldName(NameIndex field);
const String& DartFieldName(NameIndex parent, StringIndex field);
const String& DartMethodName(NameIndex method);
@@ -630,6 +641,13 @@
return LoadLocal(parsed_function_->arg_desc_var());
}
+ Fragment TestTypeArgsLen(Fragment eq_branch,
+ Fragment neq_branch,
+ intptr_t num_type_args);
+ Fragment TestDelayedTypeArgs(LocalVariable* closure,
+ Fragment present,
+ Fragment absent);
+
JoinEntryInstr* BuildThrowNoSuchMethod();
protected:
@@ -655,6 +673,7 @@
intptr_t pending_argument_count_;
friend class TryCatchBlock;
+ friend class KernelReaderHelper;
friend class StreamingFlowGraphBuilder;
friend class FlowGraphBuilder;
friend class PrologueBuilder;
@@ -874,6 +893,7 @@
friend class BreakableBlock;
friend class CatchBlock;
friend class ConstantEvaluator;
+ friend class KernelReaderHelper;
friend class StreamingFlowGraphBuilder;
friend class ScopeBuilder;
friend class SwitchBlock;
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 66a82c9..902b5b0 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -58,7 +58,7 @@
if (!compiling_for_osr_) prologue += f;
}
if (expect_type_args) {
- Fragment f = BuildTypeArgumentsHandling(strong);
+ Fragment f = BuildTypeArgumentsHandling(nsm);
if (link) prologue += f;
}
@@ -391,36 +391,49 @@
return populate_context;
}
-Fragment PrologueBuilder::BuildTypeArgumentsHandling(bool strong) {
- Fragment populate_args_desc;
-
+Fragment PrologueBuilder::BuildTypeArgumentsHandling(JoinEntryInstr* nsm) {
LocalVariable* type_args_var = parsed_function_->RawTypeArgumentsVariable();
- TargetEntryInstr *passed, *not_passed;
- populate_args_desc += LoadArgDescriptor();
- populate_args_desc += LoadField(ArgumentsDescriptor::type_args_len_offset());
- populate_args_desc += IntConstant(0);
- populate_args_desc += BranchIfEqual(¬_passed, &passed);
+ Fragment handling;
- JoinEntryInstr* join = BuildJoinEntry();
-
- Fragment store_type_args(passed);
+ Fragment store_type_args;
store_type_args += LoadArgDescriptor();
store_type_args += LoadField(ArgumentsDescriptor::count_offset());
store_type_args += LoadFpRelativeSlot(kWordSize * (1 + kParamEndSlotFromFp));
store_type_args += StoreLocal(TokenPosition::kNoSource, type_args_var);
store_type_args += Drop();
- store_type_args += Goto(join);
- Fragment store_null(not_passed);
+ Fragment store_null;
store_null += NullConstant();
store_null += StoreLocal(TokenPosition::kNoSource, type_args_var);
store_null += Drop();
- store_null += Goto(join);
- populate_args_desc = Fragment(populate_args_desc.entry, join);
+ handling += TestTypeArgsLen(store_null, store_type_args, 0);
- return populate_args_desc;
+ if (parsed_function_->function().IsClosureFunction()) {
+ LocalVariable* closure =
+ parsed_function_->node_sequence()->scope()->VariableAt(0);
+
+ // Currently, delayed type arguments can only be introduced through type
+ // inference in the FE. So if they are present, we can assume they are
+ // correct in number and bound.
+ // clang-format off
+ Fragment use_delayed_type_args = {
+ LoadLocal(closure),
+ LoadField(Closure::delayed_type_arguments_offset()),
+ StoreLocal(TokenPosition::kNoSource, type_args_var),
+ Drop()
+ };
+
+ handling += TestDelayedTypeArgs(
+ closure,
+ /*present=*/TestTypeArgsLen(
+ use_delayed_type_args, Goto(nsm), 0),
+ /*absent=*/Fragment());
+ // clang-format on
+ }
+
+ return handling;
}
void PrologueBuilder::SortOptionalNamedParametersInto(LocalVariable** opt_param,
diff --git a/runtime/vm/compiler/frontend/prologue_builder.h b/runtime/vm/compiler/frontend/prologue_builder.h
index 5e89638..2e1026f 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.h
+++ b/runtime/vm/compiler/frontend/prologue_builder.h
@@ -60,7 +60,7 @@
Fragment BuildClosureContextHandling();
- Fragment BuildTypeArgumentsHandling(bool strong);
+ Fragment BuildTypeArgumentsHandling(JoinEntryInstr* nsm);
LocalVariable* ParameterVariable(intptr_t index) {
return parsed_function_->RawParameterVariable(index);
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 48cc6c3..9fc7a63 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -65,7 +65,7 @@
R3 = 3,
R4 = 4,
R5 = 5, // PP
- R6 = 6, // CTX
+ R6 = 6,
R7 = 7, // iOS FP
R8 = 8,
R9 = 9,
@@ -264,7 +264,6 @@
// Register aliases.
const Register TMP = IP; // Used as scratch register by assembler.
const Register TMP2 = kNoRegister; // There is no second assembler temporary.
-const Register CTX = R6; // Location of current context at method entry.
const Register PP = R5; // Caches object pool pointer in generated code.
const Register SPREG = SP; // Stack pointer register.
const Register FPREG = FP; // Frame pointer register.
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index 594baf4..95b3f87 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -38,7 +38,7 @@
R25 = 25,
R26 = 26, // THR
R27 = 27, // PP
- R28 = 28, // CTX
+ R28 = 28,
R29 = 29, // FP
R30 = 30, // LR
R31 = 31, // ZR, CSP
@@ -107,7 +107,6 @@
// Register aliases.
const Register TMP = R16; // Used as scratch register by assembler.
const Register TMP2 = R17;
-const Register CTX = R28; // Location of current context at method entry.
const Register PP = R27; // Caches object pool pointer in generated code.
const Register CODE_REG = R24;
const Register FPREG = FP; // Frame pointer register.
@@ -151,12 +150,12 @@
const VRegister kAbiLastPreservedFpuReg = V15;
const int kAbiPreservedFpuRegCount = 8;
-const intptr_t kReservedCpuRegisters =
- (1 << SPREG) | // Dart SP
- (1 << FPREG) | (1 << TMP) | (1 << TMP2) | (1 << PP) | (1 << THR) |
- (1 << LR) | (1 << R31) | // C++ SP
- (1 << CTX) | (1 << R18); // iOS platform register.
- // TODO(rmacnak): Only reserve on Mac & iOS.
+const intptr_t kReservedCpuRegisters = (1 << SPREG) | // Dart SP
+ (1 << FPREG) | (1 << TMP) | (1 << TMP2) |
+ (1 << PP) | (1 << THR) | (1 << LR) |
+ (1 << R31) | // C++ SP
+ (1 << R18); // iOS platform register.
+// TODO(rmacnak): Only reserve on Mac & iOS.
// CPU registers available to Dart allocator.
const RegList kDartAvailableCpuRegs =
kAllCpuRegistersList & ~kReservedCpuRegisters;
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index b86780e..b30f42c 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -310,7 +310,7 @@
// this instruction does so, and skips the following instruction. Otherwise,
// the following instruction is not skipped.
//
-// - StoreStaticT`OS D
+// - StoreStaticTOS D
//
// Stores TOS into the static field PP[D].
//
@@ -908,7 +908,7 @@
V(Entry, D, num, ___, ___) \
V(EntryOptimized, A_D, num, num, ___) \
V(Frame, D, num, ___, ___) \
- V(SetFrame, A, num, ___, num) \
+ V(SetFrame, A, num, ___, ___) \
V(AllocateContext, D, num, ___, ___) \
V(AllocateUninitializedContext, A_D, reg, num, ___) \
V(CloneContext, 0, ___, ___, ___) \
@@ -1080,7 +1080,6 @@
const intptr_t CODE_REG = 0;
const intptr_t kExceptionObjectReg = 0;
const intptr_t kStackTraceObjectReg = 0;
-const intptr_t CTX = 0;
enum FpuRegister {
kNoFpuRegister = -1,
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 7b4dd5c..1f4e449 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -56,7 +56,6 @@
// Register aliases.
const Register TMP = kNoRegister; // No scratch register used by assembler.
const Register TMP2 = kNoRegister; // No second assembler scratch register.
-const Register CTX = EDI; // Location of current context at method entry.
const Register CODE_REG = EDI;
const Register PP = kNoRegister; // No object pool pointer.
const Register SPREG = ESP; // Stack pointer register.
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 9f9168f..3032fcf 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -99,7 +99,6 @@
// Register aliases.
const Register TMP = R11; // Used as scratch register by the assembler.
const Register TMP2 = kNoRegister; // No second assembler scratch register.
-const Register CTX = R12; // Location of current context at method entry.
// Caches object pool pointer in generated code.
const Register PP = R15;
const Register SPREG = RSP; // Stack pointer register.
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index eff8af8..43db729 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1511,6 +1511,9 @@
Isolate* I = T->isolate();
CHECK_NULL(script_snapshot_buffer);
CHECK_NULL(script_snapshot_size);
+ if (I->strong()) {
+ return Api::NewError("Script snapshots are not supported in Dart 2");
+ }
// Finalize all classes if needed.
Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
if (::Dart_IsError(state)) {
@@ -5202,6 +5205,9 @@
if (buffer == NULL) {
RETURN_NULL_ERROR(buffer);
}
+ if (I->strong()) {
+ return Api::NewError("Script snapshots are not supported in Dart 2");
+ }
NoHeapGrowthControlScope no_growth_control;
const Snapshot* snapshot = Snapshot::SetupFromBuffer(buffer);
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index fc532c3..a7d2eb9 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1927,14 +1927,14 @@
" var a = createExternalByteData();"
" Expect.equals(length, a.lengthInBytes);"
" for (int i = 0; i < length; i+=2) {"
- " Expect.equals(0x4241, a.getInt16(i, Endianness.LITTLE_ENDIAN));"
+ " Expect.equals(0x4241, a.getInt16(i, Endian.little));"
" }"
" for (int i = 0; i < length; i+=2) {"
" a.setInt8(i, 0x24);"
" a.setInt8(i + 1, 0x28);"
" }"
" for (int i = 0; i < length; i+=2) {"
- " Expect.equals(0x2824, a.getInt16(i, Endianness.LITTLE_ENDIAN));"
+ " Expect.equals(0x2824, a.getInt16(i, Endian.little));"
" }"
" return a;"
"}\n";
@@ -1995,10 +1995,10 @@
"}\n"
"ByteData createExternalByteData() native 'CreateExternalByteData';"
"access(ByteData a) {"
- " Expect.equals(0x04030201, a.getUint32(0, Endianness.LITTLE_ENDIAN));"
- " Expect.equals(0x08070605, a.getUint32(4, Endianness.LITTLE_ENDIAN));"
- " Expect.equals(0x0c0b0a09, a.getUint32(8, Endianness.LITTLE_ENDIAN));"
- " Expect.equals(0x100f0e0d, a.getUint32(12, Endianness.LITTLE_ENDIAN));"
+ " Expect.equals(0x04030201, a.getUint32(0, Endian.little));"
+ " Expect.equals(0x08070605, a.getUint32(4, Endian.little));"
+ " Expect.equals(0x0c0b0a09, a.getUint32(8, Endian.little));"
+ " Expect.equals(0x100f0e0d, a.getUint32(12, Endian.little));"
"}"
"ByteData main() {"
" var length = 16;"
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index de94a29..eb78a50 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -1280,6 +1280,11 @@
static void RecordChanges(const GrowableObjectArray& changed_in_last_reload,
const Class& old_cls,
const Class& new_cls) {
+ // All members of enum classes are synthetic, so nothing to report here.
+ if (new_cls.is_enum_class()) {
+ return;
+ }
+
// Don't report synthetic classes like the superclass of
// `class MA extends S with M {}` or `class MA = S with M'. The relevant
// changes with be reported as changes in M.
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index f65c9e4..20edba6 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -2254,7 +2254,7 @@
intptr_t saved_subclass_count = subclasses.Length();
const char* kScript =
- "class AIterator extends Iterator {\n"
+ "abstract class AIterator extends Iterator {\n"
"}\n"
"main() {\n"
" return 1;\n"
@@ -2275,7 +2275,7 @@
const char* kReloadScript =
"class AIterator {\n"
"}\n"
- "class BIterator extends Iterator {\n"
+ "abstract class BIterator extends Iterator {\n"
"}\n"
"main() {\n"
" return 2;\n"
@@ -2310,7 +2310,7 @@
intptr_t saved_subclass_count = subclasses.Length();
const char* kScript =
- "class AIterator extends Iterator {\n"
+ "abstract class AIterator extends Iterator {\n"
"}\n"
"main() {\n"
" return 1;\n"
@@ -2329,7 +2329,7 @@
EXPECT_STREQ("AIterator", name.ToCString());
const char* kReloadScript =
- "class BIterator extends Iterator {\n"
+ "abstract class BIterator extends Iterator {\n"
"}\n"
"main() {\n"
" return 2;\n"
@@ -2369,7 +2369,7 @@
intptr_t saved_subclass_count = subclasses.Length();
const char* kScript =
- "class AIterator extends Iterator {\n"
+ "abstract class AIterator extends Iterator {\n"
"}\n"
"class Foo {\n"
" final a;\n"
@@ -2394,7 +2394,7 @@
// Attempt to reload with a bogus script.
const char* kReloadScript =
- "class BIterator extends Iterator {\n"
+ "abstract class BIterator extends Iterator {\n"
"}\n"
"class Foo {\n"
" final a kjsdf ksjdf ;\n" // When we refinalize, we get an error.
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
index 8cbc078..5394e53 100644
--- a/runtime/vm/kernel.cc
+++ b/runtime/vm/kernel.cc
@@ -29,6 +29,95 @@
return field_helper.FieldHasFunctionLiteralInitializer(start, end);
}
+uint32_t KernelSourceFingerprintHelper::CalculateClassFingerprint(
+ const Class& klass) {
+ Zone* zone = Thread::Current()->zone();
+
+ // Handle typedefs.
+ if (klass.IsTypedefClass()) {
+ const Function& func = Function::Handle(zone, klass.signature_function());
+ return CalculateFunctionFingerprint(func);
+ }
+
+ String& name = String::Handle(zone, klass.Name());
+ const Array& fields = Array::Handle(zone, klass.fields());
+ const Array& functions = Array::Handle(zone, klass.functions());
+ const Array& interfaces = Array::Handle(zone, klass.interfaces());
+ AbstractType& type = AbstractType::Handle(zone);
+
+ uint32_t hash = 0;
+ hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
+
+ type ^= klass.super_type();
+ if (!type.IsNull()) {
+ name ^= type.Name();
+ hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
+ }
+
+ type ^= klass.mixin();
+ if (!type.IsNull()) {
+ name ^= type.Name();
+ hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
+ }
+
+ Field& field = Field::Handle(zone);
+ // Calculate fingerprint for the class fields.
+ for (intptr_t i = 0; i < fields.Length(); ++i) {
+ field ^= fields.At(i);
+ uint32_t fingerprint = CalculateFieldFingerprint(field);
+ hash = KernelFingerprintHelper::CalculateHash(hash, fingerprint);
+ }
+
+ // Calculate fingerprint for the class functions.
+ Function& func = Function::Handle(zone);
+ for (intptr_t i = 0; i < functions.Length(); ++i) {
+ func ^= functions.At(i);
+ uint32_t fingerprint = CalculateFunctionFingerprint(func);
+ hash = KernelFingerprintHelper::CalculateHash(hash, fingerprint);
+ }
+
+ // Calculate fingerprint for the interfaces.
+ for (intptr_t i = 0; i < interfaces.Length(); ++i) {
+ type ^= interfaces.At(i);
+ name ^= type.Name();
+ hash = KernelFingerprintHelper::CalculateHash(hash, name.Hash());
+ }
+
+ return hash;
+}
+
+uint32_t KernelSourceFingerprintHelper::CalculateFieldFingerprint(
+ const Field& field) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ const Script& script = Script::Handle(zone, field.Script());
+
+ TranslationHelper translation_helper(thread);
+ translation_helper.InitFromScript(script);
+
+ KernelFingerprintHelper helper(zone, &translation_helper, script,
+ TypedData::Handle(zone, field.KernelData()),
+ field.KernelDataProgramOffset());
+ helper.SetOffset(field.kernel_offset());
+ return helper.CalculateFieldFingerprint();
+}
+
+uint32_t KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
+ const Function& func) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ const Script& script = Script::Handle(zone, func.script());
+
+ TranslationHelper translation_helper(thread);
+ translation_helper.InitFromScript(script);
+
+ KernelFingerprintHelper helper(zone, &translation_helper, script,
+ TypedData::Handle(zone, func.KernelData()),
+ func.KernelDataProgramOffset());
+ helper.SetOffset(func.kernel_offset());
+ return helper.CalculateFunctionFingerprint();
+}
+
KernelLineStartsReader::KernelLineStartsReader(
const dart::TypedData& line_starts_data,
dart::Zone* zone)
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index deb900d..8568139 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -123,6 +123,13 @@
DISALLOW_COPY_AND_ASSIGN(Program);
};
+class KernelSourceFingerprintHelper {
+ public:
+ static uint32_t CalculateClassFingerprint(const Class& klass);
+ static uint32_t CalculateFieldFingerprint(const Field& field);
+ static uint32_t CalculateFunctionFingerprint(const Function& func);
+};
+
class KernelLineStartsReader {
public:
KernelLineStartsReader(const dart::TypedData& line_starts_data,
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index bf28e59..a5521fc 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -315,16 +315,16 @@
// the root name as in the canonical name table.
NameIndex ReadCanonicalNameReference() { return NameIndex(ReadUInt() - 1); }
- intptr_t offset() { return offset_; }
+ intptr_t offset() const { return offset_; }
void set_offset(intptr_t offset) { offset_ = offset; }
- intptr_t size() { return size_; }
+ intptr_t size() const { return size_; }
void set_size(intptr_t size) { size_ = size; }
- const TypedData* typed_data() { return typed_data_; }
+ const TypedData* typed_data() const { return typed_data_; }
void set_typed_data(const TypedData* typed_data) { typed_data_ = typed_data; }
- const uint8_t* raw_buffer() { return raw_buffer_; }
+ const uint8_t* raw_buffer() const { return raw_buffer_; }
void set_raw_buffer(const uint8_t* raw_buffer) { raw_buffer_ = raw_buffer; }
void CopyDataToVMHeap(const TypedData& typed_data,
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index a297180..c856133 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -110,9 +110,9 @@
Instance* Object::null_instance_ = NULL;
Function* Object::null_function_ = NULL;
TypeArguments* Object::null_type_arguments_ = NULL;
+TypeArguments* Object::empty_type_arguments_ = NULL;
Array* Object::empty_array_ = NULL;
Array* Object::zero_array_ = NULL;
-Context* Object::empty_context_ = NULL;
ContextScope* Object::empty_context_scope_ = NULL;
ObjectPool* Object::empty_object_pool_ = NULL;
PcDescriptors* Object::empty_descriptors_ = NULL;
@@ -506,9 +506,9 @@
null_instance_ = Instance::ReadOnlyHandle();
null_function_ = Function::ReadOnlyHandle();
null_type_arguments_ = TypeArguments::ReadOnlyHandle();
+ empty_type_arguments_ = TypeArguments::ReadOnlyHandle();
empty_array_ = Array::ReadOnlyHandle();
zero_array_ = Array::ReadOnlyHandle();
- empty_context_ = Context::ReadOnlyHandle();
empty_context_scope_ = ContextScope::ReadOnlyHandle();
empty_object_pool_ = ObjectPool::ReadOnlyHandle();
empty_descriptors_ = PcDescriptors::ReadOnlyHandle();
@@ -538,6 +538,7 @@
*null_instance_ = Instance::null();
*null_function_ = Function::null();
*null_type_arguments_ = TypeArguments::null();
+ *empty_type_arguments_ = TypeArguments::null();
// Initialize the empty and zero array handles to null_ in order to be able to
// check if the empty and zero arrays were allocated (RAW_NULL is not
@@ -775,17 +776,6 @@
zero_array_->SetCanonical();
}
- // Allocate and initialize the empty context object.
- {
- uword address = heap->Allocate(Context::InstanceSize(0), Heap::kOld);
- InitializeObject(address, kContextCid, Context::InstanceSize(0), true);
- Context::initializeHandle(empty_context_, reinterpret_cast<RawContext*>(
- address + kHeapObjectTag));
- empty_context_->StoreNonPointer(&empty_context_->raw_ptr()->num_variables_,
- 0);
- empty_context_->SetCanonical();
- }
-
// Allocate and initialize the canonical empty context scope object.
{
uword address = heap->Allocate(ContextScope::InstanceSize(0), Heap::kOld);
@@ -857,6 +847,21 @@
empty_exception_handlers_->SetCanonical();
}
+ // Allocate and initialize the canonical empty type arguments object.
+ {
+ uword address = heap->Allocate(TypeArguments::InstanceSize(0), Heap::kOld);
+ InitializeObject(address, kTypeArgumentsCid, TypeArguments::InstanceSize(0),
+ true);
+ TypeArguments::initializeHandle(
+ empty_type_arguments_,
+ reinterpret_cast<RawTypeArguments*>(address + kHeapObjectTag));
+ empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->length_,
+ Smi::New(0));
+ empty_type_arguments_->StoreSmi(&empty_type_arguments_->raw_ptr()->hash_,
+ Smi::New(0));
+ empty_type_arguments_->SetCanonical();
+ }
+
// The VM isolate snapshot object table is initialized to an empty array
// as we do not have any VM isolate snapshot at this time.
*vm_isolate_snapshot_object_table_ = Object::empty_array().raw();
@@ -962,8 +967,6 @@
ASSERT(empty_array_->IsArray());
ASSERT(!zero_array_->IsSmi());
ASSERT(zero_array_->IsArray());
- ASSERT(!empty_context_->IsSmi());
- ASSERT(empty_context_->IsContext());
ASSERT(!empty_context_scope_->IsSmi());
ASSERT(empty_context_scope_->IsContextScope());
ASSERT(!empty_descriptors_->IsSmi());
@@ -3715,8 +3718,16 @@
}
int32_t Class::SourceFingerprint() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (kernel_offset() > 0) {
+ return kernel::KernelSourceFingerprintHelper::CalculateClassFingerprint(
+ *this);
+ }
return Script::Handle(script()).SourceFingerprint(token_pos(),
ComputeEndTokenPos());
+#else
+ return 0;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
void Class::set_is_implemented() const {
@@ -4855,6 +4866,28 @@
return result;
}
+RawTypeArguments* TypeArguments::Prepend(Zone* zone,
+ const TypeArguments& other,
+ intptr_t total_length) const {
+ if (IsNull() && other.IsNull()) {
+ return Object::null_type_arguments().raw();
+ }
+ const TypeArguments& result =
+ TypeArguments::Handle(zone, TypeArguments::New(total_length, Heap::kNew));
+ AbstractType& type = AbstractType::Handle(zone);
+ const intptr_t split =
+ other.IsNull() ? total_length - Length() : other.Length();
+ for (intptr_t i = 0; i < split; i++) {
+ type = other.IsNull() ? Type::DynamicType() : other.TypeAt(i);
+ result.SetTypeAt(i, type);
+ }
+ for (intptr_t i = split; i < total_length; i++) {
+ type = IsNull() ? Type::DynamicType() : TypeAt(i - split);
+ result.SetTypeAt(i, type);
+ }
+ return result.Canonicalize();
+}
+
RawString* TypeArguments::SubvectorName(intptr_t from_index,
intptr_t len,
NameVisibility name_visibility) const {
@@ -5805,6 +5838,8 @@
// The parent function of an implicit closure function is not the enclosing
// function we are asking about here.
return false;
+ } else if (IsConvertedClosureFunction()) {
+ return NumParentTypeParameters() > 0;
}
Function& parent = Function::Handle(parent_function());
while (!parent.IsNull()) {
@@ -6212,6 +6247,8 @@
intptr_t Function::NumParentTypeParameters() const {
if (IsImplicitClosureFunction()) {
return 0;
+ } else if (IsConvertedClosureFunction()) {
+ return num_parent_type_parameters();
}
Thread* thread = Thread::Current();
Function& parent = Function::Handle(parent_function());
@@ -6738,21 +6775,10 @@
}
}
- Function& sig = Function::Handle(zone, Function::null());
- if (IsConvertedClosureFunction() && !delete_type_parameters) {
- sig = Function::NewConvertedClosureFunction(
- String::Handle(zone, name()), parent, TokenPosition::kNoSource);
- // TODO(30455): Kernel generic methods undone. Handle type parameters
- // correctly when generic closures are supported. Until then, all type
- // parameters to this target are used for captured type variables, so they
- // aren't relevant to the type of the function.
- sig.set_type_parameters(TypeArguments::Handle(zone, TypeArguments::null()));
- } else {
- sig = Function::NewSignatureFunction(owner, parent,
- TokenPosition::kNoSource, space);
- if (!delete_type_parameters) {
- sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
- }
+ Function& sig = Function::Handle(Function::NewSignatureFunction(
+ owner, parent, TokenPosition::kNoSource, space));
+ if (!delete_type_parameters) {
+ sig.set_type_parameters(TypeArguments::Handle(zone, type_parameters()));
}
AbstractType& type = AbstractType::Handle(zone, result_type());
@@ -7425,7 +7451,8 @@
//
// Function::ConvertedClosureFunction method follows the logic of
// Function::ImplicitClosureFunction method.
-RawFunction* Function::ConvertedClosureFunction() const {
+RawFunction* Function::ConvertedClosureFunction(
+ intptr_t num_parent_type_parameters) const {
// Return the existing converted closure function if any.
if (converted_closure_function() != Function::null()) {
return converted_closure_function();
@@ -7443,8 +7470,28 @@
closure_function.set_context_scope(Object::empty_context_scope());
// Set closure function's type parameters.
- closure_function.set_type_parameters(
- TypeArguments::Handle(zone, type_parameters()));
+ {
+ TypeArguments& total_type_parameters =
+ TypeArguments::Handle(type_parameters());
+
+ intptr_t num_type_parameters =
+ total_type_parameters.Length() - num_parent_type_parameters;
+ if (num_type_parameters == 0) {
+ closure_function.set_type_parameters(Object::null_type_arguments());
+ } else {
+ ASSERT(num_type_parameters > 0);
+ TypeArguments& new_type_parameters =
+ TypeArguments::Handle(TypeArguments::New(num_type_parameters));
+
+ for (intptr_t i = 0; i < num_type_parameters; ++i) {
+ new_type_parameters.SetTypeAt(
+ i, AbstractType::Handle(total_type_parameters.TypeAt(
+ i + num_parent_type_parameters)));
+ }
+ closure_function.set_type_parameters(new_type_parameters);
+ }
+ closure_function.set_num_parent_type_parameters(num_parent_type_parameters);
+ }
// Set closure function's result type to this result type.
closure_function.set_result_type(AbstractType::Handle(zone, result_type()));
@@ -7507,6 +7554,26 @@
}
}
+void Function::set_num_parent_type_parameters(intptr_t num) const {
+ if (IsConvertedClosureFunction()) {
+ const Object& obj = Object::Handle(raw_ptr()->data_);
+ ASSERT(!obj.IsNull());
+ ClosureData::Cast(obj).set_num_parent_type_parameters(num);
+ return;
+ }
+ UNREACHABLE();
+}
+
+intptr_t Function::num_parent_type_parameters() const {
+ if (IsConvertedClosureFunction()) {
+ const Object& obj = Object::Handle(raw_ptr()->data_);
+ ASSERT(!obj.IsNull());
+ return ClosureData::Cast(obj).num_parent_type_parameters();
+ }
+ UNREACHABLE();
+ return 0;
+}
+
void Function::BuildSignatureParameters(
Thread* thread,
Zone* zone,
@@ -7569,7 +7636,7 @@
ASSERT(IsImplicitStaticClosureFunction());
if (implicit_static_closure() == Instance::null()) {
Zone* zone = Thread::Current()->zone();
- const Context& context = Object::empty_context();
+ const Context& context = Context::Handle(zone);
Instance& closure =
Instance::Handle(zone, Closure::New(Object::null_type_arguments(),
Object::null_type_arguments(),
@@ -7645,35 +7712,6 @@
bool Function::HasInstantiatedSignature(Genericity genericity,
intptr_t num_free_fun_type_params,
TrailPtr trail) const {
- // This function works differently for converted closures.
- //
- // Unlike regular closures, it's not possible to know which type parameters
- // are supposed to come from parent functions or classes and which are
- // actually parameters to the closure it represents. For example, consider:
- //
- // class C<T> {
- // getf() => (T x) { return x; }
- // }
- //
- // class D {
- // getf() {
- // dynamic fn<T>(T x) { return x; }
- // return fn;
- // }
- // }
- //
- // The signature of `fn` as a converted closure will in both cases look like
- // `<T>(T) => dynamic`, because the signature of the converted closure
- // function is the same as its top-level target function. However, in the
- // first case the closure's type is instantiated, and in the second case
- // it's not.
- //
- // Since we can never assume a converted closure is instantiated if it has any
- // type parameters, we always return true in these cases.
- if (IsConvertedClosureFunction()) {
- return genericity == kCurrentClass || NumTypeParameters() == 0;
- }
-
if (num_free_fun_type_params == kCurrentAndEnclosingFree) {
num_free_fun_type_params = kAllFree;
} else if (genericity != kCurrentClass) {
@@ -7896,8 +7934,16 @@
// Construct fingerprint from token stream. The token stream contains also
// arguments.
int32_t Function::SourceFingerprint() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (kernel_offset() > 0) {
+ return kernel::KernelSourceFingerprintHelper::CalculateFunctionFingerprint(
+ *this);
+ }
return Script::Handle(script()).SourceFingerprint(token_pos(),
end_token_pos());
+#else
+ return 0;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
void Function::SaveICDataMap(
@@ -8073,6 +8119,14 @@
const_str);
}
+intptr_t ClosureData::num_parent_type_parameters() const {
+ return Smi::Value(raw_ptr()->num_parent_type_parameters_);
+}
+
+void ClosureData::set_num_parent_type_parameters(intptr_t value) const {
+ StorePointer(&raw_ptr()->num_parent_type_parameters_, Smi::New(value));
+}
+
void ClosureData::set_context_scope(const ContextScope& value) const {
StorePointer(&raw_ptr()->context_scope_, value.raw());
}
@@ -8440,8 +8494,16 @@
}
int32_t Field::SourceFingerprint() const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (kernel_offset() > 0) {
+ return kernel::KernelSourceFingerprintHelper::CalculateFieldFingerprint(
+ *this);
+ }
return Script::Handle(Script()).SourceFingerprint(token_pos(),
end_token_pos());
+#else
+ return 0;
+#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
RawString* Field::InitializingExpression() const {
@@ -17603,7 +17665,6 @@
RawAbstractType* Type::CloneUninstantiated(const Class& new_owner,
TrailPtr trail) const {
ASSERT(IsFinalized());
- ASSERT(IsCanonical());
ASSERT(!IsMalformed());
if (IsInstantiated()) {
return raw();
@@ -22714,6 +22775,8 @@
instantiator_type_arguments.raw());
result.StorePointer(&result.raw_ptr()->function_type_arguments_,
function_type_arguments.raw());
+ result.StorePointer(&result.raw_ptr()->delayed_type_arguments_,
+ Object::empty_type_arguments().raw());
result.StorePointer(&result.raw_ptr()->function_, function.raw());
result.StorePointer(&result.raw_ptr()->context_, context.raw());
}
@@ -22728,16 +22791,24 @@
RawFunction* Closure::GetInstantiatedSignature(Zone* zone) const {
Function& sig_fun = Function::Handle(zone, function());
- const TypeArguments& fn_type_args =
+ TypeArguments& fn_type_args =
TypeArguments::Handle(zone, function_type_arguments());
+ const TypeArguments& delayed_type_args =
+ TypeArguments::Handle(zone, delayed_type_arguments());
const TypeArguments& inst_type_args =
TypeArguments::Handle(zone, instantiator_type_arguments());
+
// We detect the case of a partial tearoff type application and substitute the
// type arguments for the type parameters of the function.
- intptr_t num_free_params =
- sig_fun.IsImplicitClosureFunction() && !fn_type_args.IsNull()
- ? kCurrentAndEnclosingFree
- : kAllFree;
+ intptr_t num_free_params;
+ if (delayed_type_args.raw() != Object::empty_type_arguments().raw()) {
+ num_free_params = kCurrentAndEnclosingFree;
+ fn_type_args = delayed_type_args.Prepend(
+ zone, fn_type_args,
+ sig_fun.NumTypeParameters() + sig_fun.NumParentTypeParameters());
+ } else {
+ num_free_params = kAllFree;
+ }
if (num_free_params == kCurrentAndEnclosingFree ||
!sig_fun.HasInstantiatedSignature(kAny)) {
return sig_fun.InstantiateSignatureFrom(inst_type_args, fn_type_args,
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index de0a01a..ea2c4d5 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -370,6 +370,10 @@
ASSERT(null_type_arguments_ != NULL);
return *null_type_arguments_;
}
+ static const TypeArguments& empty_type_arguments() {
+ ASSERT(empty_type_arguments_ != NULL);
+ return *empty_type_arguments_;
+ }
static const Array& empty_array() {
ASSERT(empty_array_ != NULL);
@@ -380,11 +384,6 @@
return *zero_array_;
}
- static const Context& empty_context() {
- ASSERT(empty_context_ != NULL);
- return *empty_context_;
- }
-
static const ContextScope& empty_context_scope() {
ASSERT(empty_context_scope_ != NULL);
return *empty_context_scope_;
@@ -817,9 +816,9 @@
static Instance* null_instance_;
static Function* null_function_;
static TypeArguments* null_type_arguments_;
+ static TypeArguments* empty_type_arguments_;
static Array* empty_array_;
static Array* zero_array_;
- static Context* empty_context_;
static ContextScope* empty_context_scope_;
static ObjectPool* empty_object_pool_;
static PcDescriptors* empty_descriptors_;
@@ -2163,6 +2162,11 @@
RawArray* parameter_names() const { return raw_ptr()->parameter_names_; }
void set_parameter_names(const Array& value) const;
+ // For converted closure functions: indicate how many type parameters on the
+ // target are actually captured.
+ void set_num_parent_type_parameters(intptr_t num) const;
+ intptr_t num_parent_type_parameters() const;
+
// The type parameters (and their bounds) are specified as an array of
// TypeParameter.
RawTypeArguments* type_parameters() const {
@@ -2300,7 +2304,8 @@
// If none exists yet, create one and remember it. See the comment on
// ConvertedClosureFunction definition in runtime/vm/object.cc for elaborate
// explanation.
- RawFunction* ConvertedClosureFunction() const;
+ RawFunction* ConvertedClosureFunction(
+ intptr_t num_parent_type_parameters) const;
void DropUncompiledConvertedClosureFunction() const;
// Return the closure implicitly created for this function.
@@ -2983,6 +2988,9 @@
RawInstance* implicit_static_closure() const { return raw_ptr()->closure_; }
void set_implicit_static_closure(const Instance& closure) const;
+ intptr_t num_parent_type_parameters() const;
+ void set_num_parent_type_parameters(intptr_t value) const;
+
static RawClosureData* New();
FINAL_HEAP_OBJECT_IMPLEMENTATION(ClosureData, Object);
@@ -5741,6 +5749,10 @@
return IsDynamicTypes(true, 0, len);
}
+ RawTypeArguments* Prepend(Zone* zone,
+ const TypeArguments& other,
+ intptr_t total_length) const;
+
// Check if the subvector of length 'len' starting at 'from_index' of this
// type argument vector consists solely of DynamicType, ObjectType, or
// VoidType.
@@ -8744,6 +8756,13 @@
return OFFSET_OF(RawClosure, function_type_arguments_);
}
+ RawTypeArguments* delayed_type_arguments() const {
+ return raw_ptr()->delayed_type_arguments_;
+ }
+ static intptr_t delayed_type_arguments_offset() {
+ return OFFSET_OF(RawClosure, delayed_type_arguments_);
+ }
+
RawFunction* function() const { return raw_ptr()->function_; }
static intptr_t function_offset() { return OFFSET_OF(RawClosure, function_); }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index de84a19..5d52cbd 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -983,7 +983,8 @@
RawFunction* parent_function_; // Enclosing function of this local function.
RawType* signature_type_;
RawInstance* closure_; // Closure object for static implicit closures.
- VISIT_TO(RawObject*, closure_);
+ RawSmi* num_parent_type_parameters_; // For converted closures only
+ VISIT_TO(RawObject*, num_parent_type_parameters_);
friend class Function;
};
@@ -1894,17 +1895,21 @@
VISIT_FROM(RawCompressed, instantiator_type_arguments_)
RawTypeArguments* instantiator_type_arguments_;
RawTypeArguments* function_type_arguments_;
+ RawTypeArguments* delayed_type_arguments_;
RawFunction* function_;
RawContext* context_;
RawSmi* hash_;
+
VISIT_TO(RawCompressed, hash_)
- // Note that instantiator_type_arguments_ and function_type_arguments_ are
- // used to instantiate the signature of function_ when this closure is
- // involved in a type test. In other words, these fields define the function
- // type of this closure instance, but they are not used when invoking it.
- // Whereas the source frontend will save a copy of the function's type
- // arguments in the closure's context and only use the
+ // Note that instantiator_type_arguments_, function_type_arguments_ and
+ // delayed_type_arguments_ are used to instantiate the signature of function_
+ // when this closure is involved in a type test. In other words, these fields
+ // define the function type of this closure instance.
+ //
+ // function_type_arguments_ and delayed_type_arguments_ may also be used when
+ // invoking the closure. Whereas the source frontend will save a copy of the
+ // function's type arguments in the closure's context and only use the
// function_type_arguments_ field for type tests, the kernel frontend will use
// the function_type_arguments_ vector here directly.
//
@@ -1913,6 +1918,12 @@
// if the generic closure function_ has a generic parent function, the
// passed-in function type arguments get concatenated to the function type
// arguments of the parent that are found in the context_.
+ //
+ // delayed_type_arguments_ is used to support the parital instantiation
+ // feature. When this field is set to any value other than
+ // Object::empty_type_arguments(), the types in this vector will be passed as
+ // type arguments to the closure when invoked. In this case there may not be
+ // any type arguments passed directly (or NSM will be invoked instead).
};
class RawNumber : public RawInstance {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index dd41cf1..bac281c 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -1478,9 +1478,7 @@
int32_t num_vars = reader->Read<int32_t>();
Context& context = Context::ZoneHandle(reader->zone());
reader->AddBackRef(object_id, &context, kIsDeserialized);
- if (num_vars == 0) {
- context ^= Object::empty_context().raw();
- } else {
+ if (num_vars != 0) {
context ^= Context::New(num_vars);
// Set all the object fields.
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 4dbb6b6..e07e393 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -643,7 +643,8 @@
(variable->name().raw() == Symbols::StackTraceVar().raw()) ||
(variable->name().raw() == Symbols::ExceptionVar().raw()) ||
(variable->name().raw() == Symbols::SavedTryContextVar().raw()) ||
- (variable->name().raw() == Symbols::ArgDescVar().raw())) {
+ (variable->name().raw() == Symbols::ArgDescVar().raw()) ||
+ (variable->name().raw() == Symbols::FunctionTypeArgumentsVar().raw())) {
// Don't capture those variables because the VM expects them to be on
// the stack.
continue;
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index ca885ea..1efbaa8 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -133,7 +133,7 @@
"sp", "ip", "fp", "pp", "ctx"};
static const Register kRegisters[] = {R0, R1, R2, R3, R4, R5, R6, R7,
R8, R9, R10, R11, R12, R13, R14, R15,
- PC, LR, SP, IP, FP, PP, CTX};
+ PC, LR, SP, IP, FP, PP};
ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
if (strcmp(kNames[i], name) == 0) {
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index c115b7c..3db2d65 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -133,14 +133,14 @@
"r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
"r24", "r25", "r26", "r27", "r28", "r29", "r30",
- "ip0", "ip1", "pp", "ctx", "fp", "lr", "sp", "zr",
+ "ip0", "ip1", "pp", "fp", "lr", "sp", "zr",
};
static const Register kRegisters[] = {
R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10,
R11, R12, R13, R14, R15, R16, R17, R18, R19, R20, R21,
R22, R23, R24, R25, R26, R27, R28, R29, R30,
- IP0, IP1, PP, CTX, FP, LR, R31, ZR,
+ IP0, IP1, PP, FP, LR, R31, ZR,
};
ASSERT(ARRAY_SIZE(kNames) == ARRAY_SIZE(kRegisters));
for (unsigned i = 0; i < ARRAY_SIZE(kNames); i++) {
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 447fbf4..d3667ce 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -751,13 +751,14 @@
READ_VM_SINGLETON_OBJ(kZeroArrayObject, Object::zero_array().raw());
READ_VM_SINGLETON_OBJ(kDynamicType, Object::dynamic_type().raw());
READ_VM_SINGLETON_OBJ(kVoidType, Object::void_type().raw());
+ READ_VM_SINGLETON_OBJ(kEmptyTypeArguments,
+ Object::empty_type_arguments().raw());
READ_VM_SINGLETON_OBJ(kTrueValue, Bool::True().raw());
READ_VM_SINGLETON_OBJ(kFalseValue, Bool::False().raw());
READ_VM_SINGLETON_OBJ(kExtractorParameterTypes,
Object::extractor_parameter_types().raw());
READ_VM_SINGLETON_OBJ(kExtractorParameterNames,
Object::extractor_parameter_names().raw());
- READ_VM_SINGLETON_OBJ(kEmptyContextObject, Object::empty_context().raw());
READ_VM_SINGLETON_OBJ(kEmptyContextScopeObject,
Object::empty_context_scope().raw());
READ_VM_SINGLETON_OBJ(kEmptyObjectPool, Object::empty_object_pool().raw());
@@ -1018,13 +1019,14 @@
WRITE_VM_SINGLETON_OBJ(Object::zero_array().raw(), kZeroArrayObject);
WRITE_VM_SINGLETON_OBJ(Object::dynamic_type().raw(), kDynamicType);
WRITE_VM_SINGLETON_OBJ(Object::void_type().raw(), kVoidType);
+ WRITE_VM_SINGLETON_OBJ(Object::empty_type_arguments().raw(),
+ kEmptyTypeArguments);
WRITE_VM_SINGLETON_OBJ(Bool::True().raw(), kTrueValue);
WRITE_VM_SINGLETON_OBJ(Bool::False().raw(), kFalseValue);
WRITE_VM_SINGLETON_OBJ(Object::extractor_parameter_types().raw(),
kExtractorParameterTypes);
WRITE_VM_SINGLETON_OBJ(Object::extractor_parameter_names().raw(),
kExtractorParameterNames);
- WRITE_VM_SINGLETON_OBJ(Object::empty_context().raw(), kEmptyContextObject);
WRITE_VM_SINGLETON_OBJ(Object::empty_context_scope().raw(),
kEmptyContextScopeObject);
WRITE_VM_SINGLETON_OBJ(Object::empty_object_pool().raw(), kEmptyObjectPool);
diff --git a/runtime/vm/snapshot_ids.h b/runtime/vm/snapshot_ids.h
index 3f2464a..d767648 100644
--- a/runtime/vm/snapshot_ids.h
+++ b/runtime/vm/snapshot_ids.h
@@ -42,10 +42,10 @@
kBoolType,
kStringType,
kArrayType,
+ kEmptyTypeArguments,
kExtractorParameterTypes,
kExtractorParameterNames,
- kEmptyContextObject,
kEmptyContextScopeObject,
kImplicitClosureScopeObject,
kEmptyObjectPool,
@@ -53,9 +53,9 @@
kEmptyVarDescriptors,
kEmptyExceptionHandlers,
kCachedArgumentsDescriptor0,
- kCachedArgumentsDescriptorN = (kCachedArgumentsDescriptor0 +
- ArgumentsDescriptor::kCachedDescriptorCount -
- 1),
+ kCachedArgumentsDescriptorN =
+ (kCachedArgumentsDescriptor0 +
+ ArgumentsDescriptor::kCachedDescriptorCount - 1),
kCachedICDataArray0,
kCachedICDataArrayN =
(kCachedICDataArray0 + ICData::kCachedICDataArrayCount - 1),
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index c22d567..4d58c04 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -429,24 +429,24 @@
# This is the main target for copying scripts in _platform_sdk_scripts to bin/
group("copy_platform_sdk_scripts") {
visibility = [ ":create_platform_sdk" ]
- deps = []
+ public_deps = []
foreach(sdk_script, _platform_sdk_scripts) {
- deps += [ ":copy_${sdk_script}_script" ]
+ public_deps += [ ":copy_${sdk_script}_script" ]
}
foreach(script, _scripts) {
- deps += [ ":copy_${script}_script" ]
+ public_deps += [ ":copy_${script}_script" ]
}
}
# This is the main target for copying scripts in _full_sdk_scripts to bin/
group("copy_full_sdk_scripts") {
visibility = [ ":create_full_sdk" ]
- deps = []
+ public_deps = []
foreach(sdk_script, _full_sdk_scripts) {
- deps += [ ":copy_${sdk_script}_script" ]
+ public_deps += [ ":copy_${sdk_script}_script" ]
}
foreach(script, _scripts) {
- deps += [ ":copy_${script}_script" ]
+ public_deps += [ ":copy_${script}_script" ]
}
}
@@ -473,9 +473,9 @@
# bin/snapshots
group("copy_platform_sdk_snapshots") {
visibility = [ ":create_platform_sdk" ]
- deps = []
+ public_deps = []
foreach(snapshot, _platform_sdk_snapshots) {
- deps += [ ":copy_${snapshot[0]}_snapshot" ]
+ public_deps += [ ":copy_${snapshot[0]}_snapshot" ]
}
}
@@ -483,18 +483,18 @@
# bin/snapshots
group("copy_full_sdk_snapshots") {
visibility = [ ":create_full_sdk" ]
- deps = []
+ public_deps = []
foreach(snapshot, _full_sdk_snapshots) {
- deps += [ ":copy_${snapshot[0]}_snapshot" ]
+ public_deps += [ ":copy_${snapshot[0]}_snapshot" ]
}
}
# This is the main rule for copying analyzer sources to lib/
group("copy_analyzer_sources") {
visibility = [ ":create_common_sdk" ]
- deps = []
+ public_deps = []
foreach(analyzer_source_dir, _analyzer_source_dirs) {
- deps += [ ":copy_${analyzer_source_dir}_source_dir" ]
+ public_deps += [ ":copy_${analyzer_source_dir}_source_dir" ]
}
}
@@ -505,7 +505,7 @@
# This is the main rule for copying the files that dartdoc needs.
group("copy_dartdoc_files") {
visibility = [ ":create_common_sdk" ]
- deps = [
+ public_deps = [
":copy_dartdoc_resources",
":copy_dartdoc_templates",
]
@@ -732,7 +732,7 @@
":copy_dev_compiler_sdk",
":copy_dev_compiler_tools",
]
- deps = [
+ public_deps = [
":copy_dev_compiler_js_amd",
":copy_dev_compiler_js_amd_kernel",
":copy_dev_compiler_js_common",
@@ -765,7 +765,7 @@
# This is the main rule for copying ddc's dependencies to lib/
group("copy_dev_compiler_sdk") {
visibility = [ ":create_full_sdk" ]
- deps = [
+ public_deps = [
":copy_dev_compiler_js",
":copy_dev_compiler_summary",
":copy_dev_compiler_tools",
@@ -819,9 +819,9 @@
":create_platform_sdk",
":copy_libraries",
]
- deps = []
+ public_deps = []
foreach(library, _platform_sdk_libraries) {
- deps += [ ":copy_${library}_library" ]
+ public_deps += [ ":copy_${library}_library" ]
}
}
@@ -831,19 +831,19 @@
":create_full_sdk",
":copy_libraries",
]
- deps = []
+ public_deps = []
foreach(library, _full_sdk_libraries) {
- deps += [ ":copy_${library}_library" ]
+ public_deps += [ ":copy_${library}_library" ]
}
}
group("copy_libraries") {
if (dart_platform_sdk) {
- deps = [
+ public_deps = [
":copy_platform_sdk_libraries",
]
} else {
- deps = [
+ public_deps = [
":copy_full_sdk_libraries",
]
}
@@ -947,7 +947,7 @@
# Parts common to both platform and full SDKs.
group("create_common_sdk") {
visibility = [ ":create_sdk" ]
- deps = [
+ public_deps = [
":copy_analysis_summaries",
":copy_analyzer_sources",
":copy_api_readme",
@@ -966,14 +966,14 @@
":write_version_file",
]
if (is_win) {
- deps += [ ":copy_7zip" ]
+ public_deps += [ ":copy_7zip" ]
}
}
# Parts specific to the platform SDK.
group("create_platform_sdk") {
visibility = [ ":create_sdk" ]
- deps = [
+ public_deps = [
":copy_platform_sdk_libraries",
":copy_platform_sdk_scripts",
":copy_platform_sdk_snapshots",
@@ -984,7 +984,7 @@
group("create_full_sdk") {
visibility = [ ":create_sdk" ]
- deps = [
+ public_deps = [
":copy_dart2js_dill_files",
":copy_dev_compiler_sdk",
":copy_full_sdk_libraries",
@@ -995,12 +995,12 @@
# The main target to depend on from ../BUILD.gn
group("create_sdk") {
- deps = [
+ public_deps = [
":create_common_sdk",
]
if (dart_platform_sdk) {
- deps += [ ":create_platform_sdk" ]
+ public_deps += [ ":create_platform_sdk" ]
} else {
- deps += [ ":create_full_sdk" ]
+ public_deps += [ ":create_full_sdk" ]
}
}
diff --git a/sdk/lib/_internal/js_runtime/lib/async_patch.dart b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
index bec28e9..5f04f0b 100644
--- a/sdk/lib/_internal/js_runtime/lib/async_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/async_patch.dart
@@ -17,7 +17,7 @@
import 'dart:_isolate_helper'
show IsolateNatives, TimerImpl, leaveJsAsync, enterJsAsync, isWorker;
-import 'dart:_foreign_helper' show JS;
+import 'dart:_foreign_helper' show JS, JS_GET_FLAG;
import 'dart:_async_await_error_codes' as async_error_codes;
@@ -53,8 +53,6 @@
f();
}
- ;
-
var observer = JS('', 'new self.MutationObserver(#)',
convertDartClosureToJS(internalCallback, 1));
JS('', '#.observe(#, { childList: true })', observer, div);
@@ -403,8 +401,8 @@
///
/// If yielding while the subscription is paused it will become suspended. And
/// only resume after the subscription is resumed or canceled.
-class _AsyncStarStreamController {
- StreamController controller;
+class _AsyncStarStreamController<T> {
+ StreamController<T> controller;
Stream get stream => controller.stream;
/// True when the async* function has yielded while being paused.
@@ -424,7 +422,7 @@
add(event) => controller.add(event);
- addStream(Stream stream) {
+ addStream(Stream<T> stream) {
return controller.addStream(stream, cancelOnError: false);
}
@@ -439,7 +437,7 @@
});
}
- controller = new StreamController(onListen: () {
+ controller = new StreamController<T>(onListen: () {
_resumeBody();
}, onResume: () {
// Only schedule again if the async* function actually is suspended.
@@ -466,9 +464,9 @@
}
}
-_makeAsyncStarController(body) {
- return new _AsyncStarStreamController(body);
-}
+//_makeAsyncStarController(body) {
+// return new _AsyncStarStreamController(body);
+//}
class _IterationMarker {
static const YIELD_SINGLE = 0;
@@ -500,7 +498,7 @@
toString() => "IterationMarker($state, $value)";
}
-class _SyncStarIterator implements Iterator {
+class _SyncStarIterator<T> implements Iterator<T> {
// _SyncStarIterator handles stepping a sync* generator body state machine.
//
// It also handles the stepping over 'nested' iterators to flatten yield*
@@ -515,9 +513,11 @@
dynamic _body;
// The current value, unless iterating a non-sync* nested iterator.
- dynamic _current = null;
+ T _current = null;
// This is the nested iterator when iterating a yield* of a non-sync iterator.
+ // TODO(32956): In strong-mode, yield* takes an Iterable<T> (possibly checked
+ // with an implicit downcast), so change type to Iterator<T>.
Iterator _nestedIterator = null;
// Stack of suspended state machines when iterating a yield* of a sync*
@@ -526,7 +526,10 @@
_SyncStarIterator(this._body);
- get current => _nestedIterator == null ? _current : _nestedIterator.current;
+ T get current {
+ if (_nestedIterator == null) return _current;
+ return _nestedIterator.current;
+ }
_runBody() {
// TODO(sra): Find a way to hard-wire SUCCESS and ERROR codes.
@@ -594,11 +597,20 @@
continue;
} else {
_nestedIterator = inner;
+ // TODO(32956): Change to the following when strong-mode is the only
+ // option:
+ //
+ // _nestedIterator = JS<Iterator<T>>('','#', inner);
continue;
}
}
} else {
- _current = value;
+ // TODO(32956): Remove this test.
+ if (JS_GET_FLAG('STRONG_MODE')) {
+ _current = JS<T>('', '#', value);
+ } else {
+ _current = value;
+ }
return true;
}
}
@@ -609,7 +621,7 @@
/// An Iterable corresponding to a sync* method.
///
/// Each invocation of a sync* method will return a new instance of this class.
-class _SyncStarIterable extends IterableBase {
+class _SyncStarIterable<T> extends IterableBase<T> {
// This is a function that will return a helper function that does the
// iteration of the sync*.
//
@@ -618,7 +630,8 @@
_SyncStarIterable(this._outerHelper);
- Iterator get iterator => new _SyncStarIterator(JS('', '#()', _outerHelper));
+ Iterator<T> get iterator =>
+ new _SyncStarIterator<T>(JS('', '#()', _outerHelper));
}
@patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index 5a18016..427a1b0 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -1030,11 +1030,9 @@
var field = '${JS_GET_NAME(JsGetName.OPERATOR_AS_PREFIX)}${typeOfTString}';
substitution = getField(typeOfSPrototype, field);
}
- // The class of [s] is a subclass of the class of [t]. If [s] has no type
- // arguments and no substitution, it is used as raw type. If [t] has no
- // type arguments, it used as a raw type. In both cases, [s] is a subtype
- // of [t].
- if ((!isJsArray(s) && substitution == null) || !isJsArray(t)) {
+ // The class of [s] is a subclass of the class of [t]. If [t] has no
+ // type arguments, it used as a raw type and [s] is a subtype of [t].
+ if (!isJsArray(t)) {
return true;
}
// Recursively check the type arguments.
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 8de4156..bcd1f22 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -148,12 +148,10 @@
*/
abstract class Future<T> {
/// A `Future<Null>` completed with `null`.
- static final _Future<Null> _nullFuture =
- new _Future<Null>.zoneValue(null, Zone.root);
+ static final _Future<Null> _nullFuture = new _Future<Null>.value(null);
/// A `Future<bool>` completed with `false`.
- static final _Future<bool> _falseFuture =
- new _Future<bool>.zoneValue(false, Zone.root);
+ static final _Future<bool> _falseFuture = new _Future<bool>.value(false);
/**
* Creates a future containing the result of calling [computation]
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 2b56f9d..6eeaa08 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -184,7 +184,7 @@
* Until the future is completed, the field may hold the zone that
* listener callbacks used to create this future should be run in.
*/
- final Zone _zone;
+ final Zone _zone = Zone.current;
/**
* Either the result, a list of listeners or another future.
@@ -204,24 +204,20 @@
var _resultOrListeners;
// This constructor is used by async/await.
- _Future() : _zone = Zone.current;
+ _Future();
- _Future.immediate(FutureOr<T> result) : _zone = Zone.current {
+ _Future.immediate(FutureOr<T> result) {
_asyncComplete(result);
}
- /** Creates a future with the value and the specified zone. */
- _Future.zoneValue(T value, this._zone) {
- _setValue(value);
- }
-
- _Future.immediateError(var error, [StackTrace stackTrace])
- : _zone = Zone.current {
+ _Future.immediateError(var error, [StackTrace stackTrace]) {
_asyncCompleteError(error, stackTrace);
}
/** Creates a future that is already completed with the value. */
- _Future.value(T value) : this.zoneValue(value, Zone.current);
+ _Future.value(T value) {
+ _setValue(value);
+ }
bool get _mayComplete => _state == _stateIncomplete;
bool get _isPendingComplete => _state == _statePendingComplete;
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 971f9a5..b2b328e 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -6925,8 +6925,12 @@
Language/Statements/Assert/execution_t03: RuntimeError # Please triage this failure
Language/Statements/Assert/execution_t11: RuntimeError # Please triage this failure
Language/Statements/Return/runtime_type_t04: RuntimeError # Issue 26584
+Language/Statements/Return/type_t03: RuntimeError # Would pass if FutureOr checked
+Language/Statements/Return/type_t04: RuntimeError # Would pass if FutureOr checked
Language/Statements/Switch/execution_t01: Fail # Missing type check in switch expression
Language/Statements/Switch/type_t01: RuntimeError # Issue 16089
+Language/Statements/Yield_and_Yield_Each/Yield/static_type_t01: RuntimeError
+Language/Statements/Yield_and_Yield_Each/Yield/static_type_t02: RuntimeError
Language/Types/Dynamic_Type_System/malbounded_type_error_t01: RuntimeError # Issue 21088
Language/Types/Parameterized_Types/malbounded_t06: RuntimeError # Issue 21088
Language/Types/Static_Types/malformed_type_t01: RuntimeError # Issue 21089
@@ -7155,8 +7159,6 @@
Language/Expressions/Function_Invocation/Unqualified_Invocation/instance_context_invocation_t04: Crash
Language/Expressions/Method_Invocation/Super_Invocation/accessible_instance_member_t02: Crash
Language/Expressions/Method_Invocation/Super_Invocation/evaluation_t05: Crash
-Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t03: Crash
-Language/Expressions/Method_Invocation/Super_Invocation/getter_lookup_failed_t04: Crash
Language/Expressions/Method_Invocation/Super_Invocation/invocation_t02: Crash
Language/Expressions/This/placement_t04: Crash
Language/Functions/setter_modifier_t01: Crash
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 582da56..5d636c5 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -110,6 +110,16 @@
Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError
[ $fasta && $strong ]
+Language/Classes/Abstract_Instance_Members/inherited_t01: CompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t02: CompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t03: CompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t04: CompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t05: CompileTimeError
+Language/Classes/Abstract_Instance_Members/inherited_t06: CompileTimeError
+Language/Classes/Abstract_Instance_Members/invocation_t01: CompileTimeError
+Language/Classes/Abstract_Instance_Members/invocation_t02: CompileTimeError
+Language/Classes/Abstract_Instance_Members/no_implementation_t01: CompileTimeError
+Language/Classes/Abstract_Instance_Members/override_default_value_t06: CompileTimeError
Language/Classes/Abstract_Instance_Members/override_less_positional_parameters_t01: CompileTimeError
Language/Classes/Abstract_Instance_Members/override_less_positional_parameters_t02: CompileTimeError
Language/Classes/Abstract_Instance_Members/override_more_required_parameters_t01: CompileTimeError
@@ -185,6 +195,8 @@
Language/Classes/Instance_Methods/override_subtype_t06: CompileTimeError
Language/Classes/Instance_Variables/constant_t01: MissingCompileTimeError
Language/Classes/Instance_Variables/definition_t03: CompileTimeError
+Language/Classes/Setters/name_t01: CompileTimeError
+Language/Classes/Setters/name_t05: CompileTimeError
Language/Classes/Setters/override_t01: CompileTimeError
Language/Classes/Setters/override_t03: CompileTimeError
Language/Classes/Setters/same_name_getter_different_type_t02: CompileTimeError
@@ -194,15 +206,23 @@
Language/Classes/Static_Methods/type_object_t01: CompileTimeError
Language/Classes/Static_Methods/type_object_t02: CompileTimeError
Language/Classes/Static_Variables/inheritance_t01: CompileTimeError
+Language/Classes/Superclasses/Inheritance_and_Overriding/abstract_method_t01/01: CompileTimeError
Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t03: CompileTimeError
Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t05: CompileTimeError
Language/Classes/Superclasses/Inheritance_and_Overriding/inheritance_t06: CompileTimeError
Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError
Language/Classes/Superinterfaces/implicit_interface_t01: CompileTimeError
Language/Classes/Superinterfaces/implicit_interface_t02: CompileTimeError
+Language/Classes/Superinterfaces/no_member_t01: CompileTimeError
Language/Classes/Superinterfaces/no_member_t02: CompileTimeError
+Language/Classes/Superinterfaces/no_member_t05: CompileTimeError
Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError
Language/Classes/definition_t24: MissingCompileTimeError
+Language/Classes/method_definition_t03: CompileTimeError
+Language/Classes/method_definition_t04: CompileTimeError
+Language/Classes/method_definition_t05: CompileTimeError
+Language/Classes/same_name_instance_and_static_members_t02: Pass
+Language/Classes/same_name_instance_and_static_members_t04: Pass
Language/Classes/same_name_type_variable_t04: MissingCompileTimeError
Language/Classes/same_name_type_variable_t07: MissingCompileTimeError
Language/Enums/declaration_equivalent_t03: CompileTimeError
@@ -498,6 +518,8 @@
Language/Expressions/Identifier_Reference/undeclared_identifier_t08: CompileTimeError
Language/Expressions/If_null_Expressions/static_type_t01: CompileTimeError
Language/Expressions/If_null_Expressions/static_type_t02: CompileTimeError
+Language/Expressions/Instance_Creation/Const/abstract_class_t02: CompileTimeError
+Language/Expressions/Instance_Creation/Const/abstract_class_t04: CompileTimeError
Language/Expressions/Instance_Creation/New/abstract_class_t01/01: CompileTimeError
Language/Expressions/Instance_Creation/New/abstract_class_t02/01: CompileTimeError
Language/Expressions/Instance_Creation/New/argument_static_type_t01: CompileTimeError
@@ -573,6 +595,7 @@
Language/Expressions/Lookup/Getter_and_Setter_Lookup/definition_t03: CompileTimeError
Language/Expressions/Lookup/Getter_and_Setter_Lookup/definition_t09: CompileTimeError
Language/Expressions/Lookup/Getter_and_Setter_Lookup/definition_t10: CompileTimeError
+Language/Expressions/Lookup/Method_Lookup/method_lookup_t03: CompileTimeError
Language/Expressions/Lookup/Method_Lookup/superclass_t07: CompileTimeError
Language/Expressions/Lookup/Method_Lookup/superclass_t08: CompileTimeError
Language/Expressions/Maps/key_value_equals_operator_t01: MissingCompileTimeError
@@ -929,9 +952,16 @@
Language/Libraries_and_Scripts/private_access_t01: CompileTimeError
Language/Libraries_and_Scripts/private_access_t03: CompileTimeError
Language/Libraries_and_Scripts/private_access_t04: CompileTimeError
+Language/Mixins/Mixin_Application/abstract_t05: CompileTimeError
+Language/Mixins/Mixin_Application/abstract_t06: CompileTimeError
Language/Mixins/Mixin_Application/abstract_t07: CompileTimeError
Language/Mixins/Mixin_Application/abstract_t08: CompileTimeError
Language/Mixins/Mixin_Application/deferred_t01: MissingCompileTimeError
+Language/Mixins/Mixin_Application/interfaces_t05: CompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t01: CompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t02: CompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t06: CompileTimeError
+Language/Mixins/Mixin_Application/superinterfaces_t08: CompileTimeError
Language/Mixins/Mixin_Application/syntax_t20: CompileTimeError
Language/Mixins/declaring_constructor_t05: MissingCompileTimeError
Language/Mixins/declaring_constructor_t06: MissingCompileTimeError
@@ -943,6 +973,7 @@
Language/Overview/Privacy/private_and_public_t09: CompileTimeError
Language/Overview/Privacy/private_and_public_t10: CompileTimeError
Language/Overview/Privacy/private_and_public_t11: CompileTimeError
+Language/Overview/Privacy/private_and_public_t18: CompileTimeError
Language/Overview/Privacy/private_and_public_t19: CompileTimeError
Language/Overview/Privacy/private_and_public_t20: CompileTimeError
Language/Overview/Scoping/hiding_declaration_t05: CompileTimeError
@@ -989,6 +1020,7 @@
Language/Statements/For/Asynchronous_For_in/execution_t03: CompileTimeError
Language/Statements/For/For_Loop/execution_t07: CompileTimeError
Language/Statements/For/For_Loop/execution_t08: CompileTimeError
+Language/Statements/For/For_in/execution_t05: CompileTimeError
Language/Statements/For/syntax_t07: CompileTimeError
Language/Statements/If/condition_evaluation_t01: CompileTimeError
Language/Statements/If/condition_evaluation_t02: CompileTimeError
@@ -1169,7 +1201,9 @@
LibTest/collection/DoubleLinkedQueue/takeWhile_A02_t01: CompileTimeError
LibTest/collection/HashMap/HashMap_class_A01_t01: CompileTimeError
LibTest/collection/HashSet/HashSet_class_A01_t01: CompileTimeError
+LibTest/collection/IterableBase/IterableBase_class_A01_t01: CompileTimeError
LibTest/collection/IterableBase/IterableBase_class_A01_t02: CompileTimeError
+LibTest/collection/IterableMixin/IterableMixin_class_A01_t01: CompileTimeError
LibTest/collection/IterableMixin/IterableMixin_class_A02_t01: CompileTimeError
LibTest/collection/LinkedHashMap/LinkedHashMap_A03_t01: CompileTimeError
LibTest/collection/LinkedHashMap/LinkedHashMap_A04_t01: CompileTimeError
diff --git a/tests/compiler/dart2js/async_await/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await/async_await_js_transform_test.dart
index 31dda4f..adefec8 100644
--- a/tests/compiler/dart2js/async_await/async_await_js_transform_test.dart
+++ b/tests/compiler/dart2js/async_await/async_await_js_transform_test.dart
@@ -31,6 +31,7 @@
asyncReturn: new VariableUse("returnHelper"),
asyncRethrow: new VariableUse("rethrowHelper"),
completerFactory: new VariableUse("NewCompleter"),
+ completerFactoryTypeArgument: new VariableUse("CompleterType"),
wrapBody: new VariableUse("_wrapJsFunctionForAsync"),
safeVariableName: (String name) => "__$name",
bodyName: new StringBackedName("body")));
@@ -43,6 +44,7 @@
new SyncStarRewriter(null, null,
endOfIteration: new VariableUse("endOfIteration"),
iterableFactory: new VariableUse("NewIterable"),
+ iterableFactoryTypeArgument: new VariableUse("IterableType"),
yieldStarExpression: new VariableUse("yieldStar"),
uncaughtErrorExpression: new VariableUse("uncaughtError"),
safeVariableName: (String name) => "__$name",
@@ -64,7 +66,7 @@
/// 01: ok
r"""function() {
- var __goto = 0, __completer = NewCompleter(), closures, v0, v1, v2, v3;
+ var __goto = 0, __completer = NewCompleter(CompleterType), closures, v0, v1, v2, v3;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -100,7 +102,7 @@
await foo();
}""", """
function(a) {
- var __goto = 0, __completer = NewCompleter(), __self = this;
+ var __goto = 0, __completer = NewCompleter(CompleterType), __self = this;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -145,7 +147,7 @@
return 4;
}""", """
function(b) {
- var __goto = 0, __completer = NewCompleter(), __returnValue, __handler = 2, __currentError, __next = [], __helper;
+ var __goto = 0, __completer = NewCompleter(CompleterType), __returnValue, __handler = 2, __currentError, __next = [], __helper;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1) {
__currentError = __result;
@@ -255,7 +257,7 @@
f = --foo1()[await foo2()];
}""", """
function(c) {
- var __goto = 0, __completer = NewCompleter(), a, b, c, d, e, f, __temp1;
+ var __goto = 0, __completer = NewCompleter(CompleterType), a, b, c, d, e, f, __temp1;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -307,7 +309,7 @@
h = foo1() && foo2();
}""", """
function(d2) {
- var __goto = 0, __completer = NewCompleter(), a, b, c, d, e, f, g, h, __temp1;
+ var __goto = 0, __completer = NewCompleter(CompleterType), a, b, c, d, e, f, g, h, __temp1;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -439,7 +441,7 @@
}
}""", """
function(x, y) {
- var __goto = 0, __completer = NewCompleter();
+ var __goto = 0, __completer = NewCompleter(CompleterType);
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -523,7 +525,7 @@
}
""", """
function(f) {
- var __goto = 0, __completer = NewCompleter(), a;
+ var __goto = 0, __completer = NewCompleter(CompleterType), a;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -583,7 +585,7 @@
}
""", """
function(g) {
- var __goto = 0, __completer = NewCompleter(), __returnValue, i, __temp1;
+ var __goto = 0, __completer = NewCompleter(CompleterType), __returnValue, i, __temp1;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -663,7 +665,7 @@
}
""", """
function(a, h) {
- var __goto = 0, __completer = NewCompleter(), x, __temp1, __temp2;
+ var __goto = 0, __completer = NewCompleter(CompleterType), x, __temp1, __temp2;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -739,7 +741,7 @@
}
""", """
function(c, i) {
- var __goto = 0, __completer = NewCompleter(), __handler = 1, __currentError, __next = [], x, y, __error, __error1;
+ var __goto = 0, __completer = NewCompleter(CompleterType), __handler = 1, __currentError, __next = [], x, y, __error, __error1;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1) {
__currentError = __result;
@@ -849,7 +851,7 @@
}
""", """
function(x, y, j) {
- var __goto = 0, __completer = NewCompleter(), __temp1, __temp2, __temp3;
+ var __goto = 0, __completer = NewCompleter(CompleterType), __temp1, __temp2, __temp3;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -927,7 +929,7 @@
}
}""", """
function(x, y, k) {
- var __goto = 0, __completer = NewCompleter(), __returnValue, __temp1;
+ var __goto = 0, __completer = NewCompleter(CompleterType), __returnValue, __temp1;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -1050,7 +1052,7 @@
}
}""", """
function(l) {
- var __goto = 0, __completer = NewCompleter();
+ var __goto = 0, __completer = NewCompleter(CompleterType);
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1)
return rethrowHelper(__result, __completer);
@@ -1097,7 +1099,7 @@
print(exception);
}""", """
function(m) {
- var __goto = 0, __completer = NewCompleter(), __handler = 1, __currentError, __next = [], exception, __exception;
+ var __goto = 0, __completer = NewCompleter(CompleterType), __handler = 1, __currentError, __next = [], exception, __exception;
var body = _wrapJsFunctionForAsync(function(__errorCode, __result) {
if (__errorCode === 1) {
__currentError = __result;
@@ -1189,6 +1191,6 @@
return uncaughtError(__currentError);
}
};
- });
+ }, IterableType);
}""");
}
diff --git a/tests/compiler/dart2js/closure/data/list_literal_strong_trust.dart b/tests/compiler/dart2js/closure/data/list_literal_strong_trust.dart
new file mode 100644
index 0000000..754fe55
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/list_literal_strong_trust.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.
+
+import 'package:expect/expect.dart';
+
+@NoInline()
+method<T>() {
+ /*fields=[T],free=[T]*/ dynamic local() => <T>[];
+ return local;
+}
+
+@NoInline()
+test(o) => o is List<int>;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isFalse(test(method<String>().call()));
+}
diff --git a/tests/compiler/dart2js/closure/data/list_literal_trust.dart b/tests/compiler/dart2js/closure/data/list_literal_trust.dart
new file mode 100644
index 0000000..433ef26
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/list_literal_trust.dart
@@ -0,0 +1,23 @@
+// 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';
+
+/*element: A.:hasThis*/
+class A<T> {
+ /*element: A.method:hasThis*/
+ @NoInline()
+ method() {
+ /*fields=[this],free=[this],hasThis*/ dynamic local() => <T>[];
+ return local;
+ }
+}
+
+@NoInline()
+test(o) => o is List<int>;
+
+main() {
+ Expect.isTrue(test(new A<int>().method().call()));
+ Expect.isFalse(test(new A<String>().method().call()));
+}
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_strong_trust.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_strong_trust.dart
new file mode 100644
index 0000000..55e709a
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_strong_trust.dart
@@ -0,0 +1,20 @@
+// 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';
+
+@NoInline()
+method<T>() {
+ /**/ dynamic local() => <T>[];
+ return local;
+}
+
+@NoInline()
+test(o) => o == null;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isTrue(test(method<String>().call()));
+ Expect.isFalse(test(null));
+}
diff --git a/tests/compiler/dart2js/closure/data/list_literal_untested_trust.dart b/tests/compiler/dart2js/closure/data/list_literal_untested_trust.dart
new file mode 100644
index 0000000..92b057e
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/list_literal_untested_trust.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+/*element: A.:hasThis*/
+class A<T> {
+ /*element: A.method:hasThis*/
+ @NoInline()
+ method() {
+ /*hasThis*/ dynamic local() => <T>[];
+ return local;
+ }
+}
+
+@NoInline()
+test(o) => o == null;
+
+main() {
+ Expect.isTrue(test(new A<int>().method().call()));
+ Expect.isTrue(test(new A<String>().method().call()));
+ Expect.isFalse(test(null));
+}
diff --git a/tests/compiler/dart2js/closure/data/map_literal_strong_trust.dart b/tests/compiler/dart2js/closure/data/map_literal_strong_trust.dart
new file mode 100644
index 0000000..0347de4
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/map_literal_strong_trust.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.
+
+import 'package:expect/expect.dart';
+
+@NoInline()
+method<T>() {
+ /*fields=[T],free=[T]*/ dynamic local() => <T, int>{};
+ return local;
+}
+
+@NoInline()
+test(o) => o is Map<int, int>;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isFalse(test(method<String>().call()));
+}
diff --git a/tests/compiler/dart2js/closure/data/map_literal_trust.dart b/tests/compiler/dart2js/closure/data/map_literal_trust.dart
new file mode 100644
index 0000000..08cfea6
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/map_literal_trust.dart
@@ -0,0 +1,23 @@
+// 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';
+
+/*element: A.:hasThis*/
+class A<T> {
+ /*element: A.method:hasThis*/
+ @NoInline()
+ method() {
+ /*fields=[this],free=[this],hasThis*/ dynamic local() => <T, int>{};
+ return local;
+ }
+}
+
+@NoInline()
+test(o) => o is Map<int, int>;
+
+main() {
+ Expect.isTrue(test(new A<int>().method().call()));
+ Expect.isFalse(test(new A<String>().method().call()));
+}
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_strong_trust.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_strong_trust.dart
new file mode 100644
index 0000000..8793b90
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_strong_trust.dart
@@ -0,0 +1,20 @@
+// 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';
+
+@NoInline()
+method<T>() {
+ /**/ dynamic local() => <T, int>{};
+ return local;
+}
+
+@NoInline()
+test(o) => o == null;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isTrue(test(method<String>().call()));
+ Expect.isFalse(test(null));
+}
diff --git a/tests/compiler/dart2js/closure/data/map_literal_untested_trust.dart b/tests/compiler/dart2js/closure/data/map_literal_untested_trust.dart
new file mode 100644
index 0000000..958da83
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/map_literal_untested_trust.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+/*element: A.:hasThis*/
+class A<T> {
+ /*element: A.method:hasThis*/
+ @NoInline()
+ method() {
+ /*hasThis*/ dynamic local() => <T, int>{};
+ return local;
+ }
+}
+
+@NoInline()
+test(o) => o == null;
+
+main() {
+ Expect.isTrue(test(new A<int>().method().call()));
+ Expect.isTrue(test(new A<String>().method().call()));
+ Expect.isFalse(test(null));
+}
diff --git a/tests/compiler/dart2js/closure/data/test_type.dart b/tests/compiler/dart2js/closure/data/test_type.dart
new file mode 100644
index 0000000..c74d190
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/test_type.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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit is-test is always required.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class1.:hasThis*/
+class Class1<T> {
+ /*element: Class1.method1:hasThis*/
+ method1(dynamic o) {
+ /*fields=[o,this],free=[o,this],hasThis*/
+ dynamic local() => o is T;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit as-cast is always required.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class2.:hasThis*/
+class Class2<T> {
+ /*element: Class2.method2:hasThis*/
+ method2(dynamic o) {
+ /*fields=[o,this],free=[o,this],hasThis*/
+ dynamic local() => o as T;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Implicit as-cast is only required in strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class3.:hasThis*/
+class Class3<T> {
+ /*element: Class3.method3:hasThis*/
+ method3(dynamic o) {
+ /*ast.fields=[o],free=[o],hasThis*/
+ /*kernel.fields=[o],free=[o],hasThis*/
+ /*strong.fields=[o,this],free=[o,this],hasThis*/
+ T local() => o;
+ return local;
+ }
+}
+
+main() {
+ new Class1<int>().method1(0).call();
+ new Class2<int>().method2(0).call();
+ new Class3<int>().method3(0).call();
+}
diff --git a/tests/compiler/dart2js/closure/data/test_type_strong.dart b/tests/compiler/dart2js/closure/data/test_type_strong.dart
new file mode 100644
index 0000000..93dcec0
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/test_type_strong.dart
@@ -0,0 +1,42 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit is-test is always required.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: method1:*/
+method1<T>(dynamic o) {
+ /*fields=[T,o],free=[T,o]*/
+ dynamic local() => o is T;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit as-cast is always required.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: method2:*/
+method2<T>(dynamic o) {
+ /*fields=[T,o],free=[T,o]*/
+ dynamic local() => o as T;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Implicit as-cast is only required in strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: method3:*/
+method3<T>(dynamic o) {
+ /*fields=[T,o],free=[T,o]*/
+ T local() => o;
+ return local;
+}
+
+main() {
+ method1<int>(0).call();
+ method2<int>(0).call();
+ method3<int>(0).call();
+}
diff --git a/tests/compiler/dart2js/closure/data/test_type_strong_trust.dart b/tests/compiler/dart2js/closure/data/test_type_strong_trust.dart
new file mode 100644
index 0000000..abb909b
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/test_type_strong_trust.dart
@@ -0,0 +1,42 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit is-test is required even with --omit-implicit-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: method1:*/
+method1<T>(dynamic o) {
+ /*fields=[T,o],free=[T,o]*/
+ dynamic local() => o is T;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit as-cast is required even with --omit-implicit-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: method2:*/
+method2<T>(dynamic o) {
+ /*fields=[T,o],free=[T,o]*/
+ dynamic local() => o as T;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Implicit as-cast is not required with --omit-implicit-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: method3:*/
+method3<T>(dynamic o) {
+ /*fields=[o],free=[o]*/
+ T local() => o;
+ return local;
+}
+
+main() {
+ method1<int>(0).call();
+ method2<int>(0).call();
+ method3<int>(0).call();
+}
diff --git a/tests/compiler/dart2js/closure/data/test_type_trust.dart b/tests/compiler/dart2js/closure/data/test_type_trust.dart
new file mode 100644
index 0000000..7ed8dc1
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/test_type_trust.dart
@@ -0,0 +1,51 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit is-test is required even with --omit-implicit-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class1.:hasThis*/
+class Class1<T> {
+ /*element: Class1.method1:hasThis*/
+ method1(dynamic o) {
+ /*fields=[o,this],free=[o,this],hasThis*/
+ dynamic local() => o is T;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Explicit as-cast is required even with --omit-implicit-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class2.:hasThis*/
+class Class2<T> {
+ /*element: Class2.method2:hasThis*/
+ method2(dynamic o) {
+ /*fields=[o,this],free=[o,this],hasThis*/
+ dynamic local() => o as T;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Implicit as-cast is not required with --omit-implicit-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class3.:hasThis*/
+class Class3<T> {
+ /*element: Class3.method3:hasThis*/
+ method3(dynamic o) {
+ /*fields=[o],free=[o],hasThis*/
+ T local() => o;
+ return local;
+ }
+}
+
+main() {
+ new Class1<int>().method1(0).call();
+ new Class2<int>().method2(0).call();
+ new Class3<int>().method3(0).call();
+}
diff --git a/tests/compiler/dart2js/closure/data/two_local_functions.dart b/tests/compiler/dart2js/closure/data/two_local_functions.dart
new file mode 100644
index 0000000..a7ecf9c
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/two_local_functions.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+ /**/ local1() {}
+ /*fields=[local1],free=[local1]*/ local2() => local1();
+ return local2;
+}
diff --git a/tests/compiler/dart2js/closure/data/type_annotations.dart b/tests/compiler/dart2js/closure/data/type_annotations.dart
new file mode 100644
index 0000000..329252f
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/type_annotations.dart
@@ -0,0 +1,167 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// A sound initialization of a local variable doesn't capture the type
+/// variable.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class1.:hasThis*/
+class Class1<T> {
+ /*element: Class1.method1:hasThis*/
+ method1(T o) {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic local() {
+ T t = o;
+ return t;
+ }
+
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A sound assignment to a local variable doesn't capture the type variable.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class1b.:hasThis*/
+class Class1b<T> {
+ /*element: Class1b.method1b:hasThis*/
+ method1b(T o) {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic local() {
+ T t = null;
+ t = o;
+ return t;
+ }
+
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is only captured in strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class2.:hasThis*/
+class Class2<T> {
+ /*element: Class2.method2:hasThis*/
+ method2() {
+ /*ast.hasThis*/
+ /*kernel.hasThis*/
+ /*strong.fields=[this],free=[this],hasThis*/
+ dynamic local(T t) => t;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is only captured in strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class3.:hasThis*/
+class Class3<T> {
+ /*element: Class3.method3:hasThis*/
+ method3(dynamic o) {
+ /*ast.fields=[o],free=[o],hasThis*/
+ /*kernel.fields=[o],free=[o],hasThis*/
+ /*strong.fields=[o,this],free=[o,this],hasThis*/
+ T local() => o;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member parameter type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class4.:hasThis*/
+class Class4<T> {
+ /*element: Class4.method4:hasThis*/
+ method4(T o) {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic local() => o;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member return type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class5.:hasThis*/
+class Class5<T> {
+ /*element: Class5.method5:hasThis*/
+ T method5(dynamic o) {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic local() => o;
+ return local();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class6.:hasThis*/
+class Class6<T> {
+ /*element: Class6.method6:hasThis*/
+ method6() {
+ /*ast.hasThis*/
+ /*kernel.hasThis*/
+ /*strong.fields=[this],free=[this],hasThis*/
+ dynamic local(T t) {
+ /*fields=[t],free=[t],hasThis*/
+ dynamic inner() => t;
+ return inner;
+ }
+
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class7.:hasThis*/
+class Class7<T> {
+ /*element: Class7.method7:hasThis*/
+ method7(dynamic o) {
+ /*ast.fields=[o],free=[o],hasThis*/
+ /*kernel.fields=[o],free=[o],hasThis*/
+ /*strong.fields=[o,this],free=[o,this],hasThis*/
+ T local() {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic inner() => o;
+ return inner();
+ }
+
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A field type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class8.:hasThis*/
+class Class8<T> {
+ /*element: Class8.field8:hasThis*/
+ T field8 = /*hasThis*/ () {
+ return null;
+ }();
+}
+
+main() {
+ new Class1<int>().method1(0).call();
+ new Class1b<int>().method1b(0).call();
+ new Class2<int>().method2().call(0);
+ new Class3<int>().method3(0).call();
+ new Class4<int>().method4(0).call();
+ new Class5<int>().method5(0);
+ new Class6<int>().method6().call(0).call();
+ new Class7<int>().method7(0).call().call();
+ new Class8<int>().field8;
+}
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_strong.dart b/tests/compiler/dart2js/closure/data/type_annotations_strong.dart
new file mode 100644
index 0000000..3b4c2a6
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/type_annotations_strong.dart
@@ -0,0 +1,97 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// A sound assignment to a local variable doesn't capture the type variable.
+////////////////////////////////////////////////////////////////////////////////
+
+method1<T>(T o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() {
+ T t = o;
+ return t;
+ }
+
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is captured in strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+method2<T>() {
+ /*fields=[T],free=[T]*/
+ dynamic local(T t) => t;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is captured in strong mode.
+////////////////////////////////////////////////////////////////////////////////
+
+method3<T>(dynamic o) {
+ /*fields=[T,o],free=[T,o]*/
+ T local() => o;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member parameter type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+method4<T>(T o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() => o;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member return type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+T method5<T>(dynamic o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() => o;
+ return local();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+method6<T>() {
+ /*fields=[T],free=[T]*/
+ dynamic local(T t) {
+ /*fields=[t],free=[t]*/
+ dynamic inner() => t;
+ return inner;
+ }
+
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+method7<T>(dynamic o) {
+ /*fields=[T,o],free=[T,o]*/
+ T local() {
+ /*fields=[o],free=[o]*/
+ dynamic inner() => o;
+ return inner();
+ }
+
+ return local;
+}
+
+main() {
+ method1<int>(0).call();
+ method2<int>().call(0);
+ method3<int>(0).call();
+ method4<int>(0).call();
+ method5<int>(0);
+ method6<int>().call(0).call();
+ method7<int>(0).call().call();
+}
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_strong_trust.dart b/tests/compiler/dart2js/closure/data/type_annotations_strong_trust.dart
new file mode 100644
index 0000000..1ec0bf1
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/type_annotations_strong_trust.dart
@@ -0,0 +1,97 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// A sound assignment to a local variable doesn't capture the type variable.
+////////////////////////////////////////////////////////////////////////////////
+
+method1<T>(T o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() {
+ T t = o;
+ return t;
+ }
+
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is with --omit-type-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+method2<T>() {
+ /**/
+ dynamic local(T t) => t;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is not captured with --omit-type-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+method3<T>(dynamic o) {
+ /*fields=[o],free=[o]*/
+ T local() => o;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member parameter type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+method4<T>(T o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() => o;
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member return type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+T method5<T>(dynamic o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() => o;
+ return local();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+method6<T>() {
+ /**/
+ dynamic local(T t) {
+ /*fields=[t],free=[t]*/
+ dynamic inner() => t;
+ return inner;
+ }
+
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+method7<T>(dynamic o) {
+ /*fields=[o],free=[o]*/
+ T local() {
+ /*fields=[o],free=[o]*/
+ dynamic inner() => o;
+ return inner();
+ }
+
+ return local;
+}
+
+main() {
+ method1<int>(0).call();
+ method2<int>().call(0);
+ method3<int>(0).call();
+ method4<int>(0).call();
+ method5<int>(0);
+ method6<int>().call(0).call();
+ method7<int>(0).call().call();
+}
diff --git a/tests/compiler/dart2js/closure/data/type_annotations_trust.dart b/tests/compiler/dart2js/closure/data/type_annotations_trust.dart
new file mode 100644
index 0000000..ff0ee55
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/type_annotations_trust.dart
@@ -0,0 +1,125 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// A sound assignment to a local variable doesn't capture the type variable.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class1.:hasThis*/
+class Class1<T> {
+ /*element: Class1.method1:hasThis*/
+ method1(T o) {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic local() {
+ T t = o;
+ return t;
+ }
+
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is with --omit-type-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class2.:hasThis*/
+class Class2<T> {
+ /*element: Class2.method2:hasThis*/
+ method2() {
+ /*hasThis*/
+ dynamic local(T t) => t;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is not captured with --omit-type-checks.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class3.:hasThis*/
+class Class3<T> {
+ /*element: Class3.method3:hasThis*/
+ method3(dynamic o) {
+ /*fields=[o],free=[o],hasThis*/
+ T local() => o;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member parameter type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class4.:hasThis*/
+class Class4<T> {
+ /*element: Class4.method4:hasThis*/
+ method4(T o) {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic local() => o;
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A member return type is not captured.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class5.:hasThis*/
+class Class5<T> {
+ /*element: Class5.method5:hasThis*/
+ T method5(dynamic o) {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic local() => o;
+ return local();
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function parameter type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class6.:hasThis*/
+class Class6<T> {
+ /*element: Class6.method6:hasThis*/
+ method6() {
+ /*hasThis*/
+ dynamic local(T t) {
+ /*fields=[t],free=[t],hasThis*/
+ dynamic inner() => t;
+ return inner;
+ }
+
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A local function return type is not captured by an inner local function.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class7.:hasThis*/
+class Class7<T> {
+ /*element: Class7.method7:hasThis*/
+ method7(dynamic o) {
+ /*fields=[o],free=[o],hasThis*/
+ T local() {
+ /*fields=[o],free=[o],hasThis*/
+ dynamic inner() => o;
+ return inner();
+ }
+
+ return local;
+ }
+}
+
+main() {
+ new Class1<int>().method1(0).call();
+ new Class2<int>().method2().call(0);
+ new Class3<int>().method3(0).call();
+ new Class4<int>().method4(0).call();
+ new Class5<int>().method5(0);
+ new Class6<int>().method6().call(0).call();
+ new Class7<int>().method7(0).call().call();
+}
diff --git a/tests/compiler/dart2js/closure/data/type_arguments.dart b/tests/compiler/dart2js/closure/data/type_arguments.dart
new file mode 100644
index 0000000..8061663
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/type_arguments.dart
@@ -0,0 +1,44 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// A constructor invocation to a class that needs type arguments captures the
+/// type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class1a.:hasThis*/
+class Class1a<T> {}
+
+/*element: Class1b.:hasThis*/
+class Class1b<T> {
+ /*element: Class1b.method1:hasThis*/
+ method1() {
+ /*fields=[this],free=[this],hasThis*/
+ dynamic local() => new Class1a<T>();
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A constructor invocation to a class that _doesn't_ needs type arguments does
+/// _not_ capture the type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class2a.:hasThis*/
+class Class2a<T> {}
+
+/*element: Class2b.:hasThis*/
+class Class2b<T> {
+ /*element: Class2b.method2:hasThis*/
+ method2() {
+ /*hasThis*/
+ dynamic local() => new Class2a<T>();
+ return local;
+ }
+}
+
+main() {
+ new Class1b<int>().method1().call() is Class1a<int>;
+ new Class2b<int>().method2().call();
+}
diff --git a/tests/compiler/dart2js/closure/data/type_arguments_strong.dart b/tests/compiler/dart2js/closure/data/type_arguments_strong.dart
new file mode 100644
index 0000000..99733a8
--- /dev/null
+++ b/tests/compiler/dart2js/closure/data/type_arguments_strong.dart
@@ -0,0 +1,138 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+/// A constructor invocation for a class that needs type arguments captures the
+/// type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class1a.:hasThis*/
+class Class1a<T> {}
+
+/*element: Class1b.:hasThis*/
+class Class1b<T> {
+ /*element: Class1b.method1:hasThis*/
+ method1() {
+ /*fields=[this],free=[this],hasThis*/
+ dynamic local() => new Class1a<T>();
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A constructor invocation for a class that _doesn't_ needs type arguments
+/// does _not_ capture the type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class2a.:hasThis*/
+class Class2a<T> {}
+
+/*element: Class2b.:hasThis*/
+class Class2b<T> {
+ /*element: Class2b.method2:hasThis*/
+ method2() {
+ /*hasThis*/
+ dynamic local() => new Class2a<T>();
+ return local;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A static invocation of a method that needs type arguments captures the type
+/// variables.
+////////////////////////////////////////////////////////////////////////////////
+
+method3a<T>(o) => o is T;
+
+method3b<T>(o) {
+ /*fields=[T,o],free=[T,o]*/
+ dynamic local() => method3a<T>(o);
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// A static invocation of a method that _doesn't_ needs type arguments does
+/// _not_ capture the type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+method4a<T>(o) => o;
+
+method4b<T>(o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() => method4a<T>(o);
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// An instance member invocation of a method that needs type arguments captures
+/// the type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class5a.:hasThis*/
+class Class5a {
+ /*element: Class5a.method5a:hasThis*/
+ method5a<T>(o) => o is T;
+}
+
+method5b<T>(o) {
+ /*fields=[T,o],free=[T,o]*/
+ dynamic local() => new Class5a().method5a<T>(o);
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// An instance member invocation of a method that _doesn't_ needs type
+/// arguments does _not_ capture the type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+/*element: Class6a.:hasThis*/
+class Class6a {
+ /*element: Class6a.method6a:hasThis*/
+ method6a<T>(o) => o;
+}
+
+method6b<T>(o) {
+ /*fields=[o],free=[o]*/
+ dynamic local() => new Class6a().method6a<T>(o);
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// An invocation of a local function that needs type arguments captures the
+/// type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+method7b<T>(o) {
+ /**/
+ method7a<S>(p) => p is S;
+
+ /*fields=[T,method7a,o],free=[T,method7a,o]*/
+ dynamic local() => method7a<T>(o);
+ return local;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// An invocation if a local function that _doesn't_ needs type arguments does
+/// _not_ capture the type variables.
+////////////////////////////////////////////////////////////////////////////////
+
+method8b<T>(o) {
+ /**/
+ method8a<S>(p) => p;
+
+ /*fields=[T,method8a,o],free=[T,method8a,o]*/
+ dynamic local() => method8a<T>(o);
+ return local;
+}
+
+main() {
+ new Class1b<int>().method1().call() is Class1a<int>;
+ new Class2b<int>().method2().call();
+ method3b<int>(0).call();
+ method4b<int>(0).call();
+ method5b<int>(0).call();
+ method6b<int>(0).call();
+ method7b<int>(0).call();
+ method8b<int>(0).call();
+}
diff --git a/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart b/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
new file mode 100644
index 0000000..5d224e8
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/jsarray_indexof_test.dart
@@ -0,0 +1,83 @@
+// 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 `length` access in JSArray.indexOf is encoding using `.length` and
+// not `.get$length()`.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/names.dart';
+import 'package:compiler/src/world.dart';
+import 'package:compiler/src/js_emitter/model.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/universe/selector.dart';
+import 'package:expect/expect.dart';
+import '../memory_compiler.dart';
+import '../helpers/element_lookup.dart';
+import '../helpers/program_lookup.dart';
+
+const String source = '''
+import 'package:expect/expect.dart';
+
+@NoInline()
+test(o, a) => o.indexOf(a);
+main() {
+ test([1, 2, 3], 2);
+ test(['1', '2', '3'], '2');
+}
+''';
+
+main() {
+ asyncTest(() async {
+ print('--test from ast---------------------------------------------------');
+ await runTest([Flags.useOldFrontend]);
+ print('--test from ast (trust-type-annotations)--------------------------');
+ await runTest([Flags.useOldFrontend, Flags.trustTypeAnnotations]);
+ print('--test from kernel------------------------------------------------');
+ await runTest([]);
+ print('--test from kernel (trust-type-annotations)-----------------------');
+ await runTest([Flags.trustTypeAnnotations]);
+ print('--test from kernel (strong mode)----------------------------------');
+ await runTest([Flags.strongMode]);
+ print('--test from kernel (strong mode, omit-implicit.checks)------------');
+ await runTest([Flags.strongMode, Flags.omitImplicitChecks]);
+ });
+}
+
+runTest(List<String> options) async {
+ CompilationResult result = await runCompiler(
+ memorySourceFiles: {'main.dart': source}, options: options);
+ Expect.isTrue(result.isSuccess);
+ Compiler compiler = result.compiler;
+ ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+ MemberEntity jsArrayIndexOf =
+ findClassMember(closedWorld, 'JSArray', 'indexOf');
+ ProgramLookup programLookup = new ProgramLookup(result.compiler);
+
+ Selector getLengthSelector = new Selector.getter(const PublicName('length'));
+ js.Name getLengthName =
+ compiler.backend.namer.invocationName(getLengthSelector);
+
+ Method method = programLookup.getMethod(jsArrayIndexOf);
+ int lengthCount = 0;
+ forEachNode(method.code, onCall: (js.Call node) {
+ js.Node target = node.target;
+ Expect.isFalse(
+ target is js.PropertyAccess && target.selector == getLengthName,
+ "Unexpected .get\$length access ${js.nodeToString(node)} in\n"
+ "${js.nodeToString(method.code, pretty: true)}");
+ }, onPropertyAccess: (js.PropertyAccess node) {
+ js.Node selector = node.selector;
+ if (selector is js.LiteralString && selector.value == '"length"') {
+ lengthCount++;
+ }
+ });
+ Expect.equals(
+ 2,
+ lengthCount,
+ "Unexpected .length access in\n"
+ "${js.nodeToString(method.code, pretty: true)}");
+}
diff --git a/tests/compiler/dart2js/codegen/negation_shift_regression_test.dart b/tests/compiler/dart2js/codegen/negation_shift_regression_test.dart
new file mode 100644
index 0000000..ec028c8
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/negation_shift_regression_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import '../compiler_helper.dart';
+
+// A bug in UnaryNegateSpecializer left '-a' labelled as 'positive', allowing
+// misoptimization of '<<'.
+const String TEST1 = r"""
+foo(param) {
+ var a = param ? 0xFFFFFFFF : 1;
+ return 1 << -a;
+ // present: '$shl'
+ // absent: '_shlPositive'
+}
+""";
+
+const String TEST2 = r"""
+foo(param) {
+ var a = param ? 0xFFFFFFFF : 1;
+ return 1 << a;
+ // present: '_shlPositive'
+ // absent: '$shl'
+}
+""";
+
+main() {
+ runTests({bool useKernel}) async {
+ check(String test) async {
+ await compile(test,
+ entry: 'foo',
+ useKernel: useKernel,
+ check: checkerForAbsentPresent(test));
+ }
+
+ await check(TEST1);
+ await check(TEST2);
+ }
+
+ asyncTest(() async {
+ print('--test from ast---------------------------------------------------');
+ await runTests(useKernel: false);
+ print('--test from kernel------------------------------------------------');
+ await runTests(useKernel: true);
+ });
+}
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index d15d999..52efe99 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -5,6 +5,7 @@
analyze_test: Slow, Pass
async_await_syntax_test: Pass # DON'T CHANGE THIS LINE -- Don't mark these tests as failing. Instead, fix the errors/warnings that they report or update the whitelist in the test-files to temporarily allow digression.
boolified_operator_test: Fail # Issue 8001
+closure/closure_test: Pass, Slow
codegen/gvn_dynamic_field_get_test: Fail # Issue 18519
codegen/load_elimination_test: Pass, Slow
codegen/logical_expression_test: Fail # Issue 17027
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index 1ab3749..02b0d5e 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -480,14 +480,17 @@
bool trustTypeAnnotations = false;
if (name.endsWith('_ea.dart')) {
testOptions.add(Flags.enableAsserts);
- } else if (name.endsWith('_strong.dart')) {
+ }
+ if (name.contains('_strong')) {
strongModeOnlyTest = true;
if (!testStrongMode) {
testOptions.add(Flags.strongMode);
}
- } else if (name.endsWith('_checked.dart')) {
+ }
+ if (name.endsWith('_checked.dart')) {
testOptions.add(Flags.enableCheckedMode);
- } else if (name.endsWith('_trust.dart')) {
+ }
+ if (name.contains('_trust')) {
trustTypeAnnotations = true;
}
diff --git a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
index 5c22fee..0c4ed18 100644
--- a/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
+++ b/tests/compiler/dart2js/generic_methods/function_type_variable_test.dart
@@ -18,6 +18,8 @@
const FunctionTypeData('void', 'F6', '<X extends int>(X x)'),
const FunctionTypeData('void', 'F7', '<Y extends num>(Y y, [int i])'),
const FunctionTypeData('Z', 'F8', '<Z extends num>(Z z)'),
+ const FunctionTypeData('T', 'F13', '<T>(T t1, T t2)'),
+ const FunctionTypeData('S', 'F14', '<S>(S s1, S s2)'),
];
main() {
@@ -74,6 +76,10 @@
env.isSubtype(a, b),
"Expected `$a` ${isSubtype ? '' : 'not '}to be a subtype of `$b`, "
"but it is${isSubtype ? ' not' : ''}.");
+ if (isSubtype) {
+ Expect.isTrue(env.isPotentialSubtype(a, b),
+ '$a <: $b but not a potential subtype.');
+ }
}
InterfaceType Object_ = env['Object'];
@@ -95,6 +101,8 @@
FunctionType F10 = env.getClosureType('F10');
FunctionType F11 = env.getMemberType('F11');
FunctionType F12 = env.getMemberType('F12');
+ FunctionType F13 = env.getFieldType('F13');
+ FunctionType F14 = env.getFieldType('F14');
List<FunctionType> all = <FunctionType>[
F1,
@@ -109,6 +117,8 @@
F10,
F11,
F12,
+ F13,
+ F14,
];
testToString(F1, 'void Function<#A>(#A)');
@@ -123,6 +133,8 @@
testToString(F10, 'void Function<#A extends #B,#B>(#A,#B)');
testToString(F11, 'void Function<#A extends C3<#A>>(#A)');
testToString(F12, 'void Function<#A extends C3<#A>>(#A)');
+ testToString(F13, '#A Function<#A>(#A,#A)');
+ testToString(F14, '#A Function<#A>(#A,#A)');
testBounds(F1, [Object_]);
testBounds(F2, [Object_]);
@@ -140,6 +152,8 @@
testBounds(F12, [
instantiate(C3, [F12.typeVariables.last])
]);
+ testBounds(F13, [Object_]);
+ testBounds(F14, [Object_]);
testInstantiate(F1, [C1], 'void Function(C1)');
testInstantiate(F2, [C2], 'void Function(C2)');
@@ -153,6 +167,8 @@
testInstantiate(F10, [int_, num_], 'void Function(int,num)');
testInstantiate(F11, [C4], 'void Function(C4)');
testInstantiate(F12, [C4], 'void Function(C4)');
+ testInstantiate(F13, [C1], 'C1 Function(C1,C1)');
+ testInstantiate(F14, [C2], 'C2 Function(C2,C2)');
Map<FunctionType, List<FunctionType>> expectedEquals =
<FunctionType, List<FunctionType>>{
@@ -162,6 +178,8 @@
F10: [F9],
F11: [F12],
F12: [F11],
+ F13: [F14],
+ F14: [F13],
};
Map<FunctionType, List<FunctionType>> expectedSubtype =
diff --git a/tests/compiler/dart2js/helpers/element_lookup.dart b/tests/compiler/dart2js/helpers/element_lookup.dart
index 670e45f..4ebe13a 100644
--- a/tests/compiler/dart2js/helpers/element_lookup.dart
+++ b/tests/compiler/dart2js/helpers/element_lookup.dart
@@ -13,6 +13,10 @@
elementEnvironment.lookupClass(elementEnvironment.mainLibrary, name);
cls ??= elementEnvironment.lookupClass(
closedWorld.commonElements.coreLibrary, name);
+ cls ??= elementEnvironment.lookupClass(
+ closedWorld.commonElements.interceptorsLibrary, name);
+ cls ??= elementEnvironment.lookupClass(
+ closedWorld.commonElements.jsHelperLibrary, name);
assert(cls != null, "Class '$name' not found.");
return cls;
}
diff --git a/tests/compiler/dart2js/helpers/program_lookup.dart b/tests/compiler/dart2js/helpers/program_lookup.dart
index b73b5fc..7ac0fed 100644
--- a/tests/compiler/dart2js/helpers/program_lookup.dart
+++ b/tests/compiler/dart2js/helpers/program_lookup.dart
@@ -6,6 +6,7 @@
import 'package:compiler/src/common_elements.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/js_backend/namer.dart';
import 'package:compiler/src/js_emitter/model.dart';
import 'package:compiler/src/js/js.dart' as js;
@@ -31,9 +32,11 @@
class ProgramLookup {
final Program program;
+ final Namer namer;
ProgramLookup(Compiler compiler)
- : this.program = compiler.backend.emitter.emitter.programForTesting;
+ : this.program = compiler.backend.emitter.emitter.programForTesting,
+ this.namer = compiler.backend.namer;
Map<LibraryEntity, LibraryData> libraryMap;
@@ -123,19 +126,29 @@
}
}
-void forEachCall(js.Node root, void f(js.Call node)) {
- CallVisitor visitor = new CallVisitor(f);
+void forEachNode(js.Node root,
+ {void Function(js.Call) onCall,
+ void Function(js.PropertyAccess) onPropertyAccess}) {
+ CallbackVisitor visitor =
+ new CallbackVisitor(onCall: onCall, onPropertyAccess: onPropertyAccess);
root.accept(visitor);
}
-class CallVisitor extends js.BaseVisitor {
- final void Function(js.Call) callback;
+class CallbackVisitor extends js.BaseVisitor {
+ final void Function(js.Call) onCall;
+ final void Function(js.PropertyAccess) onPropertyAccess;
- CallVisitor(this.callback);
+ CallbackVisitor({this.onCall, this.onPropertyAccess});
@override
visitCall(js.Call node) {
- callback(node);
+ if (onCall != null) onCall(node);
super.visitCall(node);
}
+
+ @override
+ visitAccess(js.PropertyAccess node) {
+ if (onPropertyAccess != null) onPropertyAccess(node);
+ super.visitAccess(node);
+ }
}
diff --git a/tests/compiler/dart2js/inference/data/expose_this.dart b/tests/compiler/dart2js/inference/data/expose_this.dart
index 8bc8934..e888229 100644
--- a/tests/compiler/dart2js/inference/data/expose_this.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this.dart
@@ -70,9 +70,6 @@
this;
/*update: [exact=Class3]*/ field = 42;
}
-
- /*element: Class3.method:[null]*/
- method() {}
}
/*element: exposeThis3:[exact=Class3]*/
diff --git a/tests/compiler/dart2js/inference/data/expose_this_mask.dart b/tests/compiler/dart2js/inference/data/expose_this_mask.dart
index 1447e11..b1033c6 100644
--- a/tests/compiler/dart2js/inference/data/expose_this_mask.dart
+++ b/tests/compiler/dart2js/inference/data/expose_this_mask.dart
@@ -42,7 +42,7 @@
/*element: otherGetter:[null]*/
otherGetter() {
- new OtherClass1();
+ new OtherClass1(). /*[exact=OtherClass1]*/ field1a;
new Class1();
}
@@ -70,7 +70,7 @@
/*element: otherMethod:[null]*/
otherMethod() {
- new OtherClass2();
+ new OtherClass2(). /*[exact=OtherClass2]*/ field2a;
new Class2();
}
diff --git a/tests/compiler/dart2js/inference/inference_test_helper.dart b/tests/compiler/dart2js/inference/inference_test_helper.dart
index ed2bc4a..2b9c68f 100644
--- a/tests/compiler/dart2js/inference/inference_test_helper.dart
+++ b/tests/compiler/dart2js/inference/inference_test_helper.dart
@@ -48,7 +48,6 @@
await checkTests(
dataDir, computeMemberAstTypeMasks, computeMemberIrTypeMasks,
libDirectory: new Directory.fromUri(Platform.script.resolve('libs')),
- testStrongMode: true,
forUserLibrariesOnly: true,
args: args,
options: [stopAfterTypeInference],
diff --git a/tests/compiler/dart2js/inference/side_effects/closure_call.dart b/tests/compiler/dart2js/inference/side_effects/closure_call.dart
index baa0e7c..7aaf687 100644
--- a/tests/compiler/dart2js/inference/side_effects/closure_call.dart
+++ b/tests/compiler/dart2js/inference/side_effects/closure_call.dart
@@ -2,8 +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.
+/*element: method:SideEffects(reads nothing; writes nothing)*/
+method() {}
+
/*element: callExpression:SideEffects(reads anything; writes anything)*/
-callExpression() => (null)();
+callExpression() => (method)();
/*element: Super.:SideEffects(reads nothing; writes nothing)*/
class Super {
diff --git a/tests/compiler/dart2js/inference/side_effects_test.dart b/tests/compiler/dart2js/inference/side_effects_test.dart
index f0189f7..a92944e 100644
--- a/tests/compiler/dart2js/inference/side_effects_test.dart
+++ b/tests/compiler/dart2js/inference/side_effects_test.dart
@@ -26,8 +26,7 @@
dataDir, computeMemberAstSideEffects, computeMemberIrSideEffects,
args: args,
options: [stopAfterTypeInference],
- // TODO(johnniwinther): Run tests with strong mode.
- testStrongMode: false);
+ skipForStrong: ['closure_call.dart']);
});
}
diff --git a/tests/compiler/dart2js/inlining/data/conditional.dart b/tests/compiler/dart2js/inlining/data/conditional.dart
index 5203943..2cb4977 100644
--- a/tests/compiler/dart2js/inlining/data/conditional.dart
+++ b/tests/compiler/dart2js/inlining/data/conditional.dart
@@ -22,7 +22,7 @@
/*element: _method1:[_conditionalField]*/
_method1() => 42;
-var _field1;
+bool _field1;
/*element: _conditionalField:[]*/
_conditionalField() {
@@ -49,7 +49,7 @@
_method2() => 42;
/*element: _conditionalParameter:[conditionalParameter]*/
-_conditionalParameter(o) {
+_conditionalParameter(bool o) {
return o
? _method2() + _method2() + _method2()
: _method2() + _method2() + _method2();
diff --git a/tests/compiler/dart2js/inlining/inlining_test.dart b/tests/compiler/dart2js/inlining/inlining_test.dart
index c14e939..36e7b3f 100644
--- a/tests/compiler/dart2js/inlining/inlining_test.dart
+++ b/tests/compiler/dart2js/inlining/inlining_test.dart
@@ -28,10 +28,7 @@
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
await checkTests(
dataDir, computeMemberAstInlinings, computeMemberIrInlinings,
- args: args,
- skipForAst: ['external.dart'],
- // TODO(johnniwinther): Run tests with strong mode.
- testStrongMode: false);
+ args: args, skipForAst: ['external.dart']);
});
}
diff --git a/tests/compiler/dart2js/jumps/data/complex_loops.dart b/tests/compiler/dart2js/jumps/data/complex_loops.dart
new file mode 100644
index 0000000..5495006
--- /dev/null
+++ b/tests/compiler/dart2js/jumps/data/complex_loops.dart
@@ -0,0 +1,101 @@
+// 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.
+
+simpleForInLoopWithContinue(list) {
+ /*0@continue*/ for (int i in list) {
+ if (i % 2 == 0) /*target=0*/ continue;
+ print(i);
+ }
+}
+
+complexForInLoopWithContinueLookalike1(list) {
+ for (int i in list) {
+ label:
+ /*0@break*/
+ {
+ if (i % 2 == 0) /*target=0*/ break label;
+ print(i);
+ }
+ print(i);
+ }
+}
+
+complexForInLoopWithContinueLookalike2(list) {
+ /*kernel.0@continue*/
+ /*strong.0@continue*/
+ for (int i in list) {
+ label:
+ /*ast.0@break*/
+ {
+ if (i % 2 == 0) /*target=0*/ break label;
+ print(i);
+ }
+ }
+}
+
+labelledBreakInNestedWhileLoop(bool condition()) {
+ int i = 111;
+ /*0@break*/ while (condition()) {
+ label:
+ /*1@break*/ {
+ while (condition()) {
+ /*target=1*/ break label;
+ }
+ i--;
+ }
+ /*target=0*/ break;
+ }
+ return i;
+}
+
+nestedLoopsWithInnerBreak(list) {
+ for (int i in list) {
+ /*0@break*/ for (int j in list) {
+ if (i % j == 0) /*target=0*/ break;
+ print(i);
+ }
+ }
+}
+
+nestedLoopsWithInnerContinue(list) {
+ for (int i in list) {
+ /*0@continue*/ for (int j in list) {
+ if (i % j == 0) /*target=0*/ continue;
+ print(i);
+ }
+ }
+}
+
+nestedLoopsWithLabelledBreak(list) {
+ outer:
+ /*0@break*/
+ for (int i in list) {
+ for (int j in list) {
+ if (i % j == 0) /*target=0*/ break outer;
+ print(i);
+ }
+ }
+}
+
+nestedLoopsWithLabelledContinue(list) {
+ outer:
+ /*0@continue*/
+ for (int i in list) {
+ for (int j in list) {
+ if (i % j == 0) /*target=0*/ continue outer;
+ print(i);
+ }
+ }
+}
+
+main() {
+ simpleForInLoopWithContinue([1, 2, 3, 4]);
+ complexForInLoopWithContinueLookalike1([1, 2, 3, 4]);
+ complexForInLoopWithContinueLookalike2([1, 2, 3, 4]);
+ labelledBreakInNestedWhileLoop(() => true);
+ nestedLoopsWithInnerBreak([1, 2, 3, 4]);
+ nestedLoopsWithInnerContinue([1, 2, 3, 4]);
+ nestedLoopsWithLabelledBreak([1, 2, 3, 4]);
+ nestedLoopsWithLabelledContinue([1, 2, 3, 4]);
+}
diff --git a/tests/compiler/dart2js/jumps/jump_test.dart b/tests/compiler/dart2js/jumps/jump_test.dart
index 2a911b4..b18da0e 100644
--- a/tests/compiler/dart2js/jumps/jump_test.dart
+++ b/tests/compiler/dart2js/jumps/jump_test.dart
@@ -24,9 +24,7 @@
Directory dataDir = new Directory.fromUri(Platform.script.resolve('data'));
await checkTests(dataDir, computeJumpsData, computeKernelJumpsData,
options: [Flags.disableTypeInference, stopAfterTypeInference],
- args: args,
- // TODO(johnniwinther): Run tests with strong mode.
- testStrongMode: false);
+ args: args);
});
}
diff --git a/tests/compiler/dart2js/model/constant_expression_test.dart b/tests/compiler/dart2js/model/constant_expression_test.dart
index 44a1406..6babb67 100644
--- a/tests/compiler/dart2js/model/constant_expression_test.dart
+++ b/tests/compiler/dart2js/model/constant_expression_test.dart
@@ -57,7 +57,9 @@
const ConstantData('1 + 2', ConstantExpressionKind.BINARY),
const ConstantData('1 == 2', ConstantExpressionKind.BINARY),
// TODO(sigmund): reenable (Issue 32511)
- // const ConstantData('1 != 2', ConstantExpressionKind.BINARY),
+ const ConstantData('1 != 2', ConstantExpressionKind.UNARY,
+ // a != b is encoded as !(a == b) by CFE.
+ text: '!(1 == 2)'),
const ConstantData('1 ?? 2', ConstantExpressionKind.BINARY),
const ConstantData('-(1)', ConstantExpressionKind.UNARY, text: '-1'),
const ConstantData('"foo".length', ConstantExpressionKind.STRING_LENGTH),
@@ -156,34 +158,44 @@
'const A<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
type: 'A<int>', fields: const {'field(A#field1)': '87'}),
// TODO(sigmund): reenable (Issue 32511)
- //const ConstantData('const B()', ConstantExpressionKind.CONSTRUCTED,
- // type: 'A<B<dynamic>>',
- // fields: const {
- // 'field(A#field1)': '42',
- // }),
- //const ConstantData('const B<int>()', ConstantExpressionKind.CONSTRUCTED,
- // type: 'A<B<int>>',
- // fields: const {
- // 'field(A#field1)': '42',
- // }),
- //const ConstantData(
- // 'const B<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
- // type: 'A<B<int>>',
- // fields: const {
- // 'field(A#field1)': '87',
- // }),
- //const ConstantData(
- // 'const C<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
- // type: 'A<B<double>>',
- // fields: const {
- // 'field(A#field1)': '87',
- // }),
- //const ConstantData(
- // 'const B<int>.named()', ConstantExpressionKind.CONSTRUCTED,
- // type: 'A<int>',
- // fields: const {
- // 'field(A#field1)': '42',
- // }),
+ const ConstantData('const B()', ConstantExpressionKind.CONSTRUCTED,
+ type: 'A<B<dynamic>>',
+ fields: const {
+ 'field(A#field1)': '42',
+ },
+ // Redirecting factories are replaced by their effective targets by CFE.
+ text: 'const A<B<dynamic>>()'),
+ const ConstantData('const B<int>()', ConstantExpressionKind.CONSTRUCTED,
+ type: 'A<B<int>>',
+ fields: const {
+ 'field(A#field1)': '42',
+ },
+ // Redirecting factories are replaced by their effective targets by CFE.
+ text: 'const A<B<int>>()'),
+ const ConstantData(
+ 'const B<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
+ type: 'A<B<int>>',
+ fields: const {
+ 'field(A#field1)': '87',
+ },
+ // Redirecting factories are replaced by their effective targets by CFE.
+ text: 'const A<B<int>>(field1: 87)'),
+ const ConstantData(
+ 'const C<int>(field1: 87)', ConstantExpressionKind.CONSTRUCTED,
+ type: 'A<B<double>>',
+ fields: const {
+ 'field(A#field1)': '87',
+ },
+ // Redirecting factories are replaced by their effective targets by CFE.
+ text: 'const A<B<double>>(field1: 87)'),
+ const ConstantData(
+ 'const B<int>.named()', ConstantExpressionKind.CONSTRUCTED,
+ type: 'A<int>',
+ fields: const {
+ 'field(A#field1)': '42',
+ },
+ // Redirecting factories are replaced by their effective targets by CFE.
+ text: 'const A<int>()'),
]),
];
diff --git a/tests/compiler/dart2js/model/enqueuer_test.dart b/tests/compiler/dart2js/model/enqueuer_test.dart
new file mode 100644
index 0000000..567a11f
--- /dev/null
+++ b/tests/compiler/dart2js/model/enqueuer_test.dart
@@ -0,0 +1,291 @@
+// 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 the enqueuers are not dependent upon in which order impacts are
+// applied.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common_elements.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/names.dart';
+import 'package:compiler/src/elements/types.dart';
+import 'package:compiler/src/enqueue.dart';
+import 'package:compiler/src/types/types.dart';
+import 'package:compiler/src/universe/call_structure.dart';
+import 'package:compiler/src/universe/selector.dart';
+import 'package:compiler/src/universe/world_impact.dart';
+import 'package:compiler/src/universe/use.dart';
+import 'package:compiler/src/universe/world_builder.dart';
+import 'package:compiler/src/world.dart';
+import 'package:expect/expect.dart';
+import '../memory_compiler.dart';
+
+class Test {
+ final String name;
+ final String code;
+ final List<Impact> impacts;
+ final Map<String, List<String>> expectedLiveMap;
+
+ const Test({this.name, this.code, this.impacts, this.expectedLiveMap});
+
+ Map<String, List<String>> get expectedLiveResolutionMap {
+ Map<String, List<String>> map = {};
+ expectedLiveMap.forEach((String clsName, List<String> memberNames) {
+ for (String memberName in memberNames) {
+ if (memberName.startsWith('?')) {
+ memberName = memberName.substring(1);
+ }
+ map.putIfAbsent(clsName, () => []).add(memberName);
+ }
+ });
+ return map;
+ }
+
+ Map<String, List<String>> get expectedLiveCodegenMap {
+ Map<String, List<String>> map = {};
+ expectedLiveMap.forEach((String clsName, List<String> memberNames) {
+ for (String memberName in memberNames) {
+ if (memberName.startsWith('?')) {
+ // Skip for codegen
+ continue;
+ }
+ map.putIfAbsent(clsName, () => []).add(memberName);
+ }
+ });
+ return map;
+ }
+}
+
+enum ImpactKind { instantiate, invoke }
+
+class Impact {
+ final ImpactKind kind;
+ final String clsName;
+ final String memberName;
+
+ const Impact.instantiate(this.clsName, [this.memberName = ''])
+ : this.kind = ImpactKind.instantiate;
+ const Impact.invoke(this.clsName, this.memberName)
+ : this.kind = ImpactKind.invoke;
+
+ String toString() =>
+ 'Impact(kind=$kind,clsName=$clsName,memberName=$memberName)';
+}
+
+const List<Test> tests = const <Test>[
+ const Test(name: 'Instantiate class', code: '''
+class A {
+ void method() {}
+}
+''', impacts: const [
+ const Impact.instantiate('A'),
+ const Impact.invoke('A', 'method'),
+ ], expectedLiveMap: const {
+ 'A': const ['', 'method'],
+ }),
+ const Test(name: 'Instantiate subclass', code: '''
+class A {
+ void method() {}
+}
+class B extends A {
+}
+''', impacts: const [
+ const Impact.instantiate('B'),
+ const Impact.invoke('B', 'method'),
+ ], expectedLiveMap: const {
+ 'A': const ['?', 'method'],
+ 'B': const [''],
+ }),
+ const Test(name: 'Instantiate superclass/subclass', code: '''
+class A {
+ void method() {}
+}
+class B extends A {
+}
+''', impacts: const [
+ const Impact.instantiate('A'),
+ const Impact.instantiate('B'),
+ const Impact.invoke('B', 'method'),
+ ], expectedLiveMap: const {
+ 'A': const ['', 'method'],
+ 'B': const [''],
+ }),
+];
+
+main() {
+ asyncTest(() async {
+ for (Test test in tests) {
+ await runTest(test);
+ }
+ });
+}
+
+runTest(Test test) async {
+ print('====================================================================');
+ print('Running test ${test.name}');
+ for (List<Impact> permutation in permutations(test.impacts)) {
+ print('------------------------------------------------------------------');
+ print('Permutation: $permutation');
+ await runTestPermutation(test, permutation);
+ }
+}
+
+Iterable<List<Impact>> permutations(List<Impact> impacts) sync* {
+ int length = impacts.length;
+ if (length <= 1) {
+ yield impacts;
+ } else {
+ for (int index = 0; index < length; index++) {
+ Impact head = impacts[index];
+ List<Impact> tail = new List<Impact>.from(impacts)..removeAt(index);
+ for (List<Impact> permutation in permutations(tail)) {
+ yield [head]..addAll(permutation);
+ }
+ }
+ }
+}
+
+runTestPermutation(Test test, List<Impact> impacts) async {
+ Compiler compiler = compilerFor(memorySourceFiles: {
+ 'main.dart': '''
+${test.code}
+main() {}
+'''
+ }, options: [
+ Flags.strongMode,
+ Flags.disableInlining,
+ ]);
+
+ void checkInvariant(
+ Enqueuer enqueuer, ElementEnvironment elementEnvironment) {
+ for (MemberEntity member
+ in compiler.enqueuer.resolution.processedEntities) {
+ Expect.isTrue(
+ member == elementEnvironment.mainFunction ||
+ member.library != elementEnvironment.mainLibrary,
+ "Unexpected member $member in ${enqueuer}.");
+ }
+ }
+
+ void instantiate(
+ Enqueuer enqueuer, ElementEnvironment elementEnvironment, String name) {
+ ClassEntity cls =
+ elementEnvironment.lookupClass(elementEnvironment.mainLibrary, name);
+ ConstructorEntity constructor =
+ elementEnvironment.lookupConstructor(cls, '');
+ InterfaceType type = elementEnvironment.getRawType(cls);
+ WorldImpact impact = new WorldImpactBuilderImpl()
+ ..registerStaticUse(new StaticUse.typedConstructorInvoke(
+ constructor, constructor.parameterStructure.callStructure, type));
+ enqueuer.applyImpact(impact);
+ }
+
+ void invoke(
+ Enqueuer enqueuer,
+ ElementEnvironment elementEnvironment,
+ String className,
+ String methodName,
+ ReceiverConstraint Function(ClassEntity cls) createConstraint) {
+ ClassEntity cls = elementEnvironment.lookupClass(
+ elementEnvironment.mainLibrary, className);
+ Selector selector = new Selector.call(
+ new Name(methodName, elementEnvironment.mainLibrary),
+ CallStructure.NO_ARGS);
+ WorldImpact impact = new WorldImpactBuilderImpl()
+ ..registerDynamicUse(new ConstrainedDynamicUse(
+ selector, createConstraint(cls), const <DartType>[]));
+ enqueuer.applyImpact(impact);
+ }
+
+ void applyImpact(
+ Enqueuer enqueuer,
+ ElementEnvironment elementEnvironment,
+ Impact impact,
+ ReceiverConstraint Function(ClassEntity cls) createConstraint) {
+ switch (impact.kind) {
+ case ImpactKind.instantiate:
+ instantiate(enqueuer, elementEnvironment, impact.clsName);
+ break;
+ case ImpactKind.invoke:
+ invoke(enqueuer, elementEnvironment, impact.clsName, impact.memberName,
+ createConstraint);
+ break;
+ }
+ }
+
+ void checkLiveMembers(
+ Enqueuer enqueuer,
+ ElementEnvironment elementEnvironment,
+ Map<String, List<String>> expectedLiveMap) {
+ Map<String, List<String>> actualLiveMap = {};
+ for (MemberEntity member in enqueuer.processedEntities) {
+ if (member != elementEnvironment.mainFunction &&
+ member.library == elementEnvironment.mainLibrary) {
+ actualLiveMap
+ .putIfAbsent(member.enclosingClass.name, () => [])
+ .add(member.name);
+ }
+ }
+
+ Expect.setEquals(
+ expectedLiveMap.keys,
+ actualLiveMap.keys,
+ "Unexpected live classes in $enqueuer\n "
+ "Expected: ${expectedLiveMap.keys}\n "
+ "Actual : ${actualLiveMap.keys}");
+ expectedLiveMap.forEach((String clsName, List<String> expectedMembers) {
+ List<String> actualMembers = actualLiveMap[clsName];
+ Expect.setEquals(
+ expectedMembers,
+ actualMembers,
+ "Unexpected live members for $clsName in $enqueuer\n "
+ "Expected: $expectedMembers\n "
+ "Actual : $actualMembers");
+ });
+ }
+
+ compiler.onResolutionQueueEmptyForTesting = () {
+ Enqueuer enqueuer = compiler.enqueuer.resolution;
+ ElementEnvironment elementEnvironment =
+ compiler.frontendStrategy.elementEnvironment;
+ checkInvariant(enqueuer, elementEnvironment);
+
+ ReceiverConstraint createConstraint(ClassEntity cls) {
+ return new StrongModeConstraint(cls);
+ }
+
+ for (Impact impact in impacts) {
+ applyImpact(enqueuer, elementEnvironment, impact, createConstraint);
+ }
+ };
+ compiler.onCodegenQueueEmptyForTesting = () {
+ Enqueuer enqueuer = compiler.enqueuer.codegenEnqueuerForTesting;
+ ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+ ElementEnvironment elementEnvironment =
+ compiler.backendClosedWorldForTesting.elementEnvironment;
+ checkInvariant(enqueuer, elementEnvironment);
+
+ ReceiverConstraint createConstraint(ClassEntity cls) {
+ return new TypeMask.subtype(cls, closedWorld);
+ }
+
+ for (Impact impact in impacts) {
+ applyImpact(enqueuer, elementEnvironment, impact, createConstraint);
+ }
+ };
+
+ await compiler.run(Uri.parse('memory:main.dart'));
+
+ checkLiveMembers(
+ compiler.enqueuer.resolution,
+ compiler.frontendStrategy.elementEnvironment,
+ test.expectedLiveResolutionMap);
+
+ checkLiveMembers(
+ compiler.enqueuer.codegenEnqueuerForTesting,
+ compiler.backendClosedWorldForTesting.elementEnvironment,
+ test.expectedLiveCodegenMap);
+}
diff --git a/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
new file mode 100644
index 0000000..fa652b4
--- /dev/null
+++ b/tests/compiler/dart2js/model/strong_mode_closed_world_test.dart
@@ -0,0 +1,194 @@
+// 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:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/common_elements.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/universe/world_builder.dart';
+import 'package:compiler/src/world.dart';
+import '../memory_compiler.dart';
+
+main() {
+ useStrongModeWorldStrategy = true;
+ asyncTest(() async {
+ print('--test from non-strong mode---------------------------------------');
+ await runTest(strongMode: false);
+ print('--test from strong mode-------------------------------------------');
+ await runTest(strongMode: true);
+ });
+}
+
+runTest({bool strongMode}) async {
+ CompilationResult result = await runCompiler(memorySourceFiles: {
+ 'main.dart': '''
+class A {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class B {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class C extends A {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class D implements B {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class E implements A {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class F extends B {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class G {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class H extends Object with G implements A {}
+
+class I {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class J extends I implements A {}
+
+class K {
+ method1() {}
+ method2() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class L = Object with K;
+class L2 = Object with L;
+class M extends L {}
+class M2 extends L2 {}
+
+class N {
+ method1() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+abstract class O extends N {}
+
+class P implements O {
+ method1() {}
+ get getter => 42;
+ set setter(_) {}
+}
+
+class Q {
+ method3() {}
+}
+
+class R extends Q {}
+
+main() {
+ A a = new A();
+ B b = new B();
+ a.method1();
+ a.getter;
+ b.method2();
+ b.setter = 42;
+ new C();
+ new D();
+ new H();
+ new J();
+ new M().method1();
+ new M2().getter;
+ new N();
+ O o = new P();
+ o.method1();
+ o.getter;
+ o.setter = 42;
+ R r;
+ r.method3();
+ r = new R(); // Create R after call.
+}
+'''
+ }, options: strongMode ? [Flags.strongMode] : []);
+ Expect.isTrue(result.isSuccess);
+ Compiler compiler = result.compiler;
+
+ Map<String, List<String>> expectedLiveMembersMap = <String, List<String>>{
+ 'A': strongMode
+ ? ['method1', 'getter']
+ : ['method1', 'method2', 'getter', 'setter'],
+ 'B': strongMode
+ ? ['method2', 'setter']
+ : ['method1', 'method2', 'getter', 'setter'],
+ 'C': strongMode
+ ? ['method1', 'getter']
+ : ['method1', 'method2', 'getter', 'setter'],
+ 'D': strongMode
+ ? ['method2', 'setter']
+ : ['method1', 'method2', 'getter', 'setter'],
+ 'G': strongMode
+ ? ['method1', 'getter']
+ : ['method1', 'method2', 'getter', 'setter'],
+ 'I': strongMode
+ ? ['method1', 'getter']
+ : ['method1', 'method2', 'getter', 'setter'],
+ 'K': strongMode
+ ? ['method1', 'getter']
+ : ['method1', 'method2', 'getter', 'setter'],
+ 'N': strongMode ? [] : ['method1', 'getter', 'setter'],
+ 'P': ['method1', 'getter', 'setter'],
+ 'Q': ['method3'],
+ };
+
+ ClosedWorld closedWorld =
+ compiler.resolutionWorldBuilder.closedWorldForTesting;
+ ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
+
+ elementEnvironment.forEachClass(elementEnvironment.mainLibrary,
+ (ClassEntity cls) {
+ List<String> expectedLiveMembers =
+ expectedLiveMembersMap[cls.name] ?? const <String>[];
+ elementEnvironment.forEachLocalClassMember(cls, (MemberEntity member) {
+ if (member.enclosingClass != cls) return;
+ bool expected = expectedLiveMembers.contains(member.name);
+ bool live = closedWorld.processedMembers.contains(member);
+ Expect.equals(
+ expected,
+ live,
+ "Member $member ${expected ? '' : 'not '}expected to be live "
+ "in ${strongMode ? 'Dart 2' : 'Dart 1'}. "
+ "Expected members for ${cls.name}: $expectedLiveMembers");
+ });
+ });
+}
diff --git a/tests/compiler/dart2js/model/subtype_test.dart b/tests/compiler/dart2js/model/subtype_test.dart
index d54572c..48445e3 100644
--- a/tests/compiler/dart2js/model/subtype_test.dart
+++ b/tests/compiler/dart2js/model/subtype_test.dart
@@ -42,6 +42,10 @@
if (expectMoreSpecific == null) expectMoreSpecific = expectSubtype;
Expect.equals(expectSubtype, env.isSubtype(subtype, supertype),
'$subtype <: $supertype');
+ if (expectSubtype) {
+ Expect.isTrue(env.isPotentialSubtype(subtype, supertype),
+ '$subtype <: $supertype (potential)');
+ }
if (env.types is Types) {
Expect.equals(expectMoreSpecific, env.isMoreSpecific(subtype, supertype),
'$subtype << $supertype');
@@ -828,6 +832,9 @@
options: strongMode ? [Flags.strongMode] : []).then((env) {
void expect(bool expectSubtype, DartType T, DartType S) {
Expect.equals(expectSubtype, env.isSubtype(T, S), '$T <: $S');
+ if (expectSubtype) {
+ Expect.isTrue(env.isPotentialSubtype(T, S), '$T <: $S (potential)');
+ }
}
InterfaceType ClassWithCall = env['ClassWithCall'];
diff --git a/tests/compiler/dart2js/model/subtypeset_test.dart b/tests/compiler/dart2js/model/subtypeset_test.dart
index 10cef63..cbaf315 100644
--- a/tests/compiler/dart2js/model/subtypeset_test.dart
+++ b/tests/compiler/dart2js/model/subtypeset_test.dart
@@ -42,8 +42,8 @@
class E extends C implements B {}
class F extends C {}
class G extends C {}
- class H implements C {}
- class I implements H {}
+ abstract class H implements C {}
+ abstract class I implements H {}
""",
mainSource: r"""
main() {
diff --git a/tests/compiler/dart2js/rti/data/closure_generic_unneeded_strong.dart b/tests/compiler/dart2js/rti/data/closure_generic_unneeded_strong.dart
index b3b1ef3..5e985bd 100644
--- a/tests/compiler/dart2js/rti/data/closure_generic_unneeded_strong.dart
+++ b/tests/compiler/dart2js/rti/data/closure_generic_unneeded_strong.dart
@@ -4,11 +4,11 @@
import 'package:expect/expect.dart';
-/*class: A:needsArgs*/
+/*class: A:*/
class A<T> {
@NoInline()
m() {
- return /*needsSignature*/ (T t, String s) {};
+ return /**/ (T t, String s) {};
}
}
diff --git a/tests/compiler/dart2js/rti/data/closure_unneeded.dart b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
index 5ba4637..5e985bd 100644
--- a/tests/compiler/dart2js/rti/data/closure_unneeded.dart
+++ b/tests/compiler/dart2js/rti/data/closure_unneeded.dart
@@ -4,14 +4,11 @@
import 'package:expect/expect.dart';
-/*ast.class: A:*/
-/*kernel.class: A:*/
-/*strong.class: A:needsArgs*/
+/*class: A:*/
class A<T> {
@NoInline()
m() {
- // TODO(johnniwinther): Optimize local function type signature need.
- return /*ast.*/ /*kernel.*/ /*strong.needsSignature*/ (T t, String s) {};
+ return /**/ (T t, String s) {};
}
}
diff --git a/tests/compiler/dart2js/rti/data/closure_unneeded_strong.dart b/tests/compiler/dart2js/rti/data/closure_unneeded_strong.dart
index 34d26df..ad98d37 100644
--- a/tests/compiler/dart2js/rti/data/closure_unneeded_strong.dart
+++ b/tests/compiler/dart2js/rti/data/closure_unneeded_strong.dart
@@ -8,7 +8,7 @@
class A<T> {
@NoInline()
m() {
- return /*needsSignature*/ (int i, String s) {};
+ return /**/ (int i, String s) {};
}
}
diff --git a/tests/compiler/dart2js/rti/data/local_function_generic_strong.dart b/tests/compiler/dart2js/rti/data/local_function_generic_strong.dart
new file mode 100644
index 0000000..71a9566
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/local_function_generic_strong.dart
@@ -0,0 +1,18 @@
+// 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';
+
+method1() {
+ /*needsSignature*/
+ T local<T>(T t) => t;
+ return local;
+}
+
+@NoInline()
+test(o) => o is S Function<S>(S);
+
+main() {
+ Expect.isTrue(test(method1()));
+}
diff --git a/tests/compiler/dart2js/rti/data/local_function_list_literal_strong.dart b/tests/compiler/dart2js/rti/data/local_function_list_literal_strong.dart
new file mode 100644
index 0000000..40f4aa7
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/local_function_list_literal_strong.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.
+
+import 'package:expect/expect.dart';
+
+/*class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SubListIterable],explicit=[JSArray],needsArgs*/
+
+/*element: method:needsArgs*/
+@NoInline()
+method<T>() {
+ return () => <T>[];
+}
+
+@NoInline()
+test(o) => o is List<int>;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isFalse(test(method<String>().call()));
+}
diff --git a/tests/compiler/dart2js/rti/data/local_function_map_literal_strong.dart b/tests/compiler/dart2js/rti/data/local_function_map_literal_strong.dart
new file mode 100644
index 0000000..d0d805a
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/local_function_map_literal_strong.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.
+
+import 'package:expect/expect.dart';
+
+/*class: global#LinkedHashMap:deps=[Map],needsArgs*/
+
+/*element: method:needsArgs*/
+@NoInline()
+method<T>() {
+ return () => <T, int>{};
+}
+
+@NoInline()
+test(o) => o is Map<int, int>;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isFalse(test(method<String>().call()));
+}
diff --git a/tests/compiler/dart2js/rti/data/local_function_signature2_strong.dart b/tests/compiler/dart2js/rti/data/local_function_signature2_strong.dart
new file mode 100644
index 0000000..a5dd390c
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/local_function_signature2_strong.dart
@@ -0,0 +1,109 @@
+// 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';
+
+class Class1 {
+ method1() {
+ /**/
+ num local<T>(num n) => null;
+ return local;
+ }
+
+ method2() {
+ /**/
+ num local<T>(int n) => null;
+ return local;
+ }
+
+ method3() {
+ /**/
+ int local<T>(num n) => null;
+ return local;
+ }
+}
+
+class Class2 {
+ /*element: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ method4<T>() {
+ /*needsSignature*/
+ num local(T n) => null;
+ return local;
+ }
+}
+
+class Class3 {
+ /*element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+ method5<T>() {
+ /*needsSignature*/
+ T local(num n) => null;
+ return local;
+ }
+}
+
+class Class4 {
+ /*element: Class4.method6:*/
+ method6<T>() {
+ /**/
+ num local(num n, T t) => null;
+ return local;
+ }
+}
+
+/*element: method7:needsArgs*/
+method7<T>() {
+ /*needsSignature*/
+ num local(T n) => null;
+ return local;
+}
+
+/*element: method8:needsArgs*/
+method8<T>() {
+ /*needsSignature*/
+ T local(num n) => null;
+ return local;
+}
+
+/*element: method9:*/
+method9<T>() {
+ /**/
+ num local(num n, T t) => null;
+ return local;
+}
+
+method10() {
+ /**/
+ num local<T>(T n) => null;
+ return local;
+}
+
+method11() {
+ /**/
+ T local<T>(num n) => null;
+ return local;
+}
+
+method12() {
+ /**/
+ num local<T>(num n, T t) => null;
+ return local;
+}
+
+@NoInline()
+test(o) => o is num Function(num);
+
+main() {
+ Expect.isFalse(test(new Class1().method1()));
+ Expect.isFalse(test(new Class1().method2()));
+ Expect.isFalse(test(new Class1().method3()));
+ Expect.isTrue(test(new Class2().method4<num>()));
+ Expect.isTrue(test(new Class3().method5<num>()));
+ Expect.isFalse(test(new Class4().method6<num>()));
+ Expect.isTrue(test(method7<num>()));
+ Expect.isTrue(test(method8<num>()));
+ Expect.isFalse(test(method9()));
+ Expect.isFalse(test(method10()));
+ Expect.isFalse(test(method11()));
+ Expect.isFalse(test(method12()));
+}
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures.dart b/tests/compiler/dart2js/rti/data/local_function_signatures.dart
new file mode 100644
index 0000000..cc7bc3d
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures.dart
@@ -0,0 +1,64 @@
+// 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';
+
+class Class1 {
+ method1() {
+ /*ast.*/
+ /*kernel.*/
+ /*strong.needsSignature*/
+ num local(num n) => null;
+ return local;
+ }
+
+ method2() {
+ num local(int n) => null;
+ return local;
+ }
+
+ method3() {
+ Object local(num n) => null;
+ return local;
+ }
+}
+
+/*class: Class2:needsArgs*/
+class Class2<T> {
+ method4() {
+ /*needsSignature*/
+ num local(T n) => null;
+ return local;
+ }
+}
+
+/*class: Class3:needsArgs*/
+class Class3<T> {
+ method5() {
+ /*needsSignature*/
+ T local(num n) => null;
+ return local;
+ }
+}
+
+/*class: Class4:*/
+class Class4<T> {
+ method6() {
+ /**/
+ num local(num n, T t) => null;
+ return local;
+ }
+}
+
+@NoInline()
+test(o) => o is num Function(num);
+
+main() {
+ Expect.isTrue(test(new Class1().method1()));
+ Expect.isFalse(test(new Class1().method2()));
+ Expect.isFalse(test(new Class1().method3()));
+ Expect.isTrue(test(new Class2<num>().method4()));
+ Expect.isTrue(test(new Class3<num>().method5()));
+ Expect.isFalse(test(new Class4<num>().method6()));
+}
diff --git a/tests/compiler/dart2js/rti/data/local_function_signatures_strong.dart b/tests/compiler/dart2js/rti/data/local_function_signatures_strong.dart
new file mode 100644
index 0000000..71f5374
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/local_function_signatures_strong.dart
@@ -0,0 +1,130 @@
+// 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';
+
+class Class1 {
+ method1() {
+ /*needsSignature*/
+ num local<T>(num n) => null;
+ return local;
+ }
+
+ method2() {
+ /**/
+ num local<T>(int n) => null;
+ return local;
+ }
+
+ method3() {
+ /*needsSignature*/
+ int local<T>(num n) => null;
+ return local;
+ }
+}
+
+class Class2 {
+ /*element: Class2.method4:needsArgs,selectors=[Selector(call, method4, arity=0, types=1)]*/
+ method4<T>() {
+ /*needsSignature*/
+ num local(T n) => null;
+ return local;
+ }
+}
+
+class Class3 {
+ /*element: Class3.method5:needsArgs,selectors=[Selector(call, method5, arity=0, types=1)]*/
+ method5<T>() {
+ /*needsSignature*/
+ T local(num n) => null;
+ return local;
+ }
+}
+
+class Class4 {
+ /*element: Class4.method6:*/
+ method6<T>() {
+ /**/
+ num local(num n, T t) => null;
+ return local;
+ }
+}
+
+/*element: method7:needsArgs*/
+method7<T>() {
+ /*needsSignature*/
+ num local(T n) => null;
+ return local;
+}
+
+/*element: method8:needsArgs*/
+method8<T>() {
+ /*needsSignature*/
+ T local(num n) => null;
+ return local;
+}
+
+/*element: method9:*/
+method9<T>() {
+ /**/
+ num local(num n, T t) => null;
+ return local;
+}
+
+method10() {
+ /*needsSignature*/
+ num local<T>(T n) => null;
+ return local;
+}
+
+method11() {
+ /*needsSignature*/
+ T local<T>(num n) => null;
+ return local;
+}
+
+method12() {
+ /**/
+ num local<T>(num n, T t) => null;
+ return local;
+}
+
+num Function(num) method13() {
+ /*needsSignature*/
+ num local<T>(num n) => null;
+ return local;
+}
+
+num Function(num) method14() {
+ /*needsSignature*/
+ num local<T>(T n) => null;
+ return local;
+}
+
+num Function(num) method15() {
+ /*needsSignature*/
+ T local<T>(num n) => null;
+ return local;
+}
+
+@NoInline()
+test(o) => o is num Function(num);
+
+main() {
+ Expect.isFalse(test(new Class1().method1()));
+ Expect.isFalse(test(new Class1().method2()));
+ Expect.isFalse(test(new Class1().method3()));
+ Expect.isTrue(test(new Class2().method4<num>()));
+ Expect.isTrue(test(new Class3().method5<num>()));
+ Expect.isFalse(test(new Class4().method6<num>()));
+ Expect.isTrue(test(method7<num>()));
+ Expect.isTrue(test(method8<num>()));
+ Expect.isFalse(test(method9()));
+ Expect.isFalse(test(method10()));
+ Expect.isFalse(test(method11()));
+ Expect.isFalse(test(method12()));
+ Expect.isTrue(test(method13()));
+ Expect.isTrue(test(method14()));
+ Expect.isTrue(test(method15()));
+}
diff --git a/tests/compiler/dart2js/rti/data/method_signatures.dart b/tests/compiler/dart2js/rti/data/method_signatures.dart
new file mode 100644
index 0000000..4c4a161
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/method_signatures.dart
@@ -0,0 +1,58 @@
+// 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';
+
+class Class1 {
+ /*element: Class1.method1:*/
+ num method1(num n) => null;
+
+ /*element: Class1.method2:*/
+ num method2(int n) => null;
+
+ /*element: Class1.method3:*/
+ Object method3(num n) => null;
+}
+
+/*class: Class2:needsArgs*/
+class Class2<T> {
+ /*element: Class2.method4:needsSignature*/
+ num method4(T n) => null;
+}
+
+/*class: Class3:needsArgs*/
+class Class3<T> {
+ /*element: Class3.method5:needsSignature*/
+ T method5(num n) => null;
+}
+
+/*class: Class4:*/
+class Class4<T> {
+ /*element: Class4.method6:*/
+ num method6(num n, T t) => null;
+}
+
+/*element: method7:*/
+num method7(num n) => null;
+
+/*element: method8:*/
+num method8(int n) => null;
+
+/*element: method9:*/
+Object method9(num n) => null;
+
+@NoInline()
+test(o) => o is num Function(num);
+
+main() {
+ Expect.isTrue(test(new Class1().method1));
+ Expect.isFalse(test(new Class1().method2));
+ Expect.isFalse(test(new Class1().method3));
+ Expect.isTrue(test(new Class2<num>().method4));
+ Expect.isTrue(test(new Class3<num>().method5));
+ Expect.isFalse(test(new Class4<num>().method6));
+ Expect.isTrue(test(method7));
+ Expect.isFalse(test(method8));
+ Expect.isFalse(test(method9));
+}
diff --git a/tests/compiler/dart2js/rti/data/method_signatures_strong.dart b/tests/compiler/dart2js/rti/data/method_signatures_strong.dart
new file mode 100644
index 0000000..811548f
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/method_signatures_strong.dart
@@ -0,0 +1,57 @@
+// 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';
+
+class Class1 {
+ /*element: Class1.method1:*/
+ num method1<T>(num n) => null;
+
+ /*element: Class1.method2:*/
+ num method2<T>(int n) => null;
+
+ /*element: Class1.method3:*/
+ int method3<T>(num n) => null;
+}
+
+class Class2 {
+ /*element: Class2.method4:*/
+ num method4<T>(T n) => null;
+}
+
+class Class3 {
+ /*element: Class3.method5:*/
+ T method5<T>(num n) => null;
+}
+
+class Class4 {
+ /*element: Class4.method6:*/
+ num method6<T>(num n, T t) => null;
+}
+
+/*element: method7:*/
+num method7<T>(T n) => null;
+
+/*element: method8:*/
+T method8<T>(num n) => null;
+
+/*element: method9:*/
+num method9<T>(num n, T t) => null;
+
+@NoInline()
+test(o) => o is num Function(num);
+
+forceInstantiation(num Function(num) f) => f;
+
+main() {
+ Expect.isFalse(test(new Class1().method1));
+ Expect.isFalse(test(new Class1().method2));
+ Expect.isFalse(test(new Class1().method3));
+ Expect.isTrue(test(forceInstantiation(new Class2().method4)));
+ Expect.isTrue(test(forceInstantiation(new Class3().method5)));
+ Expect.isFalse(test(new Class4().method6));
+ Expect.isTrue(test(forceInstantiation(method7)));
+ Expect.isTrue(test(forceInstantiation(method8)));
+ Expect.isFalse(test(method9));
+}
diff --git a/tests/compiler/dart2js/rti/emission/closure_function.dart b/tests/compiler/dart2js/rti/emission/closure_function.dart
index 2b51d64..099dee0 100644
--- a/tests/compiler/dart2js/rti/emission/closure_function.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_function.dart
@@ -8,6 +8,9 @@
test(o) => o is Function;
main() {
- test(/*checks=[],functionType,instance*/ () {});
+ test(
+ /*ast.checks=[],functionType,instance*/
+ /*kernel.checks=[],functionType,instance*/
+ /*strong.checks=[],instance*/ () {});
test(null);
}
diff --git a/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart b/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
index c205496..ac72186 100644
--- a/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
+++ b/tests/compiler/dart2js/rti/emission/closure_signature_unneeded.dart
@@ -10,7 +10,11 @@
m() {
// TODO(johnniwinther): The signature is not needed since the type isn't a
// potential subtype of the checked function types.
- return /*checks=[$signature],instance*/ (T t, String s) {};
+ return
+ /*ast.checks=[$signature],instance*/
+ /*kernel.checks=[$signature],instance*/
+ /*strong.checks=[],instance*/
+ (T t, String s) {};
}
}
diff --git a/tests/compiler/dart2js/rti/emission/local_function_list_literal_strong.dart b/tests/compiler/dart2js/rti/emission/local_function_list_literal_strong.dart
new file mode 100644
index 0000000..f3ac8a5
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/local_function_list_literal_strong.dart
@@ -0,0 +1,20 @@
+// 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';
+
+/*class: global#JSArray:checkedInstance,checks=[$isIterable,$isList],instance*/
+
+@NoInline()
+method<T>() {
+ return /*checks=[],instance*/ () => <T>[];
+}
+
+@NoInline()
+test(o) => o is List<int>;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isFalse(test(method<String>().call()));
+}
diff --git a/tests/compiler/dart2js/rti/emission/local_function_map_literal_strong.dart b/tests/compiler/dart2js/rti/emission/local_function_map_literal_strong.dart
new file mode 100644
index 0000000..fefa55b
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/local_function_map_literal_strong.dart
@@ -0,0 +1,22 @@
+// 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';
+
+/*class: global#JsLinkedHashMap:checks=[],instance*/
+
+@NoInline()
+method<T>() {
+ return
+ /*checks=[],instance*/
+ () => <T, int>{};
+}
+
+@NoInline()
+test(o) => o is Map<int, int>;
+
+main() {
+ Expect.isTrue(test(method<int>().call()));
+ Expect.isFalse(test(method<String>().call()));
+}
diff --git a/tests/compiler/dart2js/rti/factory_call_test.dart b/tests/compiler/dart2js/rti/factory_call_test.dart
index d3632ae..9d3f08f 100644
--- a/tests/compiler/dart2js/rti/factory_call_test.dart
+++ b/tests/compiler/dart2js/rti/factory_call_test.dart
@@ -83,7 +83,7 @@
js.Name selector = getName(targetName);
bool callFound = false;
- forEachCall(fun, (js.Call node) {
+ forEachNode(fun, onCall: (js.Call node) {
js.Expression target = node.target;
if (target is js.PropertyAccess && target.selector == selector) {
callFound = true;
diff --git a/tests/compiler/dart2js/rti/instance_call_test.dart b/tests/compiler/dart2js/rti/instance_call_test.dart
index 1b656ed..337bae0 100644
--- a/tests/compiler/dart2js/rti/instance_call_test.dart
+++ b/tests/compiler/dart2js/rti/instance_call_test.dart
@@ -152,7 +152,7 @@
js.Name selector = getName(targetName, expectedTypeArguments);
bool callFound = false;
- forEachCall(fun, (js.Call node) {
+ forEachNode(fun, onCall: (js.Call node) {
js.Expression target = node.target;
if (target is js.PropertyAccess && target.selector == selector) {
callFound = true;
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index ee2a76a..95e82a0 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -263,6 +263,10 @@
return types.isSubtype(T, S);
}
+ bool isPotentialSubtype(DartType T, DartType S) {
+ return types.isPotentialSubtype(T, S);
+ }
+
bool isMoreSpecific(ResolutionDartType T, ResolutionDartType S) {
return (types as Types).isMoreSpecific(T, S);
}
diff --git a/tests/compiler/dart2js_extra/32928_test.dart b/tests/compiler/dart2js_extra/32928_test.dart
new file mode 100644
index 0000000..549909b
--- /dev/null
+++ b/tests/compiler/dart2js_extra/32928_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+/// Regression test for issue 32928.
+
+abstract class A<T> {
+ set f(T value) {
+ print(value);
+ }
+}
+
+abstract class B extends A {}
+
+class C extends B {
+ m(value) => super.f = value;
+}
+
+main() {
+ new C().m(null);
+}
diff --git a/tests/compiler/dart2js_extra/local_function_generic_strong_test.dart b/tests/compiler/dart2js_extra/local_function_generic_strong_test.dart
new file mode 100644
index 0000000..c7d3ec5
--- /dev/null
+++ b/tests/compiler/dart2js_extra/local_function_generic_strong_test.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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+method1() {
+ T local<T>(T t) => t;
+ return local;
+}
+
+@NoInline()
+test(o) => o is S Function<S>(S);
+
+main() {
+ Expect.isTrue(test(method1()));
+}
diff --git a/tests/compiler/dart2js_extra/local_function_signatures_strong_test.dart b/tests/compiler/dart2js_extra/local_function_signatures_strong_test.dart
new file mode 100644
index 0000000..d6f4f31
--- /dev/null
+++ b/tests/compiler/dart2js_extra/local_function_signatures_strong_test.dart
@@ -0,0 +1,114 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+ method1() {
+ num local<T>(num n) => null;
+ return local;
+ }
+
+ method2() {
+ num local<T>(int n) => null;
+ return local;
+ }
+
+ method3() {
+ int local<T>(num n) => null;
+ return local;
+ }
+}
+
+class Class2 {
+ method4<T>() {
+ num local(T n) => null;
+ return local;
+ }
+}
+
+class Class3 {
+ method5<T>() {
+ T local(num n) => null;
+ return local;
+ }
+}
+
+class Class4 {
+ method6<T>() {
+ num local(num n, T t) => null;
+ return local;
+ }
+}
+
+method7<T>() {
+ num local(T n) => null;
+ return local;
+}
+
+method8<T>() {
+ T local(num n) => null;
+ return local;
+}
+
+method9<T>() {
+ num local(num n, T t) => null;
+ return local;
+}
+
+method10() {
+ num local<T>(T n) => null;
+ return local;
+}
+
+method11() {
+ T local<T>(num n) => null;
+ return local;
+}
+
+method12() {
+ num local<T>(num n, T t) => null;
+ return local;
+}
+
+num Function(num) //# 01: ok
+ method13() {
+ num local<T>(num n) => null;
+ return local;
+}
+
+num Function(num) //# 01: continued
+ method14() {
+ num local<T>(T n) => null;
+ return local;
+}
+
+num Function(num) //# 01: continued
+ method15() {
+ T local<T>(num n) => null;
+ return local;
+}
+
+@NoInline()
+test(o) => o is num Function(num);
+
+main() {
+ Expect.isFalse(test(new Class1().method1()));
+ Expect.isFalse(test(new Class1().method2()));
+ Expect.isFalse(test(new Class1().method3()));
+ Expect.isTrue(test(new Class2().method4<num>()));
+ Expect.isTrue(test(new Class3().method5<num>()));
+ Expect.isFalse(test(new Class4().method6<num>()));
+ Expect.isTrue(test(method7<num>()));
+ Expect.isTrue(test(method8<num>()));
+ Expect.isFalse(test(method9()));
+ Expect.isFalse(test(method10()));
+ Expect.isFalse(test(method11()));
+ Expect.isFalse(test(method12()));
+ Expect.isTrue(test(method13())); //# 01: continued
+ Expect.isTrue(test(method14())); //# 01: continued
+ Expect.isTrue(test(method15())); //# 01: continued
+}
diff --git a/tests/compiler/dart2js_extra/local_function_signatures_test.dart b/tests/compiler/dart2js_extra/local_function_signatures_test.dart
new file mode 100644
index 0000000..76ce246e
--- /dev/null
+++ b/tests/compiler/dart2js_extra/local_function_signatures_test.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+ method1() {
+ num local(num n) => null;
+ return local;
+ }
+
+ method2() {
+ num local(int n) => null;
+ return local;
+ }
+
+ method3() {
+ Object local(num n) => null;
+ return local;
+ }
+}
+
+class Class2<T> {
+ method4() {
+ num local(T n) => null;
+ return local;
+ }
+}
+
+class Class3<T> {
+ method5() {
+ T local(num n) => null;
+ return local;
+ }
+}
+
+class Class4<T> {
+ method6() {
+ num local(num n, T t) => null;
+ return local;
+ }
+}
+
+@NoInline()
+test(o) => o is num Function(num);
+
+main() {
+ Expect.isTrue(test(new Class1().method1()));
+ Expect.isFalse(test(new Class1().method2()));
+ Expect.isFalse(test(new Class1().method3()));
+ Expect.isTrue(test(new Class2<num>().method4()));
+ Expect.isTrue(test(new Class3<num>().method5()));
+ Expect.isFalse(test(new Class4<num>().method6()));
+}
diff --git a/tests/compiler/dart2js_extra/method_signatures_strong_test.dart b/tests/compiler/dart2js_extra/method_signatures_strong_test.dart
new file mode 100644
index 0000000..d23ed34
--- /dev/null
+++ b/tests/compiler/dart2js_extra/method_signatures_strong_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+ num method1<T>(num n) => null;
+
+ num method2<T>(int n) => null;
+
+ int method3<T>(num n) => null;
+}
+
+class Class2 {
+ num method4<T>(T n) => null;
+}
+
+class Class3 {
+ T method5<T>(num n) => null;
+}
+
+class Class4 {
+ num method6<T>(num n, T t) => null;
+}
+
+num method7<T>(T n) => null;
+
+T method8<T>(num n) => null;
+
+num method9<T>(num n, T t) => null;
+
+@NoInline()
+test(o) => o is num Function(num);
+
+forceInstantiation(num Function(num) f) => f;
+
+main() {
+ Expect.isFalse(test(new Class1().method1));
+ Expect.isFalse(test(new Class1().method2));
+ Expect.isFalse(test(new Class1().method3));
+ Expect.isTrue(test(forceInstantiation(new Class2().method4)));
+ Expect.isTrue(test(forceInstantiation(new Class3().method5)));
+ Expect.isFalse(test(new Class4().method6));
+ Expect.isTrue(test(forceInstantiation(method7)));
+ Expect.isTrue(test(forceInstantiation(method8)));
+ Expect.isFalse(test(method9));
+}
diff --git a/tests/compiler/dart2js_extra/method_signatures_test.dart b/tests/compiler/dart2js_extra/method_signatures_test.dart
new file mode 100644
index 0000000..569b329
--- /dev/null
+++ b/tests/compiler/dart2js_extra/method_signatures_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+ num method1(num n) => null;
+
+ num method2(int n) => null;
+
+ Object method3(num n) => null;
+}
+
+class Class2<T> {
+ num method4(T n) => null;
+}
+
+class Class3<T> {
+ T method5(num n) => null;
+}
+
+class Class4<T> {
+ num method6(num n, T t) => null;
+}
+
+num method7(num n) => null;
+
+num method8(int n) => null;
+
+Object method9(num n) => null;
+
+@NoInline()
+test(o) => o is num Function(num);
+
+main() {
+ Expect.isTrue(test(new Class1().method1));
+ Expect.isFalse(test(new Class1().method2));
+ Expect.isFalse(test(new Class1().method3));
+ Expect.isTrue(test(new Class2<num>().method4));
+ Expect.isTrue(test(new Class3<num>().method5));
+ Expect.isFalse(test(new Class4<num>().method6));
+ Expect.isTrue(test(method7));
+ Expect.isFalse(test(method8));
+ Expect.isFalse(test(method9));
+}
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 4b626c0..ce101ae 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -161,6 +161,7 @@
[ $compiler == dart2js && $checked && $fasta && $strong ]
apply3_test: RuntimeError
+collection_of_test: RuntimeError
error_stack_trace1_test: RuntimeError # Issue 12399
from_environment_const_type_test/02: MissingCompileTimeError
from_environment_const_type_test/03: MissingCompileTimeError
@@ -195,15 +196,24 @@
dynamic_nosuchmethod_test: Fail # mirrors not supported
[ $compiler == dart2js && $fast_startup && $fasta && $strong ]
-iterable_return_type_test/01: RuntimeError # Issue 20085
+cast_test: RuntimeError
+error_stack_trace1_test: RuntimeError
+growable_list_test: RuntimeError
+int_parse_radix_test/01: RuntimeError
+int_parse_radix_test/02: RuntimeError
+integer_to_radix_string_test/01: RuntimeError
+integer_to_radix_string_test/02: RuntimeError
+integer_to_radix_string_test/none: RuntimeError
+integer_to_string_test/01: RuntimeError
iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
-iterable_to_list_test/01: Crash # Wrong number of template arguments, given 2, expected 1
-iterable_to_list_test/none: Crash # Wrong number of template arguments, given 2, expected 1
-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.
+list_concurrent_modify_test: RuntimeError
+main_test: RuntimeError
+nan_infinity_test/01: RuntimeError
+string_split_test/checkedstore: RuntimeError
symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
uri_base_test: Crash # RangeError (index): Invalid value: Valid value range is empty: 0
+uri_parameters_all_test: RuntimeError
+uri_test: RuntimeError
[ $compiler == dart2js && $fasta ]
int_from_environment_test: Pass # Issue 31762
@@ -268,9 +278,6 @@
[ $compiler == dart2js && !$fasta ]
*: SkipByDesign
-[ $compiler == dart2js && $strong ]
-collection_of_test: RuntimeError
-
[ $compiler != dart2js && $compiler != dartdevc && $compiler != dartdevk && $compiler != dartk && $compiler != dartkp && $compiler != fasta ]
iterable_element_at_test/static: MissingCompileTimeError
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 80b93c7..0453fe4 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -87,7 +87,6 @@
assign_static_type_test/01: Fail
assign_static_type_test/02: MissingCompileTimeError
async_return_types_test/nestedFuture: Fail # Issue 26429
-async_return_types_test/wrongTypeParameter: Fail # Issue 26429
cha_deopt1_test: RuntimeError
cha_deopt2_test: RuntimeError
cha_deopt3_test: RuntimeError
diff --git a/tests/language_2/export1_lib.dart b/tests/language_2/export1_lib.dart
index 77768c1..3f7be5b 100644
--- a/tests/language_2/export1_lib.dart
+++ b/tests/language_2/export1_lib.dart
@@ -4,6 +4,6 @@
library export1_lib;
-export "dart:math" show LN10, LN2, E;
+export "dart:math" show ln10, ln2, e;
-var E = "E"; // Hides constant E from math lib.
+var e = "E"; // Hides constant E from math lib.
diff --git a/tests/language_2/function_type_alias6_test.dart b/tests/language_2/function_type_alias6_test.dart
index 47821da..4c5a5a6 100644
--- a/tests/language_2/function_type_alias6_test.dart
+++ b/tests/language_2/function_type_alias6_test.dart
@@ -21,7 +21,7 @@
var f = (List x) {};
Expect.isTrue(f is F);
var g = (List<F> x) {};
- Expect.isTrue(g is F);
+ Expect.isFalse(g is F);
var d = new D();
Expect.isTrue(d.foo is! C);
Expect.isTrue(d.bar is C);
diff --git a/tests/language_2/import_combinators_test.dart b/tests/language_2/import_combinators_test.dart
index ecb5c87..c2757e1 100644
--- a/tests/language_2/import_combinators_test.dart
+++ b/tests/language_2/import_combinators_test.dart
@@ -9,7 +9,7 @@
import "package:expect/expect.dart";
import "import1_lib.dart" show hide, show hide ugly;
import "export1_lib.dart";
-import "dart:math" as M show E;
+import "dart:math" as M show e;
part "import_combinators_part.dart";
@@ -19,9 +19,9 @@
// Top-level function from part, refers to imported variable show.
Expect.equals("show", lookBehindCurtain());
// Top-level variable E from export1_lib.dart.
- Expect.equals("E", E);
+ Expect.equals("E", e);
// Top-level variable E imported from dart:math.
- Expect.equals(2.718281828459045, M.E);
+ Expect.equals(2.718281828459045, M.e);
// Constant LN2 from math library, re-exported by export1_lib.dart.
- Expect.equals(0.6931471805599453, LN2);
+ Expect.equals(0.6931471805599453, ln2);
}
diff --git a/tests/language_2/instantiate_tearoff_test.dart b/tests/language_2/instantiate_tearoff_test.dart
index 1c50f7f..254949e 100644
--- a/tests/language_2/instantiate_tearoff_test.dart
+++ b/tests/language_2/instantiate_tearoff_test.dart
@@ -8,10 +8,9 @@
int intToInt(int x) => x;
String stringToString(String x) => x;
+String stringAndIntToString(String x, int y) => x;
-main() {
- int Function(int) intFunc = f;
- dynamic intFuncDynamic = intFunc;
+test(intFuncDynamic, stringFuncDynamic, dynamicFuncDynamic) {
Expect.isTrue(intFuncDynamic is int Function(int));
Expect.isFalse(intFuncDynamic is String Function(String));
Expect.equals(intFuncDynamic(1), 1);
@@ -22,8 +21,6 @@
Expect.throwsNoSuchMethodError(() {
intFuncDynamic<String>('oops');
});
- String Function(String) stringFunc = f;
- dynamic stringFuncDynamic = stringFunc;
Expect.isTrue(stringFuncDynamic is String Function(String));
Expect.isFalse(stringFuncDynamic is int Function(int));
Expect.equals(stringFuncDynamic('hello'), 'hello');
@@ -35,9 +32,33 @@
Expect.throwsNoSuchMethodError(() {
stringFuncDynamic<int>(1);
});
- dynamic Function(dynamic) dynamicFunc = f;
- dynamic dynamicFuncDynamic = dynamicFunc;
Expect.throwsNoSuchMethodError(() {
dynamicFuncDynamic<int>(1);
});
}
+
+main() {
+ int Function(int) if1 = f;
+ String Function(String) sf1 = f;
+ dynamic Function(dynamic) df1 = f;
+ test(if1, sf1, df1);
+
+ T local<T>(T x) => x;
+
+ int Function(int) if2 = local;
+ String Function(String) sf2 = local;
+ dynamic Function(dynamic) df2 = local;
+ test(if2, sf2, df2);
+
+ dynamic bar<X>() {
+ String foo<T>(X x, T t) {
+ return "$X, $T";
+ }
+
+ String Function(X, int) x = foo;
+ return x;
+ }
+ dynamic fn = bar<String>();
+ Expect.equals("${fn.runtimeType}", "${stringAndIntToString.runtimeType}");
+ Expect.equals(fn("a", 1), "String, int");
+}
diff --git a/tests/language_2/intrinsified_methods_test.dart b/tests/language_2/intrinsified_methods_test.dart
index 6e3401b..c321cf4 100644
--- a/tests/language_2/intrinsified_methods_test.dart
+++ b/tests/language_2/intrinsified_methods_test.dart
@@ -24,7 +24,7 @@
}
testTrigonometric() {
- Expect.approxEquals(1.0, sin(PI / 2.0), 0.0001);
+ Expect.approxEquals(1.0, sin(pi / 2.0), 0.0001);
Expect.approxEquals(1.0, cos(0), 0.0001);
Expect.approxEquals(1.0, cos(0.0), 0.0001);
}
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 0ed2de8..55a2708 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -140,7 +140,6 @@
switch4_negative_test: CompileTimeError
switch5_negative_test: CompileTimeError
switch7_negative_test: CompileTimeError
-syntax_test/none: Fail # Issue 11575
test_negative_test: CompileTimeError
try_catch_on_syntax_test/10: MissingCompileTimeError
try_catch_on_syntax_test/11: MissingCompileTimeError
@@ -520,26 +519,7 @@
optional_named_parameters_test/08: MissingCompileTimeError
optional_named_parameters_test/09: MissingCompileTimeError
override_field_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
-override_inheritance_abstract_test/28: MissingCompileTimeError
+override_inheritance_abstract_test/*: Skip # Tests Dart 2 semantics
override_inheritance_field_test/05: MissingCompileTimeError
override_inheritance_field_test/07: MissingCompileTimeError
override_inheritance_field_test/08: MissingCompileTimeError
@@ -590,7 +570,6 @@
override_inheritance_no_such_method_test/09: MissingCompileTimeError
override_inheritance_no_such_method_test/10: MissingCompileTimeError
override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
override_method_with_field_test/02: MissingCompileTimeError
parser_quirks_test: StaticWarning
part2_test/01: MissingCompileTimeError
@@ -984,26 +963,7 @@
optional_named_parameters_test/08: MissingCompileTimeError
optional_named_parameters_test/09: MissingCompileTimeError
override_field_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
-override_inheritance_abstract_test/28: MissingCompileTimeError
+override_inheritance_abstract_test/*: Skip # Tests Dart 2 semantics
override_inheritance_field_test/05: MissingCompileTimeError
override_inheritance_field_test/07: MissingCompileTimeError
override_inheritance_field_test/08: MissingCompileTimeError
@@ -1054,7 +1014,6 @@
override_inheritance_no_such_method_test/09: MissingCompileTimeError
override_inheritance_no_such_method_test/10: MissingCompileTimeError
override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
override_method_with_field_test/02: MissingCompileTimeError
parser_quirks_test: StaticWarning
part2_test/01: MissingCompileTimeError
@@ -1194,25 +1153,6 @@
multiple_interface_inheritance_test: CompileTimeError # Issue 30552
no_main_test/01: MissingStaticWarning # Issue 28823
no_such_method_negative_test: CompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
override_inheritance_field_test/04: CompileTimeError
override_inheritance_field_test/06: CompileTimeError
override_inheritance_field_test/26: CompileTimeError
@@ -1225,7 +1165,6 @@
override_inheritance_generic_test/02: CompileTimeError
override_inheritance_method_test/28: CompileTimeError
override_inheritance_method_test/29: CompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
parameter_initializer_test: CompileTimeError
parser_quirks_test: CompileTimeError
prefix13_negative_test: CompileTimeError, OK
@@ -1248,6 +1187,8 @@
super_bound_closure_test/none: CompileTimeError
super_setter_test: StaticWarning # Issue 28823
switch_case_test/none: CompileTimeError
+syntax_test/60: MissingCompileTimeError
+syntax_test/61: MissingCompileTimeError
type_promotion_functions_test/01: Pass
type_promotion_functions_test/05: Pass
type_promotion_functions_test/06: Pass
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 742853a..7d81932 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -73,7 +73,6 @@
function_subtype_call2_test: RuntimeError
function_subtype_cast1_test: RuntimeError
function_subtype_not1_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
function_type/function_type0_test: RuntimeError # Issue 30476
function_type/function_type10_test: RuntimeError # Issue 30476
function_type/function_type12_test: RuntimeError # Issue 30476
@@ -193,8 +192,6 @@
checked_method_error_order_test: RuntimeError
class_cycle_test/02: MissingCompileTimeError
class_cycle_test/03: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
compile_time_constant_o_test/01: MissingCompileTimeError
compile_time_constant_o_test/02: MissingCompileTimeError
conditional_method_invocation_test/05: MissingCompileTimeError
@@ -339,8 +336,6 @@
generic_closure_test/01: RuntimeError
generic_closure_test/none: RuntimeError
generic_function_dcall_test: Crash # Unsupported operation: Unsupported type parameter type node T.
-generic_function_typedef_test/01: RuntimeError
-generic_instanceof_test: RuntimeError
generic_tearoff_test: Crash # Unsupported operation: Unsupported type parameter type node T.
generic_typedef_test: RuntimeError
getter_override2_test/02: MissingCompileTimeError
@@ -371,7 +366,6 @@
list_literal_syntax_test/02: MissingCompileTimeError
list_literal_syntax_test/03: MissingCompileTimeError
malformed2_test/00: MissingCompileTimeError
-many_generic_instanceof_test: RuntimeError
map_literal1_test/01: MissingCompileTimeError
map_literal8_test: RuntimeError
method_override7_test/00: MissingCompileTimeError
@@ -525,12 +519,12 @@
switch_case_test/01: MissingCompileTimeError
switch_case_test/02: MissingCompileTimeError
symbol_literal_test/01: MissingCompileTimeError
-syntax_test/28: MissingCompileTimeError
-syntax_test/29: MissingCompileTimeError
-syntax_test/30: MissingCompileTimeError
-syntax_test/31: MissingCompileTimeError
-syntax_test/32: MissingCompileTimeError
-syntax_test/33: MissingCompileTimeError
+syntax_test/28: MissingCompileTimeError # Issue 29763
+syntax_test/29: MissingCompileTimeError # Issue 29763
+syntax_test/30: MissingCompileTimeError # Issue 29763
+syntax_test/31: MissingCompileTimeError # Issue 29763
+syntax_test/32: MissingCompileTimeError # Issue 29763
+syntax_test/33: MissingCompileTimeError # Issue 29763
tearoff_dynamic_test: RuntimeError
truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
try_catch_test/01: MissingCompileTimeError
@@ -560,8 +554,6 @@
issue31596_super_test/04: MissingCompileTimeError
issue31596_super_test/05: RuntimeError
issue31596_test: RuntimeError
-nsm5_test: MissingCompileTimeError
-override_inheritance_no_such_method_test/05: MissingCompileTimeError
[ $compiler == dart2js && $fast_startup ]
const_evaluation_test/*: Fail # mirrors not supported
@@ -592,220 +584,188 @@
vm/reflect_core_vm_test: Fail # mirrors not supported
[ $compiler == dart2js && $fast_startup && $fasta && $strong ]
-assertion_initializer_const_function_test/01: MissingCompileTimeError
assertion_test: RuntimeError
+async_await_test/02: RuntimeError
+async_await_test/03: RuntimeError
+async_await_test/none: RuntimeError
async_star_cancel_while_paused_test: RuntimeError
+async_star_test/01: RuntimeError
async_star_test/02: RuntimeError
+async_star_test/03: RuntimeError
+async_star_test/04: RuntimeError
+async_star_test/05: RuntimeError
+async_star_test/none: RuntimeError
bad_override_test/03: MissingCompileTimeError
bad_override_test/04: MissingCompileTimeError
bad_override_test/05: MissingCompileTimeError
bit_operations_test: RuntimeError
branch_canonicalization_test: RuntimeError
-call_function_apply_test: RuntimeError # Issue 23873
+call_method_implicit_tear_off_implements_function_test/02: RuntimeError
+call_method_implicit_tear_off_implements_function_test/04: RuntimeError
+call_method_implicit_tear_off_test/02: RuntimeError
+call_method_implicit_tear_off_test/04: RuntimeError
canonical_const2_test: RuntimeError, OK # non JS number semantics
+cha_deopt1_test: RuntimeError
+cha_deopt2_test: RuntimeError
+cha_deopt3_test: RuntimeError
check_member_static_test/02: MissingCompileTimeError
class_cycle_test/02: MissingCompileTimeError
class_cycle_test/03: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
compile_time_constant_o_test/01: MissingCompileTimeError
compile_time_constant_o_test/02: MissingCompileTimeError
-conditional_method_invocation_test/05: MissingCompileTimeError
-conditional_method_invocation_test/06: MissingCompileTimeError
-conditional_method_invocation_test/07: MissingCompileTimeError
-conditional_method_invocation_test/08: MissingCompileTimeError
-conditional_method_invocation_test/12: MissingCompileTimeError
-conditional_method_invocation_test/13: MissingCompileTimeError
-conditional_method_invocation_test/18: MissingCompileTimeError
-conditional_method_invocation_test/19: MissingCompileTimeError
-conditional_property_access_test/04: MissingCompileTimeError
-conditional_property_access_test/05: MissingCompileTimeError
-conditional_property_access_test/06: MissingCompileTimeError
-conditional_property_access_test/10: MissingCompileTimeError
-conditional_property_access_test/11: MissingCompileTimeError
-conditional_property_access_test/16: MissingCompileTimeError
-conditional_property_access_test/17: MissingCompileTimeError
-conditional_property_assignment_test/04: MissingCompileTimeError
-conditional_property_assignment_test/05: MissingCompileTimeError
-conditional_property_assignment_test/06: MissingCompileTimeError
-conditional_property_assignment_test/10: MissingCompileTimeError
-conditional_property_assignment_test/11: MissingCompileTimeError
-conditional_property_assignment_test/12: MissingCompileTimeError
-conditional_property_assignment_test/13: MissingCompileTimeError
-conditional_property_assignment_test/27: MissingCompileTimeError
-conditional_property_assignment_test/28: MissingCompileTimeError
-conditional_property_assignment_test/32: MissingCompileTimeError
-conditional_property_assignment_test/33: MissingCompileTimeError
-conditional_property_assignment_test/34: MissingCompileTimeError
-conditional_property_assignment_test/35: MissingCompileTimeError
-conditional_property_increment_decrement_test/04: MissingCompileTimeError
-conditional_property_increment_decrement_test/08: MissingCompileTimeError
-conditional_property_increment_decrement_test/12: MissingCompileTimeError
-conditional_property_increment_decrement_test/16: MissingCompileTimeError
-conditional_property_increment_decrement_test/21: MissingCompileTimeError
-conditional_property_increment_decrement_test/22: MissingCompileTimeError
-conditional_property_increment_decrement_test/27: MissingCompileTimeError
-conditional_property_increment_decrement_test/28: MissingCompileTimeError
-conditional_property_increment_decrement_test/33: MissingCompileTimeError
-conditional_property_increment_decrement_test/34: MissingCompileTimeError
-conditional_property_increment_decrement_test/39: MissingCompileTimeError
-conditional_property_increment_decrement_test/40: MissingCompileTimeError
+compile_time_constant_static5_test/11: CompileTimeError
+compile_time_constant_static5_test/16: CompileTimeError
+compile_time_constant_static5_test/21: CompileTimeError
+compile_time_constant_static5_test/23: CompileTimeError
+conditional_rewrite_test: RuntimeError
config_import_test: RuntimeError
-const_constructor2_test/05: MissingCompileTimeError
-const_constructor2_test/06: MissingCompileTimeError
-const_constructor2_test/13: MissingCompileTimeError
-const_constructor2_test/14: MissingCompileTimeError
-const_constructor2_test/15: MissingCompileTimeError
-const_constructor2_test/16: MissingCompileTimeError
-const_constructor2_test/17: MissingCompileTimeError
-const_constructor2_test/18: MissingCompileTimeError
-const_constructor2_test/20: MissingCompileTimeError
-const_constructor2_test/22: MissingCompileTimeError
-const_constructor2_test/24: MissingCompileTimeError
const_dynamic_type_literal_test/02: MissingCompileTimeError
-const_error_multiply_initialized_test/02: MissingCompileTimeError
-const_error_multiply_initialized_test/04: MissingCompileTimeError
const_evaluation_test/01: RuntimeError
-const_init2_test/02: MissingCompileTimeError
const_instance_field_test/01: MissingCompileTimeError
+const_list_test: RuntimeError
const_map2_test/00: MissingCompileTimeError
const_map3_test/00: MissingCompileTimeError
+const_map4_test: RuntimeError
const_switch2_test/01: MissingCompileTimeError
const_switch_test/02: RuntimeError, OK # constant identity based on JS constants
const_switch_test/04: RuntimeError, OK # constant identity based on JS constants
-const_types_test/01: MissingCompileTimeError
-const_types_test/02: MissingCompileTimeError
-const_types_test/03: MissingCompileTimeError
-const_types_test/04: MissingCompileTimeError
-const_types_test/05: MissingCompileTimeError
-const_types_test/06: MissingCompileTimeError
-const_types_test/13: MissingCompileTimeError
const_types_test/34: MissingCompileTimeError
-const_types_test/35: MissingCompileTimeError
const_types_test/39: MissingCompileTimeError
-const_types_test/40: MissingCompileTimeError
constants_test/05: MissingCompileTimeError
-constructor_duplicate_final_test/01: MissingCompileTimeError
-constructor_duplicate_final_test/02: MissingCompileTimeError
-constructor_named_arguments_test/01: MissingCompileTimeError
+constructor12_test: RuntimeError
constructor_named_arguments_test/none: RuntimeError
constructor_redirect1_negative_test/01: Crash # Stack Overflow
-constructor_redirect1_negative_test/none: MissingCompileTimeError
constructor_redirect2_negative_test: Crash # Stack Overflow
-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).
-covariant_override/runtime_check_test: RuntimeError
-covariant_subtyping_tearoff1_test: RuntimeError
-covariant_subtyping_tearoff2_test: RuntimeError
-covariant_subtyping_tearoff3_test: RuntimeError
+covariance_type_parameter_test/01: RuntimeError
+covariance_type_parameter_test/02: RuntimeError
+covariance_type_parameter_test/03: RuntimeError
+covariant_override/tear_off_type_test: RuntimeError
covariant_subtyping_test: Crash # Unsupported operation: Unsupported type parameter type node E.
-covariant_subtyping_unsafe_call1_test: RuntimeError
-covariant_subtyping_unsafe_call2_test: RuntimeError
-covariant_subtyping_unsafe_call3_test: RuntimeError
cyclic_constructor_test/01: Crash # Stack Overflow
+cyclic_type_test/00: RuntimeError
+cyclic_type_test/02: RuntimeError
+cyclic_type_test/03: RuntimeError
+cyclic_type_test/04: RuntimeError
+cyclic_typedef_test/10: Crash # Crash when compiling file:///usr/local/google/home/sra/Dart/sdk/out/ReleaseX64/generated_tests/language_2/cyclic_typedef_test_10.dart,
+cyclic_typedef_test/11: Crash # Crash when compiling file:///usr/local/google/home/sra/Dart/sdk/out/ReleaseX64/generated_tests/language_2/cyclic_typedef_test_11.dart,
+deferred_closurize_load_library_test: RuntimeError
+deferred_constant_list_test: RuntimeError
deferred_constraints_constants_test/default_argument2: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
deferred_constraints_constants_test/none: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
deferred_constraints_constants_test/reference_after_load: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
-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_constraints_type_annotation_test/new: RuntimeError
+deferred_constraints_type_annotation_test/new_generic1: RuntimeError
+deferred_constraints_type_annotation_test/none: RuntimeError
+deferred_constraints_type_annotation_test/static_method: RuntimeError
+deferred_constraints_type_annotation_test/type_annotation_non_deferred: RuntimeError
+deferred_function_type_test: RuntimeError
+deferred_global_test: RuntimeError
deferred_inheritance_constraints_test/extends: MissingCompileTimeError
deferred_inheritance_constraints_test/implements: MissingCompileTimeError
deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
+deferred_inlined_test: RuntimeError
deferred_load_constants_test/none: RuntimeError
-deferred_load_library_wrong_args_test/01: MissingRuntimeError
+deferred_load_inval_code_test: RuntimeError
+deferred_load_library_wrong_args_test/01: CompileTimeError
+deferred_mixin_test: RuntimeError
+deferred_no_such_method_test: RuntimeError
deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
+deferred_only_constant_test: RuntimeError
+deferred_optimized_test: RuntimeError
deferred_redirecting_factory_test: RuntimeError
+deferred_regression_22995_test: RuntimeError
+deferred_regression_28678_test: RuntimeError
+deferred_shadow_load_library_test: RuntimeError
+deferred_shared_and_unshared_classes_test: RuntimeError
+deferred_static_seperate_test: RuntimeError
+deferred_type_dependency_test/as: RuntimeError
+deferred_type_dependency_test/is: RuntimeError
+deferred_type_dependency_test/none: RuntimeError
+deferred_type_dependency_test/type_annotation: RuntimeError
double_int_to_string_test: RuntimeError, OK # non JS number semantics
duplicate_export_negative_test: Fail
duplicate_implements_test/01: MissingCompileTimeError
duplicate_implements_test/02: MissingCompileTimeError
-duplicate_implements_test/03: MissingCompileTimeError
-duplicate_implements_test/04: MissingCompileTimeError
-dynamic_prefix_core_test/none: RuntimeError
-dynamic_test: RuntimeError
+dynamic_prefix_core_test/none: CompileTimeError
+emit_const_fields_test: CompileTimeError
enum_mirror_test: RuntimeError
+example_constructor_test: RuntimeError
expect_test: RuntimeError, OK # Issue 13080
external_test/10: MissingRuntimeError
external_test/13: MissingRuntimeError
external_test/20: MissingRuntimeError
-factory_redirection_test/07: MissingCompileTimeError
+external_test/21: CompileTimeError
+external_test/24: CompileTimeError
+extract_type_arguments_test: RuntimeError
+f_bounded_quantification4_test: RuntimeError
fauxverride_test/03: MissingCompileTimeError
fauxverride_test/05: MissingCompileTimeError
field_increment_bailout_test: RuntimeError
+field_initialization_order_test/01: MissingCompileTimeError
+field_initialization_order_test/none: RuntimeError
field_override3_test/00: MissingCompileTimeError
field_override3_test/01: MissingCompileTimeError
field_override3_test/02: MissingCompileTimeError
field_override3_test/03: MissingCompileTimeError
field_override4_test/02: MissingCompileTimeError
-final_attempt_reinitialization_test/01: MissingCompileTimeError
-final_attempt_reinitialization_test/02: MissingCompileTimeError
+flatten_test/05: MissingRuntimeError
+flatten_test/08: MissingRuntimeError
+flatten_test/09: MissingRuntimeError
+flatten_test/12: MissingRuntimeError
full_stacktrace1_test: RuntimeError # Issue 12698
full_stacktrace2_test: RuntimeError # Issue 12698
full_stacktrace3_test: RuntimeError # Issue 12698
+function_subtype3_test: RuntimeError
function_subtype_bound_closure3_test: RuntimeError
function_subtype_bound_closure4_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_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_inline2_test: RuntimeError
-function_subtype_named1_test: RuntimeError
-function_subtype_named2_test: RuntimeError
function_subtype_not1_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_typearg2_test: RuntimeError
-function_subtype_typearg3_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
-function_type2_test: RuntimeError
function_type_alias2_test: RuntimeError
-function_type_alias_test: RuntimeError
-generalized_void_syntax_test: CompileTimeError # Issue #30176.
+function_type_alias4_test: RuntimeError
generic_closure_test/01: RuntimeError
generic_closure_test/none: RuntimeError
-generic_field_mixin6_test/none: RuntimeError
-generic_function_bounds_test: Crash # Unsupported operation: Unsupported type parameter type node T.
-generic_function_dcall_test: Crash # Unsupported operation: Unsupported type parameter type node T.
-generic_function_typedef_test/01: RuntimeError
-generic_instanceof_test: RuntimeError
-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_typedef_test: Crash # Unsupported operation: Unsupported type parameter type node S.
+generic_function_bounds_test: RuntimeError
+generic_function_dcall_test: RuntimeError
+generic_function_type_as_type_argument_test/01: MissingCompileTimeError
+generic_function_type_as_type_argument_test/02: MissingCompileTimeError
+generic_instanceof2_test: RuntimeError
+generic_is_check_test: RuntimeError
+generic_method_types_test/02: RuntimeError
+generic_methods_bounds_test/02: MissingRuntimeError
+generic_methods_dynamic_test/02: MissingRuntimeError
+generic_methods_dynamic_test/04: MissingRuntimeError
+generic_methods_generic_class_tearoff_test: RuntimeError
+generic_methods_generic_function_result_test/01: MissingCompileTimeError
+generic_methods_simple_as_expression_test/02: MissingRuntimeError
+generic_methods_type_expression_test: RuntimeError
+generic_methods_unused_parameter_test: RuntimeError
+generic_no_such_method_dispatcher_simple_test: CompileTimeError
+generic_no_such_method_dispatcher_test: CompileTimeError
+generic_tearoff_test: CompileTimeError
getter_override2_test/02: MissingCompileTimeError
getter_override_test/00: MissingCompileTimeError
getter_override_test/01: MissingCompileTimeError
getter_override_test/02: MissingCompileTimeError
-getters_setters2_test/01: RuntimeError
-getters_setters2_test/none: RuntimeError
identical_closure2_test: RuntimeError # non JS number semantics
if_null_precedence_test/none: RuntimeError
-implicit_creation/implicit_new_or_const_composite_test: RuntimeError
-implicit_creation/implicit_new_or_const_test: RuntimeError
-inferrer_synthesized_constructor_test: RuntimeError
infinity_test: RuntimeError # non JS number semantics - Issue 4984
instance_creation_in_function_annotation_test: RuntimeError
-instanceof2_test: RuntimeError
-instanceof4_test/01: RuntimeError
-instanceof4_test/none: RuntimeError
+instantiate_tearoff_of_call_test: CompileTimeError
+int64_literal_test/01: RuntimeError
+int64_literal_test/02: RuntimeError
+int64_literal_test/03: MissingCompileTimeError
+int64_literal_test/04: RuntimeError
+int64_literal_test/05: RuntimeError
+int64_literal_test/10: RuntimeError
+int64_literal_test/20: RuntimeError
+int64_literal_test/30: MissingCompileTimeError
+int64_literal_test/40: RuntimeError
+int64_literal_test/none: RuntimeError
integer_division_by_zero_test: RuntimeError # Issue 8301
internal_library_test/02: Crash # NoSuchMethodError: Class 'DillLibraryBuilder' has no instance getter 'mixinApplicationClasses'.
invocation_mirror2_test: RuntimeError # mirrors not supported
@@ -813,39 +773,29 @@
invocation_mirror_invoke_on_test: RuntimeError
issue21079_test: RuntimeError
issue23244_test: RuntimeError
+issue31596_super_test/01: CompileTimeError
+issue31596_super_test/03: CompileTimeError
left_shift_test: RuntimeError # non JS number semantics
library_env_test/has_mirror_support: RuntimeError
-list_literal1_test/01: MissingCompileTimeError
-list_literal4_test/00: MissingCompileTimeError
-list_literal4_test/01: MissingCompileTimeError
-list_literal4_test/03: MissingCompileTimeError
-list_literal4_test/04: MissingCompileTimeError
-list_literal4_test/05: MissingCompileTimeError
-list_literal_syntax_test/01: MissingCompileTimeError
-list_literal_syntax_test/02: MissingCompileTimeError
-list_literal_syntax_test/03: MissingCompileTimeError
-malformed2_test/00: MissingCompileTimeError
-many_generic_instanceof_test: RuntimeError
+local_function2_test/none: RuntimeError
+local_function3_test/none: RuntimeError
+local_function_test/none: RuntimeError
+main_test/03: RuntimeError
many_overridden_no_such_method_test: RuntimeError
-map_literal8_test: RuntimeError
method_override7_test/00: MissingCompileTimeError
method_override7_test/01: MissingCompileTimeError
method_override7_test/02: MissingCompileTimeError
method_override8_test/00: MissingCompileTimeError
method_override8_test/01: MissingCompileTimeError
+method_override_test: CompileTimeError
+minify_closure_variable_collision_test: CompileTimeError
mint_arithmetic_test: RuntimeError # non JS number semantics
mixin_forwarding_constructor4_test/01: MissingCompileTimeError
mixin_forwarding_constructor4_test/02: MissingCompileTimeError
mixin_forwarding_constructor4_test/03: MissingCompileTimeError
mixin_illegal_super_use_test/01: MissingCompileTimeError
-mixin_illegal_super_use_test/02: MissingCompileTimeError
-mixin_illegal_super_use_test/03: MissingCompileTimeError
mixin_illegal_super_use_test/04: MissingCompileTimeError
-mixin_illegal_super_use_test/05: MissingCompileTimeError
-mixin_illegal_super_use_test/06: MissingCompileTimeError
mixin_illegal_super_use_test/07: MissingCompileTimeError
-mixin_illegal_super_use_test/08: MissingCompileTimeError
-mixin_illegal_super_use_test/09: MissingCompileTimeError
mixin_illegal_super_use_test/10: MissingCompileTimeError
mixin_illegal_super_use_test/11: MissingCompileTimeError
mixin_illegal_superclass_test/01: MissingCompileTimeError
@@ -878,14 +828,7 @@
mixin_illegal_superclass_test/28: MissingCompileTimeError
mixin_illegal_superclass_test/29: MissingCompileTimeError
mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_issue10216_2_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_of_mixin_test/none: CompileTimeError
mixin_super_2_test/none: CompileTimeError
mixin_super_constructor_named_test/01: MissingCompileTimeError
@@ -911,7 +854,10 @@
mixin_supertype_subclass4_test/04: CompileTimeError
mixin_supertype_subclass4_test/05: CompileTimeError
mixin_supertype_subclass4_test/none: CompileTimeError
-mixin_type_parameters_super_test: RuntimeError
+mixin_supertype_subclass_test/01: CompileTimeError
+mixin_supertype_subclass_test/03: CompileTimeError
+mixin_supertype_subclass_test/04: CompileTimeError
+mixin_supertype_subclass_test/none: CompileTimeError
modulo_test: RuntimeError # non JS number semantics
multiline_newline_test/04: MissingCompileTimeError
multiline_newline_test/04r: MissingCompileTimeError
@@ -920,17 +866,16 @@
multiline_newline_test/06: MissingCompileTimeError
multiline_newline_test/06r: MissingCompileTimeError
named_parameters_default_eq_test/02: MissingCompileTimeError
+named_parameters_default_eq_test/none: RuntimeError
nan_identical_test: RuntimeError # Issue 11551
-nested_generic_closure_test: Crash # Unsupported operation: Unsupported type parameter type node F.
+nested_generic_closure_test: RuntimeError
no_main_test/01: CompileTimeError
+no_such_method_mock_test: RuntimeError
no_such_method_test: RuntimeError
-not_enough_positional_arguments_test/00: MissingCompileTimeError
-not_enough_positional_arguments_test/01: MissingCompileTimeError
-not_enough_positional_arguments_test/02: MissingCompileTimeError
-not_enough_positional_arguments_test/03: MissingCompileTimeError
-not_enough_positional_arguments_test/05: MissingCompileTimeError
-not_enough_positional_arguments_test/06: MissingCompileTimeError
-not_enough_positional_arguments_test/07: MissingCompileTimeError
+nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
+nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError
+nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError
+null_no_such_method_test: CompileTimeError
null_test/mirrors: RuntimeError
null_test/none: RuntimeError
number_identity2_test: RuntimeError
@@ -941,6 +886,13 @@
override_field_method4_negative_test: Fail
override_field_method5_negative_test: Fail
override_field_test/01: MissingCompileTimeError
+override_inheritance_field_test/04: CompileTimeError
+override_inheritance_field_test/06: CompileTimeError
+override_inheritance_field_test/26: CompileTimeError
+override_inheritance_field_test/29: CompileTimeError
+override_inheritance_generic_test/02: CompileTimeError
+override_inheritance_method_test/28: CompileTimeError
+override_inheritance_method_test/29: CompileTimeError
override_inheritance_mixed_test/01: MissingCompileTimeError
override_inheritance_mixed_test/02: MissingCompileTimeError
override_inheritance_mixed_test/03: MissingCompileTimeError
@@ -948,23 +900,24 @@
override_inheritance_mixed_test/08: MissingCompileTimeError
override_inheritance_mixed_test/09: MissingCompileTimeError
override_method_with_field_test/01: MissingCompileTimeError
-positional_parameters_type_test/01: MissingCompileTimeError
-positional_parameters_type_test/02: MissingCompileTimeError
-private_super_constructor_test/01: MissingCompileTimeError
+parser_quirks_test: CompileTimeError
redirecting_factory_default_values_test/01: MissingCompileTimeError
redirecting_factory_default_values_test/02: MissingCompileTimeError
-redirecting_factory_long_test: RuntimeError
redirecting_factory_reflection_test: RuntimeError
-regress_20394_test/01: MissingCompileTimeError
+regress_22443_test: RuntimeError
+regress_23089_test: Crash # Crash when compiling file:///usr/local/google/home/sra/Dart/sdk/tests/language_2/regress_23089_test.dart,
+regress_23408_test: CompileTimeError
regress_24283_test: RuntimeError # non JS number semantics
regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
-regress_28217_test/01: MissingCompileTimeError
-regress_28217_test/none: MissingCompileTimeError
regress_28255_test: RuntimeError
-regress_28341_test: RuntimeError
+regress_28278_test: RuntimeError
+regress_29025_test: CompileTimeError
+regress_29405_test: CompileTimeError
regress_29784_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in () for j:constructor(A.ok).
regress_29784_test/02: MissingCompileTimeError # Issue 29784
-regress_31057_test: Crash # Unsupported operation: Unsupported type parameter type node B.
+regress_30339_test: CompileTimeError
+runtime_type_function_test: RuntimeError
+setter_no_getter_test/01: CompileTimeError
setter_override_test/00: MissingCompileTimeError
setter_override_test/03: MissingCompileTimeError
stacktrace_demangle_ctors_test: RuntimeError # Issue 12698
@@ -972,25 +925,49 @@
stacktrace_rethrow_error_test/withtraceparameter: RuntimeError # Issue 12698
stacktrace_rethrow_nonerror_test: RuntimeError # Issue 12698
stacktrace_test: RuntimeError # Issue 12698
+string_interpolate_test: CompileTimeError
+string_interpolation_and_buffer_test: RuntimeError
+string_split_test: CompileTimeError
+string_supertype_checked_test: CompileTimeError
+super_bound_closure_test/none: CompileTimeError
super_call4_test: Crash # NoSuchMethodError: The getter 'thisLocal' was called on null.
+super_no_such_method1_test: CompileTimeError
+super_no_such_method2_test: CompileTimeError
+super_no_such_method3_test: CompileTimeError
+super_no_such_method4_test: CompileTimeError
+super_no_such_method5_test: CompileTimeError
+super_operator_index5_test: CompileTimeError
+super_operator_index6_test: CompileTimeError
+super_operator_index7_test: CompileTimeError
+super_operator_index8_test: CompileTimeError
+super_test: RuntimeError
switch_bad_case_test/01: MissingCompileTimeError
switch_bad_case_test/02: MissingCompileTimeError
switch_case_test/00: MissingCompileTimeError
switch_case_test/01: MissingCompileTimeError
switch_case_test/02: MissingCompileTimeError
-symbol_literal_test/01: MissingCompileTimeError
-syntax_test/28: MissingCompileTimeError
-syntax_test/29: MissingCompileTimeError
-syntax_test/30: MissingCompileTimeError
-syntax_test/31: MissingCompileTimeError
-syntax_test/32: MissingCompileTimeError
-syntax_test/33: MissingCompileTimeError
-tearoff_dynamic_test: Crash # Unsupported operation: Unsupported type parameter type node T.
+syntax_test/28: MissingCompileTimeError # Issue 29763
+syntax_test/29: MissingCompileTimeError # Issue 29763
+syntax_test/30: MissingCompileTimeError # Issue 29763
+syntax_test/31: MissingCompileTimeError # Issue 29763
+syntax_test/32: MissingCompileTimeError # Issue 29763
+syntax_test/33: MissingCompileTimeError # Issue 29763
+tearoff_dynamic_test: RuntimeError
truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
try_catch_test/01: MissingCompileTimeError
+type_error_test: RuntimeError
type_literal_test: RuntimeError
-type_variable_conflict2_test/02: MissingCompileTimeError
-typevariable_substitution2_test/02: RuntimeError
+type_promotion_functions_test/02: CompileTimeError
+type_promotion_functions_test/03: CompileTimeError
+type_promotion_functions_test/04: CompileTimeError
+type_promotion_functions_test/09: CompileTimeError
+type_promotion_functions_test/11: CompileTimeError
+type_promotion_functions_test/12: CompileTimeError
+type_promotion_functions_test/13: CompileTimeError
+type_promotion_functions_test/14: CompileTimeError
+type_promotion_functions_test/none: CompileTimeError
+type_promotion_more_specific_test/04: CompileTimeError
+type_variable_promotion_test: RuntimeError
[ $compiler == dart2js && $fasta ]
call_method_as_cast_test/06: RuntimeError
@@ -1005,7 +982,6 @@
extract_type_arguments_test: Crash # Issue 31371
function_propagation_test: RuntimeError
generic_test/01: MissingCompileTimeError # front end does not validate `extends`
-implicit_downcast_during_yield_star_test: RuntimeError
instantiate_tearoff_of_call_test: RuntimeError
instantiate_tearoff_test: RuntimeError
mixin_type_parameter_inference_error_test/none: CompileTimeError
@@ -1033,39 +1009,27 @@
type_alias_equality_test/04: RuntimeError # Issue 32784
[ $compiler == dart2js && $fasta && $host_checked && $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_syntax_test/00: MissingCompileTimeError
additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
assertion_test: RuntimeError
async_await_test/02: RuntimeError
async_await_test/03: RuntimeError
async_await_test/none: RuntimeError
-async_congruence_local_test/none: RuntimeError
-async_congruence_method_test/none: RuntimeError
-async_congruence_top_level_test: RuntimeError
-async_congruence_unnamed_test/none: RuntimeError
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: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
async_return_types_test/tooManyTypeParameters: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
async_return_types_test/wrongReturnType: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
-async_star_await_pauses_test: RuntimeError
async_star_cancel_while_paused_test: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
-async_star_regression_2238_test: RuntimeError
-async_star_regression_23116_test: RuntimeError
-async_star_stream_take_test: RuntimeError
async_star_test/01: RuntimeError
async_star_test/02: RuntimeError
async_star_test/03: RuntimeError
async_star_test/04: RuntimeError
async_star_test/05: RuntimeError
async_star_test/none: RuntimeError
-async_test: RuntimeError
await_not_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).
bad_override_test/01: MissingCompileTimeError
bad_override_test/02: MissingCompileTimeError
@@ -1092,8 +1056,6 @@
class_literal_static_test/01: MissingCompileTimeError
class_literal_static_test/03: MissingCompileTimeError
class_literal_static_test/07: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
closure_self_reference_test: Crash # 'file:*/pkg/compiler/lib/src/ssa/nodes.dart': Failed assertion: line 641 pos 12: 'isClosed()': is not true.
compile_time_constant_k_test/01: MissingCompileTimeError
compile_time_constant_k_test/02: MissingCompileTimeError
@@ -1197,7 +1159,6 @@
f_bounded_quantification4_test: RuntimeError
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
-factory2_test/03: MissingCompileTimeError
factory4_test/00: MissingCompileTimeError
fauxverride_test/03: MissingCompileTimeError
fauxverride_test/05: MissingCompileTimeError
@@ -1228,7 +1189,6 @@
function_subtype_inline2_test: RuntimeError
function_subtype_not1_test: RuntimeError
function_subtype_setter0_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
function_type_alias2_test: RuntimeError
function_type_alias4_test: RuntimeError
generic_closure_test/01: RuntimeError
@@ -1237,9 +1197,7 @@
generic_function_dcall_test: RuntimeError
generic_function_type_as_type_argument_test/01: MissingCompileTimeError
generic_function_type_as_type_argument_test/02: MissingCompileTimeError
-generic_function_typedef_test/01: RuntimeError
generic_instanceof2_test: RuntimeError
-generic_instanceof_test: RuntimeError
generic_is_check_test: RuntimeError
generic_method_types_test/02: RuntimeError
generic_methods_bounds_test/01: MissingCompileTimeError
@@ -1267,8 +1225,6 @@
identical_const_test/03: MissingCompileTimeError
identical_const_test/04: MissingCompileTimeError
if_null_precedence_test/none: RuntimeError
-implicit_this_test/01: MissingCompileTimeError
-implicit_this_test/04: MissingCompileTimeError
infinity_test: RuntimeError # non JS number semantics - Issue 4984
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
@@ -1321,7 +1277,6 @@
malbounded_type_test_test/00: MissingCompileTimeError
malbounded_type_test_test/01: MissingCompileTimeError
malbounded_type_test_test/02: MissingCompileTimeError
-many_generic_instanceof_test: RuntimeError
many_overridden_no_such_method_test: RuntimeError
map_literal3_test/01: MissingCompileTimeError
map_literal3_test/02: MissingCompileTimeError
@@ -1467,25 +1422,6 @@
override_field_test/01: MissingCompileTimeError
override_field_test/02: MissingCompileTimeError
override_field_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
override_inheritance_field_test/04: CompileTimeError
override_inheritance_field_test/06: CompileTimeError
override_inheritance_field_test/26: CompileTimeError
@@ -1502,18 +1438,8 @@
override_inheritance_mixed_test/02: MissingCompileTimeError
override_inheritance_mixed_test/03: MissingCompileTimeError
override_inheritance_mixed_test/04: MissingCompileTimeError
-override_inheritance_mixed_test/06: MissingCompileTimeError
-override_inheritance_mixed_test/07: MissingCompileTimeError
override_inheritance_mixed_test/08: MissingCompileTimeError
override_inheritance_mixed_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/02: MissingCompileTimeError
-override_inheritance_no_such_method_test/06: MissingCompileTimeError
-override_inheritance_no_such_method_test/07: MissingCompileTimeError
-override_inheritance_no_such_method_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/10: MissingCompileTimeError
-override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
override_method_with_field_test/01: MissingCompileTimeError
parser_quirks_test: CompileTimeError
partial_tearoff_instantiation_test/05: Crash # Assertion failure: kind=special,memberName=instantiate,callStructure:CallStructure(arity=0, types=1)
@@ -1598,12 +1524,12 @@
syntax_test/24: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
syntax_test/25: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
syntax_test/26: Crash # 'file:*/pkg/compiler/lib/src/kernel/env.dart': Failed assertion: line 322 pos 16: '!name.contains('#')': is not true.
-syntax_test/28: MissingCompileTimeError
-syntax_test/29: MissingCompileTimeError
-syntax_test/30: MissingCompileTimeError
-syntax_test/31: MissingCompileTimeError
-syntax_test/32: MissingCompileTimeError
-syntax_test/33: MissingCompileTimeError
+syntax_test/28: MissingCompileTimeError # Issue 29763
+syntax_test/29: MissingCompileTimeError # Issue 29763
+syntax_test/30: MissingCompileTimeError # Issue 29763
+syntax_test/31: MissingCompileTimeError # Issue 29763
+syntax_test/32: MissingCompileTimeError # Issue 29763
+syntax_test/33: MissingCompileTimeError # Issue 29763
tearoff_dynamic_test: RuntimeError
truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
try_catch_test/01: MissingCompileTimeError
@@ -1707,39 +1633,27 @@
wrong_number_type_arguments_test/none: Pass
[ $compiler == dart2js && $fasta && $minified && $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_syntax_test/00: MissingCompileTimeError
additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
assertion_test: RuntimeError
async_await_test/02: RuntimeError
async_await_test/03: RuntimeError
async_await_test/none: RuntimeError
-async_congruence_local_test/none: RuntimeError
-async_congruence_method_test/none: RuntimeError
-async_congruence_top_level_test: RuntimeError
-async_congruence_unnamed_test/none: RuntimeError
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: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
async_return_types_test/tooManyTypeParameters: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
async_return_types_test/wrongReturnType: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
-async_star_await_pauses_test: RuntimeError
async_star_cancel_while_paused_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
-async_star_regression_2238_test: RuntimeError
-async_star_regression_23116_test: RuntimeError
-async_star_stream_take_test: RuntimeError
async_star_test/01: RuntimeError
async_star_test/02: RuntimeError
async_star_test/03: RuntimeError
async_star_test/04: RuntimeError
async_star_test/05: RuntimeError
async_star_test/none: RuntimeError
-async_test: RuntimeError
await_not_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).
bad_override_test/01: MissingCompileTimeError
bad_override_test/02: MissingCompileTimeError
@@ -1766,8 +1680,6 @@
class_literal_static_test/01: MissingCompileTimeError
class_literal_static_test/03: MissingCompileTimeError
class_literal_static_test/07: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
compile_time_constant_k_test/01: MissingCompileTimeError
compile_time_constant_k_test/02: MissingCompileTimeError
compile_time_constant_k_test/03: MissingCompileTimeError
@@ -1866,7 +1778,6 @@
f_bounded_quantification4_test: RuntimeError # Issue 12605
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
-factory2_test/03: MissingCompileTimeError
factory4_test/00: MissingCompileTimeError
fauxverride_test/03: MissingCompileTimeError
fauxverride_test/05: MissingCompileTimeError
@@ -1897,16 +1808,13 @@
function_subtype_inline2_test: RuntimeError
function_subtype_not1_test: RuntimeError
function_subtype_setter0_test: RuntimeError
-function_subtype_typearg5_test: RuntimeError
function_type_alias2_test: RuntimeError
function_type_alias4_test: RuntimeError
generic_function_bounds_test: RuntimeError
generic_function_dcall_test: RuntimeError
generic_function_type_as_type_argument_test/01: MissingCompileTimeError
generic_function_type_as_type_argument_test/02: MissingCompileTimeError
-generic_function_typedef_test/01: RuntimeError
generic_instanceof2_test: RuntimeError
-generic_instanceof_test: RuntimeError
generic_is_check_test: RuntimeError
generic_method_types_test/02: RuntimeError
generic_methods_bounds_test/01: MissingCompileTimeError
@@ -1934,8 +1842,6 @@
identical_const_test/03: MissingCompileTimeError
identical_const_test/04: MissingCompileTimeError
if_null_precedence_test/none: RuntimeError
-implicit_this_test/01: MissingCompileTimeError
-implicit_this_test/04: MissingCompileTimeError
infinity_test: RuntimeError # non JS number semantics - Issue 4984
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
@@ -1988,7 +1894,6 @@
malbounded_type_test_test/00: MissingCompileTimeError
malbounded_type_test_test/01: MissingCompileTimeError
malbounded_type_test_test/02: MissingCompileTimeError
-many_generic_instanceof_test: RuntimeError
many_overridden_no_such_method_test: RuntimeError
map_literal3_test/01: MissingCompileTimeError
map_literal3_test/02: MissingCompileTimeError
@@ -2136,25 +2041,6 @@
override_field_test/01: MissingCompileTimeError
override_field_test/02: MissingCompileTimeError
override_field_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
override_inheritance_field_test/04: CompileTimeError
override_inheritance_field_test/06: CompileTimeError
override_inheritance_field_test/26: CompileTimeError
@@ -2171,18 +2057,8 @@
override_inheritance_mixed_test/02: MissingCompileTimeError
override_inheritance_mixed_test/03: MissingCompileTimeError
override_inheritance_mixed_test/04: MissingCompileTimeError
-override_inheritance_mixed_test/06: MissingCompileTimeError
-override_inheritance_mixed_test/07: MissingCompileTimeError
override_inheritance_mixed_test/08: MissingCompileTimeError
override_inheritance_mixed_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/02: MissingCompileTimeError
-override_inheritance_no_such_method_test/06: MissingCompileTimeError
-override_inheritance_no_such_method_test/07: MissingCompileTimeError
-override_inheritance_no_such_method_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/10: MissingCompileTimeError
-override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
override_method_with_field_test/01: MissingCompileTimeError
parser_quirks_test: CompileTimeError
recursive_generic_test: RuntimeError
@@ -2242,12 +2118,12 @@
switch_case_test/01: MissingCompileTimeError
switch_case_test/02: MissingCompileTimeError
symbol_conflict_test: RuntimeError # Issue 23857
-syntax_test/28: MissingCompileTimeError
-syntax_test/29: MissingCompileTimeError
-syntax_test/30: MissingCompileTimeError
-syntax_test/31: MissingCompileTimeError
-syntax_test/32: MissingCompileTimeError
-syntax_test/33: MissingCompileTimeError
+syntax_test/28: MissingCompileTimeError # Issue 29763
+syntax_test/29: MissingCompileTimeError # Issue 29763
+syntax_test/30: MissingCompileTimeError # Issue 29763
+syntax_test/31: MissingCompileTimeError # Issue 29763
+syntax_test/32: MissingCompileTimeError # Issue 29763
+syntax_test/33: MissingCompileTimeError # Issue 29763
tearoff_dynamic_test: RuntimeError
truncdiv_test: RuntimeError # non JS number semantics - Issue 15246
try_catch_test/01: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index b259467..b611f55 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -146,6 +146,7 @@
parameter_initializer_test: CompileTimeError
part_refers_to_core_library_test/01: Crash
prefix10_negative_test: Fail # Issue 29920
+regress_23089_test: MissingCompileTimeError
regress_23408_test: CompileTimeError
regress_24283_test: RuntimeError # Intended to fail, requires 64-bit numbers.
regress_29025_test: CompileTimeError # Issue 29081
@@ -170,7 +171,8 @@
super_operator_index7_test: RuntimeError
super_operator_index8_test: RuntimeError
switch_case_test/none: CompileTimeError
-syntax_test/none: CompileTimeError
+syntax_test/60: MissingCompileTimeError
+syntax_test/61: MissingCompileTimeError
truncdiv_test: RuntimeError # Issue 29920
try_catch_on_syntax_test/10: MissingCompileTimeError
try_catch_on_syntax_test/11: MissingCompileTimeError
@@ -287,9 +289,6 @@
void_type_usage_test/paren_void_init: MissingCompileTimeError
[ $compiler == dartdevk ]
-abstract_factory_constructor_test/00: MissingCompileTimeError
-abstract_getter_test/01: MissingCompileTimeError
-abstract_syntax_test/00: MissingCompileTimeError
additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
@@ -317,8 +316,6 @@
check_member_static_test/02: MissingCompileTimeError
class_cycle_test/02: MissingCompileTimeError
class_cycle_test/03: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
compile_time_constant_c_test/02: MissingCompileTimeError
compile_time_constant_k_test/01: MissingCompileTimeError
compile_time_constant_k_test/02: MissingCompileTimeError
@@ -379,7 +376,6 @@
external_test/24: CompileTimeError
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
-factory2_test/03: MissingCompileTimeError
factory4_test/00: MissingCompileTimeError
fauxverride_test/03: MissingCompileTimeError
fauxverride_test/05: MissingCompileTimeError
@@ -420,8 +416,6 @@
implicit_creation/implicit_const_not_default_values_test/e30: Pass
implicit_creation/implicit_const_not_default_values_test/e6: Pass
implicit_creation/implicit_const_not_default_values_test/e9: Pass
-implicit_this_test/01: MissingCompileTimeError
-implicit_this_test/04: MissingCompileTimeError
initializing_formal_type_annotation_test/01: MissingCompileTimeError
initializing_formal_type_annotation_test/02: MissingCompileTimeError
instantiate_tearoff_of_call_test: CompileTimeError
@@ -524,12 +518,6 @@
mixin_invalid_bound_test/08: MissingCompileTimeError
mixin_invalid_bound_test/09: MissingCompileTimeError
mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_of_mixin_test/01: MissingCompileTimeError
-mixin_of_mixin_test/02: MissingCompileTimeError
-mixin_of_mixin_test/03: MissingCompileTimeError
-mixin_of_mixin_test/04: MissingCompileTimeError
-mixin_of_mixin_test/05: MissingCompileTimeError
-mixin_of_mixin_test/06: MissingCompileTimeError
mixin_regress_13688_test: RuntimeError # Issue 32427
mixin_super_2_test/01: MissingCompileTimeError
mixin_super_2_test/03: MissingCompileTimeError
@@ -551,7 +539,6 @@
multiline_newline_test/06r: MissingCompileTimeError
named_constructor_test/01: MissingCompileTimeError
named_parameters_default_eq_test/02: MissingCompileTimeError
-nsm5_test: MissingCompileTimeError
null2_test: RuntimeError # Issue 32194
null_method_test: RuntimeError # Issue 32194
null_no_such_method_test: CompileTimeError # Issue 31533
@@ -579,18 +566,8 @@
override_inheritance_mixed_test/02: MissingCompileTimeError
override_inheritance_mixed_test/03: MissingCompileTimeError
override_inheritance_mixed_test/04: MissingCompileTimeError
-override_inheritance_mixed_test/06: MissingCompileTimeError
-override_inheritance_mixed_test/07: MissingCompileTimeError
override_inheritance_mixed_test/08: MissingCompileTimeError
override_inheritance_mixed_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/02: MissingCompileTimeError
-override_inheritance_no_such_method_test/05: MissingCompileTimeError
-override_inheritance_no_such_method_test/06: MissingCompileTimeError
-override_inheritance_no_such_method_test/07: MissingCompileTimeError
-override_inheritance_no_such_method_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/10: MissingCompileTimeError
-override_inheritance_no_such_method_test/12: MissingCompileTimeError
override_method_with_field_test/01: MissingCompileTimeError
recursive_mixin_test: RuntimeError # Issue 32428
redirecting_factory_default_values_test/01: MissingCompileTimeError
@@ -637,12 +614,6 @@
switch_case_test/01: MissingCompileTimeError
switch_case_test/02: MissingCompileTimeError
syncstar_yield_test/copyParameters: RuntimeError # Expect.equals(expected: <2>, actual: <3>) fails.
-syntax_test/28: MissingCompileTimeError
-syntax_test/29: MissingCompileTimeError
-syntax_test/30: MissingCompileTimeError
-syntax_test/31: MissingCompileTimeError
-syntax_test/32: MissingCompileTimeError
-syntax_test/33: MissingCompileTimeError
tearoff_dynamic_test: RuntimeError # Issue 32194
try_catch_test/01: MissingCompileTimeError
type_alias_equality_test/02: RuntimeError # Issue 32785
@@ -737,7 +708,6 @@
flatten_test/12: MissingRuntimeError # Issue 29920
for_variable_capture_test: RuntimeError # Issue 29920; Expect.equals(expected: <1>, actual: <0>) fails.
function_subtype_inline2_test: RuntimeError # Expect.fail('Missing type error: 'new C.c1(m2)'.')
-function_type_alias6_test/none: RuntimeError # Expect.isTrue(false) fails.
generic_function_type_as_type_argument_test/01: MissingCompileTimeError # Issue 29920
generic_function_type_as_type_argument_test/02: MissingCompileTimeError # Issue 29920
generic_instanceof2_test: RuntimeError # Issue 29920; ReferenceError: FooOfK$String is not defined
@@ -786,26 +756,6 @@
numbers_test: RuntimeError # Issue 29920; Expect.equals(expected: <false>, actual: <true>) fails.
overridden_no_such_method_test: RuntimeError # UnimplementedError: JsInstanceMirror.delegate unimplemented; UnimplementedError: JsInstanceMirror.delegate unimplemented
override_field_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
parser_quirks_test: CompileTimeError
private3_test: RuntimeError # Type 'PrivateSymbol' is not a subtype of type 'Symbol' in strong mode
regress_16640_test: RuntimeError # Issue 29920; Uncaught Error: type arguments should not be null: E => {
@@ -821,5 +771,7 @@
switch_label2_test: RuntimeError # Issue 29920; UnimplementedError: node <ShadowContinueSwitchStatement> see https://github.com/dart-lang/sdk/issues/29352 `continue #L1;
switch_label_test: RuntimeError # Issue 29920; UnimplementedError: node <ShadowContinueSwitchStatement> see https://github.com/dart-lang/sdk/issues/29352 `continue #L1;
switch_try_catch_test: RuntimeError # Issue 29920; Expect.throws: Unexpected 'UnimplementedError: node <ShadowContinueSwitchStatement> see https://github.com/dart-lang/sdk/issues/29352 `continue #L1;
+syntax_test/60: MissingCompileTimeError
+syntax_test/61: MissingCompileTimeError
truncdiv_test: RuntimeError # Issue 29920; Expect.throws fails: Did not throw
vm/*: SkipByDesign # VM only tests.; VM only tests.
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index ea83e68..52eae2d 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -53,11 +53,8 @@
implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError
[ $fasta ]
-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_subclass_test: MissingCompileTimeError # Issue 32014.
abstract_override_adds_optional_args_concrete_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.
async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
@@ -71,8 +68,6 @@
call_non_method_field_test/01: MissingCompileTimeError
call_non_method_field_test/02: MissingCompileTimeError
check_member_static_test/01: MissingCompileTimeError
-closure_invoked_through_interface_target_field_test: MissingCompileTimeError
-closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
compile_time_constant_o_test/01: MissingCompileTimeError
compile_time_constant_o_test/02: MissingCompileTimeError
const_cast2_test/01: CompileTimeError
@@ -102,7 +97,6 @@
duplicate_export_negative_test: Fail # Issue 6134
f_bounded_quantification_test/01: MissingCompileTimeError
f_bounded_quantification_test/02: MissingCompileTimeError
-factory2_test/03: MissingCompileTimeError
factory4_test/00: MissingCompileTimeError
field3_test/01: MissingCompileTimeError
field_override_test/00: MissingCompileTimeError
@@ -115,8 +109,6 @@
identical_const_test/02: MissingCompileTimeError
identical_const_test/03: MissingCompileTimeError
identical_const_test/04: MissingCompileTimeError
-implicit_this_test/01: MissingCompileTimeError
-implicit_this_test/04: MissingCompileTimeError
issue31596_override_test/07: MissingCompileTimeError
issue31596_override_test/08: MissingCompileTimeError
issue31596_super_test/02: MissingCompileTimeError
@@ -176,45 +168,14 @@
mixin_type_parameters_errors_test/05: MissingCompileTimeError
named_constructor_test/01: MissingCompileTimeError
named_parameters_default_eq_test/02: MissingCompileTimeError # Fasta bug: Default values are not allowed on redirecting factory constructors.
-nsm5_test: MissingCompileTimeError
override_field_test/02: MissingCompileTimeError
override_field_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/02: MissingCompileTimeError
-override_inheritance_abstract_test/03: MissingCompileTimeError
-override_inheritance_abstract_test/04: MissingCompileTimeError
-override_inheritance_abstract_test/08: MissingCompileTimeError
-override_inheritance_abstract_test/09: MissingCompileTimeError
-override_inheritance_abstract_test/10: MissingCompileTimeError
-override_inheritance_abstract_test/11: MissingCompileTimeError
-override_inheritance_abstract_test/12: MissingCompileTimeError
-override_inheritance_abstract_test/13: MissingCompileTimeError
-override_inheritance_abstract_test/14: MissingCompileTimeError
-override_inheritance_abstract_test/17: MissingCompileTimeError
-override_inheritance_abstract_test/19: MissingCompileTimeError
-override_inheritance_abstract_test/20: MissingCompileTimeError
-override_inheritance_abstract_test/21: MissingCompileTimeError
-override_inheritance_abstract_test/22: MissingCompileTimeError
-override_inheritance_abstract_test/23: MissingCompileTimeError
-override_inheritance_abstract_test/24: MissingCompileTimeError
-override_inheritance_abstract_test/25: MissingCompileTimeError
-override_inheritance_abstract_test/26: MissingCompileTimeError
override_inheritance_field_test/44: MissingCompileTimeError
override_inheritance_field_test/47: MissingCompileTimeError
override_inheritance_field_test/48: MissingCompileTimeError
override_inheritance_field_test/53: MissingCompileTimeError
override_inheritance_field_test/54: MissingCompileTimeError
-override_inheritance_mixed_test/06: MissingCompileTimeError
-override_inheritance_mixed_test/07: MissingCompileTimeError
override_inheritance_mixed_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/02: MissingCompileTimeError
-override_inheritance_no_such_method_test/05: MissingCompileTimeError
-override_inheritance_no_such_method_test/06: MissingCompileTimeError
-override_inheritance_no_such_method_test/07: MissingCompileTimeError
-override_inheritance_no_such_method_test/09: MissingCompileTimeError
-override_inheritance_no_such_method_test/10: MissingCompileTimeError
-override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
partial_tearoff_instantiation_test/05: MissingCompileTimeError
partial_tearoff_instantiation_test/06: MissingCompileTimeError
partial_tearoff_instantiation_test/07: MissingCompileTimeError
@@ -233,14 +194,14 @@
switch_case_test/00: MissingCompileTimeError # KernelVM bug: Constant evaluation.
switch_case_test/01: MissingCompileTimeError # KernelVM bug: Constant evaluation.
switch_case_test/02: MissingCompileTimeError # KernelVM bug: Constant evaluation.
-syntax_test/28: MissingCompileTimeError
-syntax_test/29: MissingCompileTimeError
-syntax_test/30: MissingCompileTimeError
-syntax_test/31: MissingCompileTimeError
-syntax_test/32: MissingCompileTimeError
-syntax_test/33: MissingCompileTimeError
-syntax_test/60: MissingCompileTimeError
-syntax_test/61: MissingCompileTimeError
+syntax_test/28: MissingCompileTimeError # Issue 29763
+syntax_test/29: MissingCompileTimeError # Issue 29763
+syntax_test/30: MissingCompileTimeError # Issue 29763
+syntax_test/31: MissingCompileTimeError # Issue 29763
+syntax_test/32: MissingCompileTimeError # Issue 29763
+syntax_test/33: MissingCompileTimeError # Issue 29763
+syntax_test/60: MissingCompileTimeError # Issue 30176
+syntax_test/61: MissingCompileTimeError # Issue 30176
type_variable_bounds2_test: MissingCompileTimeError
type_variable_bounds3_test/00: MissingCompileTimeError
type_variable_bounds4_test/01: MissingCompileTimeError
@@ -490,13 +451,6 @@
[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk ]
export_ambiguous_main_test: MissingCompileTimeError
-[ $arch == simdbc64 && $compiler == dartk && $mode == debug && $strong ]
-partial_tearoff_instantiation_test/05: Crash # Issue http://dartbug.com/32340
-partial_tearoff_instantiation_test/06: Crash # Issue http://dartbug.com/32340
-partial_tearoff_instantiation_test/07: Crash # Issue http://dartbug.com/32340
-partial_tearoff_instantiation_test/08: Crash # Issue http://dartbug.com/32340
-partial_tearoff_instantiation_test/none: Crash # Issue http://dartbug.com/32340
-
[ $compiler != dart2js && $compiler != dartk && $compiler != dartkp && $fasta ]
const_optional_args_test/01: MissingCompileTimeError
@@ -504,12 +458,6 @@
compile_time_constant_c_test/02: MissingCompileTimeError
const_constructor_nonconst_field_test/01: MissingCompileTimeError
const_syntax_test/05: MissingCompileTimeError
-mixin_of_mixin_test/01: MissingCompileTimeError
-mixin_of_mixin_test/02: MissingCompileTimeError
-mixin_of_mixin_test/03: MissingCompileTimeError
-mixin_of_mixin_test/04: MissingCompileTimeError
-mixin_of_mixin_test/05: MissingCompileTimeError
-mixin_of_mixin_test/06: MissingCompileTimeError
mixin_super_2_test/01: MissingCompileTimeError
mixin_super_2_test/03: MissingCompileTimeError
mixin_supertype_subclass_test/02: MissingCompileTimeError
@@ -652,8 +600,6 @@
for_in_side_effects_test/01: MissingCompileTimeError
function_propagation_test: RuntimeError
function_subtype_inline2_test: RuntimeError
-function_type_alias6_test/none: RuntimeError
-generic_function_dcall_test: RuntimeError
generic_instanceof2_test: RuntimeError
generic_is_check_test: RuntimeError
generic_no_such_method_dispatcher_simple_test: CompileTimeError # Issue 31533
@@ -986,7 +932,6 @@
function_propagation_test: RuntimeError
function_subtype_inline2_test: RuntimeError
function_type_alias6_test/none: RuntimeError
-generic_function_dcall_test: RuntimeError
generic_instanceof2_test: RuntimeError
generic_is_check_test: RuntimeError
generic_methods_recursive_bound_test/03: Crash, Pass
@@ -1338,9 +1283,33 @@
type_promotion_more_specific_test/04: CompileTimeError
[ $compiler == fasta && !$strong ]
+abstract_factory_constructor_test/00: MissingCompileTimeError
+abstract_getter_test/01: MissingCompileTimeError
+abstract_syntax_test/00: MissingCompileTimeError
call_method_implicit_invoke_local_test/05: MissingCompileTimeError
+closure_invoked_through_interface_target_field_test: MissingCompileTimeError
+closure_invoked_through_interface_target_getter_test: MissingCompileTimeError
+factory2_test/03: MissingCompileTimeError
+implicit_this_test/01: MissingCompileTimeError
+implicit_this_test/04: MissingCompileTimeError
invalid_override_in_mixin_test/01: MissingCompileTimeError
map_literal1_test/01: MissingCompileTimeError
+mixin_of_mixin_test/01: MissingCompileTimeError
+mixin_of_mixin_test/02: MissingCompileTimeError
+mixin_of_mixin_test/03: MissingCompileTimeError
+mixin_of_mixin_test/04: MissingCompileTimeError
+mixin_of_mixin_test/05: MissingCompileTimeError
+mixin_of_mixin_test/06: MissingCompileTimeError
+nsm5_test: MissingCompileTimeError
+override_inheritance_mixed_test/06: MissingCompileTimeError
+override_inheritance_mixed_test/07: MissingCompileTimeError
+override_inheritance_no_such_method_test/01: MissingCompileTimeError
+override_inheritance_no_such_method_test/05: MissingCompileTimeError
+override_inheritance_no_such_method_test/06: MissingCompileTimeError
+override_inheritance_no_such_method_test/07: MissingCompileTimeError
+override_inheritance_no_such_method_test/09: MissingCompileTimeError
+override_inheritance_no_such_method_test/10: MissingCompileTimeError
+override_inheritance_no_such_method_test/12: MissingCompileTimeError
[ $fasta && $strong ]
compile_time_constant_k_test/01: MissingCompileTimeError
@@ -1920,7 +1889,7 @@
override_field_method4_negative_test: Fail
override_field_method5_negative_test: Fail
override_field_test/01: MissingCompileTimeError
-override_inheritance_abstract_test/28: MissingCompileTimeError
+override_inheritance_abstract_test/*: Skip # Tests Dart 2 semantics
override_inheritance_field_test/05: MissingCompileTimeError
override_inheritance_field_test/07: MissingCompileTimeError
override_inheritance_field_test/08: MissingCompileTimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index c188ce8..8ff6cb8 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -763,6 +763,7 @@
override_inheritance_abstract_test/02: MissingCompileTimeError
override_inheritance_abstract_test/03: MissingCompileTimeError
override_inheritance_abstract_test/04: MissingCompileTimeError
+override_inheritance_abstract_test/07: MissingCompileTimeError
override_inheritance_abstract_test/08: MissingCompileTimeError
override_inheritance_abstract_test/09: MissingCompileTimeError
override_inheritance_abstract_test/10: MissingCompileTimeError
@@ -779,7 +780,6 @@
override_inheritance_abstract_test/24: MissingCompileTimeError
override_inheritance_abstract_test/25: MissingCompileTimeError
override_inheritance_abstract_test/26: MissingCompileTimeError
-override_inheritance_abstract_test/28: MissingCompileTimeError
override_inheritance_field_test/05: MissingCompileTimeError
override_inheritance_field_test/07: MissingCompileTimeError
override_inheritance_field_test/08: MissingCompileTimeError
@@ -824,7 +824,6 @@
override_inheritance_mixed_test/08: MissingCompileTimeError
override_inheritance_mixed_test/09: MissingCompileTimeError
override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/02: MissingCompileTimeError
override_inheritance_no_such_method_test/06: MissingCompileTimeError
override_inheritance_no_such_method_test/07: MissingCompileTimeError
override_inheritance_no_such_method_test/09: MissingCompileTimeError
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index 3c012b6..8e3a8e3 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -774,6 +774,7 @@
override_inheritance_abstract_test/02: MissingCompileTimeError
override_inheritance_abstract_test/03: MissingCompileTimeError
override_inheritance_abstract_test/04: MissingCompileTimeError
+override_inheritance_abstract_test/07: MissingCompileTimeError
override_inheritance_abstract_test/08: MissingCompileTimeError
override_inheritance_abstract_test/09: MissingCompileTimeError
override_inheritance_abstract_test/10: MissingCompileTimeError
@@ -790,7 +791,6 @@
override_inheritance_abstract_test/24: MissingCompileTimeError
override_inheritance_abstract_test/25: MissingCompileTimeError
override_inheritance_abstract_test/26: MissingCompileTimeError
-override_inheritance_abstract_test/28: MissingCompileTimeError
override_inheritance_field_test/05: MissingCompileTimeError
override_inheritance_field_test/07: MissingCompileTimeError
override_inheritance_field_test/08: MissingCompileTimeError
@@ -834,13 +834,11 @@
override_inheritance_mixed_test/07: MissingCompileTimeError
override_inheritance_mixed_test/09: MissingCompileTimeError
override_inheritance_no_such_method_test/01: MissingCompileTimeError
-override_inheritance_no_such_method_test/02: MissingCompileTimeError
override_inheritance_no_such_method_test/06: MissingCompileTimeError
override_inheritance_no_such_method_test/07: MissingCompileTimeError
override_inheritance_no_such_method_test/09: MissingCompileTimeError
override_inheritance_no_such_method_test/10: MissingCompileTimeError
override_inheritance_no_such_method_test/12: MissingCompileTimeError
-override_inheritance_no_such_method_test/13: MissingCompileTimeError
override_method_with_field_test/02: MissingCompileTimeError
part2_test/01: MissingCompileTimeError
positional_parameters_type_test/01: MissingCompileTimeError
@@ -1124,6 +1122,7 @@
function_type/function_type96_test: RuntimeError # Issue 30475
function_type/function_type9_test: RuntimeError # Issue 30475
function_type_alias2_test: RuntimeError
+function_type_alias6_test/none: RuntimeError
invalid_override_in_mixin_test/01: MissingCompileTimeError
type_literal_prefix_call_test: RuntimeError
diff --git a/tests/language_2/override_inheritance_abstract_test.dart b/tests/language_2/override_inheritance_abstract_test.dart
index bb6c449..026fcf3 100644
--- a/tests/language_2/override_inheritance_abstract_test.dart
+++ b/tests/language_2/override_inheritance_abstract_test.dart
@@ -6,7 +6,7 @@
method1(); //# 01: ok
method5(); //# 05: ok
method6(); //# 06: ok
- method7();
+ method7(); //# 07: compile-time error
get getter8; //# 08: compile-time error
set setter9(_); //# 09: compile-time error
method10(); //# 10: compile-time error
@@ -44,7 +44,7 @@
var member21; //# 21: continued
}
-abstract class Class extends A implements I, J {
+class Class extends A implements I, J {
method1() {} //# 01: continued
method2(); //# 02: compile-time error
get getter3; //# 03: compile-time error
@@ -62,5 +62,5 @@
}
main() {
- new Class(); //# 28: compile-time error
+ new Class();
}
diff --git a/tests/language_2/override_inheritance_no_such_method_test.dart b/tests/language_2/override_inheritance_no_such_method_test.dart
index 1f90b47..535f5a4 100644
--- a/tests/language_2/override_inheritance_no_such_method_test.dart
+++ b/tests/language_2/override_inheritance_no_such_method_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 use of @proxy and noSuchMethod in relation to abstract methods in
+// Test use of noSuchMethod in relation to abstract methods in
// concrete classes.
abstract class A {
@@ -17,14 +17,9 @@
method11(); //# 11: ok
}
-@proxy //# 02: compile-time error
-@proxy //# 07: continued
-@proxy //# 10: continued
class Class1 extends A implements I {
method1(); //# 01: compile-time error
- method2(); //# 02: continued
-
noSuchMethod(_) => null; //# 03: ok
method3(); //# 03: continued
@@ -39,11 +34,10 @@
noSuchMethod(_) => null; //# 11: continued
}
-@proxy //# 12: compile-time error
class B {
- method12(); //# 12: continued
+ method12(); //# 12: compile-time error
- noSuchMethod(_) => null; //# 13: compile-time error
+ noSuchMethod(_) => null; //# 13: ok
method13(); //# 13: continued
}
diff --git a/tests/language_2/ref_before_declaration_test.dart b/tests/language_2/ref_before_declaration_test.dart
index d5b8908..65f58ac 100644
--- a/tests/language_2/ref_before_declaration_test.dart
+++ b/tests/language_2/ref_before_declaration_test.dart
@@ -66,7 +66,7 @@
}
void testLibPrefix() {
- var pie = math.PI;
+ var pie = math.pi;
final math = 0; // //# 05: compile-time error
}
diff --git a/tests/language_2/syntax_test.dart b/tests/language_2/syntax_test.dart
index 0982b99..5946a1d 100644
--- a/tests/language_2/syntax_test.dart
+++ b/tests/language_2/syntax_test.dart
@@ -112,7 +112,9 @@
class ListFactory<E> implements List<E>
native "Array" //# 33: syntax error
-{}
+{
+ noSuchMethod(_) => null; // Allow unimplemented methods
+}
abstract class I implements UNKNOWN; //# 34: syntax error
@@ -138,7 +140,9 @@
class XListFactory<E> implements List<E>
hest "Array" //# 40: syntax error
-{}
+{
+ noSuchMethod(_) => null; // Allow unimplemented methods
+}
class YWindow extends DOMWindow
for "*Window" //# 41: syntax error
@@ -162,7 +166,9 @@
class YListFactory<E> implements List<E>
for "Array" //# 46: syntax error
-{}
+{
+ noSuchMethod(_) => null; // Allow unimplemented methods
+}
class A {
const A()
diff --git a/tests/lib_2/async/null_future_zone_test.dart b/tests/lib_2/async/null_future_zone_test.dart
deleted file mode 100644
index 802c399..0000000
--- a/tests/lib_2/async/null_future_zone_test.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "package:expect/expect.dart";
-import "package:async_helper/async_helper.dart";
-import 'dart:async';
-
-main() {
- asyncStart(2);
- () async {
- var it = new StreamIterator(new Stream.fromIterable([]));
- Expect.isFalse(await it.moveNext());
-
- Future nullFuture;
- Future falseFuture;
-
- runZoned(() {
- nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
- falseFuture = it.moveNext();
- }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
- (Zone self, ZoneDelegate parent, Zone zone, void f()) {
- Expect.fail("Should not be called");
- }));
-
- nullFuture.then((value) {
- Expect.isNull(value);
- asyncEnd();
- });
-
- falseFuture.then((value) {
- Expect.isFalse(value);
- asyncEnd();
- });
- }();
-}
diff --git a/tests/lib_2/convert/html_escape_test.dart b/tests/lib_2/convert/html_escape_test.dart
index 55de638..f40c18d 100644
--- a/tests/lib_2/convert/html_escape_test.dart
+++ b/tests/lib_2/convert/html_escape_test.dart
@@ -75,7 +75,7 @@
const _COUNT = 3;
void main() {
- _testMode(HTML_ESCAPE, _TEST_INPUT, _OUTPUT_UNKNOWN);
+ _testMode(htmlEscape, _TEST_INPUT, _OUTPUT_UNKNOWN);
_testMode(const HtmlEscape(), _TEST_INPUT, _OUTPUT_UNKNOWN);
_testMode(
const HtmlEscape(HtmlEscapeMode.unknown), _TEST_INPUT, _OUTPUT_UNKNOWN);
@@ -85,5 +85,5 @@
_OUTPUT_SQ_ATTRIBUTE);
_testMode(
const HtmlEscape(HtmlEscapeMode.element), _TEST_INPUT, _OUTPUT_ELEMENT);
- _testMode(HTML_ESCAPE, _NOOP, _NOOP);
+ _testMode(htmlEscape, _NOOP, _NOOP);
}
diff --git a/tests/lib_2/math/double_pow_test.dart b/tests/lib_2/math/double_pow_test.dart
index 4d95575..4feac67 100644
--- a/tests/lib_2/math/double_pow_test.dart
+++ b/tests/lib_2/math/double_pow_test.dart
@@ -153,8 +153,8 @@
// Some non-exceptional values.
checkVeryClose(16.0, pow(4.0, 2.0));
- checkVeryClose(SQRT2, pow(2.0, 0.5));
- checkVeryClose(SQRT1_2, pow(0.5, 0.5));
+ checkVeryClose(sqrt2, pow(2.0, 0.5));
+ checkVeryClose(sqrt1_2, pow(0.5, 0.5));
// Denormal result.
Expect.identical(5e-324, pow(2.0, -1074.0));
// Overflow.
diff --git a/tests/lib_2/math/math2_test.dart b/tests/lib_2/math/math2_test.dart
index e24e3b2..83f0183 100644
--- a/tests/lib_2/math/math2_test.dart
+++ b/tests/lib_2/math/math2_test.dart
@@ -14,21 +14,21 @@
static void testConstants() {
// Source for mathematical constants is Wolfram Alpha.
Expect.equals(
- 2.7182818284590452353602874713526624977572470936999595749669, math.E);
+ 2.7182818284590452353602874713526624977572470936999595749669, math.e);
Expect.equals(2.3025850929940456840179914546843642076011014886287729760333,
- math.LN10);
+ math.ln10);
Expect.equals(
- 0.6931471805599453094172321214581765680755001343602552541206, math.LN2);
+ 0.6931471805599453094172321214581765680755001343602552541206, math.ln2);
Expect.equals(1.4426950408889634073599246810018921374266459541529859341354,
- math.LOG2E);
+ math.log2e);
Expect.equals(0.4342944819032518276511289189166050822943970058036665661144,
- math.LOG10E);
+ math.log10e);
Expect.equals(
- 3.1415926535897932384626433832795028841971693993751058209749, math.PI);
+ 3.1415926535897932384626433832795028841971693993751058209749, math.pi);
Expect.equals(0.7071067811865475244008443621048490392848359376884740365883,
- math.SQRT1_2);
+ math.sqrt1_2);
Expect.equals(1.4142135623730950488016887242096980785696718753769480731766,
- math.SQRT2);
+ math.sqrt2);
}
static checkClose(double a, double b, EPSILON) {
@@ -37,65 +37,65 @@
}
static void testSin() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, math.sin(0.0), EPSILON);
- checkClose(0.0, math.sin(math.PI), EPSILON);
- checkClose(0.0, math.sin(2.0 * math.PI), EPSILON);
- checkClose(1.0, math.sin(math.PI / 2.0), EPSILON);
- checkClose(-1.0, math.sin(math.PI * (3.0 / 2.0)), EPSILON);
+ checkClose(0.0, math.sin(math.pi), EPSILON);
+ checkClose(0.0, math.sin(2.0 * math.pi), EPSILON);
+ checkClose(1.0, math.sin(math.pi / 2.0), EPSILON);
+ checkClose(-1.0, math.sin(math.pi * (3.0 / 2.0)), EPSILON);
}
static void testCos() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(1.0, math.cos(0.0), EPSILON);
- checkClose(-1.0, math.cos(math.PI), EPSILON);
- checkClose(1.0, math.cos(2.0 * math.PI), EPSILON);
- checkClose(0.0, math.cos(math.PI / 2.0), EPSILON);
- checkClose(0.0, math.cos(math.PI * (3.0 / 2.0)), EPSILON);
+ checkClose(-1.0, math.cos(math.pi), EPSILON);
+ checkClose(1.0, math.cos(2.0 * math.pi), EPSILON);
+ checkClose(0.0, math.cos(math.pi / 2.0), EPSILON);
+ checkClose(0.0, math.cos(math.pi * (3.0 / 2.0)), EPSILON);
}
static void testTan() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, math.tan(0.0), EPSILON);
- checkClose(0.0, math.tan(math.PI), EPSILON);
- checkClose(0.0, math.tan(2.0 * math.PI), EPSILON);
- checkClose(1.0, math.tan(math.PI / 4.0), EPSILON);
+ checkClose(0.0, math.tan(math.pi), EPSILON);
+ checkClose(0.0, math.tan(2.0 * math.pi), EPSILON);
+ checkClose(1.0, math.tan(math.pi / 4.0), EPSILON);
}
static void testAsin() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, math.asin(0.0), EPSILON);
- checkClose(math.PI / 2.0, math.asin(1.0), EPSILON);
- checkClose(-math.PI / 2.0, math.asin(-1.0), EPSILON);
+ checkClose(math.pi / 2.0, math.asin(1.0), EPSILON);
+ checkClose(-math.pi / 2.0, math.asin(-1.0), EPSILON);
}
static void testAcos() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, math.acos(1.0), EPSILON);
- checkClose(math.PI, math.acos(-1.0), EPSILON);
- checkClose(math.PI / 2.0, math.acos(0.0), EPSILON);
+ checkClose(math.pi, math.acos(-1.0), EPSILON);
+ checkClose(math.pi / 2.0, math.acos(0.0), EPSILON);
}
static void testAtan() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, math.atan(0.0), EPSILON);
- checkClose(math.PI / 4.0, math.atan(1.0), EPSILON);
- checkClose(-math.PI / 4.0, math.atan(-1.0), EPSILON);
+ checkClose(math.pi / 4.0, math.atan(1.0), EPSILON);
+ checkClose(-math.pi / 4.0, math.atan(-1.0), EPSILON);
}
static void testAtan2() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, math.atan2(0.0, 5.0), EPSILON);
- checkClose(math.PI / 4.0, math.atan2(2.0, 2.0), EPSILON);
- checkClose(3 * math.PI / 4.0, math.atan2(0.5, -0.5), EPSILON);
- checkClose(-3 * math.PI / 4.0, math.atan2(-2.5, -2.5), EPSILON);
+ checkClose(math.pi / 4.0, math.atan2(2.0, 2.0), EPSILON);
+ checkClose(3 * math.pi / 4.0, math.atan2(0.5, -0.5), EPSILON);
+ checkClose(-3 * math.pi / 4.0, math.atan2(-2.5, -2.5), EPSILON);
}
static checkVeryClose(double a, double b) {
@@ -127,32 +127,32 @@
static void testSqrt() {
checkVeryClose(2.0, math.sqrt(4.0));
- checkVeryClose(math.SQRT2, math.sqrt(2.0));
- checkVeryClose(math.SQRT1_2, math.sqrt(0.5));
+ checkVeryClose(math.sqrt2, math.sqrt(2.0));
+ checkVeryClose(math.sqrt1_2, math.sqrt(0.5));
checkVeryClose(1e50, math.sqrt(1e100));
checkVeryClose(1.1111111061110855443054405046358901279277111935183977e56,
math.sqrt(12345678901234e99));
}
static void testExp() {
- checkVeryClose(math.E, math.exp(1.0));
+ checkVeryClose(math.e, math.exp(1.0));
final EPSILON = 1e-15;
- checkClose(10.0, math.exp(math.LN10), EPSILON);
- checkClose(2.0, math.exp(math.LN2), EPSILON);
+ checkClose(10.0, math.exp(math.ln10), EPSILON);
+ checkClose(2.0, math.exp(math.ln2), EPSILON);
}
static void testLog() {
// Even though E is imprecise, it is good enough to get really close to 1.
// We still provide an epsilon.
- checkClose(1.0, math.log(math.E), 1e-16);
- checkVeryClose(math.LN10, math.log(10.0));
- checkVeryClose(math.LN2, math.log(2.0));
+ checkClose(1.0, math.log(math.e), 1e-16);
+ checkVeryClose(math.ln10, math.log(10.0));
+ checkVeryClose(math.ln2, math.log(2.0));
}
static void testPow() {
checkVeryClose(16.0, math.pow(4.0, 2.0));
- checkVeryClose(math.SQRT2, math.pow(2.0, 0.5));
- checkVeryClose(math.SQRT1_2, math.pow(0.5, 0.5));
+ checkVeryClose(math.sqrt2, math.pow(2.0, 0.5));
+ checkVeryClose(math.sqrt1_2, math.pow(0.5, 0.5));
}
static bool parseIntThrowsFormatException(str) {
diff --git a/tests/lib_2/math/math_test.dart b/tests/lib_2/math/math_test.dart
index 3e1e879..ca32951 100644
--- a/tests/lib_2/math/math_test.dart
+++ b/tests/lib_2/math/math_test.dart
@@ -11,21 +11,21 @@
static void testConstants() {
// Source for mathematical constants is Wolfram Alpha.
Expect.equals(
- 2.7182818284590452353602874713526624977572470936999595749669, E);
+ 2.7182818284590452353602874713526624977572470936999595749669, e);
Expect.equals(
- 2.3025850929940456840179914546843642076011014886287729760333, LN10);
+ 2.3025850929940456840179914546843642076011014886287729760333, ln10);
Expect.equals(
- 0.6931471805599453094172321214581765680755001343602552541206, LN2);
+ 0.6931471805599453094172321214581765680755001343602552541206, ln2);
Expect.equals(
- 1.4426950408889634073599246810018921374266459541529859341354, LOG2E);
+ 1.4426950408889634073599246810018921374266459541529859341354, log2e);
Expect.equals(
- 0.4342944819032518276511289189166050822943970058036665661144, LOG10E);
+ 0.4342944819032518276511289189166050822943970058036665661144, log10e);
Expect.equals(
- 3.1415926535897932384626433832795028841971693993751058209749, PI);
+ 3.1415926535897932384626433832795028841971693993751058209749, pi);
Expect.equals(
- 0.7071067811865475244008443621048490392848359376884740365883, SQRT1_2);
+ 0.7071067811865475244008443621048490392848359376884740365883, sqrt1_2);
Expect.equals(
- 1.4142135623730950488016887242096980785696718753769480731766, SQRT2);
+ 1.4142135623730950488016887242096980785696718753769480731766, sqrt2);
}
static checkClose(double a, double b, EPSILON) {
@@ -34,65 +34,65 @@
}
static void testSin() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, sin(0.0), EPSILON);
- checkClose(0.0, sin(PI), EPSILON);
- checkClose(0.0, sin(2.0 * PI), EPSILON);
- checkClose(1.0, sin(PI / 2.0), EPSILON);
- checkClose(-1.0, sin(PI * (3.0 / 2.0)), EPSILON);
+ checkClose(0.0, sin(pi), EPSILON);
+ checkClose(0.0, sin(2.0 * pi), EPSILON);
+ checkClose(1.0, sin(pi / 2.0), EPSILON);
+ checkClose(-1.0, sin(pi * (3.0 / 2.0)), EPSILON);
}
static void testCos() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(1.0, cos(0.0), EPSILON);
- checkClose(-1.0, cos(PI), EPSILON);
- checkClose(1.0, cos(2.0 * PI), EPSILON);
- checkClose(0.0, cos(PI / 2.0), EPSILON);
- checkClose(0.0, cos(PI * (3.0 / 2.0)), EPSILON);
+ checkClose(-1.0, cos(pi), EPSILON);
+ checkClose(1.0, cos(2.0 * pi), EPSILON);
+ checkClose(0.0, cos(pi / 2.0), EPSILON);
+ checkClose(0.0, cos(pi * (3.0 / 2.0)), EPSILON);
}
static void testTan() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, tan(0.0), EPSILON);
- checkClose(0.0, tan(PI), EPSILON);
- checkClose(0.0, tan(2.0 * PI), EPSILON);
- checkClose(1.0, tan(PI / 4.0), EPSILON);
+ checkClose(0.0, tan(pi), EPSILON);
+ checkClose(0.0, tan(2.0 * pi), EPSILON);
+ checkClose(1.0, tan(pi / 4.0), EPSILON);
}
static void testAsin() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, asin(0.0), EPSILON);
- checkClose(PI / 2.0, asin(1.0), EPSILON);
- checkClose(-PI / 2.0, asin(-1.0), EPSILON);
+ checkClose(pi / 2.0, asin(1.0), EPSILON);
+ checkClose(-pi / 2.0, asin(-1.0), EPSILON);
}
static void testAcos() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, acos(1.0), EPSILON);
- checkClose(PI, acos(-1.0), EPSILON);
- checkClose(PI / 2.0, acos(0.0), EPSILON);
+ checkClose(pi, acos(-1.0), EPSILON);
+ checkClose(pi / 2.0, acos(0.0), EPSILON);
}
static void testAtan() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, atan(0.0), EPSILON);
- checkClose(PI / 4.0, atan(1.0), EPSILON);
- checkClose(-PI / 4.0, atan(-1.0), EPSILON);
+ checkClose(pi / 4.0, atan(1.0), EPSILON);
+ checkClose(-pi / 4.0, atan(-1.0), EPSILON);
}
static void testAtan2() {
- // Given the imprecision of PI we can't expect better results than this.
+ // Given the imprecision of pi we can't expect better results than this.
final double EPSILON = 1e-15;
checkClose(0.0, atan2(0.0, 5.0), EPSILON);
- checkClose(PI / 4.0, atan2(2.0, 2.0), EPSILON);
- checkClose(3 * PI / 4.0, atan2(0.5, -0.5), EPSILON);
- checkClose(-3 * PI / 4.0, atan2(-2.5, -2.5), EPSILON);
+ checkClose(pi / 4.0, atan2(2.0, 2.0), EPSILON);
+ checkClose(3 * pi / 4.0, atan2(0.5, -0.5), EPSILON);
+ checkClose(-3 * pi / 4.0, atan2(-2.5, -2.5), EPSILON);
}
static checkVeryClose(double a, double b) {
@@ -124,26 +124,26 @@
static void testSqrt() {
checkVeryClose(2.0, sqrt(4.0));
- checkVeryClose(SQRT2, sqrt(2.0));
- checkVeryClose(SQRT1_2, sqrt(0.5));
+ checkVeryClose(sqrt2, sqrt(2.0));
+ checkVeryClose(sqrt1_2, sqrt(0.5));
checkVeryClose(1e50, sqrt(1e100));
checkVeryClose(1.1111111061110855443054405046358901279277111935183977e56,
sqrt(12345678901234e99));
}
static void testExp() {
- checkVeryClose(E, exp(1.0));
+ checkVeryClose(e, exp(1.0));
final EPSILON = 1e-15;
- checkClose(10.0, exp(LN10), EPSILON);
- checkClose(2.0, exp(LN2), EPSILON);
+ checkClose(10.0, exp(ln10), EPSILON);
+ checkClose(2.0, exp(ln2), EPSILON);
}
static void testLog() {
// Even though E is imprecise, it is good enough to get really close to 1.
// We still provide an epsilon.
- checkClose(1.0, log(E), 1e-16);
- checkVeryClose(LN10, log(10.0));
- checkVeryClose(LN2, log(2.0));
+ checkClose(1.0, log(e), 1e-16);
+ checkVeryClose(ln10, log(10.0));
+ checkVeryClose(ln2, log(2.0));
}
static bool parseIntThrowsFormatException(str) {
diff --git a/tests/lib_2/math/pi_test.dart b/tests/lib_2/math/pi_test.dart
index aec9789..ea31ade 100644
--- a/tests/lib_2/math/pi_test.dart
+++ b/tests/lib_2/math/pi_test.dart
@@ -48,5 +48,5 @@
// Mmmmh, Pie!
var pie = 4.0 * (inside / (inside + outside));
print("$pie");
- Expect.isTrue(((PI - 0.009) < pie) && (pie < (PI + 0.009)));
+ Expect.isTrue(((pi - 0.009) < pie) && (pie < (pi + 0.009)));
}
diff --git a/tests/standalone_2/io/certificates/bad_server_chain.pem b/tests/standalone_2/io/certificates/bad_server_chain.pem
new file mode 100644
index 0000000..3c5024b
--- /dev/null
+++ b/tests/standalone_2/io/certificates/bad_server_chain.pem
@@ -0,0 +1,58 @@
+-----BEGIN CERTIFICATE-----
+MIIDJzCCAg+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVpbnRl
+cm1lZGlhdGVhdXRob3JpdHkwHhcNMTgwNDIzMjAxNjM0WhcNMjgwNDIwMjAxNjM0
+WjAXMRUwEwYDVQQDDAxiYWRsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQC6gVBNsFLEkomxJ1VRe5rZ1ELduRLHJKio9zTrh+o/6EaCZ4X6
+EIr3CwVx7UiBDRyCApGZXbqvtNbP/ihbjRvxmlvCSL9ztF9tNrLqsaEq4w5KvQDT
+5u27+pAzdLjjoFTK6VZfw+AhEZHxiokEDDYB3t6gWkfabOstDouLyEYL25RLKaGQ
+v/Qb7XU6K4f20OnuXVoQ4FxNdqtvm7TgmXBT0kp+f62q6BvLUIzewpblBlgT5h3h
+KAZF7RDpGBxRgYxA6ZH4n3mv4kh84YtTODRGfb8ugdaQjrgTWOhQ4nddcdR5TVww
+A8Jp+G000RQ97Go0zgd29CicKF96zbGdKFkZAgMBAAGjdTBzMAwGA1UdEwEB/wQC
+MAAwHQYDVR0OBBYEFG8s5yvy1kAoNjJ5PYrx9RNSPFJXMB8GA1UdIwQYMBaAFCpT
+tHybjDJ/Jz25uI9Bxikc1muYMA4GA1UdDwEB/wQEAwIDqDATBgNVHSUEDDAKBggr
+BgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAgom55wfxp9ywWKZOzaGCa+uXZjPK
+rmdUcnJLduRdnchuIsQUZa3Ijpzn7Dw+UZV8ggxvU0L07PbT0QlZUoKhDj6BlZ4W
+TAseBh5QyBUeEdMU+Tr2fXGM6+mmVURBLTX5I2Chmnw2ymqqUK8MtbUhPXbfZayV
+eUV35iloOhm3q/5rKBtfdNq31zrg+Naam6/UyRgBhinweFFXiYeZRpctD3w3cA3g
+RGjuNNNRASZZzAXGiE4IOv9drd0/wGajwBT1DJDQOAxZPfADC3wEcDRG4ve1SYHY
+5N3AlidXe8dPDePhlxH3JH9s2WPi6lgiHQSmtzyeehbzqpJ9JCBM5BerdQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIDLjCCAhagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
+YXV0aG9yaXR5MB4XDTE4MDQyMzIwMTYzM1oXDTI4MDQyMDIwMTYzM1owIDEeMBwG
+A1UEAwwVaW50ZXJtZWRpYXRlYXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAsSFr3/sYhGFF7gEZSn7Am8ATtPhTo5ypQqSAv/4Uy+k4zvT3
+b3OZyYpzr5Wsa6NXcEKwNipyR1GBpYwaYI/W4DSi+COdH4DQSZDQFr+hvmXRazzj
+VSsOxF6veGLcza53meLPRb4o4yVoZARd6xR5i3OUD4kezvOjpmlFT3OKNU0Di+Vq
+qeS14/at6Vt6G0rS8CluafD7Z0/5zp6vrImKwC6OWzlmmcAqBGsE/BTzrAxLdt4K
+uw3Xs3uvS3YZIAC536C1Mop1n4FBUGxeUMWH+I/llzK9ol1pmQHJrxfOD5WdFuuE
+iFfpiOmBdUfDBbEPllmIvzUBFOo5VhxVmq8EHQIDAQABo3sweTASBgNVHRMBAf8E
+CDAGAQH/AgEAMB0GA1UdDgQWBBQqU7R8m4wyfyc9ubiPQcYpHNZrmDAfBgNVHSME
+GDAWgBT0rD9lRUhqJvAg7hfBEz/ZqHCzHjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAGjRSFvVeIrRF3iuA5vr
+SgufTCNzAyEz7+pDKflzHSQXF1fdItiOdPGv1i57gIr7HaYuxvBiEklhmnWreYye
+Tn6ghfhEHhdZHBpihDXuIvLizhtR/lg9CDZrHjuY6nukyx4JnWwUBR3TulPK5gJu
+jB9YISY8tjXrvVNqdi0a+G0T4HHnVs3v6Nd/Qdsxfp4maAB1U3HFmR3DXKTxDtBK
+mNNMqf9PpX4lw4o6UieiEwOMd+4REhmwLNTwhWrhVg5q6GKQl873Ge/7J2nXvgkH
+nUbEsncLsArqqrz201f2m32A6pinwY/j85vEeRkHwlsU0jOvVnHzAlggP0u/kFAF
+EjE=
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIC/jCCAeagAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
+YXV0aG9yaXR5MB4XDTE4MDQyMzIwMTYzM1oXDTI4MDQyMDIwMTYzM1owGDEWMBQG
+A1UEAwwNcm9vdGF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALkvRWdbx9GwxePkh0nnpht4MrPW5NkZBORqfhFi7PFbQ7Rwgl39hm9iAmci
+pOWZGSJi7AaqLuSID0UEeRdG/fNFawI5XIoxP+TmdKdrk/SaTJQKKJiZ9B8+EG0z
+hV8/v6jrlwj0gq9eBBAmOInnmQiEYE4gKFNvh9xdP//gi+otBf30gmtJ4AxXOTu/
+M+XEigXelmIvy57b+B+qnonTFcGkXhSr+JfCA1l6ta7OtknQtItpV0FDr/d8hA+6
+Bn25ZSisd00GC3CUMX1tM5V8cQE6GO/W2mnpUFVvWycYx9wDyU7rlyNUf8nWeoIW
+3d3s/6KAppa07KrkLiTantIrqMUCAwEAAaNTMFEwHQYDVR0OBBYEFPSsP2VFSGom
+8CDuF8ETP9mocLMeMB8GA1UdIwQYMBaAFPSsP2VFSGom8CDuF8ETP9mocLMeMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ1VynTevPnNtwevQpUa
+zlur64N+Dx/yF4gvd4byjO+JouMJLaJqV2dwnqgAahg6YKasVtv4xX9MVJR2IjIb
+Tfa0nYQxM5clwk3J78nh82Ncb2RNeYJyNmSdocnOkmTSoOGUFOxtRz1vmKUcrfwl
+yENO/qGe/sYmOv0IWJjeGQ2OZPblRumV4dJy3qTHFmOLpYwA0BGiIV5uj5Ou7QU1
+R5PY2pnJg4RXeaq95Pr50lkO9vpRyFUJHjR+P+J05M9FbjLPOQIFkpMYx/GyBg5n
+P+omyagOGW8bXfBTtUYu+rP/k+BC5AxI3Kdv/AD5vyHKi/JXhP3ycb8AYx5ENHoK
+qjA=
+-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/bad_server_key.pem b/tests/standalone_2/io/certificates/bad_server_key.pem
new file mode 100644
index 0000000..4b5670a
--- /dev/null
+++ b/tests/standalone_2/io/certificates/bad_server_key.pem
@@ -0,0 +1,29 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIIE4zAcBgoqhkiG9w0BDAEBMA4ECPLRqWLveTDuAgIIAASCBMGjMwpu3Hy4cuO7
+i3p2EyH+UJGm9J/KcRN2ys6E5rwCdLHtURLmdWsmtNkDNTvmgdllXfdVhO9XavRJ
+ShBSvTzvOokpl/nxRaFmhEhMWskdGpP1WSp+GtQiVHM2gczDR2jNZDZKWEnZfU5B
+CUt0VJkokJZxmdeSpFIrTTJxcOQZEsbb1ujrAMpWqEvIGq+U2Is7A5RxWJl1XKmY
+5QB9nfw5Olj0J499kMKJx8WjRhmfQHu+qMpN2HglBVK44fnk/I5ilNdhuScuaKPZ
+csOv5D5Ojlgc6hQG1zCPh8lRNH1MXLd2BMwEJqPSKNbvfrUWvr7BnJMoOdnlZwaH
+73/zJrMwuUpZzAm2sgHZlJhELoYyK0A40IhAz4u9XF1iv35yK2D6/O2qJO6VUzqD
+TsdSnUYaUTZkZdgfucR+EbmPSw7r+QYEsHFzErPTUR64hwIeC3bCv0Q4hrPskxKj
+135iDQDbuCykeNe8s51qgEt8oawdig/Anaguksuj/eKGTWZXPrhA3LTYqBkaX8ao
+XFWkj3ALvjRHCeLfQ5AlXyd3mJiHl93pxH9GIaTiL66ptYvfcN5tERcD6GL/sUXh
+vJ0kr8HsBS9WTFvVg4dzQ9NAqtRoDB1IUqEq2dLys/gjrhE26tmUnuaXiOuokSWx
+HXEK/2pWAqZ/ZA7vbQ/DyV25TDeEP3SRKeTDLdlWBjTNUKyBv3nfsoZBK1K2wOUh
+UDmB3TMBEdXI6L2FvjxMuDRJxruhn7HhRz7ifsizRHPyaPDbUFF9IK/x9qPAzufK
+lk6NqqcgJdNg8wxv/dVYAHeJmMOhTau9CL6N7AYo2VDWphlZSjBgtTZw7sY739c2
+35ziR9yBoJyveFcQko01ycJrjhivn3cqbFXZfsIbecDKz+8qZhWjKw/yysv0X6tI
+tB1btpWtlVB8h7WlXWgUGJWKCUFXRC1fCJA5W7LoTnvZ9VvYMBRKUbDsMiSWNcTZ
+mLmJj0yIhve9uCHsFXBidTCT751CYucaZYvOqNr3pKf4eTQQNCYB5Pt6jx4V7Xks
+ZDjr5ljVy6Ux6NweQT2Zs/hOnuS3q1XoLbRVsW9d9YttahnNyjP8il3HphSzBHOF
+SUReTlgAHEbSUZTZ1z2GXFblUJPb2syfJOIXP5qHQtSrGN3CkQ//JvysxlOck41h
+fLO6TZUadorgEHqb+en6h6gVvDvI3i0T66yWwurhlEvWZepAWetzSv64VsVGXEjc
+lrT8yj6AAZYISoYZU0vtM0tP+FDqvyA597DZMiDDBU6chmGxWhcnaqIIDTP2KQIJ
+Z0NAYp924NHAgnTq1FbXxllej6vxcCwymsnXGyCMhsOt1RTAVHeY0uZ5qPCToJ30
+xS/WTrVH5z0xtp2Qz+INFleNnseYKBJvEDfk+gK0sLm533fehnFeB+GgNqqV9hKc
+bLpU+C3VrsxX0JLWYgfweVDT+jT78FXzUIkWykvBGv+iv+ztFUFiopDzJzfLriH8
+K4kG2o/K3MQWrygjnt+iTjpBe08auX9Ot8X65ygArOa0zOy0nUwSQGyPXL/7L3dQ
+LqS6ZBpreqXClTeegKH8SwEYnXLFNDuU1GuD+pRyQJVWYfqiiWeenaKpCi73VWaK
+J+9e86VqcQ==
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/standalone_2/io/certificates/client1.p12 b/tests/standalone_2/io/certificates/client1.p12
index 8d19d04..69a674d 100644
--- a/tests/standalone_2/io/certificates/client1.p12
+++ b/tests/standalone_2/io/certificates/client1.p12
Binary files differ
diff --git a/tests/standalone_2/io/certificates/client1.pem b/tests/standalone_2/io/certificates/client1.pem
index 429cd72..468a677 100644
--- a/tests/standalone_2/io/certificates/client1.pem
+++ b/tests/standalone_2/io/certificates/client1.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDBzCCAe+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9jbGll
-bnRhdXRob3JpdHkwHhcNMTUxMDI3MTAyNjM1WhcNMjUxMDI0MTAyNjM1WjAQMQ4w
-DAYDVQQDDAV1c2VyMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALlg
-zRZlohMtAg44+kPk04G/gIkdeyh7toUA3nR/2sS11j8EutHewezvMV8YyxBxQn8f
-8x8FkDbrE/6GYg2Dsu6TxrXIFre9Lt5jLlJi/6qEaVtXNTdP3vKO87FJ7YVLCeYe
-MxuTCdHloeUICP5x3GJz3AVdcg/S9qRWrpm8LdRdFk66l8vD+aDf+Oqe+mLVtAr6
-kqkdq1nUJOkRBp+zFMmB3Zfm28aYew6BmFQSscxemZyJxiv4dB+EDr821kEjgGBY
-IQGpdADrfh3j9JAzEr30o6sjfr6QWKHG6ZD7xhSl7rIxmx1yoKoJh8vLpcQfdv79
-7VZZT5N7xjz0xkjqTA0CAwEAAaNiMGAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUMpcX
-0o3lu3BTmaKwCfIJMO5aMs4wHwYDVR0jBBgwFoAUtyLBueMoMi7TborRvM7CnwOi
-SQ4wEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAAB1rNFg
-wdK79r7WO0OvE90uvtFf8sO2kqwW/7JIP/kcnIwIIkNiffUEfLfVr7aecK0rPer4
-DDZFAciuaOcts7dTxXRU+la1ZEPaEyx1mHaC6HJbgFYC9cG30L6GJGkZkIGOCTn+
-/yPxTM//dSc7YACc90GNTeUFVnAw6vskH91Ph4VYbdYxt7L1d1pzvBeun6Qi0eJq
-rkWQ2DOO9h9E6Rnt8Jea3w7WzX5P8pBjm74bv38YBKefawPeiiXck2Q/lUehLePV
-U1MRdy1QWC924+p6cXbR1GEhg0FZyvS/9WdpLMGIat/j/98juN6qyAbw7XXhlB1g
-fBHlfXbx+KMZAuY=
+MIIDBzCCAe+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9jbGll
+bnRhdXRob3JpdHkwHhcNMTgwNDIzMjAxNjM0WhcNMjgwNDIwMjAxNjM0WjAQMQ4w
+DAYDVQQDDAV1c2VyMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0k
+FC9D1LDt0as0Kk3EbMKR9IXBtKazVOXq1y3VYmSM+r8l70HViKZOQ13vWHBt+iYI
+2ATt+lFfKrAo2xO74d7bJD6ag12Ar60mpfVWO1lrmbSzGGsfJZl1kI7Z9SJ4RQCp
+xqAKu+ZtIY40fO7YqRFT+yPjjdcsNOYHedATa4coq1ZHnFbU4HZgerFIeMCHr2Mb
+MPuqraJuk4G7yJgPWMwNawKKfWWiH4aRNGgmVqInVTh6hLLFC2po0koF8h4fyVz9
+BmptVyn7+/V5OOWteiaaNanRlSc9ozljSxVnqSUD9JuaIINd4+0Lf5Yp2hcPj54l
+Mt8q51euv2JGzk5NLOcCAwEAAaNiMGAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUZOyE
++fTDi2XHfAg9q9Ci4B3/PKIwHwYDVR0jBBgwFoAU+TlPoMTEPn2GHUDuD49Nm+iq
+vwwwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAADdlG1z
+kHKAI4HQojtx8yWM/D5q48/5wQjmsx6oBfaWPobL1mkc0iPQ6GNARY1Mv8OPbGkk
+8M00qVikaUyA3K14mZBzNY1Pprr06JRlDuYZABU7Jcfd6pe1LAfM0GMlng5KbHlK
+NqsECNQNIihEECdJ9UxEl191aAf4hnfvnL+RRaalCCeM9LZY+CTCuG1RH61H8Dxl
+Fq615+4DP7bKHUf2FiYVcqu9MqLCw6YasrCNFcBQuZuzO/3HUyBWHOQ2jb5w5uID
+cDsV5rGtQjc0DNc7v34lHYsfP8BWRF+z/VE865wgupQ3f5OTTHPBeMy1bO0t5rU6
+iDdImoz2KZ3ZwDc=
-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/client1_key.p12 b/tests/standalone_2/io/certificates/client1_key.p12
index 5d11e73..8f5681d 100644
--- a/tests/standalone_2/io/certificates/client1_key.p12
+++ b/tests/standalone_2/io/certificates/client1_key.p12
Binary files differ
diff --git a/tests/standalone_2/io/certificates/client1_key.pem b/tests/standalone_2/io/certificates/client1_key.pem
index 0e2ef5e..16c513c 100644
--- a/tests/standalone_2/io/certificates/client1_key.pem
+++ b/tests/standalone_2/io/certificates/client1_key.pem
@@ -1,29 +1,29 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIIE4jAcBgoqhkiG9w0BDAEBMA4ECF4ZB27y60SWAgIIAASCBMCEL3ZCzfC0q+m+
-B8gM9jQe1JFRD5reAuwK6+3speBS4KE+wjbcyQq09/5UoQu3Dci1WG1nKLB1u0Bk
-w9NuRahWCpvVLzz/GQ6Psesixq3V69zD3N6iMl/XQKymQBwGK51xIkeJO+6Skh2d
-+qoyBHINTlKY9+548Zgqu+Z3mI3pGmdhd7hCiamiffDwCLEqRxbXdZdLpC9GpAP5
-HOqXHzN2aZbAGHb1GkHVxskSNzAwlEEZhh4Ibe6o7U65hoL9borewT+gj6sQohI5
-/LHL0P2bVvtRZiwBVPUX8HZWuVYIFb6GEGTTqOofNhNHvHaKUlD8Uxi5/h/Xi8fq
-xpdkjIn7VXj9e+I3TkfiphDtk0+Q+f+UkuPyuzU1PafinPfRK1J6gk+ZqAQHW/sp
-g6GVr2r4PkOrBPsA6jmCnQhs2C4MlZyR2p65qjVutdkKU5NgftW+giK9shgglcza
-38RF8i01THOnD3j+2teM/t/Ziqb2PGWv/bmvhcYqt1aG186Pe3bBCxhh/L7bqNKD
-q7sxDmaDE2pTkfyvh07udarmBQc5gvfXYqwghbqP/n7wizqjeEJgAwwHyi8LLsFV
-XreBQ/8Z2gQwXurrh5WD+7KSgvgopW/oVC8a3++8Hmf5Nkj27lACzoDWTG2/Swah
-O1MmdtPyy/KCbf5ujt2BlXM9D206Rsr6hoO9UZ1s1ohRdJReVGc4NZ4XrVWc4TKT
-gUAFTaHIKgFe/DgLaQn8L8Pqb8B/JfoSgQ74r69S434Kc+EDKui8wnkgso5bqrr1
-M07H9Xo+OtG1D6rma2EUlpoU06CAIcyqNx5fHJ3xfk9GHScQi4U6vEDCAQTNTS65
-I5AOHthZ2kZzfXvP6TF39S5D37NrV7/WJu7ZFaJx3bUGwnS2HYTwjFPABHpVLMwJ
-nBylVJs+h7bCZdBNCWgTytcn1mYMCvXVmrW8VTwBRjUQsy4rgE2wjpZuIM9rx+gZ
-HtNvy5t2RlOSqVKapyvV0ll7qbT1lwGIePxjttiWmNbgbwRBQzjv6FZ1Yo331Fl4
-qgXGcvZWgsgQFPXviKmDx+9KJ2oL35cLnDcMCRN7lLPdAhk8J/XrUq/iIYXNxud6
-f9mfVOsd0LT030je/N25IdEoPimTnps/INGGNug+FuJ3dCeIQGwB7uQB5ozoHL5h
-hzdQYq5+FWksuHPCOL1YLRJux9sH6OYxlXy2oigLtA05EHhq83Wwb2oTW6boo+rs
-gKqzc7OtFgYDsV8R1raoqlzAv3GNgkzyuHTSUakDdnJYmfcoOuK+Ch+MjVeZW5bS
-Ir7uqugUqqI/AiO/eHkvoGpQs0c67ao0qPR7ZQna/1FBj1O8J/dI4JBUtPvDa0tW
-7U+Ja/twJWri+Nn6/iEEWEuM/xx/xFmxrTb4WYza1ysrCls5l6POjQu2n6dT52+o
-cobwltkJmSNoIT2SYRuvEfgGlwyzY5p5B8U24HIAkNJIkO7hc9oD1mbq+K526HNl
-h6TG7RGUOffXIYuykrMmCTRRnv3bXmjTgsvWhVFujpCSQf9PqkQpv+KQPeFmy12h
-TA1QNtdVOZlh2GLEUgZuJVytyEz4m+3BfvBql5K9rlAUSQqsLJDKVxsmBDl132o3
-yy9JR7iC
+MIIE5DAcBgoqhkiG9w0BDAEBMA4ECDBZgjf6kratAgIIAASCBML/IWUC3eylBatQ
+SawxuYM81Ak+LnjidlC+/3APnYNFdppoUbZu8WK9Nj/SPQBXnpuGpVuUWWaIkjzI
+d3tivlboh17M6TBSBiI6wopmi4uO7k+BKTCH0chdqKM8OjJajpeGOfejW7Jojnr8
+Yx8G3IYO5DWWXSU7kp4w5WwN93vvRZh4pmLwOIFLwdGVNooBu1FRBaguPFQoWgO+
+JFbT3qDYvpttdsgtOalqpudHcQteapgQkUfKwk+unB+dgxS3sTTY+Zy9ClnArd0d
+1wlgOm34jgDxxWIdfaa/l/hcz82F45HeA/jwvP7/EXTni3hkDT92vTMHJQPKguhL
+V+be+XNnGihNT3k6fXpHAr6Y+HXN+4nqd/ndKRkfzVeZkNMzjFgeWy/LQ1bruMSP
+Cz/RdpatxH/fRvazCXe160YIB25cwFMUvt4saiN3SvHETxC02SsA6hY1TZB2UOmO
+/PjyXiXB6nyHchwEbTkzwnHKJSDX5FlAvweOkJ9PhKZIgfXRG/5orqXWqczUV+Vk
+FyC4338kCtY8sGYlbBvusNqugkbOEMaKUtJd4R2vvXUUbcybrAmjHg10To1uHAxw
+2xE/gewcvrPTdo4upV4JzyGszJte3MWspv/tyXY/s8F1/ENwatPOZWqMDAa3WSaz
+dzi8cfQFVo2Pq2b2TtrBE0KPKt1Zw7zIHYcyWnGJaLTzXhFdaw+8jY1+tudnBtzE
+l84fqwBX/9sAjOdCz1TkIskdpDhWQm33MvTbWluj1FvEQMYgLpLpLIOs1kw8DMNE
+TH6rrVnMDpdr9bGOPwmxBa/SC6n0EHGczSJ0IyGt5GrjOLGhPgYvETUDCH00GUY7
+cH+v6S4Lh4Z19aBcDEcW+drU/I+HfoC1qhnqksvNJFeYbEDqTcXD3De2zd6MzMiL
+qoxaNWshoAYqMbNdZNeCjlJTFq4mU2v+CxLKxUmnoLzkPsrfdniEfTwCg+LoERCk
+t588o6N8g3JfPDjpTWiH17KEuiKvDYPfheKr3Zu2Zzgd3Rm63l80vINtYffTfKB+
+U/nuGRzX0bRqWLZlEEnUJxnSYurG7DH7uozCgozbkVqYRE75/wxBDNSeOWSy5HDq
+0UeRafBOJmGU/7jhNLnKP8YZ5o+XBI3oQMfLb2q3uNbLTc73vqWoFCC7hCUJnKq9
+z8yD7mETNYTyS1g7uGt2yWmuYinyn+VQkg/f2ExQ36HCjzkoaJyobpNgdzoTF0+q
+dhzCAfb3C04p/iUIXFQCD1YdZVgwXCmAgxRKbfJaW6B1FFHe3PYzac5RQtvLJQ0q
+u8sUFlkhr/ax5wUXhILXnvH0S7QtEcGTRJawna7TBZWk4kvTlU0N0DcLU+LKUmws
+3seuvYROHZ6VSrGikL5IMVZl+h47Ub4HMTvdWAiaSMchl3fxVFW5kGJcAMvoI9ZO
+ENIWeZVgXrz7FPfnfYnLLNXeHC1LM0hYHztkaXuBC4ujupPmy4/oHNmQXx/yufDK
+wmQEWsFPf/JrwraW6PAX+/FvZ2G97LIDoxB4TjaIdBXKr17YRAOD9PCcqWBtFrHu
+4HXwSF4tALbDlMryhjMNOOs0jWjl+jx1LtZ+I+USOjX+3G1ZBWgl5Ps29YMJYF5e
+NRqyXPpLaco=
-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/standalone_2/io/certificates/client2.pem b/tests/standalone_2/io/certificates/client2.pem
index f34bde4..3999216 100644
--- a/tests/standalone_2/io/certificates/client2.pem
+++ b/tests/standalone_2/io/certificates/client2.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDBzCCAe+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9jbGll
-bnRhdXRob3JpdHkwHhcNMTUxMDI3MTAyNjM1WhcNMjUxMDI0MTAyNjM1WjAQMQ4w
-DAYDVQQDDAV1c2VyMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMay
-a0BYpNJHlwcNz6TyX+D6dKnqxUfdHQDgW9/5Hl4RiHDKAH+2iVYEsedksOmxNDlV
-HqZg4fBsyPVRzeGqia7nCsN3KlMbaqZgNI3ynvvMFIJkb3e/ZJtodg+cYzqnOu2F
-G3LijzRJG363aavTnjLdFumLnsOtSDdYnjRM43eeE3X2ajAiKkE9r6b6/wt8Ki5T
-GVIm9kG674iCloawK6dgCBA1dDPsKmzhcFoAl5UMpQSvd1OuW034qryE+RzQ0RCe
-G5u2leVgiuoq2rpmPL6fA0BHsyJ3wP1Gs74i+NhZdhiBhv+E89sfKaJOPpmDBW7b
-3jCpEmgRSm5h5SDm8KsCAwEAAaNiMGAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUj0t8
-BdHrTqd7aKIV4+OLWvT6WX4wHwYDVR0jBBgwFoAUtyLBueMoMi7TborRvM7CnwOi
-SQ4wEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBABQ4PKRG
-VJYhWtktqpilP+C8CXsMArsqkEdMwHgQi8Xv3WVvXZpiLZHvO0To9J3+dgD2sOys
-MphZBXMJuOfX/+3IGerxsBxVj7Pnx37nn83g6PfCvGgVQQw7cGUjn5/Dw6apH2HH
-eO3yG+fgYeMNXyKt1KVWYeIToZfXUFvm+oMbWxxdpcctsKLRgCRvf1+r5EK9xE8+
-jYYk3S3pXvsk3qwWJz3pjg6zR3IbakkEuhE1Gl0Wrf4zZ9DOB8rd00/xirAuuYwm
-aIZ3KcFCTgVdGtB41q03D31xWNZPODCxAEADiICNE+3cuUMCi3wwBeCrybXSLhj/
-6St8K4NBvg+xL/w=
+MIIDBzCCAe+gAwIBAgIBAzANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9jbGll
+bnRhdXRob3JpdHkwHhcNMTgwNDIzMjAxNjM0WhcNMjgwNDIwMjAxNjM0WjAQMQ4w
+DAYDVQQDDAV1c2VyMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMBX
+SxFoCWZxTjBXABqf9ygEicJDLcBEnStDbo+XE7CGDNkf6AmYy9cFpNK3brxfmU3x
+ZKizie8fLeTMpaEAAR73epPn9Ui3JzP4e12HacLXVIZkDdoOjCcksf1n6CTXSTeC
+K2h8aO5oqC7ouwUcWbCbdLu+OxohAMg/vmDXvRhJC9uoJyW8hYJwpAuErh/W/DuX
+LUgAAGNnztth5UWmrD4b9vdhU6yR2t5Gj2DP44Ow5rlurqC0vY87pe+rMal26mF0
+GLYCzrJOdEwy4WGCuTxXtbqvud9NIV++61cPtOu+GQKwI6/KJ5TEKsLGEbqQViM4
+rUguOwndm/7HK00nbPECAwEAAaNiMGAwCQYDVR0TBAIwADAdBgNVHQ4EFgQUKpNM
+YZQHavaPs/m1k7d3a9QbbTQwHwYDVR0jBBgwFoAU+TlPoMTEPn2GHUDuD49Nm+iq
+vwwwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBAJSyKalJ
+wh1wQvmZ6sa7imzsWwQ70Kr8NgDZFm8Ds1dkfzxsP6lBey8HVY6nDQD2LzJth9ny
+2AXcHvT9DKRto1cJI5z8/H+E7oKzPAlJjnmhL2dIk6als2KYfBHu5eLyaoWOCvNx
+wd4wk+JrMIQuVeIQwrG2PPDSUffScb5y5OeW1PvmnAJNTI9bHSIA4/GN45/l3FEW
+IZuOBfv5DjubYoWT+OJMfSXoqIU/wciyx+SsSPHQ8F8Q6eLgxhF74eqIrIWstZIf
+bwo83QHOpqXxEkzny4Pbdcis6rGWagH6JXHoiIHcHlsRveMEUGLUJaV0nxN2DgUa
+Umod67RaTcbdses=
-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/client2_key.pem b/tests/standalone_2/io/certificates/client2_key.pem
index b4074f9..8bb2fd8 100644
--- a/tests/standalone_2/io/certificates/client2_key.pem
+++ b/tests/standalone_2/io/certificates/client2_key.pem
@@ -1,29 +1,29 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIIE5DAcBgoqhkiG9w0BDAEBMA4ECC/vc3ONj4KfAgIIAASCBMI1liT+B00kYYj+
-VRcEHQVrWsvD648OCd6BNQ9gKTYL5767lHUN0iG2JAdTHTKJy7XeEVVdPweU58jb
-HnS1yWbs0IuUFkCGy9wH3Lb6SkZtEScoAmzsNRdSY3WwmNhUG/yHrLITKM1SGkg3
-nf3ywIJYwO3YH22InVK0puVT/y943F1GXZSvklG/TGawR0uIyNuZOl0rg+5bsCaf
-1VSCWvt/Czgqm9Pc+Iz2PAKwyyjmvqRMBCtKvJTGNEPB63eDyHWQTtvQe0un06AF
-lvB7JYWaTXiwccSww2BuqTdJdBYKWxzPbdBfcqUT5Q9/LE0JhwvfZY/oDeJFP0HC
-HVBajuESZPJgb06xcsiX1qmk/iqAjZVZQ/CQ9K08qXem7YRFxJCy90wjLu3abjzQ
-Nvq0VsI8a8vlODQlr/Z5iXSYEKMYvUwh5Y9e8fc0BOOc1QzOYV2vxy28OVHmigOn
-tVHdj/FXK6N97QgtFzVUTjisO3YFygI2wybrz1BEys/vwqfCBiT+/hu+ur/lCrkn
-E2S6I967TyTvaxn+WCo9EW2Rb66XdI7tL09AkV2VZqJN4PTyis9YYgkr2uKjj4qX
-ySAQp/XHGEF1mmvjeptKTb2CMut0vcP+nl1bsUUXpSiKYGQ2BBcqgTcEFUEd75ms
-kcPMOuHdioaYh72nCRVzsRoDTDGF08NMTndW5PC8RpFsNS0vx8dq/A3VHAvJa2Rc
-9lP939FAU/Ck9b3NxH6hUgfDEFHQ61oW2Inpu4s3eRoClkgyf+aQEZZI7GTiNICm
-xqHosZ+hLe2mYoGk6xl1AruMk7kGeebRaPxzvS0UKfftOQDahFcDp8iEtLAcM1nx
-8Pdu4csyWFk+eBsTT6sPur2ZkD2LO0gLjR+N2nZNTqEJYy7n1jyV7M/JZBfh0fGi
-VX+sb+urTBAlDszX6b1LV7M78MDs6QwziDsrytjuClOWN47wzYbYYnSZZnDtTR+B
-CDHyK5wa8gNs4A+643HvD6sJz6zALOu2UI/9SrvuyYPltCwCUmWJ3A2XxoBmdJ/e
-yHEj/VdsNi6TtQ5qpBWqm43LpF0WAKNgksGnbFjOc/0QsUVk0txB9D6/oC9HyCd8
-u9nR8vLUC7l1dtYL0CwpocqU67qzVoRxrkkyCE4iblusKjr1ZlfstHDS0tPELodo
-8RroSs4vKXV9dzhzLQyqp6PzzdB7y/5Bpn0grxXrwln6/shoSR462h2CB4z9chGA
-Vdsp+KE8LDogIwZDT6iVVrpaBQDLoSxmX+E2IKRCUcj/l+gepEPyHbhOAn8/NxGX
-h16v89aDMtnyWqUcc/Gm2/Qep3o7goRfodyoyWvwy8nq9Lgf/wJIfEGn0lEeR0I/
-/Om/UAiId1o47C3LsGMm+qO+FcWesLA67eMQnp1WYoWpnanb3q4t8PWATzAlW05n
-cA59dYjutUmKJEjrh595AptMLXn6RM1GzA7x53+uAKvXaI+aR8wrtujiJLg9DwY2
-+f4ehwfwNptBxzZX97a7/3lGZ5U7BgDeJhNo9T02VQTvXxB29H6J/v6XYyPCKpuM
-upPhiHzrs9UyMvINfDnd/fJ58qr6TvEuBi0QxMMmOCfccYlj6Q5Bfqp+iuST0igg
-SLmBml+LkIM=
+MIIE5DAcBgoqhkiG9w0BDAEBMA4ECOesX1fugaR0AgIIAASCBMIl6TrcBn0oHRHl
+X3MSXdAyEMLYBaSVgyRUt1gu0WhyT9uu1xlB1VGu14QHY3uqvTMZpJabSYsafV+P
+3dbFmk9YHg3Ss0GPaRcx4Q74NR/3BzMIB3q429JSK+GYKHNkRtdMNiQ9OcFVavhD
+BDApEkavka/A9U5YOB4+/20BPYpfSZT9Z+hLffH6vl6PSsuRzYHdqbbTi44Rff+R
+m62xzgSxG2+n9J68XPaVxVOLAoNQAlPVfq+lxYF04PdZGz8euJMw2C281Ddpo+sU
+Jtvbp0JuAa24GNLM5DnmHvRbfQVxlm6dKJi40Gi0g4ellSs0roqUY+RXUC6VqL/R
+qPWiJhtnvue8zOA6F0C2nFF+Qdtm0UiwEp4TR5jhC5y1+uWzy190mM2fuo0m/7/0
+6FRv2Oc3tnYXTYg0m8h8QjPGCp3A1TwDlTOoeG81GD4sYvu/kPQH0cKmytwAqMJw
+LP6OCgOjEFwWxKkYaBVSnr7aP7f/26F8Rf8eGJO0VH2P67F8usweof30bP9eQ9MR
+rrA9uA0+odpufNMaVbA9Vnj4ipCWR0xqU0Uq+UODVwvI3Vnf1c8gWm9rFCi3hZb5
+kuxtDpXWlR7SgiRejt1cZmWTWijToF81HkFZf9XoS8jdN26XLlhqy45h9G2N3mVQ
+jS0uSAjZVk4A1k/HbicOcj92eL1nXK0QFY7OPL9XBSms+KlwAVN15M2tnfQ5mlxC
+mVAFqho5KQmYipViO/VI5aS/CxVnABSqLxhhj/ge9SQFONjsNDKkaIz7tYtz5KJ+
+dvJAg2IMcOtV4jZIBrNdfslw0TP17GZwrCUibLzEdPQ02awpemyi1sHquR/B9uoi
+3CDsPoDABzVp79wsiYz2sEwY23AaKZtMuQRSbR8BtvmMIArgJ273/vfx92skMdjn
+dpJbxTlNZ/xPo3NSXVTQYxlfeNrGelXvJYT0LxZ4uapMa91gRXRvJsjC3JGu4o+T
+CeMtclG9uYrSOlbyg4WzVKpwIHTjSCp/CkWCBJIkdxKkScwhDoG3mAcglwMikUEt
+Eg60+jPBHH3dTOvuaRXvYDVdPG8SPa3txrR1tetKGB6g7eMjYgbmYDOxQESS0j1H
+cUCIfK+NwKMBRJFy1wjWqZLKhCWrtevAMhpPFa3HWv2fLY0Vf2s6n9W9mr/hA3Tt
+tPo+c5r7M/I2jzxiHSo1bJD/0yeZDegWrB+8+8PzHoFY05458ei1rc9iNTziogl1
+DYOOcBlROOitO3VZYjbab0iwX0zqEuSYQy41zVJHbMQFp+rbIpuPWQpNAC3FxZuW
+iTVchbpHiCHZ+I1Lud3aqN2z3CBC6GLONUoyCvLfmCKoLIbjusZ/xFH9Q7INPOkH
+g2Sr/bw+8oC+FCujORB2iUmFo5fcgrF1FLxFEbYaB629ed8vE+2aII2OA4amsiD5
+1RkylPMD4Tv6FOvp4G37ph98vfdQvZeX9OdkqS3rGdbwSCf6+AngomJEJ7uVA/c7
+Won/1j0eF6JtcRPBo+jFKfdzr6ynu2AoAyKg0Rn/S7HC0YLEB1iPDWpOC39yQp+A
+x4NNJm1NJjR3oby6LdVp2J8GlKuhztxqkJ6aV9BZDM0rEpP4EdA0QClhXnIJ9H6e
+7bQ8uhT8sW8=
-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/standalone_2/io/certificates/client_authority.p12 b/tests/standalone_2/io/certificates/client_authority.p12
index 545282e..76b0575 100644
--- a/tests/standalone_2/io/certificates/client_authority.p12
+++ b/tests/standalone_2/io/certificates/client_authority.p12
Binary files differ
diff --git a/tests/standalone_2/io/certificates/client_authority.pem b/tests/standalone_2/io/certificates/client_authority.pem
index ae9ae5b..142756f 100644
--- a/tests/standalone_2/io/certificates/client_authority.pem
+++ b/tests/standalone_2/io/certificates/client_authority.pem
@@ -1,19 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIDKjCCAhKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9jbGll
-bnRhdXRob3JpdHkwHhcNMTUxMDI3MTAyNjM1WhcNMjUxMDI0MTAyNjM1WjAaMRgw
-FgYDVQQDEw9jbGllbnRhdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCi6wJAs6nppNmTZ3e/wE9l0pAmkMtDONwB9o115XXTG3rmSKfZOxa8
-TFjSn818Pr1OYb9fPdI1Y6x4WY9PELUtQyEBlNcKjwg96vhrP4p2DhqbWsI5nASH
-DSjJsM75bQ7D7qHYzriuAl0Fk1C4LcodRj+5wmErMtvGJG0x06qFbxCCMAJ2kC+h
-SneTN955/YHSXADgxjFlt3s1T0QPnqrr+G7Ro6PrVKLPBulglq7wAeTwrGkPRUt0
-3lDGOSi6i97NbpiXwrGp5XiLUtVCiID6Ro0xKWH4sjJ4JnVjIUG8CQWERc6sFDJM
-4adgFQJagkTUoxWtDGL58+WcbcJa73XJAgMBAAGjezB5MBIGA1UdEwEB/wQIMAYB
-Af8CAQAwHQYDVR0OBBYEFLciwbnjKDIu026K0bzOwp8DokkOMB8GA1UdIwQYMBaA
-FLciwbnjKDIu026K0bzOwp8DokkOMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK
-BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAh8rryWFoGjFdm0i4FLRktF8B
-aUqVCCpFVHIYlFcsQstznIb01X2Zq5nfSfrFxbr5STVGzGJ0HGDuFpicT8+qMnJX
-dou5AuaqubIDWeKL+oAgvI71Nt1gsesixqzFQAoCTRgUjrSGpY2fL7rElV0Ndy9b
-YepVouktP1/GULc8XbIG9ZLx70Id7YTyrITDgbH3hSnbjmmZSr9RKyKas4MXN0s8
-oKGHEgAx7KyNQRppjydz3bDeH/jVbM4W98vwL6rjKUJlOlo0Ru+3+oioFHqLMSvN
-w4f5rQEiuF260h7y8KKxRxQ8rw188gsBapZr4Rcp+y8gdQvlzJONtv3d1dap5A==
+MIIDKjCCAhKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9jbGll
+bnRhdXRob3JpdHkwHhcNMTgwNDIzMjAxNjM0WhcNMjgwNDIwMjAxNjM0WjAaMRgw
+FgYDVQQDDA9jbGllbnRhdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDckwmIcOYIRbH1jcuBCC/y1a4aiqXhvUCty59Cdqzlx0gbrhkVGmf0
+B0Tmo/PW4p9rcl0hwwxGvGoCvsxVpodHQmIxYwwn1sRl2C7Yo2ZHPMYbv9uq+D0d
+kS8SxHb5l4HvpcT7WoqUq8ZWEm0Losbp8cOcrvLiBQgo8xIOKQzKbwrXydnviQKL
+E5iBmUswzHwb7ZK84u6dS3iHbl9iPy+QTfiboT6BNMsO/dm6Nqmdj35fOPQgFUN/
+QR3NsPWL9GtzB9iZc3D7c30FqqqQO/THjaLJIyzdFdF3Fsp+omSuZw/q1d4/R8M3
+FRCcqzbWLA9Dy12kK/9asmlpf/fdHByVAgMBAAGjezB5MBIGA1UdEwEB/wQIMAYB
+Af8CAQAwHQYDVR0OBBYEFPk5T6DExD59hh1A7g+PTZvoqr8MMB8GA1UdIwQYMBaA
+FPk5T6DExD59hh1A7g+PTZvoqr8MMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK
+BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAh4f1I0kXK88S3yC8k0zRAp4n
+RyyjnPW9Sr2nIuC27RgfH0lxWGOlAVVrFUlgifECD/RSoMuQk5yYgAJiALbnfdlP
+AutjtwClWZ6u1BXnwdUxS+ypWtq4Fb4+vz/VRSK24ZNcrI9NF3wkqKHxnjccxROA
+BratiMbHi5VxU63iec2XqAEhqi+ArWks8XJyTvv/tBYOqmmP4Fi0i/wbpzxmFJ61
+ZGUiHFifkYHKBI/HhjDazdeAhAwcFHSbVInea10+V0dkW7sOGnJFW5PyW1F/TBBe
+3dsp8Tz88+oHbSGwV7qF/Qf6U6kRxeVVctmSSCAohUbPH26xhPhk+t1TVdb3EA==
-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/server_chain.p12 b/tests/standalone_2/io/certificates/server_chain.p12
index 79e412d..9ef96a7 100644
--- a/tests/standalone_2/io/certificates/server_chain.p12
+++ b/tests/standalone_2/io/certificates/server_chain.p12
Binary files differ
diff --git a/tests/standalone_2/io/certificates/server_chain.pem b/tests/standalone_2/io/certificates/server_chain.pem
index 341a86f..0d18b96 100644
--- a/tests/standalone_2/io/certificates/server_chain.pem
+++ b/tests/standalone_2/io/certificates/server_chain.pem
@@ -1,59 +1,60 @@
-----BEGIN CERTIFICATE-----
MIIDZDCCAkygAwIBAgIBATANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVpbnRl
-cm1lZGlhdGVhdXRob3JpdHkwHhcNMTUxMDI3MTAyNjM1WhcNMjUxMDI0MTAyNjM1
+cm1lZGlhdGVhdXRob3JpdHkwHhcNMTgwNDIzMjAxNjM0WhcNMjgwNDIwMjAxNjM0
WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCkg/Qr8RQeLTOSgCkyiEX2ztgkgscX8hKGHEHdvlkmVK3JVEIIwkvu
-/Y9LtHZUia3nPAgqEEbexzTENZjSCcC0V6I2XW/e5tIE3rO0KLZyhtZhN/2SfJ6p
-KbOh0HLr1VtkKJGp1tzUmHW/aZI32pK60ZJ/N917NLPCJpCaL8+wHo3+w3oNqln6
-oJsfgxy9SUM8Bsc9WMYKMUdqLO1QKs1A5YwqZuO7Mwj+4LY2QDixC7Ua7V9YAPo2
-1SBeLvMCHbYxSPCuxcZ/kDkgax/DF9u7aZnGhMImkwBka0OQFvpfjKtTIuoobTpe
-PAG7MQYXk4RjnjdyEX/9XAQzvNo1CDObAgMBAAGjgbQwgbEwPAYDVR0RBDUwM4IJ
+ggEKAoIBAQDZE0gF3bAFxBaxAZUFGkeFkF5B8nJD//+14rcz/Kr/Rau38g38jNyp
+K3bsyWIBq/4A/cPykwncG6Z04WD2FrLR1xDdAbO2zD3cQKbOoFOYXeYMmP4FZcbq
+nSngCzfUfJkwXXHfCC6v3XZkmR0ojWp9tGHJ6G4f9QI8wwT/Y9pvAVQVR9+S43C0
+ZAPkuNiMBN3lAH4QF2WTC5GTQo4hR+IAWN28lnqAbVoRMNvFoDenDZxURq2kT/6j
+ot6UB9f6AOugCUlEpVovTX3evPKrIZz68BM4DttA/r2wo6dw3fouZk/REJ38fi7x
+lg5n5ccCmguE2fF5PoAMH7WCc7EupYKNAgMBAAGjgbQwgbEwPAYDVR0RBDUwM4IJ
bG9jYWxob3N0ggkxMjcuMC4wLjGCAzo6MYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAA
-ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSvhJo6taTggJQBukEvMo/PDk8tKTAf
-BgNVHSMEGDAWgBS98L4T5RaIToE3DkBRsoeWPil0eDAOBgNVHQ8BAf8EBAMCA6gw
-EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAHLOt0mL2S4A
-B7vN7KsfQeGlVgZUVlEjem6kqBh4fIzl4CsQuOO8oJ0FlO1z5JAIo98hZinymJx1
-phBVpyGIKakT/etMH0op5evLe9dD36VA3IM/FEv5ibk35iGnPokiJXIAcdHd1zam
-YaTHRAnZET5S03+7BgRTKoRuszhbvuFz/vKXaIAnVNOF4Gf2NUJ/Ax7ssJtRkN+5
-UVxe8TZVxzgiRv1uF6NTr+J8PDepkHCbJ6zEQNudcFKAuC56DN1vUe06gRDrNbVq
-2JHEh4pRfMpdsPCrS5YHBjVq/XHtFHgwDR6g0WTwSUJvDeM4OPQY5f61FB0JbFza
-PkLkXmoIod8=
+ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBSFtW0d7VGk7g7ywHgrf+bbg/BhQTAf
+BgNVHSMEGDAWgBQqU7R8m4wyfyc9ubiPQcYpHNZrmDAOBgNVHQ8BAf8EBAMCA6gw
+EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAKL0FaPO+YM+
+JJgQryvkf2/WqdnnTGg/7A/HCOk1rkT9q0282Bj1OT4GiyOIOTyHkxrF72dSiN4Q
+0hg1YoUITR1uR5odQsnK3YKSfmGfn+IRNuHf/Oy1XfRrjuIgo3syeqquIJM4W1MO
+uZBkqwdXQIYqBGj4E+y32bxGVhI53rb9MyKfugajRxImTO7UnUydHsIgqNG6MfuH
+LXBNUAw6uPLyW6srfWiiDVlkUzSmXYFoScCXTj7u12Ar/hffGKrXqHojSE0XtcRz
+WuncYKJE/pflgClA5Qe64erD3q2w2SfOZDFwizP7aZU9uAMin8NbiE8Nd6h8hoRc
+ztJfeC+1gro=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDLjCCAhagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
-YXV0aG9yaXR5MB4XDTE1MTAyNzEwMjYzNVoXDTI1MTAyNDEwMjYzNVowIDEeMBwG
+YXV0aG9yaXR5MB4XDTE4MDQyMzIwMTYzM1oXDTI4MDQyMDIwMTYzM1owIDEeMBwG
A1UEAwwVaW50ZXJtZWRpYXRlYXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA6GndRFiXk+2q+Ig7ZOWKKGta+is8137qyXz+eVFs5sA0ajMN
-ZBAMWS0TIXw/Yks+y6fEcV/tfv91k1eUN4YXPcoxTdDF97d2hO9wxumeYOMnQeDy
-VZVDKQBZ+jFMeI+VkNpMEdmsLErpZDGob/1dC8tLEuR6RuRR8X6IDGMPOCMw1jLK
-V1bQjPtzqKadTscfjLuKxuLgspJdTrzsu6hdcl1mm8K6CjTY2HNXWxs1yYmwfuQ2
-Z4/8sOMNqFqLjN+ChD7pksTMq7IosqGiJzi2bpd5f44ek/k822Y0ATncJHk4h1Z+
-kZBnW6kgcLna1gDri9heRwSZ+M8T8nlHgIMZIQIDAQABo3sweTASBgNVHRMBAf8E
-CDAGAQH/AgEAMB0GA1UdDgQWBBS98L4T5RaIToE3DkBRsoeWPil0eDAfBgNVHSME
-GDAWgBRxD5DQHTmtpDFKDOiMf5FAi6vfbzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
-BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAD+4KpUeV5mUPw5IG/7w
-eOXnUpeS96XFGuS1JuFo/TbgntPWSPyo+rD4GrPIkUXyoHaMCDd2UBEjyGbBIKlB
-NZA3RJOAEp7DTkLNK4RFn/OEcLwG0J5brL7kaLRO4vwvItVIdZ2XIqzypRQTc0MG
-MmF08zycnSlaN01ryM67AsMhwdHqVa+uXQPo8R8sdFGnZ33yywTYD73FeImXilQ2
-rDnFUVqmrW1fjl0Fi4rV5XI0EQiPrzKvRtmF8ZqjGATPOsRd64cwQX6V+P5hNeIR
-9pba6td7AbNGausHfacRYMyoGJWWWkFPd+7jWOCPqW7Fk1tmBgdB8GzXa3inWIRM
-RUE=
+AQ8AMIIBCgKCAQEAsSFr3/sYhGFF7gEZSn7Am8ATtPhTo5ypQqSAv/4Uy+k4zvT3
+b3OZyYpzr5Wsa6NXcEKwNipyR1GBpYwaYI/W4DSi+COdH4DQSZDQFr+hvmXRazzj
+VSsOxF6veGLcza53meLPRb4o4yVoZARd6xR5i3OUD4kezvOjpmlFT3OKNU0Di+Vq
+qeS14/at6Vt6G0rS8CluafD7Z0/5zp6vrImKwC6OWzlmmcAqBGsE/BTzrAxLdt4K
+uw3Xs3uvS3YZIAC536C1Mop1n4FBUGxeUMWH+I/llzK9ol1pmQHJrxfOD5WdFuuE
+iFfpiOmBdUfDBbEPllmIvzUBFOo5VhxVmq8EHQIDAQABo3sweTASBgNVHRMBAf8E
+CDAGAQH/AgEAMB0GA1UdDgQWBBQqU7R8m4wyfyc9ubiPQcYpHNZrmDAfBgNVHSME
+GDAWgBT0rD9lRUhqJvAg7hfBEz/ZqHCzHjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAGjRSFvVeIrRF3iuA5vr
+SgufTCNzAyEz7+pDKflzHSQXF1fdItiOdPGv1i57gIr7HaYuxvBiEklhmnWreYye
+Tn6ghfhEHhdZHBpihDXuIvLizhtR/lg9CDZrHjuY6nukyx4JnWwUBR3TulPK5gJu
+jB9YISY8tjXrvVNqdi0a+G0T4HHnVs3v6Nd/Qdsxfp4maAB1U3HFmR3DXKTxDtBK
+mNNMqf9PpX4lw4o6UieiEwOMd+4REhmwLNTwhWrhVg5q6GKQl873Ge/7J2nXvgkH
+nUbEsncLsArqqrz201f2m32A6pinwY/j85vEeRkHwlsU0jOvVnHzAlggP0u/kFAF
+EjE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIC+zCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
-YXV0aG9yaXR5MB4XDTE1MTAyNzEwMjYzNFoXDTI1MTAyNDEwMjYzNFowGDEWMBQG
+MIIC/jCCAeagAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
+YXV0aG9yaXR5MB4XDTE4MDQyMzIwMTYzM1oXDTI4MDQyMDIwMTYzM1owGDEWMBQG
A1UEAwwNcm9vdGF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAMl+dcraUM/E7E6zl7+7hK9oUJYXJLnfiMtP/TRFVbH4+2aEN8vXzPbzKdR3
-FfaHczXQTwnTCaYA4u4uSDvSOsFFEfxEwYORsdKmQEM8nGpVX2NVvKsMcGIhh8kh
-ZwJfkMIOcAxmGIHGdMhF8VghonJ8uGiuqktxdfpARq0g3fqIjDHsF9/LpfshUfk9
-wsRyTF0yr90U/dsfnE+u8l7GvVl8j2Zegp0sagAGtLaNv7tP17AibqEGg2yDBrBN
-9r9ihe4CqMjx+Q2kQ2S9Gz2V2ReO/n6vm2VQxsPRB/lV/9jh7cUcS0/9mggLYrDy
-cq1v7rLLQrWuxMz1E3gOhyCYJ38CAwEAAaNQME4wHQYDVR0OBBYEFHEPkNAdOa2k
-MUoM6Ix/kUCLq99vMB8GA1UdIwQYMBaAFHEPkNAdOa2kMUoM6Ix/kUCLq99vMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABrhjnWC6b+z9Kw73C/niOwo
-9sPdufjS6tb0sCwDjt3mjvE4NdNWt+/+ZOugW6dqtvqhtqZM1q0u9pJkNwIrqgFD
-ZHcfNaf31G6Z2YE+Io7woTVw6fFobg/EFo+a/qwbvWL26McmiRL5yiSBjVjpX4a5
-kdZ+aPQUCBaLrTWwlCDqzSVIULWUQvveRWbToMFKPNID58NtEpymAx3Pgir7YjV9
-UnlU2l5vZrh1PTCqZxvC/IdRESUfW80LdHaeyizRUP+6vKxGgSz2MRuYINjbd6GO
-hGiCpWlwziW2xLV1l2qSRLko2kIafLZP18N0ThM9zKbU5ps9NgFOf//wqSGtLaE=
+ggEBALkvRWdbx9GwxePkh0nnpht4MrPW5NkZBORqfhFi7PFbQ7Rwgl39hm9iAmci
+pOWZGSJi7AaqLuSID0UEeRdG/fNFawI5XIoxP+TmdKdrk/SaTJQKKJiZ9B8+EG0z
+hV8/v6jrlwj0gq9eBBAmOInnmQiEYE4gKFNvh9xdP//gi+otBf30gmtJ4AxXOTu/
+M+XEigXelmIvy57b+B+qnonTFcGkXhSr+JfCA1l6ta7OtknQtItpV0FDr/d8hA+6
+Bn25ZSisd00GC3CUMX1tM5V8cQE6GO/W2mnpUFVvWycYx9wDyU7rlyNUf8nWeoIW
+3d3s/6KAppa07KrkLiTantIrqMUCAwEAAaNTMFEwHQYDVR0OBBYEFPSsP2VFSGom
+8CDuF8ETP9mocLMeMB8GA1UdIwQYMBaAFPSsP2VFSGom8CDuF8ETP9mocLMeMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ1VynTevPnNtwevQpUa
+zlur64N+Dx/yF4gvd4byjO+JouMJLaJqV2dwnqgAahg6YKasVtv4xX9MVJR2IjIb
+Tfa0nYQxM5clwk3J78nh82Ncb2RNeYJyNmSdocnOkmTSoOGUFOxtRz1vmKUcrfwl
+yENO/qGe/sYmOv0IWJjeGQ2OZPblRumV4dJy3qTHFmOLpYwA0BGiIV5uj5Ou7QU1
+R5PY2pnJg4RXeaq95Pr50lkO9vpRyFUJHjR+P+J05M9FbjLPOQIFkpMYx/GyBg5n
+P+omyagOGW8bXfBTtUYu+rP/k+BC5AxI3Kdv/AD5vyHKi/JXhP3ycb8AYx5ENHoK
+qjA=
-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/server_key.p12 b/tests/standalone_2/io/certificates/server_key.p12
index 204d42d..c95c46b 100644
--- a/tests/standalone_2/io/certificates/server_key.p12
+++ b/tests/standalone_2/io/certificates/server_key.p12
Binary files differ
diff --git a/tests/standalone_2/io/certificates/server_key.pem b/tests/standalone_2/io/certificates/server_key.pem
index 895b7d2..7598e59 100644
--- a/tests/standalone_2/io/certificates/server_key.pem
+++ b/tests/standalone_2/io/certificates/server_key.pem
@@ -1,29 +1,29 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIIE4zAcBgoqhkiG9w0BDAEBMA4ECBMCjlg8JYZ4AgIIAASCBMFd9cBoZ5xcTock
-AVQcg/HzYJtMceKn1gtMDdC7mmXuyN0shoxhG4BpQInHkFARL+nenesXFxEm4X5e
-L603Pcgw72/ratxVpTW7hPMjiLTEBqza0GjQm7Sarbdy+Vzdp/6XFrAcPfFl1juY
-oyYzbozPsvFHz3Re44y1KmI4HAzU/qkjJUbNTTiPPVI2cDP6iYN2XXxBb1wwp8jR
-iqdZqFG7lU/wvPEbD7BVPpmJBHWNG681zb4ea5Zn4hW8UaxpiIBiaH0/IWc2SVZd
-RliAFo3NEsGxCcsnBo/n00oudGbOJxdOp7FbH5hJpeqX2WhCyJRxIeHOWmeuMAet
-03HFriiEmJ99m2nEJN1x0A3QUUM7ji6vZAb4qb1dyq7LlX4M2aaqixRnaTcQkapf
-DOxX35DEBXSKrDpyWp6Rx4wNpUyi1TKyhaVnYgD3Gn0VfC/2w86gSFlrf9PMYGM0
-PvFxTDzTyjOuPBRa728gZOGXgDOL7qvdInU/opVew7kFeRQHXxHzFCLK5dD+Vrig
-5fS3m0++f55ODkxqHXB8gbXbd3GMmsW6MrGpU7VsCNtbVPdSMW0FalovEB0M+2lj
-1VfuvL+0F5huTe+BgZAt6xgET/CIcZXdNMRPVhraqUjqWtI9Rdk4STPCpU1rDkjG
-YDl/fo4W2T6qQWFUpiC9IvVVGkVxaqfZZ4Qu+V5xPUi6vk95QiTNkN1t+m+sCCgS
-Llkea8Um0aHMy33Lj3NsfL0LMrnpniqcAks8BvcgIZwk1VRqcj7BQVCygJSYrmAR
-DBhMpjWlXuSggnyVPuduZDtnTN+8lCHLOKL3a3bDb6ySaKX49Km6GutDLfpDtEA0
-3mQvmEG4XVm7zy+AlN72qFbtSLDRi/D/uQh2q/ZrFQLOBQBQB56TvEbKouLimUDM
-ascQA3aUyhOE7e+d02NOFIFTozwc/C//CIFeA+ZEwxyfha/3Bor6Jez7PC/eHNxZ
-w7YMXzPW9NhcCcerhYGebuCJxLwzqJ+IGdukjKsGV2ytWDoB2xZiJNu096j4RKcq
-YSJoen0R7IH8N4eDujXR8m9kAl724Uqs1OoAs4VNICvzTutbsgVZ6Z+NMOcfnPw9
-jZkFhot16w8znD+OmhBR7/bzOLpaeUhk7EhNq5M6U0NNWx3WwkDlvU/jx+6/EQe3
-iLEHptH2HYBF1xscaKGbtKNtuQsfdzgWpOX0qK2YbK3yCKvL/xIm1DQmDZDKkWdW
-VNh8oGV1H96CivWlvxhAgXKz9F/83CjMw8YXRk7RJvWR4vtNvXFAvGkFIYCN9Jv9
-p+1ukaYoxSLGBik907I6gWSHqumJiCprUyAX/bVfZfNiYh4hzeA3lhwxZSax3JG4
-7QFPvyepOmF/3AAzS/Pusx6jOZnuCMCkfQi6Wpem1o3s4x+fP7kz00Xuj01ErucM
-S10ixfIh84kXBN3dTRDtDdeCyoMsBKO0W5jDBBlWL02YfdF6Opo1Q4cPh2DYgXMh
-XEszNZSK5LB0y+f3A6Kdx/hkZzHVvMONA70OyrkoZzGyWENhcB0c7ntTJyPPD2qM
-s0HRA2VwF/0ypU3OKERM1Ua5NSkTgvnnVTlV9GO90Tkn5v4fxdl8NzIuJLyGguTP
-Xc0tRM34Lg==
+MIIE4zAcBgoqhkiG9w0BDAEBMA4ECDmmTgwIo/3yAgIIAASCBMHPUDfzHGi72H4W
+nKLepeD31Upra9tvQx6UrRQaBmf0frh5Coo4Yw3Z+IOZQ4ZwxoIv0/kty7FvXVDU
+BMdFqFeVvKKlsMm7Ub0hC5ks7A0mTVqcc9nW/aBL87W4nZsJ3LSLiPYXptBWOGRh
+kVghEsySowsK8OmYDwauLi5ZoZC/3cwy2YIaOC9/J8sbnzAq3EVEpJwI0GIQgYET
+aGGELjpariWrcPUa16dRU5vrBlFL2Sn3BVJU24DFq/8RJwsL2rpWXxg9x5QxoraW
+WPvxIGvanBphthRABjZ4A8mtQwvkKfdqMuJ7bWAA2YqcZnk7N5zh4XmARKvjlM5K
+ujpjRFu4+NjyQ65vqTfAwQptxj9l/nzaSZqV5K8ROlpa+UODNzLsL/gf4l/22zZ+
+/rnyko97NQ0Jhy/m0xPhXd620IWjmsjNZk+txYWx4K0srBTptRTqKWkQuY7DV/N0
+4xEA0y3T1kLXZmGmvoidB8VwWD7ZC4/fhuFKAKQmEccMsR9AUsI0h4bAjJ419AK2
+G1jsirQS5P1vBweddwbzCtztUNuCCFy9LHmJCLE/yJ2JMmnePi7eOiyvsjU4es6b
+yj9/ekbWQwZO5L15UkY9T/pP8kSR+gAvn/92DB+e2U4R+ZK886unDyLCCp0rGsPK
+ijdcwMkAJampirw3iO5FkXbGO4GoVggNUxTTCDnYenY8jcKePlP0YM7A9XZ+kmmS
+1gcNuNikKmfzusvUuvOX4Dt24gCOGa5dDEOeYHsC7SZT40IFogshZyVdKNzlyIxj
+yqIlr9LOGo7vL84aUYUUF2mRJ9n2+ivqRadQ9s59iH96uYjvZ12KztCjHEPVSVHk
++rwd4WJ5ByBV7MeB8370JtwN/ZfzAIB7ONfXP9rrfcP19VC+MpsIuOCYPJERlhBT
+9w/UuThPhM/cXp9YiDJepa0T2vmCRKHSz932WKGe3dZn+0saKa5ShdMSepp9CroE
+ot2aF+uU9rMh+DIeNVLmHFwa5+3UC18G6rIB9wpZCHmg6LyMDf/OwW2/yao/GKXN
+WayHbex+Z4yXrVUo+5m9rFwFgo2Hl8fVdSJhKmvp9HQKQjEgxUhUC9B46ErS5efM
+SPlMOYfWST5eOG55vr04dWI5t2AXAKWAxxowO1OBhj3J0FjCS/vtUkUiFohc91oV
+b11afVtizPQJOJ9D1xNEADemnJq6KNT1pRaeKOA94JKODwBMi4K3KmEN51l1uJZ8
+U5h1CjweXZjmq81Da2LMLtGgJuTUuAT6LWIXLSck7EX35D1mY4lGHcuMqVCQ1St1
+UvRjRFx3rd6aBEgj7M/FNsUAIlq4X6+58wdh3mx31608CYGyQ8p5kPhj26ZxziJj
+WSFW+YiVrLPBXhIn6Q9DIqvMPdTbLM/fDy9G0ZinhHZH+a41t7v+UZh2FtiT+p52
+n+hiHTbkGQgQ8SYZT0WAjiaS+1pVVvv+MRqpsYpnNPYxI5bp6orSFOudF3pdAbqQ
+f4WDOY0kGg2tPmaNpZSz+FPuuiWC7Y0J1+o3fMnrUMvY4XrUwkstFfROdnM0W9YG
+I1MsVM4NhcKPHcVxKWgsmL5yAVl92mz88rhgbsArhcpO5K4lxE1LB/giUZRdTkRP
+bKFBVqrcpg==
-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/standalone_2/io/certificates/server_trusted.pem b/tests/standalone_2/io/certificates/server_trusted.pem
index b943cf9..c6c2cc3 100644
--- a/tests/standalone_2/io/certificates/server_trusted.pem
+++ b/tests/standalone_2/io/certificates/server_trusted.pem
@@ -1,57 +1,58 @@
-----BEGIN CERTIFICATE-----
MIIDLjCCAhagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
-YXV0aG9yaXR5MB4XDTE1MTAyNzEwMjYzNVoXDTI1MTAyNDEwMjYzNVowIDEeMBwG
+YXV0aG9yaXR5MB4XDTE4MDQyMzIwMTYzM1oXDTI4MDQyMDIwMTYzM1owIDEeMBwG
A1UEAwwVaW50ZXJtZWRpYXRlYXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA6GndRFiXk+2q+Ig7ZOWKKGta+is8137qyXz+eVFs5sA0ajMN
-ZBAMWS0TIXw/Yks+y6fEcV/tfv91k1eUN4YXPcoxTdDF97d2hO9wxumeYOMnQeDy
-VZVDKQBZ+jFMeI+VkNpMEdmsLErpZDGob/1dC8tLEuR6RuRR8X6IDGMPOCMw1jLK
-V1bQjPtzqKadTscfjLuKxuLgspJdTrzsu6hdcl1mm8K6CjTY2HNXWxs1yYmwfuQ2
-Z4/8sOMNqFqLjN+ChD7pksTMq7IosqGiJzi2bpd5f44ek/k822Y0ATncJHk4h1Z+
-kZBnW6kgcLna1gDri9heRwSZ+M8T8nlHgIMZIQIDAQABo3sweTASBgNVHRMBAf8E
-CDAGAQH/AgEAMB0GA1UdDgQWBBS98L4T5RaIToE3DkBRsoeWPil0eDAfBgNVHSME
-GDAWgBRxD5DQHTmtpDFKDOiMf5FAi6vfbzAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
-BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAD+4KpUeV5mUPw5IG/7w
-eOXnUpeS96XFGuS1JuFo/TbgntPWSPyo+rD4GrPIkUXyoHaMCDd2UBEjyGbBIKlB
-NZA3RJOAEp7DTkLNK4RFn/OEcLwG0J5brL7kaLRO4vwvItVIdZ2XIqzypRQTc0MG
-MmF08zycnSlaN01ryM67AsMhwdHqVa+uXQPo8R8sdFGnZ33yywTYD73FeImXilQ2
-rDnFUVqmrW1fjl0Fi4rV5XI0EQiPrzKvRtmF8ZqjGATPOsRd64cwQX6V+P5hNeIR
-9pba6td7AbNGausHfacRYMyoGJWWWkFPd+7jWOCPqW7Fk1tmBgdB8GzXa3inWIRM
-RUE=
+AQ8AMIIBCgKCAQEAsSFr3/sYhGFF7gEZSn7Am8ATtPhTo5ypQqSAv/4Uy+k4zvT3
+b3OZyYpzr5Wsa6NXcEKwNipyR1GBpYwaYI/W4DSi+COdH4DQSZDQFr+hvmXRazzj
+VSsOxF6veGLcza53meLPRb4o4yVoZARd6xR5i3OUD4kezvOjpmlFT3OKNU0Di+Vq
+qeS14/at6Vt6G0rS8CluafD7Z0/5zp6vrImKwC6OWzlmmcAqBGsE/BTzrAxLdt4K
+uw3Xs3uvS3YZIAC536C1Mop1n4FBUGxeUMWH+I/llzK9ol1pmQHJrxfOD5WdFuuE
+iFfpiOmBdUfDBbEPllmIvzUBFOo5VhxVmq8EHQIDAQABo3sweTASBgNVHRMBAf8E
+CDAGAQH/AgEAMB0GA1UdDgQWBBQqU7R8m4wyfyc9ubiPQcYpHNZrmDAfBgNVHSME
+GDAWgBT0rD9lRUhqJvAg7hfBEz/ZqHCzHjAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAGjRSFvVeIrRF3iuA5vr
+SgufTCNzAyEz7+pDKflzHSQXF1fdItiOdPGv1i57gIr7HaYuxvBiEklhmnWreYye
+Tn6ghfhEHhdZHBpihDXuIvLizhtR/lg9CDZrHjuY6nukyx4JnWwUBR3TulPK5gJu
+jB9YISY8tjXrvVNqdi0a+G0T4HHnVs3v6Nd/Qdsxfp4maAB1U3HFmR3DXKTxDtBK
+mNNMqf9PpX4lw4o6UieiEwOMd+4REhmwLNTwhWrhVg5q6GKQl873Ge/7J2nXvgkH
+nUbEsncLsArqqrz201f2m32A6pinwY/j85vEeRkHwlsU0jOvVnHzAlggP0u/kFAF
+EjE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIC+zCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
-YXV0aG9yaXR5MB4XDTE1MTAyNzEwMjYzNFoXDTI1MTAyNDEwMjYzNFowGDEWMBQG
+MIIC/jCCAeagAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
+YXV0aG9yaXR5MB4XDTE4MDQyMzIwMTYzM1oXDTI4MDQyMDIwMTYzM1owGDEWMBQG
A1UEAwwNcm9vdGF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAMl+dcraUM/E7E6zl7+7hK9oUJYXJLnfiMtP/TRFVbH4+2aEN8vXzPbzKdR3
-FfaHczXQTwnTCaYA4u4uSDvSOsFFEfxEwYORsdKmQEM8nGpVX2NVvKsMcGIhh8kh
-ZwJfkMIOcAxmGIHGdMhF8VghonJ8uGiuqktxdfpARq0g3fqIjDHsF9/LpfshUfk9
-wsRyTF0yr90U/dsfnE+u8l7GvVl8j2Zegp0sagAGtLaNv7tP17AibqEGg2yDBrBN
-9r9ihe4CqMjx+Q2kQ2S9Gz2V2ReO/n6vm2VQxsPRB/lV/9jh7cUcS0/9mggLYrDy
-cq1v7rLLQrWuxMz1E3gOhyCYJ38CAwEAAaNQME4wHQYDVR0OBBYEFHEPkNAdOa2k
-MUoM6Ix/kUCLq99vMB8GA1UdIwQYMBaAFHEPkNAdOa2kMUoM6Ix/kUCLq99vMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABrhjnWC6b+z9Kw73C/niOwo
-9sPdufjS6tb0sCwDjt3mjvE4NdNWt+/+ZOugW6dqtvqhtqZM1q0u9pJkNwIrqgFD
-ZHcfNaf31G6Z2YE+Io7woTVw6fFobg/EFo+a/qwbvWL26McmiRL5yiSBjVjpX4a5
-kdZ+aPQUCBaLrTWwlCDqzSVIULWUQvveRWbToMFKPNID58NtEpymAx3Pgir7YjV9
-UnlU2l5vZrh1PTCqZxvC/IdRESUfW80LdHaeyizRUP+6vKxGgSz2MRuYINjbd6GO
-hGiCpWlwziW2xLV1l2qSRLko2kIafLZP18N0ThM9zKbU5ps9NgFOf//wqSGtLaE=
+ggEBALkvRWdbx9GwxePkh0nnpht4MrPW5NkZBORqfhFi7PFbQ7Rwgl39hm9iAmci
+pOWZGSJi7AaqLuSID0UEeRdG/fNFawI5XIoxP+TmdKdrk/SaTJQKKJiZ9B8+EG0z
+hV8/v6jrlwj0gq9eBBAmOInnmQiEYE4gKFNvh9xdP//gi+otBf30gmtJ4AxXOTu/
+M+XEigXelmIvy57b+B+qnonTFcGkXhSr+JfCA1l6ta7OtknQtItpV0FDr/d8hA+6
+Bn25ZSisd00GC3CUMX1tM5V8cQE6GO/W2mnpUFVvWycYx9wDyU7rlyNUf8nWeoIW
+3d3s/6KAppa07KrkLiTantIrqMUCAwEAAaNTMFEwHQYDVR0OBBYEFPSsP2VFSGom
+8CDuF8ETP9mocLMeMB8GA1UdIwQYMBaAFPSsP2VFSGom8CDuF8ETP9mocLMeMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ1VynTevPnNtwevQpUa
+zlur64N+Dx/yF4gvd4byjO+JouMJLaJqV2dwnqgAahg6YKasVtv4xX9MVJR2IjIb
+Tfa0nYQxM5clwk3J78nh82Ncb2RNeYJyNmSdocnOkmTSoOGUFOxtRz1vmKUcrfwl
+yENO/qGe/sYmOv0IWJjeGQ2OZPblRumV4dJy3qTHFmOLpYwA0BGiIV5uj5Ou7QU1
+R5PY2pnJg4RXeaq95Pr50lkO9vpRyFUJHjR+P+J05M9FbjLPOQIFkpMYx/GyBg5n
+P+omyagOGW8bXfBTtUYu+rP/k+BC5AxI3Kdv/AD5vyHKi/JXhP3ycb8AYx5ENHoK
+qjA=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIDKjCCAhKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9jbGll
-bnRhdXRob3JpdHkwHhcNMTUxMDI3MTAyNjM1WhcNMjUxMDI0MTAyNjM1WjAaMRgw
-FgYDVQQDEw9jbGllbnRhdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCi6wJAs6nppNmTZ3e/wE9l0pAmkMtDONwB9o115XXTG3rmSKfZOxa8
-TFjSn818Pr1OYb9fPdI1Y6x4WY9PELUtQyEBlNcKjwg96vhrP4p2DhqbWsI5nASH
-DSjJsM75bQ7D7qHYzriuAl0Fk1C4LcodRj+5wmErMtvGJG0x06qFbxCCMAJ2kC+h
-SneTN955/YHSXADgxjFlt3s1T0QPnqrr+G7Ro6PrVKLPBulglq7wAeTwrGkPRUt0
-3lDGOSi6i97NbpiXwrGp5XiLUtVCiID6Ro0xKWH4sjJ4JnVjIUG8CQWERc6sFDJM
-4adgFQJagkTUoxWtDGL58+WcbcJa73XJAgMBAAGjezB5MBIGA1UdEwEB/wQIMAYB
-Af8CAQAwHQYDVR0OBBYEFLciwbnjKDIu026K0bzOwp8DokkOMB8GA1UdIwQYMBaA
-FLciwbnjKDIu026K0bzOwp8DokkOMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK
-BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAh8rryWFoGjFdm0i4FLRktF8B
-aUqVCCpFVHIYlFcsQstznIb01X2Zq5nfSfrFxbr5STVGzGJ0HGDuFpicT8+qMnJX
-dou5AuaqubIDWeKL+oAgvI71Nt1gsesixqzFQAoCTRgUjrSGpY2fL7rElV0Ndy9b
-YepVouktP1/GULc8XbIG9ZLx70Id7YTyrITDgbH3hSnbjmmZSr9RKyKas4MXN0s8
-oKGHEgAx7KyNQRppjydz3bDeH/jVbM4W98vwL6rjKUJlOlo0Ru+3+oioFHqLMSvN
-w4f5rQEiuF260h7y8KKxRxQ8rw188gsBapZr4Rcp+y8gdQvlzJONtv3d1dap5A==
+MIIDKjCCAhKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9jbGll
+bnRhdXRob3JpdHkwHhcNMTgwNDIzMjAxNjM0WhcNMjgwNDIwMjAxNjM0WjAaMRgw
+FgYDVQQDDA9jbGllbnRhdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDckwmIcOYIRbH1jcuBCC/y1a4aiqXhvUCty59Cdqzlx0gbrhkVGmf0
+B0Tmo/PW4p9rcl0hwwxGvGoCvsxVpodHQmIxYwwn1sRl2C7Yo2ZHPMYbv9uq+D0d
+kS8SxHb5l4HvpcT7WoqUq8ZWEm0Losbp8cOcrvLiBQgo8xIOKQzKbwrXydnviQKL
+E5iBmUswzHwb7ZK84u6dS3iHbl9iPy+QTfiboT6BNMsO/dm6Nqmdj35fOPQgFUN/
+QR3NsPWL9GtzB9iZc3D7c30FqqqQO/THjaLJIyzdFdF3Fsp+omSuZw/q1d4/R8M3
+FRCcqzbWLA9Dy12kK/9asmlpf/fdHByVAgMBAAGjezB5MBIGA1UdEwEB/wQIMAYB
+Af8CAQAwHQYDVR0OBBYEFPk5T6DExD59hh1A7g+PTZvoqr8MMB8GA1UdIwQYMBaA
+FPk5T6DExD59hh1A7g+PTZvoqr8MMA4GA1UdDwEB/wQEAwICBDATBgNVHSUEDDAK
+BggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAh4f1I0kXK88S3yC8k0zRAp4n
+RyyjnPW9Sr2nIuC27RgfH0lxWGOlAVVrFUlgifECD/RSoMuQk5yYgAJiALbnfdlP
+AutjtwClWZ6u1BXnwdUxS+ypWtq4Fb4+vz/VRSK24ZNcrI9NF3wkqKHxnjccxROA
+BratiMbHi5VxU63iec2XqAEhqi+ArWks8XJyTvv/tBYOqmmP4Fi0i/wbpzxmFJ61
+ZGUiHFifkYHKBI/HhjDazdeAhAwcFHSbVInea10+V0dkW7sOGnJFW5PyW1F/TBBe
+3dsp8Tz88+oHbSGwV7qF/Qf6U6kRxeVVctmSSCAohUbPH26xhPhk+t1TVdb3EA==
-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/trusted_certs.p12 b/tests/standalone_2/io/certificates/trusted_certs.p12
index 76c76ec..f45af0a 100644
--- a/tests/standalone_2/io/certificates/trusted_certs.p12
+++ b/tests/standalone_2/io/certificates/trusted_certs.p12
Binary files differ
diff --git a/tests/standalone_2/io/certificates/trusted_certs.pem b/tests/standalone_2/io/certificates/trusted_certs.pem
index 8b5bf3e..dd8edb4 100644
--- a/tests/standalone_2/io/certificates/trusted_certs.pem
+++ b/tests/standalone_2/io/certificates/trusted_certs.pem
@@ -1,18 +1,19 @@
-----BEGIN CERTIFICATE-----
-MIIC+zCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
-YXV0aG9yaXR5MB4XDTE1MTAyNzEwMjYzNFoXDTI1MTAyNDEwMjYzNFowGDEWMBQG
+MIIC/jCCAeagAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
+YXV0aG9yaXR5MB4XDTE4MDQyMzIwMTYzM1oXDTI4MDQyMDIwMTYzM1owGDEWMBQG
A1UEAwwNcm9vdGF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAMl+dcraUM/E7E6zl7+7hK9oUJYXJLnfiMtP/TRFVbH4+2aEN8vXzPbzKdR3
-FfaHczXQTwnTCaYA4u4uSDvSOsFFEfxEwYORsdKmQEM8nGpVX2NVvKsMcGIhh8kh
-ZwJfkMIOcAxmGIHGdMhF8VghonJ8uGiuqktxdfpARq0g3fqIjDHsF9/LpfshUfk9
-wsRyTF0yr90U/dsfnE+u8l7GvVl8j2Zegp0sagAGtLaNv7tP17AibqEGg2yDBrBN
-9r9ihe4CqMjx+Q2kQ2S9Gz2V2ReO/n6vm2VQxsPRB/lV/9jh7cUcS0/9mggLYrDy
-cq1v7rLLQrWuxMz1E3gOhyCYJ38CAwEAAaNQME4wHQYDVR0OBBYEFHEPkNAdOa2k
-MUoM6Ix/kUCLq99vMB8GA1UdIwQYMBaAFHEPkNAdOa2kMUoM6Ix/kUCLq99vMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABrhjnWC6b+z9Kw73C/niOwo
-9sPdufjS6tb0sCwDjt3mjvE4NdNWt+/+ZOugW6dqtvqhtqZM1q0u9pJkNwIrqgFD
-ZHcfNaf31G6Z2YE+Io7woTVw6fFobg/EFo+a/qwbvWL26McmiRL5yiSBjVjpX4a5
-kdZ+aPQUCBaLrTWwlCDqzSVIULWUQvveRWbToMFKPNID58NtEpymAx3Pgir7YjV9
-UnlU2l5vZrh1PTCqZxvC/IdRESUfW80LdHaeyizRUP+6vKxGgSz2MRuYINjbd6GO
-hGiCpWlwziW2xLV1l2qSRLko2kIafLZP18N0ThM9zKbU5ps9NgFOf//wqSGtLaE=
+ggEBALkvRWdbx9GwxePkh0nnpht4MrPW5NkZBORqfhFi7PFbQ7Rwgl39hm9iAmci
+pOWZGSJi7AaqLuSID0UEeRdG/fNFawI5XIoxP+TmdKdrk/SaTJQKKJiZ9B8+EG0z
+hV8/v6jrlwj0gq9eBBAmOInnmQiEYE4gKFNvh9xdP//gi+otBf30gmtJ4AxXOTu/
+M+XEigXelmIvy57b+B+qnonTFcGkXhSr+JfCA1l6ta7OtknQtItpV0FDr/d8hA+6
+Bn25ZSisd00GC3CUMX1tM5V8cQE6GO/W2mnpUFVvWycYx9wDyU7rlyNUf8nWeoIW
+3d3s/6KAppa07KrkLiTantIrqMUCAwEAAaNTMFEwHQYDVR0OBBYEFPSsP2VFSGom
+8CDuF8ETP9mocLMeMB8GA1UdIwQYMBaAFPSsP2VFSGom8CDuF8ETP9mocLMeMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ1VynTevPnNtwevQpUa
+zlur64N+Dx/yF4gvd4byjO+JouMJLaJqV2dwnqgAahg6YKasVtv4xX9MVJR2IjIb
+Tfa0nYQxM5clwk3J78nh82Ncb2RNeYJyNmSdocnOkmTSoOGUFOxtRz1vmKUcrfwl
+yENO/qGe/sYmOv0IWJjeGQ2OZPblRumV4dJy3qTHFmOLpYwA0BGiIV5uj5Ou7QU1
+R5PY2pnJg4RXeaq95Pr50lkO9vpRyFUJHjR+P+J05M9FbjLPOQIFkpMYx/GyBg5n
+P+omyagOGW8bXfBTtUYu+rP/k+BC5AxI3Kdv/AD5vyHKi/JXhP3ycb8AYx5ENHoK
+qjA=
-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/untrusted_server_chain.pem b/tests/standalone_2/io/certificates/untrusted_server_chain.pem
index ff6e568..4845069 100644
--- a/tests/standalone_2/io/certificates/untrusted_server_chain.pem
+++ b/tests/standalone_2/io/certificates/untrusted_server_chain.pem
@@ -1,59 +1,60 @@
-----BEGIN CERTIFICATE-----
MIIDZDCCAkygAwIBAgIBATANBgkqhkiG9w0BAQsFADAgMR4wHAYDVQQDDBVpbnRl
-cm1lZGlhdGVhdXRob3JpdHkwHhcNMTUxMDE5MTE1NTEyWhcNMjUxMDE2MTE1NTEy
+cm1lZGlhdGVhdXRob3JpdHkwHhcNMTgwNDIzMTcxNTEzWhcNMjgwNDIwMTcxNTEz
WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDca2l3VIWhnlTqazrA07hiHjgXACUYS/nVox+a2Jar383kBz2kzN6B
-u4K7IwD2msym2IOBp1YT9OKPh9/KkSGvpPelu7ToCoehala32W+0ozh53CR8IpzQ
-tmh7J9oHtN2PcbLgEzHfAWyrY3xp9RpWUONjxoG8xXPedNsZL0Rj65Z3fKAjOypl
-+XJsgrqrNNAi3x0OMdhextMmLrYl+YQjgdND8UpykTSc8Q0vwngDZuLH/Nhx0cAA
-Ade0ZfXS6snwWVxrWke+zGF6yANoiV00gsBhq+WZZ50SmE2mz5LT9uj4t5WpcOI/
-2TlbV9HSjdOEAFD8cJIrK5FkEmz383E1AgMBAAGjgbQwgbEwPAYDVR0RBDUwM4IJ
+ggEKAoIBAQDO+XxT1pAvzkIWvAZJFGEjuIuXz1kNoCDxBHAilptAOCX5sKyLaWTc
+YvzYpDf0LOwU3T/ZtlSinkX2xCY7EXgsGJEFc1RDmhmPmSsY9Az/ewS1TNrTOkD5
+VGUwnRKpl3o+140A/aNYGQfHJRz0+BCLftv7b95HinLDq26d01eTHLOozfGqkcfA
+LfUauiwXRV817ceLiliGUtgW8DDNTVqtHA2aeKVisZZtyeEMc3BsnJDGmU6kcQ4B
+KeLHaaxCufy4bMlObwSLcdlp7R6MTudzKVEjXVz/WRLz7yZYaYDrcacUvsI8v+jX
+B7quGGkLGJH+GxDGMObFWKsAB229c9ZlAgMBAAGjgbQwgbEwPAYDVR0RBDUwM4IJ
bG9jYWxob3N0ggkxMjcuMC4wLjGCAzo6MYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAA
-ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQO+6Atr6tkTBmPasN4oTDUlbxQ1zAf
-BgNVHSMEGDAWgBRrkK4hOni2neySWQNmMfb9imn/+DAOBgNVHQ8BAf8EBAMCA6gw
-EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBACdVUzrhfXoW
-wG0zI9aT6CxD7T0i0WK4fC6Yrx0Pqz53xnuiwBfvuAJ/PRXKYsJMxa2LuHGJKU/A
-nImCXGJHoUwL6x4Eor6fg7L9nPNqtIrQ6tzubxNtVPpLj4tK6Ps3IM+FICYUSX0b
-FLSfnv74afUp/2+0OHsoUVsL1rCTO2WgEkEShLERdJvdcvUSTWHfC5IQORS9vfzG
-+cZGOOPebfm8TY2DJxMYj/t7CHs1Sk550x590sKb/prwtJAYtQxGe7v0m9rihiM3
-dFKZiNh99yXbQ1ELYyhkFP8WAdK8ZTnynGqgAYJmV89Dg8k2uU8z+dahlE3foORD
-Y/Gn0CZE1NY=
+ATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBR6zQbX0GnDCsjksKYXlzovO2yplDAf
+BgNVHSMEGDAWgBSkX16pB/ZB0hzdYIUgMhWO89CxZzAOBgNVHQ8BAf8EBAMCA6gw
+EwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAIDPqZllHvJa
+XSpqOFaT7oFzKbBnV8lLMvYnbDWHL8N+23q+y803GGNRMkDJG98OalqqKMskk4/v
+ek6dhkTHKnB7hunhogIICXCcHOJGaHN67vvkxkP5mTx6AMaPT+q6NXzu2y9YBTkr
+BIw6ZUyPxqIcH4/GezVe+pokvNZHghDePBChALXEmQLBuJy+gM55w4nB5eq8pNnP
+1r9vVhlr4jqiVNd95MglwB4xLQV5SeG8gGwGvad0vvIpHljOwT9TmlofeqqGpPLf
+3LtqrBK5qdxWcn0jDxG/Qe2EfsdmzsCQ+imu5rTc1YMCGZD52mnnq4tZj0hroWLn
+Wys+JpPMdKo=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIDLjCCAhagAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
-YXV0aG9yaXR5MB4XDTE1MTAxOTExNTUxMloXDTI1MTAxNjExNTUxMlowIDEeMBwG
+MIIDLjCCAhagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
+YXV0aG9yaXR5MB4XDTE4MDQyMzE3MTUxMloXDTI4MDQyMDE3MTUxMlowIDEeMBwG
A1UEAwwVaW50ZXJtZWRpYXRlYXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA1OV9iea75DPQ18NppXxEFW26J7IfjUvp4wVnj9m7pOhsByqd
-wwS6hpjlkpEwCyugKD/t7u/VGwp2BB+BeaX7FPj6rnYY82bOJQlyB/vvDmOZfAe2
-84ug9O7QcsQHSQ7YQFuvYKaeYCKdrGjzQPVYkoVdv2js2dYTDG3QSIxpbi305Vef
-ia6Zfs5CAW/SfL36+ETo2pXNlD1ZBGRL8H3z+mMnIEj1Tbaipf+1Npr2l3xqIs1k
-RWsM3X+9xMkWGyvsDdbLIGiTTVxM9kOF0aNLdQIKb2tZsg4jRrFIgiO+5TXwp0FW
-4ldc5/GhtaoPDcsIALyIQc7CJ/PpPm9hnxIy7QIDAQABo3sweTASBgNVHRMBAf8E
-CDAGAQH/AgEAMB0GA1UdDgQWBBRrkK4hOni2neySWQNmMfb9imn/+DAfBgNVHSME
-GDAWgBRpz+jRK9iGqijrL/4WCsGsIjxoETAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
-BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBACcwiLJUPzYGIeGIYGlo
-XlP4++adiPlXvsyTxLdGVSFWJMBV5EhtiXQXaUsOs2PyC7SWxiiUdAgE8Y2tMsF3
-Bh5LY/kKxZQXZuFa+RN1kPlhlYJWdiPyqcBziSPFBtqwudWLDUVSaVAQDhYYVB3K
-5+pFaeQKfhYmPvJKR9U2nTvukOhN1fZM8GUBnm2uaiA3giQ0wxXyQIuqC9S52qbh
-x4D4ZdbshQAgThPkHBoZVmd/NF1TNzitZZy7uaU7GpGrS1dcevN7pEUwm3+KIkIT
-AOSLB2FbFOwPUg6a/lWkFPotT3gl0tdyCaqkfneGCHzVciT0JTS/AqpdYEtuxEMe
-PJk=
+AQ8AMIIBCgKCAQEAvpFatw9XMWQDbKzWtsA5NfjQsddw5wlDpFeRYghyqo/mgWru
+Rapcz6tEpEodc3SZ/4PCwE1PmYZuxhcYnaDCM3YdmJAMPUhqi+YO+Gc7WNTbrOR0
+aJGzS2HEPxjbC4OsFG7TVuKMH1uI4rWOZxBn4rODkTmiH7epuyu65nzUJemct8GV
+OcPChjPVKvXzbHVtk8UVreD/DVyuYwsBMSAuYWiq2pgAAQV/7TKVDAQ8yRVW28J7
++QrNXqV+I6MZeMho45xgLNQmi5os9vqTuEu3oGyLFWxXz6uJ2MOFOFTjxMhHGcGn
+aICAA9BIcCeaWWRN9nZkvQuS2nysvJwBu/LROQIDAQABo3sweTASBgNVHRMBAf8E
+CDAGAQH/AgEAMB0GA1UdDgQWBBSkX16pB/ZB0hzdYIUgMhWO89CxZzAfBgNVHSME
+GDAWgBR9W+i1d5oZtiZAEjI9RDLd9SnUnDAOBgNVHQ8BAf8EBAMCAgQwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBAIdIh5sIk9Qi2KZfzJUQ
+/DmMTv6NZzAGROJGA+o6jfrMh/plzBre7QM2vzw6iHxFokepLnsXtgrqdtr1lluO
+R6apN2QLp5AJeT8gZfn0V35Wz2iYn+fJR77Map3u57IOj08gvk/BZmJxxqMT/qH/
+1H5qpd934aFLSgqsmpGOVIzrdwHVmwOKU9SDNxOILVpvgtjQ/KWEUxftKtU7Z/dd
+WGN56Vu3Ul0gzgCFifj8mnHnHpug/wEHLl0l2hk3BD1AUrCyCK4yalvsDV7vFex7
+8+Whuh4OijTP/yomn8VGPN5lMmGT4XN8Z3h97PUHF9yF4FYGJJ/lilIhxctashk+
+HuE=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
-MIIC+zCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
-YXV0aG9yaXR5MB4XDTE1MTAxOTExNTUxMloXDTI1MTAxNjExNTUxMlowGDEWMBQG
+MIIC/jCCAeagAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1yb290
+YXV0aG9yaXR5MB4XDTE4MDQyMzE3MTUxMloXDTI4MDQyMDE3MTUxMlowGDEWMBQG
A1UEAwwNcm9vdGF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAMDzkcftGzdNJz5vXEAZSCAO2J6bCPz896pK3qtaViR/aF8I2vHZQm0IEoJc
-Y1NUMF3F50d6fMYCkEoORAkC0d7iAwTprhBdIg35+TxwGObcStrohDtEgwFmFRzg
-LtYeXiU0t0dBWOOQ9k2f9VGqbzKwZ2dbhOHSTXMTFoEcMStbeFc++oiOLY+QSq/J
-Xd/BXqvwVM3Mt+OwLvyUu45Kw18ENo77qubIPJUwoyaf+N2nFRqcc7bmNy0Wvk2Q
-StvQXy6DpN3KOoZx/sR7Ff8hYuHXcxbSsJ1hOO+tIJyOZyEJvU2BBOYVlKr4E4JU
-mkex0CM1IfIFqfcEkbvjwLjaojsCAwEAAaNQME4wHQYDVR0OBBYEFGnP6NEr2Iaq
-KOsv/hYKwawiPGgRMB8GA1UdIwQYMBaAFGnP6NEr2IaqKOsv/hYKwawiPGgRMAwG
-A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJKl4RCEaXwtosNeurZlS3b9
-owXdsXDRdnfEawcc//AbRkrS4bHCQyOJNp/3DibEKkeAXCJrJ5cvXRjE5gb3Q+rl
-0AqziLY15xuMAxUK3zv0e8Zir21PQzQ9x8zbmlucEoT/jn7KvMSSqfEoer77cXev
-BpmQDQzE3FNgKohmHIzIDoTPiU3ahv6x8IhJ1e47UmRsSPFgtqglHcdCYIEclXpY
-bHvctT6+pFZuJfIs9+BATMXPJWSX7NhlMcnyP+xdDxDKuF/nwVFy6xA+njuWnnZT
-TyiGCnx+u/VpKzOrwMfzv2DW8Db80UERoox5n6QNQLnXNWPMddUL92/p9lMzWJY=
+ggEBAMuTL5lztughNg/G/9Ge8c6EmROymW0zGTN6hRp3rG2SkpJdag08ntKAmny3
+ilpnlEoxGOk1L9jq/lJsCsiqsSETCadkLsXFNeKOG+S48nc8ThOrmJe5WV6NDNmn
+qaQeek5rjvuRSdukhyZVLzmIyTYNErwkMuo+Jk1V7IS1X2pFyTfF+SLlYrOuDQIW
+qXYfWqdMSYpI8s3onIwR/qVapGu55D0CECzNyX6ZBnqYK0cGzmRaZToT84VPsJwB
+DmALQw9WNNn1CHAIt17CwsdSSasgaKz/XDDjwgKL7CI6bFttDIWVLBt8ikrsrjZN
+6L5b8PZx/dHwJJ7QjYOMKKSUjyECAwEAAaNTMFEwHQYDVR0OBBYEFH1b6LV3mhm2
+JkASMj1EMt31KdScMB8GA1UdIwQYMBaAFH1b6LV3mhm2JkASMj1EMt31KdScMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJTJx9nh+fTJ6a0aIzPY
+FUX5tg+MdUxsAG5QA2jrwZIKCSrHa/ka0vjwLO+94EWcWgKdNDu8lt2FPnJh0nzN
+Ad/CaQNSMesihlmGOgxvLgd3ndYDVYjsCrXx3ESoRavgAWXY+/p69KR1ibVLpKF/
+yr/YURqT9SLKAlgrZt5I/syzxhWdAND62oxqiDCMzPoVR2cLswIUDNRvq5nRiCIt
+1TLPDINjG1EdmwzV2jyPxphL8esopopVm/d9wgD0xQ2Ocb2Nj6Jduuli0sm+dVBL
+3t2pldRq0hXZt/9qhu38tF41TlKSpCz2oFyx2D6ObLSX0MeFp6zXM0c1lGqSCDIM
+ubk=
-----END CERTIFICATE-----
diff --git a/tests/standalone_2/io/certificates/untrusted_server_key.pem b/tests/standalone_2/io/certificates/untrusted_server_key.pem
index 29a9e32..b281bb3 100644
--- a/tests/standalone_2/io/certificates/untrusted_server_key.pem
+++ b/tests/standalone_2/io/certificates/untrusted_server_key.pem
@@ -1,29 +1,29 @@
-----BEGIN ENCRYPTED PRIVATE KEY-----
-MIIE5TAcBgoqhkiG9w0BDAEBMA4ECKAry4fwmB/TAgIIAASCBMNsKbVVvIs/l6/N
-/1J9WXSiA1gnRTd2n58GJUV6mkiaRUMiWu3fK+V7iHpIi7KeLeD+JGsDeqxw0bB5
-lmS/RJy0wNBP0PL0oiI8VUe3wxTUU2b5wW9fomeOTGWOIUL5VZXHkTCf5KMcFWMY
-GMnDpIN/f/m9zvz/3FogxIZlIAxG7gKKrfEcKExIShAJ5wYDbDSFZWfNcjMODGPn
-xz3W04aRsJGf3KlOQvSuNtcBpsuwXuAXezzuFETM20xrWW3iJIsO5UmqJ1OJcdet
-A+k5k0K+1/WwLkceWJYSd19O+7LNULsZhKUJ515ZSO1TJGgfd5DznkgRXYUx5ucS
-tvJLYvShGbaYulsVKn8q2nkIxnQCov3my1hIRk/qCKb+uOvRD9dIkjSlNubqaRb6
-geEOfTh1g5PCeKPlSTkVueLQqWxKMye4eWYqUxExkUNuGJ0d2ndBGJRo6bulnc7I
-kt44DzEufV5OLvyTufimpohqRm3Yzq87DWSSThCKOGkhfGutn8B7cJR8ZPrG2euT
-J7Bv4EuFjhpKDieqDi8yoXgIkWSgyzFNMsewV4lxFNP/wbvoKPFrKsU4ny6jRfzy
-WTjMN1UOTBvsyZbVvjLII79cBKLqlowHAZQ7YwuxtbjeB9FRH+ZwkzYeyn4GNHdf
-QoVwOMKAiOMjzAK9qdW7isVXy/7v9EXaZplRmwMRhCZevC9zeY2Rueahq8qpHpH1
-GPjrew5elPkBRQhxX6IiL7kI7upE65UI5hnnTnrdrZkRmMYOFEZLyLbTU4wMCxui
-4BmEiGp6qCWe3UND1b8YhG+gsRYzHK5oEJV+Ck7m+e9iU3/axggUfAhZeBmdlgqd
-bUajlzcgbtfaSgZ08XXU1YPw0aLlmJGzb+oWMFwBJHAUYpOV2uqDHiXZZt4SoAF9
-gJQaXvqMGzY8JyP5ZQauljVtPGcopA+jbix3Rbwf97lLqJHSpWoHpcCa6FrfaMqG
-dx8oQsO67WN0gm5DIN3kB2jHOj9Nf7kr3HGjyC5tPq8s1+aT6baZcHWzVfyVr10c
-9X13Pz5XzEa1oiaO7JDPkzb9T7aPJZwskATNB8h6tWfqdGyUY5eURtsCnVrtG/1p
-pAXyY/0vAksfDPjMChKLKxZ7rBbscoNzr2f7Vw4CTnIpaxA4eLEx6UdpG4/5RzYJ
-0YuR+SzCkuNti7uZGi9DCGkZkYl6VndatW+Pk/+JVBexdKt6MsER6aVsS8ev9UbW
-JG+2C8bjMlfKy21644KwYOtZbVcE9jwlsz8w+e6YbOzBvbwiPmoCi0xcMxRJPa2y
-cKMrs2hSKmhUP6uIH0b0qNcHEPA32mVzGC0MToC5R+yb6OdyvoEsisqS7tEAMfTJ
-0yowcZr2lPehaMr4efSB8JY6DuofitfgI6X6bmiIPQ9v//djxhkxkRAbpTRGmFZx
-1YIKDa72S8jUxHWlVvmoqTWI8T+jltF2pYBctS6IMKEot/CcBCHb5l1zfMyo5a0x
-73ooh5tq+vRWJGaLRMj66VVSWGQoJmfAGwWpjBpTLa0UQoHO0/J1IbfjFOj5HV3J
-bscmoGWhVwuJM5ActB0MOvXGQe9mf2X4p/1Rp+yBuipH1SJzFEzbOZ3kE50Z6aXH
-CoJJOKkcuf43
+MIIE5TAcBgoqhkiG9w0BDAEBMA4ECI8YmURjepD4AgIIAASCBMMwp7gfo4FvSVuR
+5w7+OcjkXNQmvrwTRFDaMWV3ORgVFMQx02Q325SnoQsmulB+dk19uj2Piel5j/+j
+xHLvC0rBQC8BjHg/uLmN/f9yW6qolDthmeJEad/L8slB7rziilOGmlPh7H1voJgr
+94uoTn6L2tE9GfoPDsksedRtGIlgSOM3UmLvCkCMcZBqrDi4uqzbhrW3bIbqdoeo
+1lbNsvFuNzF+P3cBHyUUZpPGwCZ8M/XCsCAB+9eH7TM2FJnbuffA6BfkanpQR0ul
+PLo5KDjcS5lQ4YUkI2+lYMSZMiIf50Y8eHP0QnDAuYunA2cPLd90rPpdBCgNtQqk
+aUI7FHvtLFZsTJ1s8EPnZhZOZq1LYUTFQuimMWz+nvC0oQy925brwyjfnrm44KS7
+xpJqsYMBHYflDCwE4LbxjFSeneOy4wwNMurupSdcLCm02Sm1wUMrzRrNsAy3jxP6
+TfJjHRBSt3XEDwDG3olQoK/Ewa1qP0JhAZOd7SrKw9eLQltH+djy0iDUblf5uIHj
+pDC+T1pY9tTwSVxhsJI5a0qxXYNgdaxhr0Fv8BbdScd8Tzdw7g4AByjvgCKArlNJ
+alR1ZaJP/JYuzb3VH8uXEO4b6Tjqw9O4tkZGrc8He5HTAOnSZKbclDxyRH8hkDy+
+apIJUjbE3Gc1mCbyo2nc6WDrGfQNrXDWAVIz4/lb8e8P5k1Rex4rVNhb/VA0Vh4m
+T2BSQ3pvZtKTFedvWgIFIk85rVaYyuB7Icb0YLs2cPppMCfbv+6bOMkJ4hVk5tbX
+AGk6FOjgqsQSY/gzDo9ReCJooETP2AmvHEi2b7LKs+M0Pw+CfvKD/dOkQp62WMpt
+vZJVSXIQ2bHarbhxmUxcT//G+i3QBgkM2xTRvARfRMBiCoBh0Ta3gd4/GJDwv8pr
+pkJi3Q6u88NfGG0eyYyHz+kqTtptqJj1hbAFPdt6d6sFL/wpwhK/L5MOECQ3m100
+N3/aGT7yizM0w/m6PSycSbXycRafRF3XNMBXsUWeFpSWxpJV9GH+T3z8k46GrsM6
+c3YrLG6nvmersDI2AuS9KuhIQQvp+sgwjt3HeURsDv3X4edgCILRTjv3nVuU+DGD
+Xd8CuPYmRei4eJ4nkzxY6fM7ticuArnyE+INVtA0T8yL4UbRxQV/f9jOZWJ1LXLr
+caxCOZP9YcDVG9JUK4WGUC3LVWfhJW+i51cLJk9iGZ8qDLSvgJhj+/7Ajsg6/4xO
+IPon0DVMD9jgMSWLdfpCPawyY+VLVH2CXB2z83c2818gAs85QGUlsW+xLkELSTIU
+6p+mtTF5B2IhsjEdMDAWOpAp/Gj/U9OKapTyE1sGxn66jG/UvxcgYqZo3JGjNaDE
+rMnBhOH4VQQ+FxCA6lXKYCcU1UEze5BuCzJCA7gmCceMlMe+1Car2F+nJCuLNtzB
+uJhlXDbIVhMb5cZBBd3LSjmuRZ/gWbMvV3UqoCROBXqLzVGTufpcn/MgYQKYYHkp
+I+vKDypj0a4IPovDdxg8aMKNn59mtvmMDyrt0716H9DP4SCU/nuxVSeT/HywRBo/
+53fxqtdH3hTAUXqcOLzHnvLUENiABKMeJOtGTV9MFCxgGsnzgYNXnB9hDhm84+IX
+JQdMjj+BNFE6
-----END ENCRYPTED PRIVATE KEY-----
diff --git a/tests/standalone/io/create_sample_certificates.sh b/tests/standalone_2/io/create_sample_certificates.sh
similarity index 87%
rename from tests/standalone/io/create_sample_certificates.sh
rename to tests/standalone_2/io/create_sample_certificates.sh
index cabe747..c2060c1 100755
--- a/tests/standalone/io/create_sample_certificates.sh
+++ b/tests/standalone_2/io/create_sample_certificates.sh
@@ -43,6 +43,9 @@
openssl req -subj /CN=localhost -batch -verbose -passout $password -new \
-keyout localhost_key.pem -out localhost_request.pem
+openssl req -subj /CN=badlocalhost -batch -verbose -passout $password -new \
+ -keyout badlocalhost_key.pem -out badlocalhost_request.pem
+
# Sign the server certificate with the intermediate authority. Add the
# certificate extensions for SubjectAltName and that it is not a CA itself.
openssl x509 -req -in localhost_request.pem -out localhost.pem -set_serial 1 \
@@ -50,6 +53,11 @@
-passin $password -extfile ../sample_certificate_v3_extensions \
-extensions localhost -days 3650
+openssl x509 -req -in badlocalhost_request.pem -out badlocalhost.pem -set_serial 1 \
+ -CA intermediate_authority.pem -CAkey intermediate_authority_key.pem \
+ -passin $password -extfile ../sample_certificate_v3_extensions \
+ -extensions badlocalhost -days 3650
+
# Create a self-signed client certificate authority.
openssl req -subj /CN=clientauthority -set_serial 1 -batch -verbose \
-passout $password -new -x509 -keyout client_authority_key.pem \
@@ -72,30 +80,35 @@
-passin $password -extfile ../sample_certificate_v3_extensions \
-extensions client_certificate -days 3650
-# Delete all the signing keys for the authorities, so testers that add
-# them as trusted are less vulnerable: only the sample server certificate
-# and client certificates will be signed by them. No more certificates
-# will ever be signed.
-rm root_authority_key.pem
-rm intermediate_authority.pem
-rm client_authority_key.pem
-
# Copy the certificates we will use to the 'certificates' directory.
CERTS=../certificates
cat localhost.pem intermediate_authority.pem root_authority.pem \
> $CERTS/server_chain.pem
+cat badlocalhost.pem intermediate_authority.pem root_authority.pem \
+ > $CERTS/bad_server_chain.pem
+
cat intermediate_authority.pem root_authority.pem client_authority.pem \
> $CERTS/server_trusted.pem
# BoringSSL only accepts private keys signed with the PBE-SHA1-RC4-128 cipher.
openssl pkcs8 -in localhost_key.pem -out $CERTS/server_key.pem \
-topk8 -v1 PBE-SHA1-RC4-128 -passin $password -passout $password
+openssl pkcs8 -in badlocalhost_key.pem -out $CERTS/bad_server_key.pem \
+ -topk8 -v1 PBE-SHA1-RC4-128 -passin $password -passout $password
openssl pkcs8 -in client1_key.pem -out $CERTS/client1_key.pem \
-topk8 -v1 PBE-SHA1-RC4-128 -passin $password -passout $password
openssl pkcs8 -in client2_key.pem -out $CERTS/client2_key.pem \
-topk8 -v1 PBE-SHA1-RC4-128 -passin $password -passout $password
+# Delete all the signing keys for the authorities, so testers that add
+# them as trusted are less vulnerable: only the sample server certificate
+# and client certificates will be signed by them. No more certificates
+# will ever be signed.
+rm root_authority_key.pem
+rm intermediate_authority.pem
+rm client_authority_key.pem
+
cp root_authority.pem $CERTS/trusted_certs.pem
cp client_authority.pem $CERTS
cp client1.pem $CERTS
diff --git a/tests/standalone_2/io/http_server_test.dart b/tests/standalone_2/io/http_server_test.dart
index fa3b1ea7..1a9829d 100644
--- a/tests/standalone_2/io/http_server_test.dart
+++ b/tests/standalone_2/io/http_server_test.dart
@@ -137,13 +137,13 @@
void testHttpServerZone() {
asyncStart();
- Expect.equals(Zone.ROOT, Zone.current);
+ Expect.equals(Zone.root, Zone.current);
runZoned(() {
- Expect.notEquals(Zone.ROOT, Zone.current);
+ Expect.notEquals(Zone.root, Zone.current);
HttpServer.bind("127.0.0.1", 0).then((server) {
- Expect.notEquals(Zone.ROOT, Zone.current);
+ Expect.notEquals(Zone.root, Zone.current);
server.listen((request) {
- Expect.notEquals(Zone.ROOT, Zone.current);
+ Expect.notEquals(Zone.root, Zone.current);
request.response.close();
server.close();
});
@@ -158,15 +158,15 @@
void testHttpServerZoneError() {
asyncStart();
- Expect.equals(Zone.ROOT, Zone.current);
+ Expect.equals(Zone.root, Zone.current);
runZoned(() {
- Expect.notEquals(Zone.ROOT, Zone.current);
+ Expect.notEquals(Zone.root, Zone.current);
HttpServer.bind("127.0.0.1", 0).then((server) {
- Expect.notEquals(Zone.ROOT, Zone.current);
+ Expect.notEquals(Zone.root, Zone.current);
server.listen((request) {
- Expect.notEquals(Zone.ROOT, Zone.current);
+ Expect.notEquals(Zone.root, Zone.current);
request.listen((_) {}, onError: (error) {
- Expect.notEquals(Zone.ROOT, Zone.current);
+ Expect.notEquals(Zone.root, Zone.current);
server.close();
throw error;
});
diff --git a/tests/standalone/io/sample_certificate_v3_extensions b/tests/standalone_2/io/sample_certificate_v3_extensions
similarity index 85%
rename from tests/standalone/io/sample_certificate_v3_extensions
rename to tests/standalone_2/io/sample_certificate_v3_extensions
index f9e741e..f17764d 100644
--- a/tests/standalone/io/sample_certificate_v3_extensions
+++ b/tests/standalone_2/io/sample_certificate_v3_extensions
@@ -25,6 +25,13 @@
IP.1 = 127.0.0.1
IP.2 = ::1
+[badlocalhost]
+basicConstraints = critical,CA:false
+subjectKeyIdentifier = hash
+authorityKeyIdentifier=keyid,issuer
+keyUsage=critical, digitalSignature, keyEncipherment, keyAgreement
+extendedKeyUsage=serverAuth
+
[intermediate_authority]
basicConstraints = critical, CA:true, pathlen:0
subjectKeyIdentifier=hash
diff --git a/tests/standalone_2/io/secure_bad_certificate_test.dart b/tests/standalone_2/io/secure_bad_certificate_test.dart
index 60a2623..e002313 100644
--- a/tests/standalone_2/io/secure_bad_certificate_test.dart
+++ b/tests/standalone_2/io/secure_bad_certificate_test.dart
@@ -4,6 +4,8 @@
// OtherResources=certificates/server_chain.pem
// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/bad_server_chain.pem
+// OtherResources=certificates/bad_server_key.pem
// OtherResources=certificates/trusted_certs.pem
// This test verifies that the bad certificate callback works.
@@ -22,6 +24,11 @@
..usePrivateKey(localFile('certificates/server_key.pem'),
password: 'dartdart');
+SecurityContext badServerContext = new SecurityContext()
+ ..useCertificateChain(localFile('certificates/bad_server_chain.pem'))
+ ..usePrivateKey(localFile('certificates/bad_server_key.pem'),
+ password: 'dartdart');
+
class CustomException {}
main() async {
@@ -35,6 +42,15 @@
if (e is! HandshakeException) throw e;
});
+ var badServer = await SecureServerSocket.bind(HOST_NAME, 0, badServerContext);
+ badServer.listen((SecureSocket socket) {
+ socket.listen((_) {}, onDone: () {
+ socket.close();
+ });
+ }, onError: (e) {
+ if (e is! HandshakeException) throw e;
+ });
+
SecurityContext goodContext = new SecurityContext()
..setTrustedCertificates(localFile('certificates/trusted_certs.pem'));
SecurityContext badContext = new SecurityContext();
@@ -52,14 +68,18 @@
await runClient(server.port, defaultContext, false, 'fail');
await runClient(server.port, defaultContext, 'fisk', 'fail');
await runClient(server.port, defaultContext, 'exception', 'throw');
+
+ await runClient(badServer.port, goodContext, false, 'fail');
+
server.close();
+ badServer.close();
}
Future runClient(
int port, SecurityContext context, callbackReturns, result) async {
bool badCertificateCallback(X509Certificate certificate) {
- Expect.isTrue(certificate.subject.contains('rootauthority'));
- Expect.isTrue(certificate.issuer.contains('rootauthority'));
+ Expect.isNotNull(certificate.subject);
+ Expect.isNotNull(certificate.issuer);
// Throw exception if one is requested.
if (callbackReturns == 'exception') throw new CustomException();
if (callbackReturns is bool) return callbackReturns;
diff --git a/tools/VERSION b/tools/VERSION
index 4229ed2..5c6fbcc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 0
PATCH 0
-PRERELEASE 49
+PRERELEASE 50
PRERELEASE_PATCH 0
diff --git a/tools/apps/update_homebrew/lib/update_homebrew.dart b/tools/apps/update_homebrew/lib/update_homebrew.dart
index 477ddb0..0d2fcbb 100644
--- a/tools/apps/update_homebrew/lib/update_homebrew.dart
+++ b/tools/apps/update_homebrew/lib/update_homebrew.dart
@@ -185,10 +185,6 @@
def caveats; <<~EOS
Please note the path to the Dart SDK:
#{opt_libexec}
-
- --with-dartium:
- To use with IntelliJ, set the Dartium execute home to:
- #{opt_prefix}/Chromium.app
EOS
end