| 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 | 
|---|