OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, 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 library analyzer2dart.semantic_visitor; | |
6 | |
7 import 'package:analyzer/analyzer.dart'; | |
8 import 'package:analyzer/src/generated/source.dart'; | |
9 | |
10 import 'util.dart'; | |
11 import 'identifier_semantics.dart'; | |
12 | |
13 /// An AST visitor which uses the [AccessSemantics] of invocations and accesses | |
14 /// to fine-grain visitor methods. | |
15 abstract class SemanticVisitor<R> extends RecursiveAstVisitor<R> { | |
16 | |
17 Source get currentSource; | |
18 | |
19 void reportMessage(AstNode node, String message) { | |
20 reportSourceMessage(currentSource, node, message); | |
21 } | |
22 | |
23 giveUp(AstNode node, String message) { | |
24 reportMessage(node, message); | |
25 throw new UnimplementedError(message); | |
26 } | |
27 | |
28 bool invariant(AstNode node, condition, String message) { | |
29 if (condition is Function) { | |
30 condition = condition(); | |
31 } | |
32 if (!condition) { | |
33 reportMessage(node, message); | |
34 return false; | |
35 } | |
36 return true; | |
37 } | |
38 | |
39 R visitDynamicInvocation(MethodInvocation node, | |
40 AccessSemantics semantics) { | |
41 return giveUp(node, 'visitDynamicInvocation of $semantics'); | |
42 } | |
43 | |
44 R visitLocalFunctionInvocation(MethodInvocation node, | |
45 AccessSemantics semantics) { | |
46 return giveUp(node, 'visitLocalFunctionInvocation of $semantics'); | |
47 } | |
48 | |
49 R visitLocalVariableInvocation(MethodInvocation node, | |
50 AccessSemantics semantics) { | |
51 return giveUp(node, 'visitLocalVariableInvocation of $semantics'); | |
52 } | |
53 | |
54 R visitParameterInvocation(MethodInvocation node, | |
55 AccessSemantics semantics) { | |
56 return giveUp(node, 'visitParameterInvocation of $semantics'); | |
57 } | |
58 | |
59 R visitStaticFieldInvocation(MethodInvocation node, | |
60 AccessSemantics semantics) { | |
61 return giveUp(node, 'visitStaticFieldInvocation of $semantics'); | |
62 } | |
63 | |
64 R visitStaticMethodInvocation(MethodInvocation node, | |
65 AccessSemantics semantics) { | |
66 return giveUp(node, 'visitStaticMethodInvocation of $semantics'); | |
67 } | |
68 | |
69 R visitStaticPropertyInvocation(MethodInvocation node, | |
70 AccessSemantics semantics) { | |
71 return giveUp(node, 'visitStaticPropertyInvocation of $semantics'); | |
72 } | |
73 | |
74 @override | |
75 R visitMethodInvocation(MethodInvocation node) { | |
76 if (node.target != null) { | |
77 node.target.accept(this); | |
78 } | |
79 node.argumentList.accept(this); | |
80 return handleMethodInvocation(node); | |
81 } | |
82 | |
83 R handleMethodInvocation(MethodInvocation node) { | |
84 AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR); | |
85 switch (semantics.kind) { | |
86 case AccessKind.DYNAMIC: | |
87 return visitDynamicInvocation(node, semantics); | |
88 case AccessKind.LOCAL_FUNCTION: | |
89 return visitLocalFunctionInvocation(node, semantics); | |
90 case AccessKind.LOCAL_VARIABLE: | |
91 return visitLocalVariableInvocation(node, semantics); | |
92 case AccessKind.PARAMETER: | |
93 return visitParameterInvocation(node, semantics); | |
94 case AccessKind.STATIC_FIELD: | |
95 return visitStaticFieldInvocation(node, semantics); | |
96 case AccessKind.STATIC_METHOD: | |
97 return visitStaticMethodInvocation(node, semantics); | |
98 case AccessKind.STATIC_PROPERTY: | |
99 return visitStaticPropertyInvocation(node, semantics); | |
100 default: | |
101 // Unexpected access kind. | |
102 return giveUp(node, | |
103 'Unexpected ${semantics} in visitMethodInvocation.'); | |
104 } | |
105 } | |
106 | |
107 @override | |
108 R visitPropertyAccess(PropertyAccess node) { | |
109 if (node.target != null) { | |
110 node.target.accept(this); | |
111 } | |
112 return handlePropertyAccess(node); | |
113 } | |
114 | |
115 R handlePropertyAccess(PropertyAccess node) { | |
116 return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR)); | |
117 } | |
118 | |
119 @override | |
120 R visitPrefixedIdentifier(PrefixedIdentifier node) { | |
121 node.prefix.accept(this); | |
122 return handlePrefixedIdentifier(node); | |
123 } | |
124 | |
125 R handlePrefixedIdentifier(PrefixedIdentifier node) { | |
126 return _handlePropertyAccess(node, node.accept(ACCESS_SEMANTICS_VISITOR)); | |
127 } | |
128 | |
129 @override | |
130 R visitSimpleIdentifier(SimpleIdentifier node) { | |
131 AccessSemantics semantics = node.accept(ACCESS_SEMANTICS_VISITOR); | |
132 if (semantics != null) { | |
133 return _handlePropertyAccess(node, semantics); | |
134 } else { | |
135 return null; | |
136 } | |
137 } | |
138 | |
139 R visitDynamicAccess(AstNode node, AccessSemantics semantics) { | |
140 return giveUp(node, 'visitDynamicAccess of $semantics'); | |
141 } | |
142 | |
143 R visitLocalFunctionAccess(AstNode node, AccessSemantics semantics) { | |
144 return giveUp(node, 'visitLocalFunctionAccess of $semantics'); | |
145 } | |
146 | |
147 R visitLocalVariableAccess(AstNode node, AccessSemantics semantics) { | |
148 return giveUp(node, 'visitLocalVariableAccess of $semantics'); | |
149 } | |
150 | |
151 R visitParameterAccess(AstNode node, AccessSemantics semantics) { | |
152 return giveUp(node, 'visitParameterAccess of $semantics'); | |
153 } | |
154 | |
155 R visitStaticFieldAccess(AstNode node, AccessSemantics semantics) { | |
156 return giveUp(node, 'visitStaticFieldAccess of $semantics'); | |
157 } | |
158 | |
159 R visitStaticMethodAccess(AstNode node, AccessSemantics semantics) { | |
160 return giveUp(node, 'visitStaticMethodAccess of $semantics'); | |
161 } | |
162 | |
163 R visitStaticPropertyAccess(AstNode node, AccessSemantics semantics) { | |
164 return giveUp(node, 'visitStaticPropertyAccess of $semantics'); | |
165 } | |
166 | |
167 R visitToplevelClassAccess(AstNode node, AccessSemantics semantics) { | |
168 return giveUp(node, 'visitToplevelClassAccess of $semantics'); | |
169 } | |
170 | |
171 R visitTypeParameterAccess(AstNode node, AccessSemantics semantics) { | |
172 return giveUp(node, 'visitTypeParameterAccess of $semantics'); | |
173 } | |
174 | |
175 R _handlePropertyAccess(AstNode node, AccessSemantics semantics) { | |
176 switch (semantics.kind) { | |
177 case AccessKind.DYNAMIC: | |
178 return visitDynamicAccess(node, semantics); | |
179 case AccessKind.LOCAL_FUNCTION: | |
180 return visitLocalFunctionAccess(node, semantics); | |
181 case AccessKind.LOCAL_VARIABLE: | |
182 return visitLocalVariableAccess(node, semantics); | |
183 case AccessKind.PARAMETER: | |
184 return visitParameterAccess(node, semantics); | |
185 case AccessKind.STATIC_FIELD: | |
186 return visitStaticFieldAccess(node, semantics); | |
187 case AccessKind.STATIC_METHOD: | |
188 return visitStaticMethodAccess(node, semantics); | |
189 case AccessKind.STATIC_PROPERTY: | |
190 return visitStaticPropertyAccess(node, semantics); | |
191 case AccessKind.TOPLEVEL_TYPE: | |
192 return visitToplevelClassAccess(node, semantics); | |
193 case AccessKind.TYPE_PARAMETER: | |
194 return visitTypeParameterAccess(node, semantics); | |
195 default: | |
196 // Unexpected access kind. | |
197 return giveUp(node, | |
198 'Unexpected ${semantics} in _handlePropertyAccess.'); | |
199 } | |
200 } | |
201 | |
202 R visitDynamicPropertyAssignment(AssignmentExpression node, | |
203 AccessSemantics semantics) { | |
204 return giveUp(node, 'visitDynamicPropertyAssignment of $semantics'); | |
205 } | |
206 | |
207 R visitLocalFunctionAssignment(AssignmentExpression node, | |
208 AccessSemantics semantics) { | |
209 return giveUp(node, 'visitLocalFunctionAssignment of $semantics'); | |
210 } | |
211 | |
212 R visitLocalVariableAssignment(AssignmentExpression node, | |
213 AccessSemantics semantics) { | |
214 return giveUp(node, 'visitLocalVariableAssignment of $semantics'); | |
215 } | |
216 | |
217 R visitParameterAssignment(AssignmentExpression node, | |
218 AccessSemantics semantics) { | |
219 return giveUp(node, 'visitParameterAssignment of $semantics'); | |
220 } | |
221 | |
222 R visitStaticFieldAssignment(AssignmentExpression node, | |
223 AccessSemantics semantics) { | |
224 return giveUp(node, 'visitStaticFieldAssignment of $semantics'); | |
225 } | |
226 | |
227 R visitStaticMethodAssignment(AssignmentExpression node, | |
228 AccessSemantics semantics) { | |
229 return giveUp(node, 'visitStaticMethodAssignment of $semantics'); | |
230 } | |
231 | |
232 R visitStaticPropertyAssignment(AssignmentExpression node, | |
233 AccessSemantics semantics) { | |
234 return giveUp(node, 'visitStaticPropertyAssignment of $semantics'); | |
235 } | |
236 | |
237 @override | |
238 R visitAssignmentExpression(AssignmentExpression node) { | |
239 super.visitAssignmentExpression(node); | |
240 return handleAssignmentExpression(node); | |
241 } | |
242 | |
243 R handleAssignmentExpression(AssignmentExpression node) { | |
244 AccessSemantics semantics = | |
245 node.leftHandSide.accept(ACCESS_SEMANTICS_VISITOR); | |
246 if (semantics == null) { | |
247 return giveUp(node, 'handleAssignmentExpression with no AccessSemantics'); | |
248 } else { | |
249 switch (semantics.kind) { | |
250 case AccessKind.DYNAMIC: | |
251 return visitDynamicPropertyAssignment(node, semantics); | |
252 case AccessKind.LOCAL_FUNCTION: | |
253 return visitLocalFunctionAssignment(node, semantics); | |
254 case AccessKind.LOCAL_VARIABLE: | |
255 return visitLocalVariableAssignment(node, semantics); | |
256 case AccessKind.PARAMETER: | |
257 return visitParameterAssignment(node, semantics); | |
258 case AccessKind.STATIC_FIELD: | |
259 return visitStaticFieldAssignment(node, semantics); | |
260 case AccessKind.STATIC_METHOD: | |
261 return visitStaticMethodAssignment(node, semantics); | |
262 case AccessKind.STATIC_PROPERTY: | |
263 return visitStaticPropertyAssignment(node, semantics); | |
264 default: | |
265 // Unexpected access kind. | |
266 return giveUp(node, | |
267 'Unexpected ${semantics} in _handlePropertyAccess.'); | |
268 } | |
269 } | |
270 } | |
271 } | |
OLD | NEW |