Chromium Code Reviews| 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 |