diff --git a/CHANGELOG.md b/CHANGELOG.md index d3205eb5fb..b33e864677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +* fix: add check for supertypes for [`avoid-non-null-assertions`](https://dartcodemetrics.dev/docs/rules/common/avoid-non-null-assertion) rule. * fix: cover more cases in [`prefer-immediate-return`](https://dartcodemetrics.dev/docs/rules/common/prefer-immediate-return) rule * fix: support index expressions for [`no-magic-number`](https://dartcodemetrics.dev/docs/rules/common/no-magic-number) rule. * chore: restrict `analyzer` version to `>=2.4.0 <3.5.0`. diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/avoid_non_null_assertion_rule.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/avoid_non_null_assertion_rule.dart index bea21d5ac9..6964ef5407 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/avoid_non_null_assertion_rule.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/avoid_non_null_assertion_rule.dart @@ -3,6 +3,7 @@ import 'package:analyzer/dart/ast/ast.dart'; import 'package:analyzer/dart/ast/token.dart'; import 'package:analyzer/dart/ast/visitor.dart'; +import 'package:analyzer/dart/element/type.dart'; import '../../../../../utils/node_utils.dart'; import '../../../lint_utils.dart'; diff --git a/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/visitor.dart b/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/visitor.dart index 4761787a57..76ea50b31d 100644 --- a/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/visitor.dart +++ b/lib/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/visitor.dart @@ -19,9 +19,14 @@ class _Visitor extends RecursiveAstVisitor { if (operand is IndexExpression) { final type = operand.target?.staticType; - return type != null && type.isDartCoreMap; + return type is InterfaceType && + (_isMapOrSubclassOfMap(type) || + type.allSupertypes.any(_isMapOrSubclassOfMap)); } return false; } + + bool _isMapOrSubclassOfMap(DartType? type) => + type != null && type.isDartCoreMap; } diff --git a/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/examples/example.dart b/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/examples/example.dart index a5f43627f2..e846a1478a 100644 --- a/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/examples/example.dart +++ b/test/src/analyzers/lint_analyzer/rules/rules_list/avoid_non_null_assertion/examples/example.dart @@ -27,5 +27,19 @@ class Test { object!.method(); // LINT object?.method(); + + final myMap = MyMap(); + myMap['key']!.contains('other'); + + final myOtherMap = MyAnotherMap(); + myOtherMap['key']!.contains('other'); } } + +class MyMap extends Map { + void doNothing() {} +} + +class MyAnotherMap implements Map { + void doNothing() {} +}