Version 2.14.0-221.0.dev
Merge commit 'dea0488efedbd10a913489e35f52d445160c92b9' into 'dev'
diff --git a/pkg/dev_compiler/lib/src/compiler/js_names.dart b/pkg/dev_compiler/lib/src/compiler/js_names.dart
index 3295e0c..186a316 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_names.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_names.dart
@@ -74,6 +74,17 @@
void visitChildren(NodeVisitor visitor) => _expr.visitChildren(visitor);
}
+/// Provides a mechanism to listen for naming choices when `Identifier` nodes
+/// are compiled into an actual name in the JavaScript.
+class NameListener {
+ /// A mapping of all name selections that were made.
+ final identifierNames = <Identifier, String>{};
+
+ /// Signals that [name] was selected to represent [identifier].
+ void nameSelected(Identifier identifier, String name) =>
+ identifierNames[identifier] = name;
+}
+
/// This class has two purposes:
///
/// * rename JS identifiers to avoid keywords.
@@ -88,13 +99,20 @@
class TemporaryNamer extends LocalNamer {
_FunctionScope scope;
- TemporaryNamer(Node node) : scope = _RenameVisitor.build(node).rootScope;
+ /// Listener to be notified when a name is selected (rename or not) for an
+ /// `Identifier`.
+ ///
+ /// Can be `null` when there is no listener attached.
+ final NameListener _nameListener;
+
+ TemporaryNamer(Node node, [this._nameListener])
+ : scope = _RenameVisitor.build(node).rootScope;
@override
String getName(Identifier node) {
- var rename = scope.renames[identifierKey(node)];
- if (rename != null) return rename;
- return node.name;
+ var name = scope.renames[identifierKey(node)] ?? node.name;
+ _nameListener?.nameSelected(node, name);
+ return name;
}
@override
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 2bac27d..fc521de 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -11,7 +11,6 @@
import 'package:args/args.dart';
import 'package:build_integration/file_system/multi_root.dart';
import 'package:cli_util/cli_util.dart' show getSdkPath;
-import 'package:dev_compiler/src/kernel/module_symbols.dart';
import 'package:front_end/src/api_unstable/ddc.dart' as fe;
import 'package:kernel/binary/ast_to_binary.dart' as kernel show BinaryPrinter;
import 'package:kernel/class_hierarchy.dart';
@@ -31,6 +30,8 @@
import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
import 'compiler.dart';
import 'module_metadata.dart';
+import 'module_symbols.dart';
+import 'module_symbols_collector.dart';
import 'target.dart';
const _binaryName = 'dartdevc -k';
@@ -682,8 +683,9 @@
}
var tree = transformModuleFormat(format, moduleTree);
- var namer = js_ast.TemporaryNamer(tree);
- tree.accept(js_ast.Printer(opts, printer, localNamer: namer));
+ var nameListener = emitDebugSymbols ? js_ast.NameListener() : null;
+ tree.accept(js_ast.Printer(opts, printer,
+ localNamer: js_ast.TemporaryNamer(tree, nameListener)));
Map builtMap;
if (buildSourceMap && sourceMap != null) {
@@ -726,15 +728,27 @@
? _emitMetadata(moduleTree, component, mapUrl, jsUrl, fullDillUri)
: null;
- var debugSymbols =
- emitDebugSymbols ? _emitSymbols(compiler, component) : null;
+ var debugSymbols = emitDebugSymbols
+ ? _emitSymbols(compiler, nameListener.identifierNames, component)
+ : null;
return JSCode(text, builtMap, symbols: debugSymbols, metadata: debugMetadata);
}
-ModuleSymbols _emitSymbols(ProgramCompiler compiler, Component component) {
- // TODO(annagrin): collect module symbols.
- return ModuleSymbols();
+/// Assembles symbol information describing the nodes from the AST [component]
+/// and their representation in JavaScript.
+///
+/// Uses information from the [compiler] used to compile the JS module combined
+/// with [identifierNames] that maps JavaScript identifier nodes to their actual
+/// names used when outputting the JavaScript.
+ModuleSymbols _emitSymbols(ProgramCompiler compiler,
+ Map<js_ast.Identifier, String> identifierNames, Component component) {
+ var classJsNames = <Class, String>{
+ for (var e in compiler.classIdentifiers.entries)
+ e.key: identifierNames[e.value],
+ };
+
+ return ModuleSymbolsCollector(classJsNames).collectSymbolInfo(component);
}
ModuleMetadata _emitMetadata(js_ast.Program program, Component component,
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 0d34217..e6d2dbf 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -46,6 +46,13 @@
DartTypeVisitor<js_ast.Expression> {
final SharedCompilerOptions _options;
+ /// Maps each `Class` node compiled in the module to the `Identifier`s used to
+ /// name the class in JavaScript.
+ ///
+ /// This mapping is used when generating the symbol information for the
+ /// module.
+ final classIdentifiers = <Class, js_ast.Identifier>{};
+
/// Maps a library URI import, that is not in [_libraries], to the
/// corresponding Kernel summary module we imported it with.
///
@@ -781,12 +788,15 @@
js_ast.Statement _emitClassStatement(Class c, js_ast.Expression className,
js_ast.Expression heritage, List<js_ast.Method> methods) {
if (c.typeParameters.isNotEmpty) {
- return js_ast.ClassExpression(
- className as js_ast.Identifier, heritage, methods)
+ var classIdentifier = className as js_ast.Identifier;
+ if (_options.emitDebugSymbols) classIdentifiers[c] = classIdentifier;
+ return js_ast.ClassExpression(classIdentifier, heritage, methods)
.toStatement();
}
- var classExpr = js_ast.ClassExpression(
- _emitTemporaryId(getLocalClassName(c)), heritage, methods);
+
+ var classIdentifier = _emitTemporaryId(getLocalClassName(c));
+ if (_options.emitDebugSymbols) classIdentifiers[c] = classIdentifier;
+ var classExpr = js_ast.ClassExpression(classIdentifier, heritage, methods);
return js.statement('# = #;', [className, classExpr]);
}
diff --git a/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
new file mode 100644
index 0000000..bf405a2
--- /dev/null
+++ b/pkg/dev_compiler/lib/src/kernel/module_symbols_collector.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'package:kernel/kernel.dart';
+
+import 'module_symbols.dart';
+
+class ModuleSymbolsCollector extends RecursiveVisitor {
+ final scopes = <ScopeSymbol>[];
+
+ final moduleSymbols = ModuleSymbols(
+ // TODO version
+ // TODO moduleName
+ libraries: <LibrarySymbol>[],
+ scripts: <Script>[],
+ classes: <ClassSymbol>[],
+ // TODO functionTypes
+ // TODO functions
+ // TODO scopes
+ // TODO variables
+ );
+
+ final Map<Class, String> classJsNames;
+
+ ModuleSymbolsCollector(this.classJsNames);
+
+ ModuleSymbols collectSymbolInfo(Component node) {
+ node.accept(this);
+ return moduleSymbols;
+ }
+
+ /// Returns the id of the script in this module with the matching [fileUri].
+ String _scriptId(Uri fileUri) => fileUri.toString();
+
+ @override
+ void visitClass(Class node) {
+ var classSymbol = ClassSymbol(
+ name: node.name,
+ isAbstract: node.isAbstract,
+ // TODO isConst - has a const constructor?
+ superClassId: classJsNames[node.superclass],
+ interfaceIds: [
+ for (var type in node.implementedTypes) classJsNames[type.classNode]
+ ],
+ typeParameters: {
+ for (var param in node.typeParameters)
+ param.name: param.name // TODO: value should be JS name
+ },
+ localId: classJsNames[node],
+ scopeId: scopes.last.id,
+ location: SourceLocation(
+ scriptId: _scriptId(node.location.file),
+ tokenPos: node.startFileOffset,
+ endTokenPos: node.fileEndOffset),
+ // Create empty list, they are added in visitField().
+ variableIds: <String>[],
+ scopeIds: <String>[]);
+
+ scopes.add(classSymbol);
+ node.visitChildren(this);
+ scopes
+ ..removeLast()
+ ..last.scopeIds.add(classSymbol.id);
+ moduleSymbols.classes.add(classSymbol);
+ }
+
+ @override
+ void visitLibrary(Library node) {
+ var librarySymbol = LibrarySymbol(
+ name: node.name,
+ uri: node.importUri.toString(),
+ dependencies: [
+ for (var dep in node.dependencies)
+ LibrarySymbolDependency(
+ isImport: dep.isImport,
+ isDeferred: dep.isDeferred,
+ // TODO prefix
+ targetId: dep.targetLibrary.importUri.toString())
+ ],
+ variableIds: <String>[],
+ scopeIds: <String>[]);
+
+ // TODO: Save some space by using integers as local ids?
+ var scripts = [
+ Script(
+ uri: node.fileUri.toString(),
+ localId: _scriptId(node.fileUri),
+ libraryId: librarySymbol.id),
+ for (var part in node.parts)
+ Script(
+ uri: node.fileUri.resolve(part.partUri).toString(),
+ localId: _scriptId(node.fileUri.resolve(part.partUri)),
+ libraryId: librarySymbol.id),
+ ];
+
+ librarySymbol.scriptIds = [for (var script in scripts) script.id];
+ moduleSymbols.scripts.addAll(scripts);
+
+ scopes.add(librarySymbol);
+ node.visitChildren(this);
+ scopes.removeLast();
+ moduleSymbols.libraries.add(librarySymbol);
+ }
+}
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
index d5fbeea..4a98206 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -6,102 +6,20 @@
import 'dart:io' show Directory, File;
-import 'package:cli_util/cli_util.dart';
import 'package:dev_compiler/dev_compiler.dart';
import 'package:dev_compiler/src/compiler/js_names.dart';
import 'package:dev_compiler/src/compiler/module_builder.dart';
import 'package:dev_compiler/src/js_ast/js_ast.dart';
-import 'package:front_end/src/api_unstable/ddc.dart';
-import 'package:front_end/src/compute_platform_binaries_location.dart';
-import 'package:front_end/src/fasta/incremental_serializer.dart';
import 'package:kernel/ast.dart' show Component, Library;
-import 'package:kernel/target/targets.dart';
-import 'package:path/path.dart' as p;
import 'package:test/test.dart';
import 'package:vm/transformations/type_flow/utils.dart';
+import '../shared_test_options.dart';
+
// TODO(annagrin): Replace javascript matching in tests below with evaluating
// the javascript and checking the result.
// See https://github.com/dart-lang/sdk/issues/41959
-class DevelopmentIncrementalCompiler extends IncrementalCompiler {
- Uri entryPoint;
-
- DevelopmentIncrementalCompiler(CompilerOptions options, this.entryPoint,
- [Uri initializeFrom,
- bool outlineOnly,
- IncrementalSerializer incrementalSerializer])
- : super(
- CompilerContext(
- ProcessedOptions(options: options, inputs: [entryPoint])),
- initializeFrom,
- outlineOnly,
- incrementalSerializer);
-
- DevelopmentIncrementalCompiler.fromComponent(CompilerOptions options,
- this.entryPoint, Component componentToInitializeFrom,
- [bool outlineOnly, IncrementalSerializer incrementalSerializer])
- : super.fromComponent(
- CompilerContext(
- ProcessedOptions(options: options, inputs: [entryPoint])),
- componentToInitializeFrom,
- outlineOnly,
- incrementalSerializer);
-}
-
-class SetupCompilerOptions {
- static final sdkRoot = computePlatformBinariesLocation();
- static final sdkUnsoundSummaryPath = p.join(sdkRoot.path, 'ddc_sdk.dill');
- static final sdkSoundSummaryPath =
- p.join(sdkRoot.path, 'ddc_outline_sound.dill');
- static final librariesSpecificationUri =
- p.join(p.dirname(p.dirname(getSdkPath())), 'libraries.json');
-
- static CompilerOptions getOptions(bool soundNullSafety) {
- var options = CompilerOptions()
- ..verbose = false // set to true for debugging
- ..sdkRoot = sdkRoot
- ..target = DevCompilerTarget(TargetFlags())
- ..librariesSpecificationUri = Uri.base.resolve('sdk/lib/libraries.json')
- ..omitPlatform = true
- ..sdkSummary = sdkRoot.resolve(
- soundNullSafety ? sdkSoundSummaryPath : sdkUnsoundSummaryPath)
- ..environmentDefines = const {}
- ..nnbdMode = soundNullSafety ? NnbdMode.Strong : NnbdMode.Weak;
- return options;
- }
-
- static final String dartUnsoundComment = '// @dart = 2.9';
- static final String dartSoundComment = '//';
-
- final List<String> errors = [];
- final CompilerOptions options;
- final String dartLangComment;
- final ModuleFormat moduleFormat;
- final bool soundNullSafety;
-
- SetupCompilerOptions(
- {this.soundNullSafety = true, this.moduleFormat = ModuleFormat.amd})
- : options = getOptions(soundNullSafety),
- dartLangComment =
- soundNullSafety ? dartSoundComment : dartUnsoundComment {
- options.onDiagnostic = (DiagnosticMessage m) {
- errors.addAll(m.plainTextFormatted);
- };
- }
-
- String get loadModule {
- switch (moduleFormat) {
- case ModuleFormat.amd:
- return 'require';
- case ModuleFormat.ddc:
- return 'dart_library.import';
- default:
- throw UnsupportedError('Module format: $moduleFormat');
- }
- }
-}
-
/// Convenience class describing JavaScript module
/// to ensure we have normalized module names
class Module {
diff --git a/pkg/dev_compiler/test/module_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/module_symbols_json_test.dart
similarity index 100%
rename from pkg/dev_compiler/test/module_symbols_test.dart
rename to pkg/dev_compiler/test/module_symbols/module_symbols_json_test.dart
diff --git a/pkg/dev_compiler/test/module_symbols/module_symbols_test.dart b/pkg/dev_compiler/test/module_symbols/module_symbols_test.dart
new file mode 100644
index 0000000..20fbfc1
--- /dev/null
+++ b/pkg/dev_compiler/test/module_symbols/module_symbols_test.dart
@@ -0,0 +1,245 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'dart:io' show Directory, File;
+
+import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/kernel/command.dart';
+import 'package:dev_compiler/src/kernel/module_symbols.dart';
+import 'package:kernel/ast.dart' show Component, Library;
+import 'package:test/test.dart';
+
+import '../shared_test_options.dart';
+
+class TestCompiler {
+ final SetupCompilerOptions setup;
+
+ TestCompiler(this.setup);
+
+ Future<JSCode> compile({Uri input, Uri packages}) async {
+ // Initialize incremental compiler and create component.
+ setup.options.packagesFileUri = packages;
+ var compiler = DevelopmentIncrementalCompiler(setup.options, input);
+ var component = await compiler.computeDelta();
+ component.computeCanonicalNames();
+
+ // Initialize DDC.
+ var moduleName = 'foo.dart';
+ var classHierarchy = compiler.getClassHierarchy();
+ var compilerOptions = SharedCompilerOptions(
+ replCompile: true,
+ moduleName: moduleName,
+ soundNullSafety: setup.soundNullSafety,
+ moduleFormats: [setup.moduleFormat],
+ emitDebugSymbols: true);
+ var coreTypes = compiler.getCoreTypes();
+
+ final importToSummary = Map<Library, Component>.identity();
+ final summaryToModule = Map<Component, String>.identity();
+ for (var lib in component.libraries) {
+ importToSummary[lib] = component;
+ }
+ summaryToModule[component] = moduleName;
+
+ // Compile Kernel AST to JS AST.
+ var kernel2jsCompiler = ProgramCompiler(component, classHierarchy,
+ compilerOptions, importToSummary, summaryToModule,
+ coreTypes: coreTypes);
+ var moduleTree = kernel2jsCompiler.emitModule(component);
+
+ // Compile JS AST to code.
+ return jsProgramToCode(moduleTree, ModuleFormat.amd,
+ emitDebugSymbols: true,
+ compiler: kernel2jsCompiler,
+ component: component);
+ }
+}
+
+class TestDriver {
+ final SetupCompilerOptions options;
+ Directory tempDir;
+ final String source;
+ Uri input;
+ Uri packages;
+ File file;
+
+ TestDriver(this.options, this.source) {
+ var systemTempDir = Directory.systemTemp;
+ tempDir = systemTempDir.createTempSync('foo bar');
+
+ input = tempDir.uri.resolve('foo.dart');
+ file = File.fromUri(input)..createSync();
+ file.writeAsStringSync(source);
+
+ packages = tempDir.uri.resolve('package_config.json');
+ file = File.fromUri(packages)..createSync();
+ file.writeAsStringSync('''
+ {
+ "configVersion": 2,
+ "packages": [
+ {
+ "name": "foo",
+ "rootUri": "./",
+ "packageUri": "./"
+ }
+ ]
+ }
+ ''');
+ }
+
+ Future<JSCode> compile() async =>
+ await TestCompiler(options).compile(input: input, packages: packages);
+
+ void cleanUp() {
+ tempDir.delete(recursive: true);
+ }
+}
+
+class NullSafetyTestOption {
+ final String description;
+ final bool soundNullSafety;
+
+ NullSafetyTestOption(this.description, this.soundNullSafety);
+}
+
+void main() async {
+ for (var mode in [
+ NullSafetyTestOption('Sound Mode:', true),
+ NullSafetyTestOption('Weak Mode:', false)
+ ]) {
+ group(mode.description, () {
+ var options = SetupCompilerOptions(soundNullSafety: mode.soundNullSafety);
+ group('simple class debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A {}
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('has name', () async {
+ expect(classSymbol.name, equals('A'));
+ });
+ test('is not abstract', () async {
+ expect(classSymbol.isAbstract, isFalse);
+ });
+ // TODO test isConst
+ test('has no superclassId', () async {
+ expect(classSymbol.superClassId, isNull);
+ });
+ test('empty interfacesIds', () async {
+ expect(classSymbol.interfaceIds, isEmpty);
+ });
+ test('empty typeParameters', () async {
+ expect(classSymbol.typeParameters, isEmpty);
+ });
+ test('has localId', () async {
+ expect(classSymbol.localId, equals('A'));
+ });
+ test('has library scopeId', () async {
+ expect(classSymbol.scopeId, endsWith('package:foo/foo.dart'));
+ });
+ group('location', () {
+ test('has scriptId', () async {
+ expect(classSymbol.location.scriptId, endsWith('/foo.dart'));
+ });
+ test('has start token', () async {
+ expect(classSymbol.location.tokenPos,
+ 22 + options.dartLangComment.length);
+ });
+ test('has end token', () async {
+ expect(classSymbol.location.endTokenPos,
+ 31 + options.dartLangComment.length);
+ });
+ });
+ test('no fields', () async {
+ expect(classSymbol.variableIds, isEmpty);
+ });
+ // TODO only has the implicit constructor in scopeIds.
+ });
+ group('abstract class debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ abstract class A {}
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol = result.symbols.classes.single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('is abstract', () async {
+ expect(classSymbol.isAbstract, isTrue);
+ });
+ });
+ group('class extends debug symbols', () {
+ TestDriver driver;
+ ClassSymbol classSymbol;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A extends B {}
+
+ class B {}
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbol =
+ result.symbols.classes.where((c) => c.localId == 'A').single;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('has superclass', () async {
+ expect(classSymbol.superClassId, 'B');
+ });
+ });
+ group('class implements debug symbols', () {
+ TestDriver driver;
+ List<ClassSymbol> classSymbols;
+ final source = '''
+ ${options.dartLangComment}
+
+ class A implements B, C {}
+
+ class B implements C {}
+
+ class C {}
+ ''';
+ setUpAll(() async {
+ driver = TestDriver(options, source);
+ var result = await driver.compile();
+ classSymbols = result.symbols.classes;
+ });
+ tearDownAll(() {
+ driver.cleanUp();
+ });
+ test('single implements', () async {
+ var classSymbol = classSymbols.singleWhere((c) => c.localId == 'B');
+ expect(classSymbol.interfaceIds, orderedEquals(['C']));
+ });
+ test('multiple implements', () async {
+ var classSymbol = classSymbols.singleWhere((c) => c.localId == 'A');
+ expect(classSymbol.interfaceIds, orderedEquals(['B', 'C']));
+ });
+ });
+ });
+ }
+}
diff --git a/pkg/dev_compiler/test/shared_test_options.dart b/pkg/dev_compiler/test/shared_test_options.dart
new file mode 100644
index 0000000..53d8879
--- /dev/null
+++ b/pkg/dev_compiler/test/shared_test_options.dart
@@ -0,0 +1,93 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// @dart = 2.9
+
+import 'package:cli_util/cli_util.dart';
+import 'package:dev_compiler/dev_compiler.dart';
+import 'package:dev_compiler/src/compiler/module_builder.dart';
+import 'package:front_end/src/api_unstable/ddc.dart';
+import 'package:front_end/src/compute_platform_binaries_location.dart';
+import 'package:front_end/src/fasta/incremental_serializer.dart';
+import 'package:kernel/ast.dart' show Component;
+import 'package:kernel/target/targets.dart';
+import 'package:path/path.dart' as p;
+
+class DevelopmentIncrementalCompiler extends IncrementalCompiler {
+ Uri entryPoint;
+
+ DevelopmentIncrementalCompiler(CompilerOptions options, this.entryPoint,
+ [Uri initializeFrom,
+ bool outlineOnly,
+ IncrementalSerializer incrementalSerializer])
+ : super(
+ CompilerContext(
+ ProcessedOptions(options: options, inputs: [entryPoint])),
+ initializeFrom,
+ outlineOnly,
+ incrementalSerializer);
+
+ DevelopmentIncrementalCompiler.fromComponent(CompilerOptions options,
+ this.entryPoint, Component componentToInitializeFrom,
+ [bool outlineOnly, IncrementalSerializer incrementalSerializer])
+ : super.fromComponent(
+ CompilerContext(
+ ProcessedOptions(options: options, inputs: [entryPoint])),
+ componentToInitializeFrom,
+ outlineOnly,
+ incrementalSerializer);
+}
+
+class SetupCompilerOptions {
+ static final sdkRoot = computePlatformBinariesLocation();
+ static final sdkUnsoundSummaryPath = p.join(sdkRoot.path, 'ddc_sdk.dill');
+ static final sdkSoundSummaryPath =
+ p.join(sdkRoot.path, 'ddc_outline_sound.dill');
+ static final librariesSpecificationUri =
+ p.join(p.dirname(p.dirname(getSdkPath())), 'libraries.json');
+
+ static CompilerOptions getOptions(bool soundNullSafety) {
+ var options = CompilerOptions()
+ ..verbose = false // set to true for debugging
+ ..sdkRoot = sdkRoot
+ ..target = DevCompilerTarget(TargetFlags())
+ ..librariesSpecificationUri = Uri.base.resolve('sdk/lib/libraries.json')
+ ..omitPlatform = true
+ ..sdkSummary = sdkRoot.resolve(
+ soundNullSafety ? sdkSoundSummaryPath : sdkUnsoundSummaryPath)
+ ..environmentDefines = const {}
+ ..nnbdMode = soundNullSafety ? NnbdMode.Strong : NnbdMode.Weak;
+ return options;
+ }
+
+ static final String dartUnsoundComment = '// @dart = 2.9';
+ static final String dartSoundComment = '//';
+
+ final List<String> errors = [];
+ final CompilerOptions options;
+ final String dartLangComment;
+ final ModuleFormat moduleFormat;
+ final bool soundNullSafety;
+
+ SetupCompilerOptions(
+ {this.soundNullSafety = true, this.moduleFormat = ModuleFormat.amd})
+ : options = getOptions(soundNullSafety),
+ dartLangComment =
+ soundNullSafety ? dartSoundComment : dartUnsoundComment {
+ options.onDiagnostic = (DiagnosticMessage m) {
+ errors.addAll(m.plainTextFormatted);
+ };
+ }
+
+ String get loadModule {
+ switch (moduleFormat) {
+ case ModuleFormat.amd:
+ return 'require';
+ case ModuleFormat.ddc:
+ return 'dart_library.import';
+ default:
+ throw UnsupportedError('Module format: $moduleFormat');
+ }
+ }
+}
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index 56321d5..8c9efe1 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -50,6 +50,10 @@
help: 'Compile for sound null safety at runtime. Passed through to the '
'DDC binary. Defaults to false.',
defaultsTo: false)
+ ..addFlag('emit-debug-symbols',
+ help: 'Pass through flag for DDC, emits debug symbols file along with '
+ 'the compiled module.',
+ defaultsTo: false)
..addFlag('null-assertions',
help: 'Run with assertions that values passed to non-nullable method '
'parameters are not null.',
@@ -115,6 +119,7 @@
var run = mode == 'run' || mode == 'all';
var verbose = options['verbose'] as bool;
var soundNullSafety = options['sound-null-safety'] as bool;
+ var emitDebugSymbols = options['emit-debug-symbols'] as bool;
var nonNullAsserts = options['null-assertions'] as bool;
var nativeNonNullAsserts = options['native-null-assertions'] as bool;
var weakNullSafetyErrors = options['weak-null-safety-errors'] as bool;
@@ -230,6 +235,7 @@
for (var experiment in experiments) '--enable-experiment=$experiment',
if (soundNullSafety) '--sound-null-safety',
if (options['packages'] != null) '--packages=${options['packages']}',
+ if (emitDebugSymbols) '--emit-debug-symbols',
'-o',
out,
entry
diff --git a/pkg/test_runner/lib/src/command_output.dart b/pkg/test_runner/lib/src/command_output.dart
index 3e587e3..ae762aa 100644
--- a/pkg/test_runner/lib/src/command_output.dart
+++ b/pkg/test_runner/lib/src/command_output.dart
@@ -1463,6 +1463,8 @@
}
Expectation result(TestCase testCase) {
+ if (hasCrashed) return Expectation.crash;
+ if (hasTimedOut) return Expectation.timeout;
if (hasNonUtf8) return Expectation.nonUtf8Error;
if (truncatedOutput) return Expectation.truncatedOutput;
@@ -1475,6 +1477,8 @@
}
Expectation realResult(TestCase testCase) {
+ if (hasCrashed) return Expectation.crash;
+ if (hasTimedOut) return Expectation.timeout;
if (hasNonUtf8) return Expectation.nonUtf8Error;
if (truncatedOutput) return Expectation.truncatedOutput;
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 9dc7f89..fc091da 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -34,6 +34,9 @@
[ $builder_tag == obfuscated ]
no_such_method_error_with_invocation_test: SkipByDesign # Checks the member names in the NSM error message.
+[ $compiler == app_jitk ]
+io/socket_sigpipe_test: SkipByDesign # Spawns server process using Platform.executable
+
[ $compiler == dart2analyzer ]
deferred_transitive_import_error_test: Skip
@@ -94,6 +97,9 @@
fragmentation_test: SkipSlow
fragmentation_typed_data_test: SkipSlow
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
+io/socket_sigpipe_test: SkipByDesign # Test uses ffi
+
[ $compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk ]
*: SkipByDesign
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index 2ce913c..d875452 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -34,6 +34,9 @@
[ $builder_tag == obfuscated ]
no_such_method_error_with_invocation_test: SkipByDesign # Checks the member names in the NSM error message.
+[ $compiler == app_jitk ]
+io/socket_sigpipe_test: SkipByDesign # Spawns server process using Platform.executable
+
[ $compiler == dart2analyzer ]
deferred_transitive_import_error_test: Skip
@@ -101,6 +104,9 @@
fragmentation_test: SkipSlow
fragmentation_typed_data_test: SkipSlow
+[ $arch == simarm || $arch == simarm64 || $arch == simarm64c ]
+io/socket_sigpipe_test: SkipByDesign # Test uses ffi
+
[ $compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk ]
*: SkipByDesign
diff --git a/tests/web/native/native_exceptions1_frog_test.dart b/tests/web/native/native_exceptions1_frog_test.dart
index 7585a39..5932196 100644
--- a/tests/web/native/native_exceptions1_frog_test.dart
+++ b/tests/web/native/native_exceptions1_frog_test.dart
@@ -44,8 +44,8 @@
JS('', r"""
(function(){
// Ensure we are not relying on global names 'A' and 'E'.
- A = null;
- E = null;
+ self.A = null;
+ self.E = null;
})()""");
applyTestExtensions(['E', 'A']);
}
@@ -53,6 +53,10 @@
void setup2() {
JS('', r"""
(function(){
+// Confirm A and B are null.
+console.assert(self.A == null);
+console.assert(self.B == null);
+
// This code is all inside 'setup2' and so not accessible from the global scope.
function E(x){ this.code = x; }
diff --git a/tools/VERSION b/tools/VERSION
index f477762..b8cf35e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 14
PATCH 0
-PRERELEASE 220
+PRERELEASE 221
PRERELEASE_PATCH 0
\ No newline at end of file