hint for duplicated lint rules
Change-Id: Ieee5add24bc3517e61fdf4c1f90fb217f8321295
Reviewed-on: https://dart-review.googlesource.com/c/87140
Commit-Queue: Phil Quitslund <pquitslund@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/lint/options_rule_validator.dart b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
index 0858037..9b28b1a 100644
--- a/pkg/analyzer/lib/src/lint/options_rule_validator.dart
+++ b/pkg/analyzer/lib/src/lint/options_rule_validator.dart
@@ -2,6 +2,8 @@
// 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 'dart:collection';
+
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/analysis_options/error/option_codes.dart';
@@ -22,6 +24,17 @@
"'{0}' is a deprecated lint rule and should not be used");
/**
+ * Duplicate rules.
+ *
+ * Parameters:
+ * 0: the rule name
+ */
+const AnalysisOptionsHintCode DUPLICATE_RULE_HINT = const AnalysisOptionsHintCode(
+ 'DUPLICATE_RULE',
+ "The rule {0} is already specified and doesn't need to be specified again.",
+ correction: "Try removing all but one specification of the rule.");
+
+/**
* An error code indicating an undefined lint rule.
*
* Parameters:
@@ -48,6 +61,9 @@
LinterRuleOptionsValidator({LintRuleProvider provider})
: ruleProvider = provider ?? (() => Registry.ruleRegistry.rules);
+ LintRule getRegisteredLint(Object value) => ruleProvider()
+ .firstWhere((rule) => rule.name == value, orElse: () => null);
+
@override
List<AnalysisError> validate(ErrorReporter reporter, YamlMap options) {
List<AnalysisError> errors = <AnalysisError>[];
@@ -61,6 +77,7 @@
validateRules(YamlNode rules, ErrorReporter reporter) {
if (rules is YamlList) {
+ Set<String> seenRules = new HashSet<String>();
rules.nodes.forEach((YamlNode ruleNode) {
Object value = ruleNode.value;
if (value != null) {
@@ -68,6 +85,9 @@
if (rule == null) {
reporter.reportErrorForSpan(
UNDEFINED_LINT_WARNING, ruleNode.span, [value]);
+ } else if (!seenRules.add(rule.name)) {
+ reporter.reportErrorForSpan(
+ DUPLICATE_RULE_HINT, ruleNode.span, [value]);
} else if (rule.maturity == Maturity.deprecated) {
reporter.reportErrorForSpan(
DEPRECATED_LINT_HINT, ruleNode.span, [value]);
@@ -76,7 +96,4 @@
});
}
}
-
- LintRule getRegisteredLint(Object value) => ruleProvider()
- .firstWhere((rule) => rule.name == value, orElse: () => null);
}
diff --git a/pkg/analyzer/test/src/options/options_rule_validator_test.dart b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
index fad56f3..5150828 100644
--- a/pkg/analyzer/test/src/options/options_rule_validator_test.dart
+++ b/pkg/analyzer/test/src/options/options_rule_validator_test.dart
@@ -27,12 +27,6 @@
maturity: Maturity.deprecated);
}
-class StableLint extends LintRule {
- StableLint()
- : super(
- name: 'stable_lint', group: Group.style, maturity: Maturity.stable);
-}
-
@reflectiveTest
class OptionsRuleValidatorTest extends Object with ResourceProviderMixin {
LinterRuleOptionsValidator validator = new LinterRuleOptionsValidator(
@@ -58,6 +52,15 @@
''', [DEPRECATED_LINT_HINT]);
}
+ test_duplicated_rule() {
+ assertErrors('''
+linter:
+ rules:
+ - stable_lint
+ - stable_lint
+ ''', [DUPLICATE_RULE_HINT]);
+ }
+
test_stable_rule() {
assertErrors('''
linter:
@@ -74,3 +77,9 @@
''', [UNDEFINED_LINT_WARNING]);
}
}
+
+class StableLint extends LintRule {
+ StableLint()
+ : super(
+ name: 'stable_lint', group: Group.style, maturity: Maturity.stable);
+}