| 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 18 matching lines...) Expand all Loading... |
| 29 Type getType(TypeAnnotation annotation) => types[annotation]; | 29 Type getType(TypeAnnotation annotation) => types[annotation]; |
| 30 | 30 |
| 31 void setSelector(Send send, Selector selector) { | 31 void setSelector(Send send, Selector selector) { |
| 32 selectors[send] = selector; | 32 selectors[send] = selector; |
| 33 } | 33 } |
| 34 | 34 |
| 35 Selector getSelector(Send send) => selectors[send]; | 35 Selector getSelector(Send send) => selectors[send]; |
| 36 } | 36 } |
| 37 | 37 |
| 38 class ResolverTask extends CompilerTask { | 38 class ResolverTask extends CompilerTask { |
| 39 Queue<ClassElement> toResolve; | |
| 40 | |
| 41 // Caches the elements of analyzed constructors to make them available | 39 // Caches the elements of analyzed constructors to make them available |
| 42 // for inlining in later tasks. | 40 // for inlining in later tasks. |
| 43 Map<FunctionElement, TreeElements> constructorElements; | 41 Map<FunctionElement, TreeElements> constructorElements; |
| 44 | 42 |
| 45 ResolverTask(Compiler compiler) | 43 ResolverTask(Compiler compiler) |
| 46 : super(compiler), toResolve = new Queue<ClassElement>(), | 44 : super(compiler), |
| 47 constructorElements = new Map<FunctionElement, TreeElements>(); | 45 constructorElements = new Map<FunctionElement, TreeElements>(); |
| 48 | 46 |
| 49 String get name() => 'Resolver'; | 47 String get name() => 'Resolver'; |
| 50 | 48 |
| 51 TreeElements resolve(Element element) { | 49 TreeElements resolve(Element element) { |
| 52 return measure(() { | 50 return measure(() { |
| 53 ElementKind kind = element.kind; | 51 ElementKind kind = element.kind; |
| 54 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR || | 52 if (kind === ElementKind.GENERATIVE_CONSTRUCTOR || |
| 55 kind === ElementKind.FUNCTION || | 53 kind === ElementKind.FUNCTION || |
| 56 kind === ElementKind.GETTER || | 54 kind === ElementKind.GETTER || |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 FunctionElement redirection = | 132 FunctionElement redirection = |
| 135 resolver.resolveInitializers(element, tree); | 133 resolver.resolveInitializers(element, tree); |
| 136 if (redirection !== null) { | 134 if (redirection !== null) { |
| 137 resolveRedirectingConstructor(resolver, tree, element, redirection); | 135 resolveRedirectingConstructor(resolver, tree, element, redirection); |
| 138 } | 136 } |
| 139 } else if (tree.initializers != null) { | 137 } else if (tree.initializers != null) { |
| 140 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); | 138 error(tree, MessageKind.FUNCTION_WITH_INITIALIZER); |
| 141 } | 139 } |
| 142 visitBody(visitor, tree.body); | 140 visitBody(visitor, tree.body); |
| 143 | 141 |
| 144 // Resolve the type annotations encountered in the method. | |
| 145 while (!toResolve.isEmpty()) { | |
| 146 ClassElement classElement = toResolve.removeFirst(); | |
| 147 classElement.ensureResolved(compiler); | |
| 148 } | |
| 149 if (isConstructor) { | 142 if (isConstructor) { |
| 150 constructorElements[element] = visitor.mapping; | 143 constructorElements[element] = visitor.mapping; |
| 151 } | 144 } |
| 152 return visitor.mapping; | 145 return visitor.mapping; |
| 153 }); | 146 }); |
| 154 } | 147 } |
| 155 | 148 |
| 156 void visitBody(ResolverVisitor visitor, Statement body) { | 149 void visitBody(ResolverVisitor visitor, Statement body) { |
| 157 visitor.visit(body); | 150 visitor.visit(body); |
| 158 } | 151 } |
| 159 | 152 |
| 160 void resolveConstructorImplementation(FunctionElement constructor, | 153 void resolveConstructorImplementation(FunctionElement constructor, |
| 161 FunctionExpression node) { | 154 FunctionExpression node) { |
| 162 if (constructor.defaultImplementation !== constructor) return; | 155 if (constructor.defaultImplementation !== constructor) return; |
| 163 ClassElement intrface = constructor.getEnclosingClass(); | 156 ClassElement intrface = constructor.getEnclosingClass(); |
| 164 if (!intrface.isInterface()) return; | 157 if (!intrface.isInterface()) return; |
| 165 Type defaultType = intrface.defaultClass; | 158 Type defaultType = intrface.defaultClass; |
| 166 if (defaultType === null) { | 159 if (defaultType === null) { |
| 167 error(node, MessageKind.NO_DEFAULT_CLASS, [intrface.name]); | 160 error(node, MessageKind.NO_DEFAULT_CLASS, [intrface.name]); |
| 168 } | 161 } |
| 169 ClassElement defaultClass = defaultType.element; | 162 ClassElement defaultClass = defaultType.element; |
| 170 defaultClass.ensureResolved(compiler); | 163 defaultClass.ensureResolved(compiler); |
| 164 assert(defaultClass.resolutionState == ClassElement.STATE_DONE); |
| 165 assert(defaultClass.supertypeLoadState == ClassElement.STATE_DONE); |
| 171 if (defaultClass.isInterface()) { | 166 if (defaultClass.isInterface()) { |
| 172 error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE, | 167 error(node, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 173 [defaultClass.name]); | 168 [defaultClass.name]); |
| 174 } | 169 } |
| 175 // We have now established the following: | 170 // We have now established the following: |
| 176 // [intrface] is an interface, let's say "MyInterface". | 171 // [intrface] is an interface, let's say "MyInterface". |
| 177 // [defaultClass] is a class, let's say "MyClass". | 172 // [defaultClass] is a class, let's say "MyClass". |
| 178 | 173 |
| 179 // If the default class implements the interface then we must use the | 174 // If the default class implements the interface then we must use the |
| 180 // default class' name. Otherwise we look for a factory with the name | 175 // default class' name. Otherwise we look for a factory with the name |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 if (annotation === null) return compiler.types.dynamicType; | 213 if (annotation === null) return compiler.types.dynamicType; |
| 219 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | 214 ResolverVisitor visitor = new ResolverVisitor(compiler, element); |
| 220 Type result = visitor.resolveTypeAnnotation(annotation); | 215 Type result = visitor.resolveTypeAnnotation(annotation); |
| 221 if (result === null) { | 216 if (result === null) { |
| 222 // TODO(karklose): warning. | 217 // TODO(karklose): warning. |
| 223 return compiler.types.dynamicType; | 218 return compiler.types.dynamicType; |
| 224 } | 219 } |
| 225 return result; | 220 return result; |
| 226 } | 221 } |
| 227 | 222 |
| 223 /** |
| 224 * Load and resolve the supertypes of [cls]. |
| 225 * |
| 226 * Warning: do not call this method directly. It should only be |
| 227 * called by [resolveClass] and [ClassSupertypeResolver]. |
| 228 */ |
| 229 void loadSupertypes(ClassElement cls, Node from) { |
| 230 compiler.withCurrentElement(cls, () => measure(() { |
| 231 if (cls.supertypeLoadState == ClassElement.STATE_DONE) return; |
| 232 if (cls.supertypeLoadState == ClassElement.STATE_STARTED) { |
| 233 compiler.reportMessage( |
| 234 compiler.spanFromNode(from), |
| 235 MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]), |
| 236 api.Diagnostic.ERROR); |
| 237 cls.supertypeLoadState = ClassElement.STATE_DONE; |
| 238 cls.allSupertypes = const EmptyLink<Type>().prepend( |
| 239 compiler.objectClass.computeType(compiler)); |
| 240 return; |
| 241 } |
| 242 cls.supertypeLoadState = ClassElement.STATE_STARTED; |
| 243 compiler.withCurrentElement(cls, () { |
| 244 // TODO(ahe): Cache the node in cls. |
| 245 cls.parseNode(compiler).accept(new ClassSupertypeResolver(compiler, |
| 246 cls)); |
| 247 if (cls.supertypeLoadState != ClassElement.STATE_DONE) { |
| 248 cls.supertypeLoadState = ClassElement.STATE_DONE; |
| 249 } |
| 250 }); |
| 251 })); |
| 252 } |
| 253 |
| 254 /** |
| 255 * Resolve the class [element]. |
| 256 * |
| 257 * Before calling this method, [element] was constructed by the |
| 258 * scanner and most fields are null or empty. This method fills in |
| 259 * these fields and also ensure that the supertypes of [element] are |
| 260 * resolved. |
| 261 * |
| 262 * Warning: Do not call this method directly. Instead use |
| 263 * [:element.ensureResolved(compiler):]. |
| 264 */ |
| 228 void resolveClass(ClassElement element) { | 265 void resolveClass(ClassElement element) { |
| 229 if (element.isResolved || element.isBeingResolved) return; | 266 assert(element.resolutionState == ClassElement.STATE_NOT_STARTED); |
| 230 element.isBeingResolved = true; | 267 element.resolutionState = ClassElement.STATE_STARTED; |
| 231 measure(() { | 268 compiler.withCurrentElement(element, () => measure(() { |
| 232 ClassNode tree = element.parseNode(compiler); | 269 ClassNode tree = element.parseNode(compiler); |
| 270 loadSupertypes(element, tree); |
| 271 |
| 233 ClassResolverVisitor visitor = | 272 ClassResolverVisitor visitor = |
| 234 new ClassResolverVisitor(compiler, element); | 273 new ClassResolverVisitor(compiler, element); |
| 235 visitor.visit(tree); | 274 visitor.visit(tree); |
| 236 element.isBeingResolved = false; | 275 element.resolutionState = ClassElement.STATE_DONE; |
| 237 element.isResolved = true; | 276 })); |
| 238 | |
| 239 while (!toResolve.isEmpty()) { | |
| 240 ClassElement classElement = toResolve.removeFirst(); | |
| 241 classElement.ensureResolved(compiler); | |
| 242 } | |
| 243 | |
| 244 checkMembers(element); | |
| 245 }); | |
| 246 } | 277 } |
| 247 | 278 |
| 248 checkMembers(ClassElement cls) { | 279 void checkMembers(ClassElement cls) { |
| 249 if (cls === compiler.objectClass) return; | 280 if (cls === compiler.objectClass) return; |
| 250 cls.forEachMember((holder, member) { | 281 cls.forEachMember((holder, member) { |
| 251 checkAbstractField(member); | 282 checkAbstractField(member); |
| 252 checkValidOverride(member, cls.lookupSuperMember(member.name)); | 283 checkValidOverride(member, cls.lookupSuperMember(member.name)); |
| 253 }); | 284 }); |
| 254 } | 285 } |
| 255 | 286 |
| 256 void checkAbstractField(Element member) { | 287 void checkAbstractField(Element member) { |
| 257 if (member is !AbstractFieldElement) return; | 288 if (member is !AbstractFieldElement) return; |
| 258 if (member.getter === null) return; | 289 if (member.getter === null) return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 281 compiler.spanFromElement(errorneousElement), | 312 compiler.spanFromElement(errorneousElement), |
| 282 errorMessage.error([contextElement.name, | 313 errorMessage.error([contextElement.name, |
| 283 contextElement.getEnclosingClass().name]), | 314 contextElement.getEnclosingClass().name]), |
| 284 api.Diagnostic.ERROR); | 315 api.Diagnostic.ERROR); |
| 285 compiler.reportMessage( | 316 compiler.reportMessage( |
| 286 compiler.spanFromElement(contextElement), | 317 compiler.spanFromElement(contextElement), |
| 287 contextMessage.error(), | 318 contextMessage.error(), |
| 288 api.Diagnostic.INFO); | 319 api.Diagnostic.INFO); |
| 289 } | 320 } |
| 290 | 321 |
| 291 | |
| 292 void checkValidOverride(Element member, Element superMember) { | 322 void checkValidOverride(Element member, Element superMember) { |
| 293 if (superMember === null) return; | 323 if (superMember === null) return; |
| 294 if (member.modifiers.isStatic()) { | 324 if (member.modifiers.isStatic()) { |
| 295 reportErrorWithContext( | 325 reportErrorWithContext( |
| 296 member, MessageKind.NO_STATIC_OVERRIDE, | 326 member, MessageKind.NO_STATIC_OVERRIDE, |
| 297 superMember, MessageKind.NO_STATIC_OVERRIDE_CONT); | 327 superMember, MessageKind.NO_STATIC_OVERRIDE_CONT); |
| 298 } else { | 328 } else { |
| 299 FunctionElement superFunction = superMember.asFunctionElement(); | 329 FunctionElement superFunction = superMember.asFunctionElement(); |
| 300 FunctionElement function = member.asFunctionElement(); | 330 FunctionElement function = member.asFunctionElement(); |
| 301 if (superFunction === null || superFunction.isAccessor()) { | 331 if (superFunction === null || superFunction.isAccessor()) { |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 return result; | 473 return result; |
| 444 } | 474 } |
| 445 | 475 |
| 446 void resolveImplicitSuperConstructorSend(FunctionElement constructor, | 476 void resolveImplicitSuperConstructorSend(FunctionElement constructor, |
| 447 FunctionExpression functionNode) { | 477 FunctionExpression functionNode) { |
| 448 // If the class has a super resolve the implicit super call. | 478 // If the class has a super resolve the implicit super call. |
| 449 ClassElement classElement = constructor.getEnclosingClass(); | 479 ClassElement classElement = constructor.getEnclosingClass(); |
| 450 ClassElement superClass = classElement.superclass; | 480 ClassElement superClass = classElement.superclass; |
| 451 if (classElement != visitor.compiler.objectClass) { | 481 if (classElement != visitor.compiler.objectClass) { |
| 452 assert(superClass !== null); | 482 assert(superClass !== null); |
| 453 assert(superClass.isResolved); | 483 assert(superClass.resolutionState == ClassElement.STATE_DONE); |
| 454 var element = resolveSuperOrThis(constructor, true, true, | 484 var element = resolveSuperOrThis(constructor, true, true, |
| 455 const SourceString(''), | 485 const SourceString(''), |
| 456 Selector.INVOCATION_0, functionNode); | 486 Selector.INVOCATION_0, functionNode); |
| 457 visitor.world.registerStaticUse(element); | 487 visitor.world.registerStaticUse(element); |
| 458 } | 488 } |
| 459 } | 489 } |
| 460 | 490 |
| 461 Element resolveSuperOrThis(FunctionElement constructor, | 491 Element resolveSuperOrThis(FunctionElement constructor, |
| 462 bool isSuperCall, | 492 bool isSuperCall, |
| 463 bool isImplicitSuperCall, | 493 bool isImplicitSuperCall, |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 if (element === null) { | 792 if (element === null) { |
| 763 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | 793 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); |
| 764 } else if (!element.impliesType()) { | 794 } else if (!element.impliesType()) { |
| 765 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); | 795 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); |
| 766 } else { | 796 } else { |
| 767 if (element === compiler.types.voidType.element || | 797 if (element === compiler.types.voidType.element || |
| 768 element === compiler.types.dynamicType.element) { | 798 element === compiler.types.dynamicType.element) { |
| 769 type = element.computeType(compiler); | 799 type = element.computeType(compiler); |
| 770 } else if (element.isClass()) { | 800 } else if (element.isClass()) { |
| 771 ClassElement cls = element; | 801 ClassElement cls = element; |
| 772 if (!cls.isResolved) compiler.resolveClass(cls); | 802 cls.ensureResolved(compiler); |
| 773 Link<Type> arguments = | 803 Link<Type> arguments = |
| 774 resolveTypeArguments(node, cls.typeVariables, scope, | 804 resolveTypeArguments(node, cls.typeVariables, scope, |
| 775 onFailure, whenResolved); | 805 onFailure, whenResolved); |
| 776 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) { | 806 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) { |
| 777 // Use the canonical type if it has no type parameters. | 807 // Use the canonical type if it has no type parameters. |
| 778 type = cls.computeType(compiler); | 808 type = cls.computeType(compiler); |
| 779 } else { | 809 } else { |
| 780 type = new InterfaceType(cls, arguments); | 810 type = new InterfaceType(cls, arguments); |
| 781 } | 811 } |
| 782 } else if (element.isTypedef()) { | 812 } else if (element.isTypedef()) { |
| (...skipping 928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 } else { | 1741 } else { |
| 1712 variableElement.bound = compiler.objectClass.computeType(compiler); | 1742 variableElement.bound = compiler.objectClass.computeType(compiler); |
| 1713 } | 1743 } |
| 1714 nodeLink = nodeLink.tail; | 1744 nodeLink = nodeLink.tail; |
| 1715 typeLink = typeLink.tail; | 1745 typeLink = typeLink.tail; |
| 1716 } | 1746 } |
| 1717 assert(typeLink.isEmpty()); | 1747 assert(typeLink.isEmpty()); |
| 1718 } | 1748 } |
| 1719 } | 1749 } |
| 1720 | 1750 |
| 1751 /** |
| 1752 * The implementation of [ResolverTask.resolveClass]. |
| 1753 * |
| 1754 * This visitor has to be extra careful as it is building the basic |
| 1755 * element information, and cannot safely look at other elements as |
| 1756 * this may lead to cycles. |
| 1757 * |
| 1758 * This visitor can assume that the supertypes have already been |
| 1759 * resolved, but it cannot call [ResolverTask.resolveClass] directly |
| 1760 * or indirectly (through [ClassElement.ensureResolved]) for any other |
| 1761 * types. |
| 1762 */ |
| 1721 class ClassResolverVisitor extends TypeDefinitionVisitor { | 1763 class ClassResolverVisitor extends TypeDefinitionVisitor { |
| 1722 ClassElement get element() => super.element; | 1764 ClassElement get element() => super.element; |
| 1723 | 1765 |
| 1724 ClassResolverVisitor(Compiler compiler, ClassElement classElement) | 1766 ClassResolverVisitor(Compiler compiler, ClassElement classElement) |
| 1725 : super(compiler, classElement); | 1767 : super(compiler, classElement); |
| 1726 | 1768 |
| 1727 Type visitClassNode(ClassNode node) { | 1769 Type visitClassNode(ClassNode node) { |
| 1728 compiler.ensure(element !== null); | 1770 compiler.ensure(element !== null); |
| 1729 compiler.ensure(!element.isResolved); | 1771 compiler.ensure(element.resolutionState == ClassElement.STATE_STARTED); |
| 1730 | 1772 |
| 1731 InterfaceType type = element.computeType(compiler); | 1773 InterfaceType type = element.computeType(compiler); |
| 1732 scope = new TypeDeclarationScope(scope, element); | 1774 scope = new TypeDeclarationScope(scope, element); |
| 1733 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. | 1775 // TODO(ahe): It is not safe to call resolveTypeVariableBounds yet. |
| 1734 // As a side-effect, this may get us back here trying to | 1776 // As a side-effect, this may get us back here trying to |
| 1735 // resolve this class again. | 1777 // resolve this class again. |
| 1736 resolveTypeVariableBounds(node.typeParameters); | 1778 resolveTypeVariableBounds(node.typeParameters); |
| 1737 | 1779 |
| 1738 // Find super type. | 1780 // Find super type. |
| 1739 Type supertype = visit(node.superclass); | 1781 Type supertype = visit(node.superclass); |
| 1740 if (supertype !== null && supertype.element.isExtendable()) { | 1782 if (supertype !== null && supertype.element.isExtendable()) { |
| 1741 element.supertype = supertype; | 1783 element.supertype = supertype; |
| 1742 if (isBlackListed(supertype)) { | 1784 if (isBlackListed(supertype)) { |
| 1743 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); | 1785 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); |
| 1744 } | 1786 } |
| 1745 } else if (supertype !== null) { | 1787 } else if (supertype !== null) { |
| 1746 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); | 1788 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); |
| 1747 } | 1789 } |
| 1748 final objectElement = compiler.objectClass; | 1790 final objectElement = compiler.objectClass; |
| 1749 if (element !== objectElement && element.supertype === null) { | 1791 if (element !== objectElement && element.supertype === null) { |
| 1750 if (objectElement === null) { | 1792 if (objectElement === null) { |
| 1751 compiler.internalError("Internal error: cannot resolve Object", | 1793 compiler.internalError("Internal error: cannot resolve Object", |
| 1752 node: node); | 1794 node: node); |
| 1753 } else if (!objectElement.isResolved) { | 1795 } else { |
| 1754 compiler.resolver.toResolve.add(objectElement); | 1796 objectElement.ensureResolved(compiler); |
| 1755 } | 1797 } |
| 1756 // TODO(ahe): This should be objectElement.computeType(...). | 1798 // TODO(ahe): This should be objectElement.computeType(...). |
| 1757 element.supertype = new InterfaceType(objectElement); | 1799 element.supertype = new InterfaceType(objectElement); |
| 1758 } | 1800 } |
| 1759 if (node.defaultClause !== null) { | 1801 assert(element.interfaces === null); |
| 1760 element.defaultClass = visit(node.defaultClause); | 1802 Link<Type> interfaces = const EmptyLink<Type>(); |
| 1761 } | |
| 1762 for (Link<Node> link = node.interfaces.nodes; | 1803 for (Link<Node> link = node.interfaces.nodes; |
| 1763 !link.isEmpty(); | 1804 !link.isEmpty(); |
| 1764 link = link.tail) { | 1805 link = link.tail) { |
| 1765 Type interfaceType = visit(link.head); | 1806 Type interfaceType = visit(link.head); |
| 1766 if (interfaceType !== null && interfaceType.element.isExtendable()) { | 1807 if (interfaceType !== null && interfaceType.element.isExtendable()) { |
| 1767 element.interfaces = | 1808 interfaces = interfaces.prepend(interfaceType); |
| 1768 element.interfaces.prepend(interfaceType); | |
| 1769 if (isBlackListed(interfaceType)) { | 1809 if (isBlackListed(interfaceType)) { |
| 1770 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); | 1810 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); |
| 1771 } | 1811 } |
| 1772 } else { | 1812 } else { |
| 1773 error(link.head, MessageKind.TYPE_NAME_EXPECTED); | 1813 error(link.head, MessageKind.TYPE_NAME_EXPECTED); |
| 1774 } | 1814 } |
| 1775 } | 1815 } |
| 1776 calculateAllSupertypes(element, new Set<ClassElement>()); | 1816 element.interfaces = interfaces; |
| 1817 calculateAllSupertypes(element); |
| 1818 |
| 1819 if (node.defaultClause !== null) { |
| 1820 element.defaultClass = visit(node.defaultClause); |
| 1821 } |
| 1777 addDefaultConstructorIfNeeded(element); | 1822 addDefaultConstructorIfNeeded(element); |
| 1778 return element.computeType(compiler); | 1823 return element.computeType(compiler); |
| 1779 } | 1824 } |
| 1780 | 1825 |
| 1781 Type visitTypeAnnotation(TypeAnnotation node) { | 1826 Type visitTypeAnnotation(TypeAnnotation node) { |
| 1782 return visit(node.typeName); | 1827 return visit(node.typeName); |
| 1783 } | 1828 } |
| 1784 | 1829 |
| 1785 Type visitIdentifier(Identifier node) { | 1830 Type visitIdentifier(Identifier node) { |
| 1786 Element element = scope.lookup(node.source); | 1831 Element element = scope.lookup(node.source); |
| 1787 if (element === null) { | 1832 if (element === null) { |
| 1788 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | 1833 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
| 1789 return null; | 1834 return null; |
| 1790 } else if (!element.impliesType() && !element.isTypeVariable()) { | 1835 } else if (!element.impliesType() && !element.isTypeVariable()) { |
| 1791 error(node, MessageKind.NOT_A_TYPE, [node]); | 1836 error(node, MessageKind.NOT_A_TYPE, [node]); |
| 1792 return null; | 1837 return null; |
| 1793 } else { | 1838 } else { |
| 1794 if (element.isClass()) { | |
| 1795 compiler.resolver.toResolve.add(element); | |
| 1796 } | |
| 1797 if (element.isTypeVariable()) { | 1839 if (element.isTypeVariable()) { |
| 1798 TypeVariableElement variableElement = element; | 1840 TypeVariableElement variableElement = element; |
| 1799 return variableElement.type; | 1841 return variableElement.type; |
| 1800 } else if (element.isTypedef()) { | 1842 } else if (element.isTypedef()) { |
| 1801 compiler.unimplemented('visitIdentifier for typedefs', node: node); | 1843 compiler.unimplemented('visitIdentifier for typedefs', node: node); |
| 1802 } else { | 1844 } else { |
| 1803 // TODO(ngeoffray): Use type variables. | 1845 // TODO(ngeoffray): Use type variables. |
| 1804 return element.computeType(compiler); | 1846 return element.computeType(compiler); |
| 1805 } | 1847 } |
| 1806 } | 1848 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1821 PrefixElement prefixElement = element; | 1863 PrefixElement prefixElement = element; |
| 1822 Identifier selector = node.selector.asIdentifier(); | 1864 Identifier selector = node.selector.asIdentifier(); |
| 1823 var e = prefixElement.lookupLocalMember(selector.source); | 1865 var e = prefixElement.lookupLocalMember(selector.source); |
| 1824 if (e === null || !e.impliesType()) { | 1866 if (e === null || !e.impliesType()) { |
| 1825 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); | 1867 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); |
| 1826 return null; | 1868 return null; |
| 1827 } | 1869 } |
| 1828 return e.computeType(compiler); | 1870 return e.computeType(compiler); |
| 1829 } | 1871 } |
| 1830 | 1872 |
| 1831 Link<Type> getOrCalculateAllSupertypes(ClassElement cls, | 1873 void calculateAllSupertypes(ClassElement cls) { |
| 1832 [Set<ClassElement> seen]) { | |
| 1833 Link<Type> allSupertypes = cls.allSupertypes; | |
| 1834 if (allSupertypes !== null) return allSupertypes; | |
| 1835 if (seen === null) { | |
| 1836 seen = new Set<ClassElement>(); | |
| 1837 } | |
| 1838 if (seen.contains(cls)) { | |
| 1839 error(cls.parseNode(compiler), | |
| 1840 MessageKind.CYCLIC_CLASS_HIERARCHY, | |
| 1841 [cls.name]); | |
| 1842 cls.allSupertypes = const EmptyLink<Type>(); | |
| 1843 } else { | |
| 1844 cls.ensureResolved(compiler); | |
| 1845 calculateAllSupertypes(cls, seen); | |
| 1846 } | |
| 1847 return cls.allSupertypes; | |
| 1848 } | |
| 1849 | |
| 1850 void calculateAllSupertypes(ClassElement cls, Set<ClassElement> seen) { | |
| 1851 // TODO(karlklose): substitute type variables. | 1874 // TODO(karlklose): substitute type variables. |
| 1852 // TODO(karlklose): check if type arguments match, if a classelement occurs | 1875 // TODO(karlklose): check if type arguments match, if a classelement occurs |
| 1853 // more than once in the supertypes. | 1876 // more than once in the supertypes. |
| 1854 if (cls.allSupertypes !== null) return; | 1877 if (cls.allSupertypes !== null) return; |
| 1855 final Type supertype = cls.supertype; | 1878 final Type supertype = cls.supertype; |
| 1856 if (seen.contains(cls)) { | 1879 if (supertype != null) { |
| 1857 error(cls.parseNode(compiler), | 1880 Link<Type> superSupertypes = supertype.element.allSupertypes; |
| 1858 MessageKind.CYCLIC_CLASS_HIERARCHY, | 1881 assert(superSupertypes !== null); |
| 1859 [cls.name]); | |
| 1860 cls.allSupertypes = const EmptyLink<Type>(); | |
| 1861 } else if (supertype != null) { | |
| 1862 seen.add(cls); | |
| 1863 Link<Type> superSupertypes = | |
| 1864 getOrCalculateAllSupertypes(supertype.element, seen); | |
| 1865 Link<Type> supertypes = new Link<Type>(supertype, superSupertypes); | 1882 Link<Type> supertypes = new Link<Type>(supertype, superSupertypes); |
| 1866 for (Link<Type> interfaces = cls.interfaces; | 1883 for (Link<Type> interfaces = cls.interfaces; |
| 1867 !interfaces.isEmpty(); | 1884 !interfaces.isEmpty(); |
| 1868 interfaces = interfaces.tail) { | 1885 interfaces = interfaces.tail) { |
| 1869 Element element = interfaces.head.element; | 1886 Element element = interfaces.head.element; |
| 1870 Link<Type> interfaceSupertypes = | 1887 Link<Type> interfaceSupertypes = element.allSupertypes; |
| 1871 getOrCalculateAllSupertypes(element, seen); | 1888 assert(interfaceSupertypes !== null); |
| 1872 supertypes = supertypes.reversePrependAll(interfaceSupertypes); | 1889 supertypes = supertypes.reversePrependAll(interfaceSupertypes); |
| 1873 supertypes = supertypes.prepend(interfaces.head); | 1890 supertypes = supertypes.prepend(interfaces.head); |
| 1874 } | 1891 } |
| 1875 seen.remove(cls); | |
| 1876 cls.allSupertypes = supertypes; | 1892 cls.allSupertypes = supertypes; |
| 1877 } else { | 1893 } else { |
| 1894 assert(cls === compiler.objectClass); |
| 1878 cls.allSupertypes = const EmptyLink<Type>(); | 1895 cls.allSupertypes = const EmptyLink<Type>(); |
| 1879 } | 1896 } |
| 1880 } | 1897 } |
| 1881 | 1898 |
| 1882 /** | 1899 /** |
| 1883 * Add a synthetic nullary constructor if there are no other | 1900 * Add a synthetic nullary constructor if there are no other |
| 1884 * constructors. | 1901 * constructors. |
| 1885 */ | 1902 */ |
| 1886 void addDefaultConstructorIfNeeded(ClassElement element) { | 1903 void addDefaultConstructorIfNeeded(ClassElement element) { |
| 1887 if (element.constructors.length != 0) return; | 1904 if (element.constructors.length != 0) return; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1908 type.element === compiler.boolClass || | 1925 type.element === compiler.boolClass || |
| 1909 type.element === compiler.numClass || | 1926 type.element === compiler.numClass || |
| 1910 type.element === compiler.intClass || | 1927 type.element === compiler.intClass || |
| 1911 type.element === compiler.doubleClass || | 1928 type.element === compiler.doubleClass || |
| 1912 type.element === compiler.stringClass || | 1929 type.element === compiler.stringClass || |
| 1913 type.element === compiler.nullClass || | 1930 type.element === compiler.nullClass || |
| 1914 type.element === compiler.functionClass); | 1931 type.element === compiler.functionClass); |
| 1915 } | 1932 } |
| 1916 } | 1933 } |
| 1917 | 1934 |
| 1935 class ClassSupertypeResolver extends CommonResolverVisitor { |
| 1936 Scope context; |
| 1937 ClassElement classElement; |
| 1938 |
| 1939 ClassSupertypeResolver(Compiler compiler, ClassElement cls) |
| 1940 : context = new TopScope(cls.getLibrary()), |
| 1941 this.classElement = cls, |
| 1942 super(compiler); |
| 1943 |
| 1944 void loadSupertype(ClassElement element, Node from) { |
| 1945 compiler.resolver.loadSupertypes(element, from); |
| 1946 element.ensureResolved(compiler); |
| 1947 } |
| 1948 |
| 1949 void visitClassNode(ClassNode node) { |
| 1950 if (node.superclass === null) { |
| 1951 if (classElement !== compiler.objectClass) { |
| 1952 loadSupertype(compiler.objectClass, node); |
| 1953 } |
| 1954 } else { |
| 1955 node.superclass.accept(this); |
| 1956 } |
| 1957 for (Link<Node> link = node.interfaces.nodes; |
| 1958 !link.isEmpty(); |
| 1959 link = link.tail) { |
| 1960 link.head.accept(this); |
| 1961 } |
| 1962 } |
| 1963 |
| 1964 void visitTypeAnnotation(TypeAnnotation node) { |
| 1965 node.typeName.accept(this); |
| 1966 } |
| 1967 |
| 1968 void visitIdentifier(Identifier node) { |
| 1969 Element element = context.lookup(node.source); |
| 1970 if (element === null) { |
| 1971 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
| 1972 } else if (!element.impliesType()) { |
| 1973 error(node, MessageKind.NOT_A_TYPE, [node]); |
| 1974 } else { |
| 1975 if (element.isClass()) { |
| 1976 loadSupertype(element, node); |
| 1977 } else { |
| 1978 compiler.reportMessage( |
| 1979 compiler.spanFromNode(node), |
| 1980 MessageKind.TYPE_NAME_EXPECTED.error([]), |
| 1981 api.Diagnostic.ERROR); |
| 1982 } |
| 1983 } |
| 1984 } |
| 1985 |
| 1986 void visitSend(Send node) { |
| 1987 Identifier prefix = node.receiver.asIdentifier(); |
| 1988 if (prefix === null) { |
| 1989 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| 1990 return; |
| 1991 } |
| 1992 Element element = context.lookup(prefix.source); |
| 1993 if (element === null || element.kind !== ElementKind.PREFIX) { |
| 1994 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| 1995 return; |
| 1996 } |
| 1997 PrefixElement prefixElement = element; |
| 1998 Identifier selector = node.selector.asIdentifier(); |
| 1999 var e = prefixElement.lookupLocalMember(selector.source); |
| 2000 if (e === null || !e.impliesType()) { |
| 2001 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); |
| 2002 return; |
| 2003 } |
| 2004 loadSupertype(e, node); |
| 2005 } |
| 2006 } |
| 2007 |
| 1918 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { | 2008 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { |
| 1919 VariableDefinitions definitions; | 2009 VariableDefinitions definitions; |
| 1920 ResolverVisitor resolver; | 2010 ResolverVisitor resolver; |
| 1921 ElementKind kind; | 2011 ElementKind kind; |
| 1922 VariableListElement variables; | 2012 VariableListElement variables; |
| 1923 | 2013 |
| 1924 VariableDefinitionsVisitor(Compiler compiler, | 2014 VariableDefinitionsVisitor(Compiler compiler, |
| 1925 this.definitions, this.resolver, this.kind) | 2015 this.definitions, this.resolver, this.kind) |
| 1926 : super(compiler) { | 2016 : super(compiler) { |
| 1927 variables = new VariableListElement.node( | 2017 variables = new VariableListElement.node( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2121 visitNode(Node node) { | 2211 visitNode(Node node) { |
| 2122 throw 'not supported'; | 2212 throw 'not supported'; |
| 2123 } | 2213 } |
| 2124 | 2214 |
| 2125 visitNewExpression(NewExpression node) { | 2215 visitNewExpression(NewExpression node) { |
| 2126 Node selector = node.send.selector; | 2216 Node selector = node.send.selector; |
| 2127 Element e = visit(selector); | 2217 Element e = visit(selector); |
| 2128 if (e !== null && e.kind === ElementKind.CLASS) { | 2218 if (e !== null && e.kind === ElementKind.CLASS) { |
| 2129 ClassElement cls = e; | 2219 ClassElement cls = e; |
| 2130 cls.ensureResolved(compiler); | 2220 cls.ensureResolved(compiler); |
| 2131 compiler.resolver.toResolve.add(cls); | |
| 2132 if (cls.isInterface() && (cls.defaultClass === null)) { | 2221 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 2133 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); | 2222 error(selector, MessageKind.CANNOT_INSTANTIATE_INTERFACE, [cls.name]); |
| 2134 } | 2223 } |
| 2135 e = cls.lookupConstructor(cls.name); | 2224 e = cls.lookupConstructor(cls.name); |
| 2136 } | 2225 } |
| 2137 return e; | 2226 return e; |
| 2138 } | 2227 } |
| 2139 | 2228 |
| 2140 visitTypeAnnotation(TypeAnnotation node) { | 2229 visitTypeAnnotation(TypeAnnotation node) { |
| 2141 // TODO(ahe): Do not ignore type arguments. | 2230 // TODO(ahe): Do not ignore type arguments. |
| 2142 return visit(node.typeName); | 2231 return visit(node.typeName); |
| 2143 } | 2232 } |
| 2144 | 2233 |
| 2145 visitSend(Send node) { | 2234 visitSend(Send node) { |
| 2146 Element e = visit(node.receiver); | 2235 Element e = visit(node.receiver); |
| 2147 if (e === null) return null; // TODO(ahe): Return erroneous element. | 2236 if (e === null) return null; // TODO(ahe): Return erroneous element. |
| 2148 | 2237 |
| 2149 Identifier name = node.selector.asIdentifier(); | 2238 Identifier name = node.selector.asIdentifier(); |
| 2150 if (name === null) internalError(node.selector, 'unexpected node'); | 2239 if (name === null) internalError(node.selector, 'unexpected node'); |
| 2151 | 2240 |
| 2152 if (e.kind === ElementKind.CLASS) { | 2241 if (e.kind === ElementKind.CLASS) { |
| 2153 ClassElement cls = e; | 2242 ClassElement cls = e; |
| 2154 cls.ensureResolved(compiler); | 2243 cls.ensureResolved(compiler); |
| 2155 compiler.resolver.toResolve.add(cls); | |
| 2156 if (cls.isInterface() && (cls.defaultClass === null)) { | 2244 if (cls.isInterface() && (cls.defaultClass === null)) { |
| 2157 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, | 2245 error(node.receiver, MessageKind.CANNOT_INSTANTIATE_INTERFACE, |
| 2158 [cls.name]); | 2246 [cls.name]); |
| 2159 } | 2247 } |
| 2160 SourceString constructorName = | 2248 SourceString constructorName = |
| 2161 Elements.constructConstructorName(cls.name, name.source); | 2249 Elements.constructConstructorName(cls.name, name.source); |
| 2162 FunctionElement constructor = cls.lookupConstructor(constructorName); | 2250 FunctionElement constructor = cls.lookupConstructor(constructorName); |
| 2163 if (constructor === null) { | 2251 if (constructor === null) { |
| 2164 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]); | 2252 error(name, MessageKind.CANNOT_FIND_CONSTRUCTOR, [name]); |
| 2165 } | 2253 } |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2309 TopScope(LibraryElement library) : super(null, library); | 2397 TopScope(LibraryElement library) : super(null, library); |
| 2310 Element lookup(SourceString name) { | 2398 Element lookup(SourceString name) { |
| 2311 return library.find(name); | 2399 return library.find(name); |
| 2312 } | 2400 } |
| 2313 | 2401 |
| 2314 Element add(Element newElement) { | 2402 Element add(Element newElement) { |
| 2315 throw "Cannot add an element in the top scope"; | 2403 throw "Cannot add an element in the top scope"; |
| 2316 } | 2404 } |
| 2317 String toString() => '$element'; | 2405 String toString() => '$element'; |
| 2318 } | 2406 } |
| OLD | NEW |