Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Side by Side Diff: lib/compiler/implementation/resolver.dart

Issue 10834061: Resolve typedefs. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated scope handling and type resolution Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698