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 /// |
| 1671 Identifier typeName) { | 1671 /// Returns that element paired with true if the [prefixName] was referring |
| 1672 /// to a deferred library prefix. | |
| 1673 Pair<Element, bool> resolveTypeName(Identifier prefixName, | |
|
floitsch
2014/02/28 12:58:15
I really don't like that we return a pair now.
ma
sigurdm
2014/03/03 13:18:49
With Johnni's help I found a better way.
| |
| 1674 Identifier typeName, | |
| 1675 Scope scope) { | |
| 1676 Element element; | |
| 1677 bool deferredTypeAnnotation = false; | |
| 1672 if (prefixName != null) { | 1678 if (prefixName != null) { |
| 1673 Element element = | 1679 Element prefixElement = |
| 1674 lookupInScope(compiler, prefixName, scope, prefixName.source); | 1680 lookupInScope(compiler, prefixName, scope, prefixName.source); |
| 1675 if (element != null && element.isPrefix()) { | 1681 if (prefixElement != null && prefixElement.isPrefix()) { |
| 1676 // The receiver is a prefix. Lookup in the imported members. | 1682 // The receiver is a prefix. Lookup in the imported members. |
| 1677 PrefixElement prefix = element; | 1683 PrefixElement prefix = prefixElement; |
| 1678 return prefix.lookupLocalMember(typeName.source); | 1684 element = prefix.lookupLocalMember(typeName.source); |
| 1685 if (element != null && prefix.isDeferred) { | |
| 1686 deferredTypeAnnotation = true; | |
| 1687 } | |
| 1688 } else { | |
| 1689 // The caller of this method will create the ErroneousElement for | |
| 1690 // the MalformedType. | |
| 1691 element = null; | |
| 1679 } | 1692 } |
| 1680 // The caller of this method will create the ErroneousElement for | |
| 1681 // the MalformedType. | |
| 1682 return null; | |
| 1683 } else { | 1693 } else { |
| 1684 String stringValue = typeName.source; | 1694 String stringValue = typeName.source; |
| 1685 if (identical(stringValue, 'void')) { | 1695 if (identical(stringValue, 'void')) { |
| 1686 return compiler.types.voidType.element; | 1696 element = compiler.types.voidType.element; |
| 1687 } else if (identical(stringValue, 'dynamic')) { | 1697 } else if (identical(stringValue, 'dynamic')) { |
| 1688 return compiler.dynamicClass; | 1698 element = compiler.dynamicClass; |
| 1689 } else { | 1699 } else { |
| 1690 return lookupInScope(compiler, typeName, scope, typeName.source); | 1700 element = lookupInScope(compiler, typeName, scope, typeName.source); |
| 1691 } | 1701 } |
| 1692 } | 1702 } |
| 1703 return new Pair<Element, bool>(element, deferredTypeAnnotation); | |
| 1693 } | 1704 } |
| 1694 | 1705 |
| 1695 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, | 1706 DartType resolveTypeAnnotation(MappingVisitor visitor, TypeAnnotation node, |
| 1696 {bool malformedIsError: false}) { | 1707 {bool malformedIsError: false, |
| 1708 bool deferredIsMalformed: true}) { | |
| 1697 Identifier typeName; | 1709 Identifier typeName; |
| 1698 Identifier prefixName; | 1710 Identifier prefixName; |
| 1699 Send send = node.typeName.asSend(); | 1711 Send send = node.typeName.asSend(); |
| 1700 if (send != null) { | 1712 if (send != null) { |
| 1701 // The type name is of the form [: prefix . identifier :]. | 1713 // The type name is of the form [: prefix . identifier :]. |
| 1702 prefixName = send.receiver.asIdentifier(); | 1714 prefixName = send.receiver.asIdentifier(); |
| 1703 typeName = send.selector.asIdentifier(); | 1715 typeName = send.selector.asIdentifier(); |
| 1704 } else { | 1716 } else { |
| 1705 typeName = node.typeName.asIdentifier(); | 1717 typeName = node.typeName.asIdentifier(); |
| 1706 } | 1718 } |
| 1707 | 1719 |
| 1708 Element element = resolveTypeName(visitor.scope, prefixName, typeName); | 1720 Pair<Element, bool> p = resolveTypeName(prefixName, |
| 1721 typeName, | |
| 1722 visitor.scope); | |
| 1723 Element element = p.first; | |
| 1724 bool deferredTypeAnnotation = p.second; | |
| 1709 | 1725 |
| 1710 DartType reportFailureAndCreateType(MessageKind messageKind, | 1726 DartType reportFailureAndCreateType(MessageKind messageKind, |
| 1711 Map messageArguments, | 1727 Map messageArguments, |
| 1712 {DartType userProvidedBadType}) { | 1728 {DartType userProvidedBadType}) { |
| 1713 if (malformedIsError) { | 1729 if (malformedIsError) { |
| 1714 visitor.error(node, messageKind, messageArguments); | 1730 visitor.error(node, messageKind, messageArguments); |
| 1715 } else { | 1731 } else { |
| 1716 compiler.backend.registerThrowRuntimeError(visitor.mapping); | 1732 compiler.backend.registerThrowRuntimeError(visitor.mapping); |
| 1717 visitor.warning(node, messageKind, messageArguments); | 1733 visitor.warning(node, messageKind, messageArguments); |
| 1718 } | 1734 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1731 visitor, node, const Link<DartType>(), arguments); | 1747 visitor, node, const Link<DartType>(), arguments); |
| 1732 if (hasTypeArgumentMismatch) { | 1748 if (hasTypeArgumentMismatch) { |
| 1733 return new MalformedType( | 1749 return new MalformedType( |
| 1734 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, | 1750 new ErroneousElementX(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH, |
| 1735 {'type': node}, typeName.source, visitor.enclosingElement), | 1751 {'type': node}, typeName.source, visitor.enclosingElement), |
| 1736 type, arguments.toLink()); | 1752 type, arguments.toLink()); |
| 1737 } | 1753 } |
| 1738 return type; | 1754 return type; |
| 1739 } | 1755 } |
| 1740 | 1756 |
| 1757 // Now try to construct the type from the element. | |
| 1741 DartType type; | 1758 DartType type; |
| 1742 if (element == null) { | 1759 if (element == null) { |
| 1743 type = reportFailureAndCreateType( | 1760 type = reportFailureAndCreateType( |
| 1744 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); | 1761 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.typeName}); |
| 1745 } else if (element.isAmbiguous()) { | 1762 } else if (element.isAmbiguous()) { |
| 1746 AmbiguousElement ambiguous = element; | 1763 AmbiguousElement ambiguous = element; |
| 1747 type = reportFailureAndCreateType( | 1764 type = reportFailureAndCreateType( |
| 1748 ambiguous.messageKind, ambiguous.messageArguments); | 1765 ambiguous.messageKind, ambiguous.messageArguments); |
| 1749 ambiguous.diagnose(visitor.mapping.currentElement, compiler); | 1766 ambiguous.diagnose(visitor.mapping.currentElement, compiler); |
| 1750 } else if (!element.impliesType()) { | 1767 } else if (!element.impliesType()) { |
| 1751 type = reportFailureAndCreateType( | 1768 type = reportFailureAndCreateType( |
| 1752 MessageKind.NOT_A_TYPE, {'node': node.typeName}); | 1769 MessageKind.NOT_A_TYPE, {'node': node.typeName}); |
| 1770 } else if (deferredTypeAnnotation && | |
| 1771 deferredIsMalformed && | |
| 1772 compiler.deferredLoadTask.splitProgram) { | |
| 1773 type = reportFailureAndCreateType( | |
| 1774 MessageKind.DEFERRED_TYPE_ANNOTATION, {'node': node.typeName}); | |
| 1753 } else { | 1775 } else { |
| 1754 bool addTypeVariableBoundsCheck = false; | 1776 bool addTypeVariableBoundsCheck = false; |
| 1755 if (identical(element, compiler.types.voidType.element) || | 1777 if (identical(element, compiler.types.voidType.element) || |
| 1756 identical(element, compiler.dynamicClass)) { | 1778 identical(element, compiler.dynamicClass)) { |
| 1757 type = checkNoTypeArguments(element.computeType(compiler)); | 1779 type = checkNoTypeArguments(element.computeType(compiler)); |
| 1758 } else if (element.isClass()) { | 1780 } else if (element.isClass()) { |
| 1759 ClassElement cls = element; | 1781 ClassElement cls = element; |
| 1760 compiler.resolver._ensureClassWillBeResolved(cls); | 1782 compiler.resolver._ensureClassWillBeResolved(cls); |
| 1761 element.computeType(compiler); | 1783 element.computeType(compiler); |
| 1762 var arguments = new LinkBuilder<DartType>(); | 1784 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)); | 3175 return node.accept(new ConstructorResolver(compiler, this)); |
| 3154 } | 3176 } |
| 3155 | 3177 |
| 3156 FunctionElement resolveRedirectingFactory(Return node, | 3178 FunctionElement resolveRedirectingFactory(Return node, |
| 3157 {bool inConstContext: false}) { | 3179 {bool inConstContext: false}) { |
| 3158 return node.accept(new ConstructorResolver(compiler, this, | 3180 return node.accept(new ConstructorResolver(compiler, this, |
| 3159 inConstContext: inConstContext)); | 3181 inConstContext: inConstContext)); |
| 3160 } | 3182 } |
| 3161 | 3183 |
| 3162 DartType resolveTypeAnnotation(TypeAnnotation node, | 3184 DartType resolveTypeAnnotation(TypeAnnotation node, |
| 3163 {bool malformedIsError: false}) { | 3185 {bool malformedIsError: false, |
| 3186 bool deferredIsMalformed: true}) { | |
| 3164 DartType type = typeResolver.resolveTypeAnnotation( | 3187 DartType type = typeResolver.resolveTypeAnnotation( |
| 3165 this, node, malformedIsError: malformedIsError); | 3188 this, node, malformedIsError: malformedIsError, |
| 3189 deferredIsMalformed: deferredIsMalformed); | |
| 3166 if (type == null) return null; | 3190 if (type == null) return null; |
| 3167 if (inCheckContext) { | 3191 if (inCheckContext) { |
| 3168 compiler.enqueuer.resolution.registerIsCheck(type, mapping); | 3192 compiler.enqueuer.resolution.registerIsCheck(type, mapping); |
| 3169 compiler.backend.registerRequiredType(type, enclosingElement); | 3193 compiler.backend.registerRequiredType(type, enclosingElement); |
| 3170 } | 3194 } |
| 3171 return type; | 3195 return type; |
| 3172 } | 3196 } |
| 3173 | 3197 |
| 3174 visitModifiers(Modifiers node) { | 3198 visitModifiers(Modifiers node) { |
| 3175 internalError(node, 'modifiers'); | 3199 internalError(node, 'modifiers'); |
| (...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4451 type = element.getEnclosingClass().computeType(compiler).asRaw(); | 4475 type = element.getEnclosingClass().computeType(compiler).asRaw(); |
| 4452 } | 4476 } |
| 4453 } | 4477 } |
| 4454 resolver.mapping.setType(expression, type); | 4478 resolver.mapping.setType(expression, type); |
| 4455 return element; | 4479 return element; |
| 4456 } | 4480 } |
| 4457 | 4481 |
| 4458 Element visitTypeAnnotation(TypeAnnotation node) { | 4482 Element visitTypeAnnotation(TypeAnnotation node) { |
| 4459 assert(invariant(node, type == null)); | 4483 assert(invariant(node, type == null)); |
| 4460 type = resolver.resolveTypeAnnotation(node, | 4484 type = resolver.resolveTypeAnnotation(node, |
| 4461 malformedIsError: inConstContext); | 4485 malformedIsError: inConstContext, |
| 4486 deferredIsMalformed: false); | |
|
floitsch
2014/02/28 12:58:15
Why is it not an error here?
sigurdm
2014/03/03 13:18:49
I added an explanatory comment.
The problem is th
| |
| 4462 compiler.backend.registerRequiredType(type, resolver.enclosingElement); | 4487 compiler.backend.registerRequiredType(type, resolver.enclosingElement); |
| 4463 return type.element; | 4488 return type.element; |
| 4464 } | 4489 } |
| 4465 | 4490 |
| 4466 Element visitSend(Send node) { | 4491 Element visitSend(Send node) { |
| 4467 Element element = visit(node.receiver); | 4492 Element element = visit(node.receiver); |
| 4468 assert(invariant(node.receiver, element != null, | 4493 assert(invariant(node.receiver, element != null, |
| 4469 message: 'No element return for $node.receiver.')); | 4494 message: 'No element return for $node.receiver.')); |
| 4470 if (Elements.isUnresolved(element)) return element; | 4495 if (Elements.isUnresolved(element)) return element; |
| 4471 Identifier name = node.selector.asIdentifier(); | 4496 Identifier name = node.selector.asIdentifier(); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4523 return finishConstructorReference(visit(expression), | 4548 return finishConstructorReference(visit(expression), |
| 4524 expression, expression); | 4549 expression, expression); |
| 4525 } | 4550 } |
| 4526 } | 4551 } |
| 4527 | 4552 |
| 4528 /// Looks up [name] in [scope] and unwraps the result. | 4553 /// Looks up [name] in [scope] and unwraps the result. |
| 4529 Element lookupInScope(Compiler compiler, Node node, | 4554 Element lookupInScope(Compiler compiler, Node node, |
| 4530 Scope scope, String name) { | 4555 Scope scope, String name) { |
| 4531 return Elements.unwrap(scope.lookup(name), compiler, node); | 4556 return Elements.unwrap(scope.lookup(name), compiler, node); |
| 4532 } | 4557 } |
| OLD | NEW |