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 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 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 209 TreeElements resolveParameter(Element element) { | 209 TreeElements resolveParameter(Element element) { |
| 210 Node tree = element.parseNode(compiler); | 210 Node tree = element.parseNode(compiler); |
| 211 ResolverVisitor visitor = | 211 ResolverVisitor visitor = |
| 212 new ResolverVisitor(compiler, element.enclosingElement); | 212 new ResolverVisitor(compiler, element.enclosingElement); |
| 213 initializerDo(tree, visitor.visit); | 213 initializerDo(tree, visitor.visit); |
| 214 return visitor.mapping; | 214 return visitor.mapping; |
| 215 } | 215 } |
| 216 | 216 |
| 217 Type resolveTypeAnnotation(Element element, TypeAnnotation annotation) { | 217 Type resolveTypeAnnotation(Element element, TypeAnnotation annotation) { |
| 218 if (annotation === null) return compiler.types.dynamicType; | 218 if (annotation === null) return compiler.types.dynamicType; |
| 219 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | 219 Scope context = new TopScope(element.getLibrary()); |
|
ahe
2012/07/30 10:30:05
It seems ad hoc how we build the scope here. I wou
Johnni Winther
2012/08/01 10:12:28
Done.
| |
| 220 Type result = visitor.resolveTypeAnnotation(annotation); | 220 Type result; |
| 221 Element contextElement = element.getEnclosingClassOrTypedef(); | |
| 222 if (contextElement !== null && | |
| 223 (contextElement.isTypedef() || contextElement.isClass())) { | |
| 224 var typeDefinition = contextElement; | |
| 225 context = new TypeVariablesScope(context, contextElement, | |
| 226 typeDefinition.typeParameters); | |
| 227 TypeResolver typeResolver = new TypeResolver(compiler); | |
| 228 result = typeResolver.resolveTypeAnnotation(annotation, | |
| 229 inContext: context, | |
| 230 onFailure: warning); | |
| 231 } else { | |
| 232 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | |
| 233 result = visitor.resolveTypeAnnotation(annotation); | |
| 234 } | |
| 221 if (result === null) { | 235 if (result === null) { |
| 222 // TODO(karklose): warning. | 236 // TODO(karklose): warning. |
| 223 return compiler.types.dynamicType; | 237 return compiler.types.dynamicType; |
| 224 } | 238 } |
| 225 return result; | 239 return result; |
| 226 } | 240 } |
| 227 | 241 |
| 228 void resolveClass(ClassElement element) { | 242 void resolveClass(ClassElement element) { |
| 229 if (element.isResolved || element.isBeingResolved) return; | 243 if (element.isResolved || element.isBeingResolved) return; |
| 230 element.isBeingResolved = true; | 244 element.isBeingResolved = true; |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 FunctionSignature resolveFunctionExpression(Element element, | 355 FunctionSignature resolveFunctionExpression(Element element, |
| 342 FunctionExpression node) { | 356 FunctionExpression node) { |
| 343 return measure(() => SignatureResolver.analyze( | 357 return measure(() => SignatureResolver.analyze( |
| 344 compiler, node.parameters, node.returnType, element)); | 358 compiler, node.parameters, node.returnType, element)); |
| 345 } | 359 } |
| 346 | 360 |
| 347 FunctionSignature resolveTypedef(TypedefElement element) { | 361 FunctionSignature resolveTypedef(TypedefElement element) { |
| 348 return compiler.withCurrentElement(element, () { | 362 return compiler.withCurrentElement(element, () { |
| 349 Typedef node = | 363 Typedef node = |
| 350 compiler.parser.measure(() => element.parseNode(compiler)); | 364 compiler.parser.measure(() => element.parseNode(compiler)); |
| 351 return measure(() => SignatureResolver.analyze( | 365 TypedefResolverVisitor visitor = |
| 352 compiler, node.formals, node.returnType, element)); | 366 new TypedefResolverVisitor(compiler, element.getLibrary(), element); |
|
ahe
2012/07/30 10:30:05
Construction of the visitor should also be measure
Johnni Winther
2012/08/01 10:12:29
Done.
| |
| 367 return measure(() => visitor.visit(node)); | |
| 353 }); | 368 }); |
| 354 } | 369 } |
| 355 | 370 |
| 356 FunctionType computeFunctionType(Element element, | 371 FunctionType computeFunctionType(Element element, |
| 357 FunctionSignature signature) { | 372 FunctionSignature signature) { |
| 358 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); | 373 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); |
| 359 for (Link<Element> link = signature.requiredParameters; | 374 for (Link<Element> link = signature.requiredParameters; |
| 360 !link.isEmpty(); | 375 !link.isEmpty(); |
| 361 link = link.tail) { | 376 link = link.tail) { |
| 362 parameterTypes.addLast(link.head.computeType(compiler)); | 377 parameterTypes.addLast(link.head.computeType(compiler)); |
| 363 // TODO(karlklose): optional parameters. | 378 // TODO(karlklose): optional parameters. |
| 364 } | 379 } |
| 365 return new FunctionType(signature.returnType, | 380 return new FunctionType(signature.returnType, |
| 366 parameterTypes.toLink(), | 381 parameterTypes.toLink(), |
| 367 element); | 382 element); |
| 368 } | 383 } |
| 369 | 384 |
| 370 error(Node node, MessageKind kind, [arguments = const []]) { | 385 error(Node node, MessageKind kind, [arguments = const []]) { |
| 371 ResolutionError message = new ResolutionError(kind, arguments); | 386 ResolutionError message = new ResolutionError(kind, arguments); |
| 372 compiler.reportError(node, message); | 387 compiler.reportError(node, message); |
| 373 } | 388 } |
| 389 | |
| 390 warning(Node node, MessageKind kind, [arguments = const []]) { | |
| 391 ResolutionWarning message = new ResolutionWarning(kind, arguments); | |
| 392 compiler.reportWarning(node, message); | |
| 393 } | |
| 374 } | 394 } |
| 375 | 395 |
| 376 class InitializerResolver { | 396 class InitializerResolver { |
| 377 final ResolverVisitor visitor; | 397 final ResolverVisitor visitor; |
| 378 final Map<SourceString, Node> initialized; | 398 final Map<SourceString, Node> initialized; |
| 379 Link<Node> initializers; | 399 Link<Node> initializers; |
| 380 bool hasSuper; | 400 bool hasSuper; |
| 381 | 401 |
| 382 InitializerResolver(this.visitor) | 402 InitializerResolver(this.visitor) |
| 383 : initialized = new Map<SourceString, Node>(), hasSuper = false; | 403 : initialized = new Map<SourceString, Node>(), hasSuper = false; |
| (...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1628 } | 1648 } |
| 1629 visitIn(node.formals, scope); | 1649 visitIn(node.formals, scope); |
| 1630 visitIn(node.block, scope); | 1650 visitIn(node.block, scope); |
| 1631 } | 1651 } |
| 1632 | 1652 |
| 1633 visitTypedef(Typedef node) { | 1653 visitTypedef(Typedef node) { |
| 1634 unimplemented(node, 'typedef'); | 1654 unimplemented(node, 'typedef'); |
| 1635 } | 1655 } |
| 1636 } | 1656 } |
| 1637 | 1657 |
| 1638 class ClassResolverVisitor extends CommonResolverVisitor<Type> { | 1658 class TypeDefinitionVisitor extends CommonResolverVisitor<Type> { |
| 1639 Scope context; | 1659 Scope context; |
| 1640 ClassElement classElement; | 1660 LibraryElement library; |
| 1661 Element enclosing; | |
| 1662 Function report; | |
| 1641 | 1663 |
| 1642 ClassResolverVisitor(Compiler compiler, LibraryElement library, | 1664 visitTypeRequired(Node node) { |
| 1643 ClassElement this.classElement) | 1665 Function oldReport = report; |
| 1644 : context = new TopScope(library), | 1666 report = error; |
| 1645 super(compiler); | 1667 Type result = super.visit(node); |
| 1668 report = oldReport; | |
| 1669 return result; | |
| 1670 } | |
| 1646 | 1671 |
| 1647 Type visitClassNode(ClassNode node) { | 1672 TypeDefinitionVisitor(Compiler compiler, LibraryElement library, |
| 1648 compiler.ensure(classElement !== null); | 1673 Element this.enclosing) |
| 1649 compiler.ensure(!classElement.isResolved); | 1674 : this.library = library, |
| 1675 context = new TopScope(library), | |
| 1676 super(compiler) { | |
| 1677 report = warning; | |
|
ahe
2012/07/30 10:30:05
This creates a new function closure object on each
Johnni Winther
2012/08/01 10:12:29
TODO
| |
| 1678 } | |
| 1650 | 1679 |
| 1651 classElement.ensureParametersAndType(compiler); | 1680 abstract Map<SourceString, Element> get typeParameters(); |
|
ahe
2012/07/30 10:30:05
What is this for?
Johnni Winther
2012/08/01 10:12:29
Removed.
| |
| 1652 context = new TypeVariablesScope(context, classElement); | |
| 1653 | |
| 1654 // Resolve the bounds of type variables. | |
| 1655 Link<Node> parameters = | |
| 1656 node.typeParameters !== null ? node.typeParameters.nodes | |
| 1657 : const EmptyLink<TypeVariable>(); | |
| 1658 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { | |
| 1659 TypeVariable typeNode = link.head; | |
| 1660 SourceString variableName = typeNode.name.source; | |
| 1661 TypeVariableElement variableElement = | |
| 1662 classElement.typeParameters[variableName]; | |
| 1663 if (typeNode.bound !== null) { | |
| 1664 Type boundType = visit(typeNode.bound); | |
| 1665 if (boundType !== null && boundType.element == variableElement) { | |
| 1666 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | |
| 1667 [variableElement.name]); | |
| 1668 } else if (boundType !== null) { | |
| 1669 variableElement.bound = boundType; | |
| 1670 } else { | |
| 1671 variableElement.bound = compiler.objectClass.computeType(compiler); | |
| 1672 } | |
| 1673 } | |
| 1674 } | |
| 1675 | |
| 1676 // Find super type. | |
| 1677 Type supertype = visit(node.superclass); | |
| 1678 if (supertype !== null && supertype.element.isExtendable()) { | |
| 1679 classElement.supertype = supertype; | |
| 1680 if (isBlackListed(supertype)) { | |
| 1681 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); | |
| 1682 } | |
| 1683 } else if (supertype !== null) { | |
| 1684 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); | |
| 1685 } | |
| 1686 final objectElement = compiler.objectClass; | |
| 1687 if (classElement !== objectElement && classElement.supertype === null) { | |
| 1688 if (objectElement === null) { | |
| 1689 compiler.internalError("Internal error: cannot resolve Object", | |
| 1690 node: node); | |
| 1691 } else if (!objectElement.isResolved) { | |
| 1692 compiler.resolver.toResolve.add(objectElement); | |
| 1693 } | |
| 1694 classElement.supertype = new InterfaceType(objectElement); | |
| 1695 } | |
| 1696 if (node.defaultClause !== null) { | |
| 1697 classElement.defaultClass = visit(node.defaultClause); | |
| 1698 } | |
| 1699 for (Link<Node> link = node.interfaces.nodes; | |
| 1700 !link.isEmpty(); | |
| 1701 link = link.tail) { | |
| 1702 Type interfaceType = visit(link.head); | |
| 1703 if (interfaceType !== null && interfaceType.element.isExtendable()) { | |
| 1704 classElement.interfaces = | |
| 1705 classElement.interfaces.prepend(interfaceType); | |
| 1706 if (isBlackListed(interfaceType)) { | |
| 1707 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); | |
| 1708 } | |
| 1709 } else { | |
| 1710 error(link.head, MessageKind.TYPE_NAME_EXPECTED); | |
| 1711 } | |
| 1712 } | |
| 1713 calculateAllSupertypes(classElement, new Set<ClassElement>()); | |
| 1714 addDefaultConstructorIfNeeded(classElement); | |
| 1715 return classElement.computeType(compiler); | |
| 1716 } | |
| 1717 | 1681 |
| 1718 Type visitTypeAnnotation(TypeAnnotation node) { | 1682 Type visitTypeAnnotation(TypeAnnotation node) { |
| 1719 Type type = visit(node.typeName); | 1683 Type type = visit(node.typeName); |
| 1720 if (type is! InterfaceType) { | 1684 if (type is! InterfaceType) { |
| 1721 // TODO(johnniwinther): Handle function types. | 1685 // TODO(johnniwinther): Handle function types. |
| 1722 return type; | 1686 return type; |
| 1723 } | 1687 } |
| 1724 int typeParameterCount = type.element.typeParameters.length; | 1688 int typeParameterCount = type.element.typeParameters.length; |
| 1725 if (node.typeArguments === null) { | 1689 if (node.typeArguments === null) { |
| 1726 if (type.typeArguments.isEmpty() || typeParameterCount == 0) { | 1690 if (type.typeArguments.isEmpty() || typeParameterCount == 0) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 1743 } | 1707 } |
| 1744 // TODO(johnniwinther): Check argument count and bounds. | 1708 // TODO(johnniwinther): Check argument count and bounds. |
| 1745 return new InterfaceType(type.element, typeArguments.toLink()); | 1709 return new InterfaceType(type.element, typeArguments.toLink()); |
| 1746 } | 1710 } |
| 1747 | 1711 |
| 1748 Type visitTypeVariable(TypeVariable node) { | 1712 Type visitTypeVariable(TypeVariable node) { |
| 1749 return visit(node.name); | 1713 return visit(node.name); |
| 1750 } | 1714 } |
| 1751 | 1715 |
| 1752 Type visitIdentifier(Identifier node) { | 1716 Type visitIdentifier(Identifier node) { |
| 1717 // TODO(karlklose): use a TypeResolver here. | |
| 1718 if (node.source.stringValue === 'void') return compiler.types.voidType; | |
| 1753 Element element = context.lookup(node.source); | 1719 Element element = context.lookup(node.source); |
| 1754 if (element === null) { | 1720 if (element === null) { |
| 1755 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | 1721 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
| 1756 return null; | 1722 return null; |
| 1757 } else if (!element.impliesType() && !element.isTypeVariable()) { | 1723 } else if (!element.impliesType() && !element.isTypeVariable()) { |
| 1758 error(node, MessageKind.NOT_A_TYPE, [node]); | 1724 error(node, MessageKind.NOT_A_TYPE, [node]); |
| 1759 return null; | 1725 return null; |
| 1760 } else { | 1726 } else { |
| 1761 if (element.isClass()) { | 1727 if (element.isClass()) { |
| 1762 compiler.resolver.toResolve.add(element); | 1728 compiler.resolver.toResolve.add(element); |
| 1763 } | 1729 } |
| 1764 if (element.isTypeVariable()) { | 1730 if (element.isTypeVariable()) { |
| 1765 TypeVariableElement variableElement = element; | 1731 TypeVariableElement variableElement = element; |
| 1766 return variableElement.type; | 1732 return variableElement.type; |
| 1767 } else if (element.isTypedef()) { | |
| 1768 compiler.unimplemented('visitIdentifier for typedefs', node: node); | |
| 1769 } else { | 1733 } else { |
| 1770 // Type variables are handled in [visitTypeAnnotation]. | 1734 // Type variables are handled in [visitTypeAnnotation]. |
| 1771 return element.computeType(compiler); | 1735 return element.computeType(compiler); |
| 1772 } | 1736 } |
| 1773 } | 1737 } |
| 1774 return null; | 1738 return null; |
| 1775 } | 1739 } |
| 1776 | 1740 |
| 1777 Type visitSend(Send node) { | 1741 Type visitSend(Send node) { |
| 1778 Identifier prefix = node.receiver.asIdentifier(); | 1742 Identifier prefix = node.receiver.asIdentifier(); |
| 1779 if (prefix === null) { | 1743 if (prefix === null) { |
| 1780 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | 1744 report(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| 1781 return null; | 1745 return null; |
| 1782 } | 1746 } |
| 1783 Element element = context.lookup(prefix.source); | 1747 Element element = context.lookup(prefix.source); |
| 1784 if (element === null || element.kind !== ElementKind.PREFIX) { | 1748 if (element === null || element.kind !== ElementKind.PREFIX) { |
| 1785 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | 1749 report(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| 1786 return null; | 1750 return null; |
| 1787 } | 1751 } |
| 1788 PrefixElement prefixElement = element; | 1752 PrefixElement prefixElement = element; |
| 1789 Identifier selector = node.selector.asIdentifier(); | 1753 Identifier selector = node.selector.asIdentifier(); |
| 1790 var e = prefixElement.lookupLocalMember(selector.source); | 1754 var e = prefixElement.lookupLocalMember(selector.source); |
| 1791 if (e === null || !e.impliesType()) { | 1755 if (e === null || !e.impliesType()) { |
| 1792 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); | 1756 report(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); |
| 1793 return null; | 1757 return null; |
| 1794 } | 1758 } |
| 1795 return e.computeType(compiler); | 1759 return e.computeType(compiler); |
| 1796 } | 1760 } |
| 1797 | 1761 |
| 1762 createTypeVariables(NodeList node) { | |
| 1763 if (node === null) return; | |
| 1764 // Create types and elements for type variable. | |
| 1765 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | |
| 1766 TypeVariable typeNode = link.head; | |
| 1767 SourceString variableName = typeNode.name.source; | |
| 1768 TypeVariableType variableType = new TypeVariableType(variableName); | |
| 1769 TypeVariableElement variableElement = | |
| 1770 new TypeVariableElement(variableName, enclosing, typeNode, | |
| 1771 variableType); | |
| 1772 variableType.element = variableElement; | |
| 1773 typeParameters[variableName] = variableElement; | |
| 1774 } | |
| 1775 } | |
| 1776 | |
| 1777 visitNodeList(NodeList node) { | |
| 1778 if (node === null) return; | |
| 1779 // Resolve the bounds of type variables. | |
| 1780 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | |
| 1781 TypeVariable typeNode = link.head; | |
| 1782 SourceString variableName = typeNode.name.source; | |
| 1783 TypeVariableElement variableElement = typeParameters[variableName]; | |
| 1784 if (typeNode.bound !== null) { | |
| 1785 Type boundType = visit(typeNode.bound); | |
| 1786 if (boundType !== null && boundType.element == variableElement) { | |
| 1787 report(node, MessageKind.CYCLIC_TYPE_VARIABLE, | |
| 1788 [variableElement.name]); | |
| 1789 } else if (boundType !== null) { | |
| 1790 variableElement.bound = boundType; | |
| 1791 } else { | |
| 1792 variableElement.bound = compiler.objectClass.computeType(compiler); | |
| 1793 } | |
| 1794 } | |
| 1795 } | |
| 1796 } | |
| 1797 } | |
| 1798 | |
| 1799 class TypedefResolverVisitor extends TypeDefinitionVisitor { | |
| 1800 TypedefElement get typedefElement() => enclosing; | |
| 1801 get typeParameters() => typedefElement.typeParameters; | |
| 1802 | |
| 1803 TypedefResolverVisitor(Compiler compiler, LibraryElement library, | |
| 1804 TypedefElement typedefElement) | |
| 1805 : super(compiler, library, typedefElement); | |
| 1806 | |
| 1807 visitVariableDefinitions(VariableDefinitions variables) { | |
| 1808 return visit(variables.type); | |
| 1809 } | |
| 1810 | |
| 1811 visitTypedef(Typedef node) { | |
| 1812 createTypeVariables(node.typeParameters); | |
| 1813 FunctionType type = new FunctionType(compiler.types.dynamicType, | |
| 1814 null, typedefElement); | |
| 1815 typedefElement.cachedType = type; | |
| 1816 context = new TypeVariablesScope(context, enclosing, typeParameters); | |
| 1817 Type returnType = visit(node.returnType); | |
| 1818 if (returnType === null) { | |
| 1819 returnType = compiler.types.dynamicType; | |
| 1820 } else if (returnType.element === typedefElement) { | |
| 1821 warning(node.returnType, MessageKind.CYCLIC_TYPEDEF); | |
| 1822 returnType = compiler.types.dynamicType; | |
| 1823 } | |
| 1824 LinkBuilder<Type> formalsTypes = new LinkBuilder<Type>(); | |
| 1825 TypeResolver typeResolver = new TypeResolver(compiler); | |
| 1826 for (Link<Node> formals = node.formals.nodes; | |
| 1827 !formals.isEmpty(); | |
| 1828 formals = formals.tail) { | |
| 1829 if (formals.head.asNodeList() !== null) { | |
| 1830 // If there is a NodeList in the formal parameter list, it is the list | |
| 1831 // of optional parameters. | |
| 1832 // TODO(karlklose): support optional parameters. | |
| 1833 break; | |
| 1834 } | |
| 1835 Type formalType = visit(formals.head); | |
| 1836 if (formalType === null) { | |
| 1837 formalType = compiler.types.dynamicType; | |
| 1838 } else { | |
| 1839 if (formalType.element === typedefElement) { | |
| 1840 warning(formals.head, MessageKind.CYCLIC_TYPEDEF); | |
| 1841 formalType = compiler.types.dynamicType; | |
| 1842 } | |
| 1843 } | |
| 1844 formalsTypes.addLast(formalType); | |
| 1845 } | |
| 1846 type.parameterTypes = formalsTypes.toLink(); | |
| 1847 // Resolve type parameter bounds. | |
| 1848 visit(node.typeParameters); | |
| 1849 } | |
| 1850 } | |
| 1851 | |
| 1852 class ClassResolverVisitor extends TypeDefinitionVisitor { | |
| 1853 ClassElement get classElement() => enclosing; | |
| 1854 | |
| 1855 get typeParameters() => classElement.typeParameters; | |
| 1856 | |
| 1857 ClassResolverVisitor(Compiler compiler, LibraryElement library, | |
| 1858 ClassElement classElement) | |
| 1859 : super(compiler, library, classElement); | |
| 1860 | |
| 1861 Type visitClassNode(ClassNode node) { | |
| 1862 compiler.ensure(classElement !== null); | |
| 1863 compiler.ensure(!classElement.isResolved); | |
| 1864 | |
| 1865 // TODO(johnniwinther): Unify [ClassElement.ensureParametersAndType] and | |
| 1866 // [TypeDefinitionVisitor.createTypeVariables] | |
| 1867 classElement.ensureParametersAndType(compiler); | |
| 1868 | |
| 1869 // Resolve type paramters. | |
| 1870 context = new TypeVariablesScope(context, enclosing, typeParameters); | |
| 1871 visit(node.typeParameters); | |
| 1872 | |
| 1873 // Find super type. | |
| 1874 Type supertype = visitTypeRequired(node.superclass); | |
| 1875 if (supertype !== null && supertype.element.isExtendable()) { | |
| 1876 classElement.supertype = supertype; | |
| 1877 if (isBlackListed(supertype)) { | |
| 1878 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); | |
| 1879 } | |
| 1880 } else if (supertype !== null) { | |
| 1881 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); | |
| 1882 } | |
| 1883 final objectElement = compiler.objectClass; | |
| 1884 if (classElement !== objectElement && classElement.supertype === null) { | |
| 1885 if (objectElement === null) { | |
| 1886 compiler.internalError("Internal error: cannot resolve Object", | |
| 1887 node: node); | |
| 1888 } else if (!objectElement.isResolved) { | |
| 1889 compiler.resolver.toResolve.add(objectElement); | |
| 1890 } | |
| 1891 classElement.supertype = new InterfaceType(objectElement); | |
| 1892 } | |
| 1893 if (node.defaultClause !== null) { | |
| 1894 classElement.defaultClass = visitTypeRequired(node.defaultClause); | |
| 1895 } | |
| 1896 for (Link<Node> link = node.interfaces.nodes; | |
| 1897 !link.isEmpty(); | |
| 1898 link = link.tail) { | |
| 1899 Type interfaceType = visitTypeRequired(link.head); | |
| 1900 if (interfaceType !== null && interfaceType.element.isExtendable()) { | |
| 1901 classElement.interfaces = | |
| 1902 classElement.interfaces.prepend(interfaceType); | |
| 1903 if (isBlackListed(interfaceType)) { | |
| 1904 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); | |
| 1905 } | |
| 1906 } else { | |
| 1907 error(link.head, MessageKind.TYPE_NAME_EXPECTED); | |
| 1908 } | |
| 1909 } | |
| 1910 calculateAllSupertypes(classElement, new Set<ClassElement>()); | |
| 1911 addDefaultConstructorIfNeeded(classElement); | |
| 1912 return classElement.computeType(compiler); | |
| 1913 } | |
| 1914 | |
| 1798 Link<InterfaceType> getOrCalculateAllSupertypes(ClassElement cls, | 1915 Link<InterfaceType> getOrCalculateAllSupertypes(ClassElement cls, |
| 1799 [Set<ClassElement> seen]) { | 1916 [Set<ClassElement> seen]) { |
| 1800 Link<InterfaceType> allSupertypes = cls.allSupertypes; | 1917 Link<InterfaceType> allSupertypes = cls.allSupertypes; |
| 1801 if (allSupertypes !== null) return allSupertypes; | 1918 if (allSupertypes !== null) return allSupertypes; |
| 1802 if (seen === null) { | 1919 if (seen === null) { |
| 1803 seen = new Set<ClassElement>(); | 1920 seen = new Set<ClassElement>(); |
| 1804 } | 1921 } |
| 1805 if (seen.contains(cls)) { | 1922 if (seen.contains(cls)) { |
| 1806 error(cls.parseNode(compiler), | 1923 error(cls.parseNode(compiler), |
| 1807 MessageKind.CYCLIC_CLASS_HIERARCHY, | 1924 MessageKind.CYCLIC_CLASS_HIERARCHY, |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2168 class Scope { | 2285 class Scope { |
| 2169 final Element element; | 2286 final Element element; |
| 2170 final Scope parent; | 2287 final Scope parent; |
| 2171 | 2288 |
| 2172 Scope(this.parent, this.element); | 2289 Scope(this.parent, this.element); |
| 2173 abstract Element add(Element element); | 2290 abstract Element add(Element element); |
| 2174 abstract Element lookup(SourceString name); | 2291 abstract Element lookup(SourceString name); |
| 2175 } | 2292 } |
| 2176 | 2293 |
| 2177 class TypeVariablesScope extends Scope { | 2294 class TypeVariablesScope extends Scope { |
| 2178 TypeVariablesScope(parent, ClassElement element) : super(parent, element); | 2295 final Map<SourceString, TypeVariableElement> variables; |
| 2296 | |
| 2297 TypeVariablesScope(parent, element, this.variables) : super(parent, element); | |
| 2298 | |
| 2179 Element add(Element newElement) { | 2299 Element add(Element newElement) { |
| 2180 throw "Cannot add element to TypeVariableScope"; | 2300 throw "Cannot add element to TypeVariableScope"; |
| 2181 } | 2301 } |
| 2302 | |
| 2182 Element lookup(SourceString name) { | 2303 Element lookup(SourceString name) { |
| 2183 ClassElement cls = element; | 2304 Element result = variables[name]; |
| 2184 Element result = cls.lookupTypeParameter(name); | |
| 2185 if (result !== null) return result; | 2305 if (result !== null) return result; |
| 2186 if (parent !== null) return parent.lookup(name); | 2306 if (parent !== null) return parent.lookup(name); |
| 2187 } | 2307 } |
| 2188 } | 2308 } |
| 2189 | 2309 |
| 2190 class MethodScope extends Scope { | 2310 class MethodScope extends Scope { |
| 2191 final Map<SourceString, Element> elements; | 2311 final Map<SourceString, Element> elements; |
| 2192 | 2312 |
| 2193 MethodScope(Scope parent, Element element) | 2313 MethodScope(Scope parent, Element element) |
| 2194 : super(parent, element), this.elements = new Map<SourceString, Element>(); | 2314 : super(parent, element), this.elements = new Map<SourceString, Element>(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2237 | 2357 |
| 2238 TopScope(LibraryElement library) : super(null, library); | 2358 TopScope(LibraryElement library) : super(null, library); |
| 2239 Element lookup(SourceString name) { | 2359 Element lookup(SourceString name) { |
| 2240 return library.find(name); | 2360 return library.find(name); |
| 2241 } | 2361 } |
| 2242 | 2362 |
| 2243 Element add(Element newElement) { | 2363 Element add(Element newElement) { |
| 2244 throw "Cannot add an element in the top scope"; | 2364 throw "Cannot add an element in the top scope"; |
| 2245 } | 2365 } |
| 2246 } | 2366 } |
| OLD | NEW |