diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DebuggerDfaRunner.java b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DebuggerDfaRunner.java index a01a94c189bb..db9c95bac98e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DebuggerDfaRunner.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/dfaassist/DebuggerDfaRunner.java @@ -227,8 +227,8 @@ class DebuggerDfaRunner extends DataFlowRunner { void finish() { if (myChanged) { - DfaVariableValue[] distinctValues = - StreamEx.ofValues(myCanonicalMap).filter(v -> v.getType() != null && !DfaUtil.isComparedByEquals(v.getType())) + DfaVariableValue[] distinctValues = StreamEx.ofValues(myCanonicalMap) + .filter(v -> v.getType() != null && !TypeConstraints.exact(v.getType()).isComparedByEquals()) .toArray(new DfaVariableValue[0]); EntryStream.ofPairs(distinctValues) .filterKeyValue( diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java index 6fe460200eb9..f19f8f68020e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java @@ -302,10 +302,6 @@ public class DfaUtil { return tryCast(ContainerUtil.getOnlyItem(result.getExpressionValues(condition)), Boolean.class); } - public static boolean isComparedByEquals(PsiType type) { - return type != null && TypeConstraints.exact(type).isComparedByEquals(); - } - public static DfaValue boxUnbox(DfaValue value, @Nullable PsiType type) { if (TypeConversionUtil.isPrimitiveWrapper(type)) { if (TypeConversionUtil.isPrimitiveAndNotNull(value.getType())) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java index afab9a052cc4..6d52e817ade6 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/HardcodedContracts.java @@ -265,11 +265,14 @@ public class HardcodedContracts { private static List equalsContracts(PsiMethodCallExpression call) { PsiExpression qualifier = call == null ? null : call.getMethodExpression().getQualifierExpression(); - if (qualifier != null && (knownAsEqualByReference(qualifier.getType()) || DfaUtil.isComparedByEquals(qualifier.getType()))) { - return Arrays.asList( - singleConditionContract(ContractValue.qualifier(), RelationType.EQ, ContractValue.argument(0), returnTrue()), - trivialContract(returnFalse()) - ); + if (qualifier != null) { + PsiType type = qualifier.getType(); + if (type != null && (knownAsEqualByReference(type) || TypeConstraints.exact(type).isComparedByEquals())) { + return Arrays.asList( + singleConditionContract(ContractValue.qualifier(), RelationType.EQ, ContractValue.argument(0), returnTrue()), + trivialContract(returnFalse()) + ); + } } return Arrays.asList(new StandardMethodContract(new StandardMethodContract.ValueConstraint[]{NULL_VALUE}, returnFalse()), singleConditionContract(ContractValue.qualifier(), RelationType.EQ, diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java index ae9865fdf5fd..11e5b1bcfc56 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java @@ -454,15 +454,15 @@ public class StandardInstructionVisitor extends InstructionVisitor { PsiMethodReferenceExpression context = (PsiMethodReferenceExpression)instruction.getContext(); value = dereference(memState, value, NullabilityProblemKind.callMethodRefNPE.problem(context, null)); } - if (sig.mutatesThis() && Mutability.fromDfType(memState.getDfType(value)).isUnmodifiable()) { + DfType dfType = memState.getDfType(value); + if (sig.mutatesThis() && Mutability.fromDfType(dfType).isUnmodifiable()) { reportMutabilityViolation(true, instruction.getContext()); - DfType dfType = memState.getDfType(value); if (dfType instanceof DfReferenceType) { memState.setDfType(value, ((DfReferenceType)dfType).dropMutability().meet(Mutability.MUTABLE.asDfType())); } } if (!(value.getType() instanceof PsiArrayType) && - (DfaUtil.isComparedByEquals(value.getType()) || + (TypeConstraint.fromDfType(dfType).isComparedByEquals() || instruction.shouldFlushFields() || !(instruction.getResultType() instanceof PsiPrimitiveType))) { // For now drop locality on every qualified call except primitive returning pure calls // as value might escape through the return value