Finish removing null-safety mode, checks, and reporting. (#163153)

Closes https://github.com/flutter/flutter/issues/162846.

At HEAD, including before this PR, it was impossible to use, or pass-in,
an unsound null-safety mode, but we still had code checking for it, and
reported analytics (I think? Some of these are `package:usage` specific
which is defunct).

This PR eradicates the otherwise unused code.
This commit is contained in:
Matan Lurey 2025-02-12 13:52:02 -08:00 committed by GitHub
parent d2a60f6c22
commit 063f80d40f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 14 additions and 380 deletions

View File

@ -39,7 +39,6 @@ class BuildInfo {
required this.treeShakeIcons, required this.treeShakeIcons,
this.performanceMeasurementFile, this.performanceMeasurementFile,
required this.packageConfigPath, required this.packageConfigPath,
this.nullSafetyMode = NullSafetyMode.sound,
this.codeSizeDirectory, this.codeSizeDirectory,
this.androidGradleDaemon = true, this.androidGradleDaemon = true,
this.androidSkipBuildDependencyValidation = false, this.androidSkipBuildDependencyValidation = false,
@ -56,11 +55,6 @@ class BuildInfo {
final BuildMode mode; final BuildMode mode;
/// The null safety mode the application should be run in.
///
/// If not provided, defaults to [NullSafetyMode.autodetect].
final NullSafetyMode nullSafetyMode;
/// Whether the build should subset icon fonts. /// Whether the build should subset icon fonts.
final bool treeShakeIcons; final bool treeShakeIcons;
@ -1023,15 +1017,6 @@ List<String> decodeDartDefines(Map<String, String> environmentDefines, String ke
.toList(); .toList();
} }
/// The null safety runtime mode the app should be built in.
enum NullSafetyMode {
sound,
unsound,
/// The null safety mode was not detected. Only supported for 'flutter test'.
autodetect,
}
/// Indicates the module system DDC is targeting. /// Indicates the module system DDC is targeting.
enum DdcModuleFormat { amd, ddc } enum DdcModuleFormat { amd, ddc }

View File

@ -8,7 +8,6 @@ import '../android/android_sdk.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/logger.dart'; import '../base/logger.dart';
import '../base/os.dart'; import '../base/os.dart';
import '../build_info.dart';
import '../build_system/build_system.dart'; import '../build_system/build_system.dart';
import '../commands/build_linux.dart'; import '../commands/build_linux.dart';
import '../commands/build_macos.dart'; import '../commands/build_macos.dart';
@ -95,24 +94,6 @@ abstract class BuildSubCommand extends FlutterCommand {
@protected @protected
final Logger logger; final Logger logger;
@override /// Whether this command is supported and should be shown.
bool get reportNullSafety => true;
bool get supported => true; bool get supported => true;
/// Display a message describing the current null safety runtime mode
/// that was selected.
///
/// This is similar to the run message in run_hot.dart
@protected
void displayNullSafetyMode(BuildInfo buildInfo) {
if (buildInfo.nullSafetyMode != NullSafetyMode.sound) {
logger.printStatus('');
logger.printStatus('Building without sound null safety ⚠️', emphasis: true);
logger.printStatus(
'Dart 3 will only support sound null safety, see https://dart.dev/null-safety',
);
}
logger.printStatus('');
}
} }

View File

@ -151,8 +151,6 @@ class BuildAarCommand extends BuildSubCommand {
throwToolExit('Please specify a build mode and try again.'); throwToolExit('Please specify a build mode and try again.');
} }
displayNullSafetyMode(androidBuildInfo.first.buildInfo);
await androidBuilder?.buildAar( await androidBuilder?.buildAar(
project: project, project: project,
target: targetFile.path, target: targetFile.path,

View File

@ -137,7 +137,6 @@ class BuildApkCommand extends BuildSubCommand {
targetArchs: _targetArchs.map<AndroidArch>(getAndroidArchForName), targetArchs: _targetArchs.map<AndroidArch>(getAndroidArchForName),
); );
validateBuild(androidBuildInfo); validateBuild(androidBuildInfo);
displayNullSafetyMode(androidBuildInfo.buildInfo);
globals.terminal.usesTerminalUi = true; globals.terminal.usesTerminalUi = true;
final FlutterProject project = FlutterProject.current(); final FlutterProject project = FlutterProject.current();
await androidBuilder?.buildApk( await androidBuilder?.buildApk(

View File

@ -165,7 +165,6 @@ class BuildAppBundleCommand extends BuildSubCommand {
} }
validateBuild(androidBuildInfo); validateBuild(androidBuildInfo);
displayNullSafetyMode(androidBuildInfo.buildInfo);
globals.terminal.usesTerminalUi = true; globals.terminal.usesTerminalUi = true;
await androidBuilder?.buildAab( await androidBuilder?.buildAab(
project: project, project: project,

View File

@ -140,7 +140,6 @@ class BuildBundleCommand extends BuildSubCommand {
} }
final BuildInfo buildInfo = await getBuildInfo(); final BuildInfo buildInfo = await getBuildInfo();
displayNullSafetyMode(buildInfo);
await _bundleBuilder.build( await _bundleBuilder.build(
platform: platform, platform: platform,

View File

@ -468,7 +468,6 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand {
@override @override
Future<FlutterCommandResult> runCommand() async { Future<FlutterCommandResult> runCommand() async {
final BuildInfo buildInfo = await cachedBuildInfo; final BuildInfo buildInfo = await cachedBuildInfo;
displayNullSafetyMode(buildInfo);
final FlutterCommandResult xcarchiveResult = await super.runCommand(); final FlutterCommandResult xcarchiveResult = await super.runCommand();
final List<ValidationResult?> validationResults = <ValidationResult?>[]; final List<ValidationResult?> validationResults = <ValidationResult?>[];

View File

@ -259,7 +259,6 @@ class BuildIOSFrameworkCommand extends BuildFrameworkCommand {
globals.fs.path.absolute(globals.fs.path.normalize(outputArgument)), globals.fs.path.absolute(globals.fs.path.normalize(outputArgument)),
); );
final List<BuildInfo> buildInfos = await getBuildInfos(); final List<BuildInfo> buildInfos = await getBuildInfos();
displayNullSafetyMode(buildInfos.first);
for (final BuildInfo buildInfo in buildInfos) { for (final BuildInfo buildInfo in buildInfos) {
// Create the build-mode specific metadata. // Create the build-mode specific metadata.
// //

View File

@ -86,7 +86,6 @@ class BuildLinuxCommand extends BuildSubCommand {
'Cross-build from Linux x64 host to Linux arm64 target is not currently supported.', 'Cross-build from Linux x64 host to Linux arm64 target is not currently supported.',
); );
} }
displayNullSafetyMode(buildInfo);
final Logger logger = globals.logger; final Logger logger = globals.logger;
await buildLinux( await buildLinux(
project.linux, project.linux,

View File

@ -57,7 +57,6 @@ class BuildMacosCommand extends BuildSubCommand {
if (!supported) { if (!supported) {
throwToolExit('"build macos" only supported on macOS hosts.'); throwToolExit('"build macos" only supported on macOS hosts.');
} }
displayNullSafetyMode(buildInfo);
await buildMacOS( await buildMacOS(
flutterProject: project, flutterProject: project,
buildInfo: buildInfo, buildInfo: buildInfo,

View File

@ -72,8 +72,6 @@ class BuildMacOSFrameworkCommand extends BuildFrameworkCommand {
); );
final List<BuildInfo> buildInfos = await getBuildInfos(); final List<BuildInfo> buildInfos = await getBuildInfos();
displayNullSafetyMode(buildInfos.first);
for (final BuildInfo buildInfo in buildInfos) { for (final BuildInfo buildInfo in buildInfos) {
globals.printStatus('Building macOS frameworks in ${buildInfo.mode.cliName} mode...'); globals.printStatus('Building macOS frameworks in ${buildInfo.mode.cliName} mode...');
// Create the build-mode specific metadata. // Create the build-mode specific metadata.

View File

@ -240,7 +240,6 @@ class BuildWebCommand extends BuildSubCommand {
// valid approaches for setting output directory of build artifacts // valid approaches for setting output directory of build artifacts
final String? outputDirectoryPath = stringArg('output'); final String? outputDirectoryPath = stringArg('output');
displayNullSafetyMode(buildInfo);
final WebBuilder webBuilder = WebBuilder( final WebBuilder webBuilder = WebBuilder(
logger: globals.logger, logger: globals.logger,
processManager: globals.processManager, processManager: globals.processManager,

View File

@ -64,7 +64,6 @@ class BuildWindowsCommand extends BuildSubCommand {
: 'windows-x64'; : 'windows-x64';
final TargetPlatform targetPlatform = getTargetPlatformForName(defaultTargetPlatform); final TargetPlatform targetPlatform = getTargetPlatformForName(defaultTargetPlatform);
displayNullSafetyMode(buildInfo);
await buildWindows( await buildWindows(
project.windows, project.windows,
buildInfo, buildInfo,

View File

@ -778,13 +778,6 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
..writeAsStringSync(websocketUri.toString()); ..writeAsStringSync(websocketUri.toString());
} }
_logger.printStatus('Debug service listening on $websocketUri'); _logger.printStatus('Debug service listening on $websocketUri');
if (debuggingOptions.buildInfo.nullSafetyMode != NullSafetyMode.sound) {
_logger.printStatus('');
_logger.printStatus('Running without sound null safety ⚠️', emphasis: true);
_logger.printStatus(
'Dart 3 will only support sound null safety, see https://dart.dev/null-safety',
);
}
} }
appStartedCompleter?.complete(); appStartedCompleter?.complete();
connectionInfoCompleter?.complete(DebugConnectionInfo(wsUri: websocketUri)); connectionInfoCompleter?.complete(DebugConnectionInfo(wsUri: websocketUri));

View File

@ -57,9 +57,6 @@ class CustomDimensions {
this.commandResultEventMaxRss, this.commandResultEventMaxRss,
this.commandRunAndroidEmbeddingVersion, this.commandRunAndroidEmbeddingVersion,
this.commandPackagesAndroidEmbeddingVersion, this.commandPackagesAndroidEmbeddingVersion,
this.nullSafety,
this.nullSafeMigratedLibraries,
this.nullSafeTotalLibraries,
this.hotEventCompileTimeInMs, this.hotEventCompileTimeInMs,
this.hotEventFindInvalidatedTimeInMs, this.hotEventFindInvalidatedTimeInMs,
this.hotEventScannedSourcesCount, this.hotEventScannedSourcesCount,
@ -116,10 +113,7 @@ class CustomDimensions {
final int? commandResultEventMaxRss; // cd44 final int? commandResultEventMaxRss; // cd44
final String? commandRunAndroidEmbeddingVersion; // cd45 final String? commandRunAndroidEmbeddingVersion; // cd45
final String? commandPackagesAndroidEmbeddingVersion; // cd46 final String? commandPackagesAndroidEmbeddingVersion; // cd46
final bool? nullSafety; // cd47
// cd48 was fastReassemble but that feature was removed // cd48 was fastReassemble but that feature was removed
final int? nullSafeMigratedLibraries; // cd49
final int? nullSafeTotalLibraries; // cd50
final int? hotEventCompileTimeInMs; // cd51 final int? hotEventCompileTimeInMs; // cd51
final int? hotEventFindInvalidatedTimeInMs; // cd52 final int? hotEventFindInvalidatedTimeInMs; // cd52
final int? hotEventScannedSourcesCount; // cd53 final int? hotEventScannedSourcesCount; // cd53
@ -234,11 +228,6 @@ class CustomDimensions {
if (commandPackagesAndroidEmbeddingVersion != null) if (commandPackagesAndroidEmbeddingVersion != null)
CustomDimensionsEnum.commandPackagesAndroidEmbeddingVersion.cdKey: CustomDimensionsEnum.commandPackagesAndroidEmbeddingVersion.cdKey:
commandPackagesAndroidEmbeddingVersion.toString(), commandPackagesAndroidEmbeddingVersion.toString(),
if (nullSafety != null) CustomDimensionsEnum.nullSafety.cdKey: nullSafety.toString(),
if (nullSafeMigratedLibraries != null)
CustomDimensionsEnum.nullSafeMigratedLibraries.cdKey: nullSafeMigratedLibraries.toString(),
if (nullSafeTotalLibraries != null)
CustomDimensionsEnum.nullSafeTotalLibraries.cdKey: nullSafeTotalLibraries.toString(),
if (hotEventCompileTimeInMs != null) if (hotEventCompileTimeInMs != null)
CustomDimensionsEnum.hotEventCompileTimeInMs.cdKey: hotEventCompileTimeInMs.toString(), CustomDimensionsEnum.hotEventCompileTimeInMs.cdKey: hotEventCompileTimeInMs.toString(),
if (hotEventFindInvalidatedTimeInMs != null) if (hotEventFindInvalidatedTimeInMs != null)
@ -326,9 +315,6 @@ class CustomDimensions {
other.commandRunAndroidEmbeddingVersion ?? commandRunAndroidEmbeddingVersion, other.commandRunAndroidEmbeddingVersion ?? commandRunAndroidEmbeddingVersion,
commandPackagesAndroidEmbeddingVersion: commandPackagesAndroidEmbeddingVersion:
other.commandPackagesAndroidEmbeddingVersion ?? commandPackagesAndroidEmbeddingVersion, other.commandPackagesAndroidEmbeddingVersion ?? commandPackagesAndroidEmbeddingVersion,
nullSafety: other.nullSafety ?? nullSafety,
nullSafeMigratedLibraries: other.nullSafeMigratedLibraries ?? nullSafeMigratedLibraries,
nullSafeTotalLibraries: other.nullSafeTotalLibraries ?? nullSafeTotalLibraries,
hotEventCompileTimeInMs: other.hotEventCompileTimeInMs ?? hotEventCompileTimeInMs, hotEventCompileTimeInMs: other.hotEventCompileTimeInMs ?? hotEventCompileTimeInMs,
hotEventFindInvalidatedTimeInMs: hotEventFindInvalidatedTimeInMs:
other.hotEventFindInvalidatedTimeInMs ?? hotEventFindInvalidatedTimeInMs, other.hotEventFindInvalidatedTimeInMs ?? hotEventFindInvalidatedTimeInMs,
@ -430,9 +416,6 @@ class CustomDimensions {
map, map,
CustomDimensionsEnum.commandPackagesAndroidEmbeddingVersion, CustomDimensionsEnum.commandPackagesAndroidEmbeddingVersion,
), ),
nullSafety: _extractBool(map, CustomDimensionsEnum.nullSafety),
nullSafeMigratedLibraries: _extractInt(map, CustomDimensionsEnum.nullSafeMigratedLibraries),
nullSafeTotalLibraries: _extractInt(map, CustomDimensionsEnum.nullSafeTotalLibraries),
hotEventCompileTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventCompileTimeInMs), hotEventCompileTimeInMs: _extractInt(map, CustomDimensionsEnum.hotEventCompileTimeInMs),
hotEventFindInvalidatedTimeInMs: _extractInt( hotEventFindInvalidatedTimeInMs: _extractInt(
map, map,
@ -522,10 +505,13 @@ enum CustomDimensionsEnum {
commandResultEventMaxRss, // cd44 commandResultEventMaxRss, // cd44
commandRunAndroidEmbeddingVersion, // cd45 commandRunAndroidEmbeddingVersion, // cd45
commandPackagesAndroidEmbeddingVersion, // cd46 commandPackagesAndroidEmbeddingVersion, // cd46
nullSafety, // cd47 // ignore: unused_field
_nullSafetyDeprecatedDoNotUse, // cd47
obsolete1, // cd48 (was fastReassemble) obsolete1, // cd48 (was fastReassemble)
nullSafeMigratedLibraries, // cd49 // ignore: unused_field
nullSafeTotalLibraries, // cd50 _nullSafeMigratedLibrariesDoNotUse, // cd49
// ignore: unused_field
_nullSafeTotalLibrariesDoNotUse, // cd50
hotEventCompileTimeInMs, // cd51 hotEventCompileTimeInMs, // cd51
hotEventFindInvalidatedTimeInMs, // cd52 hotEventFindInvalidatedTimeInMs, // cd52
hotEventScannedSourcesCount, // cd53 hotEventScannedSourcesCount, // cd53

View File

@ -220,71 +220,3 @@ class ErrorHandlingEvent extends UsageEvent {
ErrorHandlingEvent(String parameter) ErrorHandlingEvent(String parameter)
: super('error-handling', parameter, flutterUsage: globals.flutterUsage); : super('error-handling', parameter, flutterUsage: globals.flutterUsage);
} }
/// Emit various null safety analytic events.
///
/// 1. The current null safety runtime mode.
/// 2. The number of packages that are migrated, along with the total number of packages
/// 3. The main packages language version.
class NullSafetyAnalysisEvent implements UsageEvent {
NullSafetyAnalysisEvent(
this.packageConfig,
this.nullSafetyMode,
this.currentPackage,
this.flutterUsage,
);
/// The category for analytics events related to null safety.
static const String kNullSafetyCategory = 'null-safety';
final PackageConfig packageConfig;
final NullSafetyMode nullSafetyMode;
final String currentPackage;
@override
final Usage flutterUsage;
@override
void send() {
if (packageConfig.packages.isEmpty) {
return;
}
int migrated = 0;
LanguageVersion? languageVersion;
for (final Package package in packageConfig.packages) {
final LanguageVersion? packageLanguageVersion = package.languageVersion;
if (package.name == currentPackage) {
languageVersion = packageLanguageVersion;
}
if (packageLanguageVersion != null &&
packageLanguageVersion.major >= nullSafeVersion.major &&
packageLanguageVersion.minor >= nullSafeVersion.minor) {
migrated += 1;
}
}
flutterUsage.sendEvent(kNullSafetyCategory, 'runtime-mode', label: nullSafetyMode.toString());
flutterUsage.sendEvent(
kNullSafetyCategory,
'stats',
parameters: CustomDimensions(
nullSafeMigratedLibraries: migrated,
nullSafeTotalLibraries: packageConfig.packages.length,
),
);
if (languageVersion != null) {
final String formattedVersion = '${languageVersion.major}.${languageVersion.minor}';
flutterUsage.sendEvent(kNullSafetyCategory, 'language-version', label: formattedVersion);
}
}
@override
String get category => kNullSafetyCategory;
@override
String get label => throw UnsupportedError('');
@override
String get parameter => throw UnsupportedError('');
@override
int get value => throw UnsupportedError('');
}

View File

@ -8,14 +8,11 @@ import 'dart:async';
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:package_config/package_config.dart';
import 'package:usage/usage_io.dart'; import 'package:usage/usage_io.dart';
import '../base/error_handling_io.dart'; import '../base/error_handling_io.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/time.dart'; import '../base/time.dart';
import '../build_info.dart';
import '../dart/language_version.dart';
import '../doctor_validator.dart'; import '../doctor_validator.dart';
import '../features.dart'; import '../features.dart';
import '../globals.dart' as globals; import '../globals.dart' as globals;

View File

@ -120,20 +120,7 @@ class FlutterDevice {
// used to file a bug, but the compiler will still start up correctly. // used to file a bug, but the compiler will still start up correctly.
if (targetPlatform == TargetPlatform.web_javascript) { if (targetPlatform == TargetPlatform.web_javascript) {
// TODO(zanderso): consistently provide these flags across platforms. // TODO(zanderso): consistently provide these flags across platforms.
final String platformDillName; const String platformDillName = 'ddc_outline.dill';
final List<String> extraFrontEndOptions = List<String>.of(buildInfo.extraFrontEndOptions);
switch (buildInfo.nullSafetyMode) {
case NullSafetyMode.unsound:
// TODO(matanlurey): Should be unreachable, remove as part of https://github.com/flutter/flutter/issues/162846.
throw UnsupportedError('Unsound null safety mode is not supported');
case NullSafetyMode.sound:
platformDillName = 'ddc_outline.dill';
case NullSafetyMode.autodetect:
throw StateError(
'Expected buildInfo.nullSafetyMode to be one of unsound or sound, '
'got NullSafetyMode.autodetect',
);
}
final String platformDillPath = globals.fs.path.join( final String platformDillPath = globals.fs.path.join(
globals.artifacts!.getHostArtifact(HostArtifact.webPlatformKernelFolder).path, globals.artifacts!.getHostArtifact(HostArtifact.webPlatformKernelFolder).path,
@ -153,12 +140,12 @@ class FlutterDevice {
getDefaultCachedKernelPath( getDefaultCachedKernelPath(
trackWidgetCreation: buildInfo.trackWidgetCreation, trackWidgetCreation: buildInfo.trackWidgetCreation,
dartDefines: buildInfo.dartDefines, dartDefines: buildInfo.dartDefines,
extraFrontEndOptions: extraFrontEndOptions, extraFrontEndOptions: buildInfo.extraFrontEndOptions,
), ),
assumeInitializeFromDillUpToDate: buildInfo.assumeInitializeFromDillUpToDate, assumeInitializeFromDillUpToDate: buildInfo.assumeInitializeFromDillUpToDate,
targetModel: TargetModel.dartdevc, targetModel: TargetModel.dartdevc,
frontendServerStarterPath: buildInfo.frontendServerStarterPath, frontendServerStarterPath: buildInfo.frontendServerStarterPath,
extraFrontEndOptions: extraFrontEndOptions, extraFrontEndOptions: buildInfo.extraFrontEndOptions,
platformDill: globals.fs.file(platformDillPath).absolute.uri.toString(), platformDill: globals.fs.file(platformDillPath).absolute.uri.toString(),
dartDefines: buildInfo.dartDefines, dartDefines: buildInfo.dartDefines,
librariesSpec: librariesSpec:

View File

@ -1174,13 +1174,6 @@ class HotRunner extends ResidentRunner {
} }
commandHelp.c.print(); commandHelp.c.print();
commandHelp.q.print(); commandHelp.q.print();
if (debuggingOptions.buildInfo.nullSafetyMode != NullSafetyMode.sound) {
globals.printStatus('');
globals.printStatus('Running without sound null safety ⚠️', emphasis: true);
globals.printStatus(
'Dart 3 will only support sound null safety, see https://dart.dev/null-safety',
);
}
globals.printStatus(''); globals.printStatus('');
printDebuggerList(); printDebuggerList();
} }

View File

@ -1355,23 +1355,6 @@ abstract class FlutterCommand extends Command<void> {
codeSizeDirectory = directory.path; codeSizeDirectory = directory.path;
} }
NullSafetyMode nullSafetyMode = NullSafetyMode.sound;
if (argParser.options.containsKey(FlutterOptions.kNullSafety)) {
final bool wasNullSafetyFlagParsed =
argResults?.wasParsed(FlutterOptions.kNullSafety) ?? false;
// Extra frontend options are only provided if explicitly
// requested.
if (wasNullSafetyFlagParsed) {
if (boolArg(FlutterOptions.kNullSafety)) {
nullSafetyMode = NullSafetyMode.sound;
extraFrontEndOptions.add('--sound-null-safety');
} else {
nullSafetyMode = NullSafetyMode.unsound;
extraFrontEndOptions.add('--no-sound-null-safety');
}
}
}
final bool dartObfuscation = final bool dartObfuscation =
argParser.options.containsKey(FlutterOptions.kDartObfuscationOption) && argParser.options.containsKey(FlutterOptions.kDartObfuscationOption) &&
boolArg(FlutterOptions.kDartObfuscationOption); boolArg(FlutterOptions.kDartObfuscationOption);
@ -1471,7 +1454,6 @@ abstract class FlutterCommand extends Command<void> {
dartExperiments: experiments, dartExperiments: experiments,
performanceMeasurementFile: performanceMeasurementFile, performanceMeasurementFile: performanceMeasurementFile,
packageConfigPath: packagesPath ?? packageConfigFile.path, packageConfigPath: packagesPath ?? packageConfigFile.path,
nullSafetyMode: nullSafetyMode,
codeSizeDirectory: codeSizeDirectory, codeSizeDirectory: codeSizeDirectory,
androidGradleDaemon: androidGradleDaemon, androidGradleDaemon: androidGradleDaemon,
androidSkipBuildDependencyValidation: androidSkipBuildDependencyValidation, androidSkipBuildDependencyValidation: androidSkipBuildDependencyValidation,
@ -1880,9 +1862,6 @@ Run 'flutter -h' (or 'flutter <command> -h') for available flutter commands and
buildSystem: globals.buildSystem, buildSystem: globals.buildSystem,
buildTargets: globals.buildTargets, buildTargets: globals.buildTargets,
); );
if (reportNullSafety) {
await _sendNullSafetyAnalyticsEvents(project);
}
} }
if (regeneratePlatformSpecificToolingDuringVerify) { if (regeneratePlatformSpecificToolingDuringVerify) {
@ -1946,16 +1925,6 @@ Run 'flutter -h' (or 'flutter <command> -h') for available flutter commands and
); );
} }
Future<void> _sendNullSafetyAnalyticsEvents(FlutterProject project) async {
final BuildInfo buildInfo = await getBuildInfo();
NullSafetyAnalysisEvent(
buildInfo.packageConfig,
buildInfo.nullSafetyMode,
project.manifest.appName,
globals.flutterUsage,
).send();
}
/// The set of development artifacts required for this command. /// The set of development artifacts required for this command.
/// ///
/// Defaults to an empty set. Including [DevelopmentArtifact.universal] is /// Defaults to an empty set. Including [DevelopmentArtifact.universal] is

View File

@ -148,7 +148,6 @@ String generateTestBootstrap({
Uri? packageConfigUri, Uri? packageConfigUri,
bool updateGoldens = false, bool updateGoldens = false,
String languageVersionHeader = '', String languageVersionHeader = '',
bool nullSafety = false,
bool flutterTestDep = true, bool flutterTestDep = true,
bool integrationTest = false, bool integrationTest = false,
}) { }) {

View File

@ -118,24 +118,10 @@ class WebTestCompiler {
required BuildInfo buildInfo, required BuildInfo buildInfo,
required WebRendererMode webRenderer, required WebRendererMode webRenderer,
}) async { }) async {
LanguageVersion languageVersion = LanguageVersion(2, 8); final LanguageVersion languageVersion = currentLanguageVersion(_fileSystem, Cache.flutterRoot!);
late final String platformDillName;
// TODO(zanderso): to support autodetect this would need to partition the source code into
// a sound and unsound set and perform separate compilations
final List<String> extraFrontEndOptions = List<String>.of(buildInfo.extraFrontEndOptions);
switch (buildInfo.nullSafetyMode) {
case NullSafetyMode.unsound || NullSafetyMode.autodetect:
// TODO(matanlurey): Should be unreachable, remove as part of https://github.com/flutter/flutter/issues/162846.
throw UnsupportedError('Unsound null safety mode is not supported');
case NullSafetyMode.sound:
languageVersion = currentLanguageVersion(_fileSystem, Cache.flutterRoot!);
platformDillName = 'ddc_outline.dill';
}
final String platformDillPath = _fileSystem.path.join( final String platformDillPath = _fileSystem.path.join(
_artifacts.getHostArtifact(HostArtifact.webPlatformKernelFolder).path, _artifacts.getHostArtifact(HostArtifact.webPlatformKernelFolder).path,
platformDillName, 'ddc_outline.dill',
); );
final Directory outputDirectory = _fileSystem.directory(testOutputDir) final Directory outputDirectory = _fileSystem.directory(testOutputDir)
@ -150,7 +136,7 @@ class WebTestCompiler {
final String cachedKernelPath = getDefaultCachedKernelPath( final String cachedKernelPath = getDefaultCachedKernelPath(
trackWidgetCreation: buildInfo.trackWidgetCreation, trackWidgetCreation: buildInfo.trackWidgetCreation,
dartDefines: buildInfo.dartDefines, dartDefines: buildInfo.dartDefines,
extraFrontEndOptions: extraFrontEndOptions, extraFrontEndOptions: buildInfo.extraFrontEndOptions,
fileSystem: _fileSystem, fileSystem: _fileSystem,
config: _config, config: _config,
); );
@ -165,7 +151,7 @@ class WebTestCompiler {
fileSystemScheme: 'org-dartlang-app', fileSystemScheme: 'org-dartlang-app',
initializeFromDill: cachedKernelPath, initializeFromDill: cachedKernelPath,
targetModel: TargetModel.dartdevc, targetModel: TargetModel.dartdevc,
extraFrontEndOptions: extraFrontEndOptions, extraFrontEndOptions: buildInfo.extraFrontEndOptions,
platformDill: _fileSystem.file(platformDillPath).absolute.uri.toString(), platformDill: _fileSystem.file(platformDillPath).absolute.uri.toString(),
dartDefines: dartDefines, dartDefines: dartDefines,
librariesSpec: librariesSpec:

View File

@ -103,35 +103,6 @@ void main() {
}, },
); );
testUsingContext(
'supports --no-sound-null-safety with an overridden NonNullSafeBuilds',
() async {
fileSystem.file('lib/main.dart').createSync(recursive: true);
fileSystem.file('pubspec.yaml').createSync();
fileSystem.file('.dart_tool/package_config.json').createSync(recursive: true);
final FakeDevice device = FakeDevice(
isLocalEmulator: true,
platformType: PlatformType.android,
);
testDeviceManager.devices = <Device>[device];
final TestRunCommandThatOnlyValidates command = TestRunCommandThatOnlyValidates();
await createTestCommandRunner(command).run(const <String>[
'run',
'--use-application-binary=app/bar/faz',
'--no-sound-null-safety',
]);
},
overrides: <Type, Generator>{
DeviceManager: () => testDeviceManager,
FileSystem: () => fileSystem,
Logger: () => logger,
NonNullSafeBuilds: () => NonNullSafeBuilds.allowed,
ProcessManager: () => FakeProcessManager.any(),
},
);
testUsingContext( testUsingContext(
'does not support "--use-application-binary" and "--fast-start"', 'does not support "--use-application-binary" and "--fast-start"',
() async { () async {

View File

@ -287,7 +287,6 @@ void main() {
expect(buildInfo.splitDebugInfoPath, '/project-name/v1.2.3/'); expect(buildInfo.splitDebugInfoPath, '/project-name/v1.2.3/');
expect(buildInfo.dartObfuscation, isTrue); expect(buildInfo.dartObfuscation, isTrue);
expect(buildInfo.dartDefines.contains('foo=bar'), isTrue); expect(buildInfo.dartDefines.contains('foo=bar'), isTrue);
expect(buildInfo.nullSafetyMode, NullSafetyMode.sound);
}, overrides: <Type, Generator>{AndroidBuilder: () => fakeAndroidBuilder}); }, overrides: <Type, Generator>{AndroidBuilder: () => fakeAndroidBuilder});
}); });

View File

@ -11,7 +11,6 @@ import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/signals.dart'; import 'package:flutter_tools/src/base/signals.dart';
import 'package:flutter_tools/src/base/terminal.dart'; import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart'; import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/commands/attach.dart'; import 'package:flutter_tools/src/commands/attach.dart';
import 'package:flutter_tools/src/commands/build.dart'; import 'package:flutter_tools/src/commands/build.dart';
@ -97,20 +96,6 @@ void main() {
} }
}); });
testUsingContext('BuildSubCommand displays current null safety mode', () async {
const BuildInfo unsound = BuildInfo(
BuildMode.debug,
'',
nullSafetyMode: NullSafetyMode.unsound,
treeShakeIcons: false,
packageConfigPath: '.dart_tool/package_config.json',
);
final BufferLogger logger = BufferLogger.test();
FakeBuildSubCommand(logger).test(unsound);
expect(logger.statusText, contains('Building without sound null safety ⚠️'));
});
testUsingContext('Include only supported sub commands', () { testUsingContext('Include only supported sub commands', () {
final BufferLogger logger = BufferLogger.test(); final BufferLogger logger = BufferLogger.test();
final MemoryFileSystem fs = MemoryFileSystem.test(); final MemoryFileSystem fs = MemoryFileSystem.test();
@ -126,22 +111,3 @@ void main() {
} }
}); });
} }
class FakeBuildSubCommand extends BuildSubCommand {
FakeBuildSubCommand(Logger logger) : super(logger: logger, verboseHelp: false);
@override
String get description => throw UnimplementedError();
@override
String get name => throw UnimplementedError();
void test(BuildInfo buildInfo) {
displayNullSafetyMode(buildInfo);
}
@override
Future<FlutterCommandResult> runCommand() {
throw UnimplementedError();
}
}

View File

@ -2,10 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/doctor_validator.dart'; import 'package:flutter_tools/src/doctor_validator.dart';
import 'package:flutter_tools/src/reporting/reporting.dart'; import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:package_config/package_config.dart';
import '../../src/common.dart'; import '../../src/common.dart';
@ -58,100 +56,6 @@ void main() {
contains(const TestUsageEvent('doctor-result', 'FakeGroupedValidator', label: 'crash')), contains(const TestUsageEvent('doctor-result', 'FakeGroupedValidator', label: 'crash')),
); );
}); });
testWithoutContext('Reports null safe analytics events', () {
final TestUsage usage = TestUsage();
final PackageConfig packageConfig = PackageConfig(<Package>[
Package('foo', Uri.parse('file:///foo/'), languageVersion: LanguageVersion(2, 12)),
Package('bar', Uri.parse('file:///fizz/'), languageVersion: LanguageVersion(2, 1)),
Package('baz', Uri.parse('file:///bar/'), languageVersion: LanguageVersion(2, 2)),
]);
NullSafetyAnalysisEvent(packageConfig, NullSafetyMode.sound, 'foo', usage).send();
expect(
usage.events,
unorderedEquals(<TestUsageEvent>[
const TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory,
'runtime-mode',
label: 'NullSafetyMode.sound',
),
TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory,
'stats',
parameters: CustomDimensions.fromMap(<String, String>{'cd49': '1', 'cd50': '3'}),
),
const TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory,
'language-version',
label: '2.12',
),
]),
);
});
testWithoutContext('Does not crash if main package is missing', () {
final TestUsage usage = TestUsage();
final PackageConfig packageConfig = PackageConfig(<Package>[
Package('foo', Uri.parse('file:///foo/lib/'), languageVersion: LanguageVersion(2, 12)),
Package('bar', Uri.parse('file:///fizz/lib/'), languageVersion: LanguageVersion(2, 1)),
Package('baz', Uri.parse('file:///bar/lib/'), languageVersion: LanguageVersion(2, 2)),
]);
NullSafetyAnalysisEvent(
packageConfig,
NullSafetyMode.sound,
'something-unrelated',
usage,
).send();
expect(
usage.events,
unorderedEquals(<TestUsageEvent>[
const TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory,
'runtime-mode',
label: 'NullSafetyMode.sound',
),
TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory,
'stats',
parameters: CustomDimensions.fromMap(<String, String>{'cd49': '1', 'cd50': '3'}),
),
]),
);
});
testWithoutContext('a null language version is treated as unmigrated', () {
final TestUsage usage = TestUsage();
final PackageConfig packageConfig = PackageConfig(<Package>[
Package('foo', Uri.parse('file:///foo/lib/')),
]);
NullSafetyAnalysisEvent(
packageConfig,
NullSafetyMode.sound,
'something-unrelated',
usage,
).send();
expect(
usage.events,
unorderedEquals(<TestUsageEvent>[
const TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory,
'runtime-mode',
label: 'NullSafetyMode.sound',
),
TestUsageEvent(
NullSafetyAnalysisEvent.kNullSafetyCategory,
'stats',
parameters: CustomDimensions.fromMap(<String, String>{'cd49': '0', 'cd50': '1'}),
),
]),
);
});
} }
class FakeGroupedValidator extends GroupedValidator { class FakeGroupedValidator extends GroupedValidator {

View File

@ -916,7 +916,6 @@ void main() {
BuildMode.debug, BuildMode.debug,
'', '',
treeShakeIcons: false, treeShakeIcons: false,
nullSafetyMode: NullSafetyMode.unsound,
packageConfigPath: '.dart_tool/package_config.json', packageConfigPath: '.dart_tool/package_config.json',
), ),
enableDwds: false, enableDwds: false,