Skip to content

Commit 8ed3f80

Browse files
authored
Refactored avoid_unnecessary_type_assertions (#144)
* Refactored avoid_unnecessary_type_assertions * - Updated changelog
1 parent 03e0b44 commit 8ed3f80

File tree

4 files changed

+37
-57
lines changed

4 files changed

+37
-57
lines changed

CHANGELOG.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
- Fixed `avoid_unused_parameters` to report positional parameters from typedef if their name are not underscores.
66
- Improvement for `avoid_returning_widget` lint:
77
- ignores methods that override ones that return widget (build() for example)
8-
- no longer allows returning widgets from methods/functions named build
8+
- no longer allows returning widgets from methods/functions named build
9+
- Fixed unexpected avoid_unnecessary_type_assertions
910

1011
## 0.1.4
1112

@@ -90,12 +91,12 @@
9091
- Update `dart_code_metrics` dependency to 5.7.3
9192
- Rename deprecated `member-ordering-extended` to `member-ordering`
9293
- Add rule for widgets methods order configuration:
93-
- initState
94-
- build
95-
- didChangeDependencies
96-
- didUpdateWidget
97-
- deactivate
98-
- dispose
94+
- initState
95+
- build
96+
- didChangeDependencies
97+
- didUpdateWidget
98+
- deactivate
99+
- dispose
99100

100101
## 0.0.15
101102

lib/src/lints/avoid_unnecessary_type_assertions/avoid_unnecessary_type_assertions_rule.dart

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,23 +98,12 @@ class AvoidUnnecessaryTypeAssertions extends SolidLintRule {
9898
if (objectType == null || castedType == null) {
9999
return false;
100100
}
101-
102101
final typeCast = TypeCast(
103102
source: objectType,
104103
target: castedType,
105-
isReversed: true,
104+
isReversed: node.notOperator != null,
106105
);
107-
108-
if (node.notOperator != null &&
109-
objectType is! TypeParameterType &&
110-
objectType is! DynamicType &&
111-
!objectType.isDartCoreObject &&
112-
typeCast.isUnnecessaryTypeCheck) {
113-
return true;
114-
} else {
115-
final typeCast = TypeCast(source: objectType, target: castedType);
116-
return typeCast.isUnnecessaryTypeCheck;
117-
}
106+
return typeCast.isUnnecessaryTypeCheck;
118107
}
119108

120109
bool _isUnnecessaryWhereType(MethodInvocation node) {

lib/src/utils/typecast_utils.dart

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,30 @@ class TypeCast {
2828
this.isReversed = false,
2929
});
3030

31-
/// Returns the first type from source's supertypes
32-
/// which is corresponding to target or null
33-
DartType? castTypeInHierarchy() {
31+
/// Checks that type checking is unnecessary
32+
bool get isUnnecessaryTypeCheck {
33+
final source = this.source;
34+
35+
if (_isNullableCompatibility) {
36+
return false;
37+
}
38+
3439
if (source.element == target.element) {
35-
return source;
40+
return _areGenericsWithSameTypeArgs;
3641
}
3742

38-
final objectType = source;
39-
if (objectType is InterfaceType) {
40-
return objectType.allSupertypes.firstWhereOrNull(
41-
(value) => value.element == target.element,
43+
if (source is InterfaceType) {
44+
return source.allSupertypes.any(
45+
(e) => e.element == target.element,
4246
);
4347
}
4448

45-
return null;
49+
return false;
4650
}
4751

4852
/// Checks for nullable type casts
4953
/// Only one case `Type? is Type` always valid assertion case.
50-
bool get isNullableCompatibility {
54+
bool get _isNullableCompatibility {
5155
final isObjectTypeNullable =
5256
source.nullabilitySuffix != NullabilitySuffix.none;
5357
final isCastedTypeNullable =
@@ -56,33 +60,8 @@ class TypeCast {
5660
return isObjectTypeNullable && !isCastedTypeNullable;
5761
}
5862

59-
/// Checks that type checking is unnecessary
60-
/// [source] is the source expression type
61-
/// [target] is the type against which the expression type is compared
62-
/// and false for positive comparison, i.e. 'is', 'as' or 'whereType'
63-
bool get isUnnecessaryTypeCheck {
64-
if (isNullableCompatibility) {
65-
return false;
66-
}
67-
68-
final objectCastedType = castTypeInHierarchy();
69-
if (objectCastedType == null) {
70-
return isReversed;
71-
}
72-
73-
final objectTypeCast = TypeCast(
74-
source: objectCastedType,
75-
target: target,
76-
);
77-
if (!objectTypeCast.areGenericsWithSameTypeArgs) {
78-
return false;
79-
}
80-
81-
return !isReversed;
82-
}
83-
8463
/// Checks for type arguments and compares them
85-
bool get areGenericsWithSameTypeArgs {
64+
bool get _areGenericsWithSameTypeArgs {
8665
if (source is DynamicType || target is DynamicType) {
8766
return false;
8867
}

lint_test/avoid_unnecessary_type_assertions_test.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// ignore_for_file: prefer_const_declarations
1+
// ignore_for_file: prefer_const_declarations, prefer_match_file_name, cyclomatic_complexity, unused_element
22
// ignore_for_file: unnecessary_nullable_for_final_variable_declarations
33
// ignore_for_file: unnecessary_type_check
44
// ignore_for_file: unused_local_variable
@@ -34,3 +34,14 @@ void fun() {
3434
// casting `Type? is Type` is allowed
3535
final castedD = nullableD is double;
3636
}
37+
38+
class _A {}
39+
40+
class _B extends _A {}
41+
42+
class _C extends _A {}
43+
44+
void noLint() {
45+
final _A a = _B();
46+
if (a is! _C) return;
47+
}

0 commit comments

Comments
 (0)