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

Side by Side Diff: compiler/java/com/google/dart/compiler/resolver/Resolver.java

Issue 10725002: Validate the target of break and continue statments from within a switch (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: # Created 8 years, 5 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 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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698