| 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 abstract class TreeElements { | 7 abstract class TreeElements { |
| 8 Element get currentElement; | 8 Element get currentElement; |
| 9 Setlet<Node> get superUses; | 9 Setlet<Node> get superUses; |
| 10 | 10 |
| (...skipping 1648 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 breakTargetStack = breakTargetStack.tail; | 1659 breakTargetStack = breakTargetStack.tail; |
| 1660 labels = labels.outer; | 1660 labels = labels.outer; |
| 1661 } | 1661 } |
| 1662 } | 1662 } |
| 1663 | 1663 |
| 1664 class TypeResolver { | 1664 class TypeResolver { |
| 1665 final Compiler compiler; | 1665 final Compiler compiler; |
| 1666 | 1666 |
| 1667 TypeResolver(this.compiler); | 1667 TypeResolver(this.compiler); |
| 1668 | 1668 |
| 1669 Element resolveTypeName(Scope scope, | 1669 /// Tries to resolve the type name as an element. |
| 1670 Identifier prefixName, | 1670 Element resolveTypeName(Identifier prefixName, |
| 1671 Identifier typeName) { | 1671 Identifier typeName, |
| 1672 Scope scope, |
| 1673 {bool deferredIsMalformed: true}) { |
| 1674 Element element; |
| 1675 bool deferredTypeAnnotation = false; |
| 1672 if (prefixName != null) { | 1676 if (prefixName != null) { |
| 1673 Element element = | 1677 Element prefixElement = |
| 1674 lookupInScope(compiler, prefixName, scope, prefixName.source); | 1678 lookupInScope(compiler, prefixName, scope, prefixName.source); |
| 1675 if (element != null && element.isPrefix()) { | 1679 if (prefixElement != null && prefixElement.isPrefix()) { |
| 1676 // The receiver is a prefix. Lookup in the imported members. | 1680 // The receiver is a prefix. Lookup in the imported members. |
| 1677 PrefixElement prefix = element; | 1681 PrefixElement prefix = prefixElement; |
| 1678 return prefix.lookupLocalMember(typeName.source); | 1682 element = prefix.lookupLocalMember(typeName.source); |
| 1683 // TODO(17260, sigurdm): The test for DartBackend is there because |
| 1684 // dart2dart outputs malformed types with prefix. |
| 1685 if (element != null && |
| 1686 prefix.isDeferred && |
| 1687 deferredIsMalformed && |
| 1688 compiler.backend is! DartBackend) { |
| 1689 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION, |
| 1690 {'node': typeName}, |
| 1691 element.name, |
| 1692 element); |
| 1693 } |
| 1694 } else { |
| 1695 // The caller of this method will create the ErroneousElement for |
| 1696 // the MalformedType. |
| 1697 element = null; |
| 1679 } | 1698 } |
| 1680 // The caller of this method will create the ErroneousElement for | |
| 1681 // the MalformedType. | |
| 1682 return null; | |
| 1683 } else { | 1699 } else { |
| 1684 String stringValue = typeName.source; | 1700 String stringValue = typeName.source; |
| 1685 if (identical(stringValue, 'void')) { | 1701 if (identical(stringValue, 'void')) { |
| 1686 return compiler.types.voidType.element; | 1702 element = compiler.types.voidType.element; |
| 1687 } else if (identical(stringValue, 'dynamic')) { | 1703 } else if (identical(stringValue, 'dynamic')) { |
| 1688 return compiler.dynamicClass; | 1704 element = compiler.dynamicClass; |
| 1689 } else { | 1705 } else { |
| 1690 return lookupInScope(compiler, typeName, scope, typeName.source); | 1706 element = lookupInScope(compiler, typeName, scope, typeName.source); |
| 1691 } | 1707 } |
| 1692 } | 1708 } |
| 1709 return element; |
| 1693 } | 1710 } |
| 1694 | 1711 |
| 1695 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, | 1712 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, |
| 1696 {bool malformedIsError: false}) { | 1713 {bool malformedIsError: false, |
| 1714 bool deferredIsMalformed: true}) { |
| 1697 Identifier typeName; | 1715 Identifier typeName; |
| 1698 Identifier prefixName; | 1716 Identifier prefixName; |
| 1699 Send send = node.typeName.asSend(); | 1717 Send send = node.typeName.asSend(); |
| 1700 if (send != null) { | 1718 if (send != null) { |
| 1701 // The type name is of the form [: prefix . identifier :]. | 1719 // The type name is of the form [: prefix . identifier :]. |
| 1702 prefixName = send.receiver.asIdentifier(); | 1720 prefixName = send.receiver.asIdentifier(); |
| 1703 typeName = send.selector.asIdentifier(); | 1721 typeName = send.selector.asIdentifier(); |
| 1704 } else { | 1722 } else { |
| 1705 typeName = node.typeName.asIdentifier(); | 1723 typeName = node.typeName.asIdentifier(); |
| 1706 } | 1724 } |
| 1707 | 1725 |
| 1708 Element element = resolveTypeName(visitor.scope, prefixName, typeName); | 1726 Element element = resolveTypeName(prefixName, typeName, visitor.scope, |
| 1727 deferredIsMalformed: deferredIsMalformed); |
| 1709 | 1728 |
| 1710 DartType reportFailureAndCreateType(MessageKind messageKind, | 1729 DartType reportFailureAndCreateType(MessageKind messageKind, |
| 1711 Map messageArguments, | 1730 Map messageArguments, |
| 1712 {DartType userProvidedBadType}) { | 1731 {DartType userProvidedBadType, |
| 1732 Element erroneousElement}) { |
| 1713 if (malformedIsError) { | 1733 if (malformedIsError) { |
| 1714 visitor.error(node, messageKind, messageArguments); | 1734 visitor.error(node, messageKind, messageArguments); |
| 1715 } else { | 1735 } else { |
| 1716 compiler.backend.registerThrowRuntimeError(visitor.mapping); | 1736 compiler.backend.registerThrowRuntimeError(visitor.mapping); |
| 1717 visitor.warning(node, messageKind, messageArguments); | 1737 visitor.warning(node, messageKind, messageArguments); |
| 1718 } | 1738 } |
| 1719 Element erroneousElement = new ErroneousElementX( | 1739 if (erroneousElement == null) { |
| 1720 messageKind, messageArguments, typeName.source, | 1740 erroneousElement = new ErroneousElementX( |
| 1721 visitor.enclosingElement); | 1741 messageKind, messageArguments, typeName.source, |
| 1742 visitor.enclosingElement); |
| 1743 } |
| 1722 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); | 1744 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); |
| 1723 resolveTypeArguments(visitor, node, null, arguments); | 1745 resolveTypeArguments(visitor, node, null, arguments); |
| 1724 return new MalformedType(erroneousElement, | 1746 return new MalformedType(erroneousElement, |
| 1725 userProvidedBadType, arguments.toLink()); | 1747 userProvidedBadType, arguments.toLink()); |
| 1726 } | 1748 } |
| 1727 | 1749 |
| 1728 DartType checkNoTypeArguments(DartType type) { | 1750 DartType checkNoTypeArguments(DartType type) { |
| 1729 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); | 1751 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); |
| 1730 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1752 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1731 visitor, node, const Link<DartType>(), arguments); | 1753 visitor, node, const Link<DartType>(), arguments); |
| 1732 if (hasTypeArgumentMismatch) { | 1754 if (hasTypeArgumentMismatch) { |
| 1733 return new MalformedType( | 1755 return new MalformedType( |
| 1734 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1756 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1735 {'type': node}, typeName.source, visitor.enclosingElement), | 1757 {'type': node}, typeName.source, visitor.enclosingElement), |
| 1736 type, arguments.toLink()); | 1758 type, arguments.toLink()); |
| 1737 } | 1759 } |
| 1738 return type; | 1760 return type; |
| 1739 } | 1761 } |
| 1740 | 1762 |
| 1763 // Try to construct the type from the element. |
| 1741 DartType type; | 1764 DartType type; |
| 1742 if (element == null) { | 1765 if (element == null) { |
| 1743 type = reportFailureAndCreateType( | 1766 type = reportFailureAndCreateType( |
| 1744 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 1767 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
| 1745 } else if (element.isAmbiguous()) { | 1768 } else if (element.isAmbiguous()) { |
| 1746 AmbiguousElement ambiguous = element; | 1769 AmbiguousElement ambiguous = element; |
| 1747 type = reportFailureAndCreateType( | 1770 type = reportFailureAndCreateType( |
| 1748 ambiguous.messageKind, ambiguous.messageArguments); | 1771 ambiguous.messageKind, ambiguous.messageArguments); |
| 1749 ambiguous.diagnose(visitor.mapping.currentElement, compiler); | 1772 ambiguous.diagnose(visitor.mapping.currentElement, compiler); |
| 1773 } else if (element.isErroneous()) { |
| 1774 ErroneousElement erroneousElement = element; |
| 1775 type = reportFailureAndCreateType( |
| 1776 erroneousElement.messageKind, erroneousElement.messageArguments, |
| 1777 erroneousElement: erroneousElement); |
| 1750 } else if (!element.impliesType()) { | 1778 } else if (!element.impliesType()) { |
| 1751 type = reportFailureAndCreateType( | 1779 type = reportFailureAndCreateType( |
| 1752 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1780 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1753 } else { | 1781 } else { |
| 1754 bool addTypeVariableBoundsCheck = false; | 1782 bool addTypeVariableBoundsCheck = false; |
| 1755 if (identical(element, compiler.types.voidType.element) || | 1783 if (identical(element, compiler.types.voidType.element) || |
| 1756 identical(element, compiler.dynamicClass)) { | 1784 identical(element, compiler.dynamicClass)) { |
| 1757 type = checkNoTypeArguments(element.computeType(compiler)); | 1785 type = checkNoTypeArguments(element.computeType(compiler)); |
| 1758 } else if (element.isClass()) { | 1786 } else if (element.isClass()) { |
| 1759 ClassElement cls = element; | 1787 ClassElement cls = element; |
| (...skipping 1414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3174 return node.accept(new ConstructorResolver(compiler, this)); | 3202 return node.accept(new ConstructorResolver(compiler, this)); |
| 3175 } | 3203 } |
| 3176 | 3204 |
| 3177 FunctionElement resolveRedirectingFactory(Return node, | 3205 FunctionElement resolveRedirectingFactory(Return node, |
| 3178 {bool inConstContext: false}) { | 3206 {bool inConstContext: false}) { |
| 3179 return node.accept(new ConstructorResolver(compiler, this, | 3207 return node.accept(new ConstructorResolver(compiler, this, |
| 3180 inConstContext: inConstContext)); | 3208 inConstContext: inConstContext)); |
| 3181 } | 3209 } |
| 3182 | 3210 |
| 3183 DartType resolveTypeAnnotation(TypeAnnotation node, | 3211 DartType resolveTypeAnnotation(TypeAnnotation node, |
| 3184 {bool malformedIsError: false}) { | 3212 {bool malformedIsError: false, |
| 3213 bool deferredIsMalformed: true}) { |
| 3185 DartType type = typeResolver.resolveTypeAnnotation( | 3214 DartType type = typeResolver.resolveTypeAnnotation( |
| 3186 this, node, malformedIsError: malformedIsError); | 3215 this, node, malformedIsError: malformedIsError, |
| 3216 deferredIsMalformed: deferredIsMalformed); |
| 3187 if (type == null) return null; | 3217 if (type == null) return null; |
| 3188 if (inCheckContext) { | 3218 if (inCheckContext) { |
| 3189 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 3219 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 3190 compiler.backend.registerRequiredType(type, enclosingElement); | 3220 compiler.backend.registerRequiredType(type, enclosingElement); |
| 3191 } | 3221 } |
| 3192 return type; | 3222 return type; |
| 3193 } | 3223 } |
| 3194 | 3224 |
| 3195 visitModifiers(Modifiers node) { | 3225 visitModifiers(Modifiers node) { |
| 3196 internalError(node, 'modifiers'); | 3226 internalError(node, 'modifiers'); |
| (...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4560 } else { | 4590 } else { |
| 4561 type = element.getEnclosingClass().computeType(compiler).asRaw(); | 4591 type = element.getEnclosingClass().computeType(compiler).asRaw(); |
| 4562 } | 4592 } |
| 4563 } | 4593 } |
| 4564 resolver.mapping.setType(expression, type); | 4594 resolver.mapping.setType(expression, type); |
| 4565 return element; | 4595 return element; |
| 4566 } | 4596 } |
| 4567 | 4597 |
| 4568 Element visitTypeAnnotation(TypeAnnotation node) { | 4598 Element visitTypeAnnotation(TypeAnnotation node) { |
| 4569 assert(invariant(node, type == null)); | 4599 assert(invariant(node, type == null)); |
| 4600 // This is not really resolving a type-annotation, but the name of the |
| 4601 // constructor. Therefore we allow deferred types. |
| 4570 type = resolver.resolveTypeAnnotation(node, | 4602 type = resolver.resolveTypeAnnotation(node, |
| 4571 malformedIsError: inConstContext); | 4603 malformedIsError: inConstContext, |
| 4604 deferredIsMalformed: false); |
| 4572 compiler.backend.registerRequiredType(type, resolver.enclosingElement); | 4605 compiler.backend.registerRequiredType(type, resolver.enclosingElement); |
| 4573 return type.element; | 4606 return type.element; |
| 4574 } | 4607 } |
| 4575 | 4608 |
| 4576 Element visitSend(Send node) { | 4609 Element visitSend(Send node) { |
| 4577 Element element = visit(node.receiver); | 4610 Element element = visit(node.receiver); |
| 4578 assert(invariant(node.receiver, element != null, | 4611 assert(invariant(node.receiver, element != null, |
| 4579 message: 'No element return for $node.receiver.')); | 4612 message: 'No element return for $node.receiver.')); |
| 4580 if (Elements.isUnresolved(element)) return element; | 4613 if (Elements.isUnresolved(element)) return element; |
| 4581 Identifier name = node.selector.asIdentifier(); | 4614 Identifier name = node.selector.asIdentifier(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4633 return finishConstructorReference(visit(expression), | 4666 return finishConstructorReference(visit(expression), |
| 4634 expression, expression); | 4667 expression, expression); |
| 4635 } | 4668 } |
| 4636 } | 4669 } |
| 4637 | 4670 |
| 4638 /// Looks up [name] in [scope] and unwraps the result. | 4671 /// Looks up [name] in [scope] and unwraps the result. |
| 4639 Element lookupInScope(Compiler compiler, Node node, | 4672 Element lookupInScope(Compiler compiler, Node node, |
| 4640 Scope scope, String name) { | 4673 Scope scope, String name) { |
| 4641 return Elements.unwrap(scope.lookup(name), compiler, node); | 4674 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4642 } | 4675 } |
| OLD | NEW |