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

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

Issue 1126173002: Refactor handling of compounds. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update status. Created 5 years, 7 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
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart2js.semantics_visitor; 5 part of dart2js.semantics_visitor;
6 6
7 enum SendStructureKind { 7 enum SendStructureKind {
8 GET, 8 GET,
9 SET, 9 SET,
10 INVOKE, 10 INVOKE,
(...skipping 10 matching lines...) Expand all
21 POSTFIX, 21 POSTFIX,
22 INDEX_PREFIX, 22 INDEX_PREFIX,
23 INDEX_POSTFIX, 23 INDEX_POSTFIX,
24 } 24 }
25 25
26 abstract class SendResolverMixin { 26 abstract class SendResolverMixin {
27 TreeElements get elements; 27 TreeElements get elements;
28 28
29 internalError(Spannable spannable, String message); 29 internalError(Spannable spannable, String message);
30 30
31 AccessSemantics handleStaticallyResolvedAccess(Send node, 31 AccessSemantics handleCompoundErroneousSetterAccess(
32 Element element, 32 Send node,
33 Element getter) { 33 Element setter,
34 Element getter) {
35 assert(invariant(node, Elements.isUnresolved(setter),
36 message: "Unexpected erreneous compound setter: $setter."));
37 if (getter.isStatic) {
38 if (getter.isGetter) {
39 return new CompoundAccessSemantics(
40 CompoundAccessKind.UNRESOLVED_STATIC_SETTER, getter, setter);
41 } else if (getter.isField) {
42 // TODO(johnniwinther): Handle const field separately.
43 assert(invariant(node, getter.isFinal || getter.isConst,
44 message: "Field expected to be final or const."));
45 return new StaticAccess.finalStaticField(getter);
46 } else if (getter.isFunction) {
47 return new StaticAccess.staticMethod(getter);
48 } else {
49 return internalError(node,
50 "Unexpected erroneous static compound: getter=$getter");
51 }
52 } else if (getter.isTopLevel) {
53 if (getter.isGetter) {
54 return new CompoundAccessSemantics(
55 CompoundAccessKind.UNRESOLVED_TOPLEVEL_SETTER, getter, setter);
56 } else if (getter.isField) {
57 // TODO(johnniwinther): Handle const field separately.
58 assert(invariant(node, getter.isFinal || getter.isConst,
59 message: "Field expected to be final or const."));
60 return new StaticAccess.finalTopLevelField(getter);
61 } else if (getter.isFunction) {
62 return new StaticAccess.topLevelMethod(getter);
63 } else {
64 return internalError(node,
65 "Unexpected erroneous top level compound: getter=$getter");
66 }
67 } else if (getter.isParameter) {
68 assert(invariant(node, getter.isFinal,
69 message: "Parameter expected to be final."));
70 return new StaticAccess.finalParameter(getter);
71 } else if (getter.isLocal) {
72 if (getter.isVariable) {
73 // TODO(johnniwinther): Handle const variable separately.
74 assert(invariant(node, getter.isFinal || getter.isConst,
75 message: "Variable expected to be final or const."));
76 return new StaticAccess.finalLocalVariable(getter);
77 } else if (getter.isFunction) {
78 return new StaticAccess.localFunction(getter);
79 } else {
80 return internalError(node,
81 "Unexpected erroneous local compound: getter=$getter");
82 }
83 } else if (getter.isErroneous) {
84 return new StaticAccess.unresolved(getter);
85 } else {
86 return internalError(node,
87 "Unexpected erroneous compound: getter=$getter");
88 }
89 }
90
91 AccessSemantics handleStaticallyResolvedAccess(
92 Send node,
93 Element element,
94 Element getter,
95 {bool isCompound}) {
96 if (element == null) {
97 assert(invariant(node, isCompound, message:
98 "Non-compound static access without element."));
99 assert(invariant(node, getter != null, message:
100 "Compound static access without element."));
101 return handleCompoundErroneousSetterAccess(node, element, getter);
102 }
34 if (element.isErroneous) { 103 if (element.isErroneous) {
104 if (isCompound) {
105 return handleCompoundErroneousSetterAccess(node, element, getter);
106 }
35 return new StaticAccess.unresolved(element); 107 return new StaticAccess.unresolved(element);
36 } else if (element.isParameter) { 108 } else if (element.isParameter) {
37 return new StaticAccess.parameter(element); 109 return new StaticAccess.parameter(element);
38 } else if (element.isLocal) { 110 } else if (element.isLocal) {
39 if (element.isFunction) { 111 if (element.isFunction) {
40 return new StaticAccess.localFunction(element); 112 return new StaticAccess.localFunction(element);
41 } else { 113 } else {
42 return new StaticAccess.localVariable(element); 114 return new StaticAccess.localVariable(element);
43 } 115 }
44 } else if (element.isStatic) { 116 } else if (element.isStatic) {
45 if (element.isField) { 117 if (element.isField) {
118 if (element.isFinal || element.isConst) {
119 // TODO(johnniwinther): Handle const field separately.
120 return new StaticAccess.finalStaticField(element);
121 }
46 return new StaticAccess.staticField(element); 122 return new StaticAccess.staticField(element);
47 } else if (element.isGetter) { 123 } else if (element.isGetter) {
124 if (isCompound) {
125 return new CompoundAccessSemantics(
126 CompoundAccessKind.UNRESOLVED_STATIC_SETTER, element, null);
127 }
48 return new StaticAccess.staticGetter(element); 128 return new StaticAccess.staticGetter(element);
49 } else if (element.isSetter) { 129 } else if (element.isSetter) {
50 if (getter != null) { 130 if (getter != null) {
51 CompoundAccessKind accessKind; 131 CompoundAccessKind accessKind;
52 if (getter.isGetter) { 132 if (getter.isErroneous) {
133 accessKind = CompoundAccessKind.UNRESOLVED_STATIC_GETTER;
134 } else if (getter.isAbstractField) {
135 AbstractFieldElement abstractField = getter;
136 if (abstractField.getter == null) {
137 accessKind = CompoundAccessKind.UNRESOLVED_STATIC_GETTER;
138 } else {
139 // TODO(johnniwinther): This might be dead code.
140 getter = abstractField.getter;
141 accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
142 }
143 } else if (getter.isGetter) {
53 accessKind = CompoundAccessKind.STATIC_GETTER_SETTER; 144 accessKind = CompoundAccessKind.STATIC_GETTER_SETTER;
54 } else { 145 } else {
55 accessKind = CompoundAccessKind.STATIC_METHOD_SETTER; 146 accessKind = CompoundAccessKind.STATIC_METHOD_SETTER;
56 } 147 }
57 return new CompoundAccessSemantics( 148 return new CompoundAccessSemantics(
58 accessKind, getter, element); 149 accessKind, getter, element);
59 } else { 150 } else {
60 return new StaticAccess.staticSetter(element); 151 return new StaticAccess.staticSetter(element);
61 } 152 }
62 } else { 153 } else {
63 return new StaticAccess.staticMethod(element); 154 return new StaticAccess.staticMethod(element);
64 } 155 }
65 } else if (element.isTopLevel) { 156 } else if (element.isTopLevel) {
66 if (element.isField) { 157 if (element.isField) {
158 if (element.isFinal || element.isConst) {
159 // TODO(johnniwinther): Handle const field separately.
160 return new StaticAccess.finalTopLevelField(element);
161 }
67 return new StaticAccess.topLevelField(element); 162 return new StaticAccess.topLevelField(element);
68 } else if (element.isGetter) { 163 } else if (element.isGetter) {
69 return new StaticAccess.topLevelGetter(element); 164 return new StaticAccess.topLevelGetter(element);
70 } else if (element.isSetter) { 165 } else if (element.isSetter) {
71 if (getter != null) { 166 if (getter != null) {
72 CompoundAccessKind accessKind; 167 CompoundAccessKind accessKind;
73 if (getter.isGetter) { 168 if (getter.isErroneous) {
169 accessKind = CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER;
170 } else if (getter.isAbstractField) {
171 AbstractFieldElement abstractField = getter;
172 if (abstractField.getter == null) {
173 accessKind = CompoundAccessKind.UNRESOLVED_TOPLEVEL_GETTER;
174 } else {
175 // TODO(johnniwinther): This might be dead code.
176 getter = abstractField.getter;
177 accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
178 }
179 } else if (getter.isGetter) {
74 accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER; 180 accessKind = CompoundAccessKind.TOPLEVEL_GETTER_SETTER;
75 } else { 181 } else {
76 accessKind = CompoundAccessKind.TOPLEVEL_METHOD_SETTER; 182 accessKind = CompoundAccessKind.TOPLEVEL_METHOD_SETTER;
77 } 183 }
78 return new CompoundAccessSemantics( 184 return new CompoundAccessSemantics(
79 accessKind, getter, element); 185 accessKind, getter, element);
80 } else { 186 } else {
81 return new StaticAccess.topLevelSetter(element); 187 return new StaticAccess.topLevelSetter(element);
82 } 188 }
83 } else { 189 } else {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 kind = SendStructureKind.BINARY; 314 kind = SendStructureKind.BINARY;
209 break; 315 break;
210 } 316 }
211 } else { 317 } else {
212 return const InvalidBinaryStructure(); 318 return const InvalidBinaryStructure();
213 } 319 }
214 } 320 }
215 } 321 }
216 AccessSemantics semantics = computeAccessSemantics( 322 AccessSemantics semantics = computeAccessSemantics(
217 node, 323 node,
218 isGetOrSet: kind == SendStructureKind.GET || 324 isSet: kind == SendStructureKind.SET,
219 kind == SendStructureKind.SET,
220 isInvoke: kind == SendStructureKind.INVOKE, 325 isInvoke: kind == SendStructureKind.INVOKE,
221 isCompound: kind == SendStructureKind.COMPOUND || 326 isCompound: kind == SendStructureKind.COMPOUND ||
222 kind == SendStructureKind.COMPOUND_INDEX_SET || 327 kind == SendStructureKind.COMPOUND_INDEX_SET ||
223 kind == SendStructureKind.PREFIX || 328 kind == SendStructureKind.PREFIX ||
224 kind == SendStructureKind.POSTFIX || 329 kind == SendStructureKind.POSTFIX ||
225 kind == SendStructureKind.INDEX_PREFIX || 330 kind == SendStructureKind.INDEX_PREFIX ||
226 kind == SendStructureKind.INDEX_POSTFIX); 331 kind == SendStructureKind.INDEX_POSTFIX);
227 if (semantics == null) { 332 if (semantics == null) {
228 return internalError(node, 'No semantics for $node'); 333 return internalError(node, 'No semantics for $node');
229 } 334 }
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 elements.getGetterSelectorInComplexSendSet(node); 412 elements.getGetterSelectorInComplexSendSet(node);
308 return new PostfixStructure( 413 return new PostfixStructure(
309 semantics, 414 semantics,
310 incDecOperator, 415 incDecOperator,
311 getterSelector, 416 getterSelector,
312 selector); 417 selector);
313 } 418 }
314 } 419 }
315 420
316 AccessSemantics computeAccessSemantics(Send node, 421 AccessSemantics computeAccessSemantics(Send node,
317 {bool isGetOrSet: false, 422 {bool isSet: false,
318 bool isInvoke: false, 423 bool isInvoke: false,
319 bool isCompound: false}) { 424 bool isCompound: false}) {
320 Element element = elements[node]; 425 Element element = elements[node];
321 Element getter = isCompound ? elements[node.selector] : null; 426 Element getter = isCompound ? elements[node.selector] : null;
322 if (elements.isTypeLiteral(node)) { 427 if (elements.isTypeLiteral(node)) {
323 DartType dartType = elements.getTypeLiteralType(node); 428 DartType dartType = elements.getTypeLiteralType(node);
324 // TODO(johnniwinther): Handle deferred constants. There are runtime 429 // TODO(johnniwinther): Handle deferred constants. There are runtime
325 // but not compile-time constants and should have their own 430 // but not compile-time constants and should have their own
326 // [DeferredConstantExpression] class. 431 // [DeferredConstantExpression] class.
327 ConstantExpression constant = elements.getConstant( 432 ConstantExpression constant = elements.getConstant(
328 isInvoke ? node.selector : node); 433 isInvoke || isSet || isCompound ? node.selector : node);
329 switch (dartType.kind) { 434 switch (dartType.kind) {
330 case TypeKind.INTERFACE: 435 case TypeKind.INTERFACE:
331 return new ConstantAccess.classTypeLiteral(constant); 436 return new ConstantAccess.classTypeLiteral(constant);
332 case TypeKind.TYPEDEF: 437 case TypeKind.TYPEDEF:
333 return new ConstantAccess.typedefTypeLiteral(constant); 438 return new ConstantAccess.typedefTypeLiteral(constant);
334 case TypeKind.TYPE_VARIABLE: 439 case TypeKind.TYPE_VARIABLE:
335 return new StaticAccess.typeParameterTypeLiteral(dartType.element); 440 return new StaticAccess.typeParameterTypeLiteral(dartType.element);
336 case TypeKind.DYNAMIC: 441 case TypeKind.DYNAMIC:
337 return new ConstantAccess.dynamicTypeLiteral(constant); 442 return new ConstantAccess.dynamicTypeLiteral(constant);
338 default: 443 default:
339 return internalError(node, "Unexpected type literal type: $dartType"); 444 return internalError(node, "Unexpected type literal type: $dartType");
340 } 445 }
341 } else if (node.isSuperCall) { 446 } else if (node.isSuperCall) {
342 if (Elements.isUnresolved(element)) { 447 if (Elements.isUnresolved(element)) {
343 if (isCompound) { 448 if (isCompound) {
344 if (Elements.isUnresolved(getter)) { 449 if (Elements.isUnresolved(getter)) {
345 // TODO(johnniwinther): Ensure that [getter] is not null. This 450 // TODO(johnniwinther): Ensure that [getter] is not null. This
346 // happens in the case of missing super getter. 451 // happens in the case of missing super getter.
347 return new CompoundAccessSemantics( 452 return new StaticAccess.unresolvedSuper(element);
348 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, element); 453 } else if (getter.isField) {
454 assert(invariant(node, getter.isFinal,
455 message: "Super field expected to be final."));
456 return new StaticAccess.superFinalField(getter);
457 } else if (getter.isFunction) {
458 if (node.isIndex) {
459 return new CompoundAccessSemantics(
460 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, element);
461 } else {
462 return new StaticAccess.superMethod(getter);
463 }
349 } else { 464 } else {
350 return new CompoundAccessSemantics( 465 return new CompoundAccessSemantics(
351 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, element); 466 CompoundAccessKind.UNRESOLVED_SUPER_SETTER, getter, element);
352 } 467 }
353 } else { 468 } else {
354 return new StaticAccess.unresolvedSuper(element); 469 return new StaticAccess.unresolvedSuper(element);
355 } 470 }
356 } else if (isCompound && Elements.isUnresolved(getter)) { 471 } else if (isCompound && Elements.isUnresolved(getter)) {
357 // TODO(johnniwinther): Ensure that [getter] is not null. This happens 472 // TODO(johnniwinther): Ensure that [getter] is not null. This happens
358 // in the case of missing super getter. 473 // in the case of missing super getter.
359 return new CompoundAccessSemantics( 474 return new CompoundAccessSemantics(
360 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, element); 475 CompoundAccessKind.UNRESOLVED_SUPER_GETTER, getter, element);
361 } else if (element.isField) { 476 } else if (element.isField) {
362 if (getter != null && getter != element) { 477 if (getter != null && getter != element) {
363 CompoundAccessKind accessKind; 478 CompoundAccessKind accessKind;
364 if (getter.isField) { 479 if (getter.isField) {
365 accessKind = CompoundAccessKind.SUPER_FIELD_FIELD; 480 accessKind = CompoundAccessKind.SUPER_FIELD_FIELD;
366 } else if (getter.isGetter) { 481 } else if (getter.isGetter) {
367 accessKind = CompoundAccessKind.SUPER_GETTER_FIELD; 482 accessKind = CompoundAccessKind.SUPER_GETTER_FIELD;
368 } else { 483 } else {
369 return internalError(node, 484 return internalError(node,
370 "Unsupported super call: $node : $element/$getter."); 485 "Unsupported super call: $node : $element/$getter.");
371 } 486 }
372 return new CompoundAccessSemantics(accessKind, getter, element); 487 return new CompoundAccessSemantics(accessKind, getter, element);
488 } else if (element.isFinal) {
489 return new StaticAccess.superFinalField(element);
373 } 490 }
374 return new StaticAccess.superField(element); 491 return new StaticAccess.superField(element);
375 } else if (element.isGetter) { 492 } else if (element.isGetter) {
376 return new StaticAccess.superGetter(element); 493 return new StaticAccess.superGetter(element);
377 } else if (element.isSetter) { 494 } else if (element.isSetter) {
378 if (getter != null) { 495 if (getter != null) {
379 CompoundAccessKind accessKind; 496 CompoundAccessKind accessKind;
380 if (getter.isField) { 497 if (getter.isField) {
381 accessKind = CompoundAccessKind.SUPER_FIELD_SETTER; 498 accessKind = CompoundAccessKind.SUPER_FIELD_SETTER;
382 } else if (getter.isGetter) { 499 } else if (getter.isGetter) {
(...skipping 15 matching lines...) Expand all
398 } else if (Elements.isClosureSend(node, element)) { 515 } else if (Elements.isClosureSend(node, element)) {
399 if (element == null) { 516 if (element == null) {
400 if (node.selector.isThis()) { 517 if (node.selector.isThis()) {
401 return new AccessSemantics.thisAccess(); 518 return new AccessSemantics.thisAccess();
402 } else { 519 } else {
403 return new AccessSemantics.expression(); 520 return new AccessSemantics.expression();
404 } 521 }
405 } else if (Elements.isErroneous(element)) { 522 } else if (Elements.isErroneous(element)) {
406 return new StaticAccess.unresolved(element); 523 return new StaticAccess.unresolved(element);
407 } else { 524 } else {
408 return handleStaticallyResolvedAccess(node, element, getter); 525 return handleStaticallyResolvedAccess(
526 node, element, getter, isCompound: isCompound);
409 } 527 }
410 } else { 528 } else {
411 if (Elements.isErroneous(element)) { 529 bool isDynamicAccess(Element e) => e == null || e.isInstanceMember;
412 return new StaticAccess.unresolved(element); 530
413 } else if (isCompound && Elements.isErroneous(getter)) { 531 if (isDynamicAccess(element) &&
414 return new StaticAccess.unresolved(getter); 532 (!isCompound || isDynamicAccess(getter))) {
415 } else if (element == null || element.isInstanceMember) {
416 if (node.receiver == null || node.receiver.isThis()) { 533 if (node.receiver == null || node.receiver.isThis()) {
417 return new AccessSemantics.thisProperty(); 534 return new AccessSemantics.thisProperty();
418 } else { 535 } else {
419 return new DynamicAccess.dynamicProperty(node.receiver); 536 return new DynamicAccess.dynamicProperty(node.receiver);
420 } 537 }
421 } else if (element.impliesType) { 538 } else if (element != null && element.impliesType) {
422 // TODO(johnniwinther): Provide an [ErroneousElement]. 539 // TODO(johnniwinther): Provide an [ErroneousElement].
423 // This happens for code like `C.this`. 540 // This happens for code like `C.this`.
424 return new StaticAccess.unresolved(null); 541 return new StaticAccess.unresolved(null);
425 } else { 542 } else {
426 return handleStaticallyResolvedAccess(node, element, getter); 543 return handleStaticallyResolvedAccess(
544 node, element, getter, isCompound: isCompound);
427 } 545 }
428 } 546 }
429 } 547 }
430 548
431 ConstructorAccessSemantics computeConstructorAccessSemantics( 549 ConstructorAccessSemantics computeConstructorAccessSemantics(
432 ConstructorElement constructor, 550 ConstructorElement constructor,
433 DartType type, 551 DartType type,
434 {bool mustBeConstant: false}) { 552 {bool mustBeConstant: false}) {
435 if (mustBeConstant && !constructor.isConst) { 553 if (mustBeConstant && !constructor.isConst) {
436 return new ConstructorAccessSemantics( 554 return new ConstructorAccessSemantics(
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 return internalError(node, "Unexpected variable $element."); 931 return internalError(node, "Unexpected variable $element.");
814 } 932 }
815 if (element.isConst) { 933 if (element.isConst) {
816 ConstantExpression constant = elements.getConstant(element.initializer); 934 ConstantExpression constant = elements.getConstant(element.initializer);
817 return new ConstantVariableStructure(kind, node, element, constant); 935 return new ConstantVariableStructure(kind, node, element, constant);
818 } else { 936 } else {
819 return new NonConstantVariableStructure(kind, node, element); 937 return new NonConstantVariableStructure(kind, node, element);
820 } 938 }
821 } 939 }
822 } 940 }
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