Skip to content

Commit d35e94c

Browse files
pqcommit-bot@chromium.org
authored andcommitted
Validate incompatible lint rules
Change-Id: Ic57cdf7c7264c7d4da266f73a63b0b47e4a1d65a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/130007 Commit-Queue: Phil Quitslund <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 29e89f5 commit d35e94c

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

pkg/analyzer/lib/src/lint/options_rule_validator.dart

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'dart:collection';
6-
75
import 'package:analyzer/error/error.dart';
86
import 'package:analyzer/error/listener.dart';
97
import 'package:analyzer/src/analysis_options/error/option_codes.dart';
@@ -34,6 +32,18 @@ const AnalysisOptionsHintCode DUPLICATE_RULE_HINT = AnalysisOptionsHintCode(
3432
"The rule {0} is already specified and doesn't need to be specified again.",
3533
correction: "Try removing all but one specification of the rule.");
3634

35+
/**
36+
* An error code indicating an incompatible rule.
37+
*
38+
* Parameters:
39+
* 0: the rule name
40+
* 1: the incompatible rule
41+
*/
42+
const AnalysisOptionsWarningCode INCOMPATIBLE_LINT_WARNING =
43+
AnalysisOptionsWarningCode('INCOMPATIBLE_LINT_WARNING',
44+
"The rule '{0}' is incompatible with the rule '{1}'",
45+
correction: "Try removing one of the incompatible rules.");
46+
3747
/**
3848
* An error code indicating an undefined lint rule.
3949
*
@@ -77,14 +87,31 @@ class LinterRuleOptionsValidator extends OptionsValidator {
7787

7888
validateRules(YamlNode rules, ErrorReporter reporter) {
7989
if (rules is YamlList) {
80-
Set<String> seenRules = HashSet<String>();
81-
rules.nodes.forEach((YamlNode ruleNode) {
82-
Object value = ruleNode.value;
90+
final seenRules = <String>{};
91+
92+
String findIncompatibleRule(LintRule rule) {
93+
for (var incompatibleRule in rule.incompatibleRules) {
94+
if (seenRules.contains(incompatibleRule)) {
95+
return incompatibleRule;
96+
}
97+
}
98+
return null;
99+
}
100+
101+
for (var ruleNode in rules.nodes) {
102+
final value = ruleNode.value;
83103
if (value != null) {
84-
LintRule rule = getRegisteredLint(value);
104+
final rule = getRegisteredLint(value);
85105
if (rule == null) {
86106
reporter.reportErrorForSpan(
87107
UNDEFINED_LINT_WARNING, ruleNode.span, [value]);
108+
continue;
109+
}
110+
111+
final incompatibleRule = findIncompatibleRule(rule);
112+
if (incompatibleRule != null) {
113+
reporter.reportErrorForSpan(INCOMPATIBLE_LINT_WARNING,
114+
ruleNode.span, [value, incompatibleRule]);
88115
} else if (!seenRules.add(rule.name)) {
89116
reporter.reportErrorForSpan(
90117
DUPLICATE_RULE_HINT, ruleNode.span, [value]);
@@ -93,7 +120,7 @@ class LinterRuleOptionsValidator extends OptionsValidator {
93120
DEPRECATED_LINT_HINT, ruleNode.span, [value]);
94121
}
95122
}
96-
});
123+
}
97124
}
98125
}
99126
}

pkg/analyzer/test/src/options/options_rule_validator_test.dart

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class DeprecatedLint extends LintRule {
3030
@reflectiveTest
3131
class OptionsRuleValidatorTest extends Object with ResourceProviderMixin {
3232
LinterRuleOptionsValidator validator = LinterRuleOptionsValidator(
33-
provider: () => [DeprecatedLint(), StableLint()]);
33+
provider: () => [DeprecatedLint(), StableLint(), RuleNeg(), RulePos()]);
3434

3535
/**
3636
* Assert that when the validator is used on the given [content] the
@@ -64,6 +64,15 @@ linter:
6464
''', [DUPLICATE_RULE_HINT]);
6565
}
6666

67+
test_incompatible_rule() {
68+
assertErrors('''
69+
linter:
70+
rules:
71+
- rule_pos
72+
- rule_neg
73+
''', [INCOMPATIBLE_LINT_WARNING]);
74+
}
75+
6776
test_stable_rule() {
6877
assertErrors('''
6978
linter:
@@ -86,3 +95,15 @@ class StableLint extends LintRule {
8695
: super(
8796
name: 'stable_lint', group: Group.style, maturity: Maturity.stable);
8897
}
98+
99+
class RuleNeg extends LintRule {
100+
RuleNeg() : super(name: 'rule_neg', group: Group.style);
101+
@override
102+
List<String> get incompatibleRules => ['rule_pos'];
103+
}
104+
105+
class RulePos extends LintRule {
106+
RulePos() : super(name: 'rule_pos', group: Group.style);
107+
@override
108+
List<String> get incompatibleRules => ['rule_neg'];
109+
}

0 commit comments

Comments
 (0)