@@ -8,16 +8,15 @@ import 'package:analyzer/dart/ast/ast.dart';
8
8
import 'package:analyzer/dart/ast/visitor.dart' ;
9
9
import 'package:analyzer/dart/element/element.dart' ;
10
10
import 'package:analyzer/dart/element/type.dart' ;
11
- import 'package:collection/collection.dart' ;
12
11
13
12
import '../analyzer.dart' ;
14
13
15
14
const _desc = 'Unreachable top-level members in executable libraries.' ;
16
15
17
16
const _details = r'''
18
- Top-level members and static members in an executable library should be used
19
- directly inside this library. An executable library is a library that contains
20
- a `main` top-level function or that contains a top-level function annotated with
17
+ Top-level members in an executable library should be used directly inside this
18
+ library. An executable library is a library that contains a `main` top-level
19
+ function or that contains a top-level function annotated with
21
20
`@pragma('vm:entry-point')`). Executable libraries are not usually imported
22
21
and it's better to avoid defining unused members.
23
22
@@ -44,7 +43,7 @@ void f() {}
44
43
45
44
class UnreachableFromMain extends LintRule {
46
45
static const LintCode code = LintCode ('unreachable_from_main' ,
47
- " Unreachable member '{0}' in an executable library." ,
46
+ ' Unreachable top-level member in an executable library.' ,
48
47
correctionMessage: 'Try referencing the member or removing it.' );
49
48
50
49
UnreachableFromMain ()
@@ -100,12 +99,7 @@ class _DeclarationGatherer {
100
99
}
101
100
102
101
void _addStaticMember (ClassMember member) {
103
- if (member is ConstructorDeclaration ) {
104
- var e = member.declaredElement;
105
- if (e != null && e.isPublic && member.parent is ! EnumDeclaration ) {
106
- declarations.add (member);
107
- }
108
- } else if (member is FieldDeclaration && member.isStatic) {
102
+ if (member is FieldDeclaration && member.isStatic) {
109
103
for (var field in member.fields.variables) {
110
104
var e = field.declaredElement;
111
105
if (e != null && e.isPublic) {
@@ -121,72 +115,20 @@ class _DeclarationGatherer {
121
115
}
122
116
}
123
117
124
- /// A visitor which gathers the declarations of the "references" it visits.
125
- ///
126
- /// "References" are most often [SimpleIdentifier] s, but can also be other
127
- /// nodes which refer to a declaration.
128
- // TODO(srawlins): Add support for patterns.
129
- class _ReferenceVisitor extends RecursiveAstVisitor {
118
+ /// A visitor which gathers the declarations of the identifiers it visits.
119
+ class _IdentifierVisitor extends RecursiveAstVisitor {
130
120
Map <Element , Declaration > declarationMap;
131
121
132
122
Set <Declaration > declarations = {};
133
123
134
- _ReferenceVisitor (this .declarationMap);
135
-
136
- @override
137
- void visitAnnotation (Annotation node) {
138
- var e = node.element;
139
- if (e != null ) {
140
- _addDeclaration (e);
141
- }
142
- super .visitAnnotation (node);
143
- }
124
+ _IdentifierVisitor (this .declarationMap);
144
125
145
126
@override
146
127
void visitAssignmentExpression (AssignmentExpression node) {
147
128
_visitCompoundAssignmentExpression (node);
148
129
super .visitAssignmentExpression (node);
149
130
}
150
131
151
- @override
152
- void visitClassDeclaration (ClassDeclaration node) {
153
- var element = node.declaredElement;
154
- if (element != null ) {
155
- var hasConstructors =
156
- node.members.any ((e) => e is ConstructorDeclaration );
157
- if (! hasConstructors) {
158
- // The default constructor will have an implicit super-initializer to
159
- // the super-type's unnamed constructor.
160
- _addDefaultSuperConstructorDeclaration (node);
161
- }
162
- }
163
- super .visitClassDeclaration (node);
164
- }
165
-
166
- @override
167
- void visitConstructorDeclaration (ConstructorDeclaration node) {
168
- // If a constructor does not have an explicit super-initializer (or redirection?)
169
- // then it has an implicit super-initializer to the super-type's unnamed constructor.
170
- var hasSuperInitializer =
171
- node.initializers.any ((e) => e is SuperConstructorInvocation );
172
- if (! hasSuperInitializer) {
173
- var enclosingClass = node.parent;
174
- if (enclosingClass is ClassDeclaration ) {
175
- _addDefaultSuperConstructorDeclaration (enclosingClass);
176
- }
177
- }
178
- super .visitConstructorDeclaration (node);
179
- }
180
-
181
- @override
182
- void visitConstructorName (ConstructorName node) {
183
- var e = node.staticElement;
184
- if (e != null ) {
185
- _addDeclaration (e);
186
- }
187
- super .visitConstructorName (node);
188
- }
189
-
190
132
@override
191
133
void visitPostfixExpression (PostfixExpression node) {
192
134
_visitCompoundAssignmentExpression (node);
@@ -199,16 +141,6 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
199
141
super .visitPrefixExpression (node);
200
142
}
201
143
202
- @override
203
- void visitRedirectingConstructorInvocation (
204
- RedirectingConstructorInvocation node) {
205
- var element = node.staticElement;
206
- if (element != null ) {
207
- _addDeclaration (element);
208
- }
209
- super .visitRedirectingConstructorInvocation (node);
210
- }
211
-
212
144
@override
213
145
void visitSimpleIdentifier (SimpleIdentifier node) {
214
146
if (! node.inDeclarationContext ()) {
@@ -220,15 +152,6 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
220
152
super .visitSimpleIdentifier (node);
221
153
}
222
154
223
- @override
224
- void visitSuperConstructorInvocation (SuperConstructorInvocation node) {
225
- var e = node.staticElement;
226
- if (e != null ) {
227
- _addDeclaration (e);
228
- }
229
- super .visitSuperConstructorInvocation (node);
230
- }
231
-
232
155
/// Adds the declaration of the top-level element which contains [element] to
233
156
/// [declarations] , if it is found in [declarationMap] .
234
157
///
@@ -244,8 +167,8 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
244
167
declarations.add (enclosingTopLevelDeclaration);
245
168
}
246
169
247
- // Also add [element]'s declaration if it is a constructor, static accessor,
248
- // or static method.
170
+ // Also add [element]'s declaration if it is a static accessor or static
171
+ // method.
249
172
if (element.isPrivate) {
250
173
return ;
251
174
}
@@ -255,7 +178,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
255
178
}
256
179
if (enclosingElement is InterfaceElement ||
257
180
enclosingElement is ExtensionElement ) {
258
- if (element is ConstructorElement ) {
181
+ if (element is PropertyAccessorElement && element.isStatic ) {
259
182
var declaration = declarationMap[element];
260
183
if (declaration != null ) {
261
184
declarations.add (declaration);
@@ -265,23 +188,6 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
265
188
if (declaration != null ) {
266
189
declarations.add (declaration);
267
190
}
268
- } else if (element is PropertyAccessorElement && element.isStatic) {
269
- var declaration = declarationMap[element];
270
- if (declaration != null ) {
271
- declarations.add (declaration);
272
- }
273
- }
274
- }
275
- }
276
-
277
- void _addDefaultSuperConstructorDeclaration (ClassDeclaration class_) {
278
- var classElement = class_.declaredElement;
279
- var supertype = classElement? .supertype;
280
- if (supertype != null ) {
281
- var unnamedConstructor =
282
- supertype.constructors.firstWhereOrNull ((e) => e.name.isEmpty);
283
- if (unnamedConstructor != null ) {
284
- _addDeclaration (unnamedConstructor);
285
191
}
286
192
}
287
193
}
@@ -335,14 +241,13 @@ class _Visitor extends SimpleAstVisitor<void> {
335
241
}
336
242
}
337
243
338
- // The set of the declarations which each top-level and static declaration
339
- // references.
244
+ // The set of the declarations which each top-level declaration references.
340
245
var dependencies = < Declaration , Set <Declaration >> {};
341
246
342
247
// Map each declaration to the collection of declarations which are
343
248
// referenced within its body.
344
249
for (var declaration in declarations) {
345
- var visitor = _ReferenceVisitor (declarationByElement);
250
+ var visitor = _IdentifierVisitor (declarationByElement);
346
251
declaration.accept (visitor);
347
252
dependencies[declaration] = visitor.declarations;
348
253
}
@@ -371,25 +276,15 @@ class _Visitor extends SimpleAstVisitor<void> {
371
276
});
372
277
373
278
for (var member in unusedMembers) {
374
- if (member is ConstructorDeclaration ) {
375
- if (member.name == null ) {
376
- rule.reportLint (member.returnType, arguments: [member.nameForError]);
377
- } else {
378
- rule.reportLintForToken (member.name,
379
- arguments: [member.nameForError]);
380
- }
381
- } else if (member is NamedCompilationUnitMember ) {
382
- rule.reportLintForToken (member.name, arguments: [member.nameForError]);
279
+ if (member is NamedCompilationUnitMember ) {
280
+ rule.reportLintForToken (member.name);
383
281
} else if (member is VariableDeclaration ) {
384
- rule.reportLintForToken (member.name, arguments : [member.nameForError] );
282
+ rule.reportLintForToken (member.name);
385
283
} else if (member is ExtensionDeclaration ) {
386
- var memberName = member.name;
387
284
rule.reportLintForToken (
388
- memberName ?? member.firstTokenAfterCommentAndMetadata,
389
- arguments: [member.nameForError]);
285
+ member.name ?? member.firstTokenAfterCommentAndMetadata);
390
286
} else {
391
- rule.reportLintForToken (member.firstTokenAfterCommentAndMetadata,
392
- arguments: [member.nameForError]);
287
+ rule.reportLintForToken (member.firstTokenAfterCommentAndMetadata);
393
288
}
394
289
}
395
290
}
@@ -428,28 +323,3 @@ extension on Annotation {
428
323
return type is InterfaceType && type.element.isPragma;
429
324
}
430
325
}
431
-
432
- extension on Declaration {
433
- String get nameForError {
434
- // TODO(srawlins): Move this to analyzer when other uses are found.
435
- // TODO(srawlins): Convert to switch-expression, hopefully.
436
- var self = this ;
437
- if (self is ConstructorDeclaration ) {
438
- return self.name? .lexeme ?? self.returnType.name;
439
- } else if (self is EnumConstantDeclaration ) {
440
- return self.name.lexeme;
441
- } else if (self is ExtensionDeclaration ) {
442
- var name = self.name;
443
- return name? .lexeme ?? 'the unnamed extension' ;
444
- } else if (self is MethodDeclaration ) {
445
- return self.name.lexeme;
446
- } else if (self is NamedCompilationUnitMember ) {
447
- return self.name.lexeme;
448
- } else if (self is VariableDeclaration ) {
449
- return self.name.lexeme;
450
- }
451
-
452
- assert (false , 'Uncovered Declaration subtype: ${self .runtimeType }' );
453
- return '' ;
454
- }
455
- }
0 commit comments