| 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 part of resolution; | 5 part of resolution; |
| 6 | 6 |
| 7 /// The state of constants in resolutions. | 7 /// The state of constants in resolutions. |
| 8 enum ConstantState { | 8 enum ConstantState { |
| 9 /// Expressions are not required to be constants. | 9 /// Expressions are not required to be constants. |
| 10 NON_CONSTANT, | 10 NON_CONSTANT, |
| (...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 // whether it is erroneous. | 1333 // whether it is erroneous. |
| 1334 if (semantics.kind == AccessKind.SUPER_METHOD) { | 1334 if (semantics.kind == AccessKind.SUPER_METHOD) { |
| 1335 registry.registerStaticUse(semantics.element.declaration); | 1335 registry.registerStaticUse(semantics.element.declaration); |
| 1336 } | 1336 } |
| 1337 // TODO(23998): Remove this when all information goes through | 1337 // TODO(23998): Remove this when all information goes through |
| 1338 // the [SendStructure]. | 1338 // the [SendStructure]. |
| 1339 registry.useElement(node, semantics.element); | 1339 registry.useElement(node, semantics.element); |
| 1340 } | 1340 } |
| 1341 } else { | 1341 } else { |
| 1342 ResolutionResult expressionResult = visitExpression(expression); | 1342 ResolutionResult expressionResult = visitExpression(expression); |
| 1343 semantics = new DynamicAccess.dynamicProperty(expression); | 1343 semantics = const DynamicAccess.dynamicProperty(); |
| 1344 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); | 1344 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); |
| 1345 | 1345 |
| 1346 if (expressionResult.isConstant) { | 1346 if (expressionResult.isConstant) { |
| 1347 bool isValidConstant; | 1347 bool isValidConstant; |
| 1348 ConstantExpression expressionConstant = expressionResult.constant; | 1348 ConstantExpression expressionConstant = expressionResult.constant; |
| 1349 DartType knownExpressionType = | 1349 DartType knownExpressionType = |
| 1350 expressionConstant.getKnownType(coreTypes); | 1350 expressionConstant.getKnownType(coreTypes); |
| 1351 switch (operator.kind) { | 1351 switch (operator.kind) { |
| 1352 case UnaryOperatorKind.COMPLEMENT: | 1352 case UnaryOperatorKind.COMPLEMENT: |
| 1353 isValidConstant = | 1353 isValidConstant = |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1379 return result; | 1379 return result; |
| 1380 } | 1380 } |
| 1381 | 1381 |
| 1382 /// Handle a not expression, like `!a`. | 1382 /// Handle a not expression, like `!a`. |
| 1383 ResolutionResult handleNot(Send node, UnaryOperator operator) { | 1383 ResolutionResult handleNot(Send node, UnaryOperator operator) { |
| 1384 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); | 1384 assert(invariant(node, operator.kind == UnaryOperatorKind.NOT)); |
| 1385 | 1385 |
| 1386 Node expression = node.receiver; | 1386 Node expression = node.receiver; |
| 1387 ResolutionResult result = visitExpression(expression); | 1387 ResolutionResult result = visitExpression(expression); |
| 1388 registry.registerSendStructure(node, | 1388 registry.registerSendStructure(node, |
| 1389 new NotStructure(new DynamicAccess.dynamicProperty(expression))); | 1389 new NotStructure(const DynamicAccess.dynamicProperty())); |
| 1390 | 1390 |
| 1391 if (result.isConstant) { | 1391 if (result.isConstant) { |
| 1392 ConstantExpression expressionConstant = result.constant; | 1392 ConstantExpression expressionConstant = result.constant; |
| 1393 if (expressionConstant.getKnownType(coreTypes) == coreTypes.boolType) { | 1393 if (expressionConstant.getKnownType(coreTypes) == coreTypes.boolType) { |
| 1394 // TODO(johnniwinther): Handle potentially invalid constant expressions. | 1394 // TODO(johnniwinther): Handle potentially invalid constant expressions. |
| 1395 ConstantExpression constant = | 1395 ConstantExpression constant = |
| 1396 new UnaryConstantExpression(operator, expressionConstant); | 1396 new UnaryConstantExpression(operator, expressionConstant); |
| 1397 registry.setConstant(node, constant); | 1397 registry.setConstant(node, constant); |
| 1398 return new ConstantResult(node, constant); | 1398 return new ConstantResult(node, constant); |
| 1399 } | 1399 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1509 } | 1509 } |
| 1510 // TODO(23998): Remove this when all information goes through | 1510 // TODO(23998): Remove this when all information goes through |
| 1511 // the [SendStructure]. | 1511 // the [SendStructure]. |
| 1512 registry.useElement(node, semantics.element); | 1512 registry.useElement(node, semantics.element); |
| 1513 } | 1513 } |
| 1514 visitExpression(right); | 1514 visitExpression(right); |
| 1515 } else { | 1515 } else { |
| 1516 ResolutionResult leftResult = visitExpression(left); | 1516 ResolutionResult leftResult = visitExpression(left); |
| 1517 ResolutionResult rightResult = visitExpression(right); | 1517 ResolutionResult rightResult = visitExpression(right); |
| 1518 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); | 1518 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); |
| 1519 semantics = new DynamicAccess.dynamicProperty(left); | 1519 semantics = const DynamicAccess.dynamicProperty(); |
| 1520 | 1520 |
| 1521 if (leftResult.isConstant && rightResult.isConstant) { | 1521 if (leftResult.isConstant && rightResult.isConstant) { |
| 1522 bool isValidConstant; | 1522 bool isValidConstant; |
| 1523 ConstantExpression leftConstant = leftResult.constant; | 1523 ConstantExpression leftConstant = leftResult.constant; |
| 1524 ConstantExpression rightConstant = rightResult.constant; | 1524 ConstantExpression rightConstant = rightResult.constant; |
| 1525 DartType knownLeftType = leftConstant.getKnownType(coreTypes); | 1525 DartType knownLeftType = leftConstant.getKnownType(coreTypes); |
| 1526 DartType knownRightType = rightConstant.getKnownType(coreTypes); | 1526 DartType knownRightType = rightConstant.getKnownType(coreTypes); |
| 1527 switch (operator.kind) { | 1527 switch (operator.kind) { |
| 1528 case BinaryOperatorKind.EQ: | 1528 case BinaryOperatorKind.EQ: |
| 1529 case BinaryOperatorKind.NOT_EQ: | 1529 case BinaryOperatorKind.NOT_EQ: |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 Node expression = node.selector; | 1643 Node expression = node.selector; |
| 1644 visitExpression(expression); | 1644 visitExpression(expression); |
| 1645 CallStructure callStructure = | 1645 CallStructure callStructure = |
| 1646 resolveArguments(node.argumentsNode).callStructure; | 1646 resolveArguments(node.argumentsNode).callStructure; |
| 1647 Selector selector = callStructure.callSelector; | 1647 Selector selector = callStructure.callSelector; |
| 1648 // TODO(23998): Remove this when all information goes through the | 1648 // TODO(23998): Remove this when all information goes through the |
| 1649 // [SendStructure]. | 1649 // [SendStructure]. |
| 1650 registry.setSelector(node, selector); | 1650 registry.setSelector(node, selector); |
| 1651 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); | 1651 registry.registerDynamicInvocation(new UniverseSelector(selector, null)); |
| 1652 registry.registerSendStructure(node, | 1652 registry.registerSendStructure(node, |
| 1653 new InvokeStructure(new AccessSemantics.expression(), selector)); | 1653 new InvokeStructure(const DynamicAccess.expression(), selector)); |
| 1654 return const NoneResult(); | 1654 return const NoneResult(); |
| 1655 } | 1655 } |
| 1656 | 1656 |
| 1657 /// Handle a, possibly invalid, assertion, like `assert(cond)` or `assert()`. | 1657 /// Handle a, possibly invalid, assertion, like `assert(cond)` or `assert()`. |
| 1658 ResolutionResult handleAssert(Send node) { | 1658 ResolutionResult handleAssert(Send node) { |
| 1659 assert(invariant(node, node.isCall, | 1659 assert(invariant(node, node.isCall, |
| 1660 message: "Unexpected assert: $node")); | 1660 message: "Unexpected assert: $node")); |
| 1661 // If this send is of the form "assert(expr);", then | 1661 // If this send is of the form "assert(expr);", then |
| 1662 // this is an assertion. | 1662 // this is an assertion. |
| 1663 | 1663 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1678 sendStructure = const InvalidAssertStructure(); | 1678 sendStructure = const InvalidAssertStructure(); |
| 1679 } | 1679 } |
| 1680 registry.registerAssert(node); | 1680 registry.registerAssert(node); |
| 1681 registry.registerSendStructure(node, sendStructure); | 1681 registry.registerSendStructure(node, sendStructure); |
| 1682 return const AssertResult(); | 1682 return const AssertResult(); |
| 1683 } | 1683 } |
| 1684 | 1684 |
| 1685 /// Handle access of a property of [name] on `this`, like `this.name` and | 1685 /// Handle access of a property of [name] on `this`, like `this.name` and |
| 1686 /// `this.name()`, or `name` and `name()` in instance context. | 1686 /// `this.name()`, or `name` and `name()` in instance context. |
| 1687 ResolutionResult handleThisPropertyAccess(Send node, Name name) { | 1687 ResolutionResult handleThisPropertyAccess(Send node, Name name) { |
| 1688 AccessSemantics semantics = new AccessSemantics.thisProperty(); | 1688 AccessSemantics semantics = const DynamicAccess.thisProperty(); |
| 1689 return handleDynamicAccessSemantics(node, name, semantics); | 1689 return handleDynamicAccessSemantics(node, name, semantics); |
| 1690 } | 1690 } |
| 1691 | 1691 |
| 1692 /// Handle access on `this`, like `this()` and `this` when it is parsed as a | 1692 /// Handle access on `this`, like `this()` and `this` when it is parsed as a |
| 1693 /// [Send] node. | 1693 /// [Send] node. |
| 1694 ResolutionResult handleThisAccess(Send node) { | 1694 ResolutionResult handleThisAccess(Send node) { |
| 1695 AccessSemantics accessSemantics = new AccessSemantics.thisAccess(); | 1695 AccessSemantics accessSemantics = const DynamicAccess.thisAccess(); |
| 1696 if (node.isCall) { | 1696 if (node.isCall) { |
| 1697 CallStructure callStructure = | 1697 CallStructure callStructure = |
| 1698 resolveArguments(node.argumentsNode).callStructure; | 1698 resolveArguments(node.argumentsNode).callStructure; |
| 1699 Selector selector = callStructure.callSelector; | 1699 Selector selector = callStructure.callSelector; |
| 1700 // TODO(johnniwinther): Handle invalid this access as an | 1700 // TODO(johnniwinther): Handle invalid this access as an |
| 1701 // [AccessSemantics]. | 1701 // [AccessSemantics]. |
| 1702 if (checkThisAccess(node)) { | 1702 if (checkThisAccess(node)) { |
| 1703 registry.registerDynamicInvocation( | 1703 registry.registerDynamicInvocation( |
| 1704 new UniverseSelector(selector, null)); | 1704 new UniverseSelector(selector, null)); |
| 1705 registry.registerSendStructure(node, | 1705 registry.registerSendStructure(node, |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2219 registry.registerSendStructure(node, sendStructure); | 2219 registry.registerSendStructure(node, sendStructure); |
| 2220 // TODO(23998): Remove this when all information goes through | 2220 // TODO(23998): Remove this when all information goes through |
| 2221 // the [SendStructure]. | 2221 // the [SendStructure]. |
| 2222 registry.setSelector(node, selector); | 2222 registry.setSelector(node, selector); |
| 2223 return const NoneResult(); | 2223 return const NoneResult(); |
| 2224 } | 2224 } |
| 2225 | 2225 |
| 2226 /// Handle dynamic property access, like `a.b` or `a.b()` where `a` is not a | 2226 /// Handle dynamic property access, like `a.b` or `a.b()` where `a` is not a |
| 2227 /// prefix or class. | 2227 /// prefix or class. |
| 2228 ResolutionResult handleDynamicPropertyAccess(Send node, Name name) { | 2228 ResolutionResult handleDynamicPropertyAccess(Send node, Name name) { |
| 2229 AccessSemantics semantics = | 2229 AccessSemantics semantics = const DynamicAccess.dynamicProperty(); |
| 2230 new DynamicAccess.dynamicProperty(node.receiver); | |
| 2231 return handleDynamicAccessSemantics(node, name, semantics); | 2230 return handleDynamicAccessSemantics(node, name, semantics); |
| 2232 } | 2231 } |
| 2233 | 2232 |
| 2234 /// Handle conditional access, like `a?.b` or `a?.b()`. | 2233 /// Handle conditional access, like `a?.b` or `a?.b()`. |
| 2235 ResolutionResult handleConditionalAccess(Send node, Name name) { | 2234 ResolutionResult handleConditionalAccess(Send node, Name name) { |
| 2236 Node receiver = node.receiver; | 2235 Node receiver = node.receiver; |
| 2237 visitConditionalPrefix(receiver); | 2236 visitConditionalPrefix(receiver); |
| 2238 AccessSemantics semantics = | 2237 AccessSemantics semantics = const DynamicAccess.ifNotNullProperty(); |
| 2239 new DynamicAccess.ifNotNullProperty(receiver); | |
| 2240 return handleDynamicAccessSemantics(node, name, semantics); | 2238 return handleDynamicAccessSemantics(node, name, semantics); |
| 2241 } | 2239 } |
| 2242 | 2240 |
| 2243 /// Handle `this` as a qualified property, like `a.this`. | 2241 /// Handle `this` as a qualified property, like `a.this`. |
| 2244 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { | 2242 ResolutionResult handleQualifiedThisAccess(Send node, Name name) { |
| 2245 ErroneousElement error = reportAndCreateErroneousElement( | 2243 ErroneousElement error = reportAndCreateErroneousElement( |
| 2246 node.selector, | 2244 node.selector, |
| 2247 name.text, | 2245 name.text, |
| 2248 MessageKind.THIS_PROPERTY, {}, | 2246 MessageKind.THIS_PROPERTY, {}, |
| 2249 isError: true); | 2247 isError: true); |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2771 /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`. | 2769 /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`. |
| 2772 ResolutionResult handleIndexSendSet(SendSet node) { | 2770 ResolutionResult handleIndexSendSet(SendSet node) { |
| 2773 String operatorText = node.assignmentOperator.source; | 2771 String operatorText = node.assignmentOperator.source; |
| 2774 Node receiver = node.receiver; | 2772 Node receiver = node.receiver; |
| 2775 Node index = node.arguments.head; | 2773 Node index = node.arguments.head; |
| 2776 visitExpression(receiver); | 2774 visitExpression(receiver); |
| 2777 visitExpression(index); | 2775 visitExpression(index); |
| 2778 if (node.isPrefix || node.isPostfix) { | 2776 if (node.isPrefix || node.isPostfix) { |
| 2779 // `a[b]++` or `++a[b]`. | 2777 // `a[b]++` or `++a[b]`. |
| 2780 IncDecOperator operator = IncDecOperator.parse(operatorText); | 2778 IncDecOperator operator = IncDecOperator.parse(operatorText); |
| 2781 AccessSemantics semantics = new DynamicAccess.dynamicProperty(receiver); | 2779 AccessSemantics semantics = const DynamicAccess.dynamicProperty(); |
| 2782 Selector getterSelector = new Selector.index(); | 2780 Selector getterSelector = new Selector.index(); |
| 2783 Selector setterSelector = new Selector.indexSet(); | 2781 Selector setterSelector = new Selector.indexSet(); |
| 2784 Selector operatorSelector = | 2782 Selector operatorSelector = |
| 2785 new Selector.binaryOperator(operator.selectorName); | 2783 new Selector.binaryOperator(operator.selectorName); |
| 2786 | 2784 |
| 2787 // TODO(23998): Remove these when selectors are only accessed | 2785 // TODO(23998): Remove these when selectors are only accessed |
| 2788 // through the send structure. | 2786 // through the send structure. |
| 2789 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 2787 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 2790 registry.setSelector(node, setterSelector); | 2788 registry.setSelector(node, setterSelector); |
| 2791 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 2789 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2804 semantics, operator, getterSelector, setterSelector); | 2802 semantics, operator, getterSelector, setterSelector); |
| 2805 registry.registerSendStructure(node, sendStructure); | 2803 registry.registerSendStructure(node, sendStructure); |
| 2806 return const NoneResult(); | 2804 return const NoneResult(); |
| 2807 } else { | 2805 } else { |
| 2808 Node rhs = node.arguments.tail.head; | 2806 Node rhs = node.arguments.tail.head; |
| 2809 visitExpression(rhs); | 2807 visitExpression(rhs); |
| 2810 | 2808 |
| 2811 AssignmentOperator operator = AssignmentOperator.parse(operatorText); | 2809 AssignmentOperator operator = AssignmentOperator.parse(operatorText); |
| 2812 if (operator.kind == AssignmentOperatorKind.ASSIGN) { | 2810 if (operator.kind == AssignmentOperatorKind.ASSIGN) { |
| 2813 // `a[b] = c`. | 2811 // `a[b] = c`. |
| 2814 AccessSemantics semantics = new DynamicAccess.dynamicProperty(receiver); | 2812 AccessSemantics semantics = const DynamicAccess.dynamicProperty(); |
| 2815 Selector setterSelector = new Selector.indexSet(); | 2813 Selector setterSelector = new Selector.indexSet(); |
| 2816 | 2814 |
| 2817 // TODO(23998): Remove this when selectors are only accessed | 2815 // TODO(23998): Remove this when selectors are only accessed |
| 2818 // through the send structure. | 2816 // through the send structure. |
| 2819 registry.setSelector(node, setterSelector); | 2817 registry.setSelector(node, setterSelector); |
| 2820 registry.registerDynamicInvocation( | 2818 registry.registerDynamicInvocation( |
| 2821 new UniverseSelector(setterSelector, null)); | 2819 new UniverseSelector(setterSelector, null)); |
| 2822 | 2820 |
| 2823 SendStructure sendStructure = | 2821 SendStructure sendStructure = |
| 2824 new IndexSetStructure(semantics, setterSelector); | 2822 new IndexSetStructure(semantics, setterSelector); |
| 2825 registry.registerSendStructure(node, sendStructure); | 2823 registry.registerSendStructure(node, sendStructure); |
| 2826 return const NoneResult(); | 2824 return const NoneResult(); |
| 2827 } else { | 2825 } else { |
| 2828 // `a[b] += c`. | 2826 // `a[b] += c`. |
| 2829 AccessSemantics semantics = new DynamicAccess.dynamicProperty(receiver); | 2827 AccessSemantics semantics = const DynamicAccess.dynamicProperty(); |
| 2830 Selector getterSelector = new Selector.index(); | 2828 Selector getterSelector = new Selector.index(); |
| 2831 Selector setterSelector = new Selector.indexSet(); | 2829 Selector setterSelector = new Selector.indexSet(); |
| 2832 Selector operatorSelector = | 2830 Selector operatorSelector = |
| 2833 new Selector.binaryOperator(operator.selectorName); | 2831 new Selector.binaryOperator(operator.selectorName); |
| 2834 | 2832 |
| 2835 // TODO(23998): Remove these when selectors are only accessed | 2833 // TODO(23998): Remove these when selectors are only accessed |
| 2836 // through the send structure. | 2834 // through the send structure. |
| 2837 registry.setGetterSelectorInComplexSendSet(node, getterSelector); | 2835 registry.setGetterSelectorInComplexSendSet(node, getterSelector); |
| 2838 registry.setSelector(node, setterSelector); | 2836 registry.setSelector(node, setterSelector); |
| 2839 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); | 2837 registry.setOperatorSelectorInComplexSendSet(node, operatorSelector); |
| (...skipping 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4421 } | 4419 } |
| 4422 return const NoneResult(); | 4420 return const NoneResult(); |
| 4423 } | 4421 } |
| 4424 } | 4422 } |
| 4425 | 4423 |
| 4426 /// Looks up [name] in [scope] and unwraps the result. | 4424 /// Looks up [name] in [scope] and unwraps the result. |
| 4427 Element lookupInScope(Compiler compiler, Node node, | 4425 Element lookupInScope(Compiler compiler, Node node, |
| 4428 Scope scope, String name) { | 4426 Scope scope, String name) { |
| 4429 return Elements.unwrap(scope.lookup(name), compiler, node); | 4427 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4430 } | 4428 } |
| OLD | NEW |