mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
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:
@@ -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 <code>foo.length()</code> may produce <code>java.lang.NullPointerException</code></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(); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user