mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
DataFlowInstructionVisitor: unify method reference results and constant results processing
GitOrigin-RevId: 16b69d9f678f71ab6c9d03a93b96ffe72b5be618
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ccb7c7addc
commit
19283ee76f
+5
-8
@@ -12,7 +12,6 @@ import com.intellij.codeInspection.dataFlow.NullabilityProblemKind.NullabilityPr
|
||||
import com.intellij.codeInspection.dataFlow.fix.*;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.instructions.Instruction;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaConstValue;
|
||||
import com.intellij.codeInspection.nullable.NullableStuffInspectionBase;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -592,13 +591,11 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec
|
||||
}
|
||||
|
||||
private void reportMethodReferenceProblems(ProblemsHolder holder, DataFlowInstructionVisitor visitor) {
|
||||
visitor.getMethodReferenceResults().forEach((methodRef, dfaValue) -> {
|
||||
if (dfaValue instanceof DfaConstValue) {
|
||||
Object value = ((DfaConstValue)dfaValue).getValue();
|
||||
if(value instanceof Boolean) {
|
||||
holder.registerProblem(methodRef, InspectionsBundle.message("dataflow.message.constant.method.reference", value),
|
||||
createReplaceWithTrivialLambdaFix(value));
|
||||
}
|
||||
visitor.getMethodReferenceResults().forEach((methodRef, result) -> {
|
||||
if (result != ConstantResult.UNKNOWN) {
|
||||
Object value = result.value();
|
||||
holder.registerProblem(methodRef, InspectionsBundle.message("dataflow.message.constant.method.reference", value),
|
||||
createReplaceWithTrivialLambdaFix(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+17
-23
@@ -39,7 +39,7 @@ final class DataFlowInstructionVisitor extends StandardInstructionVisitor {
|
||||
private final Map<ExpressionChunk, ConstantResult> myConstantExpressions = new HashMap<>();
|
||||
private final Map<PsiElement, ThreeState> myOfNullableCalls = new HashMap<>();
|
||||
private final Map<PsiAssignmentExpression, Pair<PsiType, PsiType>> myArrayStoreProblems = new HashMap<>();
|
||||
private final Map<PsiMethodReferenceExpression, DfaValue> myMethodReferenceResults = new HashMap<>();
|
||||
private final Map<PsiMethodReferenceExpression, ConstantResult> myMethodReferenceResults = new HashMap<>();
|
||||
private final Map<PsiArrayAccessExpression, ThreeState> myOutOfBoundsArrayAccesses = new HashMap<>();
|
||||
private final Set<PsiElement> myReceiverMutabilityViolation = new HashSet<>();
|
||||
private final Set<PsiElement> myArgumentMutabilityViolation = new HashSet<>();
|
||||
@@ -166,7 +166,7 @@ final class DataFlowInstructionVisitor extends StandardInstructionVisitor {
|
||||
return myConstantExpressions;
|
||||
}
|
||||
|
||||
Map<PsiMethodReferenceExpression, DfaValue> getMethodReferenceResults() {
|
||||
Map<PsiMethodReferenceExpression, ConstantResult> getMethodReferenceResults() {
|
||||
return myMethodReferenceResults;
|
||||
}
|
||||
|
||||
@@ -203,13 +203,9 @@ final class DataFlowInstructionVisitor extends StandardInstructionVisitor {
|
||||
public boolean isInstanceofRedundant(InstanceofInstruction instruction) {
|
||||
PsiExpression expression = instruction.getExpression();
|
||||
if (expression == null || myUsefulInstanceofs.contains(instruction) || !myReachable.contains(instruction)) return false;
|
||||
if (expression instanceof PsiMethodReferenceExpression) {
|
||||
DfaValue value = myMethodReferenceResults.get(expression);
|
||||
return !(value instanceof DfaConstValue) || !(((DfaConstValue)value).getValue() instanceof Boolean);
|
||||
} else {
|
||||
ConstantResult result = myConstantExpressions.get(new ExpressionChunk(expression, null));
|
||||
return result != ConstantResult.TRUE && result != ConstantResult.FALSE;
|
||||
}
|
||||
ConstantResult result = expression instanceof PsiMethodReferenceExpression ?
|
||||
myMethodReferenceResults.get(expression) : myConstantExpressions.get(new ExpressionChunk(expression, null));
|
||||
return result != ConstantResult.TRUE && result != ConstantResult.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -252,11 +248,10 @@ final class DataFlowInstructionVisitor extends StandardInstructionVisitor {
|
||||
processOfNullableResult(value, state, methodRef.getReferenceNameElement());
|
||||
}
|
||||
PsiMethod method = tryCast(methodRef.resolve(), PsiMethod.class);
|
||||
if (method != null) {
|
||||
if (method != null && JavaMethodContractUtil.isPure(method)) {
|
||||
List<StandardMethodContract> contracts = JavaMethodContractUtil.getMethodContracts(method);
|
||||
if (contracts.isEmpty() || !contracts.get(0).isTrivial()) {
|
||||
// Do not track if method reference may have different results
|
||||
myMethodReferenceResults.merge(methodRef, value, (a, b) -> a == b ? a : DfaUnknownValue.getInstance());
|
||||
myMethodReferenceResults.compute(methodRef, (mr, curState) -> ConstantResult.mergeValue(curState, state, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -304,17 +299,7 @@ final class DataFlowInstructionVisitor extends StandardInstructionVisitor {
|
||||
private void reportConstantExpressionValue(DfaValue value, DfaMemoryState memState, PsiExpression expression, TextRange range) {
|
||||
if (expression instanceof PsiLiteralExpression) return;
|
||||
ExpressionChunk chunk = new ExpressionChunk(expression, range);
|
||||
ConstantResult curState = myConstantExpressions.get(chunk);
|
||||
if (curState == ConstantResult.UNKNOWN) return;
|
||||
ConstantResult nextState = ConstantResult.UNKNOWN;
|
||||
DfaConstValue dfaConst = memState.getConstantValue(value);
|
||||
if (dfaConst != null) {
|
||||
nextState = ConstantResult.fromConstValue(dfaConst);
|
||||
if (curState != null && curState != nextState) {
|
||||
nextState = ConstantResult.UNKNOWN;
|
||||
}
|
||||
}
|
||||
myConstantExpressions.put(chunk, nextState);
|
||||
myConstantExpressions.compute(chunk, (c, curState) -> ConstantResult.mergeValue(curState, memState, value));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -431,6 +416,15 @@ final class DataFlowInstructionVisitor extends StandardInstructionVisitor {
|
||||
if (Boolean.FALSE.equals(value)) return FALSE;
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static ConstantResult mergeValue(@Nullable ConstantResult state, @NotNull DfaMemoryState memState, @Nullable DfaValue value) {
|
||||
if (state == UNKNOWN) return UNKNOWN;
|
||||
DfaConstValue dfaConst = memState.getConstantValue(value);
|
||||
if (dfaConst == null) return UNKNOWN;
|
||||
ConstantResult nextState = fromConstValue(dfaConst);
|
||||
return state == null || state == nextState ? nextState : UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static class ExpressionChunk {
|
||||
|
||||
Reference in New Issue
Block a user