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

Commit 4f81ffa

Browse files
authored
feat: support excludes for a separate anti-pattern. (#637)
1 parent e788cdc commit 4f81ffa

File tree

10 files changed

+75
-53
lines changed

10 files changed

+75
-53
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## Unreleased
4+
5+
* feat: support excludes for a separate anti-pattern.
6+
37
## 4.9.0
48

59
* feat: add static code diagnostics `avoid-global-state`, `avoid-unrelated-type-assertions`.

lib/src/analyzers/lint_analyzer/anti_patterns/anti_patterns_list/long_method.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class LongMethod extends Pattern {
3838
id: patternId,
3939
supportedType: EntityType.methodEntity,
4040
severity: readSeverity(patternSettings, Severity.none),
41+
excludes: readExcludes(patternSettings),
4142
);
4243

4344
@override

lib/src/analyzers/lint_analyzer/anti_patterns/anti_patterns_list/long_parameter_list.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class LongParameterList extends Pattern {
3636
id: patternId,
3737
supportedType: EntityType.methodEntity,
3838
severity: readSeverity(patternSettings, Severity.none),
39+
excludes: readExcludes(patternSettings),
3940
);
4041

4142
@override

lib/src/analyzers/lint_analyzer/anti_patterns/models/pattern.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@ abstract class Pattern {
1919
/// The severity of issues emitted by the pattern.
2020
final Severity severity;
2121

22+
/// A list of excluded files for the pattern.
23+
final Iterable<String> excludes;
24+
2225
/// Metric ids which values are used by the anti-pattern to detect a violation.
2326
Iterable<String> get dependentMetricIds;
2427

2528
const Pattern({
2629
required this.id,
2730
required this.supportedType,
2831
required this.severity,
32+
required this.excludes,
2933
});
3034

3135
/// Returns [Iterable] with [Issue]'s detected while check the passed [source].

lib/src/analyzers/lint_analyzer/lint_analyzer.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ class LintAnalyzer {
187187
ignores,
188188
internalResult,
189189
config,
190-
filePath,
191190
),
192191
);
193192
}
@@ -249,13 +248,12 @@ class LintAnalyzer {
249248
Suppression ignores,
250249
InternalResolvedUnitResult source,
251250
LintAnalysisConfig config,
252-
String filePath,
253251
) =>
254252
config.codeRules
255253
.where((rule) =>
256254
!ignores.isSuppressed(rule.id) &&
257255
!isExcluded(
258-
filePath,
256+
source.path,
259257
prepareExcludes(rule.excludes, config.excludesRootFolder),
260258
))
261259
.expand(
@@ -275,7 +273,12 @@ class LintAnalyzer {
275273
Map<ScopedFunctionDeclaration, Report> functionMetrics,
276274
) =>
277275
config.antiPatterns
278-
.where((pattern) => !ignores.isSuppressed(pattern.id))
276+
.where((pattern) =>
277+
!ignores.isSuppressed(pattern.id) &&
278+
!isExcluded(
279+
source.path,
280+
prepareExcludes(pattern.excludes, config.excludesRootFolder),
281+
))
279282
.expand((pattern) => pattern
280283
.check(source, classMetrics, functionMetrics)
281284
.where((issue) => !ignores.isSuppressedAt(

lib/src/analyzers/lint_analyzer/lint_utils.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,15 @@ import 'models/severity.dart';
33
/// Returns a [Severity] from map based [config] otherwise [defaultValue]
44
Severity readSeverity(Map<String, Object?> config, Severity defaultValue) =>
55
Severity.fromString(config['severity'] as String?) ?? defaultValue;
6+
7+
/// Returns a list of excludes from the given [config]
8+
Iterable<String> readExcludes(Map<String, Object> config) {
9+
final data = config['exclude'];
10+
11+
return _isIterableOfStrings(data)
12+
? (data as Iterable).cast<String>()
13+
: const <String>[];
14+
}
15+
16+
bool _isIterableOfStrings(Object? object) =>
17+
object is Iterable<Object> && object.every((node) => node is String);

lib/src/analyzers/lint_analyzer/rules/rule_utils.dart

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,3 @@ Uri documentation(Rule rule) => Uri(
3535
rule.id,
3636
],
3737
);
38-
39-
/// Returns a list of excludes from the given [config]
40-
Iterable<String> readExcludes(Map<String, Object> config) {
41-
final data = config['exclude'];
42-
43-
return _isIterableOfStrings(data)
44-
? (data as Iterable).cast<String>()
45-
: const <String>[];
46-
}
47-
48-
bool _isIterableOfStrings(Object? object) =>
49-
object is Iterable<Object> && object.every((node) => node is String);

test/src/analyzers/lint_analyzer/lint_utils_test.dart

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,38 @@ import 'package:dart_code_metrics/src/analyzers/lint_analyzer/models/severity.da
33
import 'package:test/test.dart';
44

55
void main() {
6-
test('readSeverity returns a Severity from Map based config', () {
7-
expect(
8-
[
9-
{'severity': 'ERROR'},
10-
{'severity': 'wArnInG'},
11-
{'severity': 'performance'},
12-
{'severity': ''},
13-
{'': null},
14-
].map((data) => readSeverity(data, Severity.style)),
15-
equals([
16-
Severity.error,
17-
Severity.warning,
18-
Severity.performance,
19-
Severity.none,
20-
Severity.style,
21-
]),
22-
);
6+
group('Lint utils', () {
7+
test('readSeverity returns a Severity from Map based config', () {
8+
expect(
9+
[
10+
{'severity': 'ERROR'},
11+
{'severity': 'wArnInG'},
12+
{'severity': 'performance'},
13+
{'severity': ''},
14+
{'': null},
15+
].map((data) => readSeverity(data, Severity.style)),
16+
equals([
17+
Severity.error,
18+
Severity.warning,
19+
Severity.performance,
20+
Severity.none,
21+
Severity.style,
22+
]),
23+
);
24+
});
25+
26+
group('readExcludes', () {
27+
test('returns a list of excludes', () {
28+
const excludes = ['hello.dart', 'world/**'];
29+
30+
expect(readExcludes({'exclude': excludes}), equals(excludes));
31+
});
32+
33+
test('returns an empty list', () {
34+
const wrongExcludes = [1, 2];
35+
36+
expect(readExcludes({'exclude': wrongExcludes}), isEmpty);
37+
});
38+
});
2339
});
2440
}

test/src/analyzers/lint_analyzer/rules/rule_utils_test.dart

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,5 @@ void main() {
8080
expect(doc2.removeLast(), equals(ruleId2));
8181
expect(doc2.removeLast(), equals(RuleType.angular.value));
8282
});
83-
84-
group('readExcludes', () {
85-
test('returns a list of excludes', () {
86-
const excludes = [
87-
'hello.dart',
88-
'world/**',
89-
];
90-
91-
expect(readExcludes({'exclude': excludes}), equals(excludes));
92-
});
93-
94-
test('returns an empty list', () {
95-
const wrongExcludes = [1, 2];
96-
97-
expect(readExcludes({'exclude': wrongExcludes}), isEmpty);
98-
});
99-
});
10083
});
10184
}

website/docs/getting-started/configuration.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,17 @@ If you want a specific rule to ignore files, you can configure `exclude` entry f
150150
```yaml title="analysis_options.yaml"
151151
dart_code_metrics:
152152
rules:
153-
no-equal-arguments:
154-
exclude:
155-
- test/**
153+
- no-equal-arguments:
154+
exclude:
155+
- test/**
156+
```
157+
158+
and similar example for anti-pattern,
159+
160+
```yaml title="analysis_options.yaml"
161+
dart_code_metrics:
162+
anti-patterns:
163+
- long-method:
164+
exclude:
165+
- test/**
156166
```

0 commit comments

Comments
 (0)