private boolean applyEquivalenceRelation( @NotNull DfaRelationValue dfaRelation, DfaValue dfaLeft, DfaValue dfaRight) { boolean isNegated = dfaRelation.isNonEquality(); if (!isNegated && !dfaRelation.isEquality()) { return true; } final boolean containsCalls = dfaLeft instanceof DfaVariableValue && ((DfaVariableValue) dfaLeft).containsCalls(); // track "x" property state only inside "if (getX() != null) ..." if (containsCalls && !isNotNull(dfaLeft) && isNull(dfaRight) && !isNegated) { return true; } if (dfaLeft == dfaRight) { return containsCalls || !isNegated; } if (isNull(dfaLeft) && isNotNull(dfaRight) || isNull(dfaRight) && isNotNull(dfaLeft)) { return isNegated; } if (!isNegated) { if (dfaLeft instanceof DfaVariableValue) { updateVarStateOnComparison((DfaVariableValue) dfaLeft, dfaRight); } if (dfaRight instanceof DfaVariableValue) { updateVarStateOnComparison((DfaVariableValue) dfaRight, dfaLeft); } } if (!applyRelation(dfaLeft, dfaRight, isNegated)) { return false; } if (!checkCompareWithBooleanLiteral(dfaLeft, dfaRight, isNegated)) { return false; } if (dfaLeft instanceof DfaVariableValue) { if (!applyUnboxedRelation((DfaVariableValue) dfaLeft, dfaRight, isNegated)) { return false; } if (!applyBoxedRelation((DfaVariableValue) dfaLeft, dfaRight, isNegated)) { return false; } } return true; }
@Override public boolean applyInstanceofOrNull(@NotNull DfaRelationValue dfaCond) { DfaValue left = unwrap(dfaCond.getLeftOperand()); if (!(left instanceof DfaVariableValue)) return true; DfaVariableValue dfaVar = (DfaVariableValue) left; DfaTypeValue dfaType = (DfaTypeValue) dfaCond.getRightOperand(); if (isUnknownState(dfaVar) || isNull(dfaVar)) return true; DfaVariableState newState = getVariableState(dfaVar).withInstanceofValue(dfaType); if (newState != null) { setVariableState(dfaVar, newState); return true; } return false; }
private boolean applyRelationCondition(@NotNull DfaRelationValue dfaRelation) { DfaValue dfaLeft = dfaRelation.getLeftOperand(); DfaValue dfaRight = dfaRelation.getRightOperand(); if (dfaLeft instanceof DfaUnknownValue || dfaRight instanceof DfaUnknownValue) return true; boolean isNegated = dfaRelation.isNegated(); if (dfaLeft instanceof DfaTypeValue && ((DfaTypeValue) dfaLeft).isNotNull() && dfaRight == myFactory.getConstFactory().getNull()) { return isNegated; } if (dfaRight instanceof DfaTypeValue) { if (dfaLeft instanceof DfaVariableValue) { DfaVariableValue dfaVar = (DfaVariableValue) dfaLeft; if (isUnknownState(dfaVar)) return true; if (!dfaRelation.isInstanceOf()) { if (((DfaTypeValue) dfaRight).isNotNull() && isNull(dfaVar)) { return isNegated; } return true; } if (isNegated) { DfaVariableState newState = getVariableState(dfaVar).withNotInstanceofValue((DfaTypeValue) dfaRight); if (newState != null) { setVariableState(dfaVar, newState); return true; } return !getVariableState(dfaVar).isNotNull() && applyRelation(dfaVar, myFactory.getConstFactory().getNull(), false); } if (applyRelation(dfaVar, myFactory.getConstFactory().getNull(), true)) { DfaVariableState newState = getVariableState(dfaVar).withInstanceofValue((DfaTypeValue) dfaRight); if (newState != null) { setVariableState(dfaVar, newState); return true; } } return false; } return true; } if (isEffectivelyNaN(dfaLeft) || isEffectivelyNaN(dfaRight)) { applyEquivalenceRelation(dfaRelation, dfaLeft, dfaRight); return isNegated; } if (canBeNaN(dfaLeft) && canBeNaN(dfaRight)) { if (dfaLeft == dfaRight && dfaLeft instanceof DfaVariableValue && !(((DfaVariableValue) dfaLeft).getVariableType() instanceof PsiPrimitiveType)) { return !isNegated; } applyEquivalenceRelation(dfaRelation, dfaLeft, dfaRight); return true; } return applyEquivalenceRelation(dfaRelation, dfaLeft, dfaRight); }