Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: dart/lib/compiler/implementation/resolver.dart

Issue 10855125: Ensure supertypes are loaded safely. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: More cleanup of ClassElement.cloneMembersTo Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698