boolean (@NotNull ControlFlow flow, final int start, final PsiElement statement, @NotNull PsiVariable variable, @NotNull Set<Integer> excluded) { final int statementStart = flow.getStartOffset(statement); final int statementEnd = flow.getEndOffset(statement); List<ControlFlowUtil.ControlFlowEdge> edges = ControlFlowUtil.getEdges(flow, start); // DFS visits instructions mainly in backward direction while here visiting in forward direction // greatly reduces number of iterations. Collections.reverse(edges); BitSet referenced = new BitSet(); boolean changed = true; while(changed) { changed = false; for(ControlFlowUtil.ControlFlowEdge edge: edges) { int from = edge.myFrom; int to = edge.myTo; if(referenced.get(from)) { // jump to the loop start from within the loop is not considered as loop entry if (to == statementStart && (from < statementStart || from >= statementEnd)) { return true; } if (!referenced.get(to) && !excluded.contains(to)) { referenced.set(to); changed = true; } continue; } if (ControlFlowUtil.isVariableAccess(flow, from, variable) && !excluded.contains(from)) { referenced.set(from); referenced.set(to); if (to == statementStart) return true; changed = true; } } } return false; }