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 1118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1901 type.element === compiler.boolClass || | 1929 type.element === compiler.boolClass || |
1902 type.element === compiler.numClass || | 1930 type.element === compiler.numClass || |
1903 type.element === compiler.intClass || | 1931 type.element === compiler.intClass || |
1904 type.element === compiler.doubleClass || | 1932 type.element === compiler.doubleClass || |
1905 type.element === compiler.stringClass || | 1933 type.element === compiler.stringClass || |
1906 type.element === compiler.nullClass || | 1934 type.element === compiler.nullClass || |
1907 type.element === compiler.functionClass); | 1935 type.element === compiler.functionClass); |
1908 } | 1936 } |
1909 } | 1937 } |
1910 | 1938 |
| 1939 class ClassSupertypeResolver extends CommonResolverVisitor { |
| 1940 Scope context; |
| 1941 ClassElement classElement; |
| 1942 |
| 1943 ClassSupertypeResolver(Compiler compiler, ClassElement cls) |
| 1944 : context = new TopScope(cls.getLibrary()), |
| 1945 this.classElement = cls, |
| 1946 super(compiler); |
| 1947 |
| 1948 void visitClassNode(ClassNode node) { |
| 1949 if (node.superclass === null) { |
| 1950 // TODO(ahe): Handle this. |
| 1951 } else { |
| 1952 node.superclass.accept(this); |
| 1953 } |
| 1954 if (node.interfaces === null) { |
| 1955 // TODO(ahe): Can this happen? |
| 1956 } else { |
| 1957 node.interfaces.accept(this); |
| 1958 } |
| 1959 } |
| 1960 |
| 1961 void visitTypeAnnotation(TypeAnnotation node) { |
| 1962 node.typeName.accept(this); |
| 1963 } |
| 1964 |
| 1965 void visitIdentifier(Identifier node) { |
| 1966 Element element = context.lookup(node.source); |
| 1967 if (element === null) { |
| 1968 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); |
| 1969 } else if (!element.impliesType()) { |
| 1970 error(node, MessageKind.NOT_A_TYPE, [node]); |
| 1971 } else { |
| 1972 if (element.isClass()) { |
| 1973 compiler.resolver.loadSupertypes(element, node); |
| 1974 } else { |
| 1975 compiler.reportMessage( |
| 1976 compiler.spanFromNode(node), |
| 1977 MessageKind.TYPE_NAME_EXPECTED.error([]), |
| 1978 api.Diagnostic.ERROR); |
| 1979 } |
| 1980 } |
| 1981 } |
| 1982 |
| 1983 void visitNodeList(NodeList node) { |
| 1984 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { |
| 1985 visit(link.head); |
| 1986 } |
| 1987 } |
| 1988 |
| 1989 void visitSend(Send node) { |
| 1990 Identifier prefix = node.receiver.asIdentifier(); |
| 1991 if (prefix === null) { |
| 1992 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| 1993 return; |
| 1994 } |
| 1995 Element element = context.lookup(prefix.source); |
| 1996 if (element === null || element.kind !== ElementKind.PREFIX) { |
| 1997 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); |
| 1998 return; |
| 1999 } |
| 2000 PrefixElement prefixElement = element; |
| 2001 Identifier selector = node.selector.asIdentifier(); |
| 2002 var e = prefixElement.lookupLocalMember(selector.source); |
| 2003 if (e === null || !e.impliesType()) { |
| 2004 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); |
| 2005 return; |
| 2006 } |
| 2007 compiler.resolver.loadSupertypes(e, node); |
| 2008 } |
| 2009 } |
| 2010 |
1911 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { | 2011 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { |
1912 VariableDefinitions definitions; | 2012 VariableDefinitions definitions; |
1913 ResolverVisitor resolver; | 2013 ResolverVisitor resolver; |
1914 ElementKind kind; | 2014 ElementKind kind; |
1915 VariableListElement variables; | 2015 VariableListElement variables; |
1916 | 2016 |
1917 VariableDefinitionsVisitor(Compiler compiler, | 2017 VariableDefinitionsVisitor(Compiler compiler, |
1918 this.definitions, this.resolver, this.kind) | 2018 this.definitions, this.resolver, this.kind) |
1919 : super(compiler) | 2019 : super(compiler) |
1920 { | 2020 { |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2303 TopScope(LibraryElement library) : super(null, library); | 2403 TopScope(LibraryElement library) : super(null, library); |
2304 Element lookup(SourceString name) { | 2404 Element lookup(SourceString name) { |
2305 return library.find(name); | 2405 return library.find(name); |
2306 } | 2406 } |
2307 | 2407 |
2308 Element add(Element newElement) { | 2408 Element add(Element newElement) { |
2309 throw "Cannot add an element in the top scope"; | 2409 throw "Cannot add an element in the top scope"; |
2310 } | 2410 } |
2311 String toString() => '$element'; | 2411 String toString() => '$element'; |
2312 } | 2412 } |
OLD | NEW |