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 |