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

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

Issue 10661029: Ensure interfaces are loaded. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased 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 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « dart/lib/compiler/implementation/enqueue.dart ('k') | dart/lib/compiler/implementation/typechecker.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698