Migrate analyzer_cli to null safety.

Change-Id: I03184d7b3257802a90eacfb1ea912977f2082c23
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217820
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
This commit is contained in:
Konstantin Shcheglov 2021-11-20 03:23:38 +00:00 committed by commit-bot@chromium.org
parent a8891da0e7
commit 3ab1eaa03f
19 changed files with 216 additions and 209 deletions

View file

@ -88,7 +88,7 @@
"name": "analyzer_cli",
"rootUri": "../pkg/analyzer_cli",
"packageUri": "lib/",
"languageVersion": "2.7"
"languageVersion": "2.14"
},
{
"name": "analyzer_plugin",

View file

@ -44,25 +44,22 @@ class AnalyzerImpl {
/// specified on the command line as though it is reached via a "package:"
/// URI, but avoid suppressing its output in the event that the user has not
/// specified the "--package-warnings" option.
String _selfPackageName;
String? _selfPackageName;
AnalyzerImpl(this.analysisOptions, this.analysisDriver, this.libraryFile,
this.options, this.stats, this.startTime);
void addCompilationUnitSource(
CompilationUnitElement unit, Set<CompilationUnitElement> units) {
if (unit == null || !units.add(unit)) {
if (!units.add(unit)) {
return;
}
var source = unit.source;
if (source != null) {
files.add(source.fullName);
}
files.add(unit.source.fullName);
}
void addLibrarySources(LibraryElement library, Set<LibraryElement> libraries,
Set<CompilationUnitElement> units) {
if (library == null || !libraries.add(library)) {
if (!libraries.add(library)) {
return;
}
// Maybe skip library.
@ -102,7 +99,7 @@ class AnalyzerImpl {
if (_defaultSeverityProcessor(error) == null) {
continue;
}
status = status.max(computeSeverity(error, options, analysisOptions));
status = status.max(computeSeverity(error, options, analysisOptions)!);
}
}
return status;
@ -160,7 +157,7 @@ class AnalyzerImpl {
return computeMaxErrorSeverity();
}
ErrorSeverity _defaultSeverityProcessor(AnalysisError error) =>
ErrorSeverity? _defaultSeverityProcessor(AnalysisError error) =>
determineProcessedSeverity(error, options, analysisOptions);
/// Returns true if we want to report diagnostics for this library.
@ -191,7 +188,7 @@ class AnalyzerImpl {
} else if (options.showPackageWarningsPrefix == null) {
return true;
} else {
return packageName.startsWith(options.showPackageWarningsPrefix);
return packageName.startsWith(options.showPackageWarningsPrefix!);
}
}
@ -235,14 +232,14 @@ class StdInstrumentation extends NoopInstrumentationService {
@override
void logException(dynamic exception,
[StackTrace stackTrace,
List<InstrumentationServiceAttachment> attachments = const []]) {
[StackTrace? stackTrace,
List<InstrumentationServiceAttachment>? attachments = const []]) {
errorSink.writeln(exception);
errorSink.writeln(stackTrace);
}
@override
void logInfo(String message, [Object exception]) {
void logInfo(String message, [Object? exception]) {
outSink.writeln(message);
if (exception != null) {
outSink.writeln(exception);

View file

@ -41,10 +41,10 @@ import 'package:path/path.dart' as path;
import 'package:yaml/yaml.dart';
/// Shared IO sink for standard error reporting.
StringSink errorSink = io.stderr;
late StringSink errorSink = io.stderr;
/// Shared IO sink for standard out reporting.
StringSink outSink = io.stdout;
late StringSink outSink = io.stdout;
/// Test this option map to see if it specifies lint rules.
bool containsLintRuleEntry(YamlMap options) {
@ -55,13 +55,14 @@ bool containsLintRuleEntry(YamlMap options) {
class Driver implements CommandLineStarter {
static final ByteStore analysisDriverMemoryByteStore = MemoryByteStore();
_AnalysisContextProvider _analysisContextProvider;
DriverBasedAnalysisContext analysisContext;
bool _isStarted = false;
/// The driver that was most recently created by a call to [_analyzeAll], or
/// `null` if [_analyzeAll] hasn't been called yet.
late _AnalysisContextProvider _analysisContextProvider;
DriverBasedAnalysisContext? analysisContext;
/// The driver that was most recently created by a call to [_analyzeAll].
@visibleForTesting
AnalysisDriver analysisDriver;
AnalysisDriver? analysisDriver;
/// The total number of source files loaded by an AnalysisContext.
int _analyzedFileCount = 0;
@ -73,7 +74,7 @@ class Driver implements CommandLineStarter {
final AnalysisStats stats = AnalysisStats();
/// The [PathFilter] for excluded files with wildcards, etc.
PathFilter pathFilter;
late PathFilter pathFilter;
/// Create a new Driver instance.
Driver({@Deprecated('This parameter has no effect') bool isTesting = false});
@ -88,9 +89,10 @@ class Driver implements CommandLineStarter {
@override
Future<void> start(List<String> arguments) async {
if (analysisDriver != null) {
if (_isStarted) {
throw StateError('start() can only be called once');
}
_isStarted = true;
var startTime = DateTime.now().millisecondsSinceEpoch;
StringUtilities.INTERNER = MappedInterner();
@ -98,7 +100,7 @@ class Driver implements CommandLineStarter {
linter.registerLintRules();
// Parse commandline options.
var options = CommandLineOptions.parse(resourceProvider, arguments);
var options = CommandLineOptions.parse(resourceProvider, arguments)!;
_analysisContextProvider = _AnalysisContextProvider(resourceProvider);
@ -106,7 +108,7 @@ class Driver implements CommandLineStarter {
if (options.batchMode) {
var batchRunner = BatchRunner(outSink, errorSink);
batchRunner.runAsBatch(arguments, (List<String> args) async {
var options = CommandLineOptions.parse(resourceProvider, args);
var options = CommandLineOptions.parse(resourceProvider, args)!;
return await _analyzeAll(options);
});
} else {
@ -129,7 +131,7 @@ class Driver implements CommandLineStarter {
for (var i = 0; i < 3; i++) {
buildSdkSummary(
resourceProvider: PhysicalResourceProvider.INSTANCE,
sdkPath: options.dartSdkPath,
sdkPath: options.dartSdkPath!,
);
}
@ -137,13 +139,13 @@ class Driver implements CommandLineStarter {
}
if (analysisDriver != null) {
_analyzedFileCount += analysisDriver.knownFiles.length;
_analyzedFileCount += analysisDriver!.knownFiles.length;
}
if (options.perfReport != null) {
var json = makePerfReport(
startTime, currentTimeMillis, options, _analyzedFileCount, stats);
io.File(options.perfReport).writeAsStringSync(json);
io.File(options.perfReport!).writeAsStringSync(json);
}
}
@ -175,7 +177,7 @@ class Driver implements CommandLineStarter {
SeverityProcessor defaultSeverityProcessor;
defaultSeverityProcessor = (AnalysisError error) {
return determineProcessedSeverity(
error, options, analysisDriver.analysisOptions);
error, options, analysisDriver!.analysisOptions);
};
// We currently print out to stderr to ensure that when in batch mode we
@ -213,7 +215,8 @@ class Driver implements CommandLineStarter {
for (var sourcePath in pathList) {
_analysisContextProvider.configureForPath(sourcePath);
analysisContext = _analysisContextProvider.analysisContext;
analysisDriver = _analysisContextProvider.analysisDriver;
final analysisDriver =
this.analysisDriver = _analysisContextProvider.analysisDriver;
pathFilter = _analysisContextProvider.pathFilter;
// Add all the files to be analyzed en masse to the context. Skip any
@ -250,8 +253,8 @@ class Driver implements CommandLineStarter {
analysisDriver.currentSession.analysisContext.contextRoot.root.path,
);
formatter.formatErrors([
ErrorsResultImpl(analysisDriver.currentSession, path, null,
lineInfo, false, errors)
ErrorsResultImpl(analysisDriver.currentSession, path,
pathContext.toUri(path), lineInfo, false, errors)
]);
for (var error in errors) {
var severity = determineProcessedSeverity(
@ -272,7 +275,7 @@ class Driver implements CommandLineStarter {
errors.addAll(validator.validate(node.nodes));
}
if (analysisDriver != null && analysisDriver.analysisOptions.lint) {
if (analysisDriver.analysisOptions.lint) {
var visitors = <LintRule, PubspecVisitor>{};
for (var linter in analysisDriver.analysisOptions.lintRules) {
if (linter is LintRule) {
@ -301,13 +304,13 @@ class Driver implements CommandLineStarter {
if (errors.isNotEmpty) {
for (var error in errors) {
var severity = determineProcessedSeverity(
error, options, analysisDriver.analysisOptions);
error, options, analysisDriver.analysisOptions)!;
allResult = allResult.max(severity);
}
var lineInfo = LineInfo.fromContent(content);
formatter.formatErrors([
ErrorsResultImpl(analysisDriver.currentSession, path, null,
lineInfo, false, errors)
ErrorsResultImpl(analysisDriver.currentSession, path,
pathContext.toUri(path), lineInfo, false, errors)
]);
}
} catch (exception) {
@ -322,12 +325,12 @@ class Driver implements CommandLineStarter {
var errors = validator.validate(
content, analysisDriver.analysisOptions.chromeOsManifestChecks);
formatter.formatErrors([
ErrorsResultImpl(analysisDriver.currentSession, path, null,
lineInfo, false, errors)
ErrorsResultImpl(analysisDriver.currentSession, path,
pathContext.toUri(path), lineInfo, false, errors)
]);
for (var error in errors) {
var severity = determineProcessedSeverity(
error, options, analysisDriver.analysisOptions);
error, options, analysisDriver.analysisOptions)!;
allResult = allResult.max(severity);
}
} catch (exception) {
@ -360,7 +363,7 @@ class Driver implements CommandLineStarter {
// The next batch should not be affected by a previous batch.
// E.g. the same parts in both batches, but with different libraries.
for (var path in dartFiles) {
analysisDriver.removeFile(path);
analysisDriver!.removeFile(path);
}
// Any dangling parts still in this list were definitely dangling.
@ -412,6 +415,7 @@ class Driver implements CommandLineStarter {
Future<ErrorSeverity> _runAnalyzer(
FileState file, CommandLineOptions options, ErrorFormatter formatter) {
var startTime = currentTimeMillis;
final analysisDriver = this.analysisDriver!;
var analyzer = AnalyzerImpl(analysisDriver.analysisOptions, analysisDriver,
file, options, stats, startTime);
return analyzer.analyze(formatter);
@ -446,9 +450,8 @@ class Driver implements CommandLineStarter {
/// Return whether the [newOptions] are equal to the [previous].
static bool _equalCommandLineOptions(
CommandLineOptions previous, CommandLineOptions newOptions) {
CommandLineOptions? previous, CommandLineOptions newOptions) {
return previous != null &&
newOptions != null &&
newOptions.defaultPackagesPath == previous.defaultPackagesPath &&
_equalMaps(newOptions.declaredVariables, previous.declaredVariables) &&
newOptions.log == previous.log &&
@ -460,7 +463,8 @@ class Driver implements CommandLineStarter {
newOptions.lints == previous.lints &&
newOptions.defaultLanguageVersion == previous.defaultLanguageVersion &&
newOptions.disableCacheFlushing == previous.disableCacheFlushing &&
_equalLists(newOptions.enabledExperiments, previous.enabledExperiments);
_equalLists(
newOptions.enabledExperiments!, previous.enabledExperiments!);
}
/// Perform a deep comparison of two string lists.
@ -494,27 +498,27 @@ class _AnalysisContextProvider {
final ResourceProvider _resourceProvider;
final FileContentCache _fileContentCache;
CommandLineOptions _commandLineOptions;
List<String> _pathList;
CommandLineOptions? _commandLineOptions;
late List<String> _pathList;
final Map<Folder, DriverBasedAnalysisContext> _folderContexts = {};
AnalysisContextCollectionImpl _collection;
DriverBasedAnalysisContext _analysisContext;
final Map<Folder, DriverBasedAnalysisContext?> _folderContexts = {};
AnalysisContextCollectionImpl? _collection;
DriverBasedAnalysisContext? _analysisContext;
_AnalysisContextProvider(this._resourceProvider)
: _fileContentCache = FileContentCache(_resourceProvider);
DriverBasedAnalysisContext get analysisContext {
DriverBasedAnalysisContext? get analysisContext {
return _analysisContext;
}
AnalysisDriver get analysisDriver {
return _analysisContext.driver;
return _analysisContext!.driver;
}
/// TODO(scheglov) Use analyzedFiles()
PathFilter get pathFilter {
var contextRoot = analysisContext.contextRoot;
var contextRoot = analysisContext!.contextRoot;
var optionsFile = contextRoot.optionsFile;
// If there is no options file, there can be no excludes.
@ -524,7 +528,7 @@ class _AnalysisContextProvider {
// Exclude patterns are relative to the directory with the options file.
return PathFilter(contextRoot.root.path, optionsFile.parent2.path,
analysisContext.analysisOptions.excludePatterns);
analysisContext!.analysisOptions.excludePatterns);
}
void configureForPath(String path) {
@ -554,10 +558,10 @@ class _AnalysisContextProvider {
_collection = AnalysisContextCollectionImpl(
byteStore: Driver.analysisDriverMemoryByteStore,
includedPaths: _pathList,
optionsFile: _commandLineOptions.defaultAnalysisOptionsPath,
packagesFile: _commandLineOptions.defaultPackagesPath,
optionsFile: _commandLineOptions!.defaultAnalysisOptionsPath,
packagesFile: _commandLineOptions!.defaultPackagesPath,
resourceProvider: _resourceProvider,
sdkPath: _commandLineOptions.dartSdkPath,
sdkPath: _commandLineOptions!.dartSdkPath,
updateAnalysisOptions: _updateAnalysisOptions,
fileContentCache: _fileContentCache,
);
@ -580,10 +584,10 @@ class _AnalysisContextProvider {
}
void _setContextForPath(String path) {
_analysisContext = _collection.contextFor(path);
_analysisContext = _collection!.contextFor(path);
}
void _updateAnalysisOptions(AnalysisOptionsImpl analysisOptions) {
_commandLineOptions.updateAnalysisOptions(analysisOptions);
_commandLineOptions!.updateAnalysisOptions(analysisOptions);
}
}

View file

@ -34,7 +34,7 @@ ErrorSeverity _severityIdentity(AnalysisError error) =>
/// Returns desired severity for the given [error] (or `null` if it's to be
/// suppressed).
typedef SeverityProcessor = ErrorSeverity Function(AnalysisError error);
typedef SeverityProcessor = ErrorSeverity? Function(AnalysisError error);
/// Analysis statistics counter.
class AnalysisStats {
@ -113,20 +113,20 @@ class CLIError implements Comparable<CLIError> {
final String message;
final List<ContextMessage> contextMessages;
final String errorCode;
final String correction;
final String url;
final String? correction;
final String? url;
CLIError({
this.severity,
this.sourcePath,
this.offset,
this.line,
this.column,
this.message,
this.contextMessages,
this.errorCode,
this.correction,
this.url,
required this.severity,
required this.sourcePath,
required this.offset,
required this.line,
required this.column,
required this.message,
required this.contextMessages,
required this.errorCode,
required this.correction,
required this.url,
});
@override
@ -150,7 +150,8 @@ class CLIError implements Comparable<CLIError> {
@override
int compareTo(CLIError other) {
// severity
var compare = _severityCompare[other.severity] - _severityCompare[severity];
var compare =
_severityCompare[other.severity]! - _severityCompare[severity]!;
if (compare != 0) return compare;
// path
@ -179,12 +180,11 @@ abstract class ErrorFormatter {
final StringSink out;
final CommandLineOptions options;
final AnalysisStats stats;
SeverityProcessor _severityProcessor;
final SeverityProcessor _severityProcessor;
ErrorFormatter(this.out, this.options, this.stats,
{SeverityProcessor severityProcessor}) {
_severityProcessor = severityProcessor ?? _severityIdentity;
}
{SeverityProcessor? severityProcessor})
: _severityProcessor = severityProcessor ?? _severityIdentity;
/// Call to write any batched up errors from [formatErrors].
void flush();
@ -213,22 +213,20 @@ abstract class ErrorFormatter {
/// Compute the severity for this [error] or `null` if this error should be
/// filtered.
ErrorSeverity _computeSeverity(AnalysisError error) =>
ErrorSeverity? _computeSeverity(AnalysisError error) =>
_severityProcessor(error);
}
class HumanErrorFormatter extends ErrorFormatter {
AnsiLogger ansi;
late final AnsiLogger ansi = AnsiLogger(options.color);
// This is a Set in order to de-dup CLI errors.
final Set<CLIError> batchedErrors = {};
HumanErrorFormatter(
StringSink out, CommandLineOptions options, AnalysisStats stats,
{SeverityProcessor severityProcessor})
: super(out, options, stats, severityProcessor: severityProcessor) {
ansi = AnsiLogger(this.options.color);
}
{SeverityProcessor? severityProcessor})
: super(out, options, stats, severityProcessor: severityProcessor);
@override
void flush() {
@ -281,10 +279,10 @@ class HumanErrorFormatter extends ErrorFormatter {
void formatError(
Map<AnalysisError, ErrorsResult> errorToLine, AnalysisError error) {
var source = error.source;
var result = errorToLine[error];
var result = errorToLine[error]!;
var location = result.lineInfo.getLocation(error.offset);
var severity = _severityProcessor(error);
var severity = _severityProcessor(error)!;
// Get display name; translate INFOs into LINTS and HINTS.
var errorType = severity.displayName;
@ -314,7 +312,7 @@ class HumanErrorFormatter extends ErrorFormatter {
if (session is DriverBasedAnalysisContext) {
var fileResult = session.driver.getFileSync(message.filePath);
if (fileResult is FileResult) {
var lineInfo = fileResult?.lineInfo;
var lineInfo = fileResult.lineInfo;
var location = lineInfo.getLocation(message.offset);
contextMessages.add(ContextMessage(
message.filePath,
@ -343,7 +341,7 @@ class HumanErrorFormatter extends ErrorFormatter {
class JsonErrorFormatter extends ErrorFormatter {
JsonErrorFormatter(
StringSink out, CommandLineOptions options, AnalysisStats stats,
{SeverityProcessor severityProcessor})
{SeverityProcessor? severityProcessor})
: super(out, options, stats, severityProcessor: severityProcessor);
@override
@ -430,7 +428,7 @@ class MachineErrorFormatter extends ErrorFormatter {
MachineErrorFormatter(
StringSink out, CommandLineOptions options, AnalysisStats stats,
{SeverityProcessor severityProcessor})
{SeverityProcessor? severityProcessor})
: super(out, options, stats, severityProcessor: severityProcessor);
@override
@ -444,7 +442,7 @@ class MachineErrorFormatter extends ErrorFormatter {
return;
}
var source = error.source;
var location = errorToLine[error].lineInfo.getLocation(error.offset);
var location = errorToLine[error]!.lineInfo.getLocation(error.offset);
var length = error.length;
var severity = _severityProcessor(error);

View file

@ -12,17 +12,15 @@ import 'package:analyzer_cli/src/options.dart';
/// - if [options.enableTypeChecks] is false, then de-escalate checked-mode
/// compile time errors to a severity of [ErrorSeverity.INFO].
/// - if [options.lintsAreFatal] is true, escalate lints to errors.
ErrorSeverity computeSeverity(
ErrorSeverity? computeSeverity(
AnalysisError error,
CommandLineOptions commandLineOptions,
AnalysisOptions analysisOptions,
) {
if (analysisOptions != null) {
var processor = ErrorProcessor.getProcessor(analysisOptions, error);
// If there is a processor for this error, defer to it.
if (processor != null) {
return processor.severity;
}
var processor = ErrorProcessor.getProcessor(analysisOptions, error);
// If there is a processor for this error, defer to it.
if (processor != null) {
return processor.severity;
}
if (commandLineOptions.lintsAreFatal && error.errorCode is LintCode) {
@ -34,7 +32,7 @@ ErrorSeverity computeSeverity(
/// Check various configuration options to get a desired severity for this
/// [error] (or `null` if it's to be suppressed).
ErrorSeverity determineProcessedSeverity(AnalysisError error,
ErrorSeverity? determineProcessedSeverity(AnalysisError error,
CommandLineOptions commandLineOptions, AnalysisOptions analysisOptions) {
var severity = computeSeverity(error, commandLineOptions, analysisOptions);
// Skip TODOs categorically unless escalated to ERROR or HINT (#26215).

View file

@ -35,6 +35,8 @@ ExitHandler exitHandler = io.exit;
T cast<T>(dynamic value) => value as T;
T? castNullable<T>(dynamic value) => value as T?;
/// Print the given [message] to stderr and exit with the given [exitCode].
void printAndFail(String message, {int exitCode = 15}) {
errorSink.writeln(message);
@ -53,18 +55,18 @@ class CommandLineOptions {
/// The file path of the analysis options file that should be used in place of
/// any file in the root directory or a parent of the root directory,
/// or `null` if the normal lookup mechanism should be used.
String defaultAnalysisOptionsPath;
String? defaultAnalysisOptionsPath;
/// The file path of the .packages file that should be used in place of any
/// file found using the normal (Package Specification DEP) lookup mechanism,
/// or `null` if the normal lookup mechanism should be used.
String defaultPackagesPath;
String? defaultPackagesPath;
/// A table mapping variable names to values for the declared variables.
final Map<String, String> declaredVariables = {};
/// The path to the dart SDK.
String dartSdkPath;
String? dartSdkPath;
/// Whether to disable cache flushing. This option can improve analysis
/// speed at the expense of memory usage. It may also be useful for working
@ -91,7 +93,7 @@ class CommandLineOptions {
/// The path to a file to write a performance log.
/// (Or null if not enabled.)
final String perfReport;
final String? perfReport;
/// Batch mode (for unit testing)
final bool batchMode;
@ -100,7 +102,7 @@ class CommandLineOptions {
final bool showPackageWarnings;
/// If not null, show package: warnings only for matching packages.
final String showPackageWarningsPrefix;
final String? showPackageWarningsPrefix;
/// Whether to show SDK warnings
final bool showSdkWarnings;
@ -133,7 +135,7 @@ class CommandLineOptions {
ResourceProvider resourceProvider,
ArgResults args,
) : _argResults = args,
dartSdkPath = cast(args[_sdkPathOption]),
dartSdkPath = castNullable(args[_sdkPathOption]),
disableCacheFlushing = cast(args['disable-cache-flushing']),
disableHints = cast(args['no-hints']),
displayVersion = cast(args['version']),
@ -141,12 +143,13 @@ class CommandLineOptions {
log = cast(args['log']),
jsonFormat = args['format'] == 'json',
machineFormat = args['format'] == 'machine',
perfReport = cast(args['x-perf-report']),
perfReport = castNullable(args['x-perf-report']),
batchMode = cast(args['batch']),
showPackageWarnings = cast(args['show-package-warnings']) ||
cast(args['package-warnings']) ||
args['x-package-warnings-prefix'] != null,
showPackageWarningsPrefix = cast(args['x-package-warnings-prefix']),
showPackageWarningsPrefix =
castNullable(args['x-package-warnings-prefix']),
showSdkWarnings = cast(args['sdk-warnings']),
sourceFiles = args.rest,
infosAreFatal = cast(args['fatal-infos']) || cast(args['fatal-hints']),
@ -160,11 +163,11 @@ class CommandLineOptions {
//
defaultAnalysisOptionsPath = _absoluteNormalizedPath(
resourceProvider,
cast(args[_analysisOptionsFileOption]),
castNullable(args[_analysisOptionsFileOption]),
);
defaultPackagesPath = _absoluteNormalizedPath(
resourceProvider,
cast(args[_packagesOption]),
castNullable(args[_packagesOption]),
);
//
@ -192,20 +195,20 @@ class CommandLineOptions {
/// The default language version for files that are not in a package.
/// (Or null if no default language version to force.)
String get defaultLanguageVersion {
return cast(_argResults[_defaultLanguageVersionOption]);
String? get defaultLanguageVersion {
return castNullable(_argResults[_defaultLanguageVersionOption]);
}
/// A list of the names of the experiments that are to be enabled.
List<String> get enabledExperiments {
return cast(_argResults[_enableExperimentOption]);
List<String>? get enabledExperiments {
return castNullable(_argResults[_enableExperimentOption]);
}
bool get implicitCasts => _argResults[_implicitCastsFlag] as bool;
bool? get implicitCasts => _argResults[_implicitCastsFlag] as bool?;
bool get lints => _argResults[_lintsFlag] as bool;
bool? get lints => _argResults[_lintsFlag] as bool?;
bool get noImplicitDynamic => _argResults[_noImplicitDynamicFlag] as bool;
bool? get noImplicitDynamic => _argResults[_noImplicitDynamicFlag] as bool?;
/// Update the [analysisOptions] with flags that the user specified
/// explicitly. The [analysisOptions] are usually loaded from one of
@ -222,7 +225,7 @@ class CommandLineOptions {
.restrictToVersion(nonPackageLanguageVersion);
}
var enabledExperiments = this.enabledExperiments;
var enabledExperiments = this.enabledExperiments!;
if (enabledExperiments.isNotEmpty) {
analysisOptions.contextFeatures = FeatureSet.fromEnableFlags2(
sdkLanguageVersion: ExperimentStatus.currentVersion,
@ -303,7 +306,7 @@ class CommandLineOptions {
/// Parse [args] into [CommandLineOptions] describing the specified
/// analyzer options. In case of a format error, calls [printAndFail], which
/// by default prints an error message to stderr and exits.
static CommandLineOptions parse(
static CommandLineOptions? parse(
ResourceProvider resourceProvider, List<String> args,
{void Function(String msg) printAndFail = printAndFail}) {
var options = _parse(resourceProvider, args);
@ -335,9 +338,9 @@ class CommandLineOptions {
return options;
}
static String _absoluteNormalizedPath(
static String? _absoluteNormalizedPath(
ResourceProvider resourceProvider,
String path,
String? path,
) {
if (path == null) {
return null;
@ -425,7 +428,7 @@ class CommandLineOptions {
}
}
static CommandLineOptions _parse(
static CommandLineOptions? _parse(
ResourceProvider resourceProvider,
List<String> args,
) {

View file

@ -5,7 +5,7 @@ description: Command line interface for the Dart Analyzer.
publish_to: none
environment:
sdk: "^2.7.0"
sdk: "^2.14.0"
dependencies:
analyzer: any

View file

@ -18,15 +18,10 @@ void main() {
@reflectiveTest
class OptionsTest {
_Runner runner;
void setUp() {
runner = _Runner.setUp();
}
final _Runner runner = _Runner.setUp();
void tearDown() {
runner.tearDown();
runner = null;
}
Future<void> test_options() async {

View file

@ -34,16 +34,16 @@ void main() {
class BaseTest {
static const emptyOptionsFile = 'data/empty_options.yaml';
StringSink _savedOutSink, _savedErrorSink;
int _savedExitCode;
ExitHandler _savedExitHandler;
late StringSink _savedOutSink, _savedErrorSink;
late int _savedExitCode;
late ExitHandler _savedExitHandler;
Driver driver;
late Driver driver;
AnalysisOptions get analysisOptions => driver.analysisDriver.analysisOptions;
AnalysisOptions get analysisOptions => driver.analysisDriver!.analysisOptions;
/// Normalize text with bullets.
String bulletToDash(StringSink item) => '$item'.replaceAll('', '-');
String bulletToDash(StringSink? item) => '$item'.replaceAll('', '-');
/// Start a driver for the given [source], optionally providing additional
/// [args] and an [options] file path. The value of [options] defaults to an
@ -60,7 +60,7 @@ class BaseTest {
/// Like [drive], but takes an array of sources.
Future<void> driveMany(
List<String> sources, {
String options = emptyOptionsFile,
String? options = emptyOptionsFile,
List<String> args = const <String>[],
}) async {
options = _posixToPlatformPath(options);
@ -112,7 +112,7 @@ class BaseTest {
///
/// This is a utility method for testing; paths passed in to other methods in
/// this class are never converted automatically.
String _posixToPlatformPath(String filePath) {
String? _posixToPlatformPath(String? filePath) {
if (filePath == null) {
return null;
}
@ -464,7 +464,7 @@ class OptionsTest extends BaseTest {
]);
expect(processorFor(missing_return).severity, ErrorSeverity.ERROR);
expect(bulletToDash(outSink),
contains("error - This function has a return type of 'int'"));
contains("error - The body might complete normally"));
expect(outSink.toString(), contains('1 error and 1 warning found.'));
}

View file

@ -12,8 +12,8 @@ import 'utils.dart';
void main() {
group('_embedder.yaml', () {
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
late StringSink savedOutSink, savedErrorSink;
late int savedExitCode;
setUp(() {
savedOutSink = outSink;

View file

@ -18,9 +18,9 @@ void main() {
@reflectiveTest
class ErrorsReportedOnceTest {
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
ExitHandler savedExitHandler;
late StringSink savedOutSink, savedErrorSink;
late int savedExitCode;
late ExitHandler savedExitHandler;
void setUp() {
savedOutSink = outSink;

View file

@ -18,9 +18,9 @@ void main() {
@reflectiveTest
class ErrorUpgradeFailsCli {
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
ExitHandler savedExitHandler;
late StringSink savedOutSink, savedErrorSink;
late int savedExitCode;
late ExitHandler savedExitHandler;
void setUp() {
savedOutSink = outSink;

View file

@ -32,10 +32,10 @@ class MockAnalysisError implements AnalysisError {
List<DiagnosticMessage> get contextMessages => const [];
@override
String get correction => null;
String? get correction => null;
@override
String get correctionMessage => null;
String? get correctionMessage => null;
@override
DiagnosticMessage get problemMessage => DiagnosticMessageImpl(
@ -46,7 +46,7 @@ class MockAnalysisError implements AnalysisError {
url: null);
@override
Severity get severity => null;
Severity get severity => Severity.error;
}
class MockAnalysisErrorInfo implements AnalysisErrorInfo {
@ -87,7 +87,7 @@ class MockErrorCode implements ErrorCode {
String name;
@override
String url;
String? url;
MockErrorCode(this.type, this.errorSeverity, this.name);
@ -120,7 +120,7 @@ class MockErrorCode implements ErrorCode {
}
class MockLineInfo implements LineInfo {
CharacterLocation defaultLocation;
CharacterLocation? defaultLocation;
MockLineInfo({this.defaultLocation});
@ -137,7 +137,7 @@ class MockLineInfo implements LineInfo {
@override
CharacterLocation getLocation(int offset) {
if (defaultLocation != null) {
return defaultLocation;
return defaultLocation!;
}
throw StateError('Unexpected invocation of getLocation');
}

View file

@ -24,11 +24,11 @@ void main() {
var outStringBuffer = StringBuffer();
var errorStringBuffer = StringBuffer();
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
ExitHandler savedExitHandler;
late StringSink savedOutSink, savedErrorSink;
late int savedExitCode;
late ExitHandler savedExitHandler;
CommandLineOptions parse(List<String> args,
CommandLineOptions? parse(List<String> args,
{void Function(String msg) printAndFail = printAndFail}) {
var resourceProvider = PhysicalResourceProvider.INSTANCE;
return CommandLineOptions.parse(resourceProvider, args,
@ -53,7 +53,7 @@ void main() {
});
test('defaults', () {
var options = parse(['--dart-sdk', '.', 'foo.dart']);
var options = parse(['--dart-sdk', '.', 'foo.dart'])!;
expect(options, isNotNull);
expect(options.dartSdkPath, isNotNull);
expect(options.disableCacheFlushing, isFalse);
@ -78,19 +78,19 @@ void main() {
});
test('batch', () {
var options = parse(['--dart-sdk', '.', '--batch']);
var options = parse(['--dart-sdk', '.', '--batch'])!;
expect(options.batchMode, isTrue);
});
test('defined variables', () {
var options = parse(['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '-Dfoo=bar', 'foo.dart'])!;
expect(options.declaredVariables['foo'], equals('bar'));
expect(options.declaredVariables['bar'], isNull);
});
test('disable cache flushing', () {
var options =
parse(['--dart-sdk', '.', '--disable-cache-flushing', 'foo.dart']);
parse(['--dart-sdk', '.', '--disable-cache-flushing', 'foo.dart'])!;
expect(options.disableCacheFlushing, isTrue);
});
@ -126,119 +126,126 @@ void main() {
};
test('no values', () {
var options =
overrideKnownFeatures(knownFeatures, () => parse(['foo.dart']));
var options = overrideKnownFeatures(
knownFeatures, (() => parse(['foo.dart'])!));
expect(options.enabledExperiments, isEmpty);
});
test('single value', () {
var options = overrideKnownFeatures(knownFeatures,
() => parse(['--enable-experiment', 'a', 'foo.dart']));
(() => parse(['--enable-experiment', 'a', 'foo.dart'])!));
expect(options.enabledExperiments, ['a']);
});
group('multiple values', () {
test('single flag', () {
var options = overrideKnownFeatures(knownFeatures,
() => parse(['--enable-experiment', 'a,b', 'foo.dart']));
(() => parse(['--enable-experiment', 'a,b', 'foo.dart'])!));
expect(options.enabledExperiments, ['a', 'b']);
});
test('mixed single and multiple flags', () {
var options = overrideKnownFeatures(
knownFeatures,
() => parse([
(() => parse([
'--enable-experiment',
'a,b',
'--enable-experiment',
'c',
'foo.dart'
]));
])!));
expect(options.enabledExperiments, ['a', 'b', 'c']);
});
test('multiple flags', () {
var options = overrideKnownFeatures(
knownFeatures,
() => parse([
(() => parse([
'--enable-experiment',
'a',
'--enable-experiment',
'b',
'foo.dart'
]));
])!));
expect(options.enabledExperiments, ['a', 'b']);
});
});
});
test('hintsAreFatal', () {
var options = parse(['--dart-sdk', '.', '--fatal-hints', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '--fatal-hints', 'foo.dart'])!;
expect(options.infosAreFatal, isTrue);
});
test('infosAreFatal', () {
var options = parse(['--dart-sdk', '.', '--fatal-infos', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '--fatal-infos', 'foo.dart'])!;
expect(options.infosAreFatal, isTrue);
});
test('log', () {
var options = parse(['--dart-sdk', '.', '--log', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '--log', 'foo.dart'])!;
expect(options.log, isTrue);
});
group('format', () {
test('json', () {
var options = parse(['--dart-sdk', '.', '--format=json', 'foo.dart']);
var options =
parse(['--dart-sdk', '.', '--format=json', 'foo.dart'])!;
expect(options.jsonFormat, isTrue);
expect(options.machineFormat, isFalse);
});
test('machine', () {
var options =
parse(['--dart-sdk', '.', '--format=machine', 'foo.dart']);
parse(['--dart-sdk', '.', '--format=machine', 'foo.dart'])!;
expect(options.jsonFormat, isFalse);
expect(options.machineFormat, isTrue);
});
});
test('no-hints', () {
var options = parse(['--dart-sdk', '.', '--no-hints', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '--no-hints', 'foo.dart'])!;
expect(options.disableHints, isTrue);
});
test('options', () {
var options =
parse(['--dart-sdk', '.', '--options', 'options.yaml', 'foo.dart']);
var options = parse(
['--dart-sdk', '.', '--options', 'options.yaml', 'foo.dart'])!;
expect(options.defaultAnalysisOptionsPath, endsWith('options.yaml'));
});
test('lints', () {
var options = parse(['--dart-sdk', '.', '--lints', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '--lints', 'foo.dart'])!;
expect(options.lints, isTrue);
});
test('package warnings', () {
var options =
parse(['--dart-sdk', '.', '--package-warnings', 'foo.dart']);
parse(['--dart-sdk', '.', '--package-warnings', 'foo.dart'])!;
expect(options.showPackageWarnings, isTrue);
});
test('sdk warnings', () {
var options = parse(['--dart-sdk', '.', '--sdk-warnings', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '--sdk-warnings', 'foo.dart'])!;
expect(options.showSdkWarnings, isTrue);
});
test('sourceFiles', () {
var options = parse(
['--dart-sdk', '.', '--log', 'foo.dart', 'foo2.dart', 'foo3.dart']);
var options = parse([
'--dart-sdk',
'.',
'--log',
'foo.dart',
'foo2.dart',
'foo3.dart'
])!;
expect(options.sourceFiles,
equals(['foo.dart', 'foo2.dart', 'foo3.dart']));
});
test('warningsAreFatal', () {
var options =
parse(['--dart-sdk', '.', '--fatal-warnings', 'foo.dart']);
parse(['--dart-sdk', '.', '--fatal-warnings', 'foo.dart'])!;
expect(options.warningsAreFatal, isTrue);
});
@ -250,25 +257,25 @@ void main() {
'--dart-sdk',
'.',
'foo.dart'
]);
])!;
expect(options, isNotNull);
expect(options.sourceFiles, equals(['foo.dart']));
});
test('hintsAreFatal', () {
var options = parse(['--dart-sdk', '.', '--fatal-lints', 'foo.dart']);
var options = parse(['--dart-sdk', '.', '--fatal-lints', 'foo.dart'])!;
expect(options.lintsAreFatal, isTrue);
});
test('bad SDK dir', () {
String failureMessage;
String? failureMessage;
parse(['--dart-sdk', '&&&&&', 'foo.dart'],
printAndFail: (msg) => failureMessage = msg);
expect(failureMessage, equals('Invalid Dart SDK path: &&&&&'));
});
test('--train-snapshot', () {
var options = parse(['--train-snapshot', 'foo.dart']);
var options = parse(['--train-snapshot', 'foo.dart'])!;
expect(options.trainSnapshot, isTrue);
});
});
@ -278,13 +285,13 @@ void main() {
@reflectiveTest
class ArgumentsTest with ResourceProviderMixin {
CommandLineOptions commandLineOptions;
String failureMessage;
CommandLineOptions? commandLineOptions;
String? failureMessage;
void test_declaredVariables() {
_parse(['-Da=0', '-Db=', 'a.dart']);
var definedVariables = commandLineOptions.declaredVariables;
var definedVariables = commandLineOptions!.declaredVariables;
expect(definedVariables['a'], '0');
expect(definedVariables['b'], '');
@ -296,7 +303,7 @@ class ArgumentsTest with ResourceProviderMixin {
_parse(['--options=$expected', 'a.dart']);
expect(
commandLineOptions.defaultAnalysisOptionsPath,
commandLineOptions!.defaultAnalysisOptionsPath,
endsWith(expected),
);
}
@ -306,16 +313,16 @@ class ArgumentsTest with ResourceProviderMixin {
_parse(['--packages=$expected', 'a.dart']);
expect(
commandLineOptions.defaultPackagesPath,
commandLineOptions!.defaultPackagesPath,
endsWith(expected),
);
}
void test_defaults() {
_parse(['a.dart']);
expect(commandLineOptions.declaredVariables, isEmpty);
expect(commandLineOptions.defaultAnalysisOptionsPath, isNull);
expect(commandLineOptions.defaultPackagesPath, isNull);
expect(commandLineOptions!.declaredVariables, isEmpty);
expect(commandLineOptions!.defaultAnalysisOptionsPath, isNull);
expect(commandLineOptions!.defaultPackagesPath, isNull);
}
void test_filterUnknownArguments() {
@ -554,7 +561,7 @@ class ArgumentsTest with ResourceProviderMixin {
var analysisOptions = AnalysisOptionsImpl();
configureInitial(analysisOptions);
commandLineOptions.updateAnalysisOptions(analysisOptions);
commandLineOptions!.updateAnalysisOptions(analysisOptions);
checkApplied(analysisOptions);
}

View file

@ -13,7 +13,7 @@ import 'utils.dart' show testDirectory;
void main() {
group('--x-package-warnings-prefix', () {
_Runner runner;
late _Runner runner;
setUp(() {
runner = _Runner.setUp();
@ -21,7 +21,6 @@ void main() {
tearDown(() {
runner.tearDown();
runner = null;
});
test('shows only the hint whose package matches the prefix', () async {

View file

@ -15,7 +15,7 @@ void main() {
var options = CommandLineOptions.parse(
PhysicalResourceProvider.INSTANCE,
['somefile.dart'],
);
)!;
var encoded = makePerfReport(1000, 1234, options, 0, AnalysisStats());
var jsonData = json.decode(encoded);

View file

@ -2,6 +2,7 @@
// 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:analyzer/dart/analysis/session.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/dart/analysis/results.dart';
@ -14,10 +15,10 @@ import 'mocks.dart';
void main() {
group('reporter', () {
StringBuffer out;
AnalysisStats stats;
MockCommandLineOptions options;
ErrorFormatter reporter;
late StringBuffer out;
late AnalysisStats stats;
late MockCommandLineOptions options;
late ErrorFormatter reporter;
setUp(() {
ansi.runningTests = true;
@ -107,6 +108,11 @@ ErrorsResultImpl mockResult(ErrorType type, ErrorSeverity severity) {
var source = MockSource(path, package_path.toUri(path));
var error = MockAnalysisError(source, code, 20, 'MSG');
return ErrorsResultImpl(
null, source.fullName, null, lineInfo, false, [error]);
return ErrorsResultImpl(_MockAnslysisSession(), source.fullName,
Uri.file('/'), lineInfo, false, [error]);
}
class _MockAnslysisSession implements AnalysisSession {
@override
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

View file

@ -29,7 +29,7 @@ class StrongModeTest extends BaseTest {
expect(exitCode, 3);
var stdout = bulletToDash(outSink);
expect(stdout, contains("isn't a valid override of"));
expect(stdout, contains('error - The list literal type'));
expect(stdout, contains('error - A value of type'));
expect(stdout, contains('2 errors found'));
}
}

View file

@ -63,12 +63,12 @@ Stopwatch scanTimer = Stopwatch();
int scanTotalChars = 0;
/// Factory to load and resolve app, packages, and sdk sources.
SourceFactory sources;
late SourceFactory sources;
/// Add to [files] all sources reachable from [start].
void collectSources(Source start, Set<Source> files) {
void collectSources(Source? start, Set<Source?> files) {
if (!files.add(start)) return;
var unit = parseDirectives(start);
var unit = parseDirectives(start!);
for (var directive in unit.directives) {
if (directive is UriBasedDirective) {
var next = sources.resolveUri(start, directive.uri.stringValue);
@ -89,7 +89,7 @@ CompilationUnit parseDirectives(Source source) {
}
/// Parses every file in [files] and reports the time spent doing so.
void parseFiles(Set<Source> files) {
void parseFiles(Set<Source?> files) {
// The code below will record again how many chars are scanned and how long it
// takes to scan them, even though we already did so in [scanReachableFiles].
// Recording and reporting this twice is unnecessary, but we do so for now to
@ -99,7 +99,7 @@ void parseFiles(Set<Source> files) {
scanTotalChars = 0;
var parseTimer = Stopwatch()..start();
for (var source in files) {
parseFull(source);
parseFull(source!);
}
parseTimer.stop();
@ -132,7 +132,7 @@ void report(String name, int time) {
}
/// Scans every file in [files] and reports the time spent doing so.
void scanFiles(Set<Source> files) {
void scanFiles(Set<Source?> files) {
// The code below will record again how many chars are scanned and how long it
// takes to scan them, even though we already did so in [scanReachableFiles].
// Recording and reporting this twice is unnecessary, but we do so for now to
@ -141,7 +141,7 @@ void scanFiles(Set<Source> files) {
var old = scanTotalChars;
scanTotalChars = 0;
for (var source in files) {
tokenize(source);
tokenize(source!);
}
// Report size and scanning time again. See discussion above.
@ -151,8 +151,8 @@ void scanFiles(Set<Source> files) {
/// Load and scans all files we need to process: files reachable from the
/// entrypoint and all core libraries automatically included by the VM.
Set<Source> scanReachableFiles(Uri entryUri) {
var files = <Source>{};
Set<Source?> scanReachableFiles(Uri entryUri) {
var files = <Source?>{};
var loadTimer = Stopwatch()..start();
collectSources(sources.forUri2(entryUri), files);