Chromium Code Reviews| OLD | NEW |
|---|---|
| 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(FunctionExpression tree, FunctionElement element) { |
| 20 return measure(() { | 20 return measure(() { |
| 21 ResolverVisitor visitor = new SignatureResolverVisitor(compiler); | 21 ResolverVisitor visitor = new SignatureResolverVisitor(compiler, element); |
| 22 visitor.visit(tree); | 22 visitor.visit(tree); |
| 23 | 23 |
| 24 visitor = new FullResolverVisitor.from(visitor); | 24 visitor = new FullResolverVisitor.from(visitor); |
| 25 visitor.visit(tree.body); | 25 visitor.visit(tree.body); |
| 26 | 26 |
| 27 // Resolve the type annotations encountered in the method. | 27 // Resolve the type annotations encountered in the method. |
| 28 while (!toResolve.isEmpty()) { | 28 while (!toResolve.isEmpty()) { |
| 29 toResolve.removeFirst().resolve(compiler); | 29 toResolve.removeFirst().resolve(compiler); |
| 30 } | 30 } |
| 31 return visitor.mapping; | 31 return visitor.mapping; |
| 32 }); | 32 }); |
| 33 } | 33 } |
| 34 | 34 |
| 35 // Used for testing. | 35 void resolveType(ClassNode tree, Element 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(() { | 36 measure(() { |
| 49 ClassResolverVisitor visitor = new ClassResolverVisitor(compiler); | 37 ClassResolverVisitor visitor = new ClassResolverVisitor(compiler); |
| 50 visitor.visit(tree); | 38 visitor.visit(tree); |
| 51 }); | 39 }); |
| 52 } | 40 } |
| 53 | 41 |
| 54 void resolveSignature(FunctionExpression node) { | 42 void resolveSignature(FunctionExpression node, FunctionElement element) { |
| 55 measure(() { | 43 measure(() { |
| 56 SignatureResolverVisitor visitor = new SignatureResolverVisitor(compiler); | 44 SignatureResolverVisitor visitor = |
| 45 new SignatureResolverVisitor(compiler, element); | |
| 57 visitor.visitFunctionExpression(node); | 46 visitor.visitFunctionExpression(node); |
| 58 }); | 47 }); |
| 59 } | 48 } |
| 60 } | 49 } |
| 61 | 50 |
| 62 class ResolverVisitor implements Visitor<Element> { | 51 class ResolverVisitor implements Visitor<Element> { |
| 63 final Compiler compiler; | 52 final Compiler compiler; |
| 64 final TreeElements mapping; | 53 final TreeElements mapping; |
| 65 Scope context; | 54 Scope context; |
| 66 | 55 |
| 67 ResolverVisitor(Compiler compiler) | 56 ResolverVisitor(Compiler compiler, Element element) |
| 68 : this.compiler = compiler, | 57 : this.compiler = compiler, |
|
karlklose
2011/12/05 14:54:55
Extra space in the following two lines.
| |
| 69 mapping = new TreeElements(), | 58 this.mapping = new TreeElements(), |
| 70 context = new Scope(new TopScope(compiler.universe)); | 59 this.context = element.isClassMember() |
| 60 ? new ClassScope(element.enclosingElement, compiler.universe) | |
| 61 : new TopScope(compiler.universe); | |
| 71 | 62 |
| 72 ResolverVisitor.from(ResolverVisitor other) | 63 ResolverVisitor.from(ResolverVisitor other) |
| 73 : compiler = other.compiler, | 64 : compiler = other.compiler, |
| 74 mapping = other.mapping, | 65 mapping = other.mapping, |
| 75 context = other.context; | 66 context = other.context; |
| 76 | 67 |
| 77 error(Node node, MessageKind kind, [arguments = const []]) { | 68 error(Node node, MessageKind kind, [arguments = const []]) { |
| 78 ResolutionError error = new ResolutionError(kind, arguments); | 69 ResolutionError error = new ResolutionError(kind, arguments); |
| 79 compiler.reportError(node, error); | 70 compiler.reportError(node, error); |
| 80 } | 71 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 129 | 120 |
| 130 Element useElement(Node node, Element element) { | 121 Element useElement(Node node, Element element) { |
| 131 if (element === null) return null; | 122 if (element === null) return null; |
| 132 mapping[node] = element; | 123 mapping[node] = element; |
| 133 // TODO(ngeoffray): frog does not like a return on an assignment. | 124 // TODO(ngeoffray): frog does not like a return on an assignment. |
| 134 return element; | 125 return element; |
| 135 } | 126 } |
| 136 } | 127 } |
| 137 | 128 |
| 138 class SignatureResolverVisitor extends ResolverVisitor { | 129 class SignatureResolverVisitor extends ResolverVisitor { |
| 130 FunctionElement element; | |
| 139 | 131 |
| 140 SignatureResolverVisitor(Compiler compiler) : super(compiler); | 132 SignatureResolverVisitor(Compiler compiler, FunctionElement element) |
| 133 : super(compiler, element), this.element = element; | |
| 141 | 134 |
| 142 visitFunctionExpression(FunctionExpression node) { | 135 visitFunctionExpression(FunctionExpression node) { |
| 143 FunctionElement enclosingElement = context.lookup(node.name.dynamic.source); | 136 useElement(node, element); |
| 144 useElement(node, enclosingElement); | 137 context = new Scope.enclosing(context, element); |
| 145 context = new Scope.enclosing(context, enclosingElement); | |
| 146 | 138 |
| 147 if (enclosingElement.parameters == null) { | 139 if (element.parameters == null) { |
| 148 ParametersVisitor visitor = new ParametersVisitor(this); | 140 ParametersVisitor visitor = new ParametersVisitor(this); |
| 149 visitor.visit(node.parameters); | 141 visitor.visit(node.parameters); |
| 150 enclosingElement.parameters = visitor.elements.toLink(); | 142 element.parameters = visitor.elements.toLink(); |
| 151 } else { | 143 } else { |
| 152 Link<Node> parameterNodes = node.parameters.nodes; | 144 Link<Node> parameterNodes = node.parameters.nodes; |
| 153 for (Link<Element> link = enclosingElement.parameters; | 145 for (Link<Element> link = element.parameters; |
| 154 !link.isEmpty() && !parameterNodes.isEmpty(); | 146 !link.isEmpty() && !parameterNodes.isEmpty(); |
| 155 link = link.tail, parameterNodes = parameterNodes.tail) { | 147 link = link.tail, parameterNodes = parameterNodes.tail) { |
| 156 defineElement(parameterNodes.head.definitions.nodes.head, link.head); | 148 defineElement(parameterNodes.head.definitions.nodes.head, link.head); |
| 157 } | 149 } |
| 158 } | 150 } |
| 159 | 151 |
| 160 return enclosingElement; | 152 return element; |
| 161 } | 153 } |
| 162 } | 154 } |
| 163 | 155 |
| 164 class FullResolverVisitor extends ResolverVisitor { | 156 class FullResolverVisitor extends ResolverVisitor { |
| 165 | 157 |
| 166 FullResolverVisitor(Compiler compiler) : super(compiler); | 158 FullResolverVisitor(Compiler compiler, Element element) |
| 159 : super(compiler, element); | |
| 167 FullResolverVisitor.from(ResolverVisitor other) : super.from(other); | 160 FullResolverVisitor.from(ResolverVisitor other) : super.from(other); |
| 168 | 161 |
| 169 Element visitClassNode(ClassNode node) { | 162 Element visitClassNode(ClassNode node) { |
| 170 cancel(node, "shouldn't be called"); | 163 cancel(node, "shouldn't be called"); |
| 171 } | 164 } |
| 172 | 165 |
| 173 visitIn(Node node, Scope scope) { | 166 visitIn(Node node, Scope scope) { |
| 174 context = scope; | 167 context = scope; |
| 175 Element element = visit(node); | 168 Element element = visit(node); |
| 176 context = context.parent; | 169 context = context.parent; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 193 visitFor(For node) { | 186 visitFor(For node) { |
| 194 Scope scope = new Scope(context); | 187 Scope scope = new Scope(context); |
| 195 visitIn(node.initializer, scope); | 188 visitIn(node.initializer, scope); |
| 196 visitIn(node.condition, scope); | 189 visitIn(node.condition, scope); |
| 197 visitIn(node.update, scope); | 190 visitIn(node.update, scope); |
| 198 visitIn(node.body, scope); | 191 visitIn(node.body, scope); |
| 199 } | 192 } |
| 200 | 193 |
| 201 visitFunctionExpression(FunctionExpression node) { | 194 visitFunctionExpression(FunctionExpression node) { |
| 202 visit(node.returnType); | 195 visit(node.returnType); |
| 203 FunctionElement enclosingElement = | 196 FunctionElement enclosingElement = new FunctionElement.node( |
| 204 new FunctionElement.node(node, context.enclosingElement); | 197 node, ElementKind.FUNCTION, context.enclosingElement); |
| 205 defineElement(node, enclosingElement); | 198 defineElement(node, enclosingElement); |
| 206 context = new Scope.enclosing(context, enclosingElement); | 199 context = new Scope.enclosing(context, enclosingElement); |
| 207 | 200 |
| 208 ParametersVisitor visitor = new ParametersVisitor(this); | 201 ParametersVisitor visitor = new ParametersVisitor(this); |
| 209 visitor.visit(node.parameters); | 202 visitor.visit(node.parameters); |
| 210 enclosingElement.parameters = visitor.elements.toLink(); | 203 enclosingElement.parameters = visitor.elements.toLink(); |
| 211 | 204 |
| 212 visit(node.body); | 205 visit(node.body); |
| 213 context = context.parent; | 206 context = context.parent; |
| 214 return enclosingElement; | 207 return enclosingElement; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 visitWhile(While node) { | 367 visitWhile(While node) { |
| 375 visit(node.condition); | 368 visit(node.condition); |
| 376 visitIn(node.body, new Scope(context)); | 369 visitIn(node.body, new Scope(context)); |
| 377 } | 370 } |
| 378 | 371 |
| 379 visitParenthesizedExpression(ParenthesizedExpression node) { | 372 visitParenthesizedExpression(ParenthesizedExpression node) { |
| 380 visit(node.expression); | 373 visit(node.expression); |
| 381 } | 374 } |
| 382 | 375 |
| 383 visitNewExpression(NewExpression node) { | 376 visitNewExpression(NewExpression node) { |
| 384 cancel(node, "Unimplemented"); | 377 visit(node.send.argumentsNode); |
| 378 | |
| 379 ClassElement cls = visit(node.send.selector); | |
| 380 SourceString name = const SourceString(""); | |
| 381 Element constructor = null; | |
| 382 if (cls !== null) { | |
| 383 Element constructor = cls.lookupLocalElement(name); | |
| 384 if (name.stringValue === '' | |
| 385 && constructor === null | |
| 386 && node.send.argumentsNode.isEmpty() | |
| 387 && cls.canHaveDefaultConstructor()) { | |
| 388 constructor = new SynthesizedConstructorElement(cls); | |
| 389 cls.addConstructor(constructor); | |
| 390 } | |
| 391 if (constructor === null) { | |
| 392 error(node, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node]); | |
| 393 } | |
| 394 } | |
| 395 | |
| 396 return useElement(node, constructor); | |
| 385 } | 397 } |
| 386 } | 398 } |
| 387 | 399 |
| 388 class ClassResolverVisitor extends AbstractVisitor<Type> { | 400 class ClassResolverVisitor extends AbstractVisitor<Type> { |
| 389 Compiler compiler; | 401 Compiler compiler; |
| 390 Scope context; | 402 Scope context; |
| 391 | 403 |
| 392 ClassResolverVisitor(Compiler compiler) | 404 ClassResolverVisitor(Compiler compiler) |
| 393 : this.compiler = compiler, context = new TopScope(compiler.universe); | 405 : this.compiler = compiler, context = new TopScope(compiler.universe); |
| 394 | 406 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 506 return parent.lookup(name); | 518 return parent.lookup(name); |
| 507 } | 519 } |
| 508 | 520 |
| 509 Element add(Element element) { | 521 Element add(Element element) { |
| 510 if (elements.containsKey(element.name)) return elements[element.name]; | 522 if (elements.containsKey(element.name)) return elements[element.name]; |
| 511 elements[element.name] = element; | 523 elements[element.name] = element; |
| 512 return element; | 524 return element; |
| 513 } | 525 } |
| 514 } | 526 } |
| 515 | 527 |
| 528 class ClassScope extends Scope { | |
| 529 ClassScope(ClassElement element, Universe universe) | |
| 530 : super.enclosing(new TopScope(universe), element); | |
| 531 | |
| 532 Element lookup(SourceString name) { | |
| 533 ClassElement cls = enclosingElement; | |
|
ahe
2011/12/02 11:27:41
The word "enclosingElement" seems wrong in this co
ngeoffray
2011/12/02 14:44:54
Changed to 'element'.
| |
| 534 Element element = cls.lookupLocalElement(name); | |
| 535 if (element != null) return element; | |
| 536 element = parent.lookup(name); | |
| 537 if (element != null) return element; | |
| 538 // TODO(ngeoffray): Lookup in the super class. | |
| 539 return null; | |
| 540 } | |
| 541 | |
| 542 Element add(Element element) { | |
| 543 throw "Cannot add an element in a class scope"; | |
| 544 } | |
| 545 } | |
| 546 | |
| 516 // TODO(ngeoffray): this top scope should have libraryElement as | 547 // TODO(ngeoffray): this top scope should have libraryElement as |
| 517 // enclosingElement. | 548 // enclosingElement. |
| 518 class TopScope extends Scope { | 549 class TopScope extends Scope { |
| 519 Universe universe; | 550 Universe universe; |
| 520 | 551 |
| 521 TopScope(Universe this.universe) : super.top(); | 552 TopScope(Universe this.universe) : super.top(); |
| 522 Element lookup(SourceString name) => universe.find(name); | 553 Element lookup(SourceString name) => universe.find(name); |
| 523 | 554 |
| 524 Element add(Element element) { | 555 Element add(Element element) { |
| 525 throw "Cannot add an element in the top scope"; | 556 throw "Cannot add an element in the top scope"; |
| 526 } | 557 } |
| 527 } | 558 } |
| OLD | NEW |