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