From 8aa021f31eb7be789da4c192684974ef1d3fc11c Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Mon, 5 May 2025 15:44:14 -0700 Subject: [PATCH] linter: Use Diagnostic instead of deprecated AnalysisError Work towards https://github.com/dart-lang/sdk/issues/60635 Change-Id: I225bcbe2c0033872b0349258f7f2135aab6a8d20 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426561 Reviewed-by: Brian Wilkerson Commit-Queue: Samuel Rawlins --- .../test_utilities/analysis_error_info.dart | 10 ++--- .../lib/src/test_utilities/lint_driver.dart | 8 ++-- .../lib/src/test_utilities/test_linter.dart | 10 ++--- pkg/linter/test/formatter_test.dart | 8 ++-- pkg/linter/test/rule_test_support.dart | 40 ++++++++++-------- pkg/linter/tool/benchmark.dart | 4 +- pkg/linter/tool/checks/driver.dart | 16 +++---- pkg/linter/tool/util/formatter.dart | 42 ++++++++++--------- 8 files changed, 71 insertions(+), 67 deletions(-) diff --git a/pkg/linter/lib/src/test_utilities/analysis_error_info.dart b/pkg/linter/lib/src/test_utilities/analysis_error_info.dart index c3b29859c98..f7e6f863dd2 100644 --- a/pkg/linter/lib/src/test_utilities/analysis_error_info.dart +++ b/pkg/linter/lib/src/test_utilities/analysis_error_info.dart @@ -2,18 +2,18 @@ // 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/error/error.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/source/line_info.dart'; -/// The analysis errors and line info associated with a source. -class AnalysisErrorInfo { +/// The analysis diagnostics and line info associated with a source. +class DiagnosticInfo { /// The analysis errors associated with a source, or `null` if there are no /// errors. - final List errors; + final List diagnostics; /// The line information associated with the errors, or `null` if there are no /// errors. final LineInfo lineInfo; - AnalysisErrorInfo(this.errors, this.lineInfo); + DiagnosticInfo(this.diagnostics, this.lineInfo); } diff --git a/pkg/linter/lib/src/test_utilities/lint_driver.dart b/pkg/linter/lib/src/test_utilities/lint_driver.dart index 76f4e7c580a..9b66b0e3991 100644 --- a/pkg/linter/lib/src/test_utilities/lint_driver.dart +++ b/pkg/linter/lib/src/test_utilities/lint_driver.dart @@ -28,7 +28,7 @@ class LintDriver { LintDriver(this._options, this._resourceProvider); - Future> analyze(Iterable files) async { + Future> analyze(Iterable files) async { AnalysisEngine.instance.instrumentationService = _StdInstrumentation(); var filesPaths = @@ -50,14 +50,12 @@ class LintDriver { _filesAnalyzed.addAll(filesPaths); - var result = []; + var result = []; for (var path in _filesAnalyzed) { var analysisSession = contextCollection.contextFor(path).currentSession; var errorsResult = await analysisSession.getErrors(path); if (errorsResult is ErrorsResult) { - result.add( - AnalysisErrorInfo(errorsResult.errors, errorsResult.lineInfo), - ); + result.add(DiagnosticInfo(errorsResult.errors, errorsResult.lineInfo)); } } return result; diff --git a/pkg/linter/lib/src/test_utilities/test_linter.dart b/pkg/linter/lib/src/test_utilities/test_linter.dart index 0ef98a132b5..8c453a60f35 100644 --- a/pkg/linter/lib/src/test_utilities/test_linter.dart +++ b/pkg/linter/lib/src/test_utilities/test_linter.dart @@ -4,7 +4,7 @@ import 'dart:io'; -import 'package:analyzer/error/error.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/file_system/file_system.dart' as file_system; import 'package:analyzer/file_system/physical_file_system.dart' as file_system; @@ -29,7 +29,7 @@ Source _createSource(Uri uri) { /// Dart source linter, only for package:linter's tools and tests. class TestLinter implements AnalysisErrorListener { - final errors = []; + final errors = []; final LinterOptions options; final file_system.ResourceProvider _resourceProvider; @@ -38,8 +38,8 @@ class TestLinter implements AnalysisErrorListener { : _resourceProvider = resourceProvider ?? file_system.PhysicalResourceProvider.INSTANCE; - Future> lintFiles(List files) async { - var errors = []; + Future> lintFiles(List files) async { + var errors = []; var lintDriver = LintDriver(options, _resourceProvider); errors.addAll(await lintDriver.analyze(files.where(isDartFile))); for (var file in files.where(isPubspecFile)) { @@ -76,5 +76,5 @@ class TestLinter implements AnalysisErrorListener { } @override - void onError(AnalysisError error) => errors.add(error); + void onError(Diagnostic error) => errors.add(error); } diff --git a/pkg/linter/test/formatter_test.dart b/pkg/linter/test/formatter_test.dart index b4fee450884..1cc00a07298 100644 --- a/pkg/linter/test/formatter_test.dart +++ b/pkg/linter/test/formatter_test.dart @@ -2,7 +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/error/error.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:linter/src/analyzer.dart'; import 'package:linter/src/test_utilities/analysis_error_info.dart'; import 'package:test/test.dart'; @@ -24,7 +24,7 @@ void defineTests() { }); group('reporter', () { - late AnalysisErrorInfo info; + late DiagnosticInfo info; late StringBuffer out; late String sourcePath; late ReportFormatter reporter; @@ -46,14 +46,14 @@ var z = 33; sourcePath = '${d.sandbox}/project/foo.dart'; var source = MockSource(sourcePath); - var error = AnalysisError.tmp( + var error = Diagnostic.tmp( source: source, offset: 10, length: 3, errorCode: code, ); - info = AnalysisErrorInfo([error], lineInfo); + info = DiagnosticInfo([error], lineInfo); out = StringBuffer(); reporter = ReportFormatter([info], out)..write(); }); diff --git a/pkg/linter/test/rule_test_support.dart b/pkg/linter/test/rule_test_support.dart index a25fe9f16b7..917f3cb3480 100644 --- a/pkg/linter/test/rule_test_support.dart +++ b/pkg/linter/test/rule_test_support.dart @@ -5,6 +5,7 @@ import 'dart:convert' show json; import 'package:analyzer/dart/analysis/results.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/error/error.dart'; import 'package:analyzer/error/listener.dart'; import 'package:analyzer/file_system/file_system.dart'; @@ -41,7 +42,7 @@ ExpectedDiagnostic error( Pattern? messageContains, }) => _ExpectedError(code, offset, length, messageContains: messageContains); -typedef DiagnosticMatcher = bool Function(AnalysisError error); +typedef DiagnosticMatcher = bool Function(Diagnostic diagnostic); /// A description of a diagnostic that is expected to be reported. class ExpectedDiagnostic { @@ -70,16 +71,17 @@ class ExpectedDiagnostic { }) : _messageContains = messageContains, _correctionContains = correctionContains; - /// Whether the [error] matches this description of what it's expected to be. - bool matches(AnalysisError error) { - if (!_diagnosticMatcher(error)) return false; - if (error.offset != _offset) return false; - if (error.length != _length) return false; - if (_messageContains != null && !error.message.contains(_messageContains)) { + /// Whether the [diagnostic] matches this description of what it's expected to be. + bool matches(Diagnostic diagnostic) { + if (!_diagnosticMatcher(diagnostic)) return false; + if (diagnostic.offset != _offset) return false; + if (diagnostic.length != _length) return false; + if (_messageContains != null && + !diagnostic.message.contains(_messageContains)) { return false; } if (_correctionContains != null) { - var correctionMessage = error.correctionMessage; + var correctionMessage = diagnostic.correctionMessage; if (correctionMessage == null || !correctionMessage.contains(_correctionContains)) { return false; @@ -202,7 +204,7 @@ class PubPackageResolutionTest extends _ContextResolutionTest { ) async { addTestFile(content); await resolveTestFile(); - await _assertDiagnosticsIn(_errors, expectedDiagnostics); + await _assertDiagnosticsIn(_diagnostics, expectedDiagnostics); } /// Asserts that the number of diagnostics that have been gathered at [path] @@ -215,7 +217,7 @@ class PubPackageResolutionTest extends _ContextResolutionTest { List expectedDiagnostics, ) async { await _resolveFile(path); - await _assertDiagnosticsIn(_errors, expectedDiagnostics); + await _assertDiagnosticsIn(_diagnostics, expectedDiagnostics); } /// Asserts that the diagnostics for each `path` match those in the paired @@ -334,15 +336,15 @@ class PubPackageResolutionTest extends _ContextResolutionTest { writePackageConfig(path, configCopy); } - /// Asserts that the diagnostics in [errors] match [expectedDiagnostics]. + /// Asserts that the diagnostics in [diagnostics] match [expectedDiagnostics]. Future _assertDiagnosticsIn( - List errors, + List diagnostics, List expectedDiagnostics, ) async { // // Match actual diagnostics to expected diagnostics. // - var unmatchedActual = errors.toList(); + var unmatchedActual = diagnostics.toList(); var unmatchedExpected = expectedDiagnostics.toList(); var actualIndex = 0; while (actualIndex < unmatchedActual.length) { @@ -414,10 +416,12 @@ class PubPackageResolutionTest extends _ContextResolutionTest { } } if (buffer.isNotEmpty) { - errors.sort((first, second) => first.offset.compareTo(second.offset)); + diagnostics.sort( + (first, second) => first.offset.compareTo(second.offset), + ); buffer.writeln(); buffer.writeln('To accept the current state, expect:'); - for (var actual in errors) { + for (var actual in diagnostics) { late String diagnosticKind; Object? description; if (actual.errorCode is LintCode) { @@ -461,7 +465,7 @@ class PubPackageResolutionTest extends _ContextResolutionTest { } } - Future> _resolvePubspecFile(String content) async { + Future> _resolvePubspecFile(String content) async { var path = convertPath(testPackagePubspecPath); var pubspecRules = >{}; for (var rule in Registry.ruleRegistry.where( @@ -530,8 +534,8 @@ abstract class _ContextResolutionTest List get _collectionIncludedPaths; - /// The analysis errors that were computed during analysis. - List get _errors => + /// The diagnostics that were computed during analysis. + List get _diagnostics => result.errors .whereNot((e) => ignoredErrorCodes.any((c) => e.errorCode == c)) .toList(); diff --git a/pkg/linter/tool/benchmark.dart b/pkg/linter/tool/benchmark.dart index 19f84bdb798..ac80aaca8fa 100644 --- a/pkg/linter/tool/benchmark.dart +++ b/pkg/linter/tool/benchmark.dart @@ -214,8 +214,8 @@ Future writeBenchmarks( out.writeTimings(stats, 0); } -int _maxSeverity(List infos) { - var filteredErrors = infos.expand((i) => i.errors); +int _maxSeverity(List infos) { + var filteredErrors = infos.expand((i) => i.diagnostics); return filteredErrors.fold( 0, (value, e) => math.max(value, e.errorCode.errorSeverity.ordinal), diff --git a/pkg/linter/tool/checks/driver.dart b/pkg/linter/tool/checks/driver.dart index 886e2c90c32..01b4acdcc96 100644 --- a/pkg/linter/tool/checks/driver.dart +++ b/pkg/linter/tool/checks/driver.dart @@ -6,7 +6,7 @@ import 'dart:io' as io; import 'package:analyzer/dart/analysis/analysis_context_collection.dart'; import 'package:analyzer/dart/analysis/results.dart'; -import 'package:analyzer/error/error.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/file_system/file_system.dart'; import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:analyzer/src/dart/analysis/analysis_options.dart'; @@ -32,7 +32,7 @@ Future main() async { var customChecks = [VisitRegisteredNodes(), NoSoloTests(), NoTrailingSpaces()]; -Future> runChecks() async { +Future> runChecks() async { var rules = path.normalize( io.File(path.join('lib', 'src', 'rules')).absolute.path, ); @@ -49,7 +49,7 @@ class Driver { Driver(this.lints, {this.silent = true}); - Future> analyze(List sources) async { + Future> analyze(List sources) async { if (sources.isEmpty) { _print('Specify one or more files and directories.'); return []; @@ -60,7 +60,7 @@ class Driver { return failedChecks; } - Future> _analyzeFiles( + Future> _analyzeFiles( ResourceProvider resourceProvider, List analysisRoots, ) async { @@ -70,7 +70,7 @@ class Driver { lints.forEach(Registry.ruleRegistry.registerLintRule); // Track failures. - var failedChecks = {}; + var failedChecks = {}; for (var root in analysisRoots) { var collection = AnalysisContextCollection( @@ -78,7 +78,7 @@ class Driver { resourceProvider: resourceProvider, ); - var errors = []; + var errors = []; for (var context in collection.contexts) { // Add lints. @@ -100,7 +100,7 @@ class Driver { .where((e) => e.errorCode.name != 'TODO') .toList(); if (filtered.isNotEmpty) { - errors.add(AnalysisErrorInfo(filtered, result.lineInfo)); + errors.add(DiagnosticInfo(filtered, result.lineInfo)); } } } on Exception catch (e) { @@ -113,7 +113,7 @@ class Driver { ReportFormatter(errors, silent ? MockIOSink() : io.stdout).write(); for (var info in errors) { - failedChecks.addAll(info.errors); + failedChecks.addAll(info.diagnostics); } } diff --git a/pkg/linter/tool/util/formatter.dart b/pkg/linter/tool/util/formatter.dart index f9a6fc9ad46..a6dda7dbf26 100644 --- a/pkg/linter/tool/util/formatter.dart +++ b/pkg/linter/tool/util/formatter.dart @@ -5,15 +5,15 @@ import 'dart:io'; import 'dart:math'; -import 'package:analyzer/error/error.dart'; +import 'package:analyzer/diagnostic/diagnostic.dart'; import 'package:analyzer/source/line_info.dart'; import 'package:linter/src/test_utilities/analysis_error_info.dart'; String pluralize(String word, int count) => "$count ${count == 1 ? word : '${word}s'}"; -String _getLineContents(int lineNumber, AnalysisError error) { - var path = error.source.fullName; +String _getLineContents(int lineNumber, Diagnostic diagnostic) { + var path = diagnostic.source.fullName; var file = File(path); String failureDetails; if (!file.existsSync()) { @@ -32,31 +32,31 @@ String _getLineContents(int lineNumber, AnalysisError error) { class ReportFormatter { final StringSink out; - final Iterable errors; + final Iterable errors; int errorCount = 0; ReportFormatter(this.errors, this.out); - /// Override to influence error sorting. - int compare(AnalysisError error1, AnalysisError error2) { + /// Override to influence diagnostic sorting. + int compare(Diagnostic diagnostic1, Diagnostic diagnostic2) { // Severity. - var compare = error2.errorCode.errorSeverity.compareTo( - error1.errorCode.errorSeverity, + var compare = diagnostic2.errorCode.errorSeverity.compareTo( + diagnostic1.errorCode.errorSeverity, ); if (compare != 0) { return compare; } // Path. compare = Comparable.compare( - error1.source.fullName.toLowerCase(), - error2.source.fullName.toLowerCase(), + diagnostic1.source.fullName.toLowerCase(), + diagnostic2.source.fullName.toLowerCase(), ); if (compare != 0) { return compare; } // Offset. - return error1.offset - error2.offset; + return diagnostic1.offset - diagnostic2.offset; } void write() { @@ -66,38 +66,40 @@ class ReportFormatter { } void writeLint( - AnalysisError error, { + Diagnostic diagnostic, { required int offset, required int line, required int column, }) { // test/engine_test.dart 452:9 [lint] DO name types using UpperCamelCase. out - ..write('${error.source.fullName} ') + ..write('${diagnostic.source.fullName} ') ..write('$line:$column ') - ..writeln('[${error.errorCode.type.displayName}] ${error.message}'); - var contents = _getLineContents(line, error); + ..writeln( + '[${diagnostic.errorCode.type.displayName}] ${diagnostic.message}', + ); + var contents = _getLineContents(line, diagnostic); out.writeln(contents); var spaces = column - 1; - var arrows = max(1, min(error.length, contents.length - spaces)); + var arrows = max(1, min(diagnostic.length, contents.length - spaces)); var result = '${" " * spaces}${"^" * arrows}'; out.writeln(result); } - void _writeLint(AnalysisError error, LineInfo lineInfo) { - var offset = error.offset; + void _writeLint(Diagnostic diagnostic, LineInfo lineInfo) { + var offset = diagnostic.offset; var location = lineInfo.getLocation(offset); var line = location.lineNumber; var column = location.columnNumber; - writeLint(error, offset: offset, column: column, line: line); + writeLint(diagnostic, offset: offset, column: column, line: line); } void _writeLints() { for (var info in errors) { - for (var e in (info.errors.toList()..sort(compare))) { + for (var e in (info.diagnostics.toList()..sort(compare))) { ++errorCount; _writeLint(e, info.lineInfo); }