Chromium Code Reviews| 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 |