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

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

Issue 10837095: Refactor scope handling. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 return null; // If there was no redirection always return null. 562 return null; // If there was no redirection always return null.
563 } 563 }
564 } 564 }
565 565
566 class CommonResolverVisitor<R> extends AbstractVisitor<R> { 566 class CommonResolverVisitor<R> extends AbstractVisitor<R> {
567 final Compiler compiler; 567 final Compiler compiler;
568 568
569 CommonResolverVisitor(Compiler this.compiler); 569 CommonResolverVisitor(Compiler this.compiler);
570 570
571 R visitNode(Node node) { 571 R visitNode(Node node) {
572 cancel(node, 'internal error'); 572 cancel(node,
573 'internal error: Unhandled node: ${node.getObjectDescription()}');
573 } 574 }
574 575
575 R visitEmptyStatement(Node node) => null; 576 R visitEmptyStatement(Node node) => null;
576 577
577 /** Convenience method for visiting nodes that may be null. */ 578 /** Convenience method for visiting nodes that may be null. */
578 R visit(Node node) => (node == null) ? null : node.accept(this); 579 R visit(Node node) => (node == null) ? null : node.accept(this);
579 580
580 void error(Node node, MessageKind kind, [arguments = const []]) { 581 void error(Node node, MessageKind kind, [arguments = const []]) {
581 ResolutionError message = new ResolutionError(kind, arguments); 582 ResolutionError message = new ResolutionError(kind, arguments);
582 compiler.reportError(node, message); 583 compiler.reportError(node, message);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 int nestingLevel = 0; 647 int nestingLevel = 0;
647 648
648 StatementScope() 649 StatementScope()
649 : labels = const EmptyLabelScope(), 650 : labels = const EmptyLabelScope(),
650 breakTargetStack = const EmptyLink<TargetElement>(), 651 breakTargetStack = const EmptyLink<TargetElement>(),
651 continueTargetStack = const EmptyLink<TargetElement>(); 652 continueTargetStack = const EmptyLink<TargetElement>();
652 653
653 LabelElement lookupLabel(String label) { 654 LabelElement lookupLabel(String label) {
654 return labels.lookup(label); 655 return labels.lookup(label);
655 } 656 }
657
656 TargetElement currentBreakTarget() => 658 TargetElement currentBreakTarget() =>
657 breakTargetStack.isEmpty() ? null : breakTargetStack.head; 659 breakTargetStack.isEmpty() ? null : breakTargetStack.head;
658 660
659 TargetElement currentContinueTarget() => 661 TargetElement currentContinueTarget() =>
660 continueTargetStack.isEmpty() ? null : continueTargetStack.head; 662 continueTargetStack.isEmpty() ? null : continueTargetStack.head;
661 663
662 void enterLabelScope(Map<String, LabelElement> elements) { 664 void enterLabelScope(Map<String, LabelElement> elements) {
663 labels = new LabeledStatementLabelScope(labels, elements); 665 labels = new LabeledStatementLabelScope(labels, elements);
664 nestingLevel++; 666 nestingLevel++;
665 } 667 }
(...skipping 24 matching lines...) Expand all
690 692
691 void exitSwitch() { 693 void exitSwitch() {
692 nestingLevel--; 694 nestingLevel--;
693 breakTargetStack = breakTargetStack.tail; 695 breakTargetStack = breakTargetStack.tail;
694 labels = labels.outer; 696 labels = labels.outer;
695 } 697 }
696 } 698 }
697 699
698 class TypeResolver { 700 class TypeResolver {
699 final Compiler compiler; 701 final Compiler compiler;
702
700 TypeResolver(this.compiler); 703 TypeResolver(this.compiler);
701 704
702 Element resolveTypeName(Scope context, TypeAnnotation node) { 705 Element resolveTypeName(Scope scope, TypeAnnotation node) {
703 Identifier typeName = node.typeName.asIdentifier(); 706 Identifier typeName = node.typeName.asIdentifier();
704 Send send = node.typeName.asSend(); 707 Send send = node.typeName.asSend();
708 return resolveTypeNameInternal(scope, typeName, send);
709 }
710
711 Element resolveTypeNameInternal(Scope scope, Identifier typeName, Send send) {
705 if (send !== null) { 712 if (send !== null) {
706 typeName = send.selector; 713 typeName = send.selector;
707 } 714 }
708 if (typeName.source.stringValue === 'void') { 715 if (typeName.source.stringValue === 'void') {
709 return compiler.types.voidType.element; 716 return compiler.types.voidType.element;
710 } else if (send !== null) { 717 } else if (send !== null) {
711 Element e = context.lookup(send.receiver.asIdentifier().source); 718 Element e = scope.lookup(send.receiver.asIdentifier().source);
712 if (e !== null && e.kind === ElementKind.PREFIX) { 719 if (e !== null && e.kind === ElementKind.PREFIX) {
713 // The receiver is a prefix. Lookup in the imported members. 720 // The receiver is a prefix. Lookup in the imported members.
714 PrefixElement prefix = e; 721 PrefixElement prefix = e;
715 return prefix.lookupLocalMember(typeName.source); 722 return prefix.lookupLocalMember(typeName.source);
716 } else if (e !== null && e.kind === ElementKind.CLASS) { 723 } else if (e !== null && e.kind === ElementKind.CLASS) {
717 // The receiver is the class part of a named constructor. 724 // The receiver is the class part of a named constructor.
718 return e; 725 return e;
719 } else { 726 } else {
720 return null; 727 return null;
721 } 728 }
722 } else { 729 } else {
723 return context.lookup(typeName.source); 730 return scope.lookup(typeName.source);
724 } 731 }
725 } 732 }
726 733
734 // TODO(johnniwinther): Change [onFailure] and [whenResolved] to use boolean
735 // flags instead of closures.
727 Type resolveTypeAnnotation(TypeAnnotation node, 736 Type resolveTypeAnnotation(TypeAnnotation node,
728 [Scope inContext, ClassElement inClass, 737 [Scope inScope, ClassElement inClass,
729 onFailure(Node, MessageKind, [List arguments]), 738 onFailure(Node, MessageKind, [List arguments]),
730 whenResolved(Node, Type)]) { 739 whenResolved(Node, Type)]) {
731 if (onFailure === null) { 740 if (onFailure === null) {
732 onFailure = (n, k, [arguments]) {}; 741 onFailure = (n, k, [arguments]) {};
733 } 742 }
734 if (whenResolved === null) { 743 if (whenResolved === null) {
735 whenResolved = (n, t) {}; 744 whenResolved = (n, t) {};
736 } 745 }
737 if (inClass !== null) { 746 if (inClass !== null) {
738 inContext = new ClassScope(inClass, inClass.getLibrary()); 747 inScope = inClass.buildScope();
739 } 748 }
740 if (inContext === null) { 749 if (inScope === null) {
741 compiler.internalError('resolveTypeAnnotation: no scope specified'); 750 compiler.internalError('resolveTypeAnnotation: no scope specified');
742 } 751 }
743 return resolveTypeAnnotationInContext(inContext, node, onFailure, 752 return resolveTypeAnnotationInContext(inScope, node, onFailure,
744 whenResolved); 753 whenResolved);
745 } 754 }
746 755
747 Type resolveTypeAnnotationInContext(Scope context, TypeAnnotation node, 756 Type resolveTypeAnnotationInContext(Scope scope, TypeAnnotation node,
748 onFailure, whenResolved) { 757 onFailure, whenResolved) {
749 Element element = resolveTypeName(context, node); 758 Element element = resolveTypeName(scope, node);
750 Type type; 759 Type type;
751 if (element === null) { 760 if (element === null) {
752 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]); 761 onFailure(node, MessageKind.CANNOT_RESOLVE_TYPE, [node.typeName]);
753 } else if (!element.impliesType()) { 762 } else if (!element.impliesType()) {
754 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]); 763 onFailure(node, MessageKind.NOT_A_TYPE, [node.typeName]);
755 } else { 764 } else {
756 if (element === compiler.types.voidType.element || 765 if (element === compiler.types.voidType.element ||
757 element === compiler.types.dynamicType.element) { 766 element === compiler.types.dynamicType.element) {
758 type = element.computeType(compiler); 767 type = element.computeType(compiler);
759 } else if (element.isClass()) { 768 } else if (element.isClass()) {
760 ClassElement cls = element; 769 ClassElement cls = element;
761 if (!cls.isResolved) compiler.resolveClass(cls); 770 if (!cls.isResolved) compiler.resolveClass(cls);
762 LinkBuilder<Type> arguments = new LinkBuilder<Type>(); 771 LinkBuilder<Type> arguments = new LinkBuilder<Type>();
763 if (node.typeArguments !== null) { 772 if (node.typeArguments !== null) {
764 int index = 0; 773 int index = 0;
765 for (Link<Node> typeArguments = node.typeArguments.nodes; 774 for (Link<Node> typeArguments = node.typeArguments.nodes;
766 !typeArguments.isEmpty(); 775 !typeArguments.isEmpty();
767 typeArguments = typeArguments.tail) { 776 typeArguments = typeArguments.tail) {
768 if (++index > cls.typeParameters.length) { 777 if (++index > cls.typeParameters.length) {
769 onFailure(typeArguments.head, 778 onFailure(typeArguments.head,
770 MessageKind.ADDITIONAL_TYPE_ARGUMENT); 779 MessageKind.ADDITIONAL_TYPE_ARGUMENT);
771 } 780 }
772 Type argType = resolveTypeAnnotationInContext(context, 781 Type argType = resolveTypeAnnotationInContext(scope,
773 typeArguments.head, 782 typeArguments.head,
774 onFailure, 783 onFailure,
775 whenResolved); 784 whenResolved);
776 arguments.addLast(argType); 785 arguments.addLast(argType);
777 } 786 }
778 if (index < cls.typeParameters.length) { 787 if (index < cls.typeParameters.length) {
779 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT); 788 onFailure(node.typeArguments, MessageKind.MISSING_TYPE_ARGUMENT);
780 } 789 }
781 } 790 }
782 if (cls.typeParameters.length == 0) { 791 if (cls.typeParameters.length == 0) {
(...skipping 14 matching lines...) Expand all
797 whenResolved(node, type); 806 whenResolved(node, type);
798 return type; 807 return type;
799 } 808 }
800 } 809 }
801 810
802 class ResolverVisitor extends CommonResolverVisitor<Element> { 811 class ResolverVisitor extends CommonResolverVisitor<Element> {
803 final TreeElementMapping mapping; 812 final TreeElementMapping mapping;
804 final Element enclosingElement; 813 final Element enclosingElement;
805 final TypeResolver typeResolver; 814 final TypeResolver typeResolver;
806 bool inInstanceContext; 815 bool inInstanceContext;
807 Scope context; 816 Scope scope;
808 ClassElement currentClass; 817 ClassElement currentClass;
809 bool typeRequired = false; 818 bool typeRequired = false;
810 StatementScope statementScope; 819 StatementScope statementScope;
811 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; 820 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION;
812 821
813 ResolverVisitor(Compiler compiler, Element element) 822 ResolverVisitor(Compiler compiler, Element element)
814 : this.mapping = new TreeElementMapping(), 823 : this.mapping = new TreeElementMapping(),
815 this.enclosingElement = element, 824 this.enclosingElement = element,
816 inInstanceContext = element.isInstanceMember() 825 inInstanceContext = element.isInstanceMember()
817 || element.isGenerativeConstructor(), 826 || element.isGenerativeConstructor(),
818 this.currentClass = element.isMember() ? element.enclosingElement : null, 827 this.currentClass = element.isMember() ? element.enclosingElement : null,
819 this.statementScope = new StatementScope(), 828 this.statementScope = new StatementScope(),
820 typeResolver = new TypeResolver(compiler), 829 typeResolver = new TypeResolver(compiler),
830 scope = element.buildEnclosingScope(),
821 super(compiler) { 831 super(compiler) {
822 LibraryElement library = element.getLibrary();
823 element = element.getEnclosingMember();
824 if (element !== null) {
825 context = new ClassScope(element.enclosingElement, library);
826 } else {
827 this.context = new TopScope(library);
828 }
829 } 832 }
830 833
831 Enqueuer get world() => compiler.enqueuer.resolution; 834 Enqueuer get world() => compiler.enqueuer.resolution;
832 835
833 Element lookup(Node node, SourceString name) { 836 Element lookup(Node node, SourceString name) {
834 Element result = context.lookup(name); 837 Element result = scope.lookup(name);
835 if (!inInstanceContext && result != null && result.isInstanceMember()) { 838 if (!inInstanceContext && result != null && result.isInstanceMember()) {
836 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); 839 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]);
837 } 840 }
838 return result; 841 return result;
839 } 842 }
840 843
841 // Create, or reuse an already created, statement element for a statement. 844 // Create, or reuse an already created, statement element for a statement.
842 TargetElement getOrCreateTargetElement(Node statement) { 845 TargetElement getOrCreateTargetElement(Node statement) {
843 TargetElement element = mapping[statement]; 846 TargetElement element = mapping[statement];
844 if (element === null) { 847 if (element === null) {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 Type type = resolveTypeAnnotation(node); 895 Type type = resolveTypeAnnotation(node);
893 if (type !== null) return type.element; 896 if (type !== null) return type.element;
894 return null; 897 return null;
895 } 898 }
896 899
897 Element defineElement(Node node, Element element, 900 Element defineElement(Node node, Element element,
898 [bool doAddToScope = true]) { 901 [bool doAddToScope = true]) {
899 compiler.ensure(element !== null); 902 compiler.ensure(element !== null);
900 mapping[node] = element; 903 mapping[node] = element;
901 if (doAddToScope) { 904 if (doAddToScope) {
902 Element existing = context.add(element); 905 Element existing = scope.add(element);
903 if (existing != element) { 906 if (existing != element) {
904 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); 907 error(node, MessageKind.DUPLICATE_DEFINITION, [node]);
905 } 908 }
906 } 909 }
907 return element; 910 return element;
908 } 911 }
909 912
910 Element useElement(Node node, Element element) { 913 Element useElement(Node node, Element element) {
911 if (element === null) return null; 914 if (element === null) return null;
912 mapping[node] = element; 915 mapping[node] = element;
(...skipping 20 matching lines...) Expand all
933 936
934 Type useType(TypeAnnotation annotation, Type type) { 937 Type useType(TypeAnnotation annotation, Type type) {
935 if (type !== null) { 938 if (type !== null) {
936 mapping.setType(annotation, type); 939 mapping.setType(annotation, type);
937 useElement(annotation, type.element); 940 useElement(annotation, type.element);
938 } 941 }
939 return type; 942 return type;
940 } 943 }
941 944
942 void setupFunction(FunctionExpression node, FunctionElement function) { 945 void setupFunction(FunctionExpression node, FunctionElement function) {
943 context = new MethodScope(context, function); 946 scope = new MethodScope(scope, function);
944 // Put the parameters in scope. 947 // Put the parameters in scope.
945 FunctionSignature functionParameters = 948 FunctionSignature functionParameters =
946 function.computeSignature(compiler); 949 function.computeSignature(compiler);
947 Link<Node> parameterNodes = node.parameters.nodes; 950 Link<Node> parameterNodes = node.parameters.nodes;
948 functionParameters.forEachParameter((Element element) { 951 functionParameters.forEachParameter((Element element) {
949 if (element == functionParameters.optionalParameters.head) { 952 if (element == functionParameters.optionalParameters.head) {
950 NodeList nodes = parameterNodes.head; 953 NodeList nodes = parameterNodes.head;
951 parameterNodes = nodes.nodes; 954 parameterNodes = nodes.nodes;
952 } 955 }
953 VariableDefinitions variableDefinitions = parameterNodes.head; 956 VariableDefinitions variableDefinitions = parameterNodes.head;
(...skipping 15 matching lines...) Expand all
969 } 972 }
970 973
971 visitCascadeReceiver(CascadeReceiver node) { 974 visitCascadeReceiver(CascadeReceiver node) {
972 visit(node.expression); 975 visit(node.expression);
973 } 976 }
974 977
975 Element visitClassNode(ClassNode node) { 978 Element visitClassNode(ClassNode node) {
976 cancel(node, "shouldn't be called"); 979 cancel(node, "shouldn't be called");
977 } 980 }
978 981
979 visitIn(Node node, Scope scope) { 982 visitIn(Node node, Scope nestedScope) {
980 context = scope; 983 scope = nestedScope;
981 Element element = visit(node); 984 Element element = visit(node);
982 context = context.parent; 985 scope = scope.parent;
983 return element; 986 return element;
984 } 987 }
985 988
986 /** 989 /**
987 * Introduces new default targets for break and continue 990 * Introduces new default targets for break and continue
988 * before visiting the body of the loop 991 * before visiting the body of the loop
989 */ 992 */
990 visitLoopBodyIn(Node loop, Node body, Scope scope) { 993 visitLoopBodyIn(Node loop, Node body, Scope bodyScope) {
991 TargetElement element = getOrCreateTargetElement(loop); 994 TargetElement element = getOrCreateTargetElement(loop);
992 statementScope.enterLoop(element); 995 statementScope.enterLoop(element);
993 visitIn(body, scope); 996 visitIn(body, bodyScope);
994 statementScope.exitLoop(); 997 statementScope.exitLoop();
995 if (!element.isTarget) { 998 if (!element.isTarget) {
996 mapping.remove(loop); 999 mapping.remove(loop);
997 } 1000 }
998 } 1001 }
999 1002
1000 visitBlock(Block node) { 1003 visitBlock(Block node) {
1001 visitIn(node.statements, new BlockScope(context)); 1004 visitIn(node.statements, new BlockScope(scope));
1002 } 1005 }
1003 1006
1004 visitDoWhile(DoWhile node) { 1007 visitDoWhile(DoWhile node) {
1005 visitLoopBodyIn(node, node.body, new BlockScope(context)); 1008 visitLoopBodyIn(node, node.body, new BlockScope(scope));
1006 visit(node.condition); 1009 visit(node.condition);
1007 } 1010 }
1008 1011
1009 visitEmptyStatement(EmptyStatement node) { } 1012 visitEmptyStatement(EmptyStatement node) { }
1010 1013
1011 visitExpressionStatement(ExpressionStatement node) { 1014 visitExpressionStatement(ExpressionStatement node) {
1012 visit(node.expression); 1015 visit(node.expression);
1013 } 1016 }
1014 1017
1015 visitFor(For node) { 1018 visitFor(For node) {
1016 Scope scope = new BlockScope(context); 1019 Scope blockScope = new BlockScope(scope);
1017 visitIn(node.initializer, scope); 1020 visitIn(node.initializer, blockScope);
1018 visitIn(node.condition, scope); 1021 visitIn(node.condition, blockScope);
1019 visitIn(node.update, scope); 1022 visitIn(node.update, blockScope);
1020 visitLoopBodyIn(node, node.body, scope); 1023 visitLoopBodyIn(node, node.body, blockScope);
1021 } 1024 }
1022 1025
1023 visitFunctionDeclaration(FunctionDeclaration node) { 1026 visitFunctionDeclaration(FunctionDeclaration node) {
1024 assert(node.function.name !== null); 1027 assert(node.function.name !== null);
1025 visit(node.function); 1028 visit(node.function);
1026 FunctionElement functionElement = mapping[node.function]; 1029 FunctionElement functionElement = mapping[node.function];
1027 // TODO(floitsch): this might lead to two errors complaining about 1030 // TODO(floitsch): this might lead to two errors complaining about
1028 // shadowing. 1031 // shadowing.
1029 defineElement(node, functionElement); 1032 defineElement(node, functionElement);
1030 } 1033 }
1031 1034
1032 visitFunctionExpression(FunctionExpression node) { 1035 visitFunctionExpression(FunctionExpression node) {
1033 visit(node.returnType); 1036 visit(node.returnType);
1034 SourceString name; 1037 SourceString name;
1035 if (node.name === null) { 1038 if (node.name === null) {
1036 name = const SourceString(""); 1039 name = const SourceString("");
1037 } else { 1040 } else {
1038 name = node.name.asIdentifier().source; 1041 name = node.name.asIdentifier().source;
1039 } 1042 }
1040 FunctionElement enclosing = new FunctionElement.node( 1043 FunctionElement enclosing = new FunctionElement.node(
1041 name, node, ElementKind.FUNCTION, new Modifiers.empty(), 1044 name, node, ElementKind.FUNCTION, new Modifiers.empty(),
1042 context.element); 1045 scope.element);
1043 setupFunction(node, enclosing); 1046 setupFunction(node, enclosing);
1044 defineElement(node, enclosing, doAddToScope: node.name !== null); 1047 defineElement(node, enclosing, doAddToScope: node.name !== null);
1045 1048
1046 // Run the body in a fresh statement scope. 1049 // Run the body in a fresh statement scope.
1047 StatementScope oldScope = statementScope; 1050 StatementScope oldScope = statementScope;
1048 statementScope = new StatementScope(); 1051 statementScope = new StatementScope();
1049 visit(node.body); 1052 visit(node.body);
1050 statementScope = oldScope; 1053 statementScope = oldScope;
1051 1054
1052 context = context.parent; 1055 scope = scope.parent;
1053 } 1056 }
1054 1057
1055 visitIf(If node) { 1058 visitIf(If node) {
1056 visit(node.condition); 1059 visit(node.condition);
1057 visit(node.thenPart); 1060 visit(node.thenPart);
1058 visit(node.elsePart); 1061 visit(node.elsePart);
1059 } 1062 }
1060 1063
1061 static bool isLogicalOperator(Identifier op) { 1064 static bool isLogicalOperator(Identifier op) {
1062 String str = op.source.stringValue; 1065 String str = op.source.stringValue;
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1312 visitVariableDefinitions(VariableDefinitions node) { 1315 visitVariableDefinitions(VariableDefinitions node) {
1313 visit(node.type); 1316 visit(node.type);
1314 VariableDefinitionsVisitor visitor = 1317 VariableDefinitionsVisitor visitor =
1315 new VariableDefinitionsVisitor(compiler, node, this, 1318 new VariableDefinitionsVisitor(compiler, node, this,
1316 ElementKind.VARIABLE); 1319 ElementKind.VARIABLE);
1317 visitor.visit(node.definitions); 1320 visitor.visit(node.definitions);
1318 } 1321 }
1319 1322
1320 visitWhile(While node) { 1323 visitWhile(While node) {
1321 visit(node.condition); 1324 visit(node.condition);
1322 visitLoopBodyIn(node, node.body, new BlockScope(context)); 1325 visitLoopBodyIn(node, node.body, new BlockScope(scope));
1323 } 1326 }
1324 1327
1325 visitParenthesizedExpression(ParenthesizedExpression node) { 1328 visitParenthesizedExpression(ParenthesizedExpression node) {
1326 visit(node.expression); 1329 visit(node.expression);
1327 } 1330 }
1328 1331
1329 visitNewExpression(NewExpression node) { 1332 visitNewExpression(NewExpression node) {
1330 Node selector = node.send.selector; 1333 Node selector = node.send.selector;
1331 1334
1332 FunctionElement constructor = resolveConstructor(node); 1335 FunctionElement constructor = resolveConstructor(node);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1389 Type resolveTypeRequired(TypeAnnotation node) { 1392 Type resolveTypeRequired(TypeAnnotation node) {
1390 bool old = typeRequired; 1393 bool old = typeRequired;
1391 typeRequired = true; 1394 typeRequired = true;
1392 Type result = resolveTypeAnnotation(node); 1395 Type result = resolveTypeAnnotation(node);
1393 typeRequired = old; 1396 typeRequired = old;
1394 return result; 1397 return result;
1395 } 1398 }
1396 1399
1397 Type resolveTypeAnnotation(TypeAnnotation node) { 1400 Type resolveTypeAnnotation(TypeAnnotation node) {
1398 Function report = typeRequired ? error : warning; 1401 Function report = typeRequired ? error : warning;
1399 return typeResolver.resolveTypeAnnotation(node, inContext: context, 1402 return typeResolver.resolveTypeAnnotation(node, inScope: scope,
1400 onFailure: report, 1403 onFailure: report,
1401 whenResolved: useType); 1404 whenResolved: useType);
1402 } 1405 }
1403 1406
1404 visitModifiers(Modifiers node) { 1407 visitModifiers(Modifiers node) {
1405 // TODO(ngeoffray): Implement this. 1408 // TODO(ngeoffray): Implement this.
1406 unimplemented(node, 'modifiers'); 1409 unimplemented(node, 'modifiers');
1407 } 1410 }
1408 1411
1409 visitLiteralList(LiteralList node) { 1412 visitLiteralList(LiteralList node) {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 unimplemented(node, "continue to switch case"); 1477 unimplemented(node, "continue to switch case");
1475 } 1478 }
1476 label.setContinueTarget(); 1479 label.setContinueTarget();
1477 mapping[node.target] = label; 1480 mapping[node.target] = label;
1478 } 1481 }
1479 mapping[node] = target; 1482 mapping[node] = target;
1480 } 1483 }
1481 1484
1482 visitForIn(ForIn node) { 1485 visitForIn(ForIn node) {
1483 visit(node.expression); 1486 visit(node.expression);
1484 Scope scope = new BlockScope(context); 1487 Scope blockScope = new BlockScope(scope);
1485 Node declaration = node.declaredIdentifier; 1488 Node declaration = node.declaredIdentifier;
1486 visitIn(declaration, scope); 1489 visitIn(declaration, blockScope);
1487 visitLoopBodyIn(node, node.body, scope); 1490 visitLoopBodyIn(node, node.body, blockScope);
1488 1491
1489 // TODO(lrn): Also allow a single identifier. 1492 // TODO(lrn): Also allow a single identifier.
1490 if ((declaration is !Send || declaration.asSend().selector is !Identifier) 1493 if ((declaration is !Send || declaration.asSend().selector is !Identifier)
1491 && (declaration is !VariableDefinitions || 1494 && (declaration is !VariableDefinitions ||
1492 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty())) 1495 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty()))
1493 { 1496 {
1494 // The variable declaration is either not an identifier, not a 1497 // The variable declaration is either not an identifier, not a
1495 // declaration, or it's declaring more than one variable. 1498 // declaration, or it's declaring more than one variable.
1496 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); 1499 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []);
1497 } 1500 }
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1597 TargetElement targetElement = label.target; 1600 TargetElement targetElement = label.target;
1598 SwitchCase switchCase = targetElement.statement; 1601 SwitchCase switchCase = targetElement.statement;
1599 mapping.remove(switchCase); 1602 mapping.remove(switchCase);
1600 mapping.remove(label.label); 1603 mapping.remove(label.label);
1601 } 1604 }
1602 }); 1605 });
1603 } 1606 }
1604 1607
1605 visitSwitchCase(SwitchCase node) { 1608 visitSwitchCase(SwitchCase node) {
1606 node.labelsAndCases.accept(this); 1609 node.labelsAndCases.accept(this);
1607 visitIn(node.statements, new BlockScope(context)); 1610 visitIn(node.statements, new BlockScope(scope));
1608 } 1611 }
1609 1612
1610 visitCaseMatch(CaseMatch node) { 1613 visitCaseMatch(CaseMatch node) {
1611 visit(node.expression); 1614 visit(node.expression);
1612 } 1615 }
1613 1616
1614 visitTryStatement(TryStatement node) { 1617 visitTryStatement(TryStatement node) {
1615 visit(node.tryBlock); 1618 visit(node.tryBlock);
1616 if (node.catchBlocks.isEmpty() && node.finallyBlock == null) { 1619 if (node.catchBlocks.isEmpty() && node.finallyBlock == null) {
1617 // TODO(ngeoffray): The precise location is 1620 // TODO(ngeoffray): The precise location is
1618 // node.getEndtoken.next. Adjust when issue #1581 is fixed. 1621 // node.getEndtoken.next. Adjust when issue #1581 is fixed.
1619 error(node, MessageKind.NO_CATCH_NOR_FINALLY); 1622 error(node, MessageKind.NO_CATCH_NOR_FINALLY);
1620 } 1623 }
1621 visit(node.catchBlocks); 1624 visit(node.catchBlocks);
1622 visit(node.finallyBlock); 1625 visit(node.finallyBlock);
1623 } 1626 }
1624 1627
1625 visitCatchBlock(CatchBlock node) { 1628 visitCatchBlock(CatchBlock node) {
1626 Scope scope = new BlockScope(context); 1629 Scope blockScope = new BlockScope(scope);
1627 if (node.formals.isEmpty()) { 1630 if (node.formals.isEmpty()) {
1628 error(node, MessageKind.EMPTY_CATCH_DECLARATION); 1631 error(node, MessageKind.EMPTY_CATCH_DECLARATION);
1629 } else if (!node.formals.nodes.tail.isEmpty() 1632 } else if (!node.formals.nodes.tail.isEmpty()
1630 && !node.formals.nodes.tail.tail.isEmpty()) { 1633 && !node.formals.nodes.tail.tail.isEmpty()) {
1631 for (Node extra in node.formals.nodes.tail.tail) { 1634 for (Node extra in node.formals.nodes.tail.tail) {
1632 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); 1635 error(extra, MessageKind.EXTRA_CATCH_DECLARATION);
1633 } 1636 }
1634 } 1637 }
1635 visitIn(node.formals, scope); 1638 visitIn(node.formals, blockScope);
1636 visitIn(node.block, scope); 1639 visitIn(node.block, blockScope);
1637 } 1640 }
1638 1641
1639 visitTypedef(Typedef node) { 1642 visitTypedef(Typedef node) {
1640 unimplemented(node, 'typedef'); 1643 unimplemented(node, 'typedef');
1641 } 1644 }
1642 } 1645 }
1643 1646
1644 class ClassResolverVisitor extends CommonResolverVisitor<Type> { 1647 class ClassResolverVisitor extends CommonResolverVisitor<Type> {
1645 Scope context; 1648 Scope scope;
1646 ClassElement classElement; 1649 ClassElement classElement;
1647 1650
1648 ClassResolverVisitor(Compiler compiler, LibraryElement library, 1651 ClassResolverVisitor(Compiler compiler,
1649 ClassElement this.classElement) 1652 ClassElement classElement)
1650 : context = new TopScope(library), 1653 : this.classElement = classElement,
1651 super(compiler); 1654 scope = classElement.buildEnclosingScope(),
1655 super(compiler);
1652 1656
1653 Type visitClassNode(ClassNode node) { 1657 Type visitClassNode(ClassNode node) {
1654 compiler.ensure(classElement !== null); 1658 compiler.ensure(classElement !== null);
1655 compiler.ensure(!classElement.isResolved); 1659 compiler.ensure(!classElement.isResolved);
1656 final Link<Node> parameters = 1660 final Link<Node> parameters =
1657 node.typeParameters !== null ? node.typeParameters.nodes 1661 node.typeParameters !== null ? node.typeParameters.nodes
1658 : const EmptyLink<TypeVariable>(); 1662 : const EmptyLink<TypeVariable>();
1659 // Create types and elements for type variable. 1663 // Create types and elements for type variable.
1660 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { 1664 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) {
1661 TypeVariable typeNode = link.head; 1665 TypeVariable typeNode = link.head;
1662 SourceString variableName = typeNode.name.source; 1666 SourceString variableName = typeNode.name.source;
1663 TypeVariableType variableType = new TypeVariableType(variableName); 1667 TypeVariableType variableType = new TypeVariableType(variableName);
1664 TypeVariableElement variableElement = 1668 TypeVariableElement variableElement =
1665 new TypeVariableElement(variableName, classElement, node, 1669 new TypeVariableElement(variableName, classElement, node,
1666 variableType); 1670 variableType);
1667 variableType.element = variableElement; 1671 variableType.element = variableElement;
1668 classElement.typeParameters[variableName] = variableElement; 1672 classElement.typeParameters[variableName] = variableElement;
1669 context = new TypeVariablesScope(context, classElement); 1673 scope = new TypeDeclarationScope(scope, classElement);
1670 } 1674 }
1671 // Resolve the bounds of type variables. 1675 // Resolve the bounds of type variables.
1672 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) { 1676 for (Link<Node> link = parameters; !link.isEmpty(); link = link.tail) {
1673 TypeVariable typeNode = link.head; 1677 TypeVariable typeNode = link.head;
1674 SourceString variableName = typeNode.name.source; 1678 SourceString variableName = typeNode.name.source;
1675 TypeVariableElement variableElement = 1679 TypeVariableElement variableElement =
1676 classElement.typeParameters[variableName]; 1680 classElement.typeParameters[variableName];
1677 if (typeNode.bound !== null) { 1681 if (typeNode.bound !== null) {
1678 Type boundType = visit(typeNode.bound); 1682 Type boundType = visit(typeNode.bound);
1679 if (boundType !== null && boundType.element == variableElement) { 1683 if (boundType !== null && boundType.element == variableElement) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 calculateAllSupertypes(classElement, new Set<ClassElement>()); 1730 calculateAllSupertypes(classElement, new Set<ClassElement>());
1727 addDefaultConstructorIfNeeded(classElement); 1731 addDefaultConstructorIfNeeded(classElement);
1728 return classElement.computeType(compiler); 1732 return classElement.computeType(compiler);
1729 } 1733 }
1730 1734
1731 Type visitTypeAnnotation(TypeAnnotation node) { 1735 Type visitTypeAnnotation(TypeAnnotation node) {
1732 return visit(node.typeName); 1736 return visit(node.typeName);
1733 } 1737 }
1734 1738
1735 Type visitIdentifier(Identifier node) { 1739 Type visitIdentifier(Identifier node) {
1736 Element element = context.lookup(node.source); 1740 Element element = scope.lookup(node.source);
1737 if (element === null) { 1741 if (element === null) {
1738 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]); 1742 error(node, MessageKind.CANNOT_RESOLVE_TYPE, [node]);
1739 return null; 1743 return null;
1740 } else if (!element.impliesType() && !element.isTypeVariable()) { 1744 } else if (!element.impliesType() && !element.isTypeVariable()) {
1741 error(node, MessageKind.NOT_A_TYPE, [node]); 1745 error(node, MessageKind.NOT_A_TYPE, [node]);
1742 return null; 1746 return null;
1743 } else { 1747 } else {
1744 if (element.isClass()) { 1748 if (element.isClass()) {
1745 compiler.resolver.toResolve.add(element); 1749 compiler.resolver.toResolve.add(element);
1746 } 1750 }
1747 if (element.isTypeVariable()) { 1751 if (element.isTypeVariable()) {
1748 TypeVariableElement variableElement = element; 1752 TypeVariableElement variableElement = element;
1749 return variableElement.type; 1753 return variableElement.type;
1750 } else if (element.isTypedef()) { 1754 } else if (element.isTypedef()) {
1751 compiler.unimplemented('visitIdentifier for typedefs', node: node); 1755 compiler.unimplemented('visitIdentifier for typedefs', node: node);
1752 } else { 1756 } else {
1753 // TODO(ngeoffray): Use type variables. 1757 // TODO(ngeoffray): Use type variables.
1754 return element.computeType(compiler); 1758 return element.computeType(compiler);
1755 } 1759 }
1756 } 1760 }
1757 return null; 1761 return null;
1758 } 1762 }
1759 1763
1760 Type visitSend(Send node) { 1764 Type visitSend(Send node) {
1761 Identifier prefix = node.receiver.asIdentifier(); 1765 Identifier prefix = node.receiver.asIdentifier();
1762 if (prefix === null) { 1766 if (prefix === null) {
1763 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); 1767 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
1764 return null; 1768 return null;
1765 } 1769 }
1766 Element element = context.lookup(prefix.source); 1770 Element element = scope.lookup(prefix.source);
1767 if (element === null || element.kind !== ElementKind.PREFIX) { 1771 if (element === null || element.kind !== ElementKind.PREFIX) {
1768 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]); 1772 error(node.receiver, MessageKind.NOT_A_PREFIX, [node.receiver]);
1769 return null; 1773 return null;
1770 } 1774 }
1771 PrefixElement prefixElement = element; 1775 PrefixElement prefixElement = element;
1772 Identifier selector = node.selector.asIdentifier(); 1776 Identifier selector = node.selector.asIdentifier();
1773 var e = prefixElement.lookupLocalMember(selector.source); 1777 var e = prefixElement.lookupLocalMember(selector.source);
1774 if (e === null || !e.impliesType()) { 1778 if (e === null || !e.impliesType()) {
1775 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]); 1779 error(node.selector, MessageKind.CANNOT_RESOLVE_TYPE, [node.selector]);
1776 return null; 1780 return null;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1869 VariableDefinitions definitions; 1873 VariableDefinitions definitions;
1870 ResolverVisitor resolver; 1874 ResolverVisitor resolver;
1871 ElementKind kind; 1875 ElementKind kind;
1872 VariableListElement variables; 1876 VariableListElement variables;
1873 1877
1874 VariableDefinitionsVisitor(Compiler compiler, 1878 VariableDefinitionsVisitor(Compiler compiler,
1875 this.definitions, this.resolver, this.kind) 1879 this.definitions, this.resolver, this.kind)
1876 : super(compiler) 1880 : super(compiler)
1877 { 1881 {
1878 variables = new VariableListElement.node( 1882 variables = new VariableListElement.node(
1879 definitions, ElementKind.VARIABLE_LIST, resolver.context.element); 1883 definitions, ElementKind.VARIABLE_LIST, resolver.scope.element);
1880 } 1884 }
1881 1885
1882 SourceString visitSendSet(SendSet node) { 1886 SourceString visitSendSet(SendSet node) {
1883 assert(node.arguments.tail.isEmpty()); // Sanity check 1887 assert(node.arguments.tail.isEmpty()); // Sanity check
1884 resolver.visit(node.arguments.head); 1888 resolver.visit(node.arguments.head);
1885 return visit(node.selector); 1889 return visit(node.selector);
1886 } 1890 }
1887 1891
1888 SourceString visitIdentifier(Identifier node) => node.source; 1892 SourceString visitIdentifier(Identifier node) => node.source;
1889 1893
1890 visitNodeList(NodeList node) { 1894 visitNodeList(NodeList node) {
1891 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) { 1895 for (Link<Node> link = node.nodes; !link.isEmpty(); link = link.tail) {
1892 SourceString name = visit(link.head); 1896 SourceString name = visit(link.head);
1893 VariableElement element = new VariableElement( 1897 VariableElement element = new VariableElement(
1894 name, variables, kind, resolver.context.element, node: link.head); 1898 name, variables, kind, resolver.scope.element, node: link.head);
1895 resolver.defineElement(link.head, element); 1899 resolver.defineElement(link.head, element);
1896 } 1900 }
1897 } 1901 }
1898 } 1902 }
1899 1903
1904 /**
1905 * [SignatureResolver] resolves function signatures.
1906 */
1900 class SignatureResolver extends CommonResolverVisitor<Element> { 1907 class SignatureResolver extends CommonResolverVisitor<Element> {
1901 final Element enclosingElement; 1908 final Element enclosingElement;
1902 Link<Element> optionalParameters = const EmptyLink<Element>(); 1909 Link<Element> optionalParameters = const EmptyLink<Element>();
1903 int optionalParameterCount = 0; 1910 int optionalParameterCount = 0;
1904 Node currentDefinitions; 1911 VariableDefinitions currentDefinitions;
1905 1912
1906 SignatureResolver(Compiler compiler, this.enclosingElement) : super(compiler); 1913 SignatureResolver(Compiler compiler, this.enclosingElement) : super(compiler);
1907 1914
1908 Element visitNodeList(NodeList node) { 1915 Element visitNodeList(NodeList node) {
1909 // This must be a list of optional arguments. 1916 // This must be a list of optional arguments.
1910 if (node.beginToken.stringValue !== '[') { 1917 if (node.beginToken.stringValue !== '[') {
1911 internalError(node, "expected optional parameters"); 1918 internalError(node, "expected optional parameters");
1912 } 1919 }
1913 LinkBuilder<Element> elements = analyzeNodes(node.nodes); 1920 LinkBuilder<Element> elements = analyzeNodes(node.nodes);
1914 optionalParameterCount = elements.length; 1921 optionalParameterCount = elements.length;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2022 // If parameter is null, the current node should be the last, 2029 // If parameter is null, the current node should be the last,
2023 // and a list of optional named parameters. 2030 // and a list of optional named parameters.
2024 if (!link.tail.isEmpty() || (link.head is !NodeList)) { 2031 if (!link.tail.isEmpty() || (link.head is !NodeList)) {
2025 internalError(link.head, "expected optional parameters"); 2032 internalError(link.head, "expected optional parameters");
2026 } 2033 }
2027 } 2034 }
2028 } 2035 }
2029 return elements; 2036 return elements;
2030 } 2037 }
2031 2038
2039 /**
2040 * Resolves formal parameters and return type to a [FunctionSignature].
2041 */
2032 static FunctionSignature analyze(Compiler compiler, 2042 static FunctionSignature analyze(Compiler compiler,
2033 NodeList formalParameters, 2043 NodeList formalParameters,
2034 Node returnNode, 2044 Node returnNode,
2035 Element element) { 2045 Element element) {
2036 SignatureResolver visitor = new SignatureResolver(compiler, element); 2046 SignatureResolver visitor = new SignatureResolver(compiler, element);
2037 LinkBuilder<Element> parametersBuilder = 2047 LinkBuilder<Element> parametersBuilder =
2038 visitor.analyzeNodes(formalParameters.nodes); 2048 visitor.analyzeNodes(formalParameters.nodes);
2039 Link<Element> parameters = parametersBuilder.toLink(); 2049 Link<Element> parameters = parametersBuilder.toLink();
2040 Type returnType = 2050 Type returnType =
2041 compiler.resolveTypeAnnotation(element, returnNode); 2051 compiler.resolveTypeAnnotation(element, returnNode);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2141 2151
2142 class Scope { 2152 class Scope {
2143 final Element element; 2153 final Element element;
2144 final Scope parent; 2154 final Scope parent;
2145 2155
2146 Scope(this.parent, this.element); 2156 Scope(this.parent, this.element);
2147 abstract Element add(Element element); 2157 abstract Element add(Element element);
2148 abstract Element lookup(SourceString name); 2158 abstract Element lookup(SourceString name);
2149 } 2159 }
2150 2160
2151 class TypeVariablesScope extends Scope { 2161 /**
2152 TypeVariablesScope(parent, ClassElement element) : super(parent, element); 2162 * [TypeDeclarationScope] defines the outer scope of a type declaration in
2163 * which the declared type variables and the entities in the enclosing scope are
2164 * available but where declared and inherited members are not available. This
2165 * scope is only used for class/interface declarations during resolution of the
2166 * class hierarchy. In all other cases [ClassScope] is used.
2167 */
2168 class TypeDeclarationScope extends Scope {
2169 ClassElement get element() => super.element;
2170
2171 TypeDeclarationScope(Scope parent, ClassElement element)
2172 : super(parent, element);
2173
2153 Element add(Element newElement) { 2174 Element add(Element newElement) {
2154 throw "Cannot add element to TypeVariableScope"; 2175 throw "Cannot add element to TypeDeclarationScope";
2155 } 2176 }
2177
2156 Element lookup(SourceString name) { 2178 Element lookup(SourceString name) {
2157 ClassElement cls = element; 2179 Element result = element.lookupTypeParameter(name);
2158 Element result = cls.lookupTypeParameter(name);
2159 if (result !== null) return result; 2180 if (result !== null) return result;
2160 if (parent !== null) return parent.lookup(name); 2181 if (parent !== null) return parent.lookup(name);
2161 } 2182 }
2183
2184 String toString() =>
2185 '$element${element.typeParameters.getKeys()} > $parent';
2162 } 2186 }
2163 2187
2164 class MethodScope extends Scope { 2188 class MethodScope extends Scope {
2165 final Map<SourceString, Element> elements; 2189 final Map<SourceString, Element> elements;
2166 2190
2167 MethodScope(Scope parent, Element element) 2191 MethodScope(Scope parent, Element element)
2168 : super(parent, element), this.elements = new Map<SourceString, Element>(); 2192 : super(parent, element), this.elements = new Map<SourceString, Element>();
2169 2193
2170 Element lookup(SourceString name) { 2194 Element lookup(SourceString name) {
2171 Element found = elements[name]; 2195 Element found = elements[name];
2172 if (found !== null) return found; 2196 if (found !== null) return found;
2173 return parent.lookup(name); 2197 return parent.lookup(name);
2174 } 2198 }
2175 2199
2176 Element add(Element newElement) { 2200 Element add(Element newElement) {
2177 if (elements.containsKey(newElement.name)) { 2201 if (elements.containsKey(newElement.name)) {
2178 return elements[newElement.name]; 2202 return elements[newElement.name];
2179 } 2203 }
2180 elements[newElement.name] = newElement; 2204 elements[newElement.name] = newElement;
2181 return newElement; 2205 return newElement;
2182 } 2206 }
2207
2208 String toString() => '$element${elements.getKeys()} > $parent';
2183 } 2209 }
2184 2210
2185 class BlockScope extends MethodScope { 2211 class BlockScope extends MethodScope {
2186 BlockScope(Scope parent) : super(parent, parent.element); 2212 BlockScope(Scope parent) : super(parent, parent.element);
2213
2214 String toString() => 'block${elements.getKeys()} > $parent';
2187 } 2215 }
2188 2216
2189 class ClassScope extends Scope { 2217 /**
2190 ClassScope(ClassElement element, LibraryElement library) 2218 * [ClassScope] defines the inner scope of a class/interface declaration in
2191 : super(new TopScope(library), element); 2219 * which declared members, declared type variables, entities in the enclosing
2220 * scope and inherited members are available, in the given order.
2221 */
2222 class ClassScope extends TypeDeclarationScope {
2223 ClassScope(Scope parentScope, ClassElement element)
2224 : super(parentScope, element);
2192 2225
2193 Element lookup(SourceString name) { 2226 Element lookup(SourceString name) {
2194 ClassElement cls = element; 2227 ClassElement cls = element;
2195 Element result = cls.lookupLocalMember(name); 2228 Element result = cls.lookupLocalMember(name);
2196 if (result !== null) return result; 2229 if (result !== null) return result;
2197 result = cls.lookupTypeParameter(name); 2230 result = super.lookup(name);
2198 if (result !== null) return result;
2199 result = parent.lookup(name);
2200 if (result != null) return result; 2231 if (result != null) return result;
2201 return cls.lookupSuperMember(name); 2232 return cls.lookupSuperMember(name);
2202 } 2233 }
2203 2234
2204 Element add(Element newElement) { 2235 Element add(Element newElement) {
2205 throw "Cannot add an element in a class scope"; 2236 throw "Cannot add an element in a class scope";
2206 } 2237 }
2238
2239 String toString() => '$element > $parent';
2207 } 2240 }
2208 2241
2209 class TopScope extends Scope { 2242 class TopScope extends Scope {
2210 LibraryElement get library() => element; 2243 LibraryElement get library() => element;
2211 2244
2212 TopScope(LibraryElement library) : super(null, library); 2245 TopScope(LibraryElement library) : super(null, library);
2213 Element lookup(SourceString name) { 2246 Element lookup(SourceString name) {
2214 return library.find(name); 2247 return library.find(name);
2215 } 2248 }
2216 2249
2217 Element add(Element newElement) { 2250 Element add(Element newElement) {
2218 throw "Cannot add an element in the top scope"; 2251 throw "Cannot add an element in the top scope";
2219 } 2252 }
2253 String toString() => '$element';
2220 } 2254 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/elements/elements.dart ('k') | tests/compiler/dart2js/mock_compiler.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698