mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
SideEffectChecker: mark all assert* methods as having exceptional effect
SideEffectChecker#mayHaveExceptionalSideEffect extracted Fixes IDEA-174418
This commit is contained in:
+2
-3
@@ -17,7 +17,6 @@ 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.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
@@ -34,6 +33,7 @@ import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.LibraryUtil;
|
||||
import com.siyeh.ig.psiutils.MethodMatcher;
|
||||
import com.siyeh.ig.psiutils.SideEffectChecker;
|
||||
import org.intellij.lang.annotations.Pattern;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -228,8 +228,7 @@ public class IgnoreResultOfCallInspectionBase extends BaseInspection {
|
||||
final boolean honorInferred = Registry.is("ide.ignore.call.result.inspection.honor.inferred.pure");
|
||||
if (!honorInferred && AnnotationUtil.isInferredAnnotation(anno)) return false;
|
||||
return Boolean.TRUE.equals(AnnotationUtil.getBooleanAttributeValue(anno, "pure")) &&
|
||||
ControlFlowAnalyzer.getMethodCallContracts(method, null).stream()
|
||||
.noneMatch(c -> c.getReturnValue() == MethodContract.ValueConstraint.THROW_EXCEPTION);
|
||||
!SideEffectChecker.mayHaveExceptionalSideEffect(method);
|
||||
}
|
||||
|
||||
private void registerMethodCallOrRefError(PsiExpression call, PsiClass aClass) {
|
||||
|
||||
+16
-5
@@ -126,11 +126,7 @@ public class SideEffectChecker {
|
||||
protected boolean isPure(PsiMethod method) {
|
||||
if (method == null) return false;
|
||||
if (PropertyUtil.isSimpleGetter(method)) return true;
|
||||
if (ControlFlowAnalyzer.isPure(method)) {
|
||||
return ControlFlowAnalyzer.getMethodContracts(method).stream()
|
||||
.noneMatch(mc -> mc.returnValue == MethodContract.ValueConstraint.THROW_EXCEPTION);
|
||||
}
|
||||
return false;
|
||||
return ControlFlowAnalyzer.isPure(method) && !mayHaveExceptionalSideEffect(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -202,6 +198,21 @@ public class SideEffectChecker {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if given method function is likely to throw an exception (e.g. "assertEquals"). In some cases this means that
|
||||
* the method call should be preserved in source code even if it's pure (i.e. does not change the program state).
|
||||
*
|
||||
* @param method a method to check
|
||||
* @return true if the method has exceptional side effect
|
||||
*/
|
||||
public static boolean mayHaveExceptionalSideEffect(PsiMethod method) {
|
||||
if (method.getName().startsWith("assert")) {
|
||||
return true;
|
||||
}
|
||||
return ControlFlowAnalyzer.getMethodContracts(method).stream()
|
||||
.anyMatch(mc -> mc.returnValue == MethodContract.ValueConstraint.THROW_EXCEPTION);
|
||||
}
|
||||
|
||||
private static boolean isSideEffectFreeConstructor(@NotNull PsiNewExpression newExpression) {
|
||||
PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
|
||||
PsiClass aClass = classReference == null ? null : (PsiClass)classReference.resolve();
|
||||
|
||||
+12
@@ -19,6 +19,13 @@ import java.util.*;
|
||||
|
||||
public class MismatchedStringBuilderQueryUpdate {
|
||||
|
||||
public void testAssert() {
|
||||
StringBuilder finished = new StringBuilder();
|
||||
|
||||
finished.append("3 ");
|
||||
Assert.assertEquals("expected", finished.toString());
|
||||
}
|
||||
|
||||
void foo() {
|
||||
final StringBuilder b = new StringBuilder();
|
||||
b.append("");
|
||||
@@ -115,3 +122,8 @@ class EnumConstant {
|
||||
SomeEnum(StringBuilder sb) {}
|
||||
}
|
||||
}
|
||||
class Assert {
|
||||
static Object assertEquals(Object a, Object b) {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user