Skip to content
This repository was archived by the owner on Jul 16, 2023. It is now read-only.

Commit 2bb60d4

Browse files
authored
feat: show warning for rules without config that require config to work (#1125)
1 parent 8af25bd commit 2bb60d4

File tree

5 files changed

+66
-20
lines changed

5 files changed

+66
-20
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
* feat: show warning for rules without config that require config to work.
56
* fix: correctly handle FunctionExpressions for [`avoid-redundant-async`](https://dartcodemetrics.dev/docs/rules/common/avoid-redundant-async).
67
* feat: support ignoring nesting for [`prefer-conditional-expressions`](https://dartcodemetrics.dev/docs/rules/common/prefer-conditional-expressions).
78
* fix: ignore Providers for ['avoid-returning-widgets'](https://dartcodemetrics.dev/docs/rules/common/avoid-returning-widgets).

lib/src/analyzers/lint_analyzer/lint_analysis_options_validator.dart

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'lint_analysis_config.dart';
99
import 'models/issue.dart';
1010
import 'models/lint_file_report.dart';
1111
import 'models/severity.dart';
12+
import 'rules/models/rule.dart';
1213
import 'rules/rules_factory.dart';
1314

1415
class LintAnalysisOptionsValidator {
@@ -29,24 +30,12 @@ class LintAnalysisOptionsValidator {
2930
return null;
3031
}
3132

32-
final ids = allRuleIds.toSet();
33-
final issues = <Issue>[];
34-
35-
for (final rule in rulesList) {
36-
if (!ids.contains(rule.ruleName)) {
37-
issues.add(
38-
Issue(
39-
ruleId: 'unknown-config',
40-
severity: Severity.warning,
41-
message:
42-
"'${rule.ruleName}' is not recognized as a valid rule name.",
43-
documentation: Uri.parse('https://dartcodemetrics.dev/docs/rules'),
44-
location: _copySpanWithOffset(rule.span),
45-
),
46-
);
47-
}
48-
}
33+
final parsedRulesById = config.codeRules.fold(
34+
<String, Rule>{},
35+
(rules, rule) => rules..putIfAbsent(rule.id, () => rule),
36+
);
4937

38+
final issues = _validateForIssues(rulesList, parsedRulesById);
5039
if (issues.isNotEmpty) {
5140
final filePath = file.path;
5241
final relativePath = relative(filePath, from: rootFolder);
@@ -72,12 +61,20 @@ class LintAnalysisOptionsValidator {
7261
if (rule is YamlMap) {
7362
final key = rule.nodes.keys.first as Object?;
7463
if (key is YamlScalar && key.value is String) {
75-
return _RuleWithSpan(key.value as String, key.span);
64+
return _RuleWithSpan(
65+
key.value as String,
66+
key.span,
67+
hasConfig: true,
68+
);
7669
}
7770
}
7871

7972
if (rule is YamlScalar && rule.value is String) {
80-
return _RuleWithSpan(rule.value as String, rule.span);
73+
return _RuleWithSpan(
74+
rule.value as String,
75+
rule.span,
76+
hasConfig: false,
77+
);
8178
}
8279

8380
return null;
@@ -105,11 +102,51 @@ class LintAnalysisOptionsValidator {
105102
),
106103
span.text,
107104
);
105+
106+
static List<Issue> _validateForIssues(
107+
List<_RuleWithSpan> rulesList,
108+
Map<String, Rule> parsedRulesById,
109+
) {
110+
final ids = allRuleIds.toSet();
111+
final issues = <Issue>[];
112+
113+
for (final rule in rulesList) {
114+
if (!ids.contains(rule.ruleName)) {
115+
issues.add(
116+
Issue(
117+
ruleId: 'unknown-config',
118+
severity: Severity.warning,
119+
message:
120+
"'${rule.ruleName}' is not recognized as a valid rule name.",
121+
documentation: Uri.parse('https://dartcodemetrics.dev/docs/rules'),
122+
location: _copySpanWithOffset(rule.span),
123+
),
124+
);
125+
}
126+
127+
final parsedRule = parsedRulesById[rule.ruleName];
128+
if (parsedRule != null && parsedRule.requiresConfig && !rule.hasConfig) {
129+
issues.add(
130+
Issue(
131+
ruleId: 'requires-config',
132+
severity: Severity.warning,
133+
message:
134+
"'${rule.ruleName}' requires a config to produce any diagnostics.",
135+
documentation: Uri.parse('https://dartcodemetrics.dev/docs/rules'),
136+
location: _copySpanWithOffset(rule.span),
137+
),
138+
);
139+
}
140+
}
141+
142+
return issues;
143+
}
108144
}
109145

110146
class _RuleWithSpan {
111147
final String ruleName;
112148
final SourceSpan span;
149+
final bool hasConfig;
113150

114-
const _RuleWithSpan(this.ruleName, this.span);
151+
const _RuleWithSpan(this.ruleName, this.span, {required this.hasConfig});
115152
}

lib/src/analyzers/lint_analyzer/rules/models/rule.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ abstract class Rule {
3131
required this.includes,
3232
});
3333

34+
bool get requiresConfig => false;
35+
3436
/// Returns [Iterable] with [Issue]'s detected while check the passed [source]
3537
Iterable<Issue> check(InternalResolvedUnitResult source);
3638

lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_banned_imports/avoid_banned_imports_rule.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class AvoidBannedImportsRule extends CommonRule {
2828
includes: readIncludes(config),
2929
);
3030

31+
@override
32+
bool get requiresConfig => true;
33+
3134
@override
3235
Map<String, Object?> toJson() {
3336
final json = super.toJson();

lib/src/analyzers/lint_analyzer/rules/rules_list/ban_name/ban_name_rule.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ class BanNameRule extends CommonRule {
2828
includes: readIncludes(config),
2929
);
3030

31+
@override
32+
bool get requiresConfig => true;
33+
3134
@override
3235
Map<String, Object?> toJson() {
3336
final json = super.toJson();

0 commit comments

Comments
 (0)