From 560160c2d6d842fbb1fd6389b813832723ae8946 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 6 Oct 2022 11:00:10 -0700 Subject: [PATCH 1/4] Start migration of WebDev to null-safety --- webdev/lib/src/logging.dart | 14 ++++++-------- webdev/lib/src/pubspec.dart | 37 ++++++++++++++++++++----------------- webdev/lib/src/util.dart | 2 -- webdev/pubspec.yaml | 6 +++--- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/webdev/lib/src/logging.dart b/webdev/lib/src/logging.dart index 95554bf5a..00ca57f22 100644 --- a/webdev/lib/src/logging.dart +++ b/webdev/lib/src/logging.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.9 - import 'dart:async'; import 'dart:io'; @@ -11,12 +9,12 @@ import 'package:io/ansi.dart'; import 'package:logging/logging.dart'; typedef LogWriter = void Function(Level level, String message, - {String error, String loggerName, String stackTrace}); + {String? error, String? loggerName, String? stackTrace}); var _verbose = false; -StreamSubscription _subscription; +StreamSubscription? _subscription; -void configureLogWriter(bool verbose, {LogWriter customLogWriter}) { +void configureLogWriter(bool verbose, {LogWriter? customLogWriter}) { _verbose = verbose; _logWriter = customLogWriter ?? _logWriter; Logger.root.level = verbose ? Level.ALL : Level.INFO; @@ -30,7 +28,7 @@ void configureLogWriter(bool verbose, {LogWriter customLogWriter}) { // ignore: prefer_function_declarations_over_variables LogWriter _logWriter = - (level, message, {String error, String loggerName, String stackTrace}) { + (level, message, {String? error, String? loggerName, String? stackTrace}) { // Erases the previous line if (!_verbose) stdout.write('\x1b[2K\r'); var log = formatLog(level, message, @@ -54,7 +52,7 @@ LogWriter get logWriter => _logWriter; /// Colors the message and writes it to stdout. String formatLog(Level level, String message, - {bool withColors, String error, String loggerName, String stackTrace}) { + {bool? withColors, String? error, String? loggerName, String? stackTrace}) { withColors ??= false; var buffer = StringBuffer(message); if (error != null) { @@ -75,7 +73,7 @@ String formatLog(Level level, String message, } else { color = red; } - formattedLevel = color.wrap(formattedLevel); + formattedLevel = color.wrap(formattedLevel) ?? formattedLevel; } var loggerNameOutput = diff --git a/webdev/lib/src/pubspec.dart b/webdev/lib/src/pubspec.dart index a5be96f83..b87298483 100644 --- a/webdev/lib/src/pubspec.dart +++ b/webdev/lib/src/pubspec.dart @@ -2,14 +2,11 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.9 - import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:http/http.dart'; -import 'package:meta/meta.dart'; import 'package:pub_semver/pub_semver.dart'; import 'package:pubspec_parse/pubspec_parse.dart'; import 'package:yaml/yaml.dart'; @@ -20,18 +17,18 @@ import 'version.dart'; class PackageException implements Exception { final List details; - final String unsupportedArgument; + final String? unsupportedArgument; PackageException(this.details, {this.unsupportedArgument}); } class PackageExceptionDetails { final String error; - final String description; + final String? description; final bool _missingDependency; const PackageExceptionDetails._(this.error, - {this.description, bool missingDependency}) + {this.description, bool? missingDependency}) : _missingDependency = missingDependency ?? false; static const noPubspecLock = @@ -72,7 +69,7 @@ Future _runPubDeps() async { } class PubspecLock { - final YamlMap _packages; + final YamlMap? _packages; PubspecLock(this._packages); @@ -82,28 +79,31 @@ class PubspecLock { var pubspecLock = loadYaml(await File('pubspec.lock').readAsString()) as YamlMap; - var packages = pubspecLock['packages'] as YamlMap; + var packages = pubspecLock['packages'] as YamlMap?; return PubspecLock(packages); } List checkPackage( String pkgName, VersionConstraint constraint, - {String forArgument, bool requireDirect}) { + {String? forArgument, bool? requireDirect}) { requireDirect ??= true; var issues = []; var missingDetails = PackageExceptionDetails.missingDep(pkgName, constraint); - var pkgDataMap = (_packages == null) ? null : _packages[pkgName] as YamlMap; + var pkgDataMap = + (_packages == null) ? null : _packages![pkgName] as YamlMap?; if (pkgDataMap == null) { issues.add(missingDetails); } else { - var dependency = pkgDataMap['dependency'] as String; - if (requireDirect && !dependency.startsWith('direct ')) { + var dependency = pkgDataMap['dependency'] as String?; + if (requireDirect && + dependency != null && + !dependency.startsWith('direct ')) { issues.add(missingDetails); } - var source = pkgDataMap['source'] as String; + var source = pkgDataMap['source'] as String?; if (source == 'hosted') { // NOTE: pkgDataMap['description'] should be: // `{url: https://pub.dartlang.org, name: [pkgName]}` @@ -168,7 +168,7 @@ final buildWebCompilersConstraint = VersionConstraint.parse('>=2.12.0 <4.0.0'); // Note the minimum versions should never be dev versions as users will not // get them by default. Future checkPubspecLock(PubspecLock pubspecLock, - {@required bool requireBuildWebCompilers}) async { + {required bool requireBuildWebCompilers}) async { var issues = []; var buildRunnerIssues = @@ -191,7 +191,7 @@ Future checkPubspecLock(PubspecLock pubspecLock, } class _PackageInfo { - final Version version; + final Version? version; final VersionConstraint buildDaemonConstraint; final bool isNewer; _PackageInfo(this.version, this.buildDaemonConstraint, this.isNewer); @@ -212,6 +212,9 @@ Future<_PackageInfo> _latestPackageInfo() async { buildDaemonConstraint = buildDaemonDependency.version; } var currentVersion = Version.parse(packageVersion); - return _PackageInfo(pubspec.version, buildDaemonConstraint, - currentVersion.compareTo(pubspec.version) < 0); + var pubspecVersion = pubspec.version; + var isNewer = (pubspecVersion == null) + ? true + : currentVersion.compareTo(pubspecVersion) < 0; + return _PackageInfo(pubspec.version, buildDaemonConstraint, isNewer); } diff --git a/webdev/lib/src/util.dart b/webdev/lib/src/util.dart index 3fc1f388b..72006917e 100644 --- a/webdev/lib/src/util.dart +++ b/webdev/lib/src/util.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.9 - import 'dart:async'; import 'dart:io'; diff --git a/webdev/pubspec.yaml b/webdev/pubspec.yaml index c9722482e..e787cb8c5 100644 --- a/webdev/pubspec.yaml +++ b/webdev/pubspec.yaml @@ -49,9 +49,9 @@ dev_dependencies: webdriver: ^3.0.0 # Comment out before releasing webdev. -# dependency_overrides: -# dwds: -# path: ../dwds +dependency_overrides: + dwds: + path: ../dwds executables: webdev: From 93d8e9cf691b2071b9e48ba9f4ae10519fcd7063 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 6 Oct 2022 12:34:11 -0700 Subject: [PATCH 2/4] Migrate configuration.dart and shared.dart to null-safety --- webdev/lib/src/command/configuration.dart | 144 +++++++++++----------- webdev/lib/src/command/shared.dart | 14 +-- 2 files changed, 77 insertions(+), 81 deletions(-) diff --git a/webdev/lib/src/command/configuration.dart b/webdev/lib/src/command/configuration.dart index 57a9485ac..8e128a926 100644 --- a/webdev/lib/src/command/configuration.dart +++ b/webdev/lib/src/command/configuration.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.9 - import 'package:args/args.dart'; import 'package:dwds/dwds.dart'; import 'package:logging/logging.dart'; @@ -40,13 +38,13 @@ const disableDdsFlag = 'disable-dds'; ReloadConfiguration _parseReloadConfiguration(ArgResults argResults) { var auto = argResults.options.contains(autoOption) - ? argResults[autoOption] as String + ? argResults[autoOption] as String? : null; void _handleDeprecatedFlag(String flag, String autoFallback) { if (argResults.options.contains(flag) && argResults.wasParsed(flag) && - argResults[flag] as bool == true) { + argResults[flag].toUpperCase() == 'TRUE') { logWriter( Level.WARNING, '--$flag is deprecated please use --auto=$autoFallback instead ' @@ -83,52 +81,52 @@ ReloadConfiguration _parseReloadConfiguration(ArgResults argResults) { } class Configuration { - final bool _autoRun; - final int _chromeDebugPort; - final bool _debugExtension; - final bool _debug; - final bool _enableInjectedClient; - final String _hostname; - final String _tlsCertChain; - final String _tlsCertKey; - final List _launchApps; - final bool _launchInChrome; - final String _userDataDir; - final bool _logRequests; - final String _output; - final String outputInput; - final String outputPath; - final bool _release; - final ReloadConfiguration _reload; - final bool _requireBuildWebCompilers; - final bool _enableExpressionEvaluation; - final bool _verbose; - final bool _disableDds; - final String _nullSafety; + final bool? _autoRun; + final int? _chromeDebugPort; + final bool? _debugExtension; + final bool? _debug; + final bool? _enableInjectedClient; + final String? _hostname; + final String? _tlsCertChain; + final String? _tlsCertKey; + final List? _launchApps; + final bool? _launchInChrome; + final String? _userDataDir; + final bool? _logRequests; + final String? _output; + final String? outputInput; + final String? outputPath; + final bool? _release; + final ReloadConfiguration? _reload; + final bool? _requireBuildWebCompilers; + final bool? _enableExpressionEvaluation; + final bool? _verbose; + final bool? _disableDds; + final String? _nullSafety; Configuration({ - bool autoRun, - int chromeDebugPort, - bool debugExtension, - bool debug, - bool enableInjectedClient, - String hostname, - String tlsCertChain, - String tlsCertKey, - List launchApps, - bool launchInChrome, - String userDataDir, - bool logRequests, - String output, + bool? autoRun, + int? chromeDebugPort, + bool? debugExtension, + bool? debug, + bool? enableInjectedClient, + String? hostname, + String? tlsCertChain, + String? tlsCertKey, + List? launchApps, + bool? launchInChrome, + String? userDataDir, + bool? logRequests, + String? output, this.outputInput, this.outputPath, - ReloadConfiguration reload, - bool release, - bool requireBuildWebCompilers, - bool enableExpressionEvaluation, - bool verbose, - bool disableDds, - String nullSafety, + ReloadConfiguration? reload, + bool? release, + bool? requireBuildWebCompilers, + bool? enableExpressionEvaluation, + bool? verbose, + bool? disableDds, + String? nullSafety, }) : _autoRun = autoRun, _chromeDebugPort = chromeDebugPort, _debugExtension = debugExtension, @@ -155,7 +153,7 @@ class Configuration { void _validateConfiguration() { // Both null and an empty string are valid values for outputInput. For any // other value, we need to ensure it's a top-level dir. - if (outputInput?.isNotEmpty ?? false) ensureIsTopLevelDir(outputInput); + if (outputInput?.isNotEmpty ?? false) ensureIsTopLevelDir(outputInput!); if ((tlsCertKey != null && tlsCertChain == null) || (tlsCertKey == null && tlsCertChain != null)) { @@ -241,15 +239,15 @@ class Configuration { String get hostname => _hostname ?? 'localhost'; - String get tlsCertChain => _tlsCertChain; + String? get tlsCertChain => _tlsCertChain; - String get tlsCertKey => _tlsCertKey; + String? get tlsCertKey => _tlsCertKey; List get launchApps => _launchApps ?? []; bool get launchInChrome => _launchInChrome ?? false; - String get userDataDir => _userDataDir; + String? get userDataDir => _userDataDir; bool get logRequests => _logRequests ?? false; @@ -270,17 +268,17 @@ class Configuration { /// 'sound', 'unsound', or 'auto'. /// 'auto' indicates that the default `package:build_web_compilers` /// behavior should be used. - String get nullSafety => _nullSafety; + String? get nullSafety => _nullSafety; /// Returns a new configuration with values updated from the parsed args. - static Configuration fromArgs(ArgResults argResults, - {Configuration defaultConfiguration}) { + static Configuration fromArgs(ArgResults? argResults, + {Configuration? defaultConfiguration}) { defaultConfiguration ??= Configuration(); if (argResults == null) return defaultConfiguration; var enableInjectedClient = argResults.options.contains(enableInjectedClientFlag) - ? argResults[enableInjectedClientFlag] as bool + ? (argResults[enableInjectedClientFlag] as bool) : defaultConfiguration.enableInjectedClient; // Change the defaults when we have no injected client to disable all @@ -297,56 +295,56 @@ class Configuration { : defaultConfiguration.chromeDebugPort; var debugExtension = argResults.options.contains(debugExtensionFlag) - ? argResults[debugExtensionFlag] as bool + ? argResults[debugExtensionFlag] as bool? : defaultConfiguration.debugExtension; var debug = argResults.options.contains(debugFlag) - ? argResults[debugFlag] as bool + ? argResults[debugFlag] as bool? : defaultConfiguration.debug; var hostname = argResults.options.contains(hostnameFlag) - ? argResults[hostnameFlag] as String + ? argResults[hostnameFlag] as String? : defaultConfiguration.hostname; var tlsCertChain = argResults.options.contains(tlsCertChainFlag) - ? argResults[tlsCertChainFlag] as String + ? argResults[tlsCertChainFlag] as String? : defaultConfiguration.tlsCertChain; var tlsCertKey = argResults.options.contains(tlsCertKeyFlag) - ? argResults[tlsCertKeyFlag] as String + ? argResults[tlsCertKeyFlag] as String? : defaultConfiguration.tlsCertKey; var launchApps = argResults.options.contains(launchAppOption) && argResults.wasParsed(launchAppOption) - ? argResults[launchAppOption] as List + ? argResults[launchAppOption] as List? : defaultConfiguration.launchApps; var launchInChrome = argResults.options.contains(launchInChromeFlag) && argResults.wasParsed(launchInChromeFlag) - ? argResults[launchInChromeFlag] as bool + ? argResults[launchInChromeFlag] as bool? // We want to default to launch chrome if the user provides just --debug // and not --chrome-debug-port. - : debug && + : debug! && !(argResults.options.contains(launchInChromeFlag) && argResults.wasParsed(chromeDebugPortFlag)) ? true : defaultConfiguration.launchInChrome; var userDataDir = argResults.options.contains(userDataDirFlag) - ? argResults[userDataDirFlag] as String + ? argResults[userDataDirFlag] as String? : defaultConfiguration.userDataDir; var logRequests = argResults.options.contains(logRequestsFlag) - ? argResults[logRequestsFlag] as bool + ? argResults[logRequestsFlag] as bool? : defaultConfiguration.logRequests; var output = argResults.options.contains(outputFlag) - ? argResults[outputFlag] as String + ? argResults[outputFlag] as String? : defaultConfiguration.output; - String outputPath; + String? outputPath; String outputInput; - if (output == 'NONE') { + if (output == 'NONE' || output == null) { // The empty string means build everything. outputInput = ''; } else { @@ -362,29 +360,29 @@ class Configuration { } var release = argResults.options.contains(releaseFlag) - ? argResults[releaseFlag] as bool + ? argResults[releaseFlag] as bool? : defaultConfiguration.release; var requireBuildWebCompilers = argResults.options.contains(requireBuildWebCompilersFlag) - ? argResults[requireBuildWebCompilersFlag] as bool + ? argResults[requireBuildWebCompilersFlag] as bool? : defaultConfiguration.requireBuildWebCompilers; var enableExpressionEvaluation = argResults.options.contains(enableExpressionEvaluationFlag) - ? argResults[enableExpressionEvaluationFlag] as bool + ? argResults[enableExpressionEvaluationFlag] as bool? : defaultConfiguration.enableExpressionEvaluation; var verbose = argResults.options.contains(verboseFlag) - ? argResults[verboseFlag] as bool + ? argResults[verboseFlag] as bool? : defaultConfiguration.verbose; var nullSafety = argResults.options.contains(nullSafetyFlag) - ? argResults[nullSafetyFlag] as String + ? argResults[nullSafetyFlag] as String? : defaultConfiguration.nullSafety; var disableDds = argResults.options.contains(disableDdsFlag) - ? argResults[disableDdsFlag] as bool + ? argResults[disableDdsFlag] as bool? : defaultConfiguration.disableDds; return Configuration( diff --git a/webdev/lib/src/command/shared.dart b/webdev/lib/src/command/shared.dart index 3d6a8a135..6bb9b9857 100644 --- a/webdev/lib/src/command/shared.dart +++ b/webdev/lib/src/command/shared.dart @@ -2,8 +2,6 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -// @dart = 2.9 - import 'dart:async'; import 'dart:io'; @@ -16,7 +14,7 @@ import 'configuration.dart'; final lineLength = stdout.hasTerminal ? stdout.terminalColumns : 80; void addSharedArgs(ArgParser argParser, - {String outputDefault, bool releaseDefault}) { + {String? outputDefault, bool? releaseDefault}) { outputDefault ??= outputNone; releaseDefault ??= true; argParser @@ -127,13 +125,13 @@ final _defaultWebDirs = const ['web']; /// /// Throws an [InvalidConfiguration] exception if it can't find at /// least one directory. -Map parseDirectoryArgs(List args, {int basePort}) { - var result = {}; - basePort ??= 8080; +Map parseDirectoryArgs(List args, {int? basePort}) { + var result = {}; + var port = basePort ?? 8080; if (args.isEmpty) { for (var dir in _defaultWebDirs) { if (Directory(dir).existsSync()) { - result[dir] = basePort++; + result[dir] = port++; } } } else { @@ -143,7 +141,7 @@ Map parseDirectoryArgs(List args, {int basePort}) { if (splitOption.length == 2) { result[splitOption.first] = int.parse(splitOption.last); } else { - result[arg] = basePort++; + result[arg] = port++; } } } From 86b2a270e6dc9fd47e6f70873841b95135b7f1c4 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Thu, 6 Oct 2022 15:28:55 -0700 Subject: [PATCH 3/4] Make ints non-nullable --- webdev/lib/src/command/shared.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webdev/lib/src/command/shared.dart b/webdev/lib/src/command/shared.dart index 6bb9b9857..c30dba85b 100644 --- a/webdev/lib/src/command/shared.dart +++ b/webdev/lib/src/command/shared.dart @@ -125,8 +125,8 @@ final _defaultWebDirs = const ['web']; /// /// Throws an [InvalidConfiguration] exception if it can't find at /// least one directory. -Map parseDirectoryArgs(List args, {int? basePort}) { - var result = {}; +Map parseDirectoryArgs(List args, {int? basePort}) { + var result = {}; var port = basePort ?? 8080; if (args.isEmpty) { for (var dir in _defaultWebDirs) { From 7b7119fb0f332569f598c10e6d292a1a435d1a9b Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Fri, 7 Oct 2022 16:09:22 -0700 Subject: [PATCH 4/4] Respond to PR comments --- webdev/lib/src/command/configuration.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webdev/lib/src/command/configuration.dart b/webdev/lib/src/command/configuration.dart index 8e128a926..c36e7a882 100644 --- a/webdev/lib/src/command/configuration.dart +++ b/webdev/lib/src/command/configuration.dart @@ -44,7 +44,7 @@ ReloadConfiguration _parseReloadConfiguration(ArgResults argResults) { void _handleDeprecatedFlag(String flag, String autoFallback) { if (argResults.options.contains(flag) && argResults.wasParsed(flag) && - argResults[flag].toUpperCase() == 'TRUE') { + (argResults[flag] as bool? ?? false)) { logWriter( Level.WARNING, '--$flag is deprecated please use --auto=$autoFallback instead ' @@ -268,7 +268,7 @@ class Configuration { /// 'sound', 'unsound', or 'auto'. /// 'auto' indicates that the default `package:build_web_compilers` /// behavior should be used. - String? get nullSafety => _nullSafety; + String get nullSafety => _nullSafety ?? 'auto'; /// Returns a new configuration with values updated from the parsed args. static Configuration fromArgs(ArgResults? argResults,