Skip to content

Commit ed0cc81

Browse files
munificentcommit-bot@chromium.org
authored andcommitted
Get DDC and DDK test builds working with the forked NNBD SDK.
With these changes, I can run: ./tools/build.py -m release --nnbd dartdevc_test In a checkout that also includes a migrated core library that uses NNBD features. I haven't verified if the resulting JS is *correct*, but the build doesn't error out. Change-Id: I7d89efe5da8c46e2a9805743e4e61858da8097dd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122280 Reviewed-by: Nicholas Shahan <nshahan@google.com> Commit-Queue: Bob Nystrom <rnystrom@google.com>
1 parent 6c933a4 commit ed0cc81

File tree

4 files changed

+75
-23
lines changed

4 files changed

+75
-23
lines changed

pkg/async_helper/lib/async_helper.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ Future<void> asyncTest(f()) {
9090
return f().then(asyncSuccess);
9191
}
9292

93+
bool _pass(dynamic object) => true;
94+
9395
/// Calls [f] and verifies that it throws a `T`.
9496
///
9597
/// The optional [check] function can provide additional validation that the
@@ -103,7 +105,7 @@ Future<void> asyncTest(f()) {
103105
/// exception is not caught by [asyncExpectThrows]. The test is still considered
104106
/// failing.
105107
void asyncExpectThrows<T>(Future<void> f(),
106-
[bool check(T error), String reason]) {
108+
[bool check(T error) = _pass, String reason = ""]) {
107109
var type = "";
108110
if (T != dynamic && T != Object) type = "<$T>";
109111
var header = "asyncExpectThrows$type(${reason ?? ''}):";

pkg/dev_compiler/tool/build_pkgs.dart

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,13 @@ String kernelSummary;
2323
/// packages will be placed in a "pkg" subdirectory of this.
2424
String outputDirectory;
2525

26+
/// List of language experiments to enable when building.
27+
List<String> experiments;
28+
29+
/// Whether to force the analyzer backend to generate code even if there are
30+
/// errors.
31+
bool unsafeForceCompile;
32+
2633
/// Compiles the packages that the DDC tests use to JS into the given output
2734
/// directory.
2835
///
@@ -46,6 +53,10 @@ Future main(List<String> arguments) async {
4653
abbr: "o", help: "Directory to write output to.");
4754
argParser.addFlag("travis",
4855
help: "Build the additional packages tested on Travis.");
56+
argParser.addMultiOption("enable-experiment",
57+
help: "Enable experimental language features.");
58+
argParser.addFlag("unsafe-force-compile",
59+
help: "Generate output even if compile errors are reported.");
4960

5061
ArgResults argResults;
5162
try {
@@ -63,6 +74,8 @@ Future main(List<String> arguments) async {
6374
analyzerSummary = argResults["analyzer-sdk"] as String;
6475
kernelSummary = argResults["kernel-sdk"] as String;
6576
outputDirectory = argResults["output"] as String;
77+
experiments = argResults["enable-experiment"] as List<String>;
78+
unsafeForceCompile = argResults["unsafe-force-compile"] as bool;
6679

6780
// Build leaf packages. These have no other package dependencies.
6881

@@ -126,21 +139,18 @@ Future compileModule(String module,
126139
makeArgs({bool kernel = false}) {
127140
var pkgDirectory = p.join(outputDirectory, kernel ? 'pkg_kernel' : 'pkg');
128141
Directory(pkgDirectory).createSync(recursive: true);
129-
var args = <String>[];
130-
if (kernel) args.add('-k');
131142

132-
args.addAll([
143+
return [
144+
if (kernel) '-k',
145+
if (experiments.isNotEmpty)
146+
'--enable-experiment=${experiments.join(",")}',
147+
if (unsafeForceCompile && !kernel) '--unsafe-force-compile',
133148
'--dart-sdk-summary=${kernel ? kernelSummary : analyzerSummary}',
134149
'-o${pkgDirectory}/$module.js',
135-
'package:$module/$module.dart'
136-
]);
137-
for (var lib in libs) {
138-
args.add('package:$module/$lib.dart');
139-
}
140-
for (var dep in deps) {
141-
args.add('-s${pkgDirectory}/$dep.${kernel ? "dill" : "sum"}');
142-
}
143-
return args;
150+
'package:$module/$module.dart',
151+
for (var lib in libs) 'package:$module/$lib.dart',
152+
for (var dep in deps) '-s${pkgDirectory}/$dep.${kernel ? "dill" : "sum"}',
153+
];
144154
}
145155

146156
if (analyzerSummary != null) {

pkg/dev_compiler/tool/patch_sdk.dart

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import 'dart:io';
1010
import 'dart:math' as math;
1111

12+
import 'package:analyzer/dart/analysis/features.dart';
13+
import 'package:analyzer/dart/analysis/results.dart';
1214
import 'package:analyzer/dart/analysis/utilities.dart';
1315
import 'package:analyzer/dart/ast/ast.dart';
1416
import 'package:analyzer/dart/ast/token.dart';
@@ -35,8 +37,16 @@ void main(List<String> argv) {
3537
}
3638

3739
var sdk = 'sdk';
40+
var useNnbd = false;
3841
if (argv.length > 3) {
3942
sdk = argv[3];
43+
44+
// TODO(38701): While the core libraries have been forked for NNBD, use the
45+
// SDK directory name to determine whether to enable the NNBD experiment
46+
// when parsing the lib sources. Once the libraries have been unforked, we
47+
// should unconditionally enable the experiment flag since then the
48+
// canonical SDK libs will use NNBD syntax.
49+
useNnbd = sdk.contains("nnbd");
4050
}
4151

4252
var selfModifyTime = File(self).lastModifiedSync().millisecondsSinceEpoch;
@@ -63,7 +73,7 @@ void main(List<String> argv) {
6373
File(p.join(repoDir, 'tools', 'VERSION')).readAsStringSync());
6474

6575
// Parse libraries.dart
66-
var sdkLibraries = _getSdkLibraries(libContents);
76+
var sdkLibraries = _getSdkLibraries(libContents, useNnbd: useNnbd);
6777

6878
// Enumerate core libraries and apply patches
6979
for (SdkLibrary library in sdkLibraries) {
@@ -91,7 +101,8 @@ void main(List<String> argv) {
91101
int inputModifyTime = math.max(selfModifyTime,
92102
libraryFile.lastModifiedSync().millisecondsSinceEpoch);
93103
var partFiles = <File>[];
94-
for (var part in parseString(content: libraryContents).unit.directives) {
104+
for (var part
105+
in _parseString(libraryContents, useNnbd: false).unit.directives) {
95106
if (part is PartDirective) {
96107
var partPath = part.uri.stringValue;
97108
outPaths.add(p.join(p.dirname(libraryOut), partPath));
@@ -136,7 +147,7 @@ void main(List<String> argv) {
136147
contents.addAll(partFiles.map((f) => f.readAsStringSync()));
137148
if (patchExists) {
138149
var patchContents = patchFile.readAsStringSync();
139-
contents = _patchLibrary(contents, patchContents);
150+
contents = _patchLibrary(contents, patchContents, useNnbd: useNnbd);
140151
}
141152

142153
if (contents != null) {
@@ -178,18 +189,19 @@ void _writeSync(String filePath, String contents) {
178189
/// in the Dart language. Since this feature is only for the convenience of
179190
/// writing the dart:* libraries, and not a tool given to Dart developers, it
180191
/// seems like a non-ideal situation. Instead we keep the preprocessing simple.
181-
List<String> _patchLibrary(List<String> partsContents, String patchContents) {
192+
List<String> _patchLibrary(List<String> partsContents, String patchContents,
193+
{bool useNnbd = false}) {
182194
var results = <StringEditBuffer>[];
183195

184196
// Parse the patch first. We'll need to extract bits of this as we go through
185197
// the other files.
186-
var patchFinder = PatchFinder.parseAndVisit(patchContents);
198+
var patchFinder = PatchFinder.parseAndVisit(patchContents, useNnbd: useNnbd);
187199

188200
// Merge `external` declarations with the corresponding `@patch` code.
189201
bool failed = false;
190202
for (var partContent in partsContents) {
191203
var partEdits = StringEditBuffer(partContent);
192-
var partUnit = parseString(content: partContent).unit;
204+
var partUnit = _parseString(partContent, useNnbd: useNnbd).unit;
193205
var patcher = PatchApplier(partEdits, patchFinder);
194206
partUnit.accept(patcher);
195207
if (!failed) failed = patcher.patchWasMissing;
@@ -314,9 +326,9 @@ class PatchFinder extends GeneralizingAstVisitor {
314326
final mergeMembers = <String, List<ClassMember>>{};
315327
final mergeDeclarations = <CompilationUnitMember>[];
316328

317-
PatchFinder.parseAndVisit(String contents)
329+
PatchFinder.parseAndVisit(String contents, {bool useNnbd})
318330
: contents = contents,
319-
unit = parseString(content: contents).unit {
331+
unit = _parseString(contents, useNnbd: false).unit {
320332
visitCompilationUnit(unit);
321333
}
322334

@@ -478,11 +490,16 @@ class _StringEdit implements Comparable<_StringEdit> {
478490
}
479491
}
480492

481-
List<SdkLibrary> _getSdkLibraries(String contents) {
493+
List<SdkLibrary> _getSdkLibraries(String contents, {bool useNnbd}) {
482494
// TODO(jmesserly): fix SdkLibrariesReader_LibraryBuilder in Analyzer.
483495
// It doesn't understand optional new/const in Dart 2. For now, we keep
484496
// redundant `const` in tool/input_sdk/libraries.dart as a workaround.
485497
var libraryBuilder = SdkLibrariesReader_LibraryBuilder();
486-
parseString(content: contents).unit.accept(libraryBuilder);
498+
_parseString(contents, useNnbd: false).unit.accept(libraryBuilder);
487499
return libraryBuilder.librariesMap.sdkLibraries;
488500
}
501+
502+
ParseStringResult _parseString(String source, {bool useNnbd}) {
503+
var features = FeatureSet.fromEnableFlags([if (useNnbd) "non-nullable"]);
504+
return parseString(content: source, featureSet: features);
505+
}

utils/dartdevc/BUILD.gn

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,16 @@ prebuilt_dart_action("dartdevc_sdk") {
211211
"-o",
212212
rebase_path("$target_gen_dir/js/legacy/dart_sdk.js"),
213213
]
214+
215+
# TODO(38701): Cleanup after merging the forked SDK into mainline.
216+
if (use_nnbd) {
217+
args += [
218+
"--enable-experiment=non-nullable",
219+
220+
# TODO(38813): Ignore incorrect analyzer errors.
221+
"--unsafe-force-compile",
222+
]
223+
}
214224
}
215225

216226
# Builds everything needed to run dartdevc tests using test.dart.
@@ -321,6 +331,19 @@ prebuilt_dart_action("dartdevc_test_pkg") {
321331
"--output",
322332
rebase_path("$target_gen_dir"),
323333
]
334+
335+
# TODO(38701): Cleanup after merging the forked SDK into mainline.
336+
if (use_nnbd) {
337+
args += [
338+
"--enable-experiment=non-nullable",
339+
340+
# TODO(rnystrom): Most of the packages used by tests can be cleanly
341+
# compiled as opted-in libraries, but js.dart has an optional parameter
342+
# of type String with no default value. Changing that would be a breaking
343+
# API change. For now, ignore the error.
344+
"--unsafe-force-compile",
345+
]
346+
}
324347
}
325348

326349
prebuilt_dart_action("dartdevc_kernel_sdk_outline") {

0 commit comments

Comments
 (0)