do not add conditional goto switch end when no default label present but all enum constants were mentioned (IDEA-68872)

This commit is contained in:
anna
2011-06-03 17:59:04 +04:00
parent 0e416a207b
commit 48e81bb6c1
4 changed files with 108 additions and 4 deletions
@@ -26,6 +26,7 @@ import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.RedundantCastUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
@@ -34,6 +35,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
class ControlFlowAnalyzer extends JavaElementVisitor {
@@ -525,13 +527,20 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
startElement(switchStmt);
PsiElementFactory psiFactory = JavaPsiFacade.getInstance(switchStmt.getProject()).getElementFactory();
PsiExpression caseExpression = switchStmt.getExpression();
Set<PsiEnumConstant> enumVals = null;
if (caseExpression != null /*&& !(caseExpression instanceof PsiReferenceExpression)*/) {
caseExpression.accept(this);
generateBoxingUnboxingInstructionFor(caseExpression, PsiType.INT);
if (TypeConversionUtil.isEnumType(caseExpression.getType())) {
final PsiClass psiClass = PsiUtil.resolveClassInType(caseExpression.getType());
if (psiClass != null && psiClass.isEnum()) {
addInstruction(new FieldReferenceInstruction(caseExpression, "switch statement expression"));
enumVals = new HashSet<PsiEnumConstant>();
for (PsiField f : psiClass.getFields()) {
if (f instanceof PsiEnumConstant) {
enumVals.add((PsiEnumConstant)f);
}
}
} else {
addInstruction(new PopInstruction());
}
@@ -567,6 +576,12 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
}
addInstruction(new ConditionalGotoInstruction(offset, false, statement));
if (enumVals != null) {
if (caseValue instanceof PsiReferenceExpression) {
enumVals.remove(((PsiReferenceExpression)caseValue).resolve());
}
}
}
catch (IncorrectOperationException e) {
LOG.error(e);
@@ -575,8 +590,10 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
}
}
int offset = defaultLabel != null ? getStartOffset(defaultLabel) : getEndOffset(body);
addInstruction(new GotoInstruction(offset));
if (enumVals == null || !enumVals.isEmpty()) {
int offset = defaultLabel != null ? getStartOffset(defaultLabel) : getEndOffset(body);
addInstruction(new GotoInstruction(offset));
}
body.accept(this);
}
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
<problem>
<file>Test.java</file>
<line>72</line>
<description>Method invocation &lt;code&gt;foo.length()&lt;/code&gt; may produce &lt;code&gt;java.lang.NullPointerException&lt;/code&gt;</description>
</problem>
</problems>
@@ -0,0 +1,78 @@
public class Test {
void withDefaultWithoutBreak(MyEnum e) {
String foo = null;
switch (e) {
case FOO:
foo = "foo";
case BAR:
foo = "bar";
default:
foo = "default";
}
int l = foo.length();
}
void withDefaultWithBreak(MyEnum e) {
String foo = null;
switch (e) {
case FOO:
foo = "foo";
break;
case BAR:
foo = "bar";
break;
default:
foo = "default";
}
int l = foo.length();
}
void withDefaultWithoutBar(MyEnum e) {
String foo = null;
switch (e) {
case FOO:
foo = "foo";
break;
default:
foo = "default";
}
int l = foo.length();
}
void withoutDefaultWithBreak(MyEnum e) {
String foo = null;
switch (e) {
case FOO:
foo = "foo";
break;
case BAR:
foo = "bar";
break;
}
int l = foo.length();
}
void withoutDefaultWithoutBreak(MyEnum e) {
String foo = null;
switch (e) {
case FOO:
foo = "foo";
case BAR:
foo = "bar";
}
int l = foo.length();
}
void withoutDefaultWithoutBar(MyEnum e) {
String foo = null;
switch (e) {
case FOO:
foo = "foo";
}
int l = foo.length();
}
}
enum MyEnum {
FOO, BAR;
}
@@ -140,4 +140,5 @@ public class DataFlowInspectionTest extends InspectionTestCase {
public void testIDEADEV13156() throws Exception { doTest15(); }
//public void testIDEADEV11033() throws Exception { doTest15(); }
public void testSwitchEnum() throws Exception { doTest15(); }
}