OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library dart2js.resolution.members; | 5 library dart2js.resolution.members; |
6 | 6 |
7 import '../common/names.dart' show | 7 import '../common/names.dart' show |
8 Selectors; | 8 Selectors; |
9 import '../compiler.dart' show | 9 import '../compiler.dart' show |
10 Compiler, | 10 Compiler, |
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
783 reportAndCreateErroneousElement( | 783 reportAndCreateErroneousElement( |
784 node, 'super', | 784 node, 'super', |
785 MessageKind.GENERIC, | 785 MessageKind.GENERIC, |
786 {'text': "Object has no superclass"}, | 786 {'text': "Object has no superclass"}, |
787 isError: true)); | 787 isError: true)); |
788 } | 788 } |
789 registry.registerSuperUse(node); | 789 registry.registerSuperUse(node); |
790 return null; | 790 return null; |
791 } | 791 } |
792 | 792 |
793 /// Check that access to `this` is currently allowed. | 793 /// Check that access to `this` is currently allowed. Returns an |
794 bool checkThisAccess(Send node) { | 794 /// [AccessSemantics] in case of an error, `null` otherwise. |
795 AccessSemantics checkThisAccess(Send node) { | |
floitsch
2015/08/21 15:20:52
Since this is not just a check anymore might be wo
Johnni Winther
2015/08/24 09:00:24
Ack. Any suggestions?
floitsch
2015/08/24 11:46:18
Not sure...
My best proposal is currently computeB
| |
795 if (!inInstanceContext) { | 796 if (!inInstanceContext) { |
796 compiler.reportError(node, MessageKind.NO_THIS_AVAILABLE); | 797 ErroneousElement error = reportAndCreateErroneousElement( |
797 return false; | 798 node, |
799 'this', | |
800 MessageKind.NO_THIS_AVAILABLE, | |
801 const {}); | |
802 return new StaticAccess.invalid(error); | |
798 } | 803 } |
799 return true; | 804 return null; |
800 } | 805 } |
801 | 806 |
802 /// Compute the [AccessSemantics] corresponding to a super access of [target]. | 807 /// Compute the [AccessSemantics] corresponding to a super access of [target]. |
803 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { | 808 AccessSemantics computeSuperAccessSemantics(Spannable node, Element target) { |
804 if (target.isErroneous) { | 809 if (target.isErroneous) { |
805 return new StaticAccess.unresolvedSuper(target); | 810 return new StaticAccess.unresolvedSuper(target); |
806 } else if (target.isGetter) { | 811 } else if (target.isGetter) { |
807 return new StaticAccess.superGetter(target); | 812 return new StaticAccess.superGetter(target); |
808 } else if (target.isSetter) { | 813 } else if (target.isSetter) { |
809 return new StaticAccess.superSetter(target); | 814 return new StaticAccess.superSetter(target); |
(...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1557 /// `this.name++`, or `name = b` and `name++` in instance context. | 1562 /// `this.name++`, or `name = b` and `name++` in instance context. |
1558 ResolutionResult handleThisPropertyUpdate( | 1563 ResolutionResult handleThisPropertyUpdate( |
1559 SendSet node, Name name, Element element) { | 1564 SendSet node, Name name, Element element) { |
1560 AccessSemantics semantics = const DynamicAccess.thisProperty(); | 1565 AccessSemantics semantics = const DynamicAccess.thisProperty(); |
1561 return handleDynamicUpdateSemantics(node, name, element, semantics); | 1566 return handleDynamicUpdateSemantics(node, name, element, semantics); |
1562 } | 1567 } |
1563 | 1568 |
1564 /// Handle access on `this`, like `this()` and `this` when it is parsed as a | 1569 /// Handle access on `this`, like `this()` and `this` when it is parsed as a |
1565 /// [Send] node. | 1570 /// [Send] node. |
1566 ResolutionResult handleThisAccess(Send node) { | 1571 ResolutionResult handleThisAccess(Send node) { |
1567 AccessSemantics accessSemantics = const DynamicAccess.thisAccess(); | |
1568 if (node.isCall) { | 1572 if (node.isCall) { |
1569 CallStructure callStructure = | 1573 CallStructure callStructure = |
1570 resolveArguments(node.argumentsNode).callStructure; | 1574 resolveArguments(node.argumentsNode).callStructure; |
1571 Selector selector = callStructure.callSelector; | 1575 Selector selector = callStructure.callSelector; |
1572 // TODO(johnniwinther): Handle invalid this access as an | 1576 // TODO(johnniwinther): Handle invalid this access as an |
1573 // [AccessSemantics]. | 1577 // [AccessSemantics]. |
1574 if (checkThisAccess(node)) { | 1578 AccessSemantics accessSemantics = checkThisAccess(node); |
1579 if (accessSemantics == null) { | |
1580 accessSemantics = const DynamicAccess.thisAccess(); | |
1575 registry.registerDynamicInvocation( | 1581 registry.registerDynamicInvocation( |
1576 new UniverseSelector(selector, null)); | 1582 new UniverseSelector(selector, null)); |
1577 registry.registerSendStructure(node, | |
1578 new InvokeStructure(accessSemantics, selector)); | |
1579 } | 1583 } |
1584 registry.registerSendStructure(node, | |
1585 new InvokeStructure(accessSemantics, selector)); | |
1580 // TODO(23998): Remove this when all information goes through | 1586 // TODO(23998): Remove this when all information goes through |
1581 // the [SendStructure]. | 1587 // the [SendStructure]. |
1582 registry.setSelector(node, selector); | 1588 registry.setSelector(node, selector); |
1589 return const NoneResult(); | |
1583 } else { | 1590 } else { |
1584 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. | 1591 // TODO(johnniwinther): Handle get of `this` when it is a [Send] node. |
1585 internalError(node, "Unexpected node '$node'."); | 1592 internalError(node, "Unexpected node '$node'."); |
1586 } | 1593 } |
1587 return const NoneResult(); | 1594 return const NoneResult(); |
1588 } | 1595 } |
1589 | 1596 |
1590 /// Handle access of a super property, like `super.foo` and `super.foo()`. | 1597 /// Handle access of a super property, like `super.foo` and `super.foo()`. |
1591 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { | 1598 ResolutionResult handleSuperPropertyAccess(Send node, Name name) { |
1592 Element target; | 1599 Element target; |
(...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2402 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. | 2409 /// `a.b`, `a.b()`, `this.a()` and `super.a()`. |
2403 ResolutionResult handleQualifiedSend(Send node) { | 2410 ResolutionResult handleQualifiedSend(Send node) { |
2404 Identifier selector = node.selector.asIdentifier(); | 2411 Identifier selector = node.selector.asIdentifier(); |
2405 String text = selector.source; | 2412 String text = selector.source; |
2406 Name name = new Name(text, enclosingElement.library); | 2413 Name name = new Name(text, enclosingElement.library); |
2407 if (text == 'this') { | 2414 if (text == 'this') { |
2408 return handleQualifiedThisAccess(node, name); | 2415 return handleQualifiedThisAccess(node, name); |
2409 } else if (node.isSuperCall) { | 2416 } else if (node.isSuperCall) { |
2410 return handleSuperPropertyAccess(node, name); | 2417 return handleSuperPropertyAccess(node, name); |
2411 } else if (node.receiver.isThis()) { | 2418 } else if (node.receiver.isThis()) { |
2412 if (checkThisAccess(node)) { | 2419 AccessSemantics semantics = checkThisAccess(node); |
2420 if (semantics == null) { | |
2413 return handleThisPropertyAccess(node, name); | 2421 return handleThisPropertyAccess(node, name); |
2422 } else { | |
2423 // TODO(johnniwinther): Handle invalid this access as an | |
2424 // [AccessSemantics]. | |
2425 return handleErroneousAccess(node, name, semantics); | |
2414 } | 2426 } |
2415 // TODO(johnniwinther): Handle invalid this access as an | |
2416 // [AccessSemantics]. | |
2417 return const NoneResult(); | |
2418 } | 2427 } |
2419 ResolutionResult result = visitExpressionPrefix(node.receiver); | 2428 ResolutionResult result = visitExpressionPrefix(node.receiver); |
2420 if (result.kind == ResultKind.PREFIX) { | 2429 if (result.kind == ResultKind.PREFIX) { |
2421 return handlePrefixSend(node, name, result); | 2430 return handlePrefixSend(node, name, result); |
2422 } else if (node.isConditional) { | 2431 } else if (node.isConditional) { |
2423 return handleDynamicAccessSemantics( | 2432 return handleDynamicAccessSemantics( |
2424 node, name, const DynamicAccess.ifNotNullProperty()); | 2433 node, name, const DynamicAccess.ifNotNullProperty()); |
2425 } else { | 2434 } else { |
2426 // Handle dynamic property access, like `a.b` or `a.b()` where `a` is not | 2435 // Handle dynamic property access, like `a.b` or `a.b()` where `a` is not |
2427 // a prefix or class. | 2436 // a prefix or class. |
2428 // TODO(johnniwinther): Use the `element` of [result]. | 2437 // TODO(johnniwinther): Use the `element` of [result]. |
2429 return handleDynamicAccessSemantics( | 2438 return handleDynamicAccessSemantics( |
2430 node, name, const DynamicAccess.dynamicProperty()); | 2439 node, name, const DynamicAccess.dynamicProperty()); |
2431 } | 2440 } |
2432 } | 2441 } |
2433 | 2442 |
2434 /// Handle a qualified [SendSet], that is where the receiver is non-null, like | 2443 /// Handle a qualified [SendSet], that is where the receiver is non-null, like |
2435 /// `a.b = c`, `a.b++`, and `a.b += c`. | 2444 /// `a.b = c`, `a.b++`, and `a.b += c`. |
2436 ResolutionResult handleQualifiedSendSet(SendSet node) { | 2445 ResolutionResult handleQualifiedSendSet(SendSet node) { |
2437 Identifier selector = node.selector.asIdentifier(); | 2446 Identifier selector = node.selector.asIdentifier(); |
2438 String text = selector.source; | 2447 String text = selector.source; |
2439 Name name = new Name(text, enclosingElement.library); | 2448 Name name = new Name(text, enclosingElement.library); |
2440 if (text == 'this') { | 2449 if (text == 'this') { |
2441 return handleQualifiedThisAccess(node, name); | 2450 return handleQualifiedThisAccess(node, name); |
2442 } else if (node.receiver.isThis()) { | 2451 } else if (node.receiver.isThis()) { |
2443 if (checkThisAccess(node)) { | 2452 AccessSemantics semantics = checkThisAccess(node); |
2453 if (semantics == null) { | |
2444 return handleThisPropertyUpdate(node, name, null); | 2454 return handleThisPropertyUpdate(node, name, null); |
2455 } else { | |
2456 // TODO(johnniwinther): Handle invalid this access as an | |
2457 // [AccessSemantics]. | |
2458 return handleUpdate(node, name, semantics); | |
2445 } | 2459 } |
2446 // TODO(johnniwinther): Handle invalid this access as an | |
2447 // [AccessSemantics]. | |
2448 return const NoneResult(); | |
2449 } | 2460 } |
2450 ResolutionResult result = visitExpressionPrefix(node.receiver); | 2461 ResolutionResult result = visitExpressionPrefix(node.receiver); |
2451 if (result.kind == ResultKind.PREFIX) { | 2462 if (result.kind == ResultKind.PREFIX) { |
2452 return handlePrefixSendSet(node, name, result); | 2463 return handlePrefixSendSet(node, name, result); |
2453 } else if (node.isConditional) { | 2464 } else if (node.isConditional) { |
2454 return handleDynamicUpdateSemantics( | 2465 return handleDynamicUpdateSemantics( |
2455 node, name, null, const DynamicAccess.ifNotNullProperty()); | 2466 node, name, null, const DynamicAccess.ifNotNullProperty()); |
2456 } else { | 2467 } else { |
2457 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c` | 2468 // Handle dynamic property access, like `a.b = c`, `a.b++` or `a.b += c` |
2458 // where `a` is not a prefix or class. | 2469 // where `a` is not a prefix or class. |
(...skipping 2192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4651 } | 4662 } |
4652 return const NoneResult(); | 4663 return const NoneResult(); |
4653 } | 4664 } |
4654 } | 4665 } |
4655 | 4666 |
4656 /// Looks up [name] in [scope] and unwraps the result. | 4667 /// Looks up [name] in [scope] and unwraps the result. |
4657 Element lookupInScope(Compiler compiler, Node node, | 4668 Element lookupInScope(Compiler compiler, Node node, |
4658 Scope scope, String name) { | 4669 Scope scope, String name) { |
4659 return Elements.unwrap(scope.lookup(name), compiler, node); | 4670 return Elements.unwrap(scope.lookup(name), compiler, node); |
4660 } | 4671 } |
OLD | NEW |