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 |