Skip to content

Commit bb4850b

Browse files
DanTupCommit Queue
authored andcommitted
[analyzer] Don't run lints for files that don't exist
Fixes Dart-Code/Dart-Code#5343 Change-Id: I428d3f38334503bb1285afd157ebb5440e0912ed Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398881 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]>
1 parent 239b5c2 commit bb4850b

File tree

3 files changed

+117
-0
lines changed

3 files changed

+117
-0
lines changed

pkg/analysis_server/test/lsp/diagnostic_test.dart

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'dart:async';
66

77
import 'package:analysis_server/lsp_protocol/protocol.dart';
8+
import 'package:analysis_server/src/services/correction/fix_internal.dart';
89
import 'package:analyzer/src/lint/registry.dart';
910
import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
1011
import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin;
@@ -429,6 +430,32 @@ void f() {
429430
await expectNoUpdate(() => replaceFile(3, mainFileUri, 'void h() {}'));
430431
}
431432

433+
/// Verify that computation of the QuickFix for "Create file 'Foo.dart'" does
434+
/// not trigger lint warnings for that file because the CreateFile fix tries
435+
/// to get a resolved unit which triggers analysis.
436+
///
437+
/// https://github.com/Dart-Code/Dart-Code/issues/5343
438+
Future<void> test_exportMissingFile_noDiagnosticInMissingFile() async {
439+
registerLintRules();
440+
registerBuiltInProducers();
441+
setSupportedCodeActionKinds([CodeActionKind.QuickFix]);
442+
newFile(mainFilePath, "export 'Danny.dart';");
443+
newFile('$testPackageRootPath/lib/analysis_options.yaml', '''
444+
linter:
445+
rules:
446+
- file_names
447+
''');
448+
449+
await initialize();
450+
var pos = Position(line: 0, character: 0);
451+
await getCodeActions(mainFileUri, position: pos);
452+
await pumpEventQueue(times: 5000);
453+
454+
// We don't expect the lint diagnostic for the filename Danny.dart because
455+
// it doesn't exist.
456+
expect(diagnostics.keys, [mainFileUri]);
457+
}
458+
432459
Future<void> test_fixDataFile() async {
433460
var fixDataPath = join(projectFolderPath, 'lib', 'fix_data.yaml');
434461
var fixDataUri = pathContext.toUri(fixDataPath);

pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ class LibraryAnalyzer {
403403
// Skip computing lints on macro generated augmentations.
404404
// See: https://github.com/dart-lang/sdk/issues/54875
405405
if (fileAnalysis.file.isMacroPart) return;
406+
// Skip computing lints on files that don't exist.
407+
// See: https://github.com/Dart-Code/Dart-Code/issues/5343
408+
if (!fileAnalysis.file.exists) continue;
406409

407410
var unit = currentUnit.unit;
408411
var errorReporter = currentUnit.errorReporter;

pkg/analyzer/test/src/dart/analysis/driver_test.dart

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import 'dart:async';
66

77
import 'package:analyzer/dart/analysis/results.dart';
8+
import 'package:analyzer/dart/ast/ast.dart';
9+
import 'package:analyzer/dart/ast/visitor.dart';
10+
import 'package:analyzer/error/error.dart';
811
import 'package:analyzer/file_system/file_system.dart';
912
import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
1013
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -13,6 +16,8 @@ import 'package:analyzer/src/dart/analysis/file_state.dart';
1316
import 'package:analyzer/src/dart/analysis/status.dart';
1417
import 'package:analyzer/src/dart/element/element.dart';
1518
import 'package:analyzer/src/error/codes.dart';
19+
import 'package:analyzer/src/lint/linter.dart';
20+
import 'package:analyzer/src/lint/registry.dart';
1621
import 'package:analyzer/src/utilities/extensions/async.dart';
1722
import 'package:analyzer_utilities/testing/tree_string_sink.dart';
1823
import 'package:linter/src/rules.dart';
@@ -29,6 +34,7 @@ main() {
2934
defineReflectiveSuite(() {
3035
defineReflectiveTests(AnalysisDriver_PubPackageTest);
3136
defineReflectiveTests(AnalysisDriver_BlazeWorkspaceTest);
37+
defineReflectiveTests(AnalysisDriver_LintTest);
3238
defineReflectiveTests(UpdateNodeTextExpectations);
3339
});
3440
}
@@ -84,6 +90,49 @@ import '$innerUri';
8490
}
8591
}
8692

93+
@reflectiveTest
94+
class AnalysisDriver_LintTest extends PubPackageResolutionTest {
95+
@override
96+
void setUp() {
97+
super.setUp();
98+
99+
useEmptyByteStore();
100+
Registry.ruleRegistry.registerLintRule(_AlwaysReportedLint.instance);
101+
writeTestPackageAnalysisOptionsFile(analysisOptionsContent(
102+
rules: [_AlwaysReportedLint.code.name],
103+
));
104+
}
105+
106+
@override
107+
Future<void> tearDown() {
108+
Registry.ruleRegistry.unregisterLintRule(_AlwaysReportedLint.instance);
109+
return super.tearDown();
110+
}
111+
112+
test_getResolvedUnit_lint_existingFile() async {
113+
addTestFile('');
114+
await resolveTestFile();
115+
116+
// Existing/empty file triggers the lint.
117+
_assertHasLintReported(result.errors, _AlwaysReportedLint.code.name);
118+
}
119+
120+
test_getResolvedUnit_lint_notExistingFile() async {
121+
await resolveTestFile();
122+
123+
// No errors for a file that doesn't exist.
124+
assertErrorsInResult([]);
125+
}
126+
127+
void _assertHasLintReported(List<AnalysisError> errors, String name) {
128+
var matching = errors.where((element) {
129+
var errorCode = element.errorCode;
130+
return errorCode is LintCode && errorCode.name == name;
131+
}).toList();
132+
expect(matching, hasLength(1));
133+
}
134+
}
135+
87136
@reflectiveTest
88137
class AnalysisDriver_PubPackageTest extends PubPackageResolutionTest {
89138
final DriverEventsPrinterConfiguration configuration =
@@ -6048,6 +6097,44 @@ class DriverEventCollector {
60486097
}
60496098
}
60506099

6100+
/// A lint that is always reported for all linted files.
6101+
class _AlwaysReportedLint extends LintRule {
6102+
static final instance = _AlwaysReportedLint();
6103+
6104+
static const LintCode code = LintCode(
6105+
'always_reported_lint',
6106+
'This lint is reported for all files',
6107+
);
6108+
6109+
_AlwaysReportedLint()
6110+
: super(
6111+
name: 'always_reported_lint',
6112+
description: '',
6113+
);
6114+
6115+
@override
6116+
LintCode get lintCode => code;
6117+
6118+
@override
6119+
void registerNodeProcessors(
6120+
NodeLintRegistry registry, LinterContext context) {
6121+
var visitor = _AlwaysReportedLintVisitor(this);
6122+
registry.addCompilationUnit(this, visitor);
6123+
}
6124+
}
6125+
6126+
/// A visitor for [_AlwaysReportedLint] that reports the lint for all files.
6127+
class _AlwaysReportedLintVisitor extends SimpleAstVisitor<void> {
6128+
final LintRule rule;
6129+
6130+
_AlwaysReportedLintVisitor(this.rule);
6131+
6132+
@override
6133+
void visitCompilationUnit(CompilationUnit node) {
6134+
rule.reportLintForOffset(0, 0);
6135+
}
6136+
}
6137+
60516138
extension on AnalysisDriver {
60526139
Future<void> assertFilesDefiningClassMemberName(
60536140
String name,

0 commit comments

Comments
 (0)