| 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 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |