Skip to content

Commit 6fe54f8

Browse files
author
Casey Hillers
authored
Revert "[flutter_tools] Remove --no-sound-null-safety #3" (flutter#123969)
Revert "[flutter_tools] Remove --no-sound-null-safety #3"
1 parent 1edd454 commit 6fe54f8

File tree

9 files changed

+137
-98
lines changed

9 files changed

+137
-98
lines changed

dev/bots/test.dart

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,9 @@ Future<void> _runExampleProjectBuildTests(Directory exampleDirectory, [File? mai
573573
// Only verify caching with flutter gallery.
574574
final bool verifyCaching = exampleDirectory.path.contains('flutter_gallery');
575575
final String examplePath = path.relative(exampleDirectory.path, from: Directory.current.path);
576+
final bool hasNullSafety = File(path.join(examplePath, 'null_safety')).existsSync();
576577
final List<String> additionalArgs = <String>[
578+
if (hasNullSafety) '--no-sound-null-safety',
577579
if (mainFile != null) path.relative(mainFile.path, from: exampleDirectory.absolute.path),
578580
];
579581
if (Directory(path.join(examplePath, 'android')).existsSync()) {
@@ -769,14 +771,16 @@ Future<void> _runAddToAppLifeCycleTests() async {
769771
}
770772

771773
Future<void> _runFrameworkTests() async {
774+
final List<String> soundNullSafetyOptions = <String>['--null-assertions', '--sound-null-safety'];
775+
final List<String> mixedModeNullSafetyOptions = <String>['--null-assertions', '--no-sound-null-safety'];
772776
final List<String> trackWidgetCreationAlternatives = <String>['--track-widget-creation', '--no-track-widget-creation'];
773777

774778
Future<void> runWidgets() async {
775779
printProgress('${green}Running packages/flutter tests $reset for ${cyan}test/widgets/$reset');
776780
for (final String trackWidgetCreationOption in trackWidgetCreationAlternatives) {
777781
await _runFlutterTest(
778782
path.join(flutterRoot, 'packages', 'flutter'),
779-
options: <String>[trackWidgetCreationOption],
783+
options: <String>[trackWidgetCreationOption, ...soundNullSafetyOptions],
780784
tests: <String>[ path.join('test', 'widgets') + path.separator ],
781785
);
782786
}
@@ -791,13 +795,13 @@ Future<void> _runFrameworkTests() async {
791795
// Run release mode tests (see packages/flutter/test_release/README.md)
792796
await _runFlutterTest(
793797
path.join(flutterRoot, 'packages', 'flutter'),
794-
options: <String>['--dart-define=dart.vm.product=true'],
798+
options: <String>['--dart-define=dart.vm.product=true', ...soundNullSafetyOptions],
795799
tests: <String>['test_release${path.separator}'],
796800
);
797801
// Run profile mode tests (see packages/flutter/test_profile/README.md)
798802
await _runFlutterTest(
799803
path.join(flutterRoot, 'packages', 'flutter'),
800-
options: <String>['--dart-define=dart.vm.product=false', '--dart-define=dart.vm.profile=true'],
804+
options: <String>['--dart-define=dart.vm.product=false', '--dart-define=dart.vm.profile=true', ...soundNullSafetyOptions],
801805
tests: <String>['test_profile${path.separator}'],
802806
);
803807
}
@@ -813,7 +817,7 @@ Future<void> _runFrameworkTests() async {
813817
for (final String trackWidgetCreationOption in trackWidgetCreationAlternatives) {
814818
await _runFlutterTest(
815819
path.join(flutterRoot, 'packages', 'flutter'),
816-
options: <String>[trackWidgetCreationOption],
820+
options: <String>[trackWidgetCreationOption, ...soundNullSafetyOptions],
817821
tests: tests,
818822
);
819823
}
@@ -833,9 +837,9 @@ Future<void> _runFrameworkTests() async {
833837
workingDirectory: path.join(flutterRoot, 'examples', 'api'),
834838
);
835839
}
836-
await _runFlutterTest(path.join(flutterRoot, 'examples', 'api'));
837-
await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'));
838-
await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'));
840+
await _runFlutterTest(path.join(flutterRoot, 'examples', 'api'), options: soundNullSafetyOptions);
841+
await _runFlutterTest(path.join(flutterRoot, 'examples', 'hello_world'), options: soundNullSafetyOptions);
842+
await _runFlutterTest(path.join(flutterRoot, 'examples', 'layers'), options: soundNullSafetyOptions);
839843
}
840844

841845
Future<void> runTracingTests() async {
@@ -941,6 +945,7 @@ Future<void> _runFrameworkTests() async {
941945

942946
Future<void> runPrivateTests() async {
943947
final List<String> args = <String>[
948+
'--sound-null-safety',
944949
'run',
945950
'bin/test_private.dart',
946951
];
@@ -984,17 +989,17 @@ Future<void> _runFrameworkTests() async {
984989
await _runFlutterTest(path.join(flutterRoot, 'dev', 'tools', 'gen_defaults'));
985990
await _runFlutterTest(path.join(flutterRoot, 'dev', 'tools', 'gen_keycodes'));
986991
await _runFlutterTest(path.join(flutterRoot, 'dev', 'benchmarks', 'test_apps', 'stocks'));
987-
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tests: <String>[path.join('test', 'src', 'real_tests')]);
992+
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_driver'), tests: <String>[path.join('test', 'src', 'real_tests')], options: soundNullSafetyOptions);
988993
await _runFlutterTest(path.join(flutterRoot, 'packages', 'integration_test'), options: <String>[
989994
'--enable-vmservice',
990995
// Web-specific tests depend on Chromium, so they run as part of the web_long_running_tests shard.
991996
'--exclude-tags=web',
992997
]);
993-
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'));
994-
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'));
995-
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'));
996-
await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'));
997-
await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'));
998+
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_goldens'), options: soundNullSafetyOptions);
999+
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), options: soundNullSafetyOptions);
1000+
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), options: soundNullSafetyOptions);
1001+
await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), options: soundNullSafetyOptions);
1002+
await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'), options: mixedModeNullSafetyOptions);
9981003
const String httpClientWarning =
9991004
'Warning: At least one test in this suite creates an HttpClient. When\n'
10001005
'running a test suite that uses TestWidgetsFlutterBinding, all HTTP\n'
@@ -1229,7 +1234,7 @@ Future<void> _runWebLongRunningTests() async {
12291234
'--dart-define=TEST_FLUTTER_ENGINE_VERSION=$engineVersion',
12301235
]),
12311236
() => _runWebDebugTest('test/test.dart'),
1232-
() => _runWebDebugTest('lib/null_safe_main.dart'),
1237+
() => _runWebDebugTest('lib/null_safe_main.dart', enableNullSafety: true),
12331238
() => _runWebDebugTest('lib/web_define_loading.dart',
12341239
additionalArguments: <String>[
12351240
'--dart-define=test.valueA=Example,A',
@@ -1242,8 +1247,12 @@ Future<void> _runWebLongRunningTests() async {
12421247
'--dart-define=test.valueB=Value',
12431248
]
12441249
),
1245-
() => _runWebDebugTest('lib/sound_mode.dart'),
1246-
() => _runWebReleaseTest('lib/sound_mode.dart'),
1250+
() => _runWebDebugTest('lib/sound_mode.dart', additionalArguments: <String>[
1251+
'--sound-null-safety',
1252+
]),
1253+
() => _runWebReleaseTest('lib/sound_mode.dart', additionalArguments: <String>[
1254+
'--sound-null-safety',
1255+
]),
12471256
() => _runFlutterWebTest(
12481257
'html',
12491258
path.join(flutterRoot, 'packages', 'integration_test'),
@@ -1302,6 +1311,7 @@ Future<void> _runFlutterDriverWebTest({
13021311
if (driver != null) '--driver=$driver',
13031312
'--target=$target',
13041313
'--browser-name=chrome',
1314+
'--no-sound-null-safety',
13051315
'-d',
13061316
'web-server',
13071317
'--$buildMode',
@@ -1343,6 +1353,7 @@ Future<void> _runWebTreeshakeTest() async {
13431353
'build',
13441354
'web',
13451355
'--target=$target',
1356+
'--no-sound-null-safety',
13461357
'--profile',
13471358
],
13481359
workingDirectory: testAppDirectory,
@@ -1568,6 +1579,7 @@ Future<void> _runGalleryE2eWebTest(String buildMode, { bool canvasKit = false })
15681579
'--driver=test_driver/transitions_perf_e2e_test.dart',
15691580
'--target=test_driver/transitions_perf_e2e.dart',
15701581
'--browser-name=chrome',
1582+
'--no-sound-null-safety',
15711583
'-d',
15721584
'web-server',
15731585
'--$buildMode',
@@ -1674,6 +1686,7 @@ Future<void> _runWebReleaseTest(String target, {
16741686
///
16751687
/// Instead, we use `flutter run --debug` and sniff out the standard output.
16761688
Future<void> _runWebDebugTest(String target, {
1689+
bool enableNullSafety = false,
16771690
List<String> additionalArguments = const<String>[],
16781691
}) async {
16791692
final String testAppDirectory = path.join(flutterRoot, 'dev', 'integration_tests', 'web');
@@ -1687,6 +1700,11 @@ Future<void> _runWebDebugTest(String target, {
16871700
<String>[
16881701
'run',
16891702
'--debug',
1703+
if (enableNullSafety)
1704+
...<String>[
1705+
'--no-sound-null-safety',
1706+
'--null-assertions',
1707+
],
16901708
'-d',
16911709
'chrome',
16921710
'--web-run-headless',
@@ -1729,6 +1747,7 @@ Future<void> _runFlutterWebTest(String webRenderer, String workingDirectory, Lis
17291747
'--platform=chrome',
17301748
'--web-renderer=$webRenderer',
17311749
'--dart-define=DART_HHH_BOT=$_runningInDartHHHBot',
1750+
'--sound-null-safety',
17321751
...flutterTestArgs,
17331752
...tests,
17341753
],

packages/flutter/lib/src/services/clipboard.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ abstract final class Clipboard {
5656
if (result == null) {
5757
return null;
5858
}
59-
return ClipboardData(text: result['text']! as String);
59+
return ClipboardData(text: result['text'] as String);
6060
}
6161

6262
/// Returns a future that resolves to true iff the clipboard contains string

packages/flutter/test/foundation/isolates_test.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ Future<int> test5CallCompute(int value) {
8080
return compute(test5, value);
8181
}
8282

83-
Future<void> expectFileSuccessfullyCompletes(String filename) async {
83+
Future<void> expectFileSuccessfullyCompletes(String filename,
84+
[bool unsound = false]) async {
8485
// Run a Dart script that calls compute().
8586
// The Dart process will terminate only if the script exits cleanly with
8687
// all isolate ports closed.
@@ -92,10 +93,12 @@ Future<void> expectFileSuccessfullyCompletes(String filename) async {
9293
final String packageRoot = fs.path.dirname(fs.path.fromUri(platform.script));
9394
final String scriptPath =
9495
fs.path.join(packageRoot, 'test', 'foundation', filename);
96+
final String nullSafetyArg =
97+
unsound ? '--no-sound-null-safety' : '--sound-null-safety';
9598

9699
// Enable asserts to also catch potentially invalid assertions.
97100
final ProcessResult result = await Process.run(
98-
dartPath, <String>['run', '--enable-asserts', scriptPath]);
101+
dartPath, <String>[nullSafetyArg, 'run', '--enable-asserts', scriptPath]);
99102
expect(result.exitCode, 0);
100103
}
101104

packages/flutter/test_private/bin/test_private.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ class TestCase {
225225
for (final File test in tests) {
226226
final String testPath = path.join(path.dirname(test.path), 'lib', path.basenameWithoutExtension(test.path));
227227
final ProcessRunnerResult result = await runner.runProcess(
228-
<String>[flutter, 'test', testPath],
228+
<String>[flutter, 'test', '--enable-experiment=non-nullable', '--no-sound-null-safety', '--null-assertions', testPath],
229229
failOk: true,
230230
);
231231
if (result.exitCode != 0) {

packages/flutter_tools/lib/src/globals.dart

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import 'pre_run_validator.dart';
4343
import 'project.dart';
4444
import 'reporting/crash_reporting.dart';
4545
import 'reporting/reporting.dart';
46-
import 'runner/flutter_command.dart';
4746
import 'runner/local_engine.dart';
4847
import 'version.dart';
4948

@@ -286,7 +285,3 @@ const String kDefaultFrameworkChannel = 'master';
286285

287286
// Used to build RegExp instances which can detect the VM service message.
288287
final RegExp kVMServiceMessageRegExp = RegExp(r'The Dart VM service is listening on ((http|//)[a-zA-Z0-9:/=_\-\.\[\]]+)');
289-
290-
// The official tool no longer allows non-null safe builds. This can be
291-
// overridden in other clients.
292-
NonNullSafeBuilds get nonNullSafeBuilds => context.get<NonNullSafeBuilds>() ?? NonNullSafeBuilds.notAllowed;

packages/flutter_tools/lib/src/runner/flutter_command.dart

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -822,13 +822,20 @@ abstract class FlutterCommand extends Command<void> {
822822

823823
void addNullSafetyModeOptions({ required bool hide }) {
824824
argParser.addFlag(FlutterOptions.kNullSafety,
825-
help: 'This flag is deprecated as only null-safe code is supported.',
825+
help:
826+
'Whether to override the inferred null safety mode. This allows null-safe '
827+
'libraries to depend on un-migrated (non-null safe) libraries. By default, '
828+
'Flutter mobile & desktop applications will attempt to run at the null safety '
829+
'level of their entrypoint library (usually lib/main.dart). Flutter web '
830+
'applications will default to sound null-safety, unless specifically configured.',
826831
defaultsTo: true,
827-
hide: true,
832+
hide: hide,
828833
);
829834
argParser.addFlag(FlutterOptions.kNullAssertions,
830-
help: 'This flag is deprecated as only null-safe code is supported.',
831-
hide: true,
835+
help:
836+
'Perform additional null assertions on the boundaries of migrated and '
837+
'un-migrated code. This setting is not currently supported on desktop '
838+
'devices.'
832839
);
833840
}
834841

@@ -1480,16 +1487,6 @@ abstract class FlutterCommand extends Command<void> {
14801487
/// rather than calling [runCommand] directly.
14811488
@mustCallSuper
14821489
Future<FlutterCommandResult> verifyThenRunCommand(String? commandPath) async {
1483-
if (argParser.options.containsKey(FlutterOptions.kNullSafety) &&
1484-
argResults![FlutterOptions.kNullSafety] == false &&
1485-
globals.nonNullSafeBuilds == NonNullSafeBuilds.notAllowed) {
1486-
throwToolExit('''
1487-
Could not find an option named "no-${FlutterOptions.kNullSafety}".
1488-
1489-
Run 'flutter -h' (or 'flutter <command> -h') for available flutter commands and options.
1490-
''');
1491-
}
1492-
14931490
globals.preRunValidator.validate();
14941491

14951492
if (refreshWirelessDevices) {
@@ -1757,12 +1754,3 @@ DevelopmentArtifact? artifactFromTargetPlatform(TargetPlatform targetPlatform) {
17571754

17581755
/// Returns true if s is either null, empty or is solely made of whitespace characters (as defined by String.trim).
17591756
bool _isBlank(String s) => s.trim().isEmpty;
1760-
1761-
/// Whether the tool should allow non-null safe builds.
1762-
///
1763-
/// The Dart SDK no longer supports non-null safe builds, so this value in the
1764-
/// tool's context should always be [NonNullSafeBuilds.notAllowed].
1765-
enum NonNullSafeBuilds {
1766-
allowed,
1767-
notAllowed,
1768-
}

packages/flutter_tools/test/commands.shard/hermetic/run_test.dart

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -67,52 +67,6 @@ void main() {
6767
Logger: () => BufferLogger.test(),
6868
});
6969

70-
testUsingContext('does not support --no-sound-null-safety by default', () async {
71-
fileSystem.file('lib/main.dart').createSync(recursive: true);
72-
fileSystem.file('pubspec.yaml').createSync();
73-
fileSystem.file('.packages').createSync();
74-
75-
final TestRunCommandThatOnlyValidates command = TestRunCommandThatOnlyValidates();
76-
await expectLater(
77-
() => createTestCommandRunner(command).run(<String>[
78-
'run',
79-
'--use-application-binary=app/bar/faz',
80-
'--no-sound-null-safety',
81-
]),
82-
throwsA(isException.having(
83-
(Exception exception) => exception.toString(),
84-
'toString',
85-
contains('Could not find an option named "no-sound-null-safety"'),
86-
)),
87-
);
88-
}, overrides: <Type, Generator>{
89-
FileSystem: () => fileSystem,
90-
ProcessManager: () => FakeProcessManager.any(),
91-
Logger: () => BufferLogger.test(),
92-
});
93-
94-
testUsingContext('supports --no-sound-null-safety with an overridden NonNullSafeBuilds', () async {
95-
fileSystem.file('lib/main.dart').createSync(recursive: true);
96-
fileSystem.file('pubspec.yaml').createSync();
97-
fileSystem.file('.packages').createSync();
98-
99-
final FakeDevice device = FakeDevice(isLocalEmulator: true, platformType: PlatformType.android);
100-
101-
testDeviceManager.devices = <Device>[device];
102-
final TestRunCommandThatOnlyValidates command = TestRunCommandThatOnlyValidates();
103-
await createTestCommandRunner(command).run(const <String>[
104-
'run',
105-
'--use-application-binary=app/bar/faz',
106-
'--no-sound-null-safety',
107-
]);
108-
}, overrides: <Type, Generator>{
109-
DeviceManager: () => testDeviceManager,
110-
FileSystem: () => fileSystem,
111-
Logger: () => BufferLogger.test(),
112-
NonNullSafeBuilds: () => NonNullSafeBuilds.allowed,
113-
ProcessManager: () => FakeProcessManager.any(),
114-
});
115-
11670
testUsingContext('does not support "--use-application-binary" and "--fast-start"', () async {
11771
fileSystem.file('lib/main.dart').createSync(recursive: true);
11872
fileSystem.file('pubspec.yaml').createSync();

packages/flutter_tools/test/general.shard/args_test.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,7 @@ void verifyOptions(String? command, Iterable<Option> options) {
176176
expect(option.name, matches(_allowedArgumentNamePattern), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (Is it all lowercase? Does it use hyphens rather than underscores?)');
177177
}
178178
expect(option.name, isNot(matches(_bannedArgumentNamePattern)), reason: '$_header$target--${option.name}" is not a valid name for a command line argument. (We use "--foo-url", not "--foo-uri", for example.)');
179-
// The flag --sound-null-safety is deprecated
180-
if (option.name != FlutterOptions.kNullSafety && option.name != FlutterOptions.kNullAssertions) {
181-
expect(option.hide, isFalse, reason: '${_header}Help for $target--${option.name}" is always hidden. $_needHelp');
182-
}
179+
expect(option.hide, isFalse, reason: '${_header}Help for $target--${option.name}" is always hidden. $_needHelp');
183180
expect(option.help, isNotNull, reason: '${_header}Help for $target--${option.name}" has null help. $_needHelp');
184181
expect(option.help, isNotEmpty, reason: '${_header}Help for $target--${option.name}" has empty help. $_needHelp');
185182
expect(option.help, isNot(matches(_bannedLeadingPatterns)), reason: '${_header}A line in the help for $target--${option.name}" starts with a lowercase letter. For stylistic consistency, all help messages must start with a capital letter.');

0 commit comments

Comments
 (0)