Skip to content

Commit 2782a48

Browse files
pqCommit Queue
authored and
Commit Queue
committed
one_member_abstracts support for augmented classes
Fixes: https://github.com/dart-lang/linter/issues/4924 Change-Id: Ib51ba2dbbb4c4c27a582606b988ed42b4f5260ec Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/362191 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Phil Quitslund <[email protected]>
1 parent 2f5a53c commit 2782a48

File tree

3 files changed

+100
-21
lines changed

3 files changed

+100
-21
lines changed

pkg/linter/lib/src/extensions.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,18 @@ extension BlockExtension on Block {
124124
}
125125

126126
extension ClassElementExtension on ClassElement {
127+
/// Get all fields, including merged augmentations.
128+
List<FieldElement> get allFields => augmented?.fields ?? fields;
129+
130+
/// Get all interfaces, including merged augmentations.
131+
List<InterfaceType> get allInterfaces => augmented?.interfaces ?? interfaces;
132+
133+
/// Get all methods, including merged augmentations.
134+
List<MethodElement> get allMethods => augmented?.methods ?? methods;
135+
136+
/// Get all mixins, including merged augmentations.
137+
List<InterfaceType> get allMixins => augmented?.mixins ?? mixins;
138+
127139
bool get hasSubclassInDefiningCompilationUnit {
128140
var compilationUnit = library.definingCompilationUnit;
129141
for (var cls in compilationUnit.classes) {

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

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:analyzer/dart/ast/ast.dart';
66
import 'package:analyzer/dart/ast/visitor.dart';
77

88
import '../analyzer.dart';
9+
import '../extensions.dart';
910

1011
const _desc =
1112
r'Avoid defining a one-member abstract class when a simple function will do.';
@@ -66,26 +67,24 @@ class _Visitor extends SimpleAstVisitor<void> {
6667

6768
@override
6869
void visitClassDeclaration(ClassDeclaration node) {
69-
var declaredElement = node.declaredElement;
70-
if (declaredElement == null) {
71-
return;
72-
}
73-
if (declaredElement.interfaces.isNotEmpty) {
74-
return;
75-
}
76-
if (declaredElement.mixins.isNotEmpty) {
77-
return;
78-
}
79-
if (node.abstractKeyword != null &&
80-
node.extendsClause == null &&
81-
node.members.length == 1) {
82-
var member = node.members.first;
83-
if (member is MethodDeclaration &&
84-
member.isAbstract &&
85-
!member.isGetter &&
86-
!member.isSetter) {
87-
rule.reportLintForToken(node.name, arguments: [member.name.lexeme]);
88-
}
70+
if (node.abstractKeyword == null) return;
71+
if (node.extendsClause != null) return;
72+
73+
if (node.isAugmentation) return;
74+
75+
var element = node.declaredElement;
76+
if (element == null) return;
77+
78+
if (element.allInterfaces.isNotEmpty) return;
79+
if (element.allMixins.isNotEmpty) return;
80+
if (element.allFields.isNotEmpty) return;
81+
82+
var methods = element.allMethods;
83+
if (methods.length != 1) return;
84+
85+
var method = methods.first;
86+
if (method.isAbstract) {
87+
rule.reportLintForToken(node.name, arguments: [method.name]);
8988
}
9089
}
9190
}

pkg/linter/test/rules/one_member_abstracts_test.dart

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,40 @@ mixin M {
4747
''');
4848
}
4949

50+
test_oneMember_augmentedAbstractClass_augmentation() async {
51+
newFile('$testPackageLibPath/a.dart', r'''
52+
import augment 'test.dart';
53+
54+
abstract class A { }
55+
''');
56+
57+
await assertNoDiagnostics(r'''
58+
augment library 'a.dart';
59+
60+
augment abstract class A {
61+
void m();
62+
}
63+
''');
64+
}
65+
66+
test_oneMember_augmentedAbstractClass_declaration() async {
67+
newFile('$testPackageLibPath/a.dart', r'''
68+
augment library 'test.dart';
69+
70+
augment abstract class A {
71+
void m();
72+
}
73+
''');
74+
75+
await assertDiagnostics(r'''
76+
import augment 'a.dart';
77+
78+
abstract class A { }
79+
''', [
80+
lint(41, 1),
81+
]);
82+
}
83+
5084
test_oneMember_extendedType() async {
5185
await assertNoDiagnostics(r'''
5286
abstract class D extends C {
@@ -96,7 +130,32 @@ sealed class C {
96130
''');
97131
}
98132

99-
test_twoMembers() async {
133+
test_twoMembers_augmentedAbstractClass_declaration() async {
134+
newFile('$testPackageLibPath/a.dart', r'''
135+
augment library 'test.dart';
136+
137+
augment abstract class A {
138+
void m();
139+
}
140+
''');
141+
142+
newFile('$testPackageLibPath/b.dart', r'''
143+
augment library 'test.dart';
144+
145+
augment abstract class A {
146+
void n();
147+
}
148+
''');
149+
150+
await assertNoDiagnostics(r'''
151+
import augment 'a.dart';
152+
import augment 'b.dart';
153+
154+
abstract class A { }
155+
''');
156+
}
157+
158+
test_twoMembers_oneField() async {
100159
await assertNoDiagnostics(r'''
101160
abstract class C {
102161
int x = 0;
@@ -105,6 +164,15 @@ abstract class C {
105164
''');
106165
}
107166

167+
test_twoMembers_oneGetter() async {
168+
await assertNoDiagnostics(r'''
169+
abstract class C {
170+
int get x => 0;
171+
int f();
172+
}
173+
''');
174+
}
175+
108176
test_zeroMember_extendedTypeHasOneMember() async {
109177
await assertDiagnostics(r'''
110178
abstract class D extends C {}

0 commit comments

Comments
 (0)