Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 interface TreeElements { | 5 interface TreeElements { |
| 6 Element operator[](Node node); | 6 Element operator[](Node node); |
| 7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
| 8 Type getType(TypeAnnotation annotation); | 8 Type getType(TypeAnnotation annotation); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 224 } | 224 } |
| 225 return result; | 225 return result; |
| 226 } | 226 } |
| 227 | 227 |
| 228 void resolveClass(ClassElement element) { | 228 void resolveClass(ClassElement element) { |
| 229 if (element.isResolved || element.isBeingResolved) return; | 229 if (element.isResolved || element.isBeingResolved) return; |
| 230 element.isBeingResolved = true; | 230 element.isBeingResolved = true; |
| 231 measure(() { | 231 measure(() { |
| 232 ClassNode tree = element.parseNode(compiler); | 232 ClassNode tree = element.parseNode(compiler); |
| 233 ClassResolverVisitor visitor = | 233 ClassResolverVisitor visitor = |
| 234 new ClassResolverVisitor(compiler, element.getLibrary(), element); | 234 new ClassResolverVisitor(compiler, element); |
| 235 visitor.visit(tree); | 235 visitor.visit(tree); |
| 236 element.isBeingResolved = false; | 236 element.isBeingResolved = false; |
| 237 element.isResolved = true; | 237 element.isResolved = true; |
| 238 | 238 |
| 239 while (!toResolve.isEmpty()) { | 239 while (!toResolve.isEmpty()) { |
| 240 ClassElement classElement = toResolve.removeFirst(); | 240 ClassElement classElement = toResolve.removeFirst(); |
| 241 classElement.ensureResolved(compiler); | 241 classElement.ensureResolved(compiler); |
| 242 } | 242 } |
| 243 | 243 |
| 244 checkMembers(element); | 244 checkMembers(element); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 337 compiler, node.parameters, node.returnType, element)); | 337 compiler, node.parameters, node.returnType, element)); |
| 338 }); | 338 }); |
| 339 } | 339 } |
| 340 | 340 |
| 341 FunctionSignature resolveFunctionExpression(Element element, | 341 FunctionSignature resolveFunctionExpression(Element element, |
| 342 FunctionExpression node) { | 342 FunctionExpression node) { |
| 343 return measure(() => SignatureResolver.analyze( | 343 return measure(() => SignatureResolver.analyze( |
| 344 compiler, node.parameters, node.returnType, element)); | 344 compiler, node.parameters, node.returnType, element)); |
| 345 } | 345 } |
| 346 | 346 |
| 347 FunctionSignature resolveTypedef(TypedefElement element) { | 347 void resolveTypedef(TypedefElement element) { |
| 348 return compiler.withCurrentElement(element, () { | 348 return compiler.withCurrentElement(element, () { |
| 349 Typedef node = | 349 measure(() { |
| 350 Typedef node = | |
| 350 compiler.parser.measure(() => element.parseNode(compiler)); | 351 compiler.parser.measure(() => element.parseNode(compiler)); |
| 351 return measure(() => SignatureResolver.analyze( | 352 TypedefResolverVisitor visitor = |
| 352 compiler, node.formals, node.returnType, element)); | 353 new TypedefResolverVisitor(compiler, element); |
| 354 visitor.visit(node); | |
| 355 }); | |
| 353 }); | 356 }); |
| 354 } | 357 } |
| 355 | 358 |
| 356 FunctionType computeFunctionType(Element element, | 359 FunctionType computeFunctionType(Element element, |
| 357 FunctionSignature signature) { | 360 FunctionSignature signature) { |
| 358 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); | 361 LinkBuilder<Type> parameterTypes = new LinkBuilder<Type>(); |
| 359 for (Link<Element> link = signature.requiredParameters; | 362 for (Link<Element> link = signature.requiredParameters; |
| 360 !link.isEmpty(); | 363 !link.isEmpty(); |
| 361 link = link.tail) { | 364 link = link.tail) { |
| 362 parameterTypes.addLast(link.head.computeType(compiler)); | 365 parameterTypes.addLast(link.head.computeType(compiler)); |
| 363 // TODO(karlklose): optional parameters. | 366 // TODO(karlklose): optional parameters. |
| 364 } | 367 } |
| 365 return new FunctionType(signature.returnType, | 368 return new FunctionType(signature.returnType, |
| 366 parameterTypes.toLink(), | 369 parameterTypes.toLink(), |
| 367 element); | 370 element); |
| 368 } | 371 } |
| 369 | 372 |
| 370 error(Node node, MessageKind kind, [arguments = const []]) { | 373 error(Node node, MessageKind kind, [arguments = const []]) { |
| 371 ResolutionError message = new ResolutionError(kind, arguments); | 374 ResolutionError message = new ResolutionError(kind, arguments); |
| 372 compiler.reportError(node, message); | 375 compiler.reportError(node, message); |
| 373 } | 376 } |
| 377 | |
| 378 warning(Node node, MessageKind kind, [arguments = const []]) { | |
| 379 ResolutionWarning message = new ResolutionWarning(kind, arguments); | |
| 380 compiler.reportWarning(node, message); | |
| 381 } | |
| 374 } | 382 } |
| 375 | 383 |
| 376 class InitializerResolver { | 384 class InitializerResolver { |
| 377 final ResolverVisitor visitor; | 385 final ResolverVisitor visitor; |
| 378 final Map<SourceString, Node> initialized; | 386 final Map<SourceString, Node> initialized; |
| 379 Link<Node> initializers; | 387 Link<Node> initializers; |
| 380 bool hasSuper; | 388 bool hasSuper; |
| 381 | 389 |
| 382 InitializerResolver(this.visitor) | 390 InitializerResolver(this.visitor) |
| 383 : initialized = new Map<SourceString, Node>(), hasSuper = false; | 391 : initialized = new Map<SourceString, Node>(), hasSuper = false; |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 562 return null; // If there was no redirection always return null. | 570 return null; // If there was no redirection always return null. |
| 563 } | 571 } |
| 564 } | 572 } |
| 565 | 573 |
| 566 class CommonResolverVisitor<R> extends AbstractVisitor<R> { | 574 class CommonResolverVisitor<R> extends AbstractVisitor<R> { |
| 567 final Compiler compiler; | 575 final Compiler compiler; |
| 568 | 576 |
| 569 CommonResolverVisitor(Compiler this.compiler); | 577 CommonResolverVisitor(Compiler this.compiler); |
| 570 | 578 |
| 571 R visitNode(Node node) { | 579 R visitNode(Node node) { |
| 572 cancel(node, 'internal error'); | 580 cancel(node, |
| 581 'internal error: Unhandled node: ${node.getObjectDescription()}'); | |
| 573 } | 582 } |
| 574 | 583 |
| 575 R visitEmptyStatement(Node node) => null; | 584 R visitEmptyStatement(Node node) => null; |
| 576 | 585 |
| 577 /** Convenience method for visiting nodes that may be null. */ | 586 /** Convenience method for visiting nodes that may be null. */ |
| 578 R visit(Node node) => (node == null) ? null : node.accept(this); | 587 R visit(Node node) => (node == null) ? null : node.accept(this); |
| 579 | 588 |
| 580 void error(Node node, MessageKind kind, [arguments = const []]) { | 589 void error(Node node, MessageKind kind, [arguments = const []]) { |
| 581 ResolutionError message = new ResolutionError(kind, arguments); | 590 ResolutionError message = new ResolutionError(kind, arguments); |
| 582 compiler.reportError(node, message); | 591 compiler.reportError(node, message); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 646 int nestingLevel = 0; | 655 int nestingLevel = 0; |
| 647 | 656 |
| 648 StatementScope() | 657 StatementScope() |
| 649 : labels = const EmptyLabelScope(), | 658 : labels = const EmptyLabelScope(), |
| 650 breakTargetStack = const EmptyLink<TargetElement>(), | 659 breakTargetStack = const EmptyLink<TargetElement>(), |
| 651 continueTargetStack = const EmptyLink<TargetElement>(); | 660 continueTargetStack = const EmptyLink<TargetElement>(); |
| 652 | 661 |
| 653 LabelElement lookupLabel(String label) { | 662 LabelElement lookupLabel(String label) { |
| 654 return labels.lookup(label); | 663 return labels.lookup(label); |
| 655 } | 664 } |
| 665 | |
| 656 TargetElement currentBreakTarget() => | 666 TargetElement currentBreakTarget() => |
| 657 breakTargetStack.isEmpty() ? null : breakTargetStack.head; | 667 breakTargetStack.isEmpty() ? null : breakTargetStack.head; |
| 658 | 668 |
| 659 TargetElement currentContinueTarget() => | 669 TargetElement currentContinueTarget() => |
| 660 continueTargetStack.isEmpty() ? null : continueTargetStack.head; | 670 continueTargetStack.isEmpty() ? null : continueTargetStack.head; |
| 661 | 671 |
| 662 void enterLabelScope(Map<String, LabelElement> elements) { | 672 void enterLabelScope(Map<String, LabelElement> elements) { |
| 663 labels = new LabeledStatementLabelScope(labels, elements); | 673 labels = new LabeledStatementLabelScope(labels, elements); |
| 664 nestingLevel++; | 674 nestingLevel++; |
| 665 } | 675 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 690 | 700 |
| 691 void exitSwitch() { | 701 void exitSwitch() { |
| 692 nestingLevel--; | 702 nestingLevel--; |
| 693 breakTargetStack = breakTargetStack.tail; | 703 breakTargetStack = breakTargetStack.tail; |
| 694 labels = labels.outer; | 704 labels = labels.outer; |
| 695 } | 705 } |
| 696 } | 706 } |
| 697 | 707 |
| 698 class TypeResolver { | 708 class TypeResolver { |
| 699 final Compiler compiler; | 709 final Compiler compiler; |
| 710 | |
| 700 TypeResolver(this.compiler); | 711 TypeResolver(this.compiler); |
| 701 | 712 |
| 702 Element resolveTypeName(Scope context, TypeAnnotation node) { | 713 Element resolveTypeName(Scope scope, TypeAnnotation node) { |
| 703 Identifier typeName = node.typeName.asIdentifier(); | 714 Identifier typeName = node.typeName.asIdentifier(); |
| 704 Send send = node.typeName.asSend(); | 715 Send send = node.typeName.asSend(); |
| 716 return resolveTypeNameInternal(scope, typeName, send); | |
| 717 } | |
| 718 | |
| 719 Element resolveTypeNameInternal(Scope scope, Identifier typeName, Send send) { | |
| 705 if (send !== null) { | 720 if (send !== null) { |
| 706 typeName = send.selector; | 721 typeName = send.selector; |
| 707 } | 722 } |
| 708 if (typeName.source.stringValue === 'void') { | 723 if (typeName.source.stringValue === 'void') { |
| 709 return compiler.types.voidType.element; | 724 return compiler.types.voidType.element; |
| 710 } else if (send !== null) { | 725 } else if (send !== null) { |
| 711 Element e = context.lookup(send.receiver.asIdentifier().source); | 726 Element e = scope.lookup(send.receiver.asIdentifier().source); |
| 712 if (e !== null && e.kind === ElementKind.PREFIX) { | 727 if (e !== null && e.kind === ElementKind.PREFIX) { |
| 713 // The receiver is a prefix. Lookup in the imported members. | 728 // The receiver is a prefix. Lookup in the imported members. |
| 714 PrefixElement prefix = e; | 729 PrefixElement prefix = e; |
| 715 return prefix.lookupLocalMember(typeName.source); | 730 return prefix.lookupLocalMember(typeName.source); |
| 716 } else if (e !== null && e.kind === ElementKind.CLASS) { | 731 } else if (e !== null && e.kind === ElementKind.CLASS) { |
| 717 // The receiver is the class part of a named constructor. | 732 // The receiver is the class part of a named constructor. |
| 718 return e; | 733 return e; |
| 719 } else { | 734 } else { |
| 720 return null; | 735 return null; |
| 721 } | 736 } |
| 722 } else { | 737 } else { |
| 723 return context.lookup(typeName.source); | 738 return scope.lookup(typeName.source); |
| 724 } | 739 } |
| 725 } | 740 } |
| 726 | 741 |
| 742 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean | |
| 743 // flags instead of closures. | |
| 727 Type resolveTypeAnnotation(TypeAnnotation node, | 744 Type resolveTypeAnnotation(TypeAnnotation node, |
| 728 [Scope inContext, ClassElement inClass, | 745 [Scope inScope, ClassElement inClass, |
| 729 onFailure(Node, MessageKind, [List arguments]), | 746 onFailure(Node, MessageKind, [List arguments]), |
| 730 whenResolved(Node, Type)]) { | 747 whenResolved(Node, Type)]) { |
| 731 if (onFailure === null) { | 748 if (onFailure === null) { |
| 732 onFailure = (n, k, [arguments]) {}; | 749 onFailure = (n, k, [arguments]) {}; |
| 733 } | 750 } |
| 734 if (whenResolved === null) { | 751 if (whenResolved === null) { |
| 735 whenResolved = (n, t) {}; | 752 whenResolved = (n, t) {}; |
| 736 } | 753 } |
| 737 if (inClass !== null) { | 754 if (inClass !== null) { |
| 738 inContext = new ClassScope(inClass, inClass.getLibrary()); | 755 inScope = inClass.buildScope();//new ClassScope(inClass, inClass.getLibrar y()); |
|
ahe
2012/08/02 06:43:14
Remove comment.
| |
| 739 } | 756 } |
| 740 if (inContext === null) { | 757 if (inScope === null) { |
| 741 compiler.internalError('resolveTypeAnnotation: no scope specified'); | 758 compiler.internalError('resolveTypeAnnotation: no scope specified'); |
| 742 } | 759 } |
| 743 return resolveTypeAnnotationInContext(inContext, node, onFailure, | 760 return resolveTypeAnnotationInContext(inScope, node, onFailure, |
| 744 whenResolved); | 761 whenResolved); |
| 745 } | 762 } |
| 746 | 763 |
| 747 Type resolveTypeAnnotationInContext(Scope context, TypeAnnotation node, | 764 Type resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node, |
| 748 onFailure, whenResolved) { | 765 onFailure, whenResolved) { |
| 749 Element element = resolveTypeName(context, node); | 766 Element element = resolveTypeName(scope, node); |
| 750 Type type; | 767 Type type; |
| 751 if (element === null) { | 768 if (element === null) { |
| 752 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); | 769 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); |
| 753 } else if (!element.impliesType()) { | 770 } else if (!element.impliesType()) { |
| 754 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); | 771 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); |
| 755 } else { | 772 } else { |
| 756 if (element === compiler.types.voidType.element || | 773 if (element === compiler.types.voidType.element || |
| 757 element === compiler.types.dynamicType.element) { | 774 element === compiler.types.dynamicType.element) { |
| 758 type = element.computeType(compiler); | 775 type = element.computeType(compiler); |
| 759 } else if (element.isClass()) { | 776 } else if (element.isClass()) { |
| 760 ClassElement cls = element; | 777 ClassElement cls = element; |
| 761 if (!cls.isResolved) compiler.resolveClass(cls); | 778 compiler.resolver.toResolve.add(cls); |
|
ahe
2012/08/02 06:43:14
Please add a comment to explain why it is safe to
| |
| 762 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); | 779 cls.computeType(compiler); |
| 763 if (node.typeArguments !== null) { | 780 Link<Type> typeArguments = resolveTypeArguments( |
| 764 int index = 0; | 781 node, cls.typeVariables, |
| 765 for (Link<Node> typeArguments = node.typeArguments.nodes; | 782 scope, onFailure, whenResolved); |
| 766 !typeArguments.isEmpty(); | 783 if (cls.typeVariables.isEmpty()) { |
| 767 typeArguments = typeArguments.tail) { | |
| 768 if (++index > cls.typeParameters.length) { | |
| 769 onFailure(typeArguments.head, | |
| 770 MessageKind.ADDITIONAL_TYPE_ARGUMENT); | |
| 771 } | |
| 772 Type argType = resolveTypeAnnotationInContext(context, | |
| 773 typeArguments.head, | |
| 774 onFailure, | |
| 775 whenResolved); | |
| 776 arguments.addLast(argType); | |
| 777 } | |
| 778 if (index < cls.typeParameters.length) { | |
| 779 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | |
| 780 } | |
| 781 } | |
| 782 if (cls.typeParameters.length == 0) { | |
| 783 // Return the canonical type if it has no type parameters. | 784 // Return the canonical type if it has no type parameters. |
| 784 type = cls.computeType(compiler); | 785 type = cls.computeType(compiler); |
| 785 } else { | 786 } else { |
| 786 type = new InterfaceType(cls, arguments.toLink()); | 787 type = new InterfaceType(cls, typeArguments); |
| 787 } | 788 } |
| 788 } else if (element.isTypedef()) { | 789 } else if (element.isTypedef()) { |
| 789 type = element.computeType(compiler); | 790 TypedefElement typdef = element; |
| 791 // TODO(johnniwinther): Do we need to resolve the typedef? | |
| 792 typdef.computeType(compiler); | |
| 793 Link<Type> typeArguments = resolveTypeArguments( | |
| 794 node, typdef.typeVariables, | |
| 795 scope, onFailure, whenResolved); | |
| 796 if (typdef.typeVariables.isEmpty()) { | |
| 797 // Return the canonical type if it has no type parameters. | |
| 798 type = typdef.computeType(compiler); | |
| 799 } else { | |
| 800 type = new TypedefType(typdef, typeArguments); | |
| 801 } | |
| 790 } else if (element.isTypeVariable()) { | 802 } else if (element.isTypeVariable()) { |
| 791 type = element.computeType(compiler); | 803 type = element.computeType(compiler); |
| 792 } else { | 804 } else { |
| 793 compiler.cancel("unexpected element kind ${element.kind}", | 805 compiler.cancel("unexpected element kind ${element.kind}", |
| 794 node: node); | 806 node: node); |
| 795 } | 807 } |
| 796 } | 808 } |
| 797 whenResolved(node, type); | 809 whenResolved(node, type); |
| 798 return type; | 810 return type; |
| 799 } | 811 } |
| 812 | |
| 813 Link<Type> resolveTypeArguments(TypeAnnotation node, | |
| 814 Link<TypeVariableType> typeVariables, | |
| 815 Scope scope, onFailure, whenResolved) { | |
| 816 if (node.typeArguments == null) { | |
| 817 return const EmptyLink<Type>(); | |
| 818 } | |
| 819 var arguments = new LinkBuilder<Type>(); | |
| 820 for (Link<Node> typeArguments = node.typeArguments.nodes; | |
| 821 !typeArguments.isEmpty(); | |
| 822 typeArguments = typeArguments.tail) { | |
| 823 if (typeVariables.isEmpty()) { | |
| 824 onFailure(typeArguments.head, MessageKind.ADDITIONAL_TYPE_ARGUMENT); | |
| 825 } | |
| 826 Node typeArgument = typeArguments.head; | |
| 827 Type argType; | |
| 828 if (typeArgument is TypeAnnotation) { | |
|
ahe
2012/08/02 06:43:14
typeArgument.asTypeAnnotation() !== null
| |
| 829 argType = resolveTypeAnnotationInContext(scope, | |
| 830 typeArgument, | |
| 831 onFailure, | |
| 832 whenResolved); | |
| 833 } else if (typeArgument is TypeVariable) { | |
|
ahe
2012/08/02 06:43:14
asTypeVariable
| |
| 834 // This happens in default clauses! | |
|
ahe
2012/08/02 06:43:14
This case is really not making any sense to me.
| |
| 835 Element element = resolveTypeNameInternal(scope, typeArgument.name, | |
| 836 null); | |
| 837 if (element === null) { | |
| 838 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [typeArgument.name]); | |
|
ahe
2012/08/02 06:43:14
Doesn't the spec say that the type variables must
| |
| 839 } else if (!element.impliesType()) { | |
| 840 onFailure(node, MessageKind.NOT_A_TYPE, [typeArgument.name]); | |
| 841 } else if (!element.isTypeVariable()) { | |
| 842 onFailure(node, MessageKind.GENERIC, | |
| 843 ["Default clauses can only contain type variables."]); | |
| 844 } else { | |
| 845 TypeVariableElement typeVariableElement = element; | |
| 846 argType = typeVariableElement.type; | |
| 847 } | |
| 848 } | |
| 849 arguments.addLast(argType); | |
| 850 if (!typeVariables.isEmpty()) { | |
| 851 typeVariables = typeVariables.tail; | |
| 852 } | |
| 853 } | |
| 854 if (!typeVariables.isEmpty()) { | |
| 855 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); | |
| 856 } | |
| 857 return arguments.toLink(); | |
| 858 } | |
| 800 } | 859 } |
| 801 | 860 |
| 802 class ResolverVisitor extends CommonResolverVisitor<Element> { | 861 class ResolverVisitor extends CommonResolverVisitor<Element> { |
| 803 final TreeElementMapping mapping; | 862 final TreeElementMapping mapping; |
| 804 final Element enclosingElement; | 863 final Element enclosingElement; |
| 805 final TypeResolver typeResolver; | 864 final TypeResolver typeResolver; |
| 806 bool inInstanceContext; | 865 bool inInstanceContext; |
| 807 Scope context; | 866 Scope scope; |
| 808 ClassElement currentClass; | 867 ClassElement currentClass; |
| 809 bool typeRequired = false; | 868 bool typeRequired = false; |
| 810 StatementScope statementScope; | 869 StatementScope statementScope; |
| 811 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; | 870 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; |
| 812 | 871 |
| 813 ResolverVisitor(Compiler compiler, Element element) | 872 ResolverVisitor(Compiler compiler, Element element) |
| 814 : this.mapping = new TreeElementMapping(), | 873 : this.mapping = new TreeElementMapping(), |
| 815 this.enclosingElement = element, | 874 this.enclosingElement = element, |
| 816 inInstanceContext = element.isInstanceMember() | 875 inInstanceContext = element.isInstanceMember() |
| 817 || element.isGenerativeConstructor(), | 876 || element.isGenerativeConstructor(), |
| 818 this.currentClass = element.isMember() ? element.enclosingElement : null, | 877 this.currentClass = element.isMember() ? element.enclosingElement : null, |
| 819 this.statementScope = new StatementScope(), | 878 this.statementScope = new StatementScope(), |
| 820 typeResolver = new TypeResolver(compiler), | 879 typeResolver = new TypeResolver(compiler), |
| 880 scope = element.buildEnclosingScope(), | |
| 821 super(compiler) { | 881 super(compiler) { |
| 822 LibraryElement library = element.getLibrary(); | 882 if (element.enclosingElement == null) { |
| 823 element = element.getEnclosingMember(); | 883 print(element); |
| 824 if (element !== null) { | 884 } |
| 825 context = new ClassScope(element.enclosingElement, library); | |
| 826 } else { | |
| 827 this.context = new TopScope(library); | |
| 828 } | |
| 829 } | 885 } |
| 830 | 886 |
| 831 Enqueuer get world() => compiler.enqueuer.resolution; | 887 Enqueuer get world() => compiler.enqueuer.resolution; |
| 832 | 888 |
| 833 Element lookup(Node node, SourceString name) { | 889 Element lookup(Node node, SourceString name) { |
| 834 Element result = context.lookup(name); | 890 Element result = scope.lookup(name); |
| 835 if (!inInstanceContext && result != null && result.isInstanceMember()) { | 891 if (!inInstanceContext && result != null && result.isInstanceMember()) { |
| 836 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); | 892 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); |
| 837 } | 893 } |
| 838 return result; | 894 return result; |
| 839 } | 895 } |
| 840 | 896 |
| 841 // Create, or reuse an already created, statement element for a statement. | 897 // Create, or reuse an already created, statement element for a statement. |
| 842 TargetElement getOrCreateTargetElement(Node statement) { | 898 TargetElement getOrCreateTargetElement(Node statement) { |
| 843 TargetElement element = mapping[statement]; | 899 TargetElement element = mapping[statement]; |
| 844 if (element === null) { | 900 if (element === null) { |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 870 return null; | 926 return null; |
| 871 } else if (node.isSuper()) { | 927 } else if (node.isSuper()) { |
| 872 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); | 928 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); |
| 873 if ((ElementCategory.SUPER & allowedCategory) == 0) { | 929 if ((ElementCategory.SUPER & allowedCategory) == 0) { |
| 874 error(node, MessageKind.INVALID_USE_OF_SUPER); | 930 error(node, MessageKind.INVALID_USE_OF_SUPER); |
| 875 } | 931 } |
| 876 return null; | 932 return null; |
| 877 } else { | 933 } else { |
| 878 Element element = lookup(node, node.source); | 934 Element element = lookup(node, node.source); |
| 879 if (element === null) { | 935 if (element === null) { |
| 880 if (!inInstanceContext) error(node, MessageKind.CANNOT_RESOLVE, [node]); | 936 if (!inInstanceContext) { |
| 937 error(node, MessageKind.CANNOT_RESOLVE, [node]); | |
| 938 } | |
| 881 } else { | 939 } else { |
| 882 if ((element.kind.category & allowedCategory) == 0) { | 940 if ((element.kind.category & allowedCategory) == 0) { |
| 883 // TODO(ahe): Improve error message. Need UX input. | 941 // TODO(ahe): Improve error message. Need UX input. |
| 884 error(node, MessageKind.GENERIC, ["is not an expression $element"]); | 942 error(node, MessageKind.GENERIC, ["is not an expression $element"]); |
| 885 } | 943 } |
| 886 } | 944 } |
| 887 return useElement(node, element); | 945 return useElement(node, element); |
| 888 } | 946 } |
| 889 } | 947 } |
| 890 | 948 |
| 891 Element visitTypeAnnotation(TypeAnnotation node) { | 949 Element visitTypeAnnotation(TypeAnnotation node) { |
| 892 Type type = resolveTypeAnnotation(node); | 950 Type type = resolveTypeAnnotation(node); |
| 893 if (type !== null) return type.element; | 951 if (type !== null) return type.element; |
| 894 return null; | 952 return null; |
| 895 } | 953 } |
| 896 | 954 |
| 897 Element defineElement(Node node, Element element, | 955 Element defineElement(Node node, Element element, |
| 898 [bool doAddToScope = true]) { | 956 [bool doAddToScope = true]) { |
| 899 compiler.ensure(element !== null); | 957 compiler.ensure(element !== null); |
| 900 mapping[node] = element; | 958 mapping[node] = element; |
| 901 if (doAddToScope) { | 959 if (doAddToScope) { |
| 902 Element existing = context.add(element); | 960 Element existing = scope.add(element); |
| 903 if (existing != element) { | 961 if (existing != element) { |
| 904 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); | 962 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); |
| 905 } | 963 } |
| 906 } | 964 } |
| 907 return element; | 965 return element; |
| 908 } | 966 } |
| 909 | 967 |
| 910 Element useElement(Node node, Element element) { | 968 Element useElement(Node node, Element element) { |
| 911 if (element === null) return null; | 969 if (element === null) return null; |
| 912 mapping[node] = element; | 970 mapping[node] = element; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 933 | 991 |
| 934 Type useType(TypeAnnotation annotation, Type type) { | 992 Type useType(TypeAnnotation annotation, Type type) { |
| 935 if (type !== null) { | 993 if (type !== null) { |
| 936 mapping.setType(annotation, type); | 994 mapping.setType(annotation, type); |
| 937 useElement(annotation, type.element); | 995 useElement(annotation, type.element); |
| 938 } | 996 } |
| 939 return type; | 997 return type; |
| 940 } | 998 } |
| 941 | 999 |
| 942 void setupFunction(FunctionExpression node, FunctionElement function) { | 1000 void setupFunction(FunctionExpression node, FunctionElement function) { |
| 943 context = new MethodScope(context, function); | 1001 scope = new MethodScope(scope, function); |
| 944 if (node.returnType !== null) resolveTypeAnnotation(node.returnType); | 1002 if (node.returnType !== null) resolveTypeAnnotation(node.returnType); |
| 945 // Put the parameters in scope. | 1003 // Put the parameters in scope. |
| 946 FunctionSignature functionParameters = | 1004 FunctionSignature functionParameters = |
| 947 function.computeSignature(compiler); | 1005 function.computeSignature(compiler); |
| 948 Link<Node> parameterNodes = node.parameters.nodes; | 1006 Link<Node> parameterNodes = node.parameters.nodes; |
| 949 functionParameters.forEachParameter((Element element) { | 1007 functionParameters.forEachParameter((Element element) { |
| 950 if (element == functionParameters.optionalParameters.head) { | 1008 if (element == functionParameters.optionalParameters.head) { |
| 951 NodeList nodes = parameterNodes.head; | 1009 NodeList nodes = parameterNodes.head; |
| 952 parameterNodes = nodes.nodes; | 1010 parameterNodes = nodes.nodes; |
| 953 } | 1011 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 970 } | 1028 } |
| 971 | 1029 |
| 972 visitCascadeReceiver(CascadeReceiver node) { | 1030 visitCascadeReceiver(CascadeReceiver node) { |
| 973 visit(node.expression); | 1031 visit(node.expression); |
| 974 } | 1032 } |
| 975 | 1033 |
| 976 Element visitClassNode(ClassNode node) { | 1034 Element visitClassNode(ClassNode node) { |
| 977 cancel(node, "shouldn't be called"); | 1035 cancel(node, "shouldn't be called"); |
| 978 } | 1036 } |
| 979 | 1037 |
| 980 visitIn(Node node, Scope scope) { | 1038 visitIn(Node node, Scope nestedScope) { |
| 981 context = scope; | 1039 scope = nestedScope; |
| 982 Element element = visit(node); | 1040 Element element = visit(node); |
| 983 context = context.parent; | 1041 scope = scope.parent; |
| 984 return element; | 1042 return element; |
| 985 } | 1043 } |
| 986 | 1044 |
| 987 /** | 1045 /** |
| 988 * Introduces new default targets for break and continue | 1046 * Introduces new default targets for break and continue |
| 989 * before visiting the body of the loop | 1047 * before visiting the body of the loop |
| 990 */ | 1048 */ |
| 991 visitLoopBodyIn(Node loop, Node body, Scope scope) { | 1049 visitLoopBodyIn(Node loop, Node body, Scope bodyScope) { |
| 992 TargetElement element = getOrCreateTargetElement(loop); | 1050 TargetElement element = getOrCreateTargetElement(loop); |
| 993 statementScope.enterLoop(element); | 1051 statementScope.enterLoop(element); |
| 994 visitIn(body, scope); | 1052 visitIn(body, bodyScope); |
| 995 statementScope.exitLoop(); | 1053 statementScope.exitLoop(); |
| 996 if (!element.isTarget) { | 1054 if (!element.isTarget) { |
| 997 mapping.remove(loop); | 1055 mapping.remove(loop); |
| 998 } | 1056 } |
| 999 } | 1057 } |
| 1000 | 1058 |
| 1001 visitBlock(Block node) { | 1059 visitBlock(Block node) { |
| 1002 visitIn(node.statements, new BlockScope(context)); | 1060 visitIn(node.statements, new BlockScope(scope)); |
| 1003 } | 1061 } |
| 1004 | 1062 |
| 1005 visitDoWhile(DoWhile node) { | 1063 visitDoWhile(DoWhile node) { |
| 1006 visitLoopBodyIn(node, node.body, new BlockScope(context)); | 1064 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 1007 visit(node.condition); | 1065 visit(node.condition); |
| 1008 } | 1066 } |
| 1009 | 1067 |
| 1010 visitEmptyStatement(EmptyStatement node) { } | 1068 visitEmptyStatement(EmptyStatement node) { } |
| 1011 | 1069 |
| 1012 visitExpressionStatement(ExpressionStatement node) { | 1070 visitExpressionStatement(ExpressionStatement node) { |
| 1013 visit(node.expression); | 1071 visit(node.expression); |
| 1014 } | 1072 } |
| 1015 | 1073 |
| 1016 visitFor(For node) { | 1074 visitFor(For node) { |
| 1017 Scope scope = new BlockScope(context); | 1075 Scope blockScope = new BlockScope(scope); |
| 1018 visitIn(node.initializer, scope); | 1076 visitIn(node.initializer, blockScope); |
| 1019 visitIn(node.condition, scope); | 1077 visitIn(node.condition, blockScope); |
| 1020 visitIn(node.update, scope); | 1078 visitIn(node.update, blockScope); |
| 1021 visitLoopBodyIn(node, node.body, scope); | 1079 visitLoopBodyIn(node, node.body, blockScope); |
| 1022 } | 1080 } |
| 1023 | 1081 |
| 1024 visitFunctionDeclaration(FunctionDeclaration node) { | 1082 visitFunctionDeclaration(FunctionDeclaration node) { |
| 1025 assert(node.function.name !== null); | 1083 assert(node.function.name !== null); |
| 1026 visit(node.function); | 1084 visit(node.function); |
| 1027 FunctionElement functionElement = mapping[node.function]; | 1085 FunctionElement functionElement = mapping[node.function]; |
| 1028 // TODO(floitsch): this might lead to two errors complaining about | 1086 // TODO(floitsch): this might lead to two errors complaining about |
| 1029 // shadowing. | 1087 // shadowing. |
| 1030 defineElement(node, functionElement); | 1088 defineElement(node, functionElement); |
| 1031 } | 1089 } |
| 1032 | 1090 |
| 1033 visitFunctionExpression(FunctionExpression node) { | 1091 visitFunctionExpression(FunctionExpression node) { |
| 1034 visit(node.returnType); | 1092 visit(node.returnType); |
| 1035 SourceString name; | 1093 SourceString name; |
| 1036 if (node.name === null) { | 1094 if (node.name === null) { |
| 1037 name = const SourceString(""); | 1095 name = const SourceString(""); |
| 1038 } else { | 1096 } else { |
| 1039 name = node.name.asIdentifier().source; | 1097 name = node.name.asIdentifier().source; |
| 1040 } | 1098 } |
| 1041 FunctionElement enclosing = new FunctionElement.node( | 1099 FunctionElement enclosing = new FunctionElement.node( |
| 1042 name, node, ElementKind.FUNCTION, new Modifiers.empty(), | 1100 name, node, ElementKind.FUNCTION, new Modifiers.empty(), |
| 1043 context.element); | 1101 scope.element); |
| 1044 setupFunction(node, enclosing); | 1102 setupFunction(node, enclosing); |
| 1045 defineElement(node, enclosing, doAddToScope: node.name !== null); | 1103 defineElement(node, enclosing, doAddToScope: node.name !== null); |
| 1046 | 1104 |
| 1047 // Run the body in a fresh statement scope. | 1105 // Run the body in a fresh statement scope. |
| 1048 StatementScope oldScope = statementScope; | 1106 StatementScope oldScope = statementScope; |
| 1049 statementScope = new StatementScope(); | 1107 statementScope = new StatementScope(); |
| 1050 visit(node.body); | 1108 visit(node.body); |
| 1051 statementScope = oldScope; | 1109 statementScope = oldScope; |
| 1052 | 1110 |
| 1053 context = context.parent; | 1111 scope = scope.parent; |
| 1054 } | 1112 } |
| 1055 | 1113 |
| 1056 visitIf(If node) { | 1114 visitIf(If node) { |
| 1057 visit(node.condition); | 1115 visit(node.condition); |
| 1058 visit(node.thenPart); | 1116 visit(node.thenPart); |
| 1059 visit(node.elsePart); | 1117 visit(node.elsePart); |
| 1060 } | 1118 } |
| 1061 | 1119 |
| 1062 static bool isLogicalOperator(Identifier op) { | 1120 static bool isLogicalOperator(Identifier op) { |
| 1063 String str = op.source.stringValue; | 1121 String str = op.source.stringValue; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1313 visitVariableDefinitions(VariableDefinitions node) { | 1371 visitVariableDefinitions(VariableDefinitions node) { |
| 1314 visit(node.type); | 1372 visit(node.type); |
| 1315 VariableDefinitionsVisitor visitor = | 1373 VariableDefinitionsVisitor visitor = |
| 1316 new VariableDefinitionsVisitor(compiler, node, this, | 1374 new VariableDefinitionsVisitor(compiler, node, this, |
| 1317 ElementKind.VARIABLE); | 1375 ElementKind.VARIABLE); |
| 1318 visitor.visit(node.definitions); | 1376 visitor.visit(node.definitions); |
| 1319 } | 1377 } |
| 1320 | 1378 |
| 1321 visitWhile(While node) { | 1379 visitWhile(While node) { |
| 1322 visit(node.condition); | 1380 visit(node.condition); |
| 1323 visitLoopBodyIn(node, node.body, new BlockScope(context)); | 1381 visitLoopBodyIn(node, node.body, new BlockScope(scope)); |
| 1324 } | 1382 } |
| 1325 | 1383 |
| 1326 visitParenthesizedExpression(ParenthesizedExpression node) { | 1384 visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1327 visit(node.expression); | 1385 visit(node.expression); |
| 1328 } | 1386 } |
| 1329 | 1387 |
| 1330 visitNewExpression(NewExpression node) { | 1388 visitNewExpression(NewExpression node) { |
| 1331 Node selector = node.send.selector; | 1389 Node selector = node.send.selector; |
| 1332 | 1390 |
| 1333 FunctionElement constructor = resolveConstructor(node); | 1391 FunctionElement constructor = resolveConstructor(node); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1349 world.registerInstantiatedClass(cls); | 1407 world.registerInstantiatedClass(cls); |
| 1350 cls.forEachInstanceField( | 1408 cls.forEachInstanceField( |
| 1351 includeBackendMembers: false, | 1409 includeBackendMembers: false, |
| 1352 includeSuperMembers: true, | 1410 includeSuperMembers: true, |
| 1353 f: (ClassElement enclosingClass, Element member) { | 1411 f: (ClassElement enclosingClass, Element member) { |
| 1354 world.addToWorkList(member); | 1412 world.addToWorkList(member); |
| 1355 }); | 1413 }); |
| 1356 return null; | 1414 return null; |
| 1357 } | 1415 } |
| 1358 | 1416 |
| 1359 TypeAnnotation getTypeAnnotationFromSend(Send send) { | |
| 1360 if (send.selector.asTypeAnnotation() !== null) { | |
| 1361 return send.selector; | |
| 1362 } else if (send.selector.asSend() !== null) { | |
| 1363 Send selector = send.selector; | |
| 1364 if (selector.receiver.asTypeAnnotation() !== null) { | |
| 1365 return selector.receiver; | |
| 1366 } | |
| 1367 } else { | |
| 1368 compiler.internalError("malformed send in new expression"); | |
| 1369 } | |
| 1370 } | |
| 1371 | |
| 1372 FunctionElement resolveConstructor(NewExpression node) { | 1417 FunctionElement resolveConstructor(NewExpression node) { |
| 1373 FunctionElement constructor = | 1418 FunctionElement constructor = |
| 1374 node.accept(new ConstructorResolver(compiler, this)); | 1419 node.accept(new ConstructorResolver(compiler, this)); |
| 1375 TypeAnnotation annotation = getTypeAnnotationFromSend(node.send); | 1420 TypeAnnotation annotation = node.getTypeAnnotation(); |
| 1421 if (annotation == null) { | |
| 1422 compiler.internalError("malformed send in new expression"); | |
| 1423 } | |
| 1376 Type type = resolveTypeRequired(annotation); | 1424 Type type = resolveTypeRequired(annotation); |
| 1377 if (constructor === null) { | 1425 if (constructor === null) { |
| 1378 Element resolved = (type != null) ? type.element : null; | 1426 Element resolved = (type != null) ? type.element : null; |
| 1379 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { | 1427 if (resolved !== null && resolved.kind === ElementKind.TYPE_VARIABLE) { |
| 1380 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR); | 1428 error(node, MessageKind.TYPE_VARIABLE_AS_CONSTRUCTOR); |
| 1381 return null; | 1429 return null; |
| 1382 } else { | 1430 } else { |
| 1383 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); | 1431 error(node.send, MessageKind.CANNOT_FIND_CONSTRUCTOR, [node.send]); |
| 1384 return null; | 1432 return null; |
| 1385 } | 1433 } |
| 1434 } else { | |
| 1435 useType(annotation, type); | |
| 1386 } | 1436 } |
| 1387 return constructor; | 1437 return constructor; |
| 1388 } | 1438 } |
| 1389 | 1439 |
| 1390 Type resolveTypeRequired(TypeAnnotation node) { | 1440 Type resolveTypeRequired(TypeAnnotation node) { |
| 1391 bool old = typeRequired; | 1441 bool old = typeRequired; |
| 1392 typeRequired = true; | 1442 typeRequired = true; |
| 1393 Type result = resolveTypeAnnotation(node); | 1443 Type result = resolveTypeAnnotation(node); |
| 1394 typeRequired = old; | 1444 typeRequired = old; |
| 1395 return result; | 1445 return result; |
| 1396 } | 1446 } |
| 1397 | 1447 |
| 1398 Type resolveTypeAnnotation(TypeAnnotation node) { | 1448 Type resolveTypeAnnotation(TypeAnnotation node) { |
| 1399 Function report = typeRequired ? error : warning; | 1449 Function report = typeRequired ? error : warning; |
| 1400 return typeResolver.resolveTypeAnnotation(node, inContext: context, | 1450 return typeResolver.resolveTypeAnnotation(node, inScope: scope, |
| 1401 onFailure: report, | 1451 onFailure: report, |
| 1402 whenResolved: useType); | 1452 whenResolved: useType); |
| 1403 } | 1453 } |
| 1404 | 1454 |
| 1405 visitModifiers(Modifiers node) { | 1455 visitModifiers(Modifiers node) { |
| 1406 // TODO(ngeoffray): Implement this. | 1456 // TODO(ngeoffray): Implement this. |
| 1407 unimplemented(node, 'modifiers'); | 1457 unimplemented(node, 'modifiers'); |
| 1408 } | 1458 } |
| 1409 | 1459 |
| 1410 visitLiteralList(LiteralList node) { | 1460 visitLiteralList(LiteralList node) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1475 unimplemented(node, "continue to switch case"); | 1525 unimplemented(node, "continue to switch case"); |
| 1476 } | 1526 } |
| 1477 label.setContinueTarget(); | 1527 label.setContinueTarget(); |
| 1478 mapping[node.target] = label; | 1528 mapping[node.target] = label; |
| 1479 } | 1529 } |
| 1480 mapping[node] = target; | 1530 mapping[node] = target; |
| 1481 } | 1531 } |
| 1482 | 1532 |
| 1483 visitForIn(ForIn node) { | 1533 visitForIn(ForIn node) { |
| 1484 visit(node.expression); | 1534 visit(node.expression); |
| 1485 Scope scope = new BlockScope(context); | 1535 Scope blockScope = new BlockScope(scope); |
| 1486 Node declaration = node.declaredIdentifier; | 1536 Node declaration = node.declaredIdentifier; |
| 1487 visitIn(declaration, scope); | 1537 visitIn(declaration, blockScope); |
| 1488 visitLoopBodyIn(node, node.body, scope); | 1538 visitLoopBodyIn(node, node.body, blockScope); |
| 1489 | 1539 |
| 1490 // TODO(lrn): Also allow a single identifier. | 1540 // TODO(lrn): Also allow a single identifier. |
| 1491 if ((declaration is !Send || declaration.asSend().selector is !Identifier) | 1541 if ((declaration is !Send || declaration.asSend().selector is !Identifier) |
| 1492 && (declaration is !VariableDefinitions || | 1542 && (declaration is !VariableDefinitions || |
| 1493 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty())) | 1543 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty())) |
| 1494 { | 1544 { |
| 1495 // The variable declaration is either not an identifier, not a | 1545 // The variable declaration is either not an identifier, not a |
| 1496 // declaration, or it's declaring more than one variable. | 1546 // declaration, or it's declaring more than one variable. |
| 1497 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); | 1547 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); |
| 1498 } | 1548 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1598 TargetElement targetElement = label.target; | 1648 TargetElement targetElement = label.target; |
| 1599 SwitchCase switchCase = targetElement.statement; | 1649 SwitchCase switchCase = targetElement.statement; |
| 1600 mapping.remove(switchCase); | 1650 mapping.remove(switchCase); |
| 1601 mapping.remove(label.label); | 1651 mapping.remove(label.label); |
| 1602 } | 1652 } |
| 1603 }); | 1653 }); |
| 1604 } | 1654 } |
| 1605 | 1655 |
| 1606 visitSwitchCase(SwitchCase node) { | 1656 visitSwitchCase(SwitchCase node) { |
| 1607 node.labelsAndCases.accept(this); | 1657 node.labelsAndCases.accept(this); |
| 1608 visitIn(node.statements, new BlockScope(context)); | 1658 visitIn(node.statements, new BlockScope(scope)); |
| 1609 } | 1659 } |
| 1610 | 1660 |
| 1611 visitCaseMatch(CaseMatch node) { | 1661 visitCaseMatch(CaseMatch node) { |
| 1612 visit(node.expression); | 1662 visit(node.expression); |
| 1613 } | 1663 } |
| 1614 | 1664 |
| 1615 visitTryStatement(TryStatement node) { | 1665 visitTryStatement(TryStatement node) { |
| 1616 visit(node.tryBlock); | 1666 visit(node.tryBlock); |
| 1617 if (node.catchBlocks.isEmpty() && node.finallyBlock == null) { | 1667 if (node.catchBlocks.isEmpty() && node.finallyBlock == null) { |
| 1618 // TODO(ngeoffray): The precise location is | 1668 // TODO(ngeoffray): The precise location is |
| 1619 // node.getEndtoken.next. Adjust when issue #1581 is fixed. | 1669 // node.getEndtoken.next. Adjust when issue #1581 is fixed. |
| 1620 error(node, MessageKind.NO_CATCH_NOR_FINALLY); | 1670 error(node, MessageKind.NO_CATCH_NOR_FINALLY); |
| 1621 } | 1671 } |
| 1622 visit(node.catchBlocks); | 1672 visit(node.catchBlocks); |
| 1623 visit(node.finallyBlock); | 1673 visit(node.finallyBlock); |
| 1624 } | 1674 } |
| 1625 | 1675 |
| 1626 visitCatchBlock(CatchBlock node) { | 1676 visitCatchBlock(CatchBlock node) { |
| 1627 Scope scope = new BlockScope(context); | 1677 Scope blockScope = new BlockScope(scope); |
| 1628 if (node.formals.isEmpty()) { | 1678 if (node.formals.isEmpty()) { |
| 1629 error(node, MessageKind.EMPTY_CATCH_DECLARATION); | 1679 error(node, MessageKind.EMPTY_CATCH_DECLARATION); |
| 1630 } else if (!node.formals.nodes.tail.isEmpty() | 1680 } else if (!node.formals.nodes.tail.isEmpty() |
| 1631 && !node.formals.nodes.tail.tail.isEmpty()) { | 1681 && !node.formals.nodes.tail.tail.isEmpty()) { |
| 1632 for (Node extra in node.formals.nodes.tail.tail) { | 1682 for (Node extra in node.formals.nodes.tail.tail) { |
| 1633 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); | 1683 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); |
| 1634 } | 1684 } |
| 1635 } | 1685 } |
| 1636 visitIn(node.formals, scope); | 1686 visitIn(node.formals, blockScope); |
| 1637 visitIn(node.block, scope); | 1687 visitIn(node.block, blockScope); |
| 1638 } | 1688 } |
| 1639 | 1689 |
| 1640 visitTypedef(Typedef node) { | 1690 visitTypedef(Typedef node) { |
| 1641 unimplemented(node, 'typedef'); | 1691 unimplemented(node, 'typedef'); |
| 1642 } | 1692 } |
| 1643 } | 1693 } |
| 1644 | 1694 |
| 1645 class ClassResolverVisitor extends CommonResolverVisitor<Type> { | 1695 class TypeDefinitionVisitor extends CommonResolverVisitor<Type> { |
| 1646 Scope context; | 1696 Scope scope; |
| 1647 ClassElement classElement; | 1697 TypeDeclarationElement element; |
| 1698 TypeResolver typeResolver; | |
| 1648 | 1699 |
| 1649 ClassResolverVisitor(Compiler compiler, LibraryElement library, | 1700 TypeDefinitionVisitor(Compiler compiler, TypeDeclarationElement element) |
| 1650 ClassElement this.classElement) | 1701 : this.element = element, |
| 1651 : context = new TopScope(library), | 1702 scope = element.enclosingElement.buildScope(), |
| 1652 super(compiler); | 1703 typeResolver = new TypeResolver(compiler), |
| 1704 super(compiler); | |
| 1653 | 1705 |
| 1654 Type visitClassNode(ClassNode node) { | 1706 void resolveTypeVariableBounds(NodeList node) { |
| 1655 compiler.ensure(classElement !== null); | 1707 if (node === null) return; |
| 1656 compiler.ensure(!classElement.isResolved); | 1708 |
| 1657 final Link<Node> parameters = | 1709 var nameSet = new Set<SourceString>(); |
| 1658 node.typeParameters !== null ? node.typeParameters.nodes | |
| 1659 : const EmptyLink<TypeVariable>(); | |
| 1660 // Create types and elements for type variable. | |
| 1661 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { | |
| 1662 TypeVariable typeNode = link.head; | |
| 1663 SourceString variableName = typeNode.name.source; | |
| 1664 TypeVariableType variableType = new TypeVariableType(variableName); | |
| 1665 TypeVariableElement variableElement = | |
| 1666 new TypeVariableElement(variableName, classElement, node, | |
| 1667 variableType); | |
| 1668 variableType.element = variableElement; | |
| 1669 classElement.typeParameters[variableName] = variableElement; | |
| 1670 context = new TypeVariablesScope(context, classElement); | |
| 1671 } | |
| 1672 // Resolve the bounds of type variables. | 1710 // Resolve the bounds of type variables. |
| 1673 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { | 1711 Link<TypeVariableType> typeLink = element.typeVariables; |
| 1674 TypeVariable typeNode = link.head; | 1712 Link<Node> nodeLink = node.nodes; |
| 1675 SourceString variableName = typeNode.name.source; | 1713 while (!nodeLink.isEmpty()) { |
| 1676 TypeVariableElement variableElement = | 1714 TypeVariableType typeVariable = typeLink.head; |
| 1677 classElement.typeParameters[variableName]; | 1715 SourceString typeName = typeVariable.name; |
| 1716 TypeVariable typeNode = nodeLink.head; | |
| 1717 if (nameSet.contains(typeName)) { | |
| 1718 error(typeNode, MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, [typeName]); | |
| 1719 } | |
| 1720 nameSet.add(typeVariable.name); | |
| 1721 | |
| 1722 TypeVariableElement variableElement = typeVariable.element; | |
| 1678 if (typeNode.bound !== null) { | 1723 if (typeNode.bound !== null) { |
| 1679 Type boundType = visit(typeNode.bound); | 1724 Type boundType = typeResolver.resolveTypeAnnotation( |
| 1725 typeNode.bound, | |
| 1726 inScope: scope, | |
| 1727 onFailure: warning); | |
| 1680 if (boundType !== null && boundType.element == variableElement) { | 1728 if (boundType !== null && boundType.element == variableElement) { |
| 1681 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, | 1729 warning(node, MessageKind.CYCLIC_TYPE_VARIABLE, |
| 1682 [variableElement.name]); | 1730 [variableElement.name]); |
| 1683 } else if (boundType !== null) { | 1731 } else if (boundType !== null) { |
| 1684 variableElement.bound = boundType; | 1732 variableElement.bound = boundType; |
| 1685 } else { | 1733 } else { |
| 1686 variableElement.bound = compiler.objectClass.computeType(compiler); | 1734 variableElement.bound = compiler.objectClass.computeType(compiler); |
| 1687 } | 1735 } |
| 1688 } | 1736 } |
| 1737 nodeLink = nodeLink.tail; | |
| 1738 typeLink = typeLink.tail; | |
| 1689 } | 1739 } |
| 1740 } | |
| 1741 } | |
| 1742 | |
| 1743 class TypedefResolverVisitor extends TypeDefinitionVisitor { | |
| 1744 TypedefElement get element() => super.element; | |
| 1745 | |
| 1746 TypedefResolverVisitor(Compiler compiler, TypedefElement typedefElement) | |
| 1747 : super(compiler, typedefElement); | |
| 1748 | |
| 1749 visitTypedef(Typedef node) { | |
| 1750 TypedefType type = element.computeType(compiler); | |
| 1751 scope = new TypeDeclarationScope(scope, element); | |
| 1752 resolveTypeVariableBounds(node.typeParameters); | |
| 1753 | |
| 1754 element.functionSignature = SignatureResolver.analyze( | |
| 1755 compiler, node.formals, node.returnType, element); | |
| 1756 | |
| 1757 element.alias = compiler.computeFunctionType( | |
| 1758 element, element.functionSignature); | |
| 1759 | |
| 1760 // TODO(johnniwinther): Check for cyclic references in the typedef alias. | |
| 1761 } | |
| 1762 } | |
| 1763 | |
| 1764 class ClassResolverVisitor extends TypeDefinitionVisitor { | |
| 1765 ClassElement get element() => super.element; | |
| 1766 | |
| 1767 ClassResolverVisitor(Compiler compiler, ClassElement classElement) | |
| 1768 : super(compiler, classElement); | |
| 1769 | |
| 1770 visitClassNode(ClassNode node) { | |
| 1771 compiler.ensure(element !== null); | |
| 1772 compiler.ensure(!element.isResolved); | |
| 1773 | |
| 1774 InterfaceType type = element.computeType(compiler); | |
| 1775 scope = new TypeDeclarationScope(scope, element); | |
| 1776 resolveTypeVariableBounds(node.typeParameters); | |
| 1777 | |
| 1690 // Find super type. | 1778 // Find super type. |
| 1691 Type supertype = visit(node.superclass); | 1779 Type supertype; |
| 1780 if (node.superclass != null) { | |
| 1781 supertype = typeResolver.resolveTypeAnnotation( | |
| 1782 node.superclass, | |
| 1783 inScope: scope, | |
| 1784 onFailure: error); | |
| 1785 } | |
| 1692 if (supertype !== null && supertype.element.isExtendable()) { | 1786 if (supertype !== null && supertype.element.isExtendable()) { |
| 1693 classElement.supertype = supertype; | 1787 element.supertype = supertype; |
| 1694 if (isBlackListed(supertype)) { | 1788 if (isBlackListed(supertype)) { |
| 1695 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); | 1789 error(node.superclass, MessageKind.CANNOT_EXTEND, [supertype]); |
| 1696 } | 1790 } |
| 1697 } else if (supertype !== null) { | 1791 } else if (supertype !== null) { |
| 1698 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); | 1792 error(node.superclass, MessageKind.TYPE_NAME_EXPECTED); |
| 1699 } | 1793 } |
| 1700 final objectElement = compiler.objectClass; | 1794 final objectElement = compiler.objectClass; |
| 1701 if (classElement !== objectElement && classElement.supertype === null) { | 1795 if (element !== objectElement && element.supertype === null) { |
| 1702 if (objectElement === null) { | 1796 if (objectElement === null) { |
| 1703 compiler.internalError("Internal error: cannot resolve Object", | 1797 compiler.internalError("Internal error: cannot resolve Object", |
| 1704 node: node); | 1798 node: node); |
| 1705 } else if (!objectElement.isResolved) { | 1799 } else if (!objectElement.isResolved) { |
| 1706 compiler.resolver.toResolve.add(objectElement); | 1800 compiler.resolver.toResolve.add(objectElement); |
| 1707 } | 1801 } |
| 1708 classElement.supertype = new InterfaceType(objectElement); | 1802 element.supertype = new InterfaceType(objectElement); |
| 1709 } | |
| 1710 if (node.defaultClause !== null) { | |
| 1711 classElement.defaultClass = visit(node.defaultClause); | |
| 1712 } | 1803 } |
| 1713 for (Link<Node> link = node.interfaces.nodes; | 1804 for (Link<Node> link = node.interfaces.nodes; |
| 1714 !link.isEmpty(); | 1805 !link.isEmpty(); |
| 1715 link = link.tail) { | 1806 link = link.tail) { |
| 1716 Type interfaceType = visit(link.head); | 1807 Type interfaceType = typeResolver.resolveTypeAnnotation( |
| 1808 link.head, | |
| 1809 inScope: scope, | |
| 1810 onFailure: error); | |
| 1717 if (interfaceType !== null && interfaceType.element.isExtendable()) { | 1811 if (interfaceType !== null && interfaceType.element.isExtendable()) { |
| 1718 classElement.interfaces = | 1812 element.interfaces = |
| 1719 classElement.interfaces.prepend(interfaceType); | 1813 element.interfaces.prepend(interfaceType); |
| 1720 if (isBlackListed(interfaceType)) { | 1814 if (isBlackListed(interfaceType)) { |
| 1721 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); | 1815 error(link.head, MessageKind.CANNOT_IMPLEMENT, [interfaceType]); |
| 1722 } | 1816 } |
| 1723 } else { | 1817 } else { |
| 1724 error(link.head, MessageKind.TYPE_NAME_EXPECTED); | 1818 error(link.head, MessageKind.TYPE_NAME_EXPECTED); |
| 1725 } | 1819 } |
| 1726 } | 1820 } |
| 1727 calculateAllSupertypes(classElement, new Set<ClassElement>()); | 1821 calculateAllSupertypes(element, new Set<ClassElement>()); |
| 1728 addDefaultConstructorIfNeeded(classElement); | 1822 if (node.defaultClause !== null) { |
| 1729 return classElement.computeType(compiler); | 1823 // TODO(johnniwinther): Handle the variables in default clauses separately |
|
ahe
2012/08/02 06:43:14
I don't think the code you have here is working at
| |
| 1824 // or encoded default clauses as something other than [TypeAnnotation]. | |
| 1825 element.defaultClass = typeResolver.resolveTypeAnnotation( | |
| 1826 node.defaultClause, | |
| 1827 inScope: scope, | |
| 1828 onFailure: error); | |
| 1829 } | |
| 1830 addDefaultConstructorIfNeeded(element); | |
| 1730 } | 1831 } |
| 1731 | 1832 |
| 1732 Type visitTypeAnnotation(TypeAnnotation node) { | 1833 Link<InterfaceType> getOrCalculateAllSupertypes(ClassElement cls, |
| 1733 return visit(node.typeName); | 1834 [Set<ClassElement> seen]) { |
| 1734 } | 1835 Link<InterfaceType> allSupertypes = cls.allSupertypes; |
| 1735 | |
| 1736 Type visitIdentifier(Identifier node) { | |
| 1737 Element element = context.lookup(node.source); | |
| 1738 if (element === null) { | |
| 1739 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); | |
| 1740 return null; | |
| 1741 } else if (!element.impliesType() && !element.isTypeVariable()) { | |
| 1742 error(node, MessageKind.NOT_A_TYPE, [node]); | |
| 1743 return null; | |
| 1744 } else { | |
| 1745 if (element.isClass()) { | |
| 1746 compiler.resolver.toResolve.add(element); | |
| 1747 } | |
| 1748 if (element.isTypeVariable()) { | |
| 1749 TypeVariableElement variableElement = element; | |
| 1750 return variableElement.type; | |
| 1751 } else if (element.isTypedef()) { | |
| 1752 compiler.unimplemented('visitIdentifier for typedefs', node: node); | |
| 1753 } else { | |
| 1754 // TODO(ngeoffray): Use type variables. | |
| 1755 return element.computeType(compiler); | |
| 1756 } | |
| 1757 } | |
| 1758 return null; | |
| 1759 } | |
| 1760 | |
| 1761 Type visitSend(Send node) { | |
| 1762 Identifier prefix = node.receiver.asIdentifier(); | |
| 1763 if (prefix === null) { | |
| 1764 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | |
| 1765 return null; | |
| 1766 } | |
| 1767 Element element = context.lookup(prefix.source); | |
| 1768 if (element === null || element.kind !== ElementKind.PREFIX) { | |
| 1769 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); | |
| 1770 return null; | |
| 1771 } | |
| 1772 PrefixElement prefixElement = element; | |
| 1773 Identifier selector = node.selector.asIdentifier(); | |
| 1774 var e = prefixElement.lookupLocalMember(selector.source); | |
| 1775 if (e === null || !e.impliesType()) { | |
| 1776 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); | |
| 1777 return null; | |
| 1778 } | |
| 1779 return e.computeType(compiler); | |
| 1780 } | |
| 1781 | |
| 1782 Link<Type> getOrCalculateAllSupertypes(ClassElement cls, | |
| 1783 [Set<ClassElement> seen]) { | |
| 1784 Link<Type> allSupertypes = cls.allSupertypes; | |
| 1785 if (allSupertypes !== null) return allSupertypes; | 1836 if (allSupertypes !== null) return allSupertypes; |
| 1786 if (seen === null) { | 1837 if (seen === null) { |
| 1787 seen = new Set<ClassElement>(); | 1838 seen = new Set<ClassElement>(); |
| 1788 } | 1839 } |
| 1789 if (seen.contains(cls)) { | 1840 if (seen.contains(cls)) { |
| 1790 error(cls.parseNode(compiler), | 1841 error(cls.parseNode(compiler), |
| 1791 MessageKind.CYCLIC_CLASS_HIERARCHY, | 1842 MessageKind.CYCLIC_CLASS_HIERARCHY, |
| 1792 [cls.name]); | 1843 [cls.name]); |
| 1793 cls.allSupertypes = const EmptyLink<Type>(); | 1844 cls.allSupertypes = const EmptyLink<InterfaceType>(); |
| 1794 } else { | 1845 } else { |
| 1795 cls.ensureResolved(compiler); | 1846 cls.ensureResolved(compiler); |
| 1796 calculateAllSupertypes(cls, seen); | 1847 calculateAllSupertypes(cls, seen); |
| 1797 } | 1848 } |
| 1798 return cls.allSupertypes; | 1849 return cls.allSupertypes; |
| 1799 } | 1850 } |
| 1800 | 1851 |
| 1801 void calculateAllSupertypes(ClassElement cls, Set<ClassElement> seen) { | 1852 void calculateAllSupertypes(ClassElement cls, Set<ClassElement> seen) { |
| 1802 // TODO(karlklose): substitute type variables. | |
| 1803 // TODO(karlklose): check if type arguments match, if a classelement occurs | 1853 // TODO(karlklose): check if type arguments match, if a classelement occurs |
| 1804 // more than once in the supertypes. | 1854 // more than once in the supertypes. |
| 1805 if (cls.allSupertypes !== null) return; | 1855 if (cls.allSupertypes !== null) return; |
| 1806 final Type supertype = cls.supertype; | 1856 final InterfaceType supertype = cls.supertype; |
| 1807 if (seen.contains(cls)) { | 1857 if (seen.contains(cls)) { |
| 1808 error(cls.parseNode(compiler), | 1858 error(cls.parseNode(compiler), |
| 1809 MessageKind.CYCLIC_CLASS_HIERARCHY, | 1859 MessageKind.CYCLIC_CLASS_HIERARCHY, |
| 1810 [cls.name]); | 1860 [cls.name]); |
| 1811 cls.allSupertypes = const EmptyLink<Type>(); | 1861 cls.allSupertypes = const EmptyLink<InterfaceType>(); |
| 1812 } else if (supertype != null) { | 1862 } else if (supertype != null) { |
| 1813 seen.add(cls); | 1863 seen.add(cls); |
| 1814 Link<Type> superSupertypes = | 1864 ClassElement supertypeElement = supertype.element; |
| 1815 getOrCalculateAllSupertypes(supertype.element, seen); | 1865 Link<InterfaceType> superSupertypes = |
| 1816 Link<Type> supertypes = new Link<Type>(supertype, superSupertypes); | 1866 getOrCalculateAllSupertypes(supertypeElement, seen); |
| 1817 for (Link<Type> interfaces = cls.interfaces; | 1867 var superTypesBuilder = new LinkBuilder<InterfaceType>(); |
| 1868 superTypesBuilder.addLast(supertype); | |
| 1869 | |
| 1870 // Substitute type variables in supertypes. | |
| 1871 for (Type superSupertype in superSupertypes) { | |
| 1872 superTypesBuilder.addLast(superSupertype.subst(compiler, | |
| 1873 supertype.typeArguments, | |
| 1874 supertypeElement.computeType(compiler).typeArguments)); | |
| 1875 } | |
| 1876 | |
| 1877 Link<InterfaceType> supertypes = superTypesBuilder.toLink(); | |
| 1878 for (Link<InterfaceType> interfaces = cls.interfaces; | |
| 1818 !interfaces.isEmpty(); | 1879 !interfaces.isEmpty(); |
| 1819 interfaces = interfaces.tail) { | 1880 interfaces = interfaces.tail) { |
| 1820 Element element = interfaces.head.element; | 1881 Element element = interfaces.head.element; |
| 1821 Link<Type> interfaceSupertypes = | 1882 Link<InterfaceType> interfaceSupertypes = |
| 1822 getOrCalculateAllSupertypes(element, seen); | 1883 getOrCalculateAllSupertypes(element, seen); |
| 1823 supertypes = supertypes.reversePrependAll(interfaceSupertypes); | 1884 supertypes = supertypes.reversePrependAll(interfaceSupertypes); |
| 1824 supertypes = supertypes.prepend(interfaces.head); | 1885 supertypes = supertypes.prepend(interfaces.head); |
| 1825 } | 1886 } |
| 1826 seen.remove(cls); | 1887 seen.remove(cls); |
| 1827 cls.allSupertypes = supertypes; | 1888 cls.allSupertypes = supertypes; |
| 1828 } else { | 1889 } else { |
| 1829 cls.allSupertypes = const EmptyLink<Type>(); | 1890 cls.allSupertypes = const EmptyLink<InterfaceType>(); |
| 1830 } | 1891 } |
| 1831 } | 1892 } |
| 1832 | 1893 |
| 1833 /** | 1894 /** |
| 1834 * Add a synthetic nullary constructor if there are no other | 1895 * Add a synthetic nullary constructor if there are no other |
| 1835 * constructors. | 1896 * constructors. |
| 1836 */ | 1897 */ |
| 1837 void addDefaultConstructorIfNeeded(ClassElement element) { | 1898 void addDefaultConstructorIfNeeded(ClassElement element) { |
| 1838 if (element.constructors.length != 0) return; | 1899 if (element.constructors.length != 0) return; |
| 1839 SynthesizedConstructorElement constructor = | 1900 SynthesizedConstructorElement constructor = |
| 1840 new SynthesizedConstructorElement(element); | 1901 new SynthesizedConstructorElement(element); |
| 1841 element.constructors[element.name] = constructor; | 1902 element.constructors[element.name] = constructor; |
| 1842 Type returnType = compiler.types.voidType; | 1903 Type returnType = compiler.types.voidType; |
| 1843 constructor.type = new FunctionType(returnType, const EmptyLink<Type>(), | 1904 constructor.type = new FunctionType(returnType, const EmptyLink<Type>(), |
| 1844 constructor); | 1905 constructor); |
| 1845 constructor.cachedNode = | 1906 constructor.cachedNode = |
| 1846 new FunctionExpression(new Identifier(element.position()), | 1907 new FunctionExpression(new Identifier(element.position()), |
| 1847 new NodeList.empty(), | 1908 new NodeList.empty(), |
| 1848 new Block(new NodeList.empty()), | 1909 new Block(new NodeList.empty()), |
| 1849 null, null, null, null); | 1910 null, null, null, null); |
| 1850 } | 1911 } |
| 1851 | 1912 |
| 1852 isBlackListed(Type type) { | 1913 isBlackListed(Type type) { |
| 1853 LibraryElement lib = classElement.getLibrary(); | 1914 LibraryElement lib = element.getLibrary(); |
| 1854 return | 1915 return |
| 1855 lib !== compiler.coreLibrary && | 1916 lib !== compiler.coreLibrary && |
| 1856 lib !== compiler.coreImplLibrary && | 1917 lib !== compiler.coreImplLibrary && |
| 1857 lib !== compiler.jsHelperLibrary && | 1918 lib !== compiler.jsHelperLibrary && |
| 1858 (type.element === compiler.dynamicClass || | 1919 (type.element === compiler.dynamicClass || |
| 1859 type.element === compiler.boolClass || | 1920 type.element === compiler.boolClass || |
| 1860 type.element === compiler.numClass || | 1921 type.element === compiler.numClass || |
| 1861 type.element === compiler.intClass || | 1922 type.element === compiler.intClass || |
| 1862 type.element === compiler.doubleClass || | 1923 type.element === compiler.doubleClass || |
| 1863 type.element === compiler.stringClass || | 1924 type.element === compiler.stringClass || |
| 1864 type.element === compiler.nullClass || | 1925 type.element === compiler.nullClass || |
| 1865 type.element === compiler.functionClass); | 1926 type.element === compiler.functionClass); |
| 1866 } | 1927 } |
| 1867 } | 1928 } |
| 1868 | 1929 |
| 1869 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { | 1930 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { |
| 1870 VariableDefinitions definitions; | 1931 VariableDefinitions definitions; |
| 1871 ResolverVisitor resolver; | 1932 ResolverVisitor resolver; |
| 1872 ElementKind kind; | 1933 ElementKind kind; |
| 1873 VariableListElement variables; | 1934 VariableListElement variables; |
| 1874 | 1935 |
| 1875 VariableDefinitionsVisitor(Compiler compiler, | 1936 VariableDefinitionsVisitor(Compiler compiler, |
| 1876 this.definitions, this.resolver, this.kind) | 1937 this.definitions, this.resolver, this.kind) |
| 1877 : super(compiler) | 1938 : super(compiler) |
| 1878 { | 1939 { |
| 1879 variables = new VariableListElement.node( | 1940 variables = new VariableListElement.node( |
| 1880 definitions, ElementKind.VARIABLE_LIST, resolver.context.element); | 1941 definitions, ElementKind.VARIABLE_LIST, resolver.scope.element); |
| 1881 } | 1942 } |
| 1882 | 1943 |
| 1883 SourceString visitSendSet(SendSet node) { | 1944 SourceString visitSendSet(SendSet node) { |
| 1884 assert(node.arguments.tail.isEmpty()); // Sanity check | 1945 assert(node.arguments.tail.isEmpty()); // Sanity check |
| 1885 resolver.visit(node.arguments.head); | 1946 resolver.visit(node.arguments.head); |
| 1886 return visit(node.selector); | 1947 return visit(node.selector); |
| 1887 } | 1948 } |
| 1888 | 1949 |
| 1889 SourceString visitIdentifier(Identifier node) => node.source; | 1950 SourceString visitIdentifier(Identifier node) => node.source; |
| 1890 | 1951 |
| 1891 visitNodeList(NodeList node) { | 1952 visitNodeList(NodeList node) { |
| 1892 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { | 1953 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { |
| 1893 SourceString name = visit(link.head); | 1954 SourceString name = visit(link.head); |
| 1894 VariableElement element = new VariableElement( | 1955 VariableElement element = new VariableElement( |
| 1895 name, variables, kind, resolver.context.element, node: link.head); | 1956 name, variables, kind, resolver.scope.element, node: link.head); |
| 1896 resolver.defineElement(link.head, element); | 1957 resolver.defineElement(link.head, element); |
| 1897 } | 1958 } |
| 1898 } | 1959 } |
| 1899 } | 1960 } |
| 1900 | 1961 |
| 1962 /** | |
| 1963 * [SignatureResolver] resolves function signatures. | |
| 1964 */ | |
| 1901 class SignatureResolver extends CommonResolverVisitor<Element> { | 1965 class SignatureResolver extends CommonResolverVisitor<Element> { |
| 1902 final Element enclosingElement; | 1966 final Element enclosingElement; |
| 1903 Link<Element> optionalParameters = const EmptyLink<Element>(); | 1967 Link<Element> optionalParameters = const EmptyLink<Element>(); |
| 1904 int optionalParameterCount = 0; | 1968 int optionalParameterCount = 0; |
| 1905 Node currentDefinitions; | 1969 VariableDefinitions currentDefinitions; |
| 1906 | 1970 |
| 1907 SignatureResolver(Compiler compiler, this.enclosingElement) : super(compiler); | 1971 SignatureResolver(Compiler compiler, this.enclosingElement) : super(compiler); |
| 1908 | 1972 |
| 1909 Element visitNodeList(NodeList node) { | 1973 Element visitNodeList(NodeList node) { |
| 1910 // This must be a list of optional arguments. | 1974 // This must be a list of optional arguments. |
| 1911 if (node.beginToken.stringValue !== '[') { | 1975 if (node.beginToken.stringValue !== '[') { |
| 1912 internalError(node, "expected optional parameters"); | 1976 internalError(node, "expected optional parameters"); |
| 1913 } | 1977 } |
| 1914 LinkBuilder<Element> elements = analyzeNodes(node.nodes); | 1978 LinkBuilder<Element> elements = analyzeNodes(node.nodes); |
| 1915 optionalParameterCount = elements.length; | 1979 optionalParameterCount = elements.length; |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2023 // If parameter is null, the current node should be the last, | 2087 // If parameter is null, the current node should be the last, |
| 2024 // and a list of optional named parameters. | 2088 // and a list of optional named parameters. |
| 2025 if (!link.tail.isEmpty() || (link.head is !NodeList)) { | 2089 if (!link.tail.isEmpty() || (link.head is !NodeList)) { |
| 2026 internalError(link.head, "expected optional parameters"); | 2090 internalError(link.head, "expected optional parameters"); |
| 2027 } | 2091 } |
| 2028 } | 2092 } |
| 2029 } | 2093 } |
| 2030 return elements; | 2094 return elements; |
| 2031 } | 2095 } |
| 2032 | 2096 |
| 2097 /** | |
| 2098 * Resolves formal parameters and return type to a [FunctionSignature]. | |
| 2099 */ | |
| 2033 static FunctionSignature analyze(Compiler compiler, | 2100 static FunctionSignature analyze(Compiler compiler, |
| 2034 NodeList formalParameters, | 2101 NodeList formalParameters, |
| 2035 Node returnNode, | 2102 Node returnNode, |
| 2036 Element element) { | 2103 Element element) { |
| 2037 SignatureResolver visitor = new SignatureResolver(compiler, element); | 2104 SignatureResolver visitor = new SignatureResolver(compiler, element); |
| 2038 LinkBuilder<Element> parametersBuilder = | 2105 LinkBuilder<Element> parametersBuilder = |
| 2039 visitor.analyzeNodes(formalParameters.nodes); | 2106 visitor.analyzeNodes(formalParameters.nodes); |
| 2040 Link<Element> parameters = parametersBuilder.toLink(); | 2107 Link<Element> parameters = parametersBuilder.toLink(); |
| 2041 Type returnType = | 2108 Type returnType = |
| 2042 compiler.resolveTypeAnnotation(element, returnNode); | 2109 compiler.resolveTypeAnnotation(element, returnNode); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2142 | 2209 |
| 2143 class Scope { | 2210 class Scope { |
| 2144 final Element element; | 2211 final Element element; |
| 2145 final Scope parent; | 2212 final Scope parent; |
| 2146 | 2213 |
| 2147 Scope(this.parent, this.element); | 2214 Scope(this.parent, this.element); |
| 2148 abstract Element add(Element element); | 2215 abstract Element add(Element element); |
| 2149 abstract Element lookup(SourceString name); | 2216 abstract Element lookup(SourceString name); |
| 2150 } | 2217 } |
| 2151 | 2218 |
| 2152 class TypeVariablesScope extends Scope { | 2219 class EmptyScope implements Scope { |
| 2153 TypeVariablesScope(parent, ClassElement element) : super(parent, element); | 2220 const EmptyScope(); |
| 2221 | |
| 2222 Element get element() => null; | |
| 2223 | |
| 2224 Scope get parent() => null; | |
| 2225 | |
| 2226 Element add(Element element) { | |
| 2227 throw "Cannot add element to EmptyScope"; | |
| 2228 } | |
| 2229 | |
| 2230 Element lookup(SourceString name) => null; | |
| 2231 } | |
| 2232 | |
| 2233 /** | |
| 2234 * [TypeDeclarationScope] defines the outer scope of a type declaration in | |
| 2235 * which the declared type variables and the entities in the enclosing scope are | |
| 2236 * available but where declared and inherited members are not available. This | |
| 2237 * scope is only used for class/interface declarations during resolution of the | |
| 2238 * class hierarchy. In all other cases [ClassScope] is used. | |
| 2239 */ | |
| 2240 class TypeDeclarationScope extends Scope { | |
| 2241 TypeDeclarationElement get element() => super.element; | |
| 2242 | |
| 2243 TypeDeclarationScope(parent, TypeDeclarationElement element) | |
| 2244 : super(parent, element); | |
| 2245 | |
| 2154 Element add(Element newElement) { | 2246 Element add(Element newElement) { |
| 2155 throw "Cannot add element to TypeVariableScope"; | 2247 throw "Cannot add element to TypeDeclarationScope"; |
| 2156 } | 2248 } |
| 2249 | |
| 2157 Element lookup(SourceString name) { | 2250 Element lookup(SourceString name) { |
| 2158 ClassElement cls = element; | 2251 Element result = lookupTypeVariable(element, name); |
| 2159 Element result = cls.lookupTypeParameter(name); | |
| 2160 if (result !== null) return result; | 2252 if (result !== null) return result; |
| 2161 if (parent !== null) return parent.lookup(name); | 2253 if (parent !== null) return parent.lookup(name); |
| 2162 } | 2254 } |
| 2255 | |
| 2256 String toString() => | |
| 2257 '$element${element.typeVariables} > $parent'; | |
| 2163 } | 2258 } |
| 2164 | 2259 |
| 2165 class MethodScope extends Scope { | 2260 class MethodScope extends Scope { |
| 2166 final Map<SourceString, Element> elements; | 2261 final Map<SourceString, Element> elements; |
| 2167 | 2262 |
| 2168 MethodScope(Scope parent, Element element) | 2263 MethodScope(Scope parent, Element element) |
| 2169 : super(parent, element), this.elements = new Map<SourceString, Element>(); | 2264 : super(parent, element), this.elements = new Map<SourceString, Element>(); |
| 2170 | 2265 |
| 2171 Element lookup(SourceString name) { | 2266 Element lookup(SourceString name) { |
| 2172 Element found = elements[name]; | 2267 Element found = elements[name]; |
| 2173 if (found !== null) return found; | 2268 if (found !== null) return found; |
| 2174 return parent.lookup(name); | 2269 return parent.lookup(name); |
| 2175 } | 2270 } |
| 2176 | 2271 |
| 2177 Element add(Element newElement) { | 2272 Element add(Element newElement) { |
| 2178 if (elements.containsKey(newElement.name)) { | 2273 if (elements.containsKey(newElement.name)) { |
| 2179 return elements[newElement.name]; | 2274 return elements[newElement.name]; |
| 2180 } | 2275 } |
| 2181 elements[newElement.name] = newElement; | 2276 elements[newElement.name] = newElement; |
| 2182 return newElement; | 2277 return newElement; |
| 2183 } | 2278 } |
| 2279 | |
| 2280 String toString() => '$element${elements.getKeys()} > $parent'; | |
| 2184 } | 2281 } |
| 2185 | 2282 |
| 2186 class BlockScope extends MethodScope { | 2283 class BlockScope extends MethodScope { |
| 2187 BlockScope(Scope parent) : super(parent, parent.element); | 2284 BlockScope(Scope parent) : super(parent, parent.element); |
| 2285 | |
| 2286 String toString() => 'block${elements.getKeys()} > $parent'; | |
| 2188 } | 2287 } |
| 2189 | 2288 |
| 2190 class ClassScope extends Scope { | 2289 /** |
| 2191 ClassScope(ClassElement element, LibraryElement library) | 2290 * [ClassScope] defines the inner scope of a class/interface declaration in |
| 2192 : super(new TopScope(library), element); | 2291 * which declared members, declared type variables, entities in the enclosing |
| 2292 * scope and inherited members are available, in the given order. | |
| 2293 */ | |
| 2294 class ClassScope extends TypeDeclarationScope { | |
| 2295 ClassScope(Scope parentScope, ClassElement element) | |
| 2296 : super(parentScope, element); | |
| 2193 | 2297 |
| 2194 Element lookup(SourceString name) { | 2298 Element lookup(SourceString name) { |
| 2195 ClassElement cls = element; | 2299 ClassElement cls = element; |
| 2196 Element result = cls.lookupLocalMember(name); | 2300 Element result = cls.lookupLocalMember(name); |
| 2197 if (result !== null) return result; | 2301 if (result !== null) return result; |
| 2198 result = cls.lookupTypeParameter(name); | 2302 result = super.lookup(name); |
| 2199 if (result !== null) return result; | |
| 2200 result = parent.lookup(name); | |
| 2201 if (result != null) return result; | 2303 if (result != null) return result; |
| 2202 return cls.lookupSuperMember(name); | 2304 return cls.lookupSuperMember(name); |
| 2203 } | 2305 } |
| 2204 | 2306 |
| 2205 Element add(Element newElement) { | 2307 Element add(Element newElement) { |
| 2206 throw "Cannot add an element in a class scope"; | 2308 throw "Cannot add an element in a class scope"; |
| 2207 } | 2309 } |
| 2310 | |
| 2311 String toString() => '$element > $parent'; | |
| 2208 } | 2312 } |
| 2209 | 2313 |
| 2210 class TopScope extends Scope { | 2314 class TopScope extends Scope { |
| 2211 LibraryElement get library() => element; | 2315 LibraryElement get library() => element; |
| 2212 | 2316 |
| 2213 TopScope(LibraryElement library) : super(null, library); | 2317 TopScope(LibraryElement library) : super(null, library); |
| 2214 Element lookup(SourceString name) { | 2318 Element lookup(SourceString name) { |
| 2215 return library.find(name); | 2319 return library.find(name); |
| 2216 } | 2320 } |
| 2217 | 2321 |
| 2218 Element add(Element newElement) { | 2322 Element add(Element newElement) { |
| 2219 throw "Cannot add an element in the top scope"; | 2323 throw "Cannot add an element in the top scope"; |
| 2220 } | 2324 } |
| 2325 String toString() => '$element'; | |
| 2221 } | 2326 } |
| OLD | NEW |