[ CLI ] Migrate package:dartdev to null safety

Fixes https://github.com/dart-lang/sdk/issues/47964

TEST=CQ

Change-Id: I4ee57bc5739835824b0052bd9470a0d52ccf161b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/229948
Reviewed-by: Devon Carew <devoncarew@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi 2022-01-26 21:16:49 +00:00 committed by Commit Bot
parent 7ad1786e45
commit 1c571a12fa
56 changed files with 506 additions and 486 deletions

View file

@ -244,7 +244,7 @@
"name": "dartdev",
"rootUri": "../pkg/dartdev",
"packageUri": "lib/",
"languageVersion": "2.6"
"languageVersion": "2.12"
},
{
"name": "dartdoc",

View file

@ -7,6 +7,6 @@ import 'dart:isolate';
import 'package:dartdev/dartdev.dart';
/// The entry point for dartdev.
Future<void> main(List<String> args, SendPort port) async {
Future<void> main(List<String> args, SendPort? port) async {
await runDartdev(args, port);
}

View file

@ -35,7 +35,7 @@ import 'src/vm_interop_handler.dart';
/// This is typically called from bin/, but given the length of the method and
/// analytics logic, it has been moved here.
Future<void> runDartdev(List<String> args, SendPort port) async {
Future<void> runDartdev(List<String> args, SendPort? port) async {
VmInteropHandler.initialize(port);
// TODO(sigurdm): Remove when top-level pub is removed.
@ -61,7 +61,7 @@ Future<void> runDartdev(List<String> args, SendPort port) async {
// Finally, call the runner to execute the command; see DartdevRunner.
final runner = DartdevRunner(args);
var exitCode = 1;
int? exitCode = 1;
try {
exitCode = await runner.run(args);
} on UsageException catch (e) {
@ -86,7 +86,7 @@ class DartdevRunner extends CommandRunner<int> {
final bool verbose;
Analytics _analytics;
late Analytics _analytics;
DartdevRunner(List<String> args)
: verbose = args.contains('-v') || args.contains('--verbose'),
@ -221,15 +221,15 @@ class DartdevRunner extends CommandRunner<int> {
// The exit code for the dartdev process; null indicates that it has not been
// set yet. The value is set in the catch and finally blocks below.
int exitCode;
int? exitCode;
// Any caught non-UsageExceptions when running the sub command.
Object exception;
StackTrace stackTrace;
Object? exception;
StackTrace? stackTrace;
try {
exitCode = await super.runCommand(topLevelResults);
if (path != null && analytics.enabled) {
if (analytics.enabled) {
// Send the event to analytics
unawaited(
sendUsageEvent(
@ -242,7 +242,8 @@ class DartdevRunner extends CommandRunner<int> {
// value.
//
// Note that this will also conflate short-options and long-options.
command?.options?.where(command.wasParsed)?.toList(),
command?.options.where(command.wasParsed).toList() ??
const <String>[],
specifiedExperiments: topLevelResults.enabledExperiments,
),
);
@ -263,7 +264,7 @@ class DartdevRunner extends CommandRunner<int> {
if (analytics.enabled) {
unawaited(
analytics.sendTiming(
path ?? '',
path,
stopwatch.elapsedMilliseconds,
category: 'commands',
),

View file

@ -14,7 +14,6 @@ import 'package:analysis_server_client/protocol.dart'
EditBulkFixesResult,
ResponseDecoder;
import 'package:args/args.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'core.dart';
@ -23,7 +22,7 @@ import 'utils.dart';
/// When set, this function is executed just before the Analysis Server starts.
void Function(String cmdName, List<FileSystemEntity> analysisRoots,
ArgResults argResults) preAnalysisServerStart;
ArgResults? argResults)? preAnalysisServerStart;
/// A class to provide an API wrapper around an analysis server process.
class AnalysisServer {
@ -32,18 +31,18 @@ class AnalysisServer {
this.sdkPath,
this.analysisRoots, {
this.cacheDirectoryPath,
@required this.commandName,
@required this.argResults,
required this.commandName,
required this.argResults,
});
final String cacheDirectoryPath;
final File packagesFile;
final String? cacheDirectoryPath;
final File? packagesFile;
final Directory sdkPath;
final List<FileSystemEntity> analysisRoots;
final String commandName;
final ArgResults argResults;
final ArgResults? argResults;
Process _process;
Process? _process;
Completer<bool> _analysisFinished = Completer();
@ -53,8 +52,8 @@ class AnalysisServer {
// {"event":"server.status","params":{"analysis":{"isAnalyzing":true}}}
return _streamController('server.status')
.stream
.where((event) => event['analysis'] != null)
.map((event) => event['analysis']['isAnalyzing'] as bool);
.where((event) => event!['analysis'] != null)
.map((event) => (event!['analysis']['isAnalyzing']!) as bool);
}
/// This future completes when we next receive an analysis finished event
@ -65,7 +64,7 @@ class AnalysisServer {
Stream<FileAnalysisErrors> get onErrors {
// {"event":"analysis.errors","params":{"file":"/Users/.../lib/main.dart","errors":[]}}
return _streamController('analysis.errors').stream.map((event) {
final file = event['file'] as String;
final file = event!['file'] as String;
final errorsList = event['errors'] as List<dynamic>;
final errors = errorsList
.map<Map<String, dynamic>>(castStringKeyedMap)
@ -76,7 +75,7 @@ class AnalysisServer {
});
}
Future<int> get onExit => _process.exitCode;
Future<int> get onExit => _process!.exitCode;
final Map<String, StreamController<Map<String, dynamic>>> _streamControllers =
{};
@ -94,19 +93,19 @@ class AnalysisServer {
'--sdk',
sdkPath.path,
if (cacheDirectoryPath != null) '--cache=$cacheDirectoryPath',
if (packagesFile != null) '--packages=${packagesFile.path}',
if (packagesFile != null) '--packages=${packagesFile!.path}',
];
_process = await startDartProcess(sdk, command);
// This callback hookup can't throw.
_process.exitCode.whenComplete(() => _process = null);
_process!.exitCode.whenComplete(() => _process = null);
final Stream<String> errorStream = _process.stderr
final Stream<String> errorStream = _process!.stderr
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter());
errorStream.listen(log.stderr);
final Stream<String> inStream = _process.stdout
final Stream<String> inStream = _process!.stdout
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter());
inStream.listen(_handleServerResponse);
@ -125,7 +124,7 @@ class AnalysisServer {
// be passed to the analysis server.
List<String> analysisRootPaths = analysisRoots.map((root) {
return trimEnd(
root.absolute.resolveSymbolicLinksSync(), path.context.separator);
root.absolute.resolveSymbolicLinksSync(), path.context.separator)!;
}).toList();
onAnalyzing.listen((bool isAnalyzing) {
@ -178,7 +177,7 @@ class AnalysisServer {
}
Future<Map<String, dynamic>> _sendCommand(String method,
{Map<String, dynamic> params}) {
{Map<String, dynamic>? params}) {
final String id = (++_id).toString();
final String message = json.encode(<String, dynamic>{
'id': id,
@ -187,11 +186,11 @@ class AnalysisServer {
});
_requestCompleters[id] = Completer();
_process.stdin.writeln(message);
_process!.stdin.writeln(message);
log.trace('==> $message');
return _requestCompleters[id].future;
return _requestCompleters[id]!.future;
}
void _handleServerResponse(String line) {
@ -216,27 +215,28 @@ class AnalysisServer {
.remove(id)
?.completeError(RequestError.parse(error));
} else {
_requestCompleters.remove(id)?.complete(response['result']);
_requestCompleters.remove(id)?.complete(response['result'] ?? {});
}
}
}
}
void _handleServerError(Map<String, dynamic> error) {
void _handleServerError(Map<String, dynamic>? error) {
final err = error!;
// Fields are 'isFatal', 'message', and 'stackTrace'.
log.stderr('Error from the analysis server: ${error['message']}');
if (error['stackTrace'] != null) {
log.stderr(error['stackTrace'] as String);
log.stderr('Error from the analysis server: ${err['message']}');
if (err['stackTrace'] != null) {
log.stderr(err['stackTrace'] as String);
}
}
StreamController<Map<String, dynamic>> _streamController(String streamId) {
StreamController<Map<String, dynamic>?> _streamController(String streamId) {
return _streamControllers.putIfAbsent(
streamId, () => StreamController<Map<String, dynamic>>.broadcast());
}
Future<bool> dispose() async {
return _process?.kill();
return _process?.kill() ?? true;
}
}
@ -262,10 +262,10 @@ class AnalysisError implements Comparable<AnalysisError> {
// },"message":"...","hasFix":false}
Map<String, dynamic> json;
String get severity => json['severity'] as String;
String? get severity => json['severity'] as String?;
_AnalysisSeverity get _severityLevel =>
_severityMap[severity] ?? _AnalysisSeverity.none;
_severityMap[severity!] ?? _AnalysisSeverity.none;
bool get isInfo => _severityLevel == _AnalysisSeverity.info;
@ -279,26 +279,26 @@ class AnalysisError implements Comparable<AnalysisError> {
String get code => json['code'] as String;
String get correction => json['correction'] as String;
String? get correction => json['correction'] as String?;
int get endColumn => json['location']['endColumn'] as int;
int? get endColumn => json['location']['endColumn'] as int?;
int get endLine => json['location']['endLine'] as int;
int? get endLine => json['location']['endLine'] as int?;
String get file => json['location']['file'] as String;
int get startLine => json['location']['startLine'] as int;
int? get startLine => json['location']['startLine'] as int?;
int get startColumn => json['location']['startColumn'] as int;
int? get startColumn => json['location']['startColumn'] as int?;
int get offset => json['location']['offset'] as int;
int get length => json['location']['length'] as int;
String get url => json['url'] as String;
String? get url => json['url'] as String?;
List<DiagnosticMessage> get contextMessages {
var messages = json['contextMessages'] as List<dynamic>;
var messages = json['contextMessages'] as List<dynamic>?;
if (messages == null) {
// The field is optional, so we return an empty list as a default value.
return [];
@ -326,7 +326,7 @@ class AnalysisError implements Comparable<AnalysisError> {
}
@override
String toString() => '${severity.toLowerCase()}'
String toString() => '${severity!.toLowerCase()}'
'$message$file:$startLine:$startColumn'
'($code)';
}
@ -336,11 +336,11 @@ class DiagnosticMessage {
DiagnosticMessage(this.json);
int get column => json['location']['startColumn'] as int;
int? get column => json['location']['startColumn'] as int?;
int get endColumn => json['location']['endColumn'] as int;
int? get endColumn => json['location']['endColumn'] as int?;
int get endLine => json['location']['endLine'] as int;
int? get endLine => json['location']['endLine'] as int?;
String get filePath => json['location']['file'] as String;
@ -373,7 +373,7 @@ class RequestError {
final String message;
final String stackTrace;
RequestError(this.code, this.message, {this.stackTrace});
RequestError(this.code, this.message, {required this.stackTrace});
@override
String toString() => '[RequestError code: $code, message: $message]';

View file

@ -101,7 +101,7 @@ Analytics createAnalyticsInstance(bool disableAnalytics) {
///
/// This can return null under some conditions, including when the user's home
/// directory does not exist.
Directory getDartStorageDirectory() {
Directory? getDartStorageDirectory() {
var homeDir = Directory(userHomeDir());
if (!homeDir.existsSync()) {
return null;
@ -133,11 +133,11 @@ class DartdevAnalytics extends AnalyticsImpl {
}
// If there's no explicit setting (enabled or disabled) then we don't send.
return (properties['enabled'] as bool) ?? false;
return (properties['enabled'] as bool?) ?? false;
}
bool get disclosureShownOnTerminal =>
(properties['disclosureShown'] as bool) ?? false;
(properties['disclosureShown'] as bool?) ?? false;
set disclosureShownOnTerminal(bool value) {
properties['disclosureShown'] = value;
@ -171,7 +171,7 @@ class _LoggingAnalytics extends AnalyticsMock {
bool get firstRun => false;
@override
Future sendScreenView(String viewName, {Map<String, String> parameters}) {
Future sendScreenView(String viewName, {Map<String, String>? parameters}) {
parameters ??= <String, String>{};
parameters['viewName'] = viewName;
return _log('screenView', parameters);
@ -179,7 +179,7 @@ class _LoggingAnalytics extends AnalyticsMock {
@override
Future sendEvent(String category, String action,
{String label, int value, Map<String, String> parameters}) {
{String? label, int? value, Map<String, String>? parameters}) {
parameters ??= <String, String>{};
return _log(
'event',
@ -193,7 +193,7 @@ class _LoggingAnalytics extends AnalyticsMock {
@override
Future sendTiming(String variableName, int time,
{String category, String label}) {
{String? category, String? label}) {
return _log('timing', {
'variableName': variableName,
'time': time,

View file

@ -82,12 +82,13 @@ class AnalyzeCommand extends DartdevCommand {
@override
FutureOr<int> run() async {
final args = argResults!;
// Find targets from the 'rest' params.
final List<io.FileSystemEntity> targets = [];
if (argResults.rest.isEmpty) {
if (args.rest.isEmpty) {
targets.add(io.Directory.current);
} else {
for (String targetPath in argResults.rest) {
for (String targetPath in args.rest) {
if (io.Directory(targetPath).existsSync()) {
targets.add(io.Directory(targetPath));
} else if (io.File(targetPath).existsSync()) {
@ -100,8 +101,8 @@ class AnalyzeCommand extends DartdevCommand {
final List<AnalysisError> errors = <AnalysisError>[];
final machineFormat = argResults['format'] == 'machine';
final jsonFormat = argResults['format'] == 'json';
final machineFormat = args['format'] == 'machine';
final jsonFormat = args['format'] == 'json';
final targetsNames =
targets.map((entity) => path.basename(entity.path)).join(', ');
@ -113,9 +114,9 @@ class AnalyzeCommand extends DartdevCommand {
_packagesFile(),
io.Directory(sdk.sdkPath),
targets,
cacheDirectoryPath: argResults['cache'],
cacheDirectoryPath: args['cache'],
commandName: 'analyze',
argResults: argResults,
argResults: args,
);
server.onErrors.listen((FileAnalysisErrors fileErrors) {
@ -160,7 +161,9 @@ class AnalyzeCommand extends DartdevCommand {
emitDefaultFormat(
log,
errors,
relativeToDir: relativeTo is io.File ? relativeTo.parent : relativeTo,
relativeToDir: relativeTo is io.File
? relativeTo.parent
: relativeTo as io.Directory?,
verbose: verbose,
);
}
@ -181,8 +184,8 @@ class AnalyzeCommand extends DartdevCommand {
return 3;
}
bool fatalWarnings = argResults['fatal-warnings'];
bool fatalInfos = argResults['fatal-infos'];
bool fatalWarnings = args['fatal-warnings'];
bool fatalInfos = args['fatal-infos'];
if (fatalWarnings && hasWarnings) {
return 2;
@ -193,8 +196,8 @@ class AnalyzeCommand extends DartdevCommand {
}
}
io.File _packagesFile() {
var path = argResults['packages'];
io.File? _packagesFile() {
var path = argResults!['packages'];
if (path is String) {
var file = io.File(path);
if (!file.existsSync()) {
@ -210,7 +213,7 @@ class AnalyzeCommand extends DartdevCommand {
static void emitDefaultFormat(
Logger log,
List<AnalysisError> errors, {
io.Directory relativeToDir,
io.Directory? relativeToDir,
bool verbose = false,
}) {
final ansi = log.ansi;
@ -220,10 +223,10 @@ class AnalyzeCommand extends DartdevCommand {
final wrapWidth = dartdevUsageLineLength == null
? null
: (dartdevUsageLineLength - _bodyIndentWidth);
: (dartdevUsageLineLength! - _bodyIndentWidth);
for (final AnalysisError error in errors) {
var severity = error.severity.toLowerCase().padLeft(_severityWidth);
var severity = error.severity!.toLowerCase().padLeft(_severityWidth);
if (error.isError) {
severity = ansi.error(severity);
}
@ -231,7 +234,7 @@ class AnalyzeCommand extends DartdevCommand {
var codeRef = error.code;
// If we're in verbose mode, write any error urls instead of error codes.
if (error.url != null && verbose) {
codeRef = error.url;
codeRef = error.url!;
}
// Emit "file:line:col * Error message. Correction (code)."
@ -278,7 +281,7 @@ class AnalyzeCommand extends DartdevCommand {
'range': range,
};
Map<String, dynamic> position(int offset, int line, int column) => {
Map<String, dynamic> position(int? offset, int? line, int? column) => {
'offset': offset,
'line': line,
'column': column,
@ -364,8 +367,8 @@ class AnalyzeCommand extends DartdevCommand {
}
/// Return a relative path if it is a shorter reference than the given dir.
static String _relativePath(String givenPath, io.Directory fromDir) {
String fromPath = fromDir?.absolute?.resolveSymbolicLinksSync();
static String _relativePath(String givenPath, io.Directory? fromDir) {
String? fromPath = fromDir?.absolute.resolveSymbolicLinksSync();
String relative = path.relative(givenPath, from: fromPath);
return relative.length <= givenPath.length ? relative : givenPath;
}

View file

@ -21,14 +21,14 @@ const int compileErrorExitCode = 64;
class Option {
final String flag;
final String help;
final String abbr;
final String defaultsTo;
final List<String> allowed;
final Map<String, String> allowedHelp;
final String? abbr;
final String? defaultsTo;
final List<String>? allowed;
final Map<String, String>? allowedHelp;
Option(
{this.flag,
this.help,
{required this.flag,
required this.help,
this.abbr,
this.defaultsTo,
this.allowed,
@ -71,7 +71,7 @@ class CompileJSCommand extends CompileSubcommandCommand {
@override
final ArgParser argParser = ArgParser.allowAnything();
CompileJSCommand({bool verbose})
CompileJSCommand({bool verbose = false})
: super(cmdName, 'Compile Dart to JavaScript.', verbose);
@override
@ -91,7 +91,7 @@ class CompileJSCommand extends CompileSubcommandCommand {
'--libraries-spec=$librariesPath',
'--cfe-invocation-modes=compile',
'--invoker=dart_cli',
...argResults.arguments,
...argResults!.arguments,
],
packageConfigOverride: null);
@ -109,25 +109,25 @@ class CompileSnapshotCommand extends CompileSubcommandCommand {
final String formatName;
CompileSnapshotCommand({
this.commandName,
this.help,
this.fileExt,
this.formatName,
bool verbose,
required this.commandName,
required this.help,
required this.fileExt,
required this.formatName,
bool verbose = false,
}) : super(commandName, 'Compile Dart $help', verbose) {
argParser
..addOption(
commonOptions['outputFile'].flag,
help: commonOptions['outputFile'].help,
abbr: commonOptions['outputFile'].abbr,
commonOptions['outputFile']!.flag,
help: commonOptions['outputFile']!.help,
abbr: commonOptions['outputFile']!.abbr,
)
..addOption(
commonOptions['verbosity'].flag,
help: commonOptions['verbosity'].help,
abbr: commonOptions['verbosity'].abbr,
defaultsTo: commonOptions['verbosity'].defaultsTo,
allowed: commonOptions['verbosity'].allowed,
allowedHelp: commonOptions['verbosity'].allowedHelp,
commonOptions['verbosity']!.flag,
help: commonOptions['verbosity']!.help,
abbr: commonOptions['verbosity']!.abbr,
defaultsTo: commonOptions['verbosity']!.defaultsTo,
allowed: commonOptions['verbosity']!.allowed,
allowedHelp: commonOptions['verbosity']!.allowedHelp,
);
addExperimentalFlags(argParser, verbose);
@ -146,20 +146,21 @@ class CompileSnapshotCommand extends CompileSubcommandCommand {
@override
FutureOr<int> run() async {
if (argResults.rest.isEmpty) {
final args = argResults!;
if (args.rest.isEmpty) {
// This throws.
usageException('Missing Dart entry point.');
} else if (!isJitSnapshot && argResults.rest.length > 1) {
} else if (!isJitSnapshot && args.rest.length > 1) {
usageException('Unexpected arguments after Dart entry point.');
}
final String sourcePath = argResults.rest[0];
final String sourcePath = args.rest[0];
if (!checkFile(sourcePath)) {
return -1;
}
// Determine output file name.
String outputFile = argResults[commonOptions['outputFile'].flag];
String? outputFile = args[commonOptions['outputFile']!.flag];
if (outputFile == null) {
final inputWithoutDart = sourcePath.endsWith('.dart')
? sourcePath.substring(0, sourcePath.length - 5)
@ -167,31 +168,31 @@ class CompileSnapshotCommand extends CompileSubcommandCommand {
outputFile = '$inputWithoutDart.$fileExt';
}
final enabledExperiments = argResults.enabledExperiments;
final enabledExperiments = args.enabledExperiments;
// Build arguments.
List<String> args = [];
args.add('--snapshot-kind=$formatName');
args.add('--snapshot=${path.canonicalize(outputFile)}');
List<String> buildArgs = [];
buildArgs.add('--snapshot-kind=$formatName');
buildArgs.add('--snapshot=${path.canonicalize(outputFile)}');
String verbosity = argResults[commonOptions['verbosity'].flag];
args.add('--verbosity=$verbosity');
String? verbosity = args[commonOptions['verbosity']!.flag];
buildArgs.add('--verbosity=$verbosity');
if (enabledExperiments.isNotEmpty) {
args.add("--enable-experiment=${enabledExperiments.join(',')}");
buildArgs.add("--enable-experiment=${enabledExperiments.join(',')}");
}
if (verbose) {
args.add('-v');
buildArgs.add('-v');
}
args.add(path.canonicalize(sourcePath));
buildArgs.add(path.canonicalize(sourcePath));
// Add the training arguments.
if (argResults.rest.length > 1) {
args.addAll(argResults.rest.sublist(1));
if (args.rest.length > 1) {
buildArgs.addAll(args.rest.sublist(1));
}
log.stdout('Compiling $sourcePath to $commandName file $outputFile.');
// TODO(bkonyi): perform compilation in same process.
final process = await startDartProcess(sdk, args);
final process = await startDartProcess(sdk, buildArgs);
routeToStdout(process);
return process.exitCode;
}
@ -206,24 +207,24 @@ class CompileNativeCommand extends CompileSubcommandCommand {
final String help;
CompileNativeCommand({
this.commandName,
this.format,
this.help,
bool verbose,
required this.commandName,
required this.format,
required this.help,
bool verbose = false,
}) : super(commandName, 'Compile Dart $help', verbose) {
argParser
..addOption(
commonOptions['outputFile'].flag,
help: commonOptions['outputFile'].help,
abbr: commonOptions['outputFile'].abbr,
commonOptions['outputFile']!.flag,
help: commonOptions['outputFile']!.help,
abbr: commonOptions['outputFile']!.abbr,
)
..addOption(
commonOptions['verbosity'].flag,
help: commonOptions['verbosity'].help,
abbr: commonOptions['verbosity'].abbr,
defaultsTo: commonOptions['verbosity'].defaultsTo,
allowed: commonOptions['verbosity'].allowed,
allowedHelp: commonOptions['verbosity'].allowedHelp,
commonOptions['verbosity']!.flag,
help: commonOptions['verbosity']!.help,
abbr: commonOptions['verbosity']!.abbr,
defaultsTo: commonOptions['verbosity']!.defaultsTo,
allowed: commonOptions['verbosity']!.allowed,
allowedHelp: commonOptions['verbosity']!.allowedHelp,
)
..addMultiOption('define', abbr: 'D', valueHelp: 'key=value', help: '''
Define an environment declaration. To specify multiple declarations, use multiple options or use commas to separate key-value pairs.
@ -269,13 +270,14 @@ Remove debugging information from the output and save it separately to the speci
"'dart compile $format' is not supported on x86 architectures");
return 64;
}
final args = argResults!;
// We expect a single rest argument; the dart entry point.
if (argResults.rest.length != 1) {
if (args.rest.length != 1) {
// This throws.
usageException('Missing Dart entry point.');
}
final String sourcePath = argResults.rest[0];
final String sourcePath = args.rest[0];
if (!checkFile(sourcePath)) {
return -1;
}
@ -284,16 +286,16 @@ Remove debugging information from the output and save it separately to the speci
await generateNative(
kind: format,
sourceFile: sourcePath,
outputFile: argResults['output'],
defines: argResults['define'],
packages: argResults['packages'],
enableAsserts: argResults['enable-asserts'],
enableExperiment: argResults.enabledExperiments.join(','),
soundNullSafety: argResults['sound-null-safety'],
debugFile: argResults['save-debugging-info'],
outputFile: args['output'],
defines: args['define'],
packages: args['packages'],
enableAsserts: args['enable-asserts'],
enableExperiment: args.enabledExperiments.join(','),
soundNullSafety: args['sound-null-safety'],
debugFile: args['save-debugging-info'],
verbose: verbose,
verbosity: argResults['verbosity'],
extraOptions: argResults['extra-gen-snapshot-options'],
verbosity: args['verbosity'],
extraOptions: args['extra-gen-snapshot-options'],
);
return 0;
} catch (e) {

View file

@ -54,22 +54,23 @@ class CreateCommand extends DartdevCommand {
@override
FutureOr<int> run() async {
if (argResults['list-templates']) {
final args = argResults!;
if (args['list-templates']) {
log.stdout(_availableTemplatesJson());
return 0;
}
if (argResults.rest.isEmpty) {
if (args.rest.isEmpty) {
printUsage();
return 1;
}
String templateId = argResults['template'];
String templateId = args['template'];
String dir = argResults.rest.first;
String dir = args.rest.first;
var targetDir = io.Directory(dir).absolute;
dir = targetDir.path;
if (targetDir.existsSync() && !argResults['force']) {
if (targetDir.existsSync() && !args['force']) {
log.stderr(
"Directory '$dir' already exists "
"(use '--force' to force project generation).",
@ -95,13 +96,13 @@ class CreateCommand extends DartdevCommand {
);
log.stdout('');
var generator = getGenerator(templateId);
var generator = getGenerator(templateId)!;
generator.generate(
projectName,
DirectoryGeneratorTarget(generator, io.Directory(dir)),
);
if (argResults['pub']) {
if (args['pub']) {
log.stdout('');
var progress = log.progress('Running pub get');
var process = await startDartProcess(
@ -137,7 +138,7 @@ class CreateCommand extends DartdevCommand {
log.stdout('');
log.stdout(generator.getInstallInstructions(
dir,
projectName,
scriptPath: projectName,
));
log.stdout('');
@ -164,7 +165,7 @@ class CreateCommand extends DartdevCommand {
};
if (generator.entrypoint != null) {
m['entrypoint'] = generator.entrypoint.path;
m['entrypoint'] = generator.entrypoint!.path;
}
return m;

View file

@ -53,7 +53,7 @@ class DebugAdapterCommand extends DartdevCommand {
@override
FutureOr<int> run() async {
final args = argResults;
final args = argResults!;
final ipv6 = args[argIpv6] as bool;
final server = DapServer(

View file

@ -140,7 +140,7 @@ class DevToolsCommand extends DartdevCommand {
hide: !verbose,
);
// Deprecated and hidden argResults.
// Deprecated and hidden args.
// TODO: Remove this - prefer that clients use the rest arg.
argParser
..addOption(
@ -150,7 +150,7 @@ class DevToolsCommand extends DartdevCommand {
hide: true,
)
// Development only argResults.
// Development only args.
..addFlag(
argDebugMode,
negatable: false,
@ -159,7 +159,7 @@ class DevToolsCommand extends DartdevCommand {
);
}
final String customDevToolsPath;
final String? customDevToolsPath;
@override
String get name => 'devtools';
@ -172,32 +172,30 @@ class DevToolsCommand extends DartdevCommand {
@override
Future<int> run() async {
final bool version = argResults[argVersion];
final bool machineMode = argResults[argMachine];
final args = argResults!;
final bool version = args[argVersion];
final bool machineMode = args[argMachine];
// launchBrowser defaults based on machine-mode if not explicitly supplied.
final bool launchBrowser = argResults.wasParsed(argLaunchBrowser)
? argResults[argLaunchBrowser]
final bool launchBrowser = args.wasParsed(argLaunchBrowser)
? args[argLaunchBrowser]
: !machineMode;
final bool enableNotifications = argResults[argEnableNotifications];
final bool allowEmbedding = argResults.wasParsed(argAllowEmbedding)
? argResults[argAllowEmbedding]
: true;
final bool enableNotifications = args[argEnableNotifications];
final bool allowEmbedding =
args.wasParsed(argAllowEmbedding) ? args[argAllowEmbedding] : true;
final port = argResults[argPort] != null
? int.tryParse(argResults[argPort]) ?? 0
: 0;
final port = args[argPort] != null ? int.tryParse(args[argPort]) ?? 0 : 0;
final bool headlessMode = argResults[argHeadlessMode];
final bool debugMode = argResults[argDebugMode];
final bool headlessMode = args[argHeadlessMode];
final bool debugMode = args[argDebugMode];
final numPortsToTry = argResults[argTryPorts] != null
? int.tryParse(argResults[argTryPorts]) ?? 0
final numPortsToTry = args[argTryPorts] != null
? int.tryParse(args[argTryPorts]) ?? 0
: DevToolsServer.defaultTryPorts;
final bool verboseMode = argResults[argVerbose];
final String hostname = argResults[argHost];
final String appSizeBase = argResults[argAppSizeBase];
final String appSizeTest = argResults[argAppSizeTest];
final bool verboseMode = args[argVerbose];
final String? hostname = args[argHost];
final String? appSizeBase = args[argAppSizeBase];
final String? appSizeTest = args[argAppSizeTest];
final sdkDir = path.dirname(sdk.dart);
final fullSdk = sdkDir.endsWith('bin');
@ -213,22 +211,22 @@ class DevToolsCommand extends DartdevCommand {
},
machineMode: machineMode,
);
return null;
return 0;
}
// Prefer getting the VM URI from the rest argResults; fall back on the 'vm-url'
// Prefer getting the VM URI from the rest args; fall back on the 'vm-url'
// option otherwise.
String serviceProtocolUri;
if (argResults.rest.isNotEmpty) {
serviceProtocolUri = argResults.rest.first;
} else if (argResults.wasParsed(argVmUri)) {
serviceProtocolUri = argResults[argVmUri];
String? serviceProtocolUri;
if (args.rest.isNotEmpty) {
serviceProtocolUri = args.rest.first;
} else if (args.wasParsed(argVmUri)) {
serviceProtocolUri = args[argVmUri];
}
// Support collecting profile data.
String profileFilename;
if (argResults.wasParsed(argProfileMemory)) {
profileFilename = argResults[argProfileMemory];
String? profileFilename;
if (args.wasParsed(argProfileMemory)) {
profileFilename = args[argProfileMemory];
}
if (profileFilename != null && !path.isAbsolute(profileFilename)) {
profileFilename = path.absolute(profileFilename);

View file

@ -59,18 +59,19 @@ For additional documentation generation options, see the 'dartdoc_options.yaml'
@override
FutureOr<int> run() async {
final options = <String>[];
final args = argResults!;
if (argResults['sdk-docs']) {
if (args['sdk-docs']) {
options.add('--sdk-docs');
} else {
// At least one argument, the input directory, is required,
// when we're not generating docs for the Dart SDK.
if (argResults.rest.isEmpty) {
if (args.rest.isEmpty) {
usageException("Error: Input directory not specified");
}
// Determine input directory.
final dir = io.Directory(argResults.rest[0]);
final dir = io.Directory(args.rest[0]);
if (!dir.existsSync()) {
usageException("Error: Input directory doesn't exist: ${dir.path}");
}
@ -83,10 +84,10 @@ For additional documentation generation options, see the 'dartdoc_options.yaml'
// Build remaining options.
options.addAll([
'--output=${argResults['output']}',
'--output=${args['output']}',
'--resources-dir=$resourcesPath',
if (argResults['validate-links']) '--validate-links',
if (argResults['dry-run']) '--no-generate-docs',
if (args['validate-links']) '--validate-links',
if (args['dry-run']) '--no-generate-docs',
if (verbose) '--no-quiet',
]);

View file

@ -6,7 +6,7 @@ import 'dart:async';
import 'dart:io' as io;
import 'package:analysis_server_client/protocol.dart' hide AnalysisError;
import 'package:meta/meta.dart';
import 'package:cli_util/cli_logging.dart' show Progress;
import 'package:path/path.dart' as path;
import '../analysis_server.dart';
@ -54,7 +54,7 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
@override
String get description {
if (log != null && log.ansi.useAnsi) {
if (log.ansi.useAnsi) {
return cmdDescription
.replaceAll('[', log.ansi.bold)
.replaceAll(']', log.ansi.none);
@ -65,15 +65,16 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
@override
FutureOr<int> run() async {
var dryRun = argResults['dry-run'];
var inTestMode = argResults['compare-to-golden'];
var apply = argResults['apply'];
final args = argResults!;
var dryRun = args['dry-run'];
var inTestMode = args['compare-to-golden'];
var apply = args['apply'];
if (!apply && !dryRun && !inTestMode) {
printUsage();
return 0;
}
var arguments = argResults.rest;
var arguments = args.rest;
var argumentCount = arguments.length;
if (argumentCount > 1) {
usageException('Only one file or directory is expected.');
@ -90,7 +91,7 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
var modeText = dryRun ? ' (dry run)' : '';
final projectName = path.basename(dirPath);
var computeFixesProgress = log.progress(
Progress? computeFixesProgress = log.progress(
'Computing fixes in ${log.ansi.emphasized(projectName)}$modeText');
var server = AnalysisServer(
@ -131,7 +132,7 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
await server.shutdown();
if (computeFixesProgress != null) {
computeFixesProgress.finish(showTiming: true);
computeFixesProgress!.finish(showTiming: true);
computeFixesProgress = null;
}
@ -145,7 +146,8 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
var fileCount = detailsMap.length;
var fixCount = detailsMap.values
.expand((detail) => detail.fixes)
.fold(0, (previousValue, fixes) => previousValue + fixes.occurrences);
.fold<int>(0,
(int previousValue, fixes) => previousValue + fixes.occurrences);
if (dryRun) {
log.stdout('');
@ -221,7 +223,7 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
var actualIsOriginal = !fileContentCache.containsKey(filePath);
var actualCode = actualIsOriginal
? originalFile.readAsStringSync()
: fileContentCache[filePath];
: fileContentCache[filePath]!;
// Use a whitespace insensitive comparison.
if (_compressWhitespace(actualCode) !=
_compressWhitespace(expectedCode)) {
@ -305,7 +307,7 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
modifiedFilePaths
.sort((first, second) => relative(first).compareTo(relative(second)));
for (var filePath in modifiedFilePaths) {
var detail = detailsMap[filePath];
var detail = detailsMap[filePath]!;
log.stdout(relative(detail.path));
final fixes = detail.fixes.toList();
fixes.sort((a, b) => a.code.compareTo(b.code));
@ -320,7 +322,7 @@ To use the tool, run either ['dart fix --dry-run'] for a preview of the proposed
/// Report that the [actualCode] produced by applying fixes to the content of
/// [filePath] did not match the [expectedCode].
void _reportFailure(String filePath, String actualCode, String expectedCode,
{@required bool actualIsOriginal}) {
{required bool actualIsOriginal}) {
log.stdout('Failed when applying fixes to $filePath');
log.stdout('Expected:');
log.stdout(expectedCode);

View file

@ -40,7 +40,7 @@ For more information about the server's capabilities and configuration, see:
Future<int> run() async {
final driver = server_driver.Driver();
driver.start(
argResults.arguments,
argResults!.arguments,
defaultToLsp: true,
);

View file

@ -34,7 +34,7 @@ class MigrateCommand extends DartdevCommand {
FutureOr<int> run() async {
var cli = MigrationCli(binaryName: 'dart $name');
try {
await cli.decodeCommandLineArgs(argResults, isVerbose: verbose)?.run();
await cli.decodeCommandLineArgs(argResults!, isVerbose: verbose)?.run();
} on MigrationExit catch (migrationExit) {
return migrationExit.exitCode;
}

View file

@ -196,22 +196,22 @@ class RunCommand extends DartdevCommand {
@override
FutureOr<int> run() async {
final args = argResults!;
var mainCommand = '';
var runArgs = <String>[];
if (argResults.rest.isNotEmpty) {
mainCommand = argResults.rest.first;
if (args.rest.isNotEmpty) {
mainCommand = args.rest.first;
// The command line arguments after the command name.
runArgs = argResults.rest.skip(1).toList();
runArgs = args.rest.skip(1).toList();
}
if (!isProductMode) {
// --launch-dds is provided by the VM if the VM service is to be enabled. In
// that case, we need to launch DDS as well.
String launchDdsArg = argResults['launch-dds'];
String? launchDdsArg = args['launch-dds'];
String ddsHost = '';
String ddsPort = '';
bool launchDevTools = argResults['serve-devtools'];
bool launchDevTools = args['serve-devtools'] ?? false;
bool launchDds = false;
if (launchDdsArg != null) {
launchDds = true;
@ -219,9 +219,9 @@ class RunCommand extends DartdevCommand {
ddsHost = ddsUrl[0];
ddsPort = ddsUrl[1];
}
final bool debugDds = argResults['debug-dds'];
final bool debugDds = args['debug-dds'];
bool disableServiceAuthCodes = argResults['disable-service-auth-codes'];
bool disableServiceAuthCodes = args['disable-service-auth-codes'];
// If the user wants to start a debugging session we need to do some extra
// work and spawn a Dart Development Service (DDS) instance. DDS is a VM
@ -310,7 +310,7 @@ class _DebuggingSession {
const devToolsMessagePrefix =
'The Dart DevTools debugger and profiler is available at:';
if (debugDds) {
StreamSubscription stdoutSub;
late StreamSubscription stdoutSub;
stdoutSub = process.stdout.transform(utf8.decoder).listen((event) {
if (event.startsWith(devToolsMessagePrefix)) {
final ddsDebuggingUri = event.split(' ').last;
@ -321,7 +321,7 @@ class _DebuggingSession {
}
});
}
StreamSubscription stderrSub;
late StreamSubscription stderrSub;
stderrSub = process.stderr.transform(utf8.decoder).listen((event) {
final result = json.decode(event) as Map<String, dynamic>;
final state = result['state'];

View file

@ -28,11 +28,12 @@ class TestCommand extends DartdevCommand {
@override
FutureOr<int> run() async {
final args = argResults!;
try {
final testExecutable = await getExecutableForCommand('test:test');
log.trace('dart $testExecutable ${argResults.rest.join(' ')}');
VmInteropHandler.run(testExecutable.executable, argResults.rest,
packageConfigOverride: testExecutable.packageConfig);
log.trace('dart $testExecutable ${args.rest.join(' ')}');
VmInteropHandler.run(testExecutable.executable, args.rest,
packageConfigOverride: testExecutable.packageConfig!);
return 0;
} on CommandResolutionFailedException catch (e) {
if (project.hasPubspecFile) {
@ -45,8 +46,7 @@ class TestCommand extends DartdevCommand {
print(
'No pubspec.yaml file found - run this command in your project folder.');
}
if (argResults.rest.contains('-h') ||
argResults.rest.contains('--help')) {
if (args.rest.contains('-h') || args.rest.contains('--help')) {
print('');
printUsage();
}

View file

@ -15,19 +15,19 @@ import 'experiments.dart';
import 'sdk.dart';
import 'utils.dart';
Logger log;
late Logger log;
bool isDiagnostics = false;
/// When set, this function is executed from the [DartdevCommand] constructor to
/// contribute additional flags.
void Function(ArgParser argParser, String cmdName) flagContributor;
void Function(ArgParser argParser, String cmdName)? flagContributor;
abstract class DartdevCommand extends Command<int> {
final String _name;
final String _description;
final bool _verbose;
Project _project;
Project? _project;
@override
final bool hidden;
@ -43,7 +43,7 @@ abstract class DartdevCommand extends Command<int> {
@override
String get description => _description;
ArgParser _argParser;
ArgParser? _argParser;
@override
ArgParser get argParser => _argParser ??= createArgParser();
@ -70,16 +70,16 @@ abstract class DartdevCommand extends Command<int> {
extension DartDevCommand on Command {
/// Return whether commands should emit verbose output.
bool get verbose => globalResults['verbose'];
bool get verbose => globalResults!['verbose'];
/// Return whether the tool should emit diagnostic output.
bool get diagnosticsEnabled => globalResults['diagnostics'];
bool get diagnosticsEnabled => globalResults!['diagnostics'];
/// Return whether any Dart experiments were specified by the user.
bool get wereExperimentsSpecified =>
globalResults?.wasParsed(experimentFlagName) ?? false;
List<String> get specifiedExperiments => globalResults[experimentFlagName];
List<String> get specifiedExperiments => globalResults![experimentFlagName];
}
/// A utility method to start a Dart VM instance with the given arguments and an
@ -89,7 +89,7 @@ extension DartDevCommand on Command {
Future<Process> startDartProcess(
Sdk sdk,
List<String> arguments, {
String cwd,
String? cwd,
}) {
log.trace('${sdk.dart} ${arguments.join(' ')}');
return Process.start(sdk.dart, arguments, workingDirectory: cwd);
@ -98,7 +98,7 @@ Future<Process> startDartProcess(
void routeToStdout(
Process process, {
bool logToTrace = false,
void Function(String str) listener,
void Function(String str)? listener,
}) {
if (isDiagnostics) {
_streamLineTransform(process.stdout, (String line) {
@ -136,7 +136,7 @@ void _streamLineTransform(
class Project {
final Directory dir;
PackageConfig _packageConfig;
PackageConfig? _packageConfig;
Project() : dir = Directory.current;
@ -147,7 +147,7 @@ class Project {
bool get hasPackageConfigFile => packageConfig != null;
PackageConfig get packageConfig {
PackageConfig? get packageConfig {
if (_packageConfig == null) {
File file =
File(path.join(dir.path, '.dart_tool', 'package_config.json'));
@ -170,11 +170,11 @@ class PackageConfig {
PackageConfig(this.contents);
List<Map<String, dynamic>> get packages {
List<Map<String, dynamic>?> get packages {
List<dynamic> _packages = contents['packages'];
return _packages.map<Map<String, dynamic>>(castStringKeyedMap).toList();
return _packages.map<Map<String, dynamic>?>(castStringKeyedMap).toList();
}
bool hasDependency(String packageName) =>
packages.any((element) => element['name'] == packageName);
packages.any((element) => element!['name'] == packageName);
}

View file

@ -2,7 +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.
import 'package:meta/meta.dart';
import 'package:usage/usage.dart';
/// The [String] identifier `dartdev`, used as the category in the events sent
@ -54,17 +53,16 @@ Map<String, String> _useCdKeys(Map<_CustomDimensions, String> parameters) {
Future<void> sendUsageEvent(
Analytics analytics,
String action, {
String label,
List<String> specifiedExperiments,
@required int exitCode,
@required List<String> commandFlags,
String? label,
List<String>? specifiedExperiments,
required int? exitCode,
required List<String> commandFlags,
}) {
/// The category stores the name of this cli tool, 'dartdev'. This matches the
/// pattern from the flutter cli tool which always passes 'flutter' as the
/// category.
final category = _dartdev;
commandFlags =
commandFlags?.where((e) => e != 'enable-experiment')?.toList() ?? [];
commandFlags = commandFlags.where((e) => e != 'enable-experiment').toList();
specifiedExperiments = specifiedExperiments?.toList() ?? [];
// Sort the flag lists to slightly reduce the explosion of possibilities.

View file

@ -4,6 +4,7 @@
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:args/args.dart';
import 'package:collection/collection.dart' show IterableExtension;
const experimentFlagName = 'enable-experiment';
@ -53,9 +54,8 @@ extension EnabledExperimentsArg on ArgResults {
// look for --enable-experiment=. Currently, this path is only taken for
// the pub and test commands, as well as when we are trying to send
// analytics.
final String experiments = arguments.firstWhere(
final String? experiments = arguments.firstWhereOrNull(
(e) => e.startsWith('--enable-experiment='),
orElse: () => null,
);
if (experiments == null) {
return [];

View file

@ -108,7 +108,7 @@ class Runtime {
/// The SDK's release channel (`be`, `dev`, `beta`, `stable`).
///
/// May be null if [Platform.version] does not have the expected format.
final String /*?*/ channel;
final String? channel;
Runtime._(this.version, this.channel);
@ -116,7 +116,7 @@ class Runtime {
var versionString = Platform.version;
// Exepcted format: "version (channel) ..."
var version = versionString;
String /*?*/ channel;
String? channel;
var versionEnd = versionString.indexOf(' ');
if (versionEnd > 0) {
version = versionString.substring(0, versionEnd);

View file

@ -4,6 +4,7 @@
import 'dart:convert' show utf8;
import 'package:collection/collection.dart' show IterableExtension;
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;
@ -24,8 +25,8 @@ final List<Generator> generators = [
WebSimpleGenerator(),
];
Generator getGenerator(String id) =>
generators.firstWhere((g) => g.id == id, orElse: () => null);
Generator? getGenerator(String id) =>
generators.firstWhereOrNull((g) => g.id == id);
/// An abstract class which both defines a template generator and can generate a
/// user project based on this template.
@ -36,12 +37,12 @@ abstract class Generator implements Comparable<Generator> {
final List<String> categories;
final List<TemplateFile> files = [];
TemplateFile _entrypoint;
TemplateFile? _entrypoint;
/// Lazily initialized cache for lower-case if [id].
///
/// Used by [compareTo].
String /*?*/ _lowerCaseId;
String? _lowerCaseId;
Generator(
this.id,
@ -54,7 +55,7 @@ abstract class Generator implements Comparable<Generator> {
/// The entrypoint of the application; the main file for the project, which an
/// IDE might open after creating the project.
TemplateFile get entrypoint => _entrypoint;
TemplateFile? get entrypoint => _entrypoint;
TemplateFile addFile(String path, String contents) {
return addTemplateFile(TemplateFile(path, contents));
@ -67,22 +68,21 @@ abstract class Generator implements Comparable<Generator> {
}
/// Return the template file wih the given [path].
TemplateFile getFile(String path) =>
files.firstWhere((file) => file.path == path, orElse: () => null);
TemplateFile? getFile(String path) =>
files.firstWhereOrNull((file) => file.path == path);
/// Set the main entrypoint of this template. This is the 'most important'
/// file of this template. An IDE might use this information to open this file
/// after the user's project is generated.
void setEntrypoint(TemplateFile entrypoint) {
if (_entrypoint != null) throw StateError('entrypoint already set');
if (entrypoint == null) throw StateError('entrypoint is null');
_entrypoint = entrypoint;
}
void generate(
String projectName,
GeneratorTarget target, {
Map<String, String> additionalVars,
Map<String, String>? additionalVars,
}) {
final vars = {
'projectName': projectName,
@ -111,9 +111,9 @@ abstract class Generator implements Comparable<Generator> {
/// (e.g., bin/foo.dart) **without** an extension. If null, the implicit run
/// command will be output by default (e.g., dart run).
String getInstallInstructions(
String directory,
String scriptPath,
) {
String directory, {
String? scriptPath,
}) {
final buffer = StringBuffer();
buffer.writeln(' cd ${p.relative(directory)}');
if (scriptPath != null) {
@ -208,5 +208,5 @@ String substituteVars(String str, Map<String, String> vars) {
}
return str.replaceAllMapped(
_substituteRegExp, (match) => vars[match[1]] ?? match[0]);
_substituteRegExp, (match) => vars[match[1]!] ?? match[0]!);
}

View file

@ -25,10 +25,10 @@ class ConsoleFullGenerator extends DefaultGenerator {
@override
String getInstallInstructions(
String directory,
String scriptPath,
) =>
super.getInstallInstructions(directory, null);
String directory, {
String? scriptPath,
}) =>
super.getInstallInstructions(directory);
}
final String _pubspec = '''

View file

@ -17,16 +17,16 @@ class ConsoleSimpleGenerator extends DefaultGenerator {
addFile('pubspec.yaml', _pubspec);
addFile('README.md', _readme);
setEntrypoint(
addFile('bin/__projectName__.dart', main),
addFile('bin/__projectName__.dart', mainSrc),
);
}
@override
String getInstallInstructions(
String directory,
String scriptPath,
) =>
super.getInstallInstructions(directory, null);
String directory, {
String? scriptPath,
}) =>
super.getInstallInstructions(directory);
}
final String _pubspec = '''
@ -49,7 +49,7 @@ final String _readme = '''
A simple command-line application.
''';
final String main = '''
final String mainSrc = '''
void main(List<String> arguments) {
print('Hello world!');
}

View file

@ -26,12 +26,12 @@ class PackageSimpleGenerator extends DefaultGenerator {
@override
String getInstallInstructions(
String directory,
String scriptPath,
) =>
String directory, {
String? scriptPath,
}) =>
super.getInstallInstructions(
directory,
'example/${scriptPath}_example',
scriptPath: 'example/${scriptPath}_example',
);
}

View file

@ -26,12 +26,12 @@ class ServerShelfGenerator extends DefaultGenerator {
@override
String getInstallInstructions(
String directory,
String scriptPath,
) =>
String directory, {
String? scriptPath,
}) =>
super.getInstallInstructions(
directory,
'bin/server',
scriptPath: 'bin/server',
);
}

View file

@ -27,9 +27,9 @@ class WebSimpleGenerator extends DefaultGenerator {
@override
String getInstallInstructions(
String directory,
String scriptPath,
) =>
String directory, {
String? scriptPath,
}) =>
' cd ${p.relative(directory)}\n'
' dart pub global activate webdev\n'
' webdev serve';

View file

@ -8,14 +8,14 @@ import 'package:path/path.dart' as p;
/// For commands where we are able to initialize the [ArgParser], this value
/// is used as the usageLineLength.
int get dartdevUsageLineLength =>
int? get dartdevUsageLineLength =>
stdout.hasTerminal ? stdout.terminalColumns : null;
/// Given a data structure which is a Map of String to dynamic values, return
/// the same structure (`Map<String, dynamic>`) with the correct runtime types.
Map<String, dynamic> castStringKeyedMap(dynamic untyped) {
final Map<dynamic, dynamic> map = untyped as Map<dynamic, dynamic>;
return map?.cast<String, dynamic>();
final Map<dynamic, dynamic> map = untyped! as Map<dynamic, dynamic>;
return map.cast<String, dynamic>();
}
/// Emit the given word with the correct pluralization.
@ -31,7 +31,7 @@ String relativePath(String filePath, Directory dir) {
}
/// String utility to trim some suffix from the end of a [String].
String trimEnd(String s, String suffix) {
String? trimEnd(String? s, String? suffix) {
if (s != null && suffix != null && suffix.isNotEmpty && s.endsWith(suffix)) {
return s.substring(0, s.length - suffix.length);
}
@ -45,7 +45,7 @@ extension FileSystemEntityExtension on FileSystemEntity {
}
/// Wraps [text] to the given [width], if provided.
String wrapText(String text, {int width}) {
String wrapText(String text, {int? width}) {
if (width == null) {
return text;
}

View file

@ -4,13 +4,11 @@
import 'dart:isolate';
import 'package:meta/meta.dart';
/// Contains methods used to communicate DartDev results back to the VM.
abstract class VmInteropHandler {
/// Initializes [VmInteropHandler] to utilize [port] to communicate with the
/// VM.
static void initialize(SendPort port) => _port = port;
static void initialize(SendPort? port) => _port = port;
/// Notifies the VM to run [script] with [args] upon DartDev exit.
///
@ -18,10 +16,10 @@ abstract class VmInteropHandler {
static void run(
String script,
List<String> args, {
@required String packageConfigOverride,
String? packageConfigOverride,
}) {
assert(_port != null);
if (_port == null) return;
final port = _port;
if (port == null) return;
final message = <dynamic>[
_kResultRun,
script,
@ -29,21 +27,21 @@ abstract class VmInteropHandler {
// Copy the list so it doesn't get GC'd underneath us.
args.toList()
];
_port.send(message);
port.send(message);
}
/// Notifies the VM that DartDev has completed running. If provided a
/// non-zero [exitCode], the VM will terminate with the given exit code.
static void exit(int exitCode) {
assert(_port != null);
if (_port == null) return;
static void exit(int? exitCode) {
final port = _port;
if (port == null) return;
final message = <dynamic>[_kResultExit, exitCode];
_port.send(message);
port.send(message);
}
// Note: keep in sync with runtime/bin/dartdev_isolate.h
static const int _kResultRun = 1;
static const int _kResultExit = 2;
static SendPort _port;
static SendPort? _port;
}

View file

@ -4,7 +4,7 @@ name: dartdev
publish_to: none
environment:
sdk: '>=2.6.0 <3.0.0'
sdk: '>=2.12.0 <3.0.0'
dependencies:
analysis_server:
path: ../analysis_server
@ -14,6 +14,7 @@ dependencies:
path: ../analyzer
args: any
cli_util: any
collection: any
dart2native:
path: ../dart2native
dart_style: any

View file

@ -14,14 +14,14 @@ import 'utils.dart';
void main() {
group('AnalysisServer', () {
TestProject p;
late TestProject p;
setUp(() {
log = Logger.standard();
p = project();
});
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('can start', () async {
AnalysisServer server = AnalysisServer(

View file

@ -172,7 +172,7 @@ void defineAnalysisError() {
}
void defineAnalyze() {
TestProject p;
TestProject? p;
setUp(() => p = null);
@ -180,7 +180,7 @@ void defineAnalyze() {
test('--help', () async {
p = project();
var result = await p.run(['analyze', '--help']);
var result = await p!.run(['analyze', '--help']);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -190,7 +190,7 @@ void defineAnalyze() {
test('--help --verbose', () async {
p = project();
var result = await p.run(['analyze', '--help', '--verbose']);
var result = await p!.run(['analyze', '--help', '--verbose']);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -199,14 +199,15 @@ void defineAnalyze() {
});
group('multiple items', () {
TestProject secondProject;
late TestProject secondProject;
tearDown(() async => await secondProject?.dispose());
tearDown(() async => await secondProject.dispose());
test('folder and file', () async {
p = project(mainSrc: "int get foo => 'str';\n");
secondProject = project(mainSrc: "int get foo => 'str';\n");
var result = await p.run(['analyze', p.dirPath, secondProject.mainPath]);
var result =
await p!.run(['analyze', p!.dirPath, secondProject.mainPath]);
expect(result.exitCode, 3);
expect(result.stderr, isEmpty);
@ -219,7 +220,7 @@ void defineAnalyze() {
test('two folders', () async {
p = project(mainSrc: "int get foo => 'str';\n");
secondProject = project(mainSrc: "int get foo => 'str';\n");
var result = await p.run(['analyze', p.dirPath, secondProject.dirPath]);
var result = await p!.run(['analyze', p!.dirPath, secondProject.dirPath]);
expect(result.exitCode, 3);
expect(result.stderr, isEmpty);
@ -232,7 +233,7 @@ void defineAnalyze() {
test('no such directory', () async {
p = project();
var result = await p.run(['analyze', '/no/such/dir1/']);
var result = await p!.run(['analyze', '/no/such/dir1/']);
expect(result.exitCode, 64);
expect(result.stdout, isEmpty);
@ -244,7 +245,7 @@ void defineAnalyze() {
test('current working directory', () async {
p = project(mainSrc: 'int get foo => 1;\n');
var result = await p.run(['analyze'], workingDir: p.dirPath);
var result = await p!.run(['analyze'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -254,7 +255,7 @@ void defineAnalyze() {
group('single directory', () {
test('no errors', () async {
p = project(mainSrc: 'int get foo => 1;\n');
var result = await p.run(['analyze', p.dirPath]);
var result = await p!.run(['analyze', p!.dirPath]);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -263,7 +264,7 @@ void defineAnalyze() {
test('one error', () async {
p = project(mainSrc: "int get foo => 'str';\n");
var result = await p.run(['analyze', p.dirPath]);
var result = await p!.run(['analyze', p!.dirPath]);
expect(result.exitCode, 3);
expect(result.stderr, isEmpty);
@ -275,7 +276,7 @@ void defineAnalyze() {
test('two errors', () async {
p = project(mainSrc: "int get foo => 'str';\nint get bar => 'str';\n");
var result = await p.run(['analyze', p.dirPath]);
var result = await p!.run(['analyze', p!.dirPath]);
expect(result.exitCode, 3);
expect(result.stderr, isEmpty);
@ -286,7 +287,7 @@ void defineAnalyze() {
group('single file', () {
test('no errors', () async {
p = project(mainSrc: 'int get foo => 1;\n');
var result = await p.run(['analyze', p.mainPath]);
var result = await p!.run(['analyze', p!.mainPath]);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -295,7 +296,7 @@ void defineAnalyze() {
test('one error', () async {
p = project(mainSrc: "int get foo => 'str';\n");
var result = await p.run(['analyze', p.mainPath]);
var result = await p!.run(['analyze', p!.mainPath]);
expect(result.exitCode, 3);
expect(result.stderr, isEmpty);
@ -310,7 +311,7 @@ void defineAnalyze() {
p = project(
mainSrc: _unusedImportCodeSnippet,
analysisOptions: _unusedImportAnalysisOptions);
var result = await p.run(['analyze', '--fatal-warnings', p.dirPath]);
var result = await p!.run(['analyze', '--fatal-warnings', p!.dirPath]);
expect(result.exitCode, equals(2));
expect(result.stderr, isEmpty);
@ -321,7 +322,7 @@ void defineAnalyze() {
p = project(
mainSrc: _unusedImportCodeSnippet,
analysisOptions: _unusedImportAnalysisOptions);
var result = await p.run(['analyze', p.dirPath]);
var result = await p!.run(['analyze', p!.dirPath]);
expect(result.exitCode, equals(2));
expect(result.stderr, isEmpty);
@ -332,7 +333,7 @@ void defineAnalyze() {
p = project(
mainSrc: _unusedImportCodeSnippet,
analysisOptions: _unusedImportAnalysisOptions);
var result = await p.run(['analyze', '--no-fatal-warnings', p.dirPath]);
var result = await p!.run(['analyze', '--no-fatal-warnings', p!.dirPath]);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -341,7 +342,7 @@ void defineAnalyze() {
test('info implicit no --fatal-infos', () async {
p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
var result = await p.run(['analyze', p.dirPath]);
var result = await p!.run(['analyze', p!.dirPath]);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -350,7 +351,7 @@ void defineAnalyze() {
test('info --fatal-infos', () async {
p = project(mainSrc: dartVersionFilePrefix2_9 + 'String foo() {}');
var result = await p.run(['analyze', '--fatal-infos', p.dirPath]);
var result = await p!.run(['analyze', '--fatal-infos', p!.dirPath]);
expect(result.exitCode, 1);
expect(result.stderr, isEmpty);
@ -364,7 +365,7 @@ int f() {
var one = 1;
return result;
}''');
var result = await p.run(['analyze', '--verbose', p.dirPath]);
var result = await p!.run(['analyze', '--verbose', p!.dirPath]);
expect(result.exitCode, 3);
expect(result.stderr, isEmpty);
@ -386,7 +387,7 @@ import 'package:foo/foo.dart';
void f() {
my_foo;
}''');
p.file('my_packages.json', '''
p!.file('my_packages.json', '''
{
"configVersion": 2,
"packages": [
@ -399,10 +400,10 @@ void f() {
]
}
''');
var result = await p.run([
var result = await p!.run([
'analyze',
'--packages=${p.findFile('my_packages.json').path}',
p.dirPath,
'--packages=${p!.findFile('my_packages.json')!.path}',
p!.dirPath,
]);
expect(result.exitCode, 0);
@ -412,10 +413,10 @@ void f() {
test('not existing', () async {
p = project();
var result = await p.run([
var result = await p!.run([
'analyze',
'--packages=no.such.file',
p.dirPath,
p!.dirPath,
]);
expect(result.exitCode, 64);
@ -428,10 +429,10 @@ void f() {
var cache = project(name: 'cache');
p = project(mainSrc: 'var v = 0;');
var result = await p.run([
var result = await p!.run([
'analyze',
'--cache=${cache.dirPath}',
p.mainPath,
p!.mainPath,
]);
expect(result.exitCode, 0);

View file

@ -468,7 +468,7 @@ void main() {}
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
expect(File(outFile).existsSync(), true,
@ -497,7 +497,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
}, skip: isRunningOnIA32);
@ -566,7 +566,7 @@ void main() {}
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
expect(File(outFile).existsSync(), true,
@ -595,7 +595,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
});
@ -664,7 +664,7 @@ void main() {}
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
expect(File(outFile).existsSync(), true,
@ -693,7 +693,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
}, skip: isRunningOnIA32);
@ -720,7 +720,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stdout, contains('Warning: '));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
@ -747,7 +747,8 @@ void main() {
expect(
result.stderr,
predicate(
(o) => '$o'.contains('Unexpected arguments after Dart entry point.'),
(dynamic o) =>
'$o'.contains('Unexpected arguments after Dart entry point.'),
),
);
expect(result.exitCode, 64);
@ -818,7 +819,7 @@ void main() {}
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
expect(File(outFile).existsSync(), true,
@ -846,7 +847,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, contains('must be assigned before it can be used'));
expect(result.exitCode, 254);
});
@ -872,7 +873,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, contains('Warning:'));
expect(result.exitCode, 0);
});
@ -941,7 +942,7 @@ void main() {}
],
);
expect(result.stdout, predicate((o) => '$o'.contains('[foo]')));
expect(result.stdout, predicate((dynamic o) => '$o'.contains('[foo]')));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
expect(File(outFile).existsSync(), true,
@ -965,7 +966,7 @@ void main() {}
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
expect(File(outFile).existsSync(), true,
@ -993,7 +994,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, contains('must be assigned before it can be used'));
expect(result.exitCode, 254);
});
@ -1019,7 +1020,7 @@ void main() {
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, contains('Warning:'));
expect(result.exitCode, 0);
});

View file

@ -14,7 +14,7 @@ void main() {
}
void defineCreateTests() {
TestProject p;
TestProject? p;
setUp(() => p = null);
@ -25,7 +25,7 @@ void defineCreateTests() {
test(templateId, () async {
p = project();
ProcessResult createResult = await p.run([
ProcessResult createResult = await p!.run([
'create',
'--force',
'--template',
@ -37,11 +37,11 @@ void defineCreateTests() {
// Validate that the project analyzes cleanly.
// TODO: Should we use --fatal-infos here?
ProcessResult analyzeResult =
await p.run(['analyze'], workingDir: p.dir.path);
await p!.run(['analyze'], workingDir: p!.dir.path);
expect(analyzeResult.exitCode, 0, reason: analyzeResult.stdout);
// Validate that the code is well formatted.
ProcessResult formatResult = await p.run([
ProcessResult formatResult = await p!.run([
'format',
'--output',
'none',

View file

@ -17,7 +17,7 @@ void main() {
}
void defineCreateTests() {
TestProject p;
TestProject? p;
setUp(() => p = null);
@ -25,7 +25,7 @@ void defineCreateTests() {
test('--help', () async {
p = project();
var result = await p.run(['create', '--help']);
var result = await p!.run(['create', '--help']);
expect(result.stdout, contains('Create a new Dart project.'));
expect(
@ -40,7 +40,7 @@ void defineCreateTests() {
test('--help --verbose', () async {
p = project();
var result = await p.run(['create', '--help', '--verbose']);
var result = await p!.run(['create', '--help', '--verbose']);
expect(result.stdout, contains('Create a new Dart project.'));
expect(
@ -67,7 +67,7 @@ void defineCreateTests() {
test('list templates', () async {
p = project();
ProcessResult result = await p.run(['create', '--list-templates']);
ProcessResult result = await p!.run(['create', '--list-templates']);
expect(result.exitCode, 0);
String output = result.stdout.toString();
@ -81,7 +81,7 @@ void defineCreateTests() {
test('no directory given', () async {
p = project();
ProcessResult result = await p.run([
ProcessResult result = await p!.run([
'create',
]);
expect(result.exitCode, 1);
@ -90,15 +90,15 @@ void defineCreateTests() {
test('directory already exists', () async {
p = project();
ProcessResult result = await p.run(
['create', '--template', CreateCommand.defaultTemplateId, p.dir.path]);
ProcessResult result = await p!.run(
['create', '--template', CreateCommand.defaultTemplateId, p!.dir.path]);
expect(result.exitCode, 73);
});
test('project in current directory', () async {
p = project();
final projectDir = Directory('foo')..createSync();
final result = await p.run(
final result = await p!.run(
['create', '--force', '.'],
workingDir: projectDir.path,
);
@ -109,7 +109,7 @@ void defineCreateTests() {
test('project with normalized package name', () async {
p = project();
final result = await p.run(['create', 'requires-normalization']);
final result = await p!.run(['create', 'requires-normalization']);
expect(result.stderr, isEmpty);
expect(
result.stdout,
@ -120,7 +120,7 @@ void defineCreateTests() {
test('project with an invalid package name', () async {
p = project();
final result = await p.run(['create', 'bad-package^name']);
final result = await p!.run(['create', 'bad-package^name']);
expect(
result.stderr,
contains(
@ -134,8 +134,8 @@ void defineCreateTests() {
test('bad template id', () async {
p = project();
ProcessResult result = await p
.run(['create', '--no-pub', '--template', 'foo-bar', p.dir.path]);
ProcessResult result = await p!
.run(['create', '--no-pub', '--template', 'foo-bar', p!.dir.path]);
expect(result.exitCode, isNot(0));
});
@ -144,7 +144,7 @@ void defineCreateTests() {
test(templateId, () async {
p = project();
const projectName = 'template_project';
ProcessResult result = await p.run([
ProcessResult result = await p!.run([
'create',
'--force',
'--no-pub',
@ -154,9 +154,9 @@ void defineCreateTests() {
]);
expect(result.exitCode, 0);
String entry = templates.getGenerator(templateId).entrypoint.path;
String entry = templates.getGenerator(templateId)!.entrypoint!.path;
entry = entry.replaceAll('__projectName__', projectName);
File entryFile = File(path.join(p.dir.path, projectName, entry));
File entryFile = File(path.join(p!.dir.path, projectName, entry));
expect(entryFile.existsSync(), true,
reason: 'File not found: ${entryFile.path}');
@ -168,7 +168,7 @@ void defineCreateTests() {
const dir = 'foo';
const projectName = dir;
final lines = generator
.getInstallInstructions(dir, projectName)
.getInstallInstructions(dir, scriptPath: projectName)
.split('\n')
.map((e) => e.trim())
.toList();

View file

@ -14,9 +14,9 @@ void main() {
}
void devtools() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('--help', () async {
p = project();
@ -47,7 +47,7 @@ void devtools() {
});
group('integration', () {
Process process;
Process? process;
tearDown(() {
process?.kill();
@ -58,8 +58,8 @@ void devtools() {
// start the devtools server
process = await p.start(['devtools', '--no-launch-browser', '--machine']);
final Stream<String> inStream = process.stdout
process!.stderr.transform(utf8.decoder).listen(print);
final Stream<String> inStream = process!.stdout
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter());
@ -89,7 +89,7 @@ void devtools() {
expect(contents, contains('DevTools'));
// kill the process
process.kill();
process!.kill();
process = null;
});
});

View file

@ -18,9 +18,9 @@ void main() {
const runFromSource = false;
void defineFix() {
TestProject p;
TestProject? p;
ProcessResult result;
late ProcessResult result;
final bullet = Logger.standard().ansi.bullet;
@ -52,18 +52,18 @@ ${result.stderr}
''');
}
Future<ProcessResult> runFix(List<String> args, {String workingDir}) async {
Future<ProcessResult> runFix(List<String> args, {String? workingDir}) async {
if (runFromSource) {
var binary = path.join(Directory.current.path, 'bin', 'dartdev.dart');
return await p.run([binary, 'fix', ...?args], workingDir: workingDir);
return await p!.run([binary, 'fix', ...args], workingDir: workingDir);
}
return await p.run(['fix', ...args], workingDir: workingDir);
return await p!.run(['fix', ...args], workingDir: workingDir);
}
test('--help', () async {
p = project(mainSrc: 'int get foo => 1;\n');
var result = await runFix([p.dirPath, '--help']);
var result = await runFix([p!.dirPath, '--help']);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -79,7 +79,7 @@ ${result.stderr}
test('--help --verbose', () async {
p = project(mainSrc: 'int get foo => 1;\n');
var result = await runFix([p.dirPath, '--help', '--verbose']);
var result = await runFix([p!.dirPath, '--help', '--verbose']);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -98,7 +98,7 @@ ${result.stderr}
test('none', () async {
p = project(mainSrc: 'int get foo => 1;\n');
var result = await runFix([p.dirPath]);
var result = await runFix([p!.dirPath]);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -109,7 +109,7 @@ ${result.stderr}
test('--apply (none)', () async {
p = project(mainSrc: 'int get foo => 1;\n');
var result = await runFix(['--apply', p.dirPath]);
var result = await runFix(['--apply', p!.dirPath]);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
@ -128,7 +128,7 @@ linter:
''',
);
var result = await runFix(['--apply'], workingDir: p.dirPath);
var result = await runFix(['--apply'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(
@ -158,7 +158,7 @@ linter:
- prefer_single_quotes
''',
);
var result = await runFix(['--dry-run', '.'], workingDir: p.dirPath);
var result = await runFix(['--dry-run', '.'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(
@ -182,7 +182,7 @@ linter:
- prefer_single_quotes
''',
);
var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(
@ -207,7 +207,7 @@ linter:
- prefer_single_quotes
''',
);
var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(
@ -235,7 +235,7 @@ linter:
- prefer_single_quotes
''',
);
var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(result.stdout, contains('Nothing to fix!'));
@ -253,7 +253,7 @@ linter:
- prefer_single_quotes
''',
);
var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(result.stdout, contains('Nothing to fix!'));
@ -272,7 +272,7 @@ linter:
- prefer_single_quotes
''',
);
var result = await runFix(['--apply', '.'], workingDir: p.dirPath);
var result = await runFix(['--apply', '.'], workingDir: p!.dirPath);
expect(result.exitCode, 0);
expect(result.stderr, isEmpty);
expect(
@ -305,7 +305,7 @@ linter:
- prefer_single_quotes
''',
);
p.file('lib/main.dart.expect', '''
p!.file('lib/main.dart.expect', '''
class A {
String a() => '';
}
@ -315,7 +315,7 @@ class B extends A {
}
''');
result =
await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
await runFix(['--compare-to-golden', '.'], workingDir: p!.dirPath);
assertResult(exitCode: 1);
});
@ -337,7 +337,7 @@ linter:
- prefer_single_quotes
''',
);
p.file('lib/main.dart.expect', '''
p!.file('lib/main.dart.expect', '''
class A {
String a() => '';
}
@ -348,7 +348,7 @@ class B extends A {
}
''');
result =
await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
await runFix(['--compare-to-golden', '.'], workingDir: p!.dirPath);
assertResult();
});
@ -371,7 +371,7 @@ linter:
''',
);
result =
await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
await runFix(['--compare-to-golden', '.'], workingDir: p!.dirPath);
assertResult(exitCode: 1);
});
@ -379,14 +379,14 @@ linter:
p = project(mainSrc: '''
class C {}
''');
p.file('lib/main.dart.expect', '''
p!.file('lib/main.dart.expect', '''
class C {}
''');
p.file('lib/secondary.dart.expect', '''
p!.file('lib/secondary.dart.expect', '''
class A {}
''');
result =
await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
await runFix(['--compare-to-golden', '.'], workingDir: p!.dirPath);
assertResult(exitCode: 1);
});
@ -403,13 +403,13 @@ linter:
- annotate_overrides
''',
);
p.file('lib/main.dart.expect', '''
p!.file('lib/main.dart.expect', '''
class A {
String a() => '';
}
''');
result =
await runFix(['--compare-to-golden', '.'], workingDir: p.dirPath);
await runFix(['--compare-to-golden', '.'], workingDir: p!.dirPath);
assertResult(exitCode: 1);
});
});

View file

@ -11,6 +11,7 @@ import 'package:test/test.dart';
import '../utils.dart';
void main() {
initGlobalState();
group('command', command, timeout: longTimeout);
group('flag', help, timeout: longTimeout);
}
@ -34,30 +35,28 @@ void command() {
DartdevRunner(['--no-analytics'])
.commands
.forEach((String commandKey, Command command) {
if (command.argParser != null) {
if (command.name != 'help' &&
command.name != 'format' &&
command.name != 'pub' &&
command.name != 'test') {
expect(command.argParser.usageLineLength,
stdout.hasTerminal ? stdout.terminalColumns : null);
} else if (command.name == 'pub') {
// TODO(sigurdm): Avoid special casing here.
// https://github.com/dart-lang/pub/issues/2700
expect(command.argParser.usageLineLength,
stdout.hasTerminal ? stdout.terminalColumns : 80);
} else {
expect(command.argParser.usageLineLength, isNull);
}
if (command.name != 'help' &&
command.name != 'format' &&
command.name != 'pub' &&
command.name != 'test') {
expect(command.argParser.usageLineLength,
stdout.hasTerminal ? stdout.terminalColumns : null);
} else if (command.name == 'pub') {
// TODO(sigurdm): Avoid special casing here.
// https://github.com/dart-lang/pub/issues/2700
expect(command.argParser.usageLineLength,
stdout.hasTerminal ? stdout.terminalColumns : 80);
} else {
expect(command.argParser.usageLineLength, isNull);
}
});
});
}
void help() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('--help', () async {
p = project();

View file

@ -14,9 +14,9 @@ void main() {
}
void format() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('--help', () async {
p = project();

View file

@ -13,9 +13,9 @@ void main() {
}
void help() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
/// Commands not tested by the following loop.
List<String> _commandsNotTested = <String>[

View file

@ -21,10 +21,10 @@ void main() {
}
void defineLanguageServerTests() {
utils.TestProject project;
Process process;
late utils.TestProject project;
Process? process;
tearDown(() async => await project?.dispose());
tearDown(() async => await project.dispose());
Future runWithLsp(List<String> args) async {
project = utils.project();
@ -32,7 +32,7 @@ void defineLanguageServerTests() {
process = await project.start(args);
final Stream<String> inStream =
process.stdout.transform<String>(utf8.decoder);
process!.stdout.transform<String>(utf8.decoder);
// Send an LSP init.
final String message = jsonEncode({
@ -47,9 +47,9 @@ void defineLanguageServerTests() {
},
});
process.stdin.write('Content-Length: ${message.length}\r\n');
process.stdin.write('\r\n');
process.stdin.write(message);
process!.stdin.write('Content-Length: ${message.length}\r\n');
process!.stdin.write('\r\n');
process!.stdin.write(message);
List<String> responses = await inStream.take(2).toList();
expect(responses, hasLength(2));
@ -65,7 +65,7 @@ void defineLanguageServerTests() {
final serverInfo = result['serverInfo'];
expect(serverInfo['name'], isNotEmpty);
process.kill();
process!.kill();
process = null;
}
@ -82,7 +82,7 @@ void defineLanguageServerTests() {
process = await project.start(['language-server', '--protocol=analyzer']);
final Stream<String> inStream = process.stdout
final Stream<String> inStream = process!.stdout
.transform<String>(utf8.decoder)
.transform<String>(const LineSplitter());
@ -95,7 +95,7 @@ void defineLanguageServerTests() {
expect(params['version'], isNotEmpty);
expect(params['pid'], isNot(0));
process.kill();
process!.kill();
process = null;
});
}

View file

@ -15,9 +15,9 @@ void defineMigrateTests() {
final runPubGet = contains('Run `dart pub get`');
final setLowerSdkConstraint = contains('Set the lower SDK constraint');
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('--help', () async {
p = project();

View file

@ -13,9 +13,9 @@ void main() {
}
void pub() {
TestProject p;
TestProject p = project();
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
void _assertPubHelpInvoked(ProcessResult result) {
expect(result, isNotNull);

View file

@ -21,9 +21,9 @@ void main() {
}
void run() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('--help', () async {
p = project();
@ -345,7 +345,7 @@ void main(List<String> args) => print("$b $args");
);
expect(result.stdout,
predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
predicate((dynamic o) => !'$o'.contains(soundNullSafetyMessage)));
expect(result.stderr, isEmpty);
expect(result.exitCode, 0);
});
@ -497,7 +497,7 @@ void main(List<String> args) => print("$b $args");
final readyCompleter = Completer<void>();
final completer = Completer<void>();
StreamSubscription sub;
late StreamSubscription sub;
sub = process.stdout.transform(utf8.decoder).listen((event) async {
if (event.contains('ready')) {
readyCompleter.complete();

View file

@ -17,9 +17,9 @@ Future<void> main() async {
}
void defineTest(List<Experiment> experiments) {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('--help', () async {
p = project();
@ -152,7 +152,7 @@ void main() {
});
group('--enable-experiment', () {
Future<ProcessResult> runTestWithExperimentFlag(String flag) async {
Future<ProcessResult> runTestWithExperimentFlag(String? flag) async {
return await p.run([
if (flag != null) flag,
'test',
@ -162,7 +162,7 @@ void main() {
]);
}
Future<void> expectSuccess(String flag) async {
Future<void> expectSuccess(String? flag) async {
final result = await runTestWithExperimentFlag(flag);
expect(result.stdout, contains('feature enabled'),
reason: 'stderr: ${result.stderr}');
@ -170,7 +170,7 @@ void main() {
reason: 'stdout: ${result.stdout} stderr: ${result.stderr}');
}
Future<void> expectFailure(String flag) async {
Future<void> expectFailure(String? flag) async {
final result = await runTestWithExperimentFlag(flag);
expect(result.exitCode, isNot(0));
}

View file

@ -18,6 +18,7 @@ import 'package:test/test.dart';
import 'utils.dart';
void main() {
initGlobalState();
group('DartdevCommand', _dartdevCommand);
group('PackageConfig', _packageConfig);
group('Project', _project);
@ -45,29 +46,35 @@ void _dartdevCommand() {
test('compile/js', () {
_assertDartdevCommandProperties(
CompileCommand().subcommands['js'], 'js', 'compile/js');
CompileCommand().subcommands['js'] as DartdevCommand,
'js',
'compile/js');
});
test('compile/jit-snapshot', () {
_assertDartdevCommandProperties(
CompileCommand().subcommands['jit-snapshot'],
CompileCommand().subcommands['jit-snapshot'] as DartdevCommand,
'jit-snapshot',
'compile/jit-snapshot');
});
test('compile/kernel', () {
_assertDartdevCommandProperties(
CompileCommand().subcommands['kernel'], 'kernel', 'compile/kernel');
CompileCommand().subcommands['kernel'] as DartdevCommand,
'kernel',
'compile/kernel');
});
test('compile/exe', () {
_assertDartdevCommandProperties(
CompileCommand().subcommands['exe'], 'exe', 'compile/exe');
CompileCommand().subcommands['exe'] as DartdevCommand,
'exe',
'compile/exe');
});
test('compile/aot-snapshot', () {
_assertDartdevCommandProperties(
CompileCommand().subcommands['aot-snapshot'],
CompileCommand().subcommands['aot-snapshot'] as DartdevCommand,
'aot-snapshot',
'compile/aot-snapshot');
});
@ -103,9 +110,9 @@ void _packageConfig() {
}
void _project() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('hasPubspecFile positive', () {
p = project();
@ -128,7 +135,7 @@ void _project() {
Project coreProj = Project.fromDirectory(p.dir);
expect(coreProj.hasPackageConfigFile, isTrue);
expect(coreProj.packageConfig, isNotNull);
expect(coreProj.packageConfig.packages, isNotEmpty);
expect(coreProj.packageConfig!.packages, isNotEmpty);
});
test('hasPackageConfigFile negative', () {

View file

@ -12,7 +12,7 @@ import 'package:yaml/yaml.dart' as yaml;
/// associated `validation` program.
Future<List<Experiment>> experimentsWithValidation() async {
final url = (await Isolate.resolvePackageUri(
Uri.parse('package:dartdev/dartdev.dart')))
Uri.parse('package:dartdev/dartdev.dart')))!
.resolve('../../../tools/experimental_features.yaml');
final experiments =
yaml.loadYaml(File.fromUri(url).readAsStringSync(), sourceUrl: url);
@ -28,14 +28,14 @@ Future<List<Experiment>> experimentsWithValidation() async {
];
}
Version tryParseVersion(String version) =>
Version? tryParseVersion(String? version) =>
version == null ? null : Version.parse(version);
class Experiment {
final String name;
final String validation;
final Version enabledIn;
final Version experimentalReleaseVersion;
final Version? enabledIn;
final Version? experimentalReleaseVersion;
Experiment(
this.name,
this.validation,

View file

@ -18,8 +18,8 @@ Future<FixOutput> runFix(List<String> args) async {
}
void _driver() {
TestProject p;
tearDown(() async => await p?.dispose());
late TestProject p;
tearDown(() async => await p.dispose());
test('no fixes', () async {
p = project(mainSrc: 'int get foo => 1;\n');
@ -33,7 +33,7 @@ class FixOutput {
final FixResult<CapturingLogger> result;
FixOutput(this.result);
int get returnCode => result.returnCode;
int? get returnCode => result.returnCode;
String get stderr => result.logger.output.stderr.toString();
String get stdout => result.logger.output.stdout.toString();
}

View file

@ -9,9 +9,9 @@ import 'package:test/test.dart';
import 'utils.dart';
void main() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test("Fallback to dartdev.dill from dartdev.dart.snapshot for 'Hello World'",
() async {

View file

@ -7,9 +7,9 @@ import 'package:test/test.dart';
import 'utils.dart';
void main() {
TestProject p;
late TestProject p;
tearDown(() async => await p?.dispose());
tearDown(() async => await p.dispose());
test('Ensure parsing fails after encountering invalid file', () async {
// Regression test for https://github.com/dart-lang/sdk/issues/43991

View file

@ -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.10
void main() {
print('Smoke test!');
}

View file

@ -63,7 +63,7 @@ void main() {
);
expect(
result.stderr,
'Could not start VM service: localhost:${server.port} is already in use.\n',
'Could not start the VM service: localhost:${server.port} is already in use.\n',
);
expect(result.stdout, isEmpty);
server.close();

View file

@ -5,6 +5,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:cli_util/cli_logging.dart';
import 'package:dartdev/src/core.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';
@ -18,13 +20,17 @@ const Timeout longTimeout = Timeout(Duration(minutes: 5));
/// version:
const String dartVersionFilePrefix2_9 = '// @dart = 2.9\n';
void initGlobalState() {
log = Logger.standard();
}
TestProject project(
{String mainSrc,
String analysisOptions,
{String? mainSrc,
String? analysisOptions,
bool logAnalytics = false,
String name = TestProject._defaultProjectName,
VersionConstraint sdkConstraint,
Map<String, dynamic> pubspec}) =>
VersionConstraint? sdkConstraint,
Map<String, dynamic>? pubspec}) =>
TestProject(
mainSrc: mainSrc,
analysisOptions: analysisOptions,
@ -35,7 +41,7 @@ TestProject project(
class TestProject {
static const String _defaultProjectName = 'dartdev_temp';
Directory dir;
late Directory dir;
String get dirPath => dir.path;
@ -47,19 +53,20 @@ class TestProject {
final bool logAnalytics;
final VersionConstraint sdkConstraint;
final VersionConstraint? sdkConstraint;
final Map<String, dynamic> pubspec;
final Map<String, dynamic>? pubspec;
Process _process;
Process? _process;
TestProject(
{String mainSrc,
String analysisOptions,
{String? mainSrc,
String? analysisOptions,
this.name = _defaultProjectName,
this.logAnalytics = false,
this.sdkConstraint,
this.pubspec}) {
initGlobalState();
dir = Directory.systemTemp.createTempSync('a');
file(
'pubspec.yaml',
@ -113,7 +120,7 @@ dev_dependencies:
Future<ProcessResult> run(
List<String> arguments, {
String workingDir,
String? workingDir,
}) async {
_process = await Process.start(
Platform.resolvedExecutable,
@ -123,11 +130,11 @@ dev_dependencies:
],
workingDirectory: workingDir ?? dir.path,
environment: {if (logAnalytics) '_DARTDEV_LOG_ANALYTICS': 'true'});
final stdoutContents = _process.stdout.transform(utf8.decoder).join();
final stderrContents = _process.stderr.transform(utf8.decoder).join();
final code = await _process.exitCode;
final stdoutContents = _process!.stdout.transform(utf8.decoder).join();
final stderrContents = _process!.stderr.transform(utf8.decoder).join();
final code = await _process!.exitCode;
return ProcessResult(
_process.pid,
_process!.pid,
code,
await stdoutContents,
await stderrContents,
@ -136,7 +143,7 @@ dev_dependencies:
Future<Process> start(
List<String> arguments, {
String workingDir,
String? workingDir,
}) {
return Process.start(
Platform.resolvedExecutable,
@ -149,7 +156,7 @@ dev_dependencies:
..then((p) => _process = p);
}
String _sdkRootPath;
String? _sdkRootPath;
/// Return the root of the SDK.
String get sdkRootPath {
@ -161,24 +168,24 @@ dev_dependencies:
if (File(path.join(tryDir, 'pkg', 'dartdev', 'bin', 'dartdev.dart'))
.existsSync()) {
_sdkRootPath = tryDir;
return _sdkRootPath;
return _sdkRootPath!;
}
current = tryDir;
} while (path.dirname(current) != current);
throw StateError('can not find SDK repository root');
}
return _sdkRootPath;
return _sdkRootPath!;
}
String get absolutePathToDartdevFile =>
path.join(sdkRootPath, 'pkg', 'dartdev', 'bin', 'dartdev.dart');
Directory findDirectory(String name) {
Directory? findDirectory(String name) {
var directory = Directory(path.join(dir.path, name));
return directory.existsSync() ? directory : null;
}
File findFile(String name) {
File? findFile(String name) {
var file = File(path.join(dir.path, name));
return file.existsSync() ? file : null;
}

View file

@ -64,7 +64,8 @@ void main() {
List<dynamic> _packages = contents['packages'];
try {
// ignore: unused_local_variable
List<Map<String, dynamic>> packages = _packages;
List<Map<String, dynamic>> packages =
_packages as List<Map<String, dynamic>>;
fail('expected implicit cast to fail');
} on TypeError {
// TypeError is expected

View file

@ -8,9 +8,8 @@ import 'package:cli_util/cli_logging.dart';
import 'package:dartdev/src/commands/fix.dart';
import 'package:dartdev/src/core.dart';
import 'package:dartdev/src/utils.dart';
import 'package:meta/meta.dart';
Future<void> main(List<String> args) async {
Future<int?> main(List<String> args) async {
var runner = FixRunner(logger: Logger.standard());
var result = await runner.runFix(args);
return result.returnCode;
@ -32,7 +31,7 @@ class CapturedProgress extends Progress {
}
@override
void finish({String message, bool showTiming = false}) {
void finish({String? message, bool showTiming = false}) {
// todo (pq): consider capturing / tracking finish display updates.
finished = true;
}
@ -85,7 +84,7 @@ class CapturingLogger implements Logger {
class FixResult<T extends Logger> {
/// The value returned by [FixCommand.run].
final int returnCode;
final int? returnCode;
/// The logger used in driving fixes.
final T logger;
@ -104,7 +103,7 @@ class FixRunner<T extends Logger> extends CommandRunner<int> {
allowTrailingOptions: false,
);
FixRunner({@required this.logger})
FixRunner({required this.logger})
: super('fix_runner',
'A command-line utility for testing the `dart fix` command.') {
addCommand(FixCommand());
@ -112,14 +111,14 @@ class FixRunner<T extends Logger> extends CommandRunner<int> {
}
@override
Future<int> runCommand(ArgResults topLevelResults) async {
Future<int?> runCommand(ArgResults topLevelResults) async {
var result = await super.runCommand(topLevelResults);
return result;
}
Future<FixResult<T>> runFix(List<String> args) async {
log = logger;
var argResults = argParser.parse(['fix', ...?args]);
var argResults = argParser.parse(['fix', ...args]);
var result = await runCommand(argResults);
return FixResult(logger, result);
}

View file

@ -206,7 +206,7 @@ void DartDevIsolate::DartDevRunner::RunCallback(uword args) {
Dart_IsolateFlags flags;
Dart_IsolateFlagsInitialize(&flags);
flags.enable_asserts = false;
flags.null_safety = false;
flags.null_safety = true;
flags.use_field_guards = true;
flags.use_osr = true;
flags.is_system_isolate = true;

View file

@ -25,6 +25,7 @@ application_snapshot("generate_dartdev_kernel") {
main_dart = "../../pkg/dartdev/bin/dartdev.dart"
training_args = []
deps = [ "../dds:dds" ]
vm_args = [ "--sound-null-safety" ]
output = "$root_gen_dir/dartdev.dill"
}
@ -39,6 +40,7 @@ application_snapshot("generate_dartdev_snapshot") {
main_dart = "../../pkg/dartdev/bin/dartdev.dart"
training_args = [ "--help" ]
deps = [ "../dds:dds" ]
vm_args = [ "--sound-null-safety" ]
output = "$root_gen_dir/dartdev.dart.snapshot"
}