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 interface TreeElements { | 5 interface TreeElements { |
6 Element operator[](Node node); | 6 Element operator[](Node node); |
7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
8 Type getType(TypeAnnotation annotation); | 8 Type getType(TypeAnnotation annotation); |
9 } | 9 } |
10 | 10 |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
562 return null; // If there was no redirection always return null. | 562 return null; // If there was no redirection always return null. |
563 } | 563 } |
564 } | 564 } |
565 | 565 |
566 class CommonResolverVisitor<R> extends AbstractVisitor<R> { | 566 class CommonResolverVisitor<R> extends AbstractVisitor<R> { |
567 final Compiler compiler; | 567 final Compiler compiler; |
568 | 568 |
569 CommonResolverVisitor(Compiler this.compiler); | 569 CommonResolverVisitor(Compiler this.compiler); |
570 | 570 |
571 R visitNode(Node node) { | 571 R visitNode(Node node) { |
572 cancel(node, 'internal error'); | 572 cancel(node, |
| 573 'internal error: Unhandled node: ${node.getObjectDescription()}'); |
573 } | 574 } |
574 | 575 |
575 R visitEmptyStatement(Node node) => null; | 576 R visitEmptyStatement(Node node) => null; |
576 | 577 |
577 /** Convenience method for visiting nodes that may be null. */ | 578 /** Convenience method for visiting nodes that may be null. */ |
578 R visit(Node node) => (node == null) ? null : node.accept(this); | 579 R visit(Node node) => (node == null) ? null : node.accept(this); |
579 | 580 |
580 void error(Node node, MessageKind kind, [arguments = const []]) { | 581 void error(Node node, MessageKind kind, [arguments = const []]) { |
581 ResolutionError message = new ResolutionError(kind, arguments); | 582 ResolutionError message = new ResolutionError(kind, arguments); |
582 compiler.reportError(node, message); | 583 compiler.reportError(node, message); |
(...skipping 1064 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 ClassElement classElement; | 1648 ClassElement classElement; |
1648 | 1649 |
1649 ClassResolverVisitor(Compiler compiler, LibraryElement library, | 1650 ClassResolverVisitor(Compiler compiler, LibraryElement library, |
1650 ClassElement this.classElement) | 1651 ClassElement this.classElement) |
1651 : context = new TopScope(library), | 1652 : context = new TopScope(library), |
1652 super(compiler); | 1653 super(compiler); |
1653 | 1654 |
1654 Type visitClassNode(ClassNode node) { | 1655 Type visitClassNode(ClassNode node) { |
1655 compiler.ensure(classElement !== null); | 1656 compiler.ensure(classElement !== null); |
1656 compiler.ensure(!classElement.isResolved); | 1657 compiler.ensure(!classElement.isResolved); |
1657 final Link<Node> parameters = | 1658 |
| 1659 classElement.ensureParametersAndType(compiler); |
| 1660 context = new TypeVariablesScope(context, classElement); |
| 1661 |
| 1662 // Resolve the bounds of type variables. |
| 1663 Link<Node> parameters = |
1658 node.typeParameters !== null ? node.typeParameters.nodes | 1664 node.typeParameters !== null ? node.typeParameters.nodes |
1659 : const EmptyLink<TypeVariable>(); | 1665 : const EmptyLink<TypeVariable>(); |
1660 // Create types and elements for type variable. | |
1661 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { | 1666 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { |
1662 TypeVariable typeNode = link.head; | 1667 TypeVariable typeNode = link.head; |
1663 SourceString variableName = typeNode.name.source; | 1668 SourceString variableName = typeNode.name.source; |
1664 TypeVariableType variableType = new TypeVariableType(variableName); | |
1665 TypeVariableElement variableElement = | |
1666 new TypeVariableElement(variableName, classElement, node, | |
1667 variableType); | |
1668 variableType.element = variableElement; | |
1669 classElement.typeParameters[variableName] = variableElement; | |
1670 context = new TypeVariablesScope(context, classElement); | |
1671 } | |
1672 // Resolve the bounds of type variables. | |
1673 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { | |
1674 TypeVariable typeNode = link.head; | |
1675 SourceString variableName = typeNode.name.source; | |
1676 TypeVariableElement variableElement = | 1669 TypeVariableElement variableElement = |
1677 classElement.typeParameters[variableName]; | 1670 classElement.typeParameters[variableName]; |
1678 if (typeNode.bound !== null) { | 1671 if (typeNode.bound !== null) { |
1679 Type boundType = visit(typeNode.bound); | 1672 Type boundType = visit(typeNode.bound); |
1680 if (boundType !== null && boundType.element == variableElement) { | 1673 if (boundType !== null && boundType.element == variableElement) { |
1681 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | 1674 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, |
1682 [variableElement.name]); | 1675 [variableElement.name]); |
1683 } else if (boundType !== null) { | 1676 } else if (boundType !== null) { |
1684 variableElement.bound = boundType; | 1677 variableElement.bound = boundType; |
1685 } else { | 1678 } else { |
1686 variableElement.bound = compiler.objectClass.computeType(compiler); | 1679 variableElement.bound = compiler.objectClass.computeType(compiler); |
1687 } | 1680 } |
1688 } | 1681 } |
1689 } | 1682 } |
| 1683 |
1690 // Find super type. | 1684 // Find super type. |
1691 Type supertype = visit(node.superclass); | 1685 Type supertype = visit(node.superclass); |
1692 if (supertype !== null && supertype.element.isExtendable()) { | 1686 if (supertype !== null && supertype.element.isExtendable()) { |
1693 classElement.supertype = supertype; | 1687 classElement.supertype = supertype; |
1694 if (isBlackListed(supertype)) { | 1688 if (isBlackListed(supertype)) { |
1695 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); | 1689 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); |
1696 } | 1690 } |
1697 } else if (supertype !== null) { | 1691 } else if (supertype !== null) { |
1698 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); | 1692 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); |
1699 } | 1693 } |
(...skipping 23 matching lines...) Expand all Loading... |
1723 } else { | 1717 } else { |
1724 error(link.head, MessageKind.TYPE_NAME_EXPECTED); | 1718 error(link.head, MessageKind.TYPE_NAME_EXPECTED); |
1725 } | 1719 } |
1726 } | 1720 } |
1727 calculateAllSupertypes(classElement, new Set<ClassElement>()); | 1721 calculateAllSupertypes(classElement, new Set<ClassElement>()); |
1728 addDefaultConstructorIfNeeded(classElement); | 1722 addDefaultConstructorIfNeeded(classElement); |
1729 return classElement.computeType(compiler); | 1723 return classElement.computeType(compiler); |
1730 } | 1724 } |
1731 | 1725 |
1732 Type visitTypeAnnotation(TypeAnnotation node) { | 1726 Type visitTypeAnnotation(TypeAnnotation node) { |
1733 return visit(node.typeName); | 1727 Type type = visit(node.typeName); |
| 1728 if (type is! InterfaceType) { |
| 1729 // TODO(johnniwinther): Handle function types. |
| 1730 return type; |
| 1731 } |
| 1732 if (node.typeArguments === null) { |
| 1733 if (type.arguments.isEmpty()) { |
| 1734 return type; |
| 1735 } |
| 1736 // Return the 'raw' version, for example List for List<E>. |
| 1737 return new InterfaceType(type.element); |
| 1738 } |
| 1739 var typeArguments = new LinkBuilder<Type>(); |
| 1740 var link = node.typeArguments.nodes; |
| 1741 while (!link.isEmpty()) { |
| 1742 typeArguments.addLast(visit(link.head)); |
| 1743 link = link.tail; |
| 1744 } |
| 1745 // TODO(johnniwinther): Check argument count and bounds. |
| 1746 return new InterfaceType(type.element, typeArguments.toLink()); |
| 1747 } |
| 1748 |
| 1749 Type visitTypeVariable(TypeVariable node) { |
| 1750 return visit(node.name); |
1734 } | 1751 } |
1735 | 1752 |
1736 Type visitIdentifier(Identifier node) { | 1753 Type visitIdentifier(Identifier node) { |
1737 Element element = context.lookup(node.source); | 1754 Element element = context.lookup(node.source); |
1738 if (element === null) { | 1755 if (element === null) { |
1739 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | 1756 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
1740 return null; | 1757 return null; |
1741 } else if (!element.impliesType() && !element.isTypeVariable()) { | 1758 } else if (!element.impliesType() && !element.isTypeVariable()) { |
1742 error(node, MessageKind.NOT_A_TYPE, [node]); | 1759 error(node, MessageKind.NOT_A_TYPE, [node]); |
1743 return null; | 1760 return null; |
1744 } else { | 1761 } else { |
1745 if (element.isClass()) { | 1762 if (element.isClass()) { |
1746 compiler.resolver.toResolve.add(element); | 1763 compiler.resolver.toResolve.add(element); |
1747 } | 1764 } |
1748 if (element.isTypeVariable()) { | 1765 if (element.isTypeVariable()) { |
1749 TypeVariableElement variableElement = element; | 1766 TypeVariableElement variableElement = element; |
1750 return variableElement.type; | 1767 return variableElement.type; |
1751 } else if (element.isTypedef()) { | 1768 } else if (element.isTypedef()) { |
1752 compiler.unimplemented('visitIdentifier for typedefs', node: node); | 1769 compiler.unimplemented('visitIdentifier for typedefs', node: node); |
1753 } else { | 1770 } else { |
1754 // TODO(ngeoffray): Use type variables. | 1771 // Type variables are handled in [visitTypeAnnotation]. |
1755 return element.computeType(compiler); | 1772 return element.computeType(compiler); |
1756 } | 1773 } |
1757 } | 1774 } |
1758 return null; | 1775 return null; |
1759 } | 1776 } |
1760 | 1777 |
1761 Type visitSend(Send node) { | 1778 Type visitSend(Send node) { |
1762 Identifier prefix = node.receiver.asIdentifier(); | 1779 Identifier prefix = node.receiver.asIdentifier(); |
1763 if (prefix === null) { | 1780 if (prefix === null) { |
1764 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | 1781 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
(...skipping 27 matching lines...) Expand all Loading... |
1792 [cls.name]); | 1809 [cls.name]); |
1793 cls.allSupertypes = const EmptyLink<Type>(); | 1810 cls.allSupertypes = const EmptyLink<Type>(); |
1794 } else { | 1811 } else { |
1795 cls.ensureResolved(compiler); | 1812 cls.ensureResolved(compiler); |
1796 calculateAllSupertypes(cls, seen); | 1813 calculateAllSupertypes(cls, seen); |
1797 } | 1814 } |
1798 return cls.allSupertypes; | 1815 return cls.allSupertypes; |
1799 } | 1816 } |
1800 | 1817 |
1801 void calculateAllSupertypes(ClassElement cls, Set<ClassElement> seen) { | 1818 void calculateAllSupertypes(ClassElement cls, Set<ClassElement> seen) { |
1802 // TODO(karlklose): substitute type variables. | |
1803 // TODO(karlklose): check if type arguments match, if a classelement occurs | 1819 // TODO(karlklose): check if type arguments match, if a classelement occurs |
1804 // more than once in the supertypes. | 1820 // more than once in the supertypes. |
1805 if (cls.allSupertypes !== null) return; | 1821 if (cls.allSupertypes !== null) return; |
1806 final Type supertype = cls.supertype; | 1822 final InterfaceType supertype = cls.supertype; |
1807 if (seen.contains(cls)) { | 1823 if (seen.contains(cls)) { |
1808 error(cls.parseNode(compiler), | 1824 error(cls.parseNode(compiler), |
1809 MessageKind.CYCLIC_CLASS_HIERARCHY, | 1825 MessageKind.CYCLIC_CLASS_HIERARCHY, |
1810 [cls.name]); | 1826 [cls.name]); |
1811 cls.allSupertypes = const EmptyLink<Type>(); | 1827 cls.allSupertypes = const EmptyLink<Type>(); |
1812 } else if (supertype != null) { | 1828 } else if (supertype != null) { |
1813 seen.add(cls); | 1829 seen.add(cls); |
| 1830 ClassElement supertypeElement = supertype.element; |
1814 Link<Type> superSupertypes = | 1831 Link<Type> superSupertypes = |
1815 getOrCalculateAllSupertypes(supertype.element, seen); | 1832 getOrCalculateAllSupertypes(supertypeElement, seen); |
1816 Link<Type> supertypes = new Link<Type>(supertype, superSupertypes); | 1833 var superTypesBuilder = new LinkBuilder<Type>(); |
| 1834 superTypesBuilder.addLast(supertype); |
| 1835 |
| 1836 // Substitute type variables in supertypes. |
| 1837 var superTypeParameters = <Type>[]; |
| 1838 var typeVariableElements = supertypeElement.typeParameters.getValues(); |
| 1839 for (TypeVariableElement typeVariableElement in typeVariableElements) { |
| 1840 superTypeParameters.add(typeVariableElement.type); |
| 1841 } |
| 1842 for (Type superSupertype in superSupertypes) { |
| 1843 superTypesBuilder.addLast(superSupertype.subst( |
| 1844 supertype.arguments, superTypeParameters)); |
| 1845 } |
| 1846 |
| 1847 Link<Type> supertypes = superTypesBuilder.toLink(); |
1817 for (Link<Type> interfaces = cls.interfaces; | 1848 for (Link<Type> interfaces = cls.interfaces; |
1818 !interfaces.isEmpty(); | 1849 !interfaces.isEmpty(); |
1819 interfaces = interfaces.tail) { | 1850 interfaces = interfaces.tail) { |
1820 Element element = interfaces.head.element; | 1851 Element element = interfaces.head.element; |
1821 Link<Type> interfaceSupertypes = | 1852 Link<Type> interfaceSupertypes = |
1822 getOrCalculateAllSupertypes(element, seen); | 1853 getOrCalculateAllSupertypes(element, seen); |
1823 supertypes = supertypes.reversePrependAll(interfaceSupertypes); | 1854 supertypes = supertypes.reversePrependAll(interfaceSupertypes); |
1824 supertypes = supertypes.prepend(interfaces.head); | 1855 supertypes = supertypes.prepend(interfaces.head); |
1825 } | 1856 } |
1826 seen.remove(cls); | 1857 seen.remove(cls); |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2212 | 2243 |
2213 TopScope(LibraryElement library) : super(null, library); | 2244 TopScope(LibraryElement library) : super(null, library); |
2214 Element lookup(SourceString name) { | 2245 Element lookup(SourceString name) { |
2215 return library.find(name); | 2246 return library.find(name); |
2216 } | 2247 } |
2217 | 2248 |
2218 Element add(Element newElement) { | 2249 Element add(Element newElement) { |
2219 throw "Cannot add an element in the top scope"; | 2250 throw "Cannot add an element in the top scope"; |
2220 } | 2251 } |
2221 } | 2252 } |
OLD | NEW |