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

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

Issue 8769012: Start resolving classes and default constructors. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 9 years 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 | « frog/leg/elements/elements.dart ('k') | frog/leg/scanner/class_element_parser.dart » ('j') | no next file with comments »
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 }
11 11
12 class ResolverTask extends CompilerTask { 12 class ResolverTask extends CompilerTask {
13 Queue<ClassElement> toResolve; 13 Queue<ClassElement> toResolve;
14 ResolverTask(Compiler compiler) 14 ResolverTask(Compiler compiler)
15 : super(compiler), toResolve = new Queue<ClassElement>(); 15 : super(compiler), toResolve = new Queue<ClassElement>();
16 16
17 String get name() => 'Resolver'; 17 String get name() => 'Resolver';
18 18
19 TreeElements resolve(FunctionExpression tree) { 19 TreeElements resolve(FunctionElement element) {
20 return measure(() { 20 return measure(() {
21 ResolverVisitor visitor = new SignatureResolverVisitor(compiler); 21 FunctionExpression tree = element.node;
22 ResolverVisitor visitor = new SignatureResolverVisitor(compiler, element);
22 visitor.visit(tree); 23 visitor.visit(tree);
23 24
24 visitor = new FullResolverVisitor.from(visitor); 25 visitor = new FullResolverVisitor.from(visitor);
25 visitor.visit(tree.body); 26 visitor.visit(tree.body);
26 27
27 // Resolve the type annotations encountered in the method. 28 // Resolve the type annotations encountered in the method.
28 while (!toResolve.isEmpty()) { 29 while (!toResolve.isEmpty()) {
29 toResolve.removeFirst().resolve(compiler); 30 toResolve.removeFirst().resolve(compiler);
30 } 31 }
31 return visitor.mapping; 32 return visitor.mapping;
32 }); 33 });
33 } 34 }
34 35
35 // Used for testing. 36 void resolveType(ClassElement element) {
36 TreeElements resolveStatement(Node node) {
37 ResolverVisitor visitor = new FullResolverVisitor(compiler);
38 visitor.visit(node);
39
40 // Resolve the type annotations encountered in the code.
41 while (!toResolve.isEmpty()) {
42 toResolve.removeFirst().resolve(compiler);
43 }
44 return visitor.mapping;
45 }
46
47 void resolveType(ClassNode tree) {
48 measure(() { 37 measure(() {
38 ClassNode tree = element.node;
49 ClassResolverVisitor visitor = new ClassResolverVisitor(compiler); 39 ClassResolverVisitor visitor = new ClassResolverVisitor(compiler);
50 visitor.visit(tree); 40 visitor.visit(tree);
51 }); 41 });
52 } 42 }
53 43
54 void resolveSignature(FunctionExpression node) { 44 void resolveSignature(FunctionElement element) {
55 measure(() { 45 measure(() {
56 SignatureResolverVisitor visitor = new SignatureResolverVisitor(compiler); 46 FunctionExpression node = element.node;
47 SignatureResolverVisitor visitor =
48 new SignatureResolverVisitor(compiler, element);
57 visitor.visitFunctionExpression(node); 49 visitor.visitFunctionExpression(node);
58 }); 50 });
59 } 51 }
60 } 52 }
61 53
62 class ResolverVisitor implements Visitor<Element> { 54 class ResolverVisitor implements Visitor<Element> {
63 final Compiler compiler; 55 final Compiler compiler;
64 final TreeElements mapping; 56 final TreeElements mapping;
65 Scope context; 57 Scope context;
66 58
67 ResolverVisitor(Compiler compiler) 59 ResolverVisitor(Compiler compiler, Element element)
68 : this.compiler = compiler, 60 : this.compiler = compiler,
69 mapping = new TreeElements(), 61 this.mapping = new TreeElements(),
70 context = new Scope(new TopScope(compiler.universe)); 62 this.context = element.isClassMember()
63 ? new ClassScope(element.enclosingElement, compiler.universe)
64 : new TopScope(compiler.universe);
71 65
72 ResolverVisitor.from(ResolverVisitor other) 66 ResolverVisitor.from(ResolverVisitor other)
73 : compiler = other.compiler, 67 : compiler = other.compiler,
74 mapping = other.mapping, 68 mapping = other.mapping,
75 context = other.context; 69 context = other.context;
76 70
77 error(Node node, MessageKind kind, [arguments = const []]) { 71 error(Node node, MessageKind kind, [arguments = const []]) {
78 ResolutionError error = new ResolutionError(kind, arguments); 72 ResolutionError error = new ResolutionError(kind, arguments);
79 compiler.reportError(node, error); 73 compiler.reportError(node, error);
80 } 74 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 123
130 Element useElement(Node node, Element element) { 124 Element useElement(Node node, Element element) {
131 if (element === null) return null; 125 if (element === null) return null;
132 mapping[node] = element; 126 mapping[node] = element;
133 // TODO(ngeoffray): frog does not like a return on an assignment. 127 // TODO(ngeoffray): frog does not like a return on an assignment.
134 return element; 128 return element;
135 } 129 }
136 } 130 }
137 131
138 class SignatureResolverVisitor extends ResolverVisitor { 132 class SignatureResolverVisitor extends ResolverVisitor {
133 FunctionElement element;
139 134
140 SignatureResolverVisitor(Compiler compiler) : super(compiler); 135 SignatureResolverVisitor(Compiler compiler, FunctionElement element)
136 : super(compiler, element), this.element = element;
141 137
142 visitFunctionExpression(FunctionExpression node) { 138 visitFunctionExpression(FunctionExpression node) {
143 FunctionElement enclosingElement = context.lookup(node.name.dynamic.source); 139 useElement(node, element);
144 useElement(node, enclosingElement); 140 context = new MethodScope(context, element);
145 context = new Scope.enclosing(context, enclosingElement);
146 141
147 if (enclosingElement.parameters == null) { 142 if (element.parameters == null) {
148 ParametersVisitor visitor = new ParametersVisitor(this); 143 ParametersVisitor visitor = new ParametersVisitor(this);
149 visitor.visit(node.parameters); 144 visitor.visit(node.parameters);
150 enclosingElement.parameters = visitor.elements.toLink(); 145 element.parameters = visitor.elements.toLink();
151 } else { 146 } else {
152 Link<Node> parameterNodes = node.parameters.nodes; 147 Link<Node> parameterNodes = node.parameters.nodes;
153 for (Link<Element> link = enclosingElement.parameters; 148 for (Link<Element> link = element.parameters;
154 !link.isEmpty() && !parameterNodes.isEmpty(); 149 !link.isEmpty() && !parameterNodes.isEmpty();
155 link = link.tail, parameterNodes = parameterNodes.tail) { 150 link = link.tail, parameterNodes = parameterNodes.tail) {
156 defineElement(parameterNodes.head.definitions.nodes.head, link.head); 151 defineElement(parameterNodes.head.definitions.nodes.head, link.head);
157 } 152 }
158 } 153 }
159 154
160 return enclosingElement; 155 return element;
161 } 156 }
162 } 157 }
163 158
164 class FullResolverVisitor extends ResolverVisitor { 159 class FullResolverVisitor extends ResolverVisitor {
165 160
166 FullResolverVisitor(Compiler compiler) : super(compiler); 161 FullResolverVisitor(Compiler compiler, Element element)
162 : super(compiler, element);
167 FullResolverVisitor.from(ResolverVisitor other) : super.from(other); 163 FullResolverVisitor.from(ResolverVisitor other) : super.from(other);
168 164
169 Element visitClassNode(ClassNode node) { 165 Element visitClassNode(ClassNode node) {
170 cancel(node, "shouldn't be called"); 166 cancel(node, "shouldn't be called");
171 } 167 }
172 168
173 visitIn(Node node, Scope scope) { 169 visitIn(Node node, Scope scope) {
174 context = scope; 170 context = scope;
175 Element element = visit(node); 171 Element element = visit(node);
176 context = context.parent; 172 context = context.parent;
177 return element; 173 return element;
178 } 174 }
179 175
180 visitBlock(Block node) { 176 visitBlock(Block node) {
181 visitIn(node.statements, new Scope(context)); 177 visitIn(node.statements, new BlockScope(context));
182 } 178 }
183 179
184 visitDoWhile(DoWhile node) { 180 visitDoWhile(DoWhile node) {
185 visitIn(node.body, new Scope(context)); 181 visitIn(node.body, new BlockScope(context));
186 visit(node.condition); 182 visit(node.condition);
187 } 183 }
188 184
189 visitExpressionStatement(ExpressionStatement node) { 185 visitExpressionStatement(ExpressionStatement node) {
190 visit(node.expression); 186 visit(node.expression);
191 } 187 }
192 188
193 visitFor(For node) { 189 visitFor(For node) {
194 Scope scope = new Scope(context); 190 Scope scope = new BlockScope(context);
195 visitIn(node.initializer, scope); 191 visitIn(node.initializer, scope);
196 visitIn(node.condition, scope); 192 visitIn(node.condition, scope);
197 visitIn(node.update, scope); 193 visitIn(node.update, scope);
198 visitIn(node.body, scope); 194 visitIn(node.body, scope);
199 } 195 }
200 196
201 visitFunctionExpression(FunctionExpression node) { 197 visitFunctionExpression(FunctionExpression node) {
202 visit(node.returnType); 198 visit(node.returnType);
203 FunctionElement enclosingElement = 199 FunctionElement enclosingElement = new FunctionElement.node(
204 new FunctionElement.node(node, context.enclosingElement); 200 node, ElementKind.FUNCTION, context.element);
205 defineElement(node, enclosingElement); 201 defineElement(node, enclosingElement);
206 context = new Scope.enclosing(context, enclosingElement); 202 context = new MethodScope(context, enclosingElement);
207 203
208 ParametersVisitor visitor = new ParametersVisitor(this); 204 ParametersVisitor visitor = new ParametersVisitor(this);
209 visitor.visit(node.parameters); 205 visitor.visit(node.parameters);
210 enclosingElement.parameters = visitor.elements.toLink(); 206 enclosingElement.parameters = visitor.elements.toLink();
211 207
212 visit(node.body); 208 visit(node.body);
213 context = context.parent; 209 context = context.parent;
214 return enclosingElement; 210 return enclosingElement;
215 } 211 }
216 212
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 362
367 visitVariableDefinitions(VariableDefinitions node) { 363 visitVariableDefinitions(VariableDefinitions node) {
368 visit(node.type); 364 visit(node.type);
369 VariableDefinitionsVisitor visitor = 365 VariableDefinitionsVisitor visitor =
370 new VariableDefinitionsVisitor(node, this, ElementKind.VARIABLE); 366 new VariableDefinitionsVisitor(node, this, ElementKind.VARIABLE);
371 visitor.visit(node.definitions); 367 visitor.visit(node.definitions);
372 } 368 }
373 369
374 visitWhile(While node) { 370 visitWhile(While node) {
375 visit(node.condition); 371 visit(node.condition);
376 visitIn(node.body, new Scope(context)); 372 visitIn(node.body, new BlockScope(context));
377 } 373 }
378 374
379 visitParenthesizedExpression(ParenthesizedExpression node) { 375 visitParenthesizedExpression(ParenthesizedExpression node) {
380 visit(node.expression); 376 visit(node.expression);
381 } 377 }
382 378
383 visitNewExpression(NewExpression node) { 379 visitNewExpression(NewExpression node) {
384 cancel(node, "Unimplemented"); 380 visit(node.send.argumentsNode);
381
382 ClassElement cls = visit(node.send.selector);
383 SourceString name = const SourceString("");
384 Element constructor = null;
385 if (cls !== null) {
386 // TODO(ngeoffray): define what isResolved means. Also, pass the
387 // needed element to resolve?
388 if (!cls.isResolved) compiler.resolveType(cls);
389 constructor = cls.lookupLocalElement(name);
390 if (name.stringValue === ''
391 && constructor === null
392 && node.send.argumentsNode.isEmpty()
393 && cls.canHaveDefaultConstructor()) {
394 constructor = new SynthesizedConstructorElement(cls);
395 cls.addConstructor(constructor);
396 }
397 if (constructor === null) {
398 error(node, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node]);
399 }
400 }
401
402 return useElement(node, constructor);
385 } 403 }
386 404
387 visitLiteralList(LiteralList node) { 405 visitLiteralList(LiteralList node) {
388 visit(node.elements); 406 visit(node.elements);
389 } 407 }
390 } 408 }
391 409
392 class ClassResolverVisitor extends AbstractVisitor<Type> { 410 class ClassResolverVisitor extends AbstractVisitor<Type> {
393 Compiler compiler; 411 Compiler compiler;
394 Scope context; 412 Scope context;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 472
455 return visit(node.selector); 473 return visit(node.selector);
456 } 474 }
457 475
458 SourceString visitIdentifier(Identifier node) => node.source; 476 SourceString visitIdentifier(Identifier node) => node.source;
459 477
460 visitNodeList(NodeList node) { 478 visitNodeList(NodeList node) {
461 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 479 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
462 SourceString name = visit(link.head); 480 SourceString name = visit(link.head);
463 Element element = new VariableElement(link.head, definitions.type, 481 Element element = new VariableElement(link.head, definitions.type,
464 kind, name, resolver.context.enclosingElement); 482 kind, name, resolver.context.element);
465 resolver.defineElement(link.head, element); 483 resolver.defineElement(link.head, element);
466 } 484 }
467 } 485 }
468 486
469 visit(Node node) => node.accept(this); 487 visit(Node node) => node.accept(this);
470 } 488 }
471 489
472 class ParametersVisitor extends AbstractVisitor<Element> { 490 class ParametersVisitor extends AbstractVisitor<Element> {
473 ResolverVisitor resolver; 491 ResolverVisitor resolver;
474 LinkBuilder<Element> elements; 492 LinkBuilder<Element> elements;
(...skipping 10 matching lines...) Expand all
485 VariableDefinitionsVisitor visitor = 503 VariableDefinitionsVisitor visitor =
486 new VariableDefinitionsVisitor(node, resolver, ElementKind.PARAMETER); 504 new VariableDefinitionsVisitor(node, resolver, ElementKind.PARAMETER);
487 visitor.visit(node.definitions); 505 visitor.visit(node.definitions);
488 return resolver.mapping[node.definitions.nodes.head]; 506 return resolver.mapping[node.definitions.nodes.head];
489 } 507 }
490 508
491 visit(Node node) => node.accept(this); 509 visit(Node node) => node.accept(this);
492 } 510 }
493 511
494 class Scope { 512 class Scope {
513 final Element element;
495 final Scope parent; 514 final Scope parent;
515
516 Scope(this.parent, this.element);
517 abstract Element add(Element element);
518 abstract Element lookup(Element element);
519 }
520
521 class MethodScope extends Scope {
496 final Map<SourceString, Element> elements; 522 final Map<SourceString, Element> elements;
497 final Element enclosingElement;
498 523
499 Scope(Scope parent) 524 MethodScope(Scope parent, Element element)
500 : this.enclosing(parent, parent.enclosingElement); 525 : super(parent, element), this.elements = {};
501
502 Scope.enclosing(Scope this.parent, this.enclosingElement)
503 : this.elements = {};
504
505 Scope.top() : parent = null, elements = const {}, enclosingElement = null;
506 526
507 Element lookup(SourceString name) { 527 Element lookup(SourceString name) {
508 Element element = elements[name]; 528 Element element = elements[name];
509 if (element !== null) return element; 529 if (element !== null) return element;
510 return parent.lookup(name); 530 return parent.lookup(name);
511 } 531 }
512 532
513 Element add(Element element) { 533 Element add(Element element) {
514 if (elements.containsKey(element.name)) return elements[element.name]; 534 if (elements.containsKey(element.name)) return elements[element.name];
515 elements[element.name] = element; 535 elements[element.name] = element;
516 return element; 536 return element;
517 } 537 }
518 } 538 }
519 539
540 class BlockScope extends MethodScope {
541 BlockScope(Scope parent) : super(parent, parent.element);
542 }
543
544 class ClassScope extends Scope {
545 ClassScope(ClassElement element, Universe universe)
546 : super(new TopScope(universe), element);
547
548 Element lookup(SourceString name) {
549 ClassElement cls = element;
550 Element element = cls.lookupLocalElement(name);
551 if (element != null) return element;
552 element = parent.lookup(name);
553 if (element != null) return element;
554 // TODO(ngeoffray): Lookup in the super class.
555 return null;
556 }
557
558 Element add(Element element) {
559 throw "Cannot add an element in a class scope";
560 }
561 }
562
520 // TODO(ngeoffray): this top scope should have libraryElement as 563 // TODO(ngeoffray): this top scope should have libraryElement as
521 // enclosingElement. 564 // element.
522 class TopScope extends Scope { 565 class TopScope extends Scope {
523 Universe universe; 566 Universe universe;
524 567
525 TopScope(Universe this.universe) : super.top(); 568 TopScope(Universe this.universe) : super(null, null);
526 Element lookup(SourceString name) => universe.find(name); 569 Element lookup(SourceString name) => universe.find(name);
527 570
528 Element add(Element element) { 571 Element add(Element element) {
529 throw "Cannot add an element in the top scope"; 572 throw "Cannot add an element in the top scope";
530 } 573 }
531 } 574 }
OLDNEW
« no previous file with comments | « frog/leg/elements/elements.dart ('k') | frog/leg/scanner/class_element_parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698