boolean (@Nullable PsiExpression expression1, @Nullable PsiExpression expression2) { expression1 = PsiUtil.skipParenthesizedExprDown(expression1); expression2 = PsiUtil.skipParenthesizedExprDown(expression2); if (expression1 == null || expression2 == null) return false; EquivalenceChecker equivalence = EquivalenceChecker.getCanonicalPsiEquivalence(); if (isNegation(expression1)) { return equivalence.expressionsAreEquivalent(getNegated(expression1), expression2); } if (isNegation(expression2)) { return equivalence.expressionsAreEquivalent(getNegated(expression2), expression1); } if (expression1 instanceof PsiBinaryExpression binOp1 && expression2 instanceof PsiBinaryExpression binOp2) { RelationType rel1 = DfaPsiUtil.getRelationByToken(binOp1.getOperationTokenType()); RelationType rel2 = DfaPsiUtil.getRelationByToken(binOp2.getOperationTokenType()); if (rel1 == null || rel2 == null) return false; PsiType type = binOp1.getLOperand().getType(); // a > b and a <= b are not strictly opposite due to NaN semantics if (type == null || type.equals(PsiTypes.floatType()) || type.equals(PsiTypes.doubleType())) return false; if (rel1 == rel2.getNegated()) { return equivalence.expressionsAreEquivalent(binOp1.getLOperand(), binOp2.getLOperand()) && equivalence.expressionsAreEquivalent(binOp1.getROperand(), binOp2.getROperand()); } if (rel1.getFlipped() == rel2.getNegated()) { return equivalence.expressionsAreEquivalent(binOp1.getLOperand(), binOp2.getROperand()) && equivalence.expressionsAreEquivalent(binOp1.getROperand(), binOp2.getLOperand()); } } return false; }