Lines 24-29
Link Here
|
24 |
*/ |
24 |
*/ |
25 |
package com.sun.tools.javac.comp; |
25 |
package com.sun.tools.javac.comp; |
26 |
|
26 |
|
|
|
27 |
import com.sun.source.tree.CaseTree; |
28 |
import com.sun.source.tree.TreeVisitor; |
27 |
import com.sun.tools.javac.code.Flags; |
29 |
import com.sun.tools.javac.code.Flags; |
28 |
import com.sun.tools.javac.code.Kinds; |
30 |
import com.sun.tools.javac.code.Kinds; |
29 |
import com.sun.tools.javac.code.Scope; |
31 |
import com.sun.tools.javac.code.Scope; |
Lines 53-63
Link Here
|
53 |
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; |
55 |
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation; |
54 |
import com.sun.tools.javac.tree.JCTree.JCNewClass; |
56 |
import com.sun.tools.javac.tree.JCTree.JCNewClass; |
55 |
import com.sun.tools.javac.tree.JCTree.JCStatement; |
57 |
import com.sun.tools.javac.tree.JCTree.JCStatement; |
|
|
58 |
import com.sun.tools.javac.tree.JCTree.JCSwitch; |
56 |
import com.sun.tools.javac.tree.JCTree.JCTypeParameter; |
59 |
import com.sun.tools.javac.tree.JCTree.JCTypeParameter; |
57 |
import com.sun.tools.javac.tree.JCTree.JCUnary; |
60 |
import com.sun.tools.javac.tree.JCTree.JCUnary; |
58 |
import com.sun.tools.javac.tree.JCTree.JCVariableDecl; |
61 |
import com.sun.tools.javac.tree.JCTree.JCVariableDecl; |
59 |
import com.sun.tools.javac.tree.TreeInfo; |
62 |
import com.sun.tools.javac.tree.TreeInfo; |
60 |
import com.sun.tools.javac.tree.TreeMaker; |
63 |
import com.sun.tools.javac.tree.TreeMaker; |
|
|
64 |
import com.sun.tools.javac.tree.TreeScanner; |
61 |
import com.sun.tools.javac.tree.TreeTranslator; |
65 |
import com.sun.tools.javac.tree.TreeTranslator; |
62 |
import com.sun.tools.javac.util.Context; |
66 |
import com.sun.tools.javac.util.Context; |
63 |
import com.sun.tools.javac.util.JCDiagnostic; |
67 |
import com.sun.tools.javac.util.JCDiagnostic; |
Lines 158-167
Link Here
|
158 |
return tree; |
162 |
return tree; |
159 |
if (tree.hasTag(JCTree.Tag.CASE)) |
163 |
if (tree.hasTag(JCTree.Tag.CASE)) |
160 |
return tree; |
164 |
return tree; |
161 |
if (tree.hasTag(JCTree.Tag.CLASSDEF) || tree.hasTag(JCTree.Tag.VARDEF)) { |
165 |
if (tree.hasTag(JCTree.Tag.CLASSDEF)) { |
162 |
JCTree parent = parents.head; |
166 |
JCTree parent = parents.head; |
163 |
if (parent == null || (!parent.hasTag(JCTree.Tag.BLOCK) && !parent.hasTag(JCTree.Tag.CASE))) |
167 |
if (parent == null || (!parent.hasTag(JCTree.Tag.BLOCK) && !parent.hasTag(JCTree.Tag.CASE))) { |
164 |
return tree; |
168 |
return tree; |
|
|
169 |
} |
170 |
} |
171 |
if (tree.hasTag(JCTree.Tag.VARDEF)) { |
172 |
JCTree parent = parents.head; |
173 |
if (parent == null) { |
174 |
return tree; |
175 |
} |
176 |
// special case: in switch-case, generate throw and terminate the case only if the variable is not used |
177 |
// in subsequent switch cases. Otherwise return the tree unchanged with error flags, the whole switch |
178 |
// statement will be aborted and replaced by throw. |
179 |
if (parent.hasTag(JCTree.Tag.CASE)) { |
180 |
if (!parents.tail.isEmpty()) { |
181 |
JCTree t = parents.tail.head; |
182 |
if (t.hasTag(JCTree.Tag.SWITCH) && varUsedInOtherCaseBranch((JCVariableDecl)tree, (JCSwitch)t, (JCCase)parent)) { |
183 |
// assume the whole switch will be replaced by throw statement. |
184 |
return tree; |
185 |
} |
186 |
} |
187 |
} else if (!parent.hasTag(JCTree.Tag.BLOCK)) { |
188 |
return tree; |
189 |
} |
165 |
} |
190 |
} |
166 |
String msg = err != null ? err.getMessage(null) : errMessage; |
191 |
String msg = err != null ? err.getMessage(null) : errMessage; |
167 |
hasError = false; |
192 |
hasError = false; |
Lines 173-179
Link Here
|
173 |
} |
198 |
} |
174 |
return (T)generateErrStat(tree.pos(), msg); |
199 |
return (T)generateErrStat(tree.pos(), msg); |
175 |
} |
200 |
} |
|
|
201 |
|
202 |
private boolean varUsedInOtherCaseBranch(final JCTree.JCVariableDecl varDecl, JCSwitch sw, JCCase defCase) { |
203 |
List<JCCase> cases = sw.getCases(); |
204 |
int index = cases.indexOf(defCase); |
205 |
if (index == -1) { |
206 |
// not sure, eliminate whole switch |
207 |
return true; |
208 |
} |
209 |
class SwitchVariableFinder extends TreeScanner { |
210 |
private boolean used; |
176 |
|
211 |
|
|
|
212 |
@Override |
213 |
public void visitIdent(JCTree.JCIdent tree) { |
214 |
used |= tree.sym == varDecl.sym; |
215 |
super.visitIdent(tree); |
216 |
} |
217 |
} |
218 |
SwitchVariableFinder finder = new SwitchVariableFinder(); |
219 |
for (int i = index + 1; i < cases.size(); i++) { |
220 |
JCTree testCase = cases.get(i); |
221 |
finder.scan(testCase); |
222 |
if (finder.used) { |
223 |
return true; |
224 |
} |
225 |
} |
226 |
return false; |
227 |
} |
228 |
|
177 |
@Override |
229 |
@Override |
178 |
public void visitImport(JCImport tree) { |
230 |
public void visitImport(JCImport tree) { |
179 |
super.visitImport(tree); |
231 |
super.visitImport(tree); |