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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 if (annotation === null) return compiler.types.dynamicType; | 218 if (annotation === null) return compiler.types.dynamicType; |
219 ResolverVisitor visitor = new ResolverVisitor(compiler, element); | 219 ResolverVisitor visitor = new ResolverVisitor(compiler, element); |
220 Type result = visitor.resolveTypeAnnotation(annotation); | 220 Type result = visitor.resolveTypeAnnotation(annotation); |
221 if (result === null) { | 221 if (result === null) { |
222 // TODO(karklose): warning. | 222 // TODO(karklose): warning. |
223 return compiler.types.dynamicType; | 223 return compiler.types.dynamicType; |
224 } | 224 } |
225 return result; | 225 return result; |
226 } | 226 } |
227 | 227 |
228 void loadSupertypes(ClassElement cls, Node from) { | |
229 compiler.withCurrentElement(cls, () => measure(() { | |
230 if (cls.supertypesAreLoaded) return; | |
231 if (cls.isLoadingSupertypes) { | |
232 compiler.reportMessage( | |
233 compiler.spanFromNode(from), | |
234 MessageKind.CYCLIC_CLASS_HIERARCHY.error([cls.name]), | |
235 api.Diagnostic.ERROR); | |
236 cls.allSupertypes = const EmptyLink<Type>().prepend( | |
237 compiler.objectClass.computeType(compiler)); | |
238 return; | |
239 } | |
240 cls.isLoadingSupertypes = true; | |
241 compiler.withCurrentElement(cls, () { | |
242 // TODO(ahe): Cache the node in cls. | |
243 cls.parseNode(compiler).accept(new ClassSupertypeResolver(compiler, | |
244 cls)); | |
245 }); | |
246 cls.isLoadingSupertypes = false; | |
247 cls.supertypesAreLoaded = true; | |
248 toResolve.add(cls); | |
249 })); | |
250 } | |
251 | |
252 /** | |
253 * Do not call this method directly. Instead use | |
254 * [:element.ensureResolved(compiler):]. | |
255 */ | |
228 void resolveClass(ClassElement element) { | 256 void resolveClass(ClassElement element) { |
229 if (element.isResolved || element.isBeingResolved) return; | 257 compiler.withCurrentElement(element, () => measure(() { |
230 element.isBeingResolved = true; | 258 assert(element.isBeingResolved && !element.isResolved); |
231 measure(() { | 259 loadSupertypes(element, null); |
232 ClassNode tree = element.parseNode(compiler); | 260 ClassNode tree = element.parseNode(compiler); |
261 | |
233 ClassResolverVisitor visitor = | 262 ClassResolverVisitor visitor = |
234 new ClassResolverVisitor(compiler, element); | 263 new ClassResolverVisitor(compiler, element); |
235 visitor.visit(tree); | 264 visitor.visit(tree); |
236 element.isBeingResolved = false; | 265 element.isBeingResolved = false; |
237 element.isResolved = true; | 266 element.isResolved = true; |
238 | 267 |
239 while (!toResolve.isEmpty()) { | 268 while (!toResolve.isEmpty()) { |
240 ClassElement classElement = toResolve.removeFirst(); | 269 ClassElement classElement = toResolve.removeFirst(); |
241 classElement.ensureResolved(compiler); | 270 classElement.ensureResolved(compiler); |
242 } | 271 } |
243 | 272 |
244 checkMembers(element); | 273 checkMembers(element); |
245 }); | 274 })); |
246 } | 275 } |
247 | 276 |
248 checkMembers(ClassElement cls) { | 277 checkMembers(ClassElement cls) { |
249 if (cls === compiler.objectClass) return; | 278 if (cls === compiler.objectClass) return; |
250 cls.forEachMember((holder, member) { | 279 cls.forEachMember((holder, member) { |
251 checkAbstractField(member); | 280 checkAbstractField(member); |
252 checkValidOverride(member, cls.lookupSuperMember(member.name)); | 281 checkValidOverride(member, cls.lookupSuperMember(member.name)); |
253 }); | 282 }); |
254 } | 283 } |
255 | 284 |
(...skipping 25 matching lines...) Expand all Loading... | |
281 compiler.spanFromElement(errorneousElement), | 310 compiler.spanFromElement(errorneousElement), |
282 errorMessage.error([contextElement.name, | 311 errorMessage.error([contextElement.name, |
283 contextElement.getEnclosingClass().name]), | 312 contextElement.getEnclosingClass().name]), |
284 api.Diagnostic.ERROR); | 313 api.Diagnostic.ERROR); |
285 compiler.reportMessage( | 314 compiler.reportMessage( |
286 compiler.spanFromElement(contextElement), | 315 compiler.spanFromElement(contextElement), |
287 contextMessage.error(), | 316 contextMessage.error(), |
288 api.Diagnostic.INFO); | 317 api.Diagnostic.INFO); |
289 } | 318 } |
290 | 319 |
291 | |
292 void checkValidOverride(Element member, Element superMember) { | 320 void checkValidOverride(Element member, Element superMember) { |
293 if (superMember === null) return; | 321 if (superMember === null) return; |
294 if (member.modifiers.isStatic()) { | 322 if (member.modifiers.isStatic()) { |
295 reportErrorWithContext( | 323 reportErrorWithContext( |
296 member, MessageKind.NO_STATIC_OVERRIDE, | 324 member, MessageKind.NO_STATIC_OVERRIDE, |
297 superMember, MessageKind.NO_STATIC_OVERRIDE_CONT); | 325 superMember, MessageKind.NO_STATIC_OVERRIDE_CONT); |
298 } else { | 326 } else { |
299 FunctionElement superFunction = superMember.asFunctionElement(); | 327 FunctionElement superFunction = superMember.asFunctionElement(); |
300 FunctionElement function = member.asFunctionElement(); | 328 FunctionElement function = member.asFunctionElement(); |
301 if (superFunction === null || superFunction.isAccessor()) { | 329 if (superFunction === null || superFunction.isAccessor()) { |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
762 if (element === null) { | 790 if (element === null) { |
763 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | 791 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); |
764 } else if (!element.impliesType()) { | 792 } else if (!element.impliesType()) { |
765 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); | 793 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); |
766 } else { | 794 } else { |
767 if (element === compiler.types.voidType.element || | 795 if (element === compiler.types.voidType.element || |
768 element === compiler.types.dynamicType.element) { | 796 element === compiler.types.dynamicType.element) { |
769 type = element.computeType(compiler); | 797 type = element.computeType(compiler); |
770 } else if (element.isClass()) { | 798 } else if (element.isClass()) { |
771 ClassElement cls = element; | 799 ClassElement cls = element; |
772 if (!cls.isResolved) compiler.resolveClass(cls); | 800 cls.ensureResolved(compiler); |
773 Link<Type> arguments = | 801 Link<Type> arguments = |
774 resolveTypeArguments(node, cls.typeVariables, scope, | 802 resolveTypeArguments(node, cls.typeVariables, scope, |
775 onFailure, whenResolved); | 803 onFailure, whenResolved); |
776 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) { | 804 if (cls.typeVariables.isEmpty() && arguments.isEmpty()) { |
777 // Use the canonical type if it has no type parameters. | 805 // Use the canonical type if it has no type parameters. |
778 type = cls.computeType(compiler); | 806 type = cls.computeType(compiler); |
779 } else { | 807 } else { |
780 type = new InterfaceType(cls, arguments); | 808 type = new InterfaceType(cls, arguments); |
781 } | 809 } |
782 } else if (element.isTypedef()) { | 810 } else if (element.isTypedef()) { |
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1899 type.element === compiler.boolClass || | 1927 type.element === compiler.boolClass || |
1900 type.element === compiler.numClass || | 1928 type.element === compiler.numClass || |
1901 type.element === compiler.intClass || | 1929 type.element === compiler.intClass || |
1902 type.element === compiler.doubleClass || | 1930 type.element === compiler.doubleClass || |
1903 type.element === compiler.stringClass || | 1931 type.element === compiler.stringClass || |
1904 type.element === compiler.nullClass || | 1932 type.element === compiler.nullClass || |
1905 type.element === compiler.functionClass); | 1933 type.element === compiler.functionClass); |
1906 } | 1934 } |
1907 } | 1935 } |
1908 | 1936 |
1937 class ClassSupertypeResolver extends CommonResolverVisitor { | |
1938 Scope context; | |
1939 ClassElement classElement; | |
1940 | |
1941 ClassSupertypeResolver(Compiler compiler, ClassElement cls) | |
1942 : context = new TopScope(cls.getLibrary()), | |
1943 this.classElement = cls, | |
1944 super(compiler); | |
1945 | |
1946 void visitClassNode(ClassNode node) { | |
1947 if (node.superclass === null) { | |
1948 // TODO(ahe): Handle this. | |
1949 } else { | |
1950 node.superclass.accept(this); | |
1951 } | |
1952 if (node.interfaces === null) { | |
1953 // TODO(ahe): Can this happen? | |
Lasse Reichstein Nielsen
2012/08/07 09:02:17
If it can, it should be fixed.
| |
1954 } else { | |
1955 node.interfaces.accept(this); | |
1956 } | |
1957 } | |
1958 | |
1959 void visitTypeAnnotation(TypeAnnotation node) { | |
1960 node.typeName.accept(this); | |
1961 } | |
1962 | |
1963 void visitIdentifier(Identifier node) { | |
1964 Element element = context.lookup(node.source); | |
1965 if (element === null) { | |
1966 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | |
1967 } else if (!element.impliesType()) { | |
1968 error(node, MessageKind.NOT_A_TYPE, [node]); | |
1969 } else { | |
1970 if (element.isClass()) { | |
1971 compiler.resolver.loadSupertypes(element, node); | |
1972 } else { | |
1973 compiler.reportMessage( | |
1974 compiler.spanFromNode(node), | |
1975 MessageKind.TYPE_NAME_EXPECTED.error([]), | |
1976 api.Diagnostic.ERROR); | |
1977 } | |
1978 } | |
1979 } | |
1980 | |
1981 void visitNodeList(NodeList node) { | |
1982 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | |
1983 visit(link.head); | |
1984 } | |
1985 } | |
1986 | |
1987 void visitSend(Send node) { | |
1988 Identifier prefix = node.receiver.asIdentifier(); | |
1989 if (prefix === null) { | |
1990 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | |
1991 return; | |
1992 } | |
1993 Element element = context.lookup(prefix.source); | |
1994 if (element === null || element.kind !== ElementKind.PREFIX) { | |
1995 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | |
1996 return; | |
1997 } | |
1998 PrefixElement prefixElement = element; | |
1999 Identifier selector = node.selector.asIdentifier(); | |
2000 var e = prefixElement.lookupLocalMember(selector.source); | |
2001 if (e === null || !e.impliesType()) { | |
2002 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); | |
2003 return; | |
2004 } | |
2005 compiler.resolver.loadSupertypes(e, node); | |
2006 } | |
2007 } | |
2008 | |
1909 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { | 2009 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { |
1910 VariableDefinitions definitions; | 2010 VariableDefinitions definitions; |
1911 ResolverVisitor resolver; | 2011 ResolverVisitor resolver; |
1912 ElementKind kind; | 2012 ElementKind kind; |
1913 VariableListElement variables; | 2013 VariableListElement variables; |
1914 | 2014 |
1915 VariableDefinitionsVisitor(Compiler compiler, | 2015 VariableDefinitionsVisitor(Compiler compiler, |
1916 this.definitions, this.resolver, this.kind) | 2016 this.definitions, this.resolver, this.kind) |
1917 : super(compiler) | 2017 : super(compiler) |
1918 { | 2018 { |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2301 TopScope(LibraryElement library) : super(null, library); | 2401 TopScope(LibraryElement library) : super(null, library); |
2302 Element lookup(SourceString name) { | 2402 Element lookup(SourceString name) { |
2303 return library.find(name); | 2403 return library.find(name); |
2304 } | 2404 } |
2305 | 2405 |
2306 Element add(Element newElement) { | 2406 Element add(Element newElement) { |
2307 throw "Cannot add an element in the top scope"; | 2407 throw "Cannot add an element in the top scope"; |
2308 } | 2408 } |
2309 String toString() => '$element'; | 2409 String toString() => '$element'; |
2310 } | 2410 } |
OLD | NEW |