List<PsiExpression> (TerminalGenerator generator, PsiPolyadicExpression expression) { EquivalenceChecker equivalence = EquivalenceChecker.getCanonicalPsiEquivalence(); PsiExpression[] operands = generator.getOperands(expression); if (operands.length < 3) return Collections.emptyList(); List<PsiExpression> elements = new ArrayList<>(); for (int i = 1; i < operands.length; i++) { if (!Objects.equals(operands[0].getType(), operands[i].getType())) return Collections.emptyList(); EquivalenceChecker.Match match = equivalence.expressionsMatch(operands[0], operands[i]); PsiExpression left = null; PsiExpression right = null; if (match.isPartialMatch()) { left = tryCast(match.getLeftDiff(), PsiExpression.class); right = tryCast(match.getRightDiff(), PsiExpression.class); } else if (match.isExactMismatch() && generator.isDittoSupported()) { left = operands[0]; right = operands[i]; } if (left == null || right == null) return Collections.emptyList(); if (elements.isEmpty()) { if (!StreamApiUtil.isSupportedStreamElement(left.getType()) || !ExpressionUtils.isSafelyRecomputableExpression(left)) { return Collections.emptyList(); } PsiBinaryExpression binOp = tryCast(PsiUtil.skipParenthesizedExprDown(operands[0]), PsiBinaryExpression.class); if (binOp != null) { if (ComparisonUtils.isComparison(binOp) && (left == PsiUtil.skipParenthesizedExprDown(binOp.getLOperand()) && ExpressionUtils.isSafelyRecomputableExpression(binOp.getROperand())) || (left == PsiUtil.skipParenthesizedExprDown(binOp.getROperand()) && ExpressionUtils.isSafelyRecomputableExpression(binOp.getLOperand()))) { // Disable for simple comparison chains like "a == null && b == null && c == null": // using Stream API here looks an overkill return Collections.emptyList(); } } elements.add(left); } else if (elements.get(0) != left) { return Collections.emptyList(); } if (!Objects.equals(left.getType(), right.getType()) || !ExpressionUtils.isSafelyRecomputableExpression(right)) { return Collections.emptyList(); } elements.add(right); } return elements; }