Context (@NotNull PsiConditionalLoopStatement loopStatement, boolean noConversionToDoWhile, boolean suggestConversionWhenIfIsASingleStmtInLoop) { boolean isEndlessLoop = ControlFlowUtils.isEndlessLoop(loopStatement); if (!isEndlessLoop) { if (loopStatement instanceof PsiForStatement forStatement) { if ((forStatement.getInitialization() != null && !(forStatement.getInitialization() instanceof PsiEmptyStatement)) || (forStatement.getUpdate() != null && !(forStatement.getUpdate() instanceof PsiEmptyStatement))) { return null; } } } PsiStatement body = loopStatement.getBody(); if (body == null) return null; PsiStatement[] statements = ControlFlowUtils.unwrapBlock(body); if (statements.length < 1) return null; if (statements.length == 1 && !suggestConversionWhenIfIsASingleStmtInLoop) return null; if (StreamEx.ofTree((PsiElement)body, el -> StreamEx.of(el.getChildren())) .select(PsiBreakStatement.class) .filter(stmt -> ControlFlowUtils.statementBreaksLoop(stmt, loopStatement)) .count() != 1) { return null; } PsiIfStatement first = tryCast(statements[0], PsiIfStatement.class); Ref<Boolean> isBreakInThen = new Ref<>(false); PsiExpression firstBreakCondition = extractBreakCondition(first, loopStatement, isBreakInThen); PsiExpression loopCondition = loopStatement.getCondition(); boolean isLoopConditionAtStart = !(loopStatement instanceof PsiDoWhileStatement); if (first != null && firstBreakCondition != null && (isEndlessLoop || (isLoopConditionAtStart && (BoolUtils.getLogicalOperandCount(loopCondition) + BoolUtils.getLogicalOperandCount(firstBreakCondition)) < 4))) { return new Context(loopStatement, body, firstBreakCondition, first, true, isBreakInThen.get(), isEndlessLoop); } if (noConversionToDoWhile) return null; PsiIfStatement last = tryCast(statements[statements.length - 1], PsiIfStatement.class); if (last != null && last.getElseBranch() != null) return null; PsiExpression lastBreakCondition = extractBreakCondition(last, loopStatement, isBreakInThen); if (lastBreakCondition == null || !isBreakInThen.get()) return null; if (!isEndlessLoop && (isLoopConditionAtStart || (3 < BoolUtils.getLogicalOperandCount(loopCondition) + BoolUtils.getLogicalOperandCount(lastBreakCondition)))) { return null; } if (StreamEx.of(statements) .flatMap(statement -> StreamEx.ofTree((PsiElement)statement, el -> StreamEx.of(el.getChildren()))) .anyMatch(e -> e instanceof PsiContinueStatement && ((PsiContinueStatement)e).findContinuedStatement() == loopStatement)) { return null; } boolean variablesInLoop = ContainerUtil.exists(VariableAccessUtils.collectUsedVariables(lastBreakCondition), variable -> PsiTreeUtil.isAncestor(loopStatement, variable, false)); if (variablesInLoop) return null; return new Context(loopStatement, body, lastBreakCondition, last, false, isBreakInThen.get(), isEndlessLoop); }