Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(647)

Side by Side Diff: lib/compiler/implementation/resolver.dart

Issue 10825177: Unify ClassElement and TypedefElement. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 } else { 726 } else {
727 return null; 727 return null;
728 } 728 }
729 } else { 729 } else {
730 return scope.lookup(typeName.source); 730 return scope.lookup(typeName.source);
731 } 731 }
732 } 732 }
733 733
734 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean 734 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean
735 // flags instead of closures. 735 // flags instead of closures.
736 // TODO(johnniwinther): Should never return [null] but instead an erroneous
737 // type.
736 Type resolveTypeAnnotation(TypeAnnotation node, 738 Type resolveTypeAnnotation(TypeAnnotation node,
737 [Scope inScope, ClassElement inClass, 739 [Scope inScope, ClassElement inClass,
738 onFailure(Node, MessageKind, [List arguments]), 740 onFailure(Node, MessageKind, [List arguments]),
739 whenResolved(Node, Type)]) { 741 whenResolved(Node, Type)]) {
740 if (onFailure === null) { 742 if (onFailure === null) {
741 onFailure = (n, k, [arguments]) {}; 743 onFailure = (n, k, [arguments]) {};
742 } 744 }
743 if (whenResolved === null) { 745 if (whenResolved === null) {
744 whenResolved = (n, t) {}; 746 whenResolved = (n, t) {};
745 } 747 }
(...skipping 15 matching lines...) Expand all
761 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); 763 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]);
762 } else if (!element.impliesType()) { 764 } else if (!element.impliesType()) {
763 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); 765 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]);
764 } else { 766 } else {
765 if (element === compiler.types.voidType.element || 767 if (element === compiler.types.voidType.element ||
766 element === compiler.types.dynamicType.element) { 768 element === compiler.types.dynamicType.element) {
767 type = element.computeType(compiler); 769 type = element.computeType(compiler);
768 } else if (element.isClass()) { 770 } else if (element.isClass()) {
769 ClassElement cls = element; 771 ClassElement cls = element;
770 if (!cls.isResolved) compiler.resolveClass(cls); 772 if (!cls.isResolved) compiler.resolveClass(cls);
771 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); 773 Link<Type> arguments =
772 if (node.typeArguments !== null) { 774 resolveTypeArguments(node, cls.typeVariables, scope,
773 int index = 0; 775 onFailure, whenResolved);
774 for (Link<Node> typeArguments = node.typeArguments.nodes; 776 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) {
775 !typeArguments.isEmpty(); 777 // Use the canonical type if it has no type parameters.
776 typeArguments = typeArguments.tail) {
777 if (++index > cls.typeParameters.length) {
778 onFailure(typeArguments.head,
779 MessageKind.ADDITIONAL_TYPE_ARGUMENT);
780 }
781 Type argType = resolveTypeAnnotationInContext(scope,
782 typeArguments.head,
783 onFailure,
784 whenResolved);
785 arguments.addLast(argType);
786 }
787 if (index < cls.typeParameters.length) {
788 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
789 }
790 }
791 if (cls.typeParameters.length == 0) {
792 // Return the canonical type if it has no type parameters.
793 type = cls.computeType(compiler); 778 type = cls.computeType(compiler);
794 } else { 779 } else {
795 type = new InterfaceType(cls, arguments.toLink()); 780 type = new InterfaceType(cls, arguments);
796 } 781 }
797 } else if (element.isTypedef()) { 782 } else if (element.isTypedef()) {
798 type = element.computeType(compiler); 783 type = element.computeType(compiler);
799 } else if (element.isTypeVariable()) { 784 } else if (element.isTypeVariable()) {
800 type = element.computeType(compiler); 785 type = element.computeType(compiler);
801 } else { 786 } else {
802 compiler.cancel("unexpected element kind ${element.kind}", 787 compiler.cancel("unexpected element kind ${element.kind}",
803 node: node); 788 node: node);
804 } 789 }
805 } 790 }
806 whenResolved(node, type); 791 whenResolved(node, type);
807 return type; 792 return type;
808 } 793 }
794
795 Link<Type> resolveTypeArguments(TypeAnnotation node,
796 Link<Type> typeVariables,
797 Scope scope, onFailure, whenResolved) {
798 if (node.typeArguments == null) {
799 return const EmptyLink<Type>();
800 }
801 var arguments = new LinkBuilder<Type>();
802 for (Link<Node> typeArguments = node.typeArguments.nodes;
803 !typeArguments.isEmpty();
804 typeArguments = typeArguments.tail) {
805 if (typeVariables.isEmpty()) {
806 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT);
807 }
808 Type argType = resolveTypeAnnotationInContext(scope,
809 typeArguments.head,
810 onFailure,
811 whenResolved);
812 arguments.addLast(argType);
813 if (!typeVariables.isEmpty()) {
814 typeVariables = typeVariables.tail;
815 }
816 }
817 if (!typeVariables.isEmpty()) {
818 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
819 }
820 return arguments.toLink();
821 }
809 } 822 }
810 823
811 class ResolverVisitor extends CommonResolverVisitor<Element> { 824 class ResolverVisitor extends CommonResolverVisitor<Element> {
812 final TreeElementMapping mapping; 825 final TreeElementMapping mapping;
813 final Element enclosingElement; 826 final Element enclosingElement;
814 final TypeResolver typeResolver; 827 final TypeResolver typeResolver;
815 bool inInstanceContext; 828 bool inInstanceContext;
816 Scope scope; 829 Scope scope;
817 ClassElement currentClass; 830 ClassElement currentClass;
818 bool typeRequired = false; 831 bool typeRequired = false;
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 } 1650 }
1638 visitIn(node.formals, blockScope); 1651 visitIn(node.formals, blockScope);
1639 visitIn(node.block, blockScope); 1652 visitIn(node.block, blockScope);
1640 } 1653 }
1641 1654
1642 visitTypedef(Typedef node) { 1655 visitTypedef(Typedef node) {
1643 unimplemented(node, 'typedef'); 1656 unimplemented(node, 'typedef');
1644 } 1657 }
1645 } 1658 }
1646 1659
1647 class ClassResolverVisitor extends CommonResolverVisitor<Type> { 1660 class ClassResolverVisitor extends TypeDefinitionVisitor {
1648 Scope scope; 1661 ClassElement get element() => super.element;
1649 ClassElement classElement;
1650 1662
1651 ClassResolverVisitor(Compiler compiler, 1663 ClassResolverVisitor(Compiler compiler, ClassElement classElement)
1652 ClassElement classElement) 1664 : super(compiler, classElement);
1653 : this.classElement = classElement,
1654 scope = classElement.buildEnclosingScope(),
1655 super(compiler);
1656 1665
1657 Type visitClassNode(ClassNode node) { 1666 Type visitClassNode(ClassNode node) {
1658 compiler.ensure(classElement !== null); 1667 compiler.ensure(element !== null);
1659 compiler.ensure(!classElement.isResolved); 1668 compiler.ensure(!element.isResolved);
1660 final Link<Node> parameters = 1669
1661 node.typeParameters !== null ? node.typeParameters.nodes 1670 InterfaceType type = element.computeType(compiler);
1662 : const EmptyLink<TypeVariable>(); 1671 scope = new TypeDeclarationScope(scope, element);
1663 // Create types and elements for type variable. 1672 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet.
1664 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { 1673 // As a side-effect, this may get us back here trying to
1665 TypeVariable typeNode = link.head; 1674 // resolve this class again.
1666 SourceString variableName = typeNode.name.source; 1675 resolveTypeVariableBounds(node.typeParameters);
1667 TypeVariableType variableType = new TypeVariableType(variableName); 1676
1668 TypeVariableElement variableElement =
1669 new TypeVariableElement(variableName, classElement, node,
1670 variableType);
1671 variableType.element = variableElement;
1672 classElement.typeParameters[variableName] = variableElement;
1673 scope = new TypeDeclarationScope(scope, classElement);
1674 }
1675 // Resolve the bounds of type variables.
1676 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) {
1677 TypeVariable typeNode = link.head;
1678 SourceString variableName = typeNode.name.source;
1679 TypeVariableElement variableElement =
1680 classElement.typeParameters[variableName];
1681 if (typeNode.bound !== null) {
1682 Type boundType = visit(typeNode.bound);
1683 if (boundType !== null && boundType.element == variableElement) {
1684 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
1685 [variableElement.name]);
1686 } else if (boundType !== null) {
1687 variableElement.bound = boundType;
1688 } else {
1689 variableElement.bound = compiler.objectClass.computeType(compiler);
1690 }
1691 }
1692 }
1693 // Find super type. 1677 // Find super type.
1694 Type supertype = visit(node.superclass); 1678 Type supertype = visit(node.superclass);
1695 if (supertype !== null && supertype.element.isExtendable()) { 1679 if (supertype !== null && supertype.element.isExtendable()) {
1696 classElement.supertype = supertype; 1680 element.supertype = supertype;
1697 if (isBlackListed(supertype)) { 1681 if (isBlackListed(supertype)) {
1698 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); 1682 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]);
1699 } 1683 }
1700 } else if (supertype !== null) { 1684 } else if (supertype !== null) {
1701 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); 1685 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED);
1702 } 1686 }
1703 final objectElement = compiler.objectClass; 1687 final objectElement = compiler.objectClass;
1704 if (classElement !== objectElement && classElement.supertype === null) { 1688 if (element !== objectElement && element.supertype === null) {
1705 if (objectElement === null) { 1689 if (objectElement === null) {
1706 compiler.internalError("Internal error: cannot resolve Object", 1690 compiler.internalError("Internal error: cannot resolve Object",
1707 node: node); 1691 node: node);
1708 } else if (!objectElement.isResolved) { 1692 } else if (!objectElement.isResolved) {
1709 compiler.resolver.toResolve.add(objectElement); 1693 compiler.resolver.toResolve.add(objectElement);
1710 } 1694 }
1711 classElement.supertype = new InterfaceType(objectElement); 1695 // TODO(ahe): This should be objectElement.computeType(...).
1696 element.supertype = new InterfaceType(objectElement);
1712 } 1697 }
1713 if (node.defaultClause !== null) { 1698 if (node.defaultClause !== null) {
1714 classElement.defaultClass = visit(node.defaultClause); 1699 element.defaultClass = visit(node.defaultClause);
1715 } 1700 }
1716 for (Link<Node> link = node.interfaces.nodes; 1701 for (Link<Node> link = node.interfaces.nodes;
1717 !link.isEmpty(); 1702 !link.isEmpty();
1718 link = link.tail) { 1703 link = link.tail) {
1719 Type interfaceType = visit(link.head); 1704 Type interfaceType = visit(link.head);
1720 if (interfaceType !== null && interfaceType.element.isExtendable()) { 1705 if (interfaceType !== null && interfaceType.element.isExtendable()) {
1721 classElement.interfaces = 1706 element.interfaces =
1722 classElement.interfaces.prepend(interfaceType); 1707 element.interfaces.prepend(interfaceType);
1723 if (isBlackListed(interfaceType)) { 1708 if (isBlackListed(interfaceType)) {
1724 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); 1709 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]);
1725 } 1710 }
1726 } else { 1711 } else {
1727 error(link.head, MessageKind.TYPE_NAME_EXPECTED); 1712 error(link.head, MessageKind.TYPE_NAME_EXPECTED);
1728 } 1713 }
1729 } 1714 }
1730 calculateAllSupertypes(classElement, new Set<ClassElement>()); 1715 calculateAllSupertypes(element, new Set<ClassElement>());
1731 addDefaultConstructorIfNeeded(classElement); 1716 addDefaultConstructorIfNeeded(element);
1732 return classElement.computeType(compiler); 1717 return element.computeType(compiler);
1733 } 1718 }
1734 1719
1735 Type visitTypeAnnotation(TypeAnnotation node) { 1720 Type visitTypeAnnotation(TypeAnnotation node) {
1736 return visit(node.typeName); 1721 return visit(node.typeName);
1737 } 1722 }
1738 1723
1739 Type visitIdentifier(Identifier node) { 1724 Type visitIdentifier(Identifier node) {
1740 Element element = scope.lookup(node.source); 1725 Element element = scope.lookup(node.source);
1741 if (element === null) { 1726 if (element === null) {
1742 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); 1727 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 constructor.type = new FunctionType(returnType, const EmptyLink<Type>(), 1831 constructor.type = new FunctionType(returnType, const EmptyLink<Type>(),
1847 constructor); 1832 constructor);
1848 constructor.cachedNode = 1833 constructor.cachedNode =
1849 new FunctionExpression(new Identifier(element.position()), 1834 new FunctionExpression(new Identifier(element.position()),
1850 new NodeList.empty(), 1835 new NodeList.empty(),
1851 new Block(new NodeList.empty()), 1836 new Block(new NodeList.empty()),
1852 null, null, null, null); 1837 null, null, null, null);
1853 } 1838 }
1854 1839
1855 isBlackListed(Type type) { 1840 isBlackListed(Type type) {
1856 LibraryElement lib = classElement.getLibrary(); 1841 LibraryElement lib = element.getLibrary();
1857 return 1842 return
1858 lib !== compiler.coreLibrary && 1843 lib !== compiler.coreLibrary &&
1859 lib !== compiler.coreImplLibrary && 1844 lib !== compiler.coreImplLibrary &&
1860 lib !== compiler.jsHelperLibrary && 1845 lib !== compiler.jsHelperLibrary &&
1861 (type.element === compiler.dynamicClass || 1846 (type.element === compiler.dynamicClass ||
1862 type.element === compiler.boolClass || 1847 type.element === compiler.boolClass ||
1863 type.element === compiler.numClass || 1848 type.element === compiler.numClass ||
1864 type.element === compiler.intClass || 1849 type.element === compiler.intClass ||
1865 type.element === compiler.doubleClass || 1850 type.element === compiler.doubleClass ||
1866 type.element === compiler.stringClass || 1851 type.element === compiler.stringClass ||
1867 type.element === compiler.nullClass || 1852 type.element === compiler.nullClass ||
1868 type.element === compiler.functionClass); 1853 type.element === compiler.functionClass);
1869 } 1854 }
1870 } 1855 }
1871 1856
1857 class TypeDefinitionVisitor extends CommonResolverVisitor<Type> {
1858 Scope scope;
1859 TypeDeclarationElement element;
1860 TypeResolver typeResolver;
1861
1862 TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element)
1863 : this.element = element,
1864 scope = element.enclosingElement.buildScope(),
1865 typeResolver = new TypeResolver(compiler),
1866 super(compiler);
1867
1868 void resolveTypeVariableBounds(NodeList node) {
1869 if (node === null) return;
1870
1871 var nameSet = new Set<SourceString>();
1872 // Resolve the bounds of type variables.
1873 Link<Type> typeLink = element.typeVariables;
1874 Link<Node> nodeLink = node.nodes;
1875 while (!nodeLink.isEmpty()) {
1876 TypeVariableType typeVariable = typeLink.head;
1877 SourceString typeName = typeVariable.name;
1878 TypeVariable typeNode = nodeLink.head;
1879 if (nameSet.contains(typeName)) {
1880 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]);
1881 }
1882 nameSet.add(typeName);
1883
1884 TypeVariableElement variableElement = typeVariable.element;
1885 if (typeNode.bound !== null) {
1886 Type boundType = typeResolver.resolveTypeAnnotation(
1887 typeNode.bound, inScope: scope, onFailure: warning);
1888 if (boundType !== null && boundType.element == variableElement) {
1889 // TODO(johnniwinther): Check for more general cycles, like
1890 // [: <A extends B, B extends C, C extends B> :].
1891 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE,
1892 [variableElement.name]);
1893 } else if (boundType !== null) {
1894 variableElement.bound = boundType;
1895 } else {
1896 // TODO(johnniwinther): Should be an erroneous type.
1897 variableElement.bound = compiler.objectClass.computeType(compiler);
1898 }
1899 } else {
1900 variableElement.bound = compiler.objectClass.computeType(compiler);
1901 }
1902 nodeLink = nodeLink.tail;
1903 typeLink = typeLink.tail;
1904 }
1905 assert(typeLink.isEmpty());
1906 }
1907 }
1908
1872 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { 1909 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> {
1873 VariableDefinitions definitions; 1910 VariableDefinitions definitions;
1874 ResolverVisitor resolver; 1911 ResolverVisitor resolver;
1875 ElementKind kind; 1912 ElementKind kind;
1876 VariableListElement variables; 1913 VariableListElement variables;
1877 1914
1878 VariableDefinitionsVisitor(Compiler compiler, 1915 VariableDefinitionsVisitor(Compiler compiler,
1879 this.definitions, this.resolver, this.kind) 1916 this.definitions, this.resolver, this.kind)
1880 : super(compiler) 1917 : super(compiler)
1881 { 1918 {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
2159 } 2196 }
2160 2197
2161 /** 2198 /**
2162 * [TypeDeclarationScope] defines the outer scope of a type declaration in 2199 * [TypeDeclarationScope] defines the outer scope of a type declaration in
2163 * which the declared type variables and the entities in the enclosing scope are 2200 * which the declared type variables and the entities in the enclosing scope are
2164 * available but where declared and inherited members are not available. This 2201 * available but where declared and inherited members are not available. This
2165 * scope is only used for class/interface declarations during resolution of the 2202 * scope is only used for class/interface declarations during resolution of the
2166 * class hierarchy. In all other cases [ClassScope] is used. 2203 * class hierarchy. In all other cases [ClassScope] is used.
2167 */ 2204 */
2168 class TypeDeclarationScope extends Scope { 2205 class TypeDeclarationScope extends Scope {
2169 ClassElement get element() => super.element; 2206 TypeDeclarationElement get element() => super.element;
2170 2207
2171 TypeDeclarationScope(Scope parent, ClassElement element) 2208 TypeDeclarationScope(parent, TypeDeclarationElement element)
2172 : super(parent, element); 2209 : super(parent, element) {
2210 assert(parent !== null);
2211 }
2173 2212
2174 Element add(Element newElement) { 2213 Element add(Element newElement) {
2175 throw "Cannot add element to TypeDeclarationScope"; 2214 throw "Cannot add element to TypeDeclarationScope";
2176 } 2215 }
2177 2216
2217 /**
2218 * Looks up [name] within the type variables declared in [element].
2219 */
2220 Element lookupTypeVariable(SourceString name) {
2221 return null;
2222 }
2223
2178 Element lookup(SourceString name) { 2224 Element lookup(SourceString name) {
2179 Element result = element.lookupTypeParameter(name); 2225 Link<Type> typeVariableLink = element.typeVariables;
2180 if (result !== null) return result; 2226 while (!typeVariableLink.isEmpty()) {
2181 if (parent !== null) return parent.lookup(name); 2227 TypeVariableType typeVariable = typeVariableLink.head;
2228 if (typeVariable.name == name) {
2229 return typeVariable.element;
2230 }
2231 typeVariableLink = typeVariableLink.tail;
2232 }
2233
2234 return parent.lookup(name);
2182 } 2235 }
2183 2236
2184 String toString() => 2237 String toString() =>
2185 '$element${element.typeParameters.getKeys()} > $parent'; 2238 '$element${element.typeVariables} > $parent';
2186 } 2239 }
2187 2240
2188 class MethodScope extends Scope { 2241 class MethodScope extends Scope {
2189 final Map<SourceString, Element> elements; 2242 final Map<SourceString, Element> elements;
2190 2243
2191 MethodScope(Scope parent, Element element) 2244 MethodScope(Scope parent, Element element)
2192 : super(parent, element), this.elements = new Map<SourceString, Element>(); 2245 : super(parent, element),
2246 this.elements = new Map<SourceString, Element>() {
2247 assert(parent !== null);
2248 }
2193 2249
2194 Element lookup(SourceString name) { 2250 Element lookup(SourceString name) {
2195 Element found = elements[name]; 2251 Element found = elements[name];
2196 if (found !== null) return found; 2252 if (found !== null) return found;
2197 return parent.lookup(name); 2253 return parent.lookup(name);
2198 } 2254 }
2199 2255
2200 Element add(Element newElement) { 2256 Element add(Element newElement) {
2201 if (elements.containsKey(newElement.name)) { 2257 if (elements.containsKey(newElement.name)) {
2202 return elements[newElement.name]; 2258 return elements[newElement.name];
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2245 TopScope(LibraryElement library) : super(null, library); 2301 TopScope(LibraryElement library) : super(null, library);
2246 Element lookup(SourceString name) { 2302 Element lookup(SourceString name) {
2247 return library.find(name); 2303 return library.find(name);
2248 } 2304 }
2249 2305
2250 Element add(Element newElement) { 2306 Element add(Element newElement) {
2251 throw "Cannot add an element in the top scope"; 2307 throw "Cannot add an element in the top scope";
2252 } 2308 }
2253 String toString() => '$element'; 2309 String toString() => '$element';
2254 } 2310 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/elements/elements.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698