diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart index 437b941f639..e22e4dbce0f 100644 --- a/pkg/dartdev/lib/src/commands/compile.dart +++ b/pkg/dartdev/lib/src/commands/compile.dart @@ -127,6 +127,9 @@ class CompileSnapshotCommand extends CompileSubcommandCommand { abbr: defineOption.abbr, valueHelp: defineOption.valueHelp, ) + ..addFlag('sound-null-safety', + help: 'Respect the nullability of types at runtime.', + defaultsTo: null) ..addExperimentalFlags(verbose: verbose); } @@ -183,6 +186,11 @@ class CompileSnapshotCommand extends CompileSubcommandCommand { buildArgs.add('--snapshot-kind=$formatName'); buildArgs.add('--snapshot=${path.canonicalize(outputFile)}'); + final bool? soundNullSafety = args['sound-null-safety']; + if (soundNullSafety != null) { + buildArgs.add('--${soundNullSafety ? '' : 'no-'}sound-null-safety'); + } + final String? packages = args[packagesOption.flag]; if (packages != null) { buildArgs.add('--packages=$packages'); diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart index 11deb0ec85e..dab7120ee55 100644 --- a/pkg/dartdev/test/commands/compile_test.dart +++ b/pkg/dartdev/test/commands/compile_test.dart @@ -962,6 +962,56 @@ void main() {} reason: 'File not found: $outFile'); }); + test('Compile kernel with --sound-null-safety', () async { + final p = project(mainSrc: '''void main() { + print(([] is List) ? 'oh no' : 'sound'); + }'''); + final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath)); + final outFile = path.canonicalize(path.join(p.dirPath, 'mydill')); + + var result = await p.run( + [ + 'compile', + 'kernel', + '--sound-null-safety', + '-o', + outFile, + inFile, + ], + ); + + expect(result.stderr, isEmpty); + expect(result.stdout, contains(soundNullSafetyMessage)); + expect(result.exitCode, 0); + expect(File(outFile).existsSync(), true, + reason: 'File not found: $outFile'); + }); + + test('Compile kernel with --no-sound-null-safety', () async { + final p = project(mainSrc: '''void main() { + print(([] is List) ? 'unsound' : 'oh no'); + }'''); + final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath)); + final outFile = path.canonicalize(path.join(p.dirPath, 'mydill')); + + var result = await p.run( + [ + 'compile', + 'kernel', + '--no-sound-null-safety', + '-o', + outFile, + inFile, + ], + ); + + expect(result.stderr, isEmpty); + expect(result.stdout, isNot(contains(soundNullSafetyMessage))); + expect(result.exitCode, 0); + expect(File(outFile).existsSync(), true, + reason: 'File not found: $outFile'); + }); + test('Compile kernel without info', () async { final p = project(mainSrc: '''void main() {}'''); final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath)); @@ -1085,6 +1135,56 @@ void main() {} reason: 'File not found: $outFile'); }); + test('Compile JIT snapshot with --sound-null-safety', () async { + final p = project(mainSrc: '''void main() { + print(([] is List) ? 'oh no' : 'sound'); + }'''); + final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath)); + final outFile = path.canonicalize(path.join(p.dirPath, 'myjit')); + + var result = await p.run( + [ + 'compile', + 'jit-snapshot', + '--sound-null-safety', + '-o', + outFile, + inFile, + ], + ); + + expect(result.stderr, isEmpty); + expect(result.stdout, contains(soundNullSafetyMessage)); + expect(result.exitCode, 0); + expect(File(outFile).existsSync(), true, + reason: 'File not found: $outFile'); + }); + + test('Compile JIT snapshot with --no-sound-null-safety', () async { + final p = project(mainSrc: '''void main() { + print(([] is List) ? 'unsound' : 'oh no'); + }'''); + final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath)); + final outFile = path.canonicalize(path.join(p.dirPath, 'mydill')); + + var result = await p.run( + [ + 'compile', + 'jit-snapshot', + '--no-sound-null-safety', + '-o', + outFile, + inFile, + ], + ); + + expect(result.stderr, isEmpty); + expect(result.stdout, isNot(contains(soundNullSafetyMessage))); + expect(result.exitCode, 0); + expect(File(outFile).existsSync(), true, + reason: 'File not found: $outFile'); + }); + test('Compile JIT snapshot with training args', () async { final p = project(mainSrc: '''void main(List args) => print(args);''');