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

Side by Side Diff: frog/leg/resolver.dart

Issue 9166010: Implement super calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 8 years, 11 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
« no previous file with comments | « no previous file | frog/leg/ssa/builder.dart » ('j') | frog/leg/ssa/builder.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 class TreeElements { 5 class TreeElements {
6 Map<Node, Element> map; 6 Map<Node, Element> map;
7 TreeElements() : map = new LinkedHashMap<Node, Element>(); 7 TreeElements() : map = new LinkedHashMap<Node, Element>();
8 operator []=(Node node, Element element) => map[node] = element; 8 operator []=(Node node, Element element) => map[node] = element;
9 operator [](Node node) => map[node]; 9 operator [](Node node) => map[node];
10 } 10 }
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 109 }
110 } 110 }
111 111
112 // TODO(ahe): Frog cannot handle generic types. 112 // TODO(ahe): Frog cannot handle generic types.
113 class ResolverVisitor extends AbstractVisitor/*<Element>*/ { 113 class ResolverVisitor extends AbstractVisitor/*<Element>*/ {
114 final Compiler compiler; 114 final Compiler compiler;
115 final TreeElements mapping; 115 final TreeElements mapping;
116 final Element enclosingElement; 116 final Element enclosingElement;
117 bool inInstanceContext; 117 bool inInstanceContext;
118 Scope context; 118 Scope context;
119 ClassElement currentClass;
119 120
120 ResolverVisitor(Compiler compiler, Element element) 121 ResolverVisitor(Compiler compiler, Element element)
121 : this.compiler = compiler, 122 : this.compiler = compiler,
122 this.mapping = new TreeElements(), 123 this.mapping = new TreeElements(),
123 this.enclosingElement = element, 124 this.enclosingElement = element,
124 inInstanceContext = element.isInstanceMember() 125 inInstanceContext = element.isInstanceMember()
125 || element.isGenerativeConstructor(), 126 || element.isGenerativeConstructor(),
126 this.context = element.isMember() 127 this.context = element.isMember()
127 ? new ClassScope(element.enclosingElement, compiler.universe) 128 ? new ClassScope(element.enclosingElement, compiler.universe)
128 : new TopScope(compiler.universe); 129 : new TopScope(compiler.universe),
130 this.currentClass = element.isMember() ? element.enclosingElement : null;
129 131
130 ResolverVisitor.from(ResolverVisitor other) 132 ResolverVisitor.from(ResolverVisitor other)
131 : compiler = other.compiler, 133 : compiler = other.compiler,
132 mapping = other.mapping, 134 mapping = other.mapping,
133 enclosingElement = other.enclosingElement, 135 enclosingElement = other.enclosingElement,
134 inInstanceContext = other.inInstanceContext, 136 inInstanceContext = other.inInstanceContext,
135 context = other.context; 137 context = other.context,
138 currentClass = other.currentClass;
136 139
137 error(Node node, MessageKind kind, [arguments = const []]) { 140 error(Node node, MessageKind kind, [arguments = const []]) {
138 ResolutionError error = new ResolutionError(kind, arguments); 141 ResolutionError error = new ResolutionError(kind, arguments);
139 compiler.reportError(node, error); 142 compiler.reportError(node, error);
140 } 143 }
141 144
142 warning(Node node, MessageKind kind, [arguments = const []]) { 145 warning(Node node, MessageKind kind, [arguments = const []]) {
143 ResolutionWarning warning = new ResolutionWarning(kind, arguments); 146 ResolutionWarning warning = new ResolutionWarning(kind, arguments);
144 compiler.reportWarning(node, warning); 147 compiler.reportWarning(node, warning);
145 } 148 }
(...skipping 19 matching lines...) Expand all
165 168
166 visit(Node node) { 169 visit(Node node) {
167 if (node == null) return null; 170 if (node == null) return null;
168 return node.accept(this); 171 return node.accept(this);
169 } 172 }
170 173
171 visitIdentifier(Identifier node) { 174 visitIdentifier(Identifier node) {
172 if (node.isThis()) { 175 if (node.isThis()) {
173 if (!inInstanceContext) error(node, MessageKind.NO_THIS_IN_STATIC); 176 if (!inInstanceContext) error(node, MessageKind.NO_THIS_IN_STATIC);
174 return null; 177 return null;
178 } else if (node.isSuper()) {
179 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC);
180 return null;
175 } else { 181 } else {
176 Element element = lookup(node, node.source); 182 Element element = lookup(node, node.source);
177 if (element == null) { 183 if (element == null) {
178 error(node, MessageKind.CANNOT_RESOLVE, [node]); 184 error(node, MessageKind.CANNOT_RESOLVE, [node]);
179 } 185 }
180 return useElement(node, element); 186 return useElement(node, element);
181 } 187 }
182 } 188 }
183 189
184 visitTypeAnnotation(TypeAnnotation node) { 190 visitTypeAnnotation(TypeAnnotation node) {
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 assert(receiver === null); 330 assert(receiver === null);
325 visit(node.selector); 331 visit(node.selector);
326 return null; 332 return null;
327 } 333 }
328 334
329 SourceString name = selector.source; 335 SourceString name = selector.source;
330 // No need to assign an element for a logical operation. 336 // No need to assign an element for a logical operation.
331 if (isLogicalOperator(selector)) return null; 337 if (isLogicalOperator(selector)) return null;
332 338
333 Element target = null; 339 Element target = null;
334 if (node.isOperator) { 340 if (node.receiver !== null
341 && node.receiver.asIdentifier() !== null
342 && node.receiver.asIdentifier().isSuper()) {
343 SourceString superName = const SourceString('');
344 print(currentClass);
ngeoffray 2012/01/11 13:00:48 Remove debugging code
karlklose 2012/01/11 13:46:12 Done.
345 if (currentClass !== null) {
346 ClassElement superElement = currentClass.superClass;
347 if (superElement !== null) {
348 target = superElement.lookupLocalMember(name);
349 superName = superElement.name;
350 } else {
351 superName = compiler.types.OBJECT;
352 }
353 }
354 if (target == null) {
355 error(node, MessageKind.METHOD_NOT_FOUND, [superName, name]);
ngeoffray 2012/01/11 13:00:48 I think I'd prefer two kinds of errors, one for th
karlklose 2012/01/11 13:46:12 Yes we already report an error if we encounter sup
356 }
357 } else if (node.isOperator) {
335 return null; 358 return null;
336 } else if (node.receiver === null) { 359 } else if (node.receiver === null) {
337 target = lookup(node, name); 360 target = lookup(node, name);
338 if (target == null && !enclosingElement.isInstanceMember()) { 361 if (target == null && !enclosingElement.isInstanceMember()) {
339 error(node, MessageKind.CANNOT_RESOLVE, [name]); 362 error(node, MessageKind.CANNOT_RESOLVE, [name]);
340 } 363 }
341 } else if (receiver === null) { 364 } else if (receiver === null) {
342 return null; 365 return null;
343 } else if (receiver.kind === ElementKind.CLASS) { 366 } else if (receiver.kind === ElementKind.CLASS) {
344 ClassElement receiverClass = receiver; 367 ClassElement receiverClass = receiver;
345 target = receiverClass.resolve(compiler).lookupLocalMember(name); 368 target = receiverClass.resolve(compiler).lookupLocalMember(name);
346 if (target == null) { 369 if (target == null) {
347 error(node, MessageKind.METHOD_NOT_FOUND, [receiver, name]); 370 error(node, MessageKind.METHOD_NOT_FOUND, [receiver.name, name]);
348 } else if (target.isInstanceMember()) { 371 } else if (target.isInstanceMember()) {
349 error(node, MessageKind.MEMBER_NOT_STATIC, [receiver, name]); 372 error(node, MessageKind.MEMBER_NOT_STATIC, [receiver.name, name]);
350 } 373 }
351 } 374 }
352 return target; 375 return target;
353 } 376 }
354 377
355 visitSend(Send node) { 378 visitSend(Send node) {
356 Element target = resolveSend(node); 379 Element target = resolveSend(node);
357 // TODO(ngeoffray): If target is a field, check that there's a 380 // TODO(ngeoffray): If target is a field, check that there's a
358 // getter. 381 // getter.
359 return useElement(node, target); 382 return useElement(node, target);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 Scope context; 558 Scope context;
536 559
537 ClassResolverVisitor(Compiler compiler) 560 ClassResolverVisitor(Compiler compiler)
538 : this.compiler = compiler, context = new TopScope(compiler.universe); 561 : this.compiler = compiler, context = new TopScope(compiler.universe);
539 562
540 Type visitClassNode(ClassNode node) { 563 Type visitClassNode(ClassNode node) {
541 ClassElement element = context.lookup(node.name.source); 564 ClassElement element = context.lookup(node.name.source);
542 compiler.ensure(element !== null); 565 compiler.ensure(element !== null);
543 compiler.ensure(!element.isResolved); 566 compiler.ensure(!element.isResolved);
544 element.supertype = visit(node.superclass); 567 element.supertype = visit(node.superclass);
568 if (element.name != Types.OBJECT && element.supertype === null) {
569 ClassElement objectElement = context.lookup(Types.OBJECT);
570 if (objectElement !== null && !objectElement.isResolved) {
571 compiler.resolver.toResolve.add(objectElement);
572 } else if (objectElement === null){
573 compiler.reportError(node,
574 new ResolutionError(MessageKind.CANNOT_RESOLVE_TYPE,
575 [Types.OBJECT]));
576 }
577 element.supertype = new SimpleType(Types.OBJECT,
578 objectElement);
579 }
545 for (Link<Node> link = node.interfaces.nodes; 580 for (Link<Node> link = node.interfaces.nodes;
546 !link.isEmpty(); 581 !link.isEmpty();
547 link = link.tail) { 582 link = link.tail) {
548 element.interfaces = element.interfaces.prepend(visit(link.head)); 583 element.interfaces = element.interfaces.prepend(visit(link.head));
549 } 584 }
550 return element.computeType(compiler); 585 return element.computeType(compiler);
551 } 586 }
552 587
553 Type visitTypeAnnotation(TypeAnnotation node) { 588 Type visitTypeAnnotation(TypeAnnotation node) {
554 Identifier name = node.typeName; 589 Identifier name = node.typeName;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
714 class TopScope extends Scope { 749 class TopScope extends Scope {
715 Universe universe; 750 Universe universe;
716 751
717 TopScope(Universe this.universe) : super(null, null); 752 TopScope(Universe this.universe) : super(null, null);
718 Element lookup(SourceString name) => universe.find(name); 753 Element lookup(SourceString name) => universe.find(name);
719 754
720 Element add(Element element) { 755 Element add(Element element) {
721 throw "Cannot add an element in the top scope"; 756 throw "Cannot add an element in the top scope";
722 } 757 }
723 } 758 }
OLDNEW
« no previous file with comments | « no previous file | frog/leg/ssa/builder.dart » ('j') | frog/leg/ssa/builder.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698