Unverified Commit b1d75fc9 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] add flag for sound-null-safety, unify with experiments (#58533)

Also combines experiments into extraGenSnapshot/ExtraFrontEndOptions. Allows providing --no-sound-null-safety to allow out of order migration and running.
parent 95edf281
...@@ -340,8 +340,7 @@ Future<void> _runToolTests() async { ...@@ -340,8 +340,7 @@ Future<void> _runToolTests() async {
/// target app. /// target app.
Future<void> _runBuildTests() async { Future<void> _runBuildTests() async {
final List<FileSystemEntity> exampleDirectories = Directory(path.join(flutterRoot, 'examples')).listSync() final List<FileSystemEntity> exampleDirectories = Directory(path.join(flutterRoot, 'examples')).listSync()
// TODO(jonahwilliams): re-enable once https://github.com/flutter/flutter/issues/57234 is done. ..add(Directory(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable')))
// ..add(Directory(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable')))
..add(Directory(path.join(flutterRoot, 'dev', 'integration_tests', 'flutter_gallery'))); ..add(Directory(path.join(flutterRoot, 'dev', 'integration_tests', 'flutter_gallery')));
final String branch = Platform.environment['CIRRUS_BRANCH']; final String branch = Platform.environment['CIRRUS_BRANCH'];
...@@ -377,7 +376,7 @@ Future<void> _runExampleProjectBuildTests(FileSystemEntity exampleDirectory) asy ...@@ -377,7 +376,7 @@ Future<void> _runExampleProjectBuildTests(FileSystemEntity exampleDirectory) asy
final String examplePath = exampleDirectory.path; final String examplePath = exampleDirectory.path;
final bool hasNullSafety = File(path.join(examplePath, 'null_safety')).existsSync(); final bool hasNullSafety = File(path.join(examplePath, 'null_safety')).existsSync();
final List<String> additionalArgs = hasNullSafety final List<String> additionalArgs = hasNullSafety
? <String>['--enable-experiment', 'non-nullable'] ? <String>['--enable-experiment', 'non-nullable', '--no-sound-null-safety']
: <String>[]; : <String>[];
if (Directory(path.join(examplePath, 'android')).existsSync()) { if (Directory(path.join(examplePath, 'android')).existsSync()) {
await _flutterBuildApk(examplePath, release: false, additionalArgs: additionalArgs, verifyCaching: verifyCaching); await _flutterBuildApk(examplePath, release: false, additionalArgs: additionalArgs, verifyCaching: verifyCaching);
...@@ -603,10 +602,9 @@ Future<void> _runFrameworkTests() async { ...@@ -603,10 +602,9 @@ Future<void> _runFrameworkTests() async {
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_localizations'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'flutter_test'), tableData: bigqueryApi?.tabledata);
await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata); await _runFlutterTest(path.join(flutterRoot, 'packages', 'fuchsia_remote_debug_protocol'), tableData: bigqueryApi?.tabledata);
// TODO(jonahwilliams): re-enable once https://github.com/flutter/flutter/issues/57234 is done. await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'),
// await _runFlutterTest(path.join(flutterRoot, 'dev', 'integration_tests', 'non_nullable'), options: <String>['--enable-experiment=non-nullable', '--no-sound-null-safety'],
// options: <String>['--enable-experiment=non-nullable'], );
// );
await _runFlutterTest( await _runFlutterTest(
path.join(flutterRoot, 'dev', 'tracing_tests'), path.join(flutterRoot, 'dev', 'tracing_tests'),
options: <String>['--enable-vmservice'], options: <String>['--enable-vmservice'],
...@@ -756,8 +754,7 @@ Future<void> _runWebIntegrationTests() async { ...@@ -756,8 +754,7 @@ Future<void> _runWebIntegrationTests() async {
await _runWebDebugTest('lib/stack_trace.dart'); await _runWebDebugTest('lib/stack_trace.dart');
await _runWebDebugTest('lib/web_directory_loading.dart'); await _runWebDebugTest('lib/web_directory_loading.dart');
await _runWebDebugTest('test/test.dart'); await _runWebDebugTest('test/test.dart');
// TODO(jonahwilliams): re-enable once https://github.com/flutter/flutter/issues/57234 is done. await _runWebDebugTest('lib/null_safe_main.dart', enableNullSafety: true);
// await _runWebDebugTest('lib/null_safe_main.dart', enableNullSafety: true);
await _runWebDebugTest('lib/web_define_loading.dart', await _runWebDebugTest('lib/web_define_loading.dart',
additionalArguments: <String>[ additionalArguments: <String>[
'--dart-define=test.valueA=Example', '--dart-define=test.valueA=Example',
...@@ -875,6 +872,7 @@ Future<void> _runWebDebugTest(String target, { ...@@ -875,6 +872,7 @@ Future<void> _runWebDebugTest(String target, {
...<String>[ ...<String>[
'--enable-experiment', '--enable-experiment',
'non-nullable', 'non-nullable',
'--no-sound-null-safety'
], ],
'-d', '-d',
'chrome', 'chrome',
......
...@@ -155,7 +155,7 @@ Future<void> run(List<String> args) async { ...@@ -155,7 +155,7 @@ Future<void> run(List<String> args) async {
concurrency: math.max(1, globals.platform.numberOfProcessors - 2), concurrency: math.max(1, globals.platform.numberOfProcessors - 2),
icudtlPath: globals.fs.path.absolute(argResults[_kOptionIcudtl] as String), icudtlPath: globals.fs.path.absolute(argResults[_kOptionIcudtl] as String),
coverageDirectory: coverageDirectory, coverageDirectory: coverageDirectory,
dartExperiments: <String>[], extraFrontEndOptions: <String>[],
); );
if (collector != null) { if (collector != null) {
......
...@@ -82,7 +82,7 @@ RunCommand "${FLUTTER_ROOT}/bin/flutter" \ ...@@ -82,7 +82,7 @@ RunCommand "${FLUTTER_ROOT}/bin/flutter" \
-dTrackWidgetCreation="${TRACK_WIDGET_CREATION}" \ -dTrackWidgetCreation="${TRACK_WIDGET_CREATION}" \
--DartDefines="${DART_DEFINES}" \ --DartDefines="${DART_DEFINES}" \
--ExtraGenSnapshotOptions="${EXTRA_GEN_SNAPSHOT_OPTIONS}" \ --ExtraGenSnapshotOptions="${EXTRA_GEN_SNAPSHOT_OPTIONS}" \
-dExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \ --ExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \
--build-inputs="${build_inputs_path}" \ --build-inputs="${build_inputs_path}" \
--build-outputs="${build_outputs_path}" \ --build-outputs="${build_outputs_path}" \
--output="${ephemeral_dir}" \ --output="${ephemeral_dir}" \
......
...@@ -69,7 +69,7 @@ or ...@@ -69,7 +69,7 @@ or
if (extraGenSnapshotOptions != null) if (extraGenSnapshotOptions != null)
'--ExtraGenSnapshotOptions=$extraGenSnapshotOptions', '--ExtraGenSnapshotOptions=$extraGenSnapshotOptions',
if (extraFrontEndOptions != null) if (extraFrontEndOptions != null)
'-dExtraFrontEndOptions=$extraFrontEndOptions', '--ExtraFrontEndOptions=$extraFrontEndOptions',
target, target,
], ],
); );
......
...@@ -168,7 +168,7 @@ is set to release or run \"flutter build ios --release\", then re-run Archive fr ...@@ -168,7 +168,7 @@ is set to release or run \"flutter build ios --release\", then re-run Archive fr
-dEnableBitcode="${bitcode_flag}" \ -dEnableBitcode="${bitcode_flag}" \
--ExtraGenSnapshotOptions="${EXTRA_GEN_SNAPSHOT_OPTIONS}" \ --ExtraGenSnapshotOptions="${EXTRA_GEN_SNAPSHOT_OPTIONS}" \
--DartDefines="${DART_DEFINES}" \ --DartDefines="${DART_DEFINES}" \
-dExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \ --ExtraFrontEndOptions="${EXTRA_FRONT_END_OPTIONS}" \
"${build_mode}_ios_bundle_flutter_assets" "${build_mode}_ios_bundle_flutter_assets"
if [[ $? -ne 0 ]]; then if [[ $? -ne 0 ]]; then
......
...@@ -919,9 +919,6 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -919,9 +919,6 @@ abstract class BaseFlutterTask extends DefaultTask {
} }
args "-dTargetPlatform=android" args "-dTargetPlatform=android"
args "-dBuildMode=${buildMode}" args "-dBuildMode=${buildMode}"
if (extraFrontEndOptions != null) {
args "-dExtraFrontEndOptions=${extraFrontEndOptions}"
}
if (trackWidgetCreation != null) { if (trackWidgetCreation != null) {
args "-dTrackWidgetCreation=${trackWidgetCreation}" args "-dTrackWidgetCreation=${trackWidgetCreation}"
} }
...@@ -943,6 +940,9 @@ abstract class BaseFlutterTask extends DefaultTask { ...@@ -943,6 +940,9 @@ abstract class BaseFlutterTask extends DefaultTask {
if (extraGenSnapshotOptions != null) { if (extraGenSnapshotOptions != null) {
args "--ExtraGenSnapshotOptions=${extraGenSnapshotOptions}" args "--ExtraGenSnapshotOptions=${extraGenSnapshotOptions}"
} }
if (extraFrontEndOptions != null) {
args "--ExtraFrontEndOptions=${extraFrontEndOptions}"
}
args ruleNames args ruleNames
} }
} }
......
...@@ -310,10 +310,10 @@ Future<void> buildGradleApp({ ...@@ -310,10 +310,10 @@ Future<void> buildGradleApp({
command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}'); command.add('-Ptrack-widget-creation=${buildInfo.trackWidgetCreation}');
if (buildInfo.extraFrontEndOptions != null) { if (buildInfo.extraFrontEndOptions != null) {
command.add('-Pextra-front-end-options=${buildInfo.extraFrontEndOptions.join(',')}'); command.add('-Pextra-front-end-options=${encodeDartDefines(buildInfo.extraFrontEndOptions)}');
} }
if (buildInfo.extraGenSnapshotOptions != null) { if (buildInfo.extraGenSnapshotOptions != null) {
command.add('-Pextra-gen-snapshot-options=${buildInfo.extraGenSnapshotOptions.join(',')}'); command.add('-Pextra-gen-snapshot-options=${encodeDartDefines(buildInfo.extraGenSnapshotOptions)}');
} }
if (buildInfo.fileSystemRoots != null && buildInfo.fileSystemRoots.isNotEmpty) { if (buildInfo.fileSystemRoots != null && buildInfo.fileSystemRoots.isNotEmpty) {
command.add('-Pfilesystem-roots=${buildInfo.fileSystemRoots.join('|')}'); command.add('-Pfilesystem-roots=${buildInfo.fileSystemRoots.join('|')}');
......
...@@ -143,9 +143,9 @@ class BuildInfo { ...@@ -143,9 +143,9 @@ class BuildInfo {
if (dartObfuscation != null) if (dartObfuscation != null)
'DART_OBFUSCATION': dartObfuscation.toString(), 'DART_OBFUSCATION': dartObfuscation.toString(),
if (extraFrontEndOptions?.isNotEmpty ?? false) if (extraFrontEndOptions?.isNotEmpty ?? false)
'EXTRA_FRONT_END_OPTIONS': extraFrontEndOptions.join(','), 'EXTRA_FRONT_END_OPTIONS': encodeDartDefines(extraFrontEndOptions),
if (extraGenSnapshotOptions?.isNotEmpty ?? false) if (extraGenSnapshotOptions?.isNotEmpty ?? false)
'EXTRA_GEN_SNAPSHOT_OPTIONS': extraGenSnapshotOptions.join(','), 'EXTRA_GEN_SNAPSHOT_OPTIONS': encodeDartDefines(extraGenSnapshotOptions),
if (splitDebugInfoPath != null) if (splitDebugInfoPath != null)
'SPLIT_DEBUG_INFO': splitDebugInfoPath, 'SPLIT_DEBUG_INFO': splitDebugInfoPath,
if (trackWidgetCreation != null) if (trackWidgetCreation != null)
...@@ -667,11 +667,11 @@ String encodeDartDefines(List<String> defines) { ...@@ -667,11 +667,11 @@ String encodeDartDefines(List<String> defines) {
} }
/// Dart defines are encoded inside [environmentDefines] as a comma-separated list. /// Dart defines are encoded inside [environmentDefines] as a comma-separated list.
List<String> decodeDartDefines(Map<String, String> environmentDefines) { List<String> decodeDartDefines(Map<String, String> environmentDefines, String key) {
if (!environmentDefines.containsKey(kDartDefines) || environmentDefines[kDartDefines].isEmpty) { if (!environmentDefines.containsKey(key) || environmentDefines[key].isEmpty) {
return const <String>[]; return const <String>[];
} }
return environmentDefines[kDartDefines] return environmentDefines[key]
.split(',') .split(',')
.map<Object>(Uri.decodeComponent) .map<Object>(Uri.decodeComponent)
.cast<String>() .cast<String>()
......
...@@ -441,7 +441,6 @@ class _ResidentWebRunner extends ResidentWebRunner { ...@@ -441,7 +441,6 @@ class _ResidentWebRunner extends ResidentWebRunner {
debuggingOptions.buildInfo, debuggingOptions.buildInfo,
debuggingOptions.initializePlatform, debuggingOptions.initializePlatform,
false, false,
debuggingOptions.buildInfo.dartExperiments,
); );
} }
await device.device.startApp( await device.device.startApp(
...@@ -504,7 +503,6 @@ class _ResidentWebRunner extends ResidentWebRunner { ...@@ -504,7 +503,6 @@ class _ResidentWebRunner extends ResidentWebRunner {
debuggingOptions.buildInfo, debuggingOptions.buildInfo,
debuggingOptions.initializePlatform, debuggingOptions.initializePlatform,
false, false,
debuggingOptions.buildInfo.dartExperiments,
); );
} on ToolExit { } on ToolExit {
return OperationResult(1, 'Failed to recompile application.'); return OperationResult(1, 'Failed to recompile application.');
......
...@@ -246,8 +246,7 @@ class AndroidAot extends AotElfBase { ...@@ -246,8 +246,7 @@ class AndroidAot extends AotElfBase {
if (!output.existsSync()) { if (!output.existsSync()) {
output.createSync(recursive: true); output.createSync(recursive: true);
} }
final List<String> extraGenSnapshotOptions = environment.defines[kExtraGenSnapshotOptions]?.split(',') final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions);
?? const <String>[];
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]); final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true'; final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true';
final int snapshotExitCode = await snapshotter.build( final int snapshotExitCode = await snapshotter.build(
......
...@@ -205,10 +205,7 @@ class KernelSnapshot extends Target { ...@@ -205,10 +205,7 @@ class KernelSnapshot extends Target {
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]); final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
// This configuration is all optional. // This configuration is all optional.
final String rawFrontEndOption = environment.defines[kExtraFrontEndOptions]; final List<String> extraFrontEndOptions = decodeDartDefines(environment.defines, kExtraFrontEndOptions);
final List<String> extraFrontEndOptions = (rawFrontEndOption?.isNotEmpty ?? false)
? rawFrontEndOption?.split(',')
: null;
final List<String> fileSystemRoots = environment.defines[kFileSystemRoots]?.split(','); final List<String> fileSystemRoots = environment.defines[kFileSystemRoots]?.split(',');
final String fileSystemScheme = environment.defines[kFileSystemScheme]; final String fileSystemScheme = environment.defines[kFileSystemScheme];
...@@ -254,7 +251,7 @@ class KernelSnapshot extends Target { ...@@ -254,7 +251,7 @@ class KernelSnapshot extends Target {
extraFrontEndOptions: extraFrontEndOptions, extraFrontEndOptions: extraFrontEndOptions,
fileSystemRoots: fileSystemRoots, fileSystemRoots: fileSystemRoots,
fileSystemScheme: fileSystemScheme, fileSystemScheme: fileSystemScheme,
dartDefines: decodeDartDefines(environment.defines), dartDefines: decodeDartDefines(environment.defines, kDartDefines),
packageConfig: packageConfig, packageConfig: packageConfig,
); );
if (output == null || output.errorCount != 0) { if (output == null || output.errorCount != 0) {
...@@ -287,8 +284,7 @@ abstract class AotElfBase extends Target { ...@@ -287,8 +284,7 @@ abstract class AotElfBase extends Target {
if (environment.defines[kTargetPlatform] == null) { if (environment.defines[kTargetPlatform] == null) {
throw MissingDefineException(kTargetPlatform, 'aot_elf'); throw MissingDefineException(kTargetPlatform, 'aot_elf');
} }
final List<String> extraGenSnapshotOptions = environment.defines[kExtraGenSnapshotOptions]?.split(',') final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions);
?? const <String>[];
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]); final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]); final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
final String splitDebugInfo = environment.defines[kSplitDebugInfo]; final String splitDebugInfo = environment.defines[kSplitDebugInfo];
......
...@@ -46,7 +46,7 @@ abstract class AotAssemblyBase extends Target { ...@@ -46,7 +46,7 @@ abstract class AotAssemblyBase extends Target {
if (environment.defines[kTargetPlatform] == null) { if (environment.defines[kTargetPlatform] == null) {
throw MissingDefineException(kTargetPlatform, 'aot_assembly'); throw MissingDefineException(kTargetPlatform, 'aot_assembly');
} }
final List<String> extraGenSnapshotOptions = parseExtraGenSnapshotOptions(environment); final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions);
final bool bitcode = environment.defines[kBitcodeFlag] == 'true'; final bool bitcode = environment.defines[kBitcodeFlag] == 'true';
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]); final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]); final TargetPlatform targetPlatform = getTargetPlatformForName(environment.defines[kTargetPlatform]);
...@@ -447,13 +447,3 @@ Future<RunResult> createStubAppFramework(File outputFile, SdkType sdk, { bool in ...@@ -447,13 +447,3 @@ Future<RunResult> createStubAppFramework(File outputFile, SdkType sdk, { bool in
} }
} }
} }
/// iOS and macOS build scripts may pass extraGenSnapshotOptions as an empty
/// string.
List<String> parseExtraGenSnapshotOptions(Environment environment) {
final String value = environment.defines[kExtraGenSnapshotOptions];
if (value == null || value.trim().isEmpty) {
return <String>[];
}
return value.split(',');
}
...@@ -15,7 +15,6 @@ import '../exceptions.dart'; ...@@ -15,7 +15,6 @@ import '../exceptions.dart';
import 'assets.dart'; import 'assets.dart';
import 'dart.dart'; import 'dart.dart';
import 'icon_tree_shaker.dart'; import 'icon_tree_shaker.dart';
import 'ios.dart';
/// Copy the macOS framework to the correct copy dir by invoking 'cp -R'. /// Copy the macOS framework to the correct copy dir by invoking 'cp -R'.
/// ///
...@@ -198,7 +197,7 @@ class CompileMacOSFramework extends Target { ...@@ -198,7 +197,7 @@ class CompileMacOSFramework extends Target {
} }
final String splitDebugInfo = environment.defines[kSplitDebugInfo]; final String splitDebugInfo = environment.defines[kSplitDebugInfo];
final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true'; final bool dartObfuscation = environment.defines[kDartObfuscation] == 'true';
final List<String> extraGenSnapshotOptions = parseExtraGenSnapshotOptions(environment); final List<String> extraGenSnapshotOptions = decodeDartDefines(environment.defines, kExtraGenSnapshotOptions);
final AOTSnapshotter snapshotter = AOTSnapshotter( final AOTSnapshotter snapshotter = AOTSnapshotter(
reportTimings: false, reportTimings: false,
fileSystem: globals.fs, fileSystem: globals.fs,
......
...@@ -28,11 +28,6 @@ const String kHasWebPlugins = 'HasWebPlugins'; ...@@ -28,11 +28,6 @@ const String kHasWebPlugins = 'HasWebPlugins';
/// Valid values are O1 (lowest, profile default) to O4 (highest, release default). /// Valid values are O1 (lowest, profile default) to O4 (highest, release default).
const String kDart2jsOptimization = 'Dart2jsOptimization'; const String kDart2jsOptimization = 'Dart2jsOptimization';
/// Allow specifying experiments for dart2js.
///
/// Multiple values should be encoded as a comma-separated list.
const String kEnableExperiment = 'EnableExperiment';
/// Whether to disable dynamic generation code to satisfy csp policies. /// Whether to disable dynamic generation code to satisfy csp policies.
const String kCspMode = 'cspMode'; const String kCspMode = 'cspMode';
...@@ -164,8 +159,8 @@ class Dart2JSTarget extends Target { ...@@ -164,8 +159,8 @@ class Dart2JSTarget extends Target {
final String packageFile = globalPackagesPath; final String packageFile = globalPackagesPath;
final File outputKernel = environment.buildDir.childFile('app.dill'); final File outputKernel = environment.buildDir.childFile('app.dill');
final File outputFile = environment.buildDir.childFile('main.dart.js'); final File outputFile = environment.buildDir.childFile('main.dart.js');
final List<String> dartDefines = decodeDartDefines(environment.defines); final List<String> dartDefines = decodeDartDefines(environment.defines, kDartDefines);
final String enabledExperiments = environment.defines[kEnableExperiment]; final List<String> extraFrontEndOptions = decodeDartDefines(environment.defines, kExtraFrontEndOptions);
// Run the dart2js compilation in two stages, so that icon tree shaking can // Run the dart2js compilation in two stages, so that icon tree shaking can
// parse the kernel file for web builds. // parse the kernel file for web builds.
...@@ -173,8 +168,7 @@ class Dart2JSTarget extends Target { ...@@ -173,8 +168,7 @@ class Dart2JSTarget extends Target {
globals.artifacts.getArtifactPath(Artifact.engineDartBinary), globals.artifacts.getArtifactPath(Artifact.engineDartBinary),
globals.artifacts.getArtifactPath(Artifact.dart2jsSnapshot), globals.artifacts.getArtifactPath(Artifact.dart2jsSnapshot),
'--libraries-spec=$specPath', '--libraries-spec=$specPath',
if (enabledExperiments != null) ...?extraFrontEndOptions,
'--enable-experiment=$enabledExperiments',
'-o', '-o',
outputKernel.path, outputKernel.path,
'--packages=$packageFile', '--packages=$packageFile',
...@@ -194,8 +188,7 @@ class Dart2JSTarget extends Target { ...@@ -194,8 +188,7 @@ class Dart2JSTarget extends Target {
globals.artifacts.getArtifactPath(Artifact.engineDartBinary), globals.artifacts.getArtifactPath(Artifact.engineDartBinary),
globals.artifacts.getArtifactPath(Artifact.dart2jsSnapshot), globals.artifacts.getArtifactPath(Artifact.dart2jsSnapshot),
'--libraries-spec=$specPath', '--libraries-spec=$specPath',
if (enabledExperiments != null) ...?extraFrontEndOptions,
'--enable-experiment=$enabledExperiments',
if (dart2jsOptimization != null) if (dart2jsOptimization != null)
'-$dart2jsOptimization' '-$dart2jsOptimization'
else else
......
...@@ -105,6 +105,7 @@ class AssembleCommand extends FlutterCommand { ...@@ -105,6 +105,7 @@ class AssembleCommand extends FlutterCommand {
'root of the current Flutter project.', 'root of the current Flutter project.',
); );
argParser.addOption(kExtraGenSnapshotOptions); argParser.addOption(kExtraGenSnapshotOptions);
argParser.addOption(kExtraFrontEndOptions);
argParser.addOption(kDartDefines); argParser.addOption(kDartDefines);
argParser.addOption( argParser.addOption(
'resource-pool-size', 'resource-pool-size',
...@@ -204,10 +205,12 @@ class AssembleCommand extends FlutterCommand { ...@@ -204,10 +205,12 @@ class AssembleCommand extends FlutterCommand {
if (argResults.wasParsed(kExtraGenSnapshotOptions)) { if (argResults.wasParsed(kExtraGenSnapshotOptions)) {
results[kExtraGenSnapshotOptions] = argResults[kExtraGenSnapshotOptions] as String; results[kExtraGenSnapshotOptions] = argResults[kExtraGenSnapshotOptions] as String;
} }
// Workaround for dart-define formatting
if (argResults.wasParsed(kDartDefines)) { if (argResults.wasParsed(kDartDefines)) {
results[kDartDefines] = argResults[kDartDefines] as String; results[kDartDefines] = argResults[kDartDefines] as String;
} }
if (argResults.wasParsed(kExtraFrontEndOptions)) {
results[kExtraFrontEndOptions] = argResults[kExtraFrontEndOptions] as String;
}
return results; return results;
} }
......
...@@ -41,6 +41,7 @@ class BuildAarCommand extends BuildSubCommand { ...@@ -41,6 +41,7 @@ class BuildAarCommand extends BuildSubCommand {
addSplitDebugInfoOption(); addSplitDebugInfoOption();
addDartObfuscationOption(); addDartObfuscationOption();
usesTrackWidgetCreation(verboseHelp: false); usesTrackWidgetCreation(verboseHelp: false);
addNullSafetyModeOptions();
argParser argParser
..addMultiOption( ..addMultiOption(
'target-platform', 'target-platform',
......
...@@ -33,6 +33,7 @@ class BuildApkCommand extends BuildSubCommand { ...@@ -33,6 +33,7 @@ class BuildApkCommand extends BuildSubCommand {
addBundleSkSLPathOption(hide: !verboseHelp); addBundleSkSLPathOption(hide: !verboseHelp);
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp); addBuildPerformanceFile(hide: !verboseHelp);
addNullSafetyModeOptions();
argParser argParser
..addFlag('split-per-abi', ..addFlag('split-per-abi',
negatable: false, negatable: false,
......
...@@ -21,6 +21,7 @@ class BuildFuchsiaCommand extends BuildSubCommand { ...@@ -21,6 +21,7 @@ class BuildFuchsiaCommand extends BuildSubCommand {
usesTargetOption(); usesTargetOption();
usesDartDefineOption(); usesDartDefineOption();
addBuildModeFlags(verboseHelp: verboseHelp); addBuildModeFlags(verboseHelp: verboseHelp);
addNullSafetyModeOptions();
argParser.addOption( argParser.addOption(
'runner-source', 'runner-source',
help: 'The package source to use for the flutter_runner. ' help: 'The package source to use for the flutter_runner. '
......
...@@ -33,6 +33,7 @@ class BuildIOSCommand extends BuildSubCommand { ...@@ -33,6 +33,7 @@ class BuildIOSCommand extends BuildSubCommand {
usesExtraFrontendOptions(); usesExtraFrontendOptions();
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp); addBuildPerformanceFile(hide: !verboseHelp);
addNullSafetyModeOptions();
argParser argParser
..addFlag('simulator', ..addFlag('simulator',
help: 'Build for the iOS simulator instead of the device. This changes ' help: 'Build for the iOS simulator instead of the device. This changes '
......
...@@ -28,6 +28,7 @@ class BuildLinuxCommand extends BuildSubCommand { ...@@ -28,6 +28,7 @@ class BuildLinuxCommand extends BuildSubCommand {
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
usesTrackWidgetCreation(verboseHelp: verboseHelp); usesTrackWidgetCreation(verboseHelp: verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp); addBuildPerformanceFile(hide: !verboseHelp);
addNullSafetyModeOptions();
} }
@override @override
......
...@@ -29,6 +29,7 @@ class BuildMacosCommand extends BuildSubCommand { ...@@ -29,6 +29,7 @@ class BuildMacosCommand extends BuildSubCommand {
usesBuildNameOption(); usesBuildNameOption();
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
addBuildPerformanceFile(hide: !verboseHelp); addBuildPerformanceFile(hide: !verboseHelp);
addNullSafetyModeOptions();
} }
@override @override
......
...@@ -11,7 +11,7 @@ import '../build_info.dart'; ...@@ -11,7 +11,7 @@ import '../build_info.dart';
import '../features.dart'; import '../features.dart';
import '../project.dart'; import '../project.dart';
import '../runner/flutter_command.dart' import '../runner/flutter_command.dart'
show DevelopmentArtifact, FlutterCommandResult, FlutterOptions; show DevelopmentArtifact, FlutterCommandResult;
import '../web/compile.dart'; import '../web/compile.dart';
import 'build.dart'; import 'build.dart';
...@@ -25,6 +25,7 @@ class BuildWebCommand extends BuildSubCommand { ...@@ -25,6 +25,7 @@ class BuildWebCommand extends BuildSubCommand {
addBuildModeFlags(excludeDebug: true); addBuildModeFlags(excludeDebug: true);
usesDartDefineOption(); usesDartDefineOption();
addEnableExperimentation(hide: !verboseHelp); addEnableExperimentation(hide: !verboseHelp);
addNullSafetyModeOptions();
argParser.addFlag('web-initialize-platform', argParser.addFlag('web-initialize-platform',
defaultsTo: true, defaultsTo: true,
negatable: true, negatable: true,
...@@ -71,7 +72,6 @@ class BuildWebCommand extends BuildSubCommand { ...@@ -71,7 +72,6 @@ class BuildWebCommand extends BuildSubCommand {
buildInfo, buildInfo,
boolArg('web-initialize-platform'), boolArg('web-initialize-platform'),
boolArg('csp'), boolArg('csp'),
stringsArg(FlutterOptions.kEnableExperiment),
); );
return FlutterCommandResult.success(); return FlutterCommandResult.success();
} }
......
...@@ -66,6 +66,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment ...@@ -66,6 +66,7 @@ abstract class RunCommandBase extends FlutterCommand with DeviceBasedDevelopment
usesPubOption(); usesPubOption();
usesTrackWidgetCreation(verboseHelp: verboseHelp); usesTrackWidgetCreation(verboseHelp: verboseHelp);
usesIsolateFilterOption(hide: !verboseHelp); usesIsolateFilterOption(hide: !verboseHelp);
addNullSafetyModeOptions();
} }
bool get traceStartup => boolArg('trace-startup'); bool get traceStartup => boolArg('trace-startup');
......
...@@ -31,6 +31,9 @@ class TestCommand extends FlutterCommand { ...@@ -31,6 +31,9 @@ class TestCommand extends FlutterCommand {
}) : assert(testWrapper != null) { }) : assert(testWrapper != null) {
requiresPubspecYaml(); requiresPubspecYaml();
usesPubOption(); usesPubOption();
addNullSafetyModeOptions();
usesTrackWidgetCreation(verboseHelp: verboseHelp);
addEnableExperimentation(hide: !verboseHelp);
argParser argParser
..addMultiOption('name', ..addMultiOption('name',
help: 'A regular expression matching substrings of the names of tests to run.', help: 'A regular expression matching substrings of the names of tests to run.',
...@@ -128,8 +131,6 @@ class TestCommand extends FlutterCommand { ...@@ -128,8 +131,6 @@ class TestCommand extends FlutterCommand {
'This flag is ignored if --start-paused or coverage are requested. ' 'This flag is ignored if --start-paused or coverage are requested. '
'The vmservice will be enabled no matter what in those cases.' 'The vmservice will be enabled no matter what in those cases.'
); );
usesTrackWidgetCreation(verboseHelp: verboseHelp);
addEnableExperimentation(hide: !verboseHelp);
} }
/// The interface for starting and configuring the tester. /// The interface for starting and configuring the tester.
...@@ -172,7 +173,6 @@ class TestCommand extends FlutterCommand { ...@@ -172,7 +173,6 @@ class TestCommand extends FlutterCommand {
final String tags = stringArg('tags'); final String tags = stringArg('tags');
final String excludeTags = stringArg('exclude-tags'); final String excludeTags = stringArg('exclude-tags');
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
final List<String> dartExperiments = stringsArg(FlutterOptions.kEnableExperiment);
if (buildTestAssets && flutterProject.manifest.assets.isNotEmpty) { if (buildTestAssets && flutterProject.manifest.assets.isNotEmpty) {
await _buildTestAsset(); await _buildTestAsset();
...@@ -278,7 +278,7 @@ class TestCommand extends FlutterCommand { ...@@ -278,7 +278,7 @@ class TestCommand extends FlutterCommand {
flutterProject: flutterProject, flutterProject: flutterProject,
web: stringArg('platform') == 'chrome', web: stringArg('platform') == 'chrome',
randomSeed: stringArg('test-randomize-ordering-seed'), randomSeed: stringArg('test-randomize-ordering-seed'),
dartExperiments: dartExperiments, extraFrontEndOptions: getBuildInfo(forcedBuildMode: BuildMode.debug).extraFrontEndOptions,
); );
if (collector != null) { if (collector != null) {
......
...@@ -269,7 +269,14 @@ class KernelCompiler { ...@@ -269,7 +269,14 @@ class KernelCompiler {
'--platform', '--platform',
platformDill, platformDill,
], ],
...?extraFrontEndOptions, if (extraFrontEndOptions != null)
for (String arg in extraFrontEndOptions)
if (arg == '--sound-null-safety')
'--null-safety'
else if (arg == '--no-sound-null-safety')
'--no-null-safety'
else
arg,
mainUri?.toString() ?? mainPath, mainUri?.toString() ?? mainPath,
]; ];
...@@ -398,7 +405,7 @@ abstract class ResidentCompiler { ...@@ -398,7 +405,7 @@ abstract class ResidentCompiler {
String initializeFromDill, String initializeFromDill,
TargetModel targetModel, TargetModel targetModel,
bool unsafePackageSerialization, bool unsafePackageSerialization,
List<String> experimentalFlags, List<String> extraFrontEndOptions,
String platformDill, String platformDill,
List<String> dartDefines, List<String> dartDefines,
String librariesSpec, String librariesSpec,
...@@ -494,7 +501,7 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -494,7 +501,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
this.initializeFromDill, this.initializeFromDill,
this.targetModel = TargetModel.flutter, this.targetModel = TargetModel.flutter,
this.unsafePackageSerialization, this.unsafePackageSerialization,
this.experimentalFlags, this.extraFrontEndOptions,
this.platformDill, this.platformDill,
List<String> dartDefines, List<String> dartDefines,
this.librariesSpec, this.librariesSpec,
...@@ -512,7 +519,7 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -512,7 +519,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
final String fileSystemScheme; final String fileSystemScheme;
final String initializeFromDill; final String initializeFromDill;
final bool unsafePackageSerialization; final bool unsafePackageSerialization;
final List<String> experimentalFlags; final List<String> extraFrontEndOptions;
final List<String> dartDefines; final List<String> dartDefines;
final String librariesSpec; final String librariesSpec;
...@@ -660,8 +667,14 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -660,8 +667,14 @@ class DefaultResidentCompiler implements ResidentCompiler {
platformDill, platformDill,
], ],
if (unsafePackageSerialization == true) '--unsafe-package-serialization', if (unsafePackageSerialization == true) '--unsafe-package-serialization',
if ((experimentalFlags != null) && experimentalFlags.isNotEmpty) if (extraFrontEndOptions != null)
'--enable-experiment=${experimentalFlags.join(',')}', for (String arg in extraFrontEndOptions)
if (arg == '--sound-null-safety')
'--null-safety'
else if (arg == '--no-sound-null-safety')
'--no-null-safety'
else
arg,
]; ];
globals.printTrace(command.join(' ')); globals.printTrace(command.join(' '));
_server = await globals.processManager.start(command); _server = await globals.processManager.start(command);
......
...@@ -47,7 +47,6 @@ class FlutterDevice { ...@@ -47,7 +47,6 @@ class FlutterDevice {
this.viewFilter, this.viewFilter,
TargetModel targetModel = TargetModel.flutter, TargetModel targetModel = TargetModel.flutter,
TargetPlatform targetPlatform, TargetPlatform targetPlatform,
List<String> experimentalFlags,
ResidentCompiler generator, ResidentCompiler generator,
}) : assert(buildInfo.trackWidgetCreation != null), }) : assert(buildInfo.trackWidgetCreation != null),
generator = generator ?? ResidentCompiler( generator = generator ?? ResidentCompiler(
...@@ -61,9 +60,9 @@ class FlutterDevice { ...@@ -61,9 +60,9 @@ class FlutterDevice {
fileSystemRoots: fileSystemRoots ?? <String>[], fileSystemRoots: fileSystemRoots ?? <String>[],
fileSystemScheme: fileSystemScheme, fileSystemScheme: fileSystemScheme,
targetModel: targetModel, targetModel: targetModel,
experimentalFlags: experimentalFlags,
dartDefines: buildInfo.dartDefines, dartDefines: buildInfo.dartDefines,
packagesPath: globalPackagesPath, packagesPath: globalPackagesPath,
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
); );
/// Create a [FlutterDevice] with optional code generation enabled. /// Create a [FlutterDevice] with optional code generation enabled.
...@@ -106,7 +105,7 @@ class FlutterDevice { ...@@ -106,7 +105,7 @@ class FlutterDevice {
trackWidgetCreation: buildInfo.trackWidgetCreation, trackWidgetCreation: buildInfo.trackWidgetCreation,
), ),
targetModel: TargetModel.dartdevc, targetModel: TargetModel.dartdevc,
experimentalFlags: experimentalFlags, extraFrontEndOptions: buildInfo.extraFrontEndOptions,
platformDill: globals.fs.file(globals.artifacts platformDill: globals.fs.file(globals.artifacts
.getArtifactPath(Artifact.webPlatformKernelDill, mode: buildInfo.mode)) .getArtifactPath(Artifact.webPlatformKernelDill, mode: buildInfo.mode))
.absolute.uri.toString(), .absolute.uri.toString(),
...@@ -127,8 +126,8 @@ class FlutterDevice { ...@@ -127,8 +126,8 @@ class FlutterDevice {
fileSystemRoots: fileSystemRoots, fileSystemRoots: fileSystemRoots,
fileSystemScheme: fileSystemScheme, fileSystemScheme: fileSystemScheme,
targetModel: targetModel, targetModel: targetModel,
experimentalFlags: experimentalFlags,
dartDefines: buildInfo.dartDefines, dartDefines: buildInfo.dartDefines,
extraFrontEndOptions: buildInfo.extraFrontEndOptions,
initializeFromDill: getDefaultCachedKernelPath( initializeFromDill: getDefaultCachedKernelPath(
trackWidgetCreation: buildInfo.trackWidgetCreation, trackWidgetCreation: buildInfo.trackWidgetCreation,
), ),
...@@ -148,7 +147,6 @@ class FlutterDevice { ...@@ -148,7 +147,6 @@ class FlutterDevice {
fileSystemRoots: fileSystemRoots, fileSystemRoots: fileSystemRoots,
fileSystemScheme:fileSystemScheme, fileSystemScheme:fileSystemScheme,
viewFilter: viewFilter, viewFilter: viewFilter,
experimentalFlags: experimentalFlags,
targetModel: targetModel, targetModel: targetModel,
targetPlatform: targetPlatform, targetPlatform: targetPlatform,
generator: generator, generator: generator,
......
...@@ -109,6 +109,7 @@ class FlutterOptions { ...@@ -109,6 +109,7 @@ class FlutterOptions {
static const String kDartDefinesOption = 'dart-define'; static const String kDartDefinesOption = 'dart-define';
static const String kBundleSkSLPathOption = 'bundle-sksl-path'; static const String kBundleSkSLPathOption = 'bundle-sksl-path';
static const String kPerformanceMeasurementFile = 'performance-measurement-file'; static const String kPerformanceMeasurementFile = 'performance-measurement-file';
static const String kNullSafety = 'sound-null-safety';
} }
abstract class FlutterCommand extends Command<void> { abstract class FlutterCommand extends Command<void> {
...@@ -460,6 +461,14 @@ abstract class FlutterCommand extends Command<void> { ...@@ -460,6 +461,14 @@ abstract class FlutterCommand extends Command<void> {
); );
} }
void addNullSafetyModeOptions() {
argParser.addFlag(FlutterOptions.kNullSafety,
help: 'Whether to override the default null safety setting.',
defaultsTo: null,
hide: true,
);
}
void usesExtraFrontendOptions() { void usesExtraFrontendOptions() {
argParser.addMultiOption(FlutterOptions.kExtraFrontEndOptions, argParser.addMultiOption(FlutterOptions.kExtraFrontEndOptions,
splitCommas: true, splitCommas: true,
...@@ -572,15 +581,15 @@ abstract class FlutterCommand extends Command<void> { ...@@ -572,15 +581,15 @@ abstract class FlutterCommand extends Command<void> {
final List<String> experiments = final List<String> experiments =
argParser.options.containsKey(FlutterOptions.kEnableExperiment) argParser.options.containsKey(FlutterOptions.kEnableExperiment)
? stringsArg(FlutterOptions.kEnableExperiment) ? stringsArg(FlutterOptions.kEnableExperiment).toList()
: <String>[]; : <String>[];
final List<String> extraGenSnapshotOptions = final List<String> extraGenSnapshotOptions =
argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions) argParser.options.containsKey(FlutterOptions.kExtraGenSnapshotOptions)
? stringsArg(FlutterOptions.kExtraGenSnapshotOptions) ? stringsArg(FlutterOptions.kExtraGenSnapshotOptions).toList()
: <String>[]; : <String>[];
final List<String> extraFrontEndOptions = final List<String> extraFrontEndOptions =
argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions) argParser.options.containsKey(FlutterOptions.kExtraFrontEndOptions)
? stringsArg(FlutterOptions.kExtraFrontEndOptions) ? stringsArg(FlutterOptions.kExtraFrontEndOptions).toList()
: <String>[]; : <String>[];
if (experiments.isNotEmpty) { if (experiments.isNotEmpty) {
...@@ -591,6 +600,18 @@ abstract class FlutterCommand extends Command<void> { ...@@ -591,6 +600,18 @@ abstract class FlutterCommand extends Command<void> {
} }
} }
if (argParser.options.containsKey(FlutterOptions.kNullSafety)) {
final bool nullSafety = boolArg(FlutterOptions.kNullSafety);
// Explicitly check for `true` and `false` so that `null` results in not
// passing a flag. This will use the automatically detected null-safety
// value based on the entrypoint
if (nullSafety == true) {
extraFrontEndOptions.add('--sound-null-safety');
} else if (nullSafety == false) {
extraFrontEndOptions.add('--no-sound-null-safety');
}
}
final bool dartObfuscation = argParser.options.containsKey(FlutterOptions.kDartObfuscationOption) final bool dartObfuscation = argParser.options.containsKey(FlutterOptions.kDartObfuscationOption)
&& boolArg(FlutterOptions.kDartObfuscationOption); && boolArg(FlutterOptions.kDartObfuscationOption);
......
...@@ -88,7 +88,7 @@ FlutterPlatform installHook({ ...@@ -88,7 +88,7 @@ FlutterPlatform installHook({
FlutterProject flutterProject, FlutterProject flutterProject,
String icudtlPath, String icudtlPath,
PlatformPluginRegistration platformPluginRegistration, PlatformPluginRegistration platformPluginRegistration,
@required List<String> dartExperiments, @required List<String> extraFrontEndOptions,
}) { }) {
assert(testWrapper != null); assert(testWrapper != null);
assert(enableObservatory || (!startPaused && observatoryPort == null)); assert(enableObservatory || (!startPaused && observatoryPort == null));
...@@ -121,7 +121,7 @@ FlutterPlatform installHook({ ...@@ -121,7 +121,7 @@ FlutterPlatform installHook({
projectRootDirectory: projectRootDirectory, projectRootDirectory: projectRootDirectory,
flutterProject: flutterProject, flutterProject: flutterProject,
icudtlPath: icudtlPath, icudtlPath: icudtlPath,
dartExperiments: dartExperiments, extraFrontEndOptions: extraFrontEndOptions,
); );
platformPluginRegistration(platform); platformPluginRegistration(platform);
return platform; return platform;
...@@ -269,7 +269,7 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -269,7 +269,7 @@ class FlutterPlatform extends PlatformPlugin {
this.projectRootDirectory, this.projectRootDirectory,
this.flutterProject, this.flutterProject,
this.icudtlPath, this.icudtlPath,
@required this.dartExperiments, @required this.extraFrontEndOptions,
}) : assert(shellPath != null); }) : assert(shellPath != null);
final String shellPath; final String shellPath;
...@@ -290,7 +290,7 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -290,7 +290,7 @@ class FlutterPlatform extends PlatformPlugin {
final Uri projectRootDirectory; final Uri projectRootDirectory;
final FlutterProject flutterProject; final FlutterProject flutterProject;
final String icudtlPath; final String icudtlPath;
final List<String> dartExperiments; final List<String> extraFrontEndOptions;
Directory fontsDirectory; Directory fontsDirectory;
...@@ -459,7 +459,7 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -459,7 +459,7 @@ class FlutterPlatform extends PlatformPlugin {
if (precompiledDillPath == null && precompiledDillFiles == null) { if (precompiledDillPath == null && precompiledDillFiles == null) {
// Lazily instantiate compiler so it is built only if it is actually used. // Lazily instantiate compiler so it is built only if it is actually used.
compiler ??= TestCompiler(buildMode, trackWidgetCreation, flutterProject, dartExperiments); compiler ??= TestCompiler(buildMode, trackWidgetCreation, flutterProject, extraFrontEndOptions);
mainDart = await compiler.compile(globals.fs.file(mainDart).uri); mainDart = await compiler.compile(globals.fs.file(mainDart).uri);
if (mainDart == null) { if (mainDart == null) {
...@@ -751,7 +751,7 @@ class FlutterPlatform extends PlatformPlugin { ...@@ -751,7 +751,7 @@ class FlutterPlatform extends PlatformPlugin {
testConfigFile: findTestConfigFile(globals.fs.file(testUrl)), testConfigFile: findTestConfigFile(globals.fs.file(testUrl)),
host: host, host: host,
updateGoldens: updateGoldens, updateGoldens: updateGoldens,
nullSafety: dartExperiments.contains('non-nullable'), nullSafety: extraFrontEndOptions?.contains('--enable-experiment=non-nullable') ?? false,
); );
} }
......
...@@ -51,7 +51,7 @@ abstract class FlutterTestRunner { ...@@ -51,7 +51,7 @@ abstract class FlutterTestRunner {
Directory coverageDirectory, Directory coverageDirectory,
bool web = false, bool web = false,
String randomSeed, String randomSeed,
@required List<String> dartExperiments, @required List<String> extraFrontEndOptions,
}); });
} }
...@@ -85,7 +85,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner { ...@@ -85,7 +85,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner {
Directory coverageDirectory, Directory coverageDirectory,
bool web = false, bool web = false,
String randomSeed, String randomSeed,
@required List<String> dartExperiments, @required List<String> extraFrontEndOptions,
}) async { }) async {
// Configure package:test to use the Flutter engine for child processes. // Configure package:test to use the Flutter engine for child processes.
final String shellPath = globals.artifacts.getArtifactPath(Artifact.flutterTester); final String shellPath = globals.artifacts.getArtifactPath(Artifact.flutterTester);
...@@ -177,7 +177,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner { ...@@ -177,7 +177,7 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner {
projectRootDirectory: globals.fs.currentDirectory.uri, projectRootDirectory: globals.fs.currentDirectory.uri,
flutterProject: flutterProject, flutterProject: flutterProject,
icudtlPath: icudtlPath, icudtlPath: icudtlPath,
dartExperiments: dartExperiments, extraFrontEndOptions: extraFrontEndOptions,
); );
// Make the global packages path absolute. // Make the global packages path absolute.
......
...@@ -42,7 +42,7 @@ class TestCompiler { ...@@ -42,7 +42,7 @@ class TestCompiler {
this.buildMode, this.buildMode,
this.trackWidgetCreation, this.trackWidgetCreation,
this.flutterProject, this.flutterProject,
this.dartExperiments, this.extraFrontEndOptions,
) : testFilePath = getKernelPathForTransformerOptions( ) : testFilePath = getKernelPathForTransformerOptions(
globals.fs.path.join(flutterProject.directory.path, getBuildDirectory(), 'testfile.dill'), globals.fs.path.join(flutterProject.directory.path, getBuildDirectory(), 'testfile.dill'),
trackWidgetCreation: trackWidgetCreation, trackWidgetCreation: trackWidgetCreation,
...@@ -66,7 +66,7 @@ class TestCompiler { ...@@ -66,7 +66,7 @@ class TestCompiler {
final BuildMode buildMode; final BuildMode buildMode;
final bool trackWidgetCreation; final bool trackWidgetCreation;
final String testFilePath; final String testFilePath;
final List<String> dartExperiments; final List<String> extraFrontEndOptions;
ResidentCompiler compiler; ResidentCompiler compiler;
...@@ -106,7 +106,7 @@ class TestCompiler { ...@@ -106,7 +106,7 @@ class TestCompiler {
unsafePackageSerialization: false, unsafePackageSerialization: false,
dartDefines: const <String>[], dartDefines: const <String>[],
packagesPath: globalPackagesPath, packagesPath: globalPackagesPath,
experimentalFlags: dartExperiments, extraFrontEndOptions: extraFrontEndOptions,
); );
if (flutterProject.hasBuilders) { if (flutterProject.hasBuilders) {
return CodeGeneratingResidentCompiler.create( return CodeGeneratingResidentCompiler.create(
......
...@@ -28,7 +28,6 @@ Future<void> buildWeb( ...@@ -28,7 +28,6 @@ Future<void> buildWeb(
BuildInfo buildInfo, BuildInfo buildInfo,
bool initializePlatform, bool initializePlatform,
bool csp, bool csp,
List<String> experiments,
) async { ) async {
if (!flutterProject.web.existsSync()) { if (!flutterProject.web.existsSync()) {
throwToolExit('Missing index.html.'); throwToolExit('Missing index.html.');
...@@ -53,8 +52,8 @@ Future<void> buildWeb( ...@@ -53,8 +52,8 @@ Future<void> buildWeb(
kDartDefines: encodeDartDefines(buildInfo.dartDefines), kDartDefines: encodeDartDefines(buildInfo.dartDefines),
kCspMode: csp.toString(), kCspMode: csp.toString(),
kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(), kIconTreeShakerFlag: buildInfo.treeShakeIcons.toString(),
if (experiments.isNotEmpty) if (buildInfo.extraFrontEndOptions?.isNotEmpty ?? false)
kEnableExperiment: experiments?.join(','), kExtraFrontEndOptions: buildInfo.extraFrontEndOptions.join(',')
}, },
artifacts: globals.artifacts, artifacts: globals.artifacts,
fileSystem: globals.fs, fileSystem: globals.fs,
......
...@@ -356,8 +356,8 @@ void main() { ...@@ -356,8 +356,8 @@ void main() {
'set(PROJECT_DIR "${fileSystem.currentDirectory.path}")', 'set(PROJECT_DIR "${fileSystem.currentDirectory.path}")',
' "DART_DEFINES=\\"foo.bar%3D2,fizz.far%3D3\\""', ' "DART_DEFINES=\\"foo.bar%3D2,fizz.far%3D3\\""',
' "DART_OBFUSCATION=\\"true\\""', ' "DART_OBFUSCATION=\\"true\\""',
' "EXTRA_FRONT_END_OPTIONS=\\"--enable-experiment=non-nullable\\""', ' "EXTRA_FRONT_END_OPTIONS=\\"--enable-experiment%3Dnon-nullable\\""',
' "EXTRA_GEN_SNAPSHOT_OPTIONS=\\"--enable-experiment=non-nullable\\""', ' "EXTRA_GEN_SNAPSHOT_OPTIONS=\\"--enable-experiment%3Dnon-nullable\\""',
' "SPLIT_DEBUG_INFO=\\"foo/\\""', ' "SPLIT_DEBUG_INFO=\\"foo/\\""',
' "TRACK_WIDGET_CREATION=\\"true\\""', ' "TRACK_WIDGET_CREATION=\\"true\\""',
' "TREE_SHAKE_ICONS=\\"true\\""', ' "TREE_SHAKE_ICONS=\\"true\\""',
......
...@@ -56,7 +56,6 @@ void main() { ...@@ -56,7 +56,6 @@ void main() {
BuildInfo.debug, BuildInfo.debug,
false, false,
false, false,
<String>[],
), throwsToolExit()); ), throwsToolExit());
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
Platform: () => fakePlatform, Platform: () => fakePlatform,
......
...@@ -291,8 +291,8 @@ void main() { ...@@ -291,8 +291,8 @@ void main() {
expect(props.findAllElements('FLUTTER_ROOT').first.text, flutterRoot); expect(props.findAllElements('FLUTTER_ROOT').first.text, flutterRoot);
expect(props.findAllElements('TRACK_WIDGET_CREATION').first.text, 'true'); expect(props.findAllElements('TRACK_WIDGET_CREATION').first.text, 'true');
expect(props.findAllElements('TREE_SHAKE_ICONS').first.text, 'true'); expect(props.findAllElements('TREE_SHAKE_ICONS').first.text, 'true');
expect(props.findAllElements('EXTRA_GEN_SNAPSHOT_OPTIONS').first.text, '--enable-experiment=non-nullable'); expect(props.findAllElements('EXTRA_GEN_SNAPSHOT_OPTIONS').first.text, '--enable-experiment%3Dnon-nullable');
expect(props.findAllElements('EXTRA_FRONT_END_OPTIONS').first.text, '--enable-experiment=non-nullable'); expect(props.findAllElements('EXTRA_FRONT_END_OPTIONS').first.text, '--enable-experiment%3Dnon-nullable');
expect(props.findAllElements('DART_DEFINES').first.text, 'foo%3Da,bar%3Db'); expect(props.findAllElements('DART_DEFINES').first.text, 'foo%3Da,bar%3Db');
expect(props.findAllElements('DART_OBFUSCATION').first.text, 'true'); expect(props.findAllElements('DART_OBFUSCATION').first.text, 'true');
expect(props.findAllElements('SPLIT_DEBUG_INFO').first.text, r'C:\foo\'); expect(props.findAllElements('SPLIT_DEBUG_INFO').first.text, r'C:\foo\');
......
...@@ -184,7 +184,7 @@ class FakeFlutterTestRunner implements FlutterTestRunner { ...@@ -184,7 +184,7 @@ class FakeFlutterTestRunner implements FlutterTestRunner {
Directory coverageDirectory, Directory coverageDirectory,
bool web = false, bool web = false,
String randomSeed, String randomSeed,
@override List<String> dartExperiments, @override List<String> extraFrontEndOptions,
}) async { }) async {
lastEnableObservatoryValue = enableObservatory; lastEnableObservatoryValue = enableObservatory;
return exitCode; return exitCode;
......
...@@ -113,8 +113,8 @@ void main() { ...@@ -113,8 +113,8 @@ void main() {
'DART_DEFINES': 'foo%3D2,bar%3D2', 'DART_DEFINES': 'foo%3D2,bar%3D2',
'DART_OBFUSCATION': 'true', 'DART_OBFUSCATION': 'true',
'SPLIT_DEBUG_INFO': 'foo/', 'SPLIT_DEBUG_INFO': 'foo/',
'EXTRA_FRONT_END_OPTIONS': '--enable-experiment=non-nullable,bar', 'EXTRA_FRONT_END_OPTIONS': '--enable-experiment%3Dnon-nullable,bar',
'EXTRA_GEN_SNAPSHOT_OPTIONS': '--enable-experiment=non-nullable,fizz', 'EXTRA_GEN_SNAPSHOT_OPTIONS': '--enable-experiment%3Dnon-nullable,fizz',
}); });
}); });
...@@ -129,18 +129,18 @@ void main() { ...@@ -129,18 +129,18 @@ void main() {
testWithoutContext('decodeDartDefines decodes URI encoded dart defines', () { testWithoutContext('decodeDartDefines decodes URI encoded dart defines', () {
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: '%22hello%22' kDartDefines: '%22hello%22'
}), <String>['"hello"']); }, kDartDefines), <String>['"hello"']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: 'https%3A%2F%2Fwww.google.com' kDartDefines: 'https%3A%2F%2Fwww.google.com'
}), <String>['https://www.google.com']); }, kDartDefines), <String>['https://www.google.com']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: '2%2C3%2C4,5' kDartDefines: '2%2C3%2C4,5'
}), <String>['2,3,4', '5']); }, kDartDefines), <String>['2,3,4', '5']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: 'true,false,flase' kDartDefines: 'true,false,flase'
}), <String>['true', 'false', 'flase']); }, kDartDefines), <String>['true', 'false', 'flase']);
expect(decodeDartDefines(<String, String>{ expect(decodeDartDefines(<String, String>{
kDartDefines: '1232%2C456,2' kDartDefines: '1232%2C456,2'
}), <String>['1232,456', '2']); }, kDartDefines), <String>['1232,456', '2']);
}); });
} }
...@@ -255,7 +255,7 @@ void main() { ...@@ -255,7 +255,7 @@ void main() {
test('Dart2JSTarget calls dart2js with expected args with enabled experiment', () => testbed.run(() async { test('Dart2JSTarget calls dart2js with expected args with enabled experiment', () => testbed.run(() async {
environment.defines[kBuildMode] = 'profile'; environment.defines[kBuildMode] = 'profile';
environment.defines[kEnableExperiment] = 'non-nullable'; environment.defines[kExtraFrontEndOptions] = '--enable-experiment=non-nullable';
processManager.addCommand(FakeCommand( processManager.addCommand(FakeCommand(
command: <String>[ command: <String>[
...kDart2jsLinuxArgs, ...kDart2jsLinuxArgs,
......
...@@ -22,7 +22,7 @@ void main() { ...@@ -22,7 +22,7 @@ void main() {
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
shellPath: '/', shellPath: '/',
explicitObservatoryPort: 1234, explicitObservatoryPort: 1234,
dartExperiments: <String>[], extraFrontEndOptions: <String>[],
); );
flutterPlatform.loadChannel('test1.dart', MockSuitePlatform()); flutterPlatform.loadChannel('test1.dart', MockSuitePlatform());
...@@ -35,7 +35,7 @@ void main() { ...@@ -35,7 +35,7 @@ void main() {
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
shellPath: '/', shellPath: '/',
precompiledDillPath: 'example.dill', precompiledDillPath: 'example.dill',
dartExperiments: <String>[], extraFrontEndOptions: <String>[],
); );
flutterPlatform.loadChannel('test1.dart', MockSuitePlatform()); flutterPlatform.loadChannel('test1.dart', MockSuitePlatform());
...@@ -113,7 +113,7 @@ void main() { ...@@ -113,7 +113,7 @@ void main() {
shellPath: 'abc', shellPath: 'abc',
enableObservatory: false, enableObservatory: false,
startPaused: true, startPaused: true,
dartExperiments: <String>[], extraFrontEndOptions: <String>[],
), throwsAssertionError); ), throwsAssertionError);
expect(() => installHook( expect(() => installHook(
...@@ -122,7 +122,7 @@ void main() { ...@@ -122,7 +122,7 @@ void main() {
enableObservatory: false, enableObservatory: false,
startPaused: false, startPaused: false,
observatoryPort: 123, observatoryPort: 123,
dartExperiments: <String>[], extraFrontEndOptions: <String>[],
), throwsAssertionError); ), throwsAssertionError);
FlutterPlatform capturedPlatform; FlutterPlatform capturedPlatform;
...@@ -143,7 +143,7 @@ void main() { ...@@ -143,7 +143,7 @@ void main() {
observatoryPort: 200, observatoryPort: 200,
serverType: InternetAddressType.IPv6, serverType: InternetAddressType.IPv6,
icudtlPath: 'ghi', icudtlPath: 'ghi',
dartExperiments: <String>[], extraFrontEndOptions: <String>[],
platformPluginRegistration: (FlutterPlatform platform) { platformPluginRegistration: (FlutterPlatform platform) {
capturedPlatform = platform; capturedPlatform = platform;
}); });
...@@ -192,7 +192,7 @@ class TestFlutterPlatform extends FlutterPlatform { ...@@ -192,7 +192,7 @@ class TestFlutterPlatform extends FlutterPlatform {
startPaused: false, startPaused: false,
enableObservatory: false, enableObservatory: false,
buildTestAssets: false, buildTestAssets: false,
dartExperiments: <String>[], extraFrontEndOptions: <String>[],
); );
@override @override
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment