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

Commit 7024c66

Browse files
authored
Merge 80714e4 into b8f190c
2 parents b8f190c + 80714e4 commit 7024c66

File tree

7 files changed

+89
-3
lines changed

7 files changed

+89
-3
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: add `strict` config option to [`avoid-collection-methods-with-unrelated-types`](https://dartcodemetrics.dev/docs/rules/common/avoid-collection-methods-with-unrelated-types).
6+
37
## 5.2.1
48

59
* fix: avoid null check exception in the analyzer.

lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_collection_methods_with_unrelated_types/avoid_collection_methods_with_unrelated_types_rule.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@ import '../../../models/severity.dart';
1616
import '../../models/common_rule.dart';
1717
import '../../rule_utils.dart';
1818

19+
part 'config_parser.dart';
1920
part 'visitor.dart';
2021

2122
class AvoidCollectionMethodsWithUnrelatedTypesRule extends CommonRule {
2223
static const String ruleId = 'avoid-collection-methods-with-unrelated-types';
2324

2425
static const _warning = 'Avoid collection methods with unrelated types.';
2526

27+
final bool _isStrictMode;
28+
2629
AvoidCollectionMethodsWithUnrelatedTypesRule([
2730
Map<String, Object> config = const {},
28-
]) : super(
31+
]) : _isStrictMode = _ConfigParser.parseIsStrictMode(config),
32+
super(
2933
id: ruleId,
3034
severity: readSeverity(config, Severity.warning),
3135
excludes: readExcludes(config),
@@ -34,7 +38,7 @@ class AvoidCollectionMethodsWithUnrelatedTypesRule extends CommonRule {
3438

3539
@override
3640
Iterable<Issue> check(InternalResolvedUnitResult source) {
37-
final visitor = _Visitor();
41+
final visitor = _Visitor(_isStrictMode);
3842

3943
source.unit.visitChildren(visitor);
4044

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
part of 'avoid_collection_methods_with_unrelated_types_rule.dart';
2+
3+
class _ConfigParser {
4+
static const _strictConfig = 'strict';
5+
6+
static bool parseIsStrictMode(Map<String, Object> config) =>
7+
config[_strictConfig] == null || config[_strictConfig] == true;
8+
}

lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_collection_methods_with_unrelated_types/visitor.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ part of 'avoid_collection_methods_with_unrelated_types_rule.dart';
33
class _Visitor extends RecursiveAstVisitor<void> {
44
final _expressions = <Expression>[];
55

6+
final bool _isStrictMode;
7+
68
Iterable<Expression> get expressions => _expressions;
79

10+
// ignore: avoid_positional_boolean_parameters
11+
_Visitor(this._isStrictMode);
12+
813
// for `operator []` and `operator []=`
914
@override
1015
void visitIndexExpression(IndexExpression node) {
@@ -66,13 +71,20 @@ class _Visitor extends RecursiveAstVisitor<void> {
6671
) {
6772
if (parentElement != null &&
6873
childType != null &&
69-
childType.asInstanceOf(parentElement.element) == null &&
74+
(_isNotInstance(childType, parentElement) &&
75+
_isNotDynamic(childType)) &&
7076
!(parentElement.type.nullabilitySuffix == NullabilitySuffix.question &&
7177
childType.isDartCoreNull)) {
7278
_expressions.add(node);
7379
}
7480
}
7581

82+
bool _isNotInstance(DartType type, _TypedClassElement parentElement) =>
83+
type.asInstanceOf(parentElement.element) == null;
84+
85+
bool _isNotDynamic(DartType type) =>
86+
_isStrictMode || !(type.isDynamic || type.isDartCoreObject);
87+
7688
List<_TypedClassElement>? _getMapTypeElement(DartType? type) =>
7789
_getTypeArgElements(getSupertypeMap(type));
7890

test/src/analyzers/lint_analyzer/rules/rules_list/avoid_collection_methods_with_unrelated_types/avoid_collection_methods_with_unrelated_types_rule_test.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const _examplePath =
88
'avoid_collection_methods_with_unrelated_types/examples/example.dart';
99
const _nullableExamplePath =
1010
'avoid_collection_methods_with_unrelated_types/examples/nullable_example.dart';
11+
const _dynamicExamplePath =
12+
'avoid_collection_methods_with_unrelated_types/examples/dynamic_example.dart';
1113

1214
void main() {
1315
group('AvoidCollectionMethodsWithUnrelatedTypesRule', () {
@@ -161,5 +163,33 @@ void main() {
161163
],
162164
);
163165
});
166+
167+
test('reports about found issues for dynamic keys', () async {
168+
final unit = await RuleTestHelper.resolveFromFile(_dynamicExamplePath);
169+
final issues = AvoidCollectionMethodsWithUnrelatedTypesRule().check(unit);
170+
171+
RuleTestHelper.verifyIssues(
172+
issues: issues,
173+
startLines: [6, 13],
174+
startColumns: [5, 5],
175+
locationTexts: [
176+
'regularMap[key]',
177+
'regularMap[key]',
178+
],
179+
messages: [
180+
'Avoid collection methods with unrelated types.',
181+
'Avoid collection methods with unrelated types.',
182+
],
183+
);
184+
});
185+
186+
test('reports no issues for dynamic keys if not in strict mode', () async {
187+
final unit = await RuleTestHelper.resolveFromFile(_dynamicExamplePath);
188+
final issues = AvoidCollectionMethodsWithUnrelatedTypesRule(const {
189+
'strict': false,
190+
}).check(unit);
191+
192+
RuleTestHelper.verifyNoIssues(issues);
193+
});
164194
});
165195
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
void main() {
2+
{
3+
dynamic key = 1;
4+
5+
final regularMap = Map<int, String>();
6+
regularMap[key] = "value"; // LINT
7+
}
8+
9+
{
10+
Object? key = 1;
11+
12+
final regularMap = Map<int, String>();
13+
regularMap[key] = "value"; // LINT
14+
}
15+
}

website/docs/rules/common/avoid-collection-methods-with-unrelated-types.mdx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ Related: Dart's built-in `list_remove_unrelated_type` and `iterable_contains_unr
1212

1313
:::
1414

15+
Use `strict` configuration (default is `true`), if you want `dynamic` or `Object` type keys to not trigger the warning.
16+
17+
### ⚙️ Config example {#config-example}
18+
19+
```yaml
20+
dart_code_metrics:
21+
...
22+
rules:
23+
...
24+
- avoid-collection-methods-with-unrelated-types:
25+
strict: false
26+
```
27+
1528
### Example {#example}
1629
1730
**❌ Bad:**

0 commit comments

Comments
 (0)