Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(793)

Side by Side Diff: pkg/analyzer/lib/src/dart/analysis/referenced_names.dart

Issue 2519443003: Compute names referenced in a unit. (Closed)
Patch Set: Fix for top-level declarations, more tests. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 import 'package:analyzer/dart/ast/ast.dart';
6 import 'package:analyzer/dart/ast/visitor.dart';
7
8 /**
9 * Compute the set of external names referenced in the [unit].
10 */
11 Set<String> computeReferencedNames(CompilationUnit unit) {
12 _ReferencedNamesComputer computer = new _ReferencedNamesComputer();
13 unit.accept(computer);
14 return computer.names;
15 }
16
17 /**
18 * Chained set of local names, that hide corresponding external names.
19 */
20 class _LocalNameScope {
21 final _LocalNameScope enclosing;
22 Set<String> names;
23
24 _LocalNameScope(this.enclosing);
25
26 factory _LocalNameScope.forBlock(_LocalNameScope enclosing, Block node) {
27 _LocalNameScope scope = new _LocalNameScope(enclosing);
28 for (Statement statement in node.statements) {
29 if (statement is FunctionDeclarationStatement) {
30 scope.add(statement.functionDeclaration.name);
31 } else if (statement is VariableDeclarationStatement) {
32 scope.addVariableNames(statement.variables);
33 }
34 }
35 return scope;
36 }
37
38 factory _LocalNameScope.forClass(
39 _LocalNameScope enclosing, ClassDeclaration node) {
40 _LocalNameScope scope = new _LocalNameScope(enclosing);
41 scope.addTypeParameters(node.typeParameters);
42 for (ClassMember member in node.members) {
43 if (member is FieldDeclaration) {
44 scope.addVariableNames(member.fields);
45 } else if (member is MethodDeclaration) {
46 scope.add(member.name);
47 }
48 }
49 return scope;
50 }
51
52 factory _LocalNameScope.forClassTypeAlias(
53 _LocalNameScope enclosing, ClassTypeAlias node) {
54 _LocalNameScope scope = new _LocalNameScope(enclosing);
55 scope.addTypeParameters(node.typeParameters);
56 return scope;
57 }
58
59 factory _LocalNameScope.forFunction(
60 _LocalNameScope enclosing, FunctionDeclaration node) {
61 _LocalNameScope scope = new _LocalNameScope(enclosing);
62 scope.addTypeParameters(node.functionExpression.typeParameters);
63 scope.addFormalParameters(node.functionExpression.parameters);
64 return scope;
65 }
66
67 factory _LocalNameScope.forFunctionTypeAlias(
68 _LocalNameScope enclosing, FunctionTypeAlias node) {
69 _LocalNameScope scope = new _LocalNameScope(enclosing);
70 scope.addTypeParameters(node.typeParameters);
71 return scope;
72 }
73
74 factory _LocalNameScope.forMethod(
75 _LocalNameScope enclosing, MethodDeclaration node) {
76 _LocalNameScope scope = new _LocalNameScope(enclosing);
77 scope.addTypeParameters(node.typeParameters);
78 scope.addFormalParameters(node.parameters);
79 return scope;
80 }
81
82 factory _LocalNameScope.forUnit(CompilationUnit node) {
83 _LocalNameScope scope = new _LocalNameScope(null);
84 for (CompilationUnitMember declaration in node.declarations) {
85 if (declaration is NamedCompilationUnitMember) {
86 scope.add(declaration.name);
87 } else if (declaration is TopLevelVariableDeclaration) {
88 scope.addVariableNames(declaration.variables);
89 }
90 }
91 return scope;
92 }
93
94 void add(SimpleIdentifier identifier) {
95 if (identifier != null) {
96 names ??= new Set<String>();
97 names.add(identifier.name);
98 }
99 }
100
101 void addFormalParameters(FormalParameterList parameterList) {
102 if (parameterList != null) {
103 parameterList.parameters
104 .map((p) => p is NormalFormalParameter ? p.identifier : null)
105 .forEach(add);
106 }
107 }
108
109 void addTypeParameters(TypeParameterList typeParameterList) {
110 if (typeParameterList != null) {
111 typeParameterList.typeParameters.map((p) => p.name).forEach(add);
112 }
113 }
114
115 void addVariableNames(VariableDeclarationList variableList) {
116 for (VariableDeclaration variable in variableList.variables) {
117 add(variable.name);
118 }
119 }
120
121 bool contains(String name) {
122 if (names != null && names.contains(name)) {
123 return true;
124 }
125 if (enclosing != null) {
126 return enclosing.contains(name);
127 }
128 return false;
129 }
130 }
131
132 class _ReferencedNamesComputer extends GeneralizingAstVisitor {
133 final Set<String> names = new Set<String>();
134 final Set<String> importPrefixNames = new Set<String>();
135
136 _LocalNameScope localScope = new _LocalNameScope(null);
137
138 @override
139 visitBlock(Block node) {
140 _LocalNameScope outerScope = localScope;
141 try {
142 localScope = new _LocalNameScope.forBlock(localScope, node);
143 super.visitBlock(node);
144 } finally {
145 localScope = outerScope;
146 }
147 }
148
149 @override
150 visitClassDeclaration(ClassDeclaration node) {
151 _LocalNameScope outerScope = localScope;
152 try {
153 localScope = new _LocalNameScope.forClass(localScope, node);
154 super.visitClassDeclaration(node);
155 } finally {
156 localScope = outerScope;
157 }
158 }
159
160 @override
161 visitClassTypeAlias(ClassTypeAlias node) {
162 _LocalNameScope outerScope = localScope;
163 try {
164 localScope = new _LocalNameScope.forClassTypeAlias(localScope, node);
165 super.visitClassTypeAlias(node);
166 } finally {
167 localScope = outerScope;
168 }
169 }
170
171 @override
172 visitCompilationUnit(CompilationUnit node) {
173 localScope = new _LocalNameScope.forUnit(node);
174 super.visitCompilationUnit(node);
175 }
176
177 @override
178 visitConstructorName(ConstructorName node) {
179 if (node.parent is! ConstructorDeclaration) {
180 super.visitConstructorName(node);
181 }
182 }
183
184 @override
185 visitFunctionDeclaration(FunctionDeclaration node) {
186 _LocalNameScope outerScope = localScope;
187 try {
188 localScope = new _LocalNameScope.forFunction(localScope, node);
189 super.visitFunctionDeclaration(node);
190 } finally {
191 localScope = outerScope;
192 }
193 }
194
195 @override
196 visitFunctionTypeAlias(FunctionTypeAlias node) {
197 _LocalNameScope outerScope = localScope;
198 try {
199 localScope = new _LocalNameScope.forFunctionTypeAlias(localScope, node);
200 super.visitFunctionTypeAlias(node);
201 } finally {
202 localScope = outerScope;
203 }
204 }
205
206 @override
207 visitImportDirective(ImportDirective node) {
208 if (node.prefix != null) {
209 importPrefixNames.add(node.prefix.name);
210 }
211 super.visitImportDirective(node);
212 }
213
214 @override
215 visitMethodDeclaration(MethodDeclaration node) {
216 _LocalNameScope outerScope = localScope;
217 try {
218 localScope = new _LocalNameScope.forMethod(localScope, node);
219 super.visitMethodDeclaration(node);
220 } finally {
221 localScope = outerScope;
222 }
223 }
224
225 @override
226 visitSimpleIdentifier(SimpleIdentifier node) {
227 // Ignore all declarations.
228 if (node.inDeclarationContext()) {
229 return;
230 }
231 // Ignore class names references from constructors.
232 AstNode parent = node.parent;
233 if (parent is ConstructorDeclaration && parent.returnType == node) {
234 return;
235 }
236 // Prepare name.
237 String name = node.name;
238 // Ignore unqualified names shadowed by local elements.
239 if (!node.isQualified) {
240 if (localScope.contains(name)) {
241 return;
242 }
243 if (importPrefixNames.contains(name)) {
244 return;
245 }
246 }
247 // Do add the name.
248 names.add(name);
249 }
250 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/src/dart/analysis/referenced_names_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698