OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 package com.google.dart.compiler.resolver; | 5 package com.google.dart.compiler.resolver; |
6 | 6 |
7 import com.google.common.annotations.VisibleForTesting; | 7 import com.google.common.annotations.VisibleForTesting; |
8 import com.google.common.collect.Lists; | 8 import com.google.common.collect.Lists; |
9 import com.google.common.collect.Sets; | 9 import com.google.common.collect.Sets; |
10 import com.google.dart.compiler.DartCompilationPhase; | 10 import com.google.dart.compiler.DartCompilationPhase; |
11 import com.google.dart.compiler.DartCompilerContext; | 11 import com.google.dart.compiler.DartCompilerContext; |
12 import com.google.dart.compiler.ErrorCode; | 12 import com.google.dart.compiler.ErrorCode; |
13 import com.google.dart.compiler.ast.DartArrayLiteral; | 13 import com.google.dart.compiler.ast.DartArrayLiteral; |
14 import com.google.dart.compiler.ast.DartBinaryExpression; | 14 import com.google.dart.compiler.ast.DartBinaryExpression; |
15 import com.google.dart.compiler.ast.DartBlock; | 15 import com.google.dart.compiler.ast.DartBlock; |
16 import com.google.dart.compiler.ast.DartBooleanLiteral; | 16 import com.google.dart.compiler.ast.DartBooleanLiteral; |
17 import com.google.dart.compiler.ast.DartBreakStatement; | 17 import com.google.dart.compiler.ast.DartBreakStatement; |
18 import com.google.dart.compiler.ast.DartCatchBlock; | 18 import com.google.dart.compiler.ast.DartCatchBlock; |
19 import com.google.dart.compiler.ast.DartClass; | 19 import com.google.dart.compiler.ast.DartClass; |
20 import com.google.dart.compiler.ast.DartClassMember; | 20 import com.google.dart.compiler.ast.DartClassMember; |
| 21 import com.google.dart.compiler.ast.DartContinueStatement; |
21 import com.google.dart.compiler.ast.DartDoWhileStatement; | 22 import com.google.dart.compiler.ast.DartDoWhileStatement; |
22 import com.google.dart.compiler.ast.DartDoubleLiteral; | 23 import com.google.dart.compiler.ast.DartDoubleLiteral; |
23 import com.google.dart.compiler.ast.DartExpression; | 24 import com.google.dart.compiler.ast.DartExpression; |
24 import com.google.dart.compiler.ast.DartField; | 25 import com.google.dart.compiler.ast.DartField; |
25 import com.google.dart.compiler.ast.DartFieldDefinition; | 26 import com.google.dart.compiler.ast.DartFieldDefinition; |
26 import com.google.dart.compiler.ast.DartForInStatement; | 27 import com.google.dart.compiler.ast.DartForInStatement; |
27 import com.google.dart.compiler.ast.DartForStatement; | 28 import com.google.dart.compiler.ast.DartForStatement; |
28 import com.google.dart.compiler.ast.DartFunction; | 29 import com.google.dart.compiler.ast.DartFunction; |
29 import com.google.dart.compiler.ast.DartFunctionExpression; | 30 import com.google.dart.compiler.ast.DartFunctionExpression; |
30 import com.google.dart.compiler.ast.DartFunctionObjectInvocation; | 31 import com.google.dart.compiler.ast.DartFunctionObjectInvocation; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 import com.google.dart.compiler.ast.DartTypeParameter; | 63 import com.google.dart.compiler.ast.DartTypeParameter; |
63 import com.google.dart.compiler.ast.DartUnit; | 64 import com.google.dart.compiler.ast.DartUnit; |
64 import com.google.dart.compiler.ast.DartUnqualifiedInvocation; | 65 import com.google.dart.compiler.ast.DartUnqualifiedInvocation; |
65 import com.google.dart.compiler.ast.DartVariable; | 66 import com.google.dart.compiler.ast.DartVariable; |
66 import com.google.dart.compiler.ast.DartVariableStatement; | 67 import com.google.dart.compiler.ast.DartVariableStatement; |
67 import com.google.dart.compiler.ast.DartWhileStatement; | 68 import com.google.dart.compiler.ast.DartWhileStatement; |
68 import com.google.dart.compiler.ast.Modifiers; | 69 import com.google.dart.compiler.ast.Modifiers; |
69 import com.google.dart.compiler.common.HasSourceInfo; | 70 import com.google.dart.compiler.common.HasSourceInfo; |
70 import com.google.dart.compiler.common.SourceInfo; | 71 import com.google.dart.compiler.common.SourceInfo; |
71 import com.google.dart.compiler.parser.Token; | 72 import com.google.dart.compiler.parser.Token; |
| 73 import com.google.dart.compiler.resolver.LabelElement.LabeledStatementType; |
72 import com.google.dart.compiler.type.InterfaceType; | 74 import com.google.dart.compiler.type.InterfaceType; |
73 import com.google.dart.compiler.type.InterfaceType.Member; | 75 import com.google.dart.compiler.type.InterfaceType.Member; |
74 import com.google.dart.compiler.type.Type; | 76 import com.google.dart.compiler.type.Type; |
75 import com.google.dart.compiler.type.TypeKind; | 77 import com.google.dart.compiler.type.TypeKind; |
76 import com.google.dart.compiler.type.TypeVariable; | 78 import com.google.dart.compiler.type.TypeVariable; |
77 import com.google.dart.compiler.type.Types; | 79 import com.google.dart.compiler.type.Types; |
78 import com.google.dart.compiler.util.apache.StringUtils; | 80 import com.google.dart.compiler.util.apache.StringUtils; |
79 | 81 |
80 import java.util.EnumSet; | 82 import java.util.EnumSet; |
81 import java.util.Iterator; | 83 import java.util.Iterator; |
(...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 for (DartVariable variable : node.getVariables()) { | 748 for (DartVariable variable : node.getVariables()) { |
747 String name = variable.getVariableName(); | 749 String name = variable.getVariableName(); |
748 getContext().getScope().removeDeclaredButNotReachedVariable(name); | 750 getContext().getScope().removeDeclaredButNotReachedVariable(name); |
749 Elements.setType(resolveVariable(variable, node.getModifiers()), type); | 751 Elements.setType(resolveVariable(variable, node.getModifiers()), type); |
750 checkVariableStatement(node, variable, isImplicitlyInitialized); | 752 checkVariableStatement(node, variable, isImplicitlyInitialized); |
751 } | 753 } |
752 } | 754 } |
753 | 755 |
754 @Override | 756 @Override |
755 public Element visitLabel(DartLabel x) { | 757 public Element visitLabel(DartLabel x) { |
756 LabelElement currentLabel = Elements.labelElement(x, x.getName(), innermos
tFunction); | 758 DartNode parent = x.getParent(); |
757 recordElement(x.getLabel(), currentLabel); | 759 if (!(parent instanceof DartSwitchMember)) { |
758 recordElement(x, currentLabel); | 760 LabelElement labelElement; |
| 761 DartStatement childStatement = x.getStatement(); |
| 762 while (childStatement instanceof DartLabel) { |
| 763 childStatement = ((DartLabel)childStatement).getStatement(); |
| 764 } |
| 765 if (childStatement instanceof DartSwitchStatement) { |
| 766 labelElement = Elements.switchLabelElement(x, x.getName(), innermostFu
nction); |
| 767 } else { |
| 768 labelElement = Elements.statementLabelElement(x, x.getName(), innermos
tFunction); |
| 769 } |
| 770 recordElement(x.getLabel(), labelElement); |
| 771 recordElement(x, labelElement); |
| 772 } |
759 x.visitChildren(this); | 773 x.visitChildren(this); |
760 if (!labelsInScopes.contains(currentLabel)) { | |
761 // TODO(zundel): warning, not type error. | |
762 // topLevelContext.typeError(x, DartCompilerErrorCode.USELESS_LABEL, x.g
etName()); | |
763 } else if (!referencedLabels.contains(currentLabel)) { | |
764 // TODO(zundel): warning, not type error. | |
765 // topLevelContext.typeError(x, DartCompilerErrorCode.UNREFERENCED_LABEL
, x.getName()); | |
766 } | |
767 return null; | 774 return null; |
768 } | 775 } |
769 | 776 |
770 @Override | 777 @Override |
771 public Element visitFunctionExpression(DartFunctionExpression x) { | 778 public Element visitFunctionExpression(DartFunctionExpression x) { |
772 MethodElement element; | 779 MethodElement element; |
773 if (x.isStatement()) { | 780 if (x.isStatement()) { |
774 // Function statement names live in the outer scope. | 781 // Function statement names live in the outer scope. |
775 element = getContext().declareFunction(x); | 782 element = getContext().declareFunction(x); |
776 getContext().pushFunctionScope(x); | 783 getContext().pushFunctionScope(x); |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 resolveVariableStatement(x.getVariableStatement(), true); | 903 resolveVariableStatement(x.getVariableStatement(), true); |
897 } else { | 904 } else { |
898 x.getIdentifier().accept(this); | 905 x.getIdentifier().accept(this); |
899 } | 906 } |
900 x.getIterable().accept(this); | 907 x.getIterable().accept(this); |
901 x.getBody().accept(this); | 908 x.getBody().accept(this); |
902 getContext().popScope(); | 909 getContext().popScope(); |
903 return null; | 910 return null; |
904 } | 911 } |
905 | 912 |
906 private void addLabelToStatement(DartStatement x) { | 913 private void addLabelToStatement(DartNode x) { |
907 DartNode parent = x.getParent(); | 914 DartNode parent = x.getParent(); |
908 while (parent instanceof DartLabel) { | 915 while (parent instanceof DartLabel) { |
909 LabelElement currentLabel = ((DartLabel) parent).getElement(); | 916 DartLabel label = (DartLabel) parent; |
| 917 LabelElement currentLabel = label.getElement(); |
910 getContext().getScope().addLabel(currentLabel); | 918 getContext().getScope().addLabel(currentLabel); |
911 labelsInScopes.add(currentLabel); | 919 labelsInScopes.add(currentLabel); |
912 parent = parent.getParent(); | 920 parent = parent.getParent(); |
913 } | 921 } |
914 } | 922 } |
915 | 923 |
916 private void addLabelToSwitchMember(DartSwitchMember x) { | |
917 DartLabel label = x.getLabel(); | |
918 if (label != null) { | |
919 LabelElement currentLabel = label.getElement(); // TODO(zundel): Y U NO
HAVE ELEMENT? | |
920 if (getContext().getScope().hasLocalLabel(label.getName())) { | |
921 onError(label, ResolverErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT); | |
922 } | |
923 getContext().getScope().addLabel(currentLabel); | |
924 labelsInScopes.add(currentLabel); | |
925 } | |
926 } | |
927 | |
928 | |
929 @Override | 924 @Override |
930 public Element visitForStatement(DartForStatement x) { | 925 public Element visitForStatement(DartForStatement x) { |
931 getContext().pushScope("<for>"); | 926 getContext().pushScope("<for>"); |
932 addLabelToStatement(x); | 927 addLabelToStatement(x); |
933 x.visitChildren(this); | 928 x.visitChildren(this); |
934 getContext().popScope(); | 929 getContext().popScope(); |
935 return null; | 930 return null; |
936 } | 931 } |
937 | 932 |
938 | 933 |
939 @Override | 934 @Override |
940 public Element visitSwitchStatement(DartSwitchStatement x) { | 935 public Element visitSwitchStatement(DartSwitchStatement x) { |
941 getContext().pushScope("<switch>"); | 936 getContext().pushScope("<switch>"); |
942 addLabelToStatement(x); | 937 addLabelToStatement(x); |
| 938 // The scope of a label on the case statement is the case statement itself
. These labels |
| 939 // need to be resolved before the continue <label>; statements can be reso
lved. |
| 940 for (DartSwitchMember member : x.getMembers()) { |
| 941 recordSwitchMamberLabel(member); |
| 942 } |
943 x.visitChildren(this); | 943 x.visitChildren(this); |
944 getContext().popScope(); | 944 getContext().popScope(); |
945 return null; | 945 return null; |
946 } | 946 } |
947 | 947 |
948 @Override | 948 @Override |
949 public Element visitSwitchMember(DartSwitchMember x) { | 949 public Element visitSwitchMember(DartSwitchMember x) { |
950 getContext().pushScope("<switch member>"); | 950 getContext().pushScope("<switch member>"); |
951 x.visitChildren(this); | 951 x.visitChildren(this); |
952 getContext().popScope(); | 952 getContext().popScope(); |
953 // The scope of a label on the case statement is the case statement itself
. | |
954 addLabelToSwitchMember(x); | |
955 return null; | 953 return null; |
956 } | 954 } |
957 | 955 |
| 956 private void recordSwitchMamberLabel(DartSwitchMember x) { |
| 957 DartLabel label = x.getLabel(); |
| 958 if (label != null) { |
| 959 LabelElement labelElement = Elements.switchMemberLabelElement(label, la
bel.getName(), |
| 960 innermostFunction); |
| 961 recordElement(label.getLabel(), labelElement); |
| 962 recordElement(label, labelElement); |
| 963 if (getContext().getScope().hasLocalLabel(label.getName())) { |
| 964 onError(label, ResolverErrorCode.DUPLICATE_LABEL_IN_SWITCH_STATEMENT); |
| 965 } |
| 966 getContext().getScope().addLabel(labelElement); |
| 967 labelsInScopes.add(labelElement); |
| 968 } |
| 969 } |
| 970 |
958 @Override | 971 @Override |
959 public Element visitThisExpression(DartThisExpression x) { | 972 public Element visitThisExpression(DartThisExpression x) { |
960 if (ElementKind.of(currentHolder).equals(ElementKind.LIBRARY)) { | 973 if (ElementKind.of(currentHolder).equals(ElementKind.LIBRARY)) { |
961 onError(x, ResolverErrorCode.THIS_ON_TOP_LEVEL); | 974 onError(x, ResolverErrorCode.THIS_ON_TOP_LEVEL); |
962 } else if (currentMethod == null) { | 975 } else if (currentMethod == null) { |
963 onError(x, ResolverErrorCode.THIS_OUTSIDE_OF_METHOD); | 976 onError(x, ResolverErrorCode.THIS_OUTSIDE_OF_METHOD); |
964 } else if (currentMethod.getModifiers().isStatic()) { | 977 } else if (currentMethod.getModifiers().isStatic()) { |
965 onError(x, ResolverErrorCode.THIS_IN_STATIC_METHOD); | 978 onError(x, ResolverErrorCode.THIS_IN_STATIC_METHOD); |
966 } else if (currentMethod.getModifiers().isFactory()) { | 979 } else if (currentMethod.getModifiers().isFactory()) { |
967 onError(x, ResolverErrorCode.THIS_IN_FACTORY_CONSTRUCTOR); | 980 onError(x, ResolverErrorCode.THIS_IN_FACTORY_CONSTRUCTOR); |
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1561 } | 1574 } |
1562 } | 1575 } |
1563 | 1576 |
1564 @Override | 1577 @Override |
1565 public Element visitGotoStatement(DartGotoStatement x) { | 1578 public Element visitGotoStatement(DartGotoStatement x) { |
1566 // Don't bother unless there's a target. | 1579 // Don't bother unless there's a target. |
1567 if (x.getTargetName() != null) { | 1580 if (x.getTargetName() != null) { |
1568 Element element = getContext().getScope().findLabel(x.getTargetName(), i
nnermostFunction); | 1581 Element element = getContext().getScope().findLabel(x.getTargetName(), i
nnermostFunction); |
1569 if (ElementKind.of(element).equals(ElementKind.LABEL)) { | 1582 if (ElementKind.of(element).equals(ElementKind.LABEL)) { |
1570 LabelElement labelElement = (LabelElement) element; | 1583 LabelElement labelElement = (LabelElement) element; |
| 1584 if (x instanceof DartBreakStatement |
| 1585 && labelElement.getStatementType() == LabeledStatementType.SWITCH_
MEMBER_STATEMENT) { |
| 1586 onError(x.getLabel(), ResolverErrorCode.BREAK_LABEL_RESOLVES_TO_CASE
_OR_DEFAULT); |
| 1587 return null; |
| 1588 } |
| 1589 if (x instanceof DartContinueStatement |
| 1590 && labelElement.getStatementType() == LabeledStatementType.SWITCH_
STATEMENT) { |
| 1591 onError(x.getLabel(), ResolverErrorCode.CONTINUE_LABEL_RESOLVES_TO_S
WITCH); |
| 1592 return null; |
| 1593 } |
1571 MethodElement enclosingFunction = (labelElement).getEnclosingFunction(
); | 1594 MethodElement enclosingFunction = (labelElement).getEnclosingFunction(
); |
1572 if (enclosingFunction == innermostFunction) { | 1595 if (enclosingFunction == innermostFunction) { |
1573 referencedLabels.add(labelElement); | 1596 referencedLabels.add(labelElement); |
1574 return recordElement(x, element); | 1597 return recordElement(x, element); |
1575 } | 1598 } |
1576 } | 1599 } |
1577 diagnoseErrorInGotoStatement(x, element); | 1600 diagnoseErrorInGotoStatement(x, element); |
1578 } | 1601 } |
1579 return null; | 1602 return null; |
1580 } | 1603 } |
(...skipping 27 matching lines...) Expand all Loading... |
1608 classOrLibrary.getName()); | 1631 classOrLibrary.getName()); |
1609 break; | 1632 break; |
1610 default: | 1633 default: |
1611 onError(errorNode, ResolverErrorCode.CANNOT_RESOLVE_METHOD, name); | 1634 onError(errorNode, ResolverErrorCode.CANNOT_RESOLVE_METHOD, name); |
1612 } | 1635 } |
1613 | 1636 |
1614 break; | 1637 break; |
1615 | 1638 |
1616 case CONSTRUCTOR: | 1639 case CONSTRUCTOR: |
1617 onError(errorNode, ResolverErrorCode.IS_A_CONSTRUCTOR, classOrLibrary.
getName(), | 1640 onError(errorNode, ResolverErrorCode.IS_A_CONSTRUCTOR, classOrLibrary.
getName(), |
1618 name); | 1641 name); |
1619 break; | 1642 break; |
1620 | 1643 |
1621 case METHOD: { | 1644 case METHOD: { |
1622 assert !((MethodElement) element).getModifiers().isStatic(); | 1645 assert !((MethodElement) element).getModifiers().isStatic(); |
1623 onError(errorNode, ResolverErrorCode.IS_AN_INSTANCE_METHOD, | 1646 onError(errorNode, ResolverErrorCode.IS_AN_INSTANCE_METHOD, |
1624 classOrLibrary.getName(), name); | 1647 classOrLibrary.getName(), name); |
1625 break; | 1648 break; |
1626 } | 1649 } |
1627 | 1650 |
1628 default: | 1651 default: |
(...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2141 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos
ingElement(); | 2164 ClassElement nextClass = (ClassElement) nextConstructorElement.getEnclos
ingElement(); |
2142 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme
nt(); | 2165 ClassElement currentClass = (ClassElement) constructor.getEnclosingEleme
nt(); |
2143 if (nextClass == currentClass) { | 2166 if (nextClass == currentClass) { |
2144 return (ConstructorNodeElement) nextConstructorElement; | 2167 return (ConstructorNodeElement) nextConstructorElement; |
2145 } | 2168 } |
2146 } | 2169 } |
2147 } | 2170 } |
2148 return null; | 2171 return null; |
2149 } | 2172 } |
2150 } | 2173 } |
OLD | NEW |