Skip to content

Commit a569f4a

Browse files
bkonyiCommit Queue
authored and
Commit Queue
committed
[ CLI ] Lockdown --no-sound-null-safety in dart compile subcommands
Related to #51513 Change-Id: Ie798af562133b933a76351b9e7244870ea49e6dd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/285380 Commit-Queue: Ben Konyi <[email protected]> Reviewed-by: Siva Annamalai <[email protected]>
1 parent 35e9a34 commit a569f4a

File tree

2 files changed

+55
-51
lines changed

2 files changed

+55
-51
lines changed

pkg/dartdev/lib/src/commands/compile.dart

+39-6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class Option {
2525
final String help;
2626
final String? abbr;
2727
final String? defaultsTo;
28+
final bool? flagDefaultsTo;
2829
final String? valueHelp;
2930
final List<String>? allowed;
3031
final Map<String, String>? allowedHelp;
@@ -34,6 +35,7 @@ class Option {
3435
required this.help,
3536
this.abbr,
3637
this.defaultsTo,
38+
this.flagDefaultsTo,
3739
this.valueHelp,
3840
this.allowed,
3941
this.allowedHelp,
@@ -127,9 +129,10 @@ class CompileSnapshotCommand extends CompileSubcommandCommand {
127129
abbr: defineOption.abbr,
128130
valueHelp: defineOption.valueHelp,
129131
)
130-
..addFlag('sound-null-safety',
131-
help: 'Respect the nullability of types at runtime.',
132-
defaultsTo: true)
132+
..addFlag(soundNullSafetyOption.flag,
133+
help: soundNullSafetyOption.help,
134+
defaultsTo: soundNullSafetyOption.flagDefaultsTo,
135+
hide: true)
133136
..addExperimentalFlags(verbose: verbose);
134137
}
135138

@@ -188,6 +191,9 @@ class CompileSnapshotCommand extends CompileSubcommandCommand {
188191

189192
final bool soundNullSafety = args['sound-null-safety'];
190193
if (!soundNullSafety) {
194+
if (!shouldAllowNoSoundNullSafety()) {
195+
return compileErrorExitCode;
196+
}
191197
buildArgs.add('--no-sound-null-safety');
192198
}
193199

@@ -269,9 +275,10 @@ class CompileNativeCommand extends CompileSubcommandCommand {
269275
valueHelp: packagesOption.valueHelp,
270276
help: packagesOption.help,
271277
)
272-
..addFlag('sound-null-safety',
273-
help: 'Respect the nullability of types at runtime.',
274-
defaultsTo: true)
278+
..addFlag(soundNullSafetyOption.flag,
279+
help: soundNullSafetyOption.help,
280+
defaultsTo: soundNullSafetyOption.flagDefaultsTo,
281+
hide: true)
275282
..addOption('save-debugging-info', abbr: 'S', valueHelp: 'path', help: '''
276283
Remove debugging information from the output and save it separately to the specified file.
277284
<path> can be relative or absolute.''')
@@ -315,6 +322,10 @@ Remove debugging information from the output and save it separately to the speci
315322
return -1;
316323
}
317324

325+
if (!args['sound-null-safety'] && !shouldAllowNoSoundNullSafety()) {
326+
return compileErrorExitCode;
327+
}
328+
318329
try {
319330
await generateNative(
320331
kind: format,
@@ -362,6 +373,11 @@ Sets the verbosity level of the compilation.
362373
allowed: Verbosity.allowedValues,
363374
allowedHelp: Verbosity.allowedValuesHelp,
364375
);
376+
final soundNullSafetyOption = Option(
377+
flag: 'sound-null-safety',
378+
help: 'DEPRECATED: Respect the nullability of types at runtime.',
379+
flagDefaultsTo: true,
380+
);
365381

366382
late final Option defineOption;
367383
late final Option packagesOption;
@@ -385,6 +401,23 @@ For example: dart compile $name -Da=1,b=2 main.dart''',
385401
<path> can be relative or absolute.
386402
For example: dart compile $name --packages=/tmp/pkgs.json main.dart'''),
387403
super(name, description, verbose, hidden: hidden);
404+
405+
bool shouldAllowNoSoundNullSafety() {
406+
// We need to maintain support for generating AOT snapshots and kernel
407+
// files with no-sound-null-safety internal Flutter aplications are
408+
// fully null-safe.
409+
//
410+
// See https://github.com/dart-lang/sdk/issues/51513 for context.
411+
if (name == CompileNativeCommand.aotSnapshotCmdName ||
412+
name == CompileSnapshotCommand.kernelCmdName) {
413+
log.stdout(
414+
'Warning: the flag --no-sound-null-safety is deprecated and pending removal.');
415+
return true;
416+
}
417+
log.stdout(
418+
'Error: the flag --no-sound-null-safety is not supported in Dart 3.');
419+
return false;
420+
}
388421
}
389422

390423
class CompileCommand extends DartdevCommand {

pkg/dartdev/test/commands/compile_test.dart

+16-45
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ void main() {
2323
const String soundNullSafetyMessage = 'Info: Compiling with sound null safety';
2424
const String unsoundNullSafetyMessage =
2525
'Info: Compiling without sound null safety';
26+
const String unsoundNullSafetyError =
27+
'Error: the flag --no-sound-null-safety is not supported in Dart 3.';
28+
const String unsoundNullSafetyWarning =
29+
'Warning: the flag --no-sound-null-safety is deprecated and pending removal.';
2630

2731
void defineCompileTests() {
2832
final isRunningOnIA32 = Platform.version.contains('ia32');
@@ -538,11 +542,10 @@ void main() {}
538542
],
539543
);
540544

541-
expect(result.stdout, contains(unsoundNullSafetyMessage));
545+
expect(result.stdout, contains(unsoundNullSafetyError));
542546
expect(result.stderr, isEmpty);
543-
expect(result.exitCode, 0);
544-
expect(File(outFile).existsSync(), true,
545-
reason: 'File not found: $outFile');
547+
expect(result.exitCode, 64);
548+
expect(File(outFile).existsSync(), false, reason: 'File found: $outFile');
546549
}, skip: isRunningOnIA32);
547550

548551
test('Compile and run exe with --sound-null-safety', () async {
@@ -579,40 +582,6 @@ void main() {}
579582
expect(result.stdout, contains('sound'));
580583
}, skip: isRunningOnIA32);
581584

582-
test('Compile and run exe with --no-sound-null-safety', () async {
583-
final p = project(mainSrc: '''void main() {
584-
print((<int?>[] is List<int>) ? 'unsound' : 'oh no');
585-
}''');
586-
final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
587-
final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
588-
589-
var result = await p.run(
590-
[
591-
'compile',
592-
'exe',
593-
'--no-sound-null-safety',
594-
'-o',
595-
outFile,
596-
inFile,
597-
],
598-
);
599-
600-
expect(result.stdout, contains(unsoundNullSafetyMessage));
601-
expect(result.stderr, isEmpty);
602-
expect(result.exitCode, 0);
603-
expect(File(outFile).existsSync(), true,
604-
reason: 'File not found: $outFile');
605-
606-
result = Process.runSync(
607-
outFile,
608-
[],
609-
);
610-
611-
expect(result.stdout, contains('unsound'));
612-
expect(result.stderr, isEmpty);
613-
expect(result.exitCode, 0);
614-
}, skip: isRunningOnIA32);
615-
616585
test('Compile exe without info', () async {
617586
final p = project(mainSrc: '''void main() {}''');
618587
final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -804,6 +773,7 @@ void main() {}
804773
);
805774

806775
expect(result.stdout, contains(unsoundNullSafetyMessage));
776+
expect(result.stdout, contains(unsoundNullSafetyWarning));
807777
expect(result.stderr, isEmpty);
808778
expect(result.exitCode, 0);
809779
expect(File(outFile).existsSync(), true,
@@ -958,6 +928,7 @@ void main() {}
958928
);
959929

960930
expect(result.stderr, contains(unsoundNullSafetyMessage));
931+
expect(result.stdout, contains(unsoundNullSafetyWarning));
961932
expect(result.exitCode, 0);
962933
expect(File(outFile).existsSync(), true,
963934
reason: 'File not found: $outFile');
@@ -1006,6 +977,7 @@ void main() {}
1006977
);
1007978

1008979
expect(result.stderr, isNot(contains(soundNullSafetyMessage)));
980+
expect(result.stdout, contains(unsoundNullSafetyWarning));
1009981
expect(result.exitCode, 0);
1010982
expect(File(outFile).existsSync(), true,
1011983
reason: 'File not found: $outFile');
@@ -1126,10 +1098,9 @@ void main() {}
11261098
],
11271099
);
11281100

1129-
expect(result.stderr, contains(unsoundNullSafetyMessage));
1130-
expect(result.exitCode, 0);
1131-
expect(File(outFile).existsSync(), true,
1132-
reason: 'File not found: $outFile');
1101+
expect(result.stdout, contains(unsoundNullSafetyError));
1102+
expect(result.exitCode, 64);
1103+
expect(File(outFile).existsSync(), false, reason: 'File found: $outFile');
11331104
});
11341105

11351106
test('Compile JIT snapshot with --sound-null-safety', () async {
@@ -1175,9 +1146,9 @@ void main() {}
11751146
);
11761147

11771148
expect(result.stderr, isNot(contains(soundNullSafetyMessage)));
1178-
expect(result.exitCode, 0);
1179-
expect(File(outFile).existsSync(), true,
1180-
reason: 'File not found: $outFile');
1149+
expect(result.stdout, contains(unsoundNullSafetyError));
1150+
expect(result.exitCode, 64);
1151+
expect(File(outFile).existsSync(), false, reason: 'File found: $outFile');
11811152
});
11821153

11831154
test('Compile JIT snapshot with training args', () async {

0 commit comments

Comments
 (0)