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 } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 // TODO(ahe): Frog cannot handle generic types. | 138 // TODO(ahe): Frog cannot handle generic types. |
| 139 class ResolverVisitor extends AbstractVisitor/*<Element>*/ { | 139 class ResolverVisitor extends AbstractVisitor/*<Element>*/ { |
| 140 final Compiler compiler; | 140 final Compiler compiler; |
| 141 final TreeElements mapping; | 141 final TreeElements mapping; |
| 142 final Element enclosingElement; | 142 final Element enclosingElement; |
| 143 bool inInstanceContext; | 143 bool inInstanceContext; |
| 144 Scope context; | 144 Scope context; |
| 145 ClassElement currentClass; | |
| 145 | 146 |
| 146 ResolverVisitor(Compiler compiler, Element element) | 147 ResolverVisitor(Compiler compiler, Element element) |
| 147 : this.compiler = compiler, | 148 : this.compiler = compiler, |
| 148 this.mapping = new TreeElements(), | 149 this.mapping = new TreeElements(), |
| 149 this.enclosingElement = element, | 150 this.enclosingElement = element, |
| 150 inInstanceContext = element.isInstanceMember() | 151 inInstanceContext = element.isInstanceMember() |
| 151 || element.isGenerativeConstructor(), | 152 || element.isGenerativeConstructor(), |
| 152 this.context = element.isMember() | 153 this.context = element.isMember() |
| 153 ? new ClassScope(element.enclosingElement, compiler.universe) | 154 ? new ClassScope(element.enclosingElement, compiler.universe) |
| 154 : new TopScope(compiler.universe); | 155 : new TopScope(compiler.universe), |
| 156 this.currentClass = element.isMember() ? element.enclosingElement : null; | |
| 155 | 157 |
| 156 ResolverVisitor.from(ResolverVisitor other) | 158 ResolverVisitor.from(ResolverVisitor other) |
| 157 : compiler = other.compiler, | 159 : compiler = other.compiler, |
| 158 mapping = other.mapping, | 160 mapping = other.mapping, |
| 159 enclosingElement = other.enclosingElement, | 161 enclosingElement = other.enclosingElement, |
| 160 inInstanceContext = other.inInstanceContext, | 162 inInstanceContext = other.inInstanceContext, |
| 161 context = other.context; | 163 context = other.context, |
| 164 currentClass = other.currentClass; | |
| 162 | 165 |
| 163 error(Node node, MessageKind kind, [arguments = const []]) { | 166 error(Node node, MessageKind kind, [arguments = const []]) { |
| 164 ResolutionError error = new ResolutionError(kind, arguments); | 167 ResolutionError error = new ResolutionError(kind, arguments); |
| 165 compiler.reportError(node, error); | 168 compiler.reportError(node, error); |
| 166 } | 169 } |
| 167 | 170 |
| 168 warning(Node node, MessageKind kind, [arguments = const []]) { | 171 warning(Node node, MessageKind kind, [arguments = const []]) { |
| 169 ResolutionWarning warning = new ResolutionWarning(kind, arguments); | 172 ResolutionWarning warning = new ResolutionWarning(kind, arguments); |
| 170 compiler.reportWarning(node, warning); | 173 compiler.reportWarning(node, warning); |
| 171 } | 174 } |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 191 | 194 |
| 192 visit(Node node) { | 195 visit(Node node) { |
| 193 if (node == null) return null; | 196 if (node == null) return null; |
| 194 return node.accept(this); | 197 return node.accept(this); |
| 195 } | 198 } |
| 196 | 199 |
| 197 visitIdentifier(Identifier node) { | 200 visitIdentifier(Identifier node) { |
| 198 if (node.isThis()) { | 201 if (node.isThis()) { |
| 199 if (!inInstanceContext) error(node, MessageKind.NO_THIS_IN_STATIC); | 202 if (!inInstanceContext) error(node, MessageKind.NO_THIS_IN_STATIC); |
| 200 return null; | 203 return null; |
| 204 } else if (node.isSuper()) { | |
| 205 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); | |
| 206 return null; | |
| 201 } else { | 207 } else { |
| 202 Element element = lookup(node, node.source); | 208 Element element = lookup(node, node.source); |
| 203 if (element == null) { | 209 if (element == null) { |
| 204 error(node, MessageKind.CANNOT_RESOLVE, [node]); | 210 error(node, MessageKind.CANNOT_RESOLVE, [node]); |
| 205 } | 211 } |
| 206 return useElement(node, element); | 212 return useElement(node, element); |
| 207 } | 213 } |
| 208 } | 214 } |
| 209 | 215 |
| 210 visitTypeAnnotation(TypeAnnotation node) { | 216 visitTypeAnnotation(TypeAnnotation node) { |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 assert(receiver === null); | 356 assert(receiver === null); |
| 351 visit(node.selector); | 357 visit(node.selector); |
| 352 return null; | 358 return null; |
| 353 } | 359 } |
| 354 | 360 |
| 355 SourceString name = selector.source; | 361 SourceString name = selector.source; |
| 356 // No need to assign an element for a logical operation. | 362 // No need to assign an element for a logical operation. |
| 357 if (isLogicalOperator(selector)) return null; | 363 if (isLogicalOperator(selector)) return null; |
| 358 | 364 |
| 359 Element target = null; | 365 Element target = null; |
| 360 if (node.isOperator) { | 366 if (node.isSuperCall) { |
| 367 if (currentClass !== null) { | |
| 368 ClassElement superElement = currentClass.superClass; | |
|
ahe
2012/01/11 13:55:58
It is called "superclass", but an element should n
| |
| 369 if (superElement !== null) { | |
| 370 target = superElement.lookupLocalMember(name); | |
| 371 } | |
| 372 if (target == null) { | |
| 373 error(node, MessageKind.METHOD_NOT_FOUND, [superElement.name, name]); | |
| 374 } | |
| 375 } | |
| 376 } else if (node.isOperator) { | |
| 361 return null; | 377 return null; |
| 362 } else if (node.receiver === null) { | 378 } else if (node.receiver === null) { |
| 363 target = lookup(node, name); | 379 target = lookup(node, name); |
| 364 if (target == null && !enclosingElement.isInstanceMember()) { | 380 if (target == null && !enclosingElement.isInstanceMember()) { |
| 365 error(node, MessageKind.CANNOT_RESOLVE, [name]); | 381 error(node, MessageKind.CANNOT_RESOLVE, [name]); |
| 366 } | 382 } |
| 367 } else if (receiver === null) { | 383 } else if (receiver === null) { |
| 368 return null; | 384 return null; |
| 369 } else if (receiver.kind === ElementKind.CLASS) { | 385 } else if (receiver.kind === ElementKind.CLASS) { |
| 370 ClassElement receiverClass = receiver; | 386 ClassElement receiverClass = receiver; |
| 371 target = receiverClass.resolve(compiler).lookupLocalMember(name); | 387 target = receiverClass.resolve(compiler).lookupLocalMember(name); |
| 372 if (target == null) { | 388 if (target == null) { |
| 373 error(node, MessageKind.METHOD_NOT_FOUND, [receiver, name]); | 389 error(node, MessageKind.METHOD_NOT_FOUND, [receiver.name, name]); |
| 374 } else if (target.isInstanceMember()) { | 390 } else if (target.isInstanceMember()) { |
| 375 error(node, MessageKind.MEMBER_NOT_STATIC, [receiver, name]); | 391 error(node, MessageKind.MEMBER_NOT_STATIC, [receiver.name, name]); |
| 376 } | 392 } |
| 377 } | 393 } |
| 378 return target; | 394 return target; |
| 379 } | 395 } |
| 380 | 396 |
| 381 visitSend(Send node) { | 397 visitSend(Send node) { |
| 382 Element target = resolveSend(node); | 398 Element target = resolveSend(node); |
| 383 // TODO(ngeoffray): If target is a field, check that there's a | 399 // TODO(ngeoffray): If target is a field, check that there's a |
| 384 // getter. | 400 // getter. |
| 385 return useElement(node, target); | 401 return useElement(node, target); |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 Scope context; | 589 Scope context; |
| 574 | 590 |
| 575 ClassResolverVisitor(Compiler compiler) | 591 ClassResolverVisitor(Compiler compiler) |
| 576 : this.compiler = compiler, context = new TopScope(compiler.universe); | 592 : this.compiler = compiler, context = new TopScope(compiler.universe); |
| 577 | 593 |
| 578 Type visitClassNode(ClassNode node) { | 594 Type visitClassNode(ClassNode node) { |
| 579 ClassElement element = context.lookup(node.name.source); | 595 ClassElement element = context.lookup(node.name.source); |
| 580 compiler.ensure(element !== null); | 596 compiler.ensure(element !== null); |
| 581 compiler.ensure(!element.isResolved); | 597 compiler.ensure(!element.isResolved); |
| 582 element.supertype = visit(node.superclass); | 598 element.supertype = visit(node.superclass); |
| 599 if (element.name != Types.OBJECT && element.supertype === null) { | |
| 600 ClassElement objectElement = context.lookup(Types.OBJECT); | |
| 601 if (objectElement !== null && !objectElement.isResolved) { | |
| 602 compiler.resolver.toResolve.add(objectElement); | |
| 603 } else if (objectElement === null){ | |
| 604 compiler.reportError(node, | |
| 605 new ResolutionError(MessageKind.CANNOT_RESOLVE_TYPE, | |
| 606 [Types.OBJECT])); | |
| 607 } | |
| 608 element.supertype = new SimpleType(Types.OBJECT, | |
| 609 objectElement); | |
| 610 } | |
| 583 for (Link<Node> link = node.interfaces.nodes; | 611 for (Link<Node> link = node.interfaces.nodes; |
| 584 !link.isEmpty(); | 612 !link.isEmpty(); |
| 585 link = link.tail) { | 613 link = link.tail) { |
| 586 element.interfaces = element.interfaces.prepend(visit(link.head)); | 614 element.interfaces = element.interfaces.prepend(visit(link.head)); |
| 587 } | 615 } |
| 588 return element.computeType(compiler); | 616 return element.computeType(compiler); |
| 589 } | 617 } |
| 590 | 618 |
| 591 Type visitTypeAnnotation(TypeAnnotation node) { | 619 Type visitTypeAnnotation(TypeAnnotation node) { |
| 592 Identifier name = node.typeName; | 620 Identifier name = node.typeName; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 752 class TopScope extends Scope { | 780 class TopScope extends Scope { |
| 753 Universe universe; | 781 Universe universe; |
| 754 | 782 |
| 755 TopScope(Universe this.universe) : super(null, null); | 783 TopScope(Universe this.universe) : super(null, null); |
| 756 Element lookup(SourceString name) => universe.find(name); | 784 Element lookup(SourceString name) => universe.find(name); |
| 757 | 785 |
| 758 Element add(Element element) { | 786 Element add(Element element) { |
| 759 throw "Cannot add an element in the top scope"; | 787 throw "Cannot add an element in the top scope"; |
| 760 } | 788 } |
| 761 } | 789 } |
| OLD | NEW |