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 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 if (element != null && | |
| 1684 prefix.isDeferred && | |
| 1685 deferredIsMalformed && | |
| 1686 compiler.deferredLoadTask.splitProgram) { | |
|
floitsch
2014/03/03 14:18:06
why the check for compiler.deferredLoadTast.splitP
sigurdm
2014/03/04 12:36:19
Added a comment explaining why.
| |
| 1687 element = new ErroneousElementX(MessageKind.DEFERRED_TYPE_ANNOTATION, | |
| 1688 {'node': typeName}, | |
| 1689 element.name, | |
| 1690 element); | |
| 1691 } | |
| 1692 } else { | |
| 1693 // The caller of this method will create the ErroneousElement for | |
| 1694 // the MalformedType. | |
| 1695 element = null; | |
| 1679 } | 1696 } |
| 1680 // The caller of this method will create the ErroneousElement for | |
| 1681 // the MalformedType. | |
| 1682 return null; | |
| 1683 } else { | 1697 } else { |
| 1684 String stringValue = typeName.source; | 1698 String stringValue = typeName.source; |
| 1685 if (identical(stringValue, 'void')) { | 1699 if (identical(stringValue, 'void')) { |
| 1686 return compiler.types.voidType.element; | 1700 element = compiler.types.voidType.element; |
| 1687 } else if (identical(stringValue, 'dynamic')) { | 1701 } else if (identical(stringValue, 'dynamic')) { |
| 1688 return compiler.dynamicClass; | 1702 element = compiler.dynamicClass; |
| 1689 } else { | 1703 } else { |
| 1690 return lookupInScope(compiler, typeName, scope, typeName.source); | 1704 element = lookupInScope(compiler, typeName, scope, typeName.source); |
| 1691 } | 1705 } |
| 1692 } | 1706 } |
| 1707 return element; | |
|
floitsch
2014/03/03 14:18:06
nit: I preferred the individual returns. But keep
sigurdm
2014/03/04 12:36:19
Done.
| |
| 1693 } | 1708 } |
| 1694 | 1709 |
| 1695 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, | 1710 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, |
| 1696 {bool malformedIsError: false}) { | 1711 {bool malformedIsError: false, |
| 1712 bool deferredIsMalformed: true}) { | |
| 1697 Identifier typeName; | 1713 Identifier typeName; |
| 1698 Identifier prefixName; | 1714 Identifier prefixName; |
| 1699 Send send = node.typeName.asSend(); | 1715 Send send = node.typeName.asSend(); |
| 1700 if (send != null) { | 1716 if (send != null) { |
| 1701 // The type name is of the form [: prefix . identifier :]. | 1717 // The type name is of the form [: prefix . identifier :]. |
| 1702 prefixName = send.receiver.asIdentifier(); | 1718 prefixName = send.receiver.asIdentifier(); |
| 1703 typeName = send.selector.asIdentifier(); | 1719 typeName = send.selector.asIdentifier(); |
| 1704 } else { | 1720 } else { |
| 1705 typeName = node.typeName.asIdentifier(); | 1721 typeName = node.typeName.asIdentifier(); |
| 1706 } | 1722 } |
| 1707 | 1723 |
| 1708 Element element = resolveTypeName(visitor.scope, prefixName, typeName); | 1724 Element element = resolveTypeName(prefixName, typeName, visitor.scope, |
| 1725 deferredIsMalformed: deferredIsMalformed); | |
| 1709 | 1726 |
| 1710 DartType reportFailureAndCreateType(MessageKind messageKind, | 1727 DartType reportFailureAndCreateType(MessageKind messageKind, |
| 1711 Map messageArguments, | 1728 Map messageArguments, |
| 1712 {DartType userProvidedBadType}) { | 1729 {DartType userProvidedBadType, |
| 1730 Element erroneousElement}) { | |
| 1713 if (malformedIsError) { | 1731 if (malformedIsError) { |
| 1714 visitor.error(node, messageKind, messageArguments); | 1732 visitor.error(node, messageKind, messageArguments); |
| 1715 } else { | 1733 } else { |
| 1716 compiler.backend.registerThrowRuntimeError(visitor.mapping); | 1734 compiler.backend.registerThrowRuntimeError(visitor.mapping); |
| 1717 visitor.warning(node, messageKind, messageArguments); | 1735 visitor.warning(node, messageKind, messageArguments); |
| 1718 } | 1736 } |
| 1719 Element erroneousElement = new ErroneousElementX( | 1737 if (erroneousElement == null) { |
| 1720 messageKind, messageArguments, typeName.source, | 1738 erroneousElement = new ErroneousElementX( |
| 1721 visitor.enclosingElement); | 1739 messageKind, messageArguments, typeName.source, |
| 1740 visitor.enclosingElement); | |
| 1741 } | |
| 1722 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); | 1742 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); |
| 1723 resolveTypeArguments(visitor, node, null, arguments); | 1743 resolveTypeArguments(visitor, node, null, arguments); |
| 1724 return new MalformedType(erroneousElement, | 1744 return new MalformedType(erroneousElement, |
| 1725 userProvidedBadType, arguments.toLink()); | 1745 userProvidedBadType, arguments.toLink()); |
| 1726 } | 1746 } |
| 1727 | 1747 |
| 1728 DartType checkNoTypeArguments(DartType type) { | 1748 DartType checkNoTypeArguments(DartType type) { |
| 1729 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); | 1749 LinkBuilder<DartType> arguments = new LinkBuilder<DartType>(); |
| 1730 bool hasTypeArgumentMismatch = resolveTypeArguments( | 1750 bool hasTypeArgumentMismatch = resolveTypeArguments( |
| 1731 visitor, node, const Link<DartType>(), arguments); | 1751 visitor, node, const Link<DartType>(), arguments); |
| 1732 if (hasTypeArgumentMismatch) { | 1752 if (hasTypeArgumentMismatch) { |
| 1733 return new MalformedType( | 1753 return new MalformedType( |
| 1734 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1754 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1735 {'type': node}, typeName.source, visitor.enclosingElement), | 1755 {'type': node}, typeName.source, visitor.enclosingElement), |
| 1736 type, arguments.toLink()); | 1756 type, arguments.toLink()); |
| 1737 } | 1757 } |
| 1738 return type; | 1758 return type; |
| 1739 } | 1759 } |
| 1740 | 1760 |
| 1761 // Now try to construct the type from the element. | |
|
floitsch
2014/03/03 14:18:06
-Now-
sigurdm
2014/03/04 12:36:19
Done.
| |
| 1741 DartType type; | 1762 DartType type; |
| 1742 if (element == null) { | 1763 if (element == null) { |
| 1743 type = reportFailureAndCreateType( | 1764 type = reportFailureAndCreateType( |
| 1744 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 1765 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
| 1745 } else if (element.isAmbiguous()) { | 1766 } else if (element.isAmbiguous()) { |
| 1746 AmbiguousElement ambiguous = element; | 1767 AmbiguousElement ambiguous = element; |
| 1747 type = reportFailureAndCreateType( | 1768 type = reportFailureAndCreateType( |
| 1748 ambiguous.messageKind, ambiguous.messageArguments); | 1769 ambiguous.messageKind, ambiguous.messageArguments); |
| 1749 ambiguous.diagnose(visitor.mapping.currentElement, compiler); | 1770 ambiguous.diagnose(visitor.mapping.currentElement, compiler); |
| 1750 } else if (!element.impliesType()) { | 1771 } else if (!element.impliesType()) { |
| 1751 type = reportFailureAndCreateType( | 1772 type = reportFailureAndCreateType( |
| 1752 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1773 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1774 } else if (element.isErroneous()) { | |
| 1775 ErroneousElement erroneousElement = element; | |
| 1776 type = reportFailureAndCreateType( | |
| 1777 erroneousElement.messageKind, erroneousElement.messageArguments, | |
| 1778 erroneousElement: erroneousElement); | |
| 1753 } else { | 1779 } else { |
| 1754 bool addTypeVariableBoundsCheck = false; | 1780 bool addTypeVariableBoundsCheck = false; |
| 1755 if (identical(element, compiler.types.voidType.element) || | 1781 if (identical(element, compiler.types.voidType.element) || |
| 1756 identical(element, compiler.dynamicClass)) { | 1782 identical(element, compiler.dynamicClass)) { |
| 1757 type = checkNoTypeArguments(element.computeType(compiler)); | 1783 type = checkNoTypeArguments(element.computeType(compiler)); |
| 1758 } else if (element.isClass()) { | 1784 } else if (element.isClass()) { |
| 1759 ClassElement cls = element; | 1785 ClassElement cls = element; |
| 1760 compiler.resolver._ensureClassWillBeResolved(cls); | 1786 compiler.resolver._ensureClassWillBeResolved(cls); |
| 1761 element.computeType(compiler); | 1787 element.computeType(compiler); |
| 1762 var arguments = new LinkBuilder<DartType>(); | 1788 var arguments = new LinkBuilder<DartType>(); |
| (...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3153 return node.accept(new ConstructorResolver(compiler, this)); | 3179 return node.accept(new ConstructorResolver(compiler, this)); |
| 3154 } | 3180 } |
| 3155 | 3181 |
| 3156 FunctionElement resolveRedirectingFactory(Return node, | 3182 FunctionElement resolveRedirectingFactory(Return node, |
| 3157 {bool inConstContext: false}) { | 3183 {bool inConstContext: false}) { |
| 3158 return node.accept(new ConstructorResolver(compiler, this, | 3184 return node.accept(new ConstructorResolver(compiler, this, |
| 3159 inConstContext: inConstContext)); | 3185 inConstContext: inConstContext)); |
| 3160 } | 3186 } |
| 3161 | 3187 |
| 3162 DartType resolveTypeAnnotation(TypeAnnotation node, | 3188 DartType resolveTypeAnnotation(TypeAnnotation node, |
| 3163 {bool malformedIsError: false}) { | 3189 {bool malformedIsError: false, |
| 3190 bool deferredIsMalformed: true}) { | |
| 3164 DartType type = typeResolver.resolveTypeAnnotation( | 3191 DartType type = typeResolver.resolveTypeAnnotation( |
| 3165 this, node, malformedIsError: malformedIsError); | 3192 this, node, malformedIsError: malformedIsError, |
| 3193 deferredIsMalformed: deferredIsMalformed); | |
| 3166 if (type == null) return null; | 3194 if (type == null) return null; |
| 3167 if (inCheckContext) { | 3195 if (inCheckContext) { |
| 3168 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 3196 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 3169 compiler.backend.registerRequiredType(type, enclosingElement); | 3197 compiler.backend.registerRequiredType(type, enclosingElement); |
| 3170 } | 3198 } |
| 3171 return type; | 3199 return type; |
| 3172 } | 3200 } |
| 3173 | 3201 |
| 3174 visitModifiers(Modifiers node) { | 3202 visitModifiers(Modifiers node) { |
| 3175 internalError(node, 'modifiers'); | 3203 internalError(node, 'modifiers'); |
| (...skipping 1274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4450 } else { | 4478 } else { |
| 4451 type = element.getEnclosingClass().computeType(compiler).asRaw(); | 4479 type = element.getEnclosingClass().computeType(compiler).asRaw(); |
| 4452 } | 4480 } |
| 4453 } | 4481 } |
| 4454 resolver.mapping.setType(expression, type); | 4482 resolver.mapping.setType(expression, type); |
| 4455 return element; | 4483 return element; |
| 4456 } | 4484 } |
| 4457 | 4485 |
| 4458 Element visitTypeAnnotation(TypeAnnotation node) { | 4486 Element visitTypeAnnotation(TypeAnnotation node) { |
| 4459 assert(invariant(node, type == null)); | 4487 assert(invariant(node, type == null)); |
| 4488 // This is not really resolving a type-annotation, but the name of the | |
| 4489 // constructor. Therefore we allow deferred types. | |
| 4460 type = resolver.resolveTypeAnnotation(node, | 4490 type = resolver.resolveTypeAnnotation(node, |
| 4461 malformedIsError: inConstContext); | 4491 malformedIsError: inConstContext, |
| 4492 deferredIsMalformed: false); | |
| 4462 compiler.backend.registerRequiredType(type, resolver.enclosingElement); | 4493 compiler.backend.registerRequiredType(type, resolver.enclosingElement); |
| 4463 return type.element; | 4494 return type.element; |
| 4464 } | 4495 } |
| 4465 | 4496 |
| 4466 Element visitSend(Send node) { | 4497 Element visitSend(Send node) { |
| 4467 Element element = visit(node.receiver); | 4498 Element element = visit(node.receiver); |
| 4468 assert(invariant(node.receiver, element != null, | 4499 assert(invariant(node.receiver, element != null, |
| 4469 message: 'No element return for $node.receiver.')); | 4500 message: 'No element return for $node.receiver.')); |
| 4470 if (Elements.isUnresolved(element)) return element; | 4501 if (Elements.isUnresolved(element)) return element; |
| 4471 Identifier name = node.selector.asIdentifier(); | 4502 Identifier name = node.selector.asIdentifier(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4523 return finishConstructorReference(visit(expression), | 4554 return finishConstructorReference(visit(expression), |
| 4524 expression, expression); | 4555 expression, expression); |
| 4525 } | 4556 } |
| 4526 } | 4557 } |
| 4527 | 4558 |
| 4528 /// Looks up [name] in [scope] and unwraps the result. | 4559 /// Looks up [name] in [scope] and unwraps the result. |
| 4529 Element lookupInScope(Compiler compiler, Node node, | 4560 Element lookupInScope(Compiler compiler, Node node, |
| 4530 Scope scope, String name) { | 4561 Scope scope, String name) { |
| 4531 return Elements.unwrap(scope.lookup(name), compiler, node); | 4562 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4532 } | 4563 } |
| OLD | NEW |