IDEA-123948 Constant condition and exceptions: false positive on MappedByteBuffer.getInt

This commit is contained in:
peter
2014-04-18 22:37:31 +02:00
parent 0fd86dea1f
commit 29fec2258a
4 changed files with 47 additions and 2 deletions
@@ -22,6 +22,7 @@ import com.intellij.codeInspection.dataFlow.instructions.*;
import com.intellij.codeInspection.dataFlow.value.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -38,6 +39,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.regex.Pattern;
import static com.intellij.codeInsight.ConditionChecker.Type.*;
import static com.intellij.codeInspection.dataFlow.MethodContract.ValueConstraint;
@@ -45,6 +47,24 @@ import static com.intellij.psi.CommonClassNames.*;
public class ControlFlowAnalyzer extends JavaElementVisitor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer");
private static final Condition<String> FALSE_GETTERS = parseFalseGetters();
private static Condition<String> parseFalseGetters() {
try {
final Pattern pattern = Pattern.compile(Registry.stringValue("ide.dfa.getters.with.side.effects"));
return new Condition<String>() {
@Override
public boolean value(String s) {
return pattern.matcher(s).matches();
}
};
}
catch (Exception e) {
LOG.error(e);
return Condition.FALSE;
}
}
public static final String ORG_JETBRAINS_ANNOTATIONS_CONTRACT = Contract.class.getName();
private boolean myIgnoreAssertions;
@@ -1891,7 +1911,10 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
}
if (target instanceof PsiMethod) {
if (PropertyUtil.isSimplePropertyGetter((PsiMethod)target)) {
return (PsiMethod)target;
String qName = PsiUtil.getMemberQualifiedName((PsiMethod)target);
if (qName == null || !FALSE_GETTERS.value(qName)) {
return (PsiMethod)target;
}
}
}
return null;
@@ -0,0 +1,14 @@
import java.nio.MappedByteBuffer;
class Test
{
public static int triggerBug(MappedByteBuffer buffer)
{
int a = buffer.getInt();
int b = buffer.getInt();
if(a == 0 && b == 1)
return 0;
else
return 1;
}
}
@@ -286,7 +286,12 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
public void testNoConfusionWithAnonymousConstantInitializer() { doTest(); }
public void testForeachOverWildcards() { doTest(); }
public void testFinalGetter() { doTest(); }
public void testByteBufferGetter() {
myFixture.addClass("package java.nio; public class MappedByteBuffer { public int getInt() {} }");
doTest();
}
public void testManySequentialIfsNotComplex() { doTest(); }
public void testManySequentialInstanceofsNotComplex() { doTest(); }
public void testLongDisjunctionsNotComplex() { doTest(); }
@@ -262,6 +262,9 @@ ide.structural.navigation.visit.fields.description=Whether fields should be stop
ide.non.english.keyboard.layout.fix=false
ide.non.english.keyboard.layout.fix.description=Enables a fix for key codes with non-English keyboard layouts
ide.dfa.getters.with.side.effects=java\\.nio\\..*ByteBuffer\\.get.*
ide.dfa.getters.with.side.effects.description=A regex on qualified names of methods that look like getters but are not. For Constant Conditions & Exception inspection
ide.enable.toolwindow.stack=false
change.signature.awesome.mode=true