@@ -8,16 +8,15 @@ import 'package:analyzer/dart/ast/ast.dart';
88import 'package:analyzer/dart/ast/visitor.dart' ;
99import 'package:analyzer/dart/element/element.dart' ;
1010import 'package:analyzer/dart/element/type.dart' ;
11- import 'package:collection/collection.dart' ;
1211
1312import '../analyzer.dart' ;
1413
1514const _desc = 'Unreachable top-level members in executable libraries.' ;
1615
1716const _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
2120`@pragma('vm:entry-point')`). Executable libraries are not usually imported
2221and it's better to avoid defining unused members.
2322
@@ -44,7 +43,7 @@ void f() {}
4443
4544class UnreachableFromMain extends LintRule {
4645 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.' ,
4847 correctionMessage: 'Try referencing the member or removing it.' );
4948
5049 UnreachableFromMain ()
@@ -100,12 +99,7 @@ class _DeclarationGatherer {
10099 }
101100
102101 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) {
109103 for (var field in member.fields.variables) {
110104 var e = field.declaredElement;
111105 if (e != null && e.isPublic) {
@@ -121,72 +115,20 @@ class _DeclarationGatherer {
121115 }
122116}
123117
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 {
130120 Map <Element , Declaration > declarationMap;
131121
132122 Set <Declaration > declarations = {};
133123
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);
144125
145126 @override
146127 void visitAssignmentExpression (AssignmentExpression node) {
147128 _visitCompoundAssignmentExpression (node);
148129 super .visitAssignmentExpression (node);
149130 }
150131
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-
190132 @override
191133 void visitPostfixExpression (PostfixExpression node) {
192134 _visitCompoundAssignmentExpression (node);
@@ -199,16 +141,6 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
199141 super .visitPrefixExpression (node);
200142 }
201143
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-
212144 @override
213145 void visitSimpleIdentifier (SimpleIdentifier node) {
214146 if (! node.inDeclarationContext ()) {
@@ -220,15 +152,6 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
220152 super .visitSimpleIdentifier (node);
221153 }
222154
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-
232155 /// Adds the declaration of the top-level element which contains [element] to
233156 /// [declarations] , if it is found in [declarationMap] .
234157 ///
@@ -244,8 +167,8 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
244167 declarations.add (enclosingTopLevelDeclaration);
245168 }
246169
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.
249172 if (element.isPrivate) {
250173 return ;
251174 }
@@ -255,7 +178,7 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
255178 }
256179 if (enclosingElement is InterfaceElement ||
257180 enclosingElement is ExtensionElement ) {
258- if (element is ConstructorElement ) {
181+ if (element is PropertyAccessorElement && element.isStatic ) {
259182 var declaration = declarationMap[element];
260183 if (declaration != null ) {
261184 declarations.add (declaration);
@@ -265,23 +188,6 @@ class _ReferenceVisitor extends RecursiveAstVisitor {
265188 if (declaration != null ) {
266189 declarations.add (declaration);
267190 }
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);
285191 }
286192 }
287193 }
@@ -335,14 +241,13 @@ class _Visitor extends SimpleAstVisitor<void> {
335241 }
336242 }
337243
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.
340245 var dependencies = < Declaration , Set <Declaration >> {};
341246
342247 // Map each declaration to the collection of declarations which are
343248 // referenced within its body.
344249 for (var declaration in declarations) {
345- var visitor = _ReferenceVisitor (declarationByElement);
250+ var visitor = _IdentifierVisitor (declarationByElement);
346251 declaration.accept (visitor);
347252 dependencies[declaration] = visitor.declarations;
348253 }
@@ -371,25 +276,15 @@ class _Visitor extends SimpleAstVisitor<void> {
371276 });
372277
373278 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);
383281 } else if (member is VariableDeclaration ) {
384- rule.reportLintForToken (member.name, arguments : [member.nameForError] );
282+ rule.reportLintForToken (member.name);
385283 } else if (member is ExtensionDeclaration ) {
386- var memberName = member.name;
387284 rule.reportLintForToken (
388- memberName ?? member.firstTokenAfterCommentAndMetadata,
389- arguments: [member.nameForError]);
285+ member.name ?? member.firstTokenAfterCommentAndMetadata);
390286 } else {
391- rule.reportLintForToken (member.firstTokenAfterCommentAndMetadata,
392- arguments: [member.nameForError]);
287+ rule.reportLintForToken (member.firstTokenAfterCommentAndMetadata);
393288 }
394289 }
395290 }
@@ -428,28 +323,3 @@ extension on Annotation {
428323 return type is InterfaceType && type.element.isPragma;
429324 }
430325}
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