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

Side by Side Diff: pkg/compiler/lib/src/resolution/send_resolver.dart

Issue 929113002: Add SemanticVisitor to dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix indents and long lines. Created 5 years, 9 months 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2015, 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 part of dart2js.semantics_visitor;
6
7 enum SendStructureKind {
8 GET,
9 SET,
10 INVOKE,
11 UNARY,
12 NOT,
13 BINARY,
14 EQ,
15 NOT_EQ,
16 COMPOUND,
17 INDEX_SET,
18 COMPOUND_INDEX_SET,
19 PREFIX,
20 POSTFIX,
21 }
22
23 abstract class SendResolverMixin {
24 TreeElements get elements;
25
26 internalError(Spannable spannable, String message);
27
28 AccessSemantics handleStaticallyResolvedAccess(Send node,
29 Element element,
30 Element getter) {
31 if (element.isErroneous) {
32 return new StaticAccess.unresolved(element);
33 } else if (element.isParameter) {
34 return new StaticAccess.parameter(element);
35 } else if (element.isLocal) {
36 if (element.isFunction) {
37 return new StaticAccess.localFunction(element);
38 } else {
39 return new StaticAccess.localVariable(element);
40 }
41 } else if (element.isStatic) {
42 if (element.isField) {
43 return new StaticAccess.staticField(element);
44 } else if (element.isGetter) {
45 return new StaticAccess.staticGetter(element);
46 } else if (element.isSetter) {
47 if (getter != null) {
48 CompoundAccessKind accessKind;
49 if (getter.isGetter) {
50 accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
51 } else {
52 accessKind = CompoundAccessKind.STATIC_METHOD_SETTER;
53 }
54 return new CompoundAccessSemantics(
55 accessKind, getter, element);
56 } else {
57 return new StaticAccess.staticSetter(element);
58 }
59 } else {
60 return new StaticAccess.staticMethod(element);
61 }
62 } else if (element.isTopLevel) {
63 if (element.isField) {
64 return new StaticAccess.topLevelField(element);
65 } else if (element.isGetter) {
66 return new StaticAccess.topLevelGetter(element);
67 } else if (element.isSetter) {
68 if (getter != null) {
69 CompoundAccessKind accessKind;
70 if (getter.isGetter) {
71 accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
72 } else {
73 accessKind = CompoundAccessKind.TOPLEVEL_METHOD_SETTER;
74 }
75 return new CompoundAccessSemantics(
76 accessKind, getter, element);
77 } else {
78 return new StaticAccess.topLevelSetter(element);
79 }
80 } else {
81 return new StaticAccess.topLevelMethod(element);
82 }
83 } else {
84 return internalError(
85 node, "Unhandled resolved property access: $element");
86 }
87 }
88
89 SendStructure computeSendStructure(Send node) {
90 if (elements.isAssert(node)) {
91 if (!node.arguments.isEmpty && node.arguments.tail.isEmpty) {
92 return const AssertStructure();
93 } else {
94 return const InvalidAssertStructure();
95 }
96 }
97
98 AssignmentOperator assignmentOperator;
99 UnaryOperator unaryOperator;
100 BinaryOperator binaryOperator;
101 IncDecOperator incDecOperator;
102
103 if (node.isOperator) {
104 String operatorText = node.selector.asOperator().source;
105 if (operatorText == 'is') {
106 if (node.isIsNotCheck) {
107 return new IsNotStructure(
108 elements.getType(node.arguments.single.asSend().receiver));
109 } else {
110 return new IsStructure(elements.getType(node.arguments.single));
111 }
112 } else if (operatorText == 'as') {
113 return new AsStructure(elements.getType(node.arguments.single));
114 } else if (operatorText == '&&') {
115 return const LogicalAndStructure();
116 } else if (operatorText == '||') {
117 return const LogicalOrStructure();
118 }
119 }
120
121 SendStructureKind kind;
122
123 if (node.asSendSet() != null) {
124 SendSet sendSet = node.asSendSet();
125 String operatorText = sendSet.assignmentOperator.source;
126 if (sendSet.isPrefix || sendSet.isPostfix) {
127 kind = sendSet.isPrefix
128 ? SendStructureKind.PREFIX
129 : SendStructureKind.POSTFIX;
130 incDecOperator = IncDecOperator.parse(operatorText);
131 if (incDecOperator == null) {
132 return internalError(
133 node, "No inc/dec operator for '$operatorText'.");
134 }
135 } else {
136 assignmentOperator = AssignmentOperator.parse(operatorText);
137 if (assignmentOperator != null) {
138 switch (assignmentOperator.kind) {
139 case AssignmentOperatorKind.ASSIGN:
140 kind = SendStructureKind.SET;
141 break;
142 default:
143 kind = SendStructureKind.COMPOUND;
144 }
145 } else {
146 return internalError(
147 node, "No assignment operator for '$operatorText'.");
148 }
149 }
150 } else if (!node.isPropertyAccess) {
151 kind = SendStructureKind.INVOKE;
152 } else {
153 kind = SendStructureKind.GET;
154 }
155
156 if (node.isOperator) {
157 String operatorText = node.selector.asOperator().source;
158 if (node.arguments.isEmpty) {
159 unaryOperator = UnaryOperator.parse(operatorText);
160 if (unaryOperator != null) {
161 switch (unaryOperator.kind) {
162 case UnaryOperatorKind.NOT:
163 kind = SendStructureKind.NOT;
164 break;
165 default:
166 kind = SendStructureKind.UNARY;
167 break;
168 }
169 } else {
170 return const InvalidUnaryStructure();
171 }
172 } else {
173 binaryOperator = BinaryOperator.parse(operatorText);
174 if (binaryOperator != null) {
175 switch (binaryOperator.kind) {
176 case BinaryOperatorKind.EQ:
177 kind = SendStructureKind.EQ;
178 break;
179 case BinaryOperatorKind.NOT_EQ:
180 if (node.isSuperCall) {
181 // `super != foo` is a compile-time error.
182 return const InvalidBinaryStructure();
183 }
184 kind = SendStructureKind.NOT_EQ;
185 break;
186 case BinaryOperatorKind.INDEX:
187 if (node.arguments.tail.isEmpty) {
188 // a[b]
189 kind = SendStructureKind.BINARY;
190 } else {
191 if (kind == SendStructureKind.COMPOUND) {
192 // a[b] += c
193 kind = SendStructureKind.COMPOUND_INDEX_SET;
194 } else {
195 // a[b] = c
196 kind = SendStructureKind.INDEX_SET;
197 }
198 }
199 break;
200 default:
201 kind = SendStructureKind.BINARY;
202 break;
203 }
204 } else {
205 return const InvalidBinaryStructure();
206 }
207 }
208 }
209 AccessSemantics semantics = computeAccessSemantics(
210 node,
211 isGetOrSet: kind == SendStructureKind.GET ||
212 kind == SendStructureKind.SET,
213 isInvoke: kind == SendStructureKind.INVOKE,
214 isCompound: kind == SendStructureKind.COMPOUND ||
215 kind == SendStructureKind.COMPOUND_INDEX_SET ||
216 kind == SendStructureKind.PREFIX ||
217 kind == SendStructureKind.POSTFIX);
218 if (semantics == null) {
219 return internalError(node, 'No semantics for $node');
220 }
221 Selector selector = elements.getSelector(node);
222 switch (kind) {
223 case SendStructureKind.GET:
224 return new GetStructure(semantics, selector);
225 case SendStructureKind.SET:
226 return new SetStructure(semantics, selector);
227 case SendStructureKind.INVOKE:
228 return new InvokeStructure(semantics, selector);
229 case SendStructureKind.UNARY:
230 return new UnaryStructure(semantics, unaryOperator, selector);
231 case SendStructureKind.NOT:
232 assert(selector == null);
233 return new NotStructure(semantics, selector);
234 case SendStructureKind.BINARY:
235 return new BinaryStructure(semantics, binaryOperator, selector);
236 case SendStructureKind.EQ:
237 return new EqualsStructure(semantics, selector);
238 case SendStructureKind.NOT_EQ:
239 return new NotEqualsStructure(semantics, selector);
240 case SendStructureKind.COMPOUND:
241 Selector getterSelector =
242 elements.getGetterSelectorInComplexSendSet(node);
243 return new CompoundStructure(
244 semantics,
245 assignmentOperator,
246 getterSelector,
247 selector);
248 case SendStructureKind.INDEX_SET:
249 return new IndexSetStructure(semantics, selector);
250 case SendStructureKind.COMPOUND_INDEX_SET:
251 Selector getterSelector =
252 elements.getGetterSelectorInComplexSendSet(node);
253 return new CompoundIndexSetStructure(
254 semantics,
255 assignmentOperator,
256 getterSelector,
257 selector);
258 case SendStructureKind.PREFIX:
259 Selector getterSelector =
260 elements.getGetterSelectorInComplexSendSet(node);
261 return new PrefixStructure(
262 semantics,
263 incDecOperator,
264 getterSelector,
265 selector);
266 case SendStructureKind.POSTFIX:
267 Selector getterSelector =
268 elements.getGetterSelectorInComplexSendSet(node);
269 return new PostfixStructure(
270 semantics,
271 incDecOperator,
272 getterSelector,
273 selector);
274 }
275 }
276
277 AccessSemantics computeAccessSemantics(Send node,
278 {bool isGetOrSet: false,
279 bool isInvoke: false,
280 bool isCompound: false}) {
281 Element element = elements[node];
282 Element getter = isCompound ? elements[node.selector] : null;
283 if (elements.isTypeLiteral(node)) {
284 DartType dartType = elements.getTypeLiteralType(node);
285 TypeConstantExpression constant = elements.getConstant(
286 isInvoke ? node.selector : node);
287 switch (dartType.kind) {
288 case TypeKind.INTERFACE:
289 return new ConstantAccess.classTypeLiteral(constant);
290 case TypeKind.TYPEDEF:
291 return new ConstantAccess.typedefTypeLiteral(constant);
292 case TypeKind.TYPE_VARIABLE:
293 return new StaticAccess.typeParameterTypeLiteral(dartType.element);
294 case TypeKind.DYNAMIC:
295 return new ConstantAccess.dynamicTypeLiteral(constant);
296 default:
297 return internalError(node, "Unexpected type literal type: $dartType");
298 }
299 } else if (node.isSuperCall) {
300 if (Elements.isUnresolved(element)) {
301 return new StaticAccess.unresolved(element);
302 } else if (isCompound && Elements.isUnresolved(getter)) {
303 // TODO(johnniwinther): Ensure that [getter] is not null. This happens
304 // in the case of missing super getter.
305 return new StaticAccess.unresolved(getter);
306 } else if (element.isField) {
307 if (getter != null && getter != element) {
308 CompoundAccessKind accessKind;
309 if (getter.isField) {
310 accessKind = CompoundAccessKind.SUPER_FIELD_FIELD;
311 } else if (getter.isGetter) {
312 accessKind = CompoundAccessKind.SUPER_GETTER_FIELD;
313 } else {
314 return internalError(node,
315 "Unsupported super call: $node : $element/$getter.");
316 }
317 return new CompoundAccessSemantics(accessKind, getter, element);
318 }
319 return new StaticAccess.superField(element);
320 } else if (element.isGetter) {
321 return new StaticAccess.superGetter(element);
322 } else if (element.isSetter) {
323 if (getter != null) {
324 CompoundAccessKind accessKind;
325 if (getter.isField) {
326 accessKind = CompoundAccessKind.SUPER_FIELD_SETTER;
327 } else if (getter.isGetter) {
328 accessKind = CompoundAccessKind.SUPER_GETTER_SETTER;
329 } else {
330 accessKind = CompoundAccessKind.SUPER_METHOD_SETTER;
331 }
332 return new CompoundAccessSemantics(accessKind, getter, element);
333 }
334 return new StaticAccess.superSetter(element);
335 } else if (isCompound) {
336 return new CompoundAccessSemantics(
337 CompoundAccessKind.SUPER_GETTER_SETTER, getter, element);
338 } else {
339 return new StaticAccess.superMethod(element);
340 }
341 } else if (node.isOperator) {
342 return new DynamicAccess.dynamicProperty(node.receiver);
343 } else if (Elements.isClosureSend(node, element)) {
344 if (element == null) {
345 if (node.selector.isThis()) {
346 return new AccessSemantics.thisAccess();
347 } else {
348 return new AccessSemantics.expression();
349 }
350 } else if (Elements.isErroneous(element)) {
351 return new StaticAccess.unresolved(element);
352 } else {
353 return handleStaticallyResolvedAccess(node, element, getter);
354 }
355 } else {
356 if (Elements.isErroneous(element)) {
357 return new StaticAccess.unresolved(element);
358 } else if (element == null || element.isInstanceMember) {
359 if (node.receiver == null || node.receiver.isThis()) {
360 return new AccessSemantics.thisProperty();
361 } else {
362 return new DynamicAccess.dynamicProperty(node.receiver);
363 }
364 } else if (element.impliesType) {
365 // TODO(johnniwinther): Provide an [ErroneousElement].
366 // This happens for code like `C.this`.
367 return new StaticAccess.unresolved(null);
368 } else {
369 return handleStaticallyResolvedAccess(node, element, getter);
370 }
371 }
372 }
373 }
374
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/resolution/semantic_visitor_mixins.dart ('k') | pkg/compiler/lib/src/resolution/send_structure.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698