| 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(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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |