Skip to content

Commit 9330195

Browse files
pqCommit Queue
authored and
Commit Queue
committed
augmentation support for avoid_equals_and_hash_code_on_mutable_classes
Fixes: https://github.com/dart-lang/linter/issues/4932 Change-Id: Ic9b20d81ae36536251568dbf25616b9ddc9f6693 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/363142 Commit-Queue: Phil Quitslund <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent ae6d2ed commit 9330195

File tree

2 files changed

+55
-9
lines changed

2 files changed

+55
-9
lines changed

pkg/linter/lib/src/rules/avoid_equals_and_hash_code_on_mutable_classes.dart

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:analyzer/dart/element/element.dart';
99

1010
import '../analyzer.dart';
1111
import '../ast.dart';
12+
import '../extensions.dart';
1213

1314
const _desc =
1415
r'Avoid overloading operator == and hashCode on classes not marked `@immutable`.';
@@ -95,24 +96,31 @@ class _Visitor extends SimpleAstVisitor<void> {
9596

9697
@override
9798
void visitMethodDeclaration(MethodDeclaration node) {
99+
if (node.isAugmentation) return;
100+
98101
if (node.name.type == TokenType.EQ_EQ || isHashCode(node)) {
99-
var classElement = _getClassForMethod(node);
100-
if (classElement != null && !_hasImmutableAnnotation(classElement)) {
102+
var classElement = node.classElement;
103+
if (classElement != null && !classElement.hasImmutableAnnotation) {
101104
rule.reportLintForToken(node.firstTokenAfterCommentAndMetadata,
102105
arguments: [node.name.lexeme]);
103106
}
104107
}
105108
}
109+
}
106110

107-
ClassElement? _getClassForMethod(MethodDeclaration node) =>
108-
// TODO(pq): should this be ClassOrMixinDeclaration ?
109-
node.thisOrAncestorOfType<ClassDeclaration>()?.declaredElement;
110-
111-
bool _hasImmutableAnnotation(ClassElement clazz) {
111+
extension on ClassElement {
112+
bool get hasImmutableAnnotation {
113+
// TODO(pq): consider augmentations? https://github.com/dart-lang/linter/issues/4939
112114
var inheritedAndSelfElements = <InterfaceElement>[
113-
...clazz.allSupertypes.map((t) => t.element),
114-
clazz,
115+
...allSupertypes.map((t) => t.element),
116+
this,
115117
];
116118
return inheritedAndSelfElements.any((e) => e.hasImmutable);
117119
}
118120
}
121+
122+
extension on MethodDeclaration {
123+
ClassElement? get classElement =>
124+
// TODO(pq): should this be ClassOrMixinDeclaration ?
125+
thisOrAncestorOfType<ClassDeclaration>()?.declaredElement;
126+
}

pkg/linter/test/rules/avoid_equals_and_hash_code_on_mutable_classes_test.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,44 @@ class A {
6969
]);
7070
}
7171

72+
test_mutableClass_augmentationMethod() async {
73+
newFile('$testPackageLibPath/a.dart', r'''
74+
import augment 'test.dart';
75+
76+
class A {
77+
@override
78+
int get hashCode => 0;
79+
}
80+
''');
81+
82+
await assertNoDiagnostics(r'''
83+
augment library 'a.dart';
84+
85+
augment class A {
86+
augment int get hashCode => 0;
87+
}
88+
''');
89+
}
90+
91+
test_mutableClass_augmented() async {
92+
newFile('$testPackageLibPath/a.dart', r'''
93+
import augment 'test.dart';
94+
95+
class A {}
96+
''');
97+
98+
await assertDiagnostics(r'''
99+
augment library 'a.dart';
100+
101+
augment class A {
102+
@override
103+
int get hashCode => 0;
104+
}
105+
''', [
106+
lint(59, 3),
107+
]);
108+
}
109+
72110
test_subtypeOfImmutableClass() async {
73111
await assertNoDiagnostics(r'''
74112
import 'package:meta/meta.dart';

0 commit comments

Comments
 (0)