IgnoreResultOfCallInspectionBase: when inferred annotation checked, suppress for methods which have failing contracts.

This commit is contained in:
Tagir Valeev
2017-04-28 12:10:36 +07:00
parent c69528e2ea
commit 64f6abbecd
2 changed files with 42 additions and 4 deletions
@@ -17,6 +17,8 @@ package com.siyeh.ig.bugs;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInspection.dataFlow.ControlFlowAnalyzer;
import com.intellij.codeInspection.dataFlow.MethodContract;
import com.intellij.codeInspection.dataFlow.StandardMethodContract;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.registry.Registry;
@@ -173,6 +175,18 @@ public class IgnoreResultOfCallInspectionBase extends BaseInspection {
if (anno != null &&
(honorInferred || !AnnotationUtil.isInferredAnnotation(anno)) &&
Boolean.TRUE.equals(AnnotationUtil.getBooleanAttributeValue(anno, "pure"))) {
String text = AnnotationUtil.getStringAttributeValue(anno, null);
if (text != null) {
try {
if (StandardMethodContract.parseContract(text).stream()
.anyMatch(c -> c.getReturnValue() == MethodContract.ValueConstraint.THROW_EXCEPTION)) {
return;
}
}
catch (StandardMethodContract.ParseException ignored) {
}
}
registerMethodCallOrRefError(call, aClass);
return;
}
@@ -16,9 +16,10 @@
package com.siyeh.ig.bugs
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.openapi.util.registry.Registry
import com.siyeh.ig.LightInspectionTestCase
@SuppressWarnings("ResultOfMethodCallIgnored")
@SuppressWarnings(["ResultOfMethodCallIgnored", "UnusedReturnValue"])
class IgnoreResultOfCallInspectionTest extends LightInspectionTestCase {
@Override
@@ -98,7 +99,7 @@ class IgnoreResultOfCallInspectionTest extends LightInspectionTestCase {
" final java.util.regex.Pattern pattern = java.util.regex.Pattern.compile(\"baaaa\");\n" +
" final java.util.regex.Matcher matcher = pattern.matcher(\"babaaaaaaaa\");\n" +
" matcher./*Result of 'Matcher.find()' is ignored*/find/**/();\n" +
" matcher.notify();\n" +
" matcher.notifyAll();\n" +
" }\n" +
"}\n")
}
@@ -166,6 +167,29 @@ class IgnoreResultOfCallInspectionTest extends LightInspectionTestCase {
"}")
}
void testInference() {
Registry.get("ide.ignore.call.result.inspection.honor.inferred.pure").setValue(true, getTestRootDisposable())
doTest("""class Test {
private static <T> T checkNotNull(T reference) {
if (reference == null) {
throw new NullPointerException();
}
return reference;
}
private static String twice(String s) {
return s+s;
}
void test(String string) {
checkNotNull(string);
/*Result of 'Test.twice()' is ignored*/twice/**/("foo");
/*Result of 'Test.twice()' is ignored*/twice/**/("bar");
}
}
""")
}
void testPureMethod() {
doTest """
import org.jetbrains.annotations.Contract;
@@ -176,7 +200,7 @@ class Util {
}
class C {
{
static {
Util./*Result of 'Util.util()' is ignored*/util/**/();
}
}
@@ -193,7 +217,7 @@ class Util {
}
class C {
{
static {
Runnable r = () -> Util./*Result of 'Util.util()' is ignored*/util/**/();
Runnable r1 = Util::/*Result of 'Util.util()' is ignored*/util/**/;
}