boolean[] (@NotNull PsiVariable variable, @NotNull ControlFlow flow) { class MyVisitor extends InstructionClientVisitor<boolean[]> { final PsiManager psiManager = variable.getManager(); // true if from this point below there may be branch with no variable assignment private final boolean[] maybeUnassigned = new boolean[flow.getSize() + 1]; { maybeUnassigned[maybeUnassigned.length - 1] = true; } @Override public void visitWriteVariableInstruction(WriteVariableInstruction instruction, int offset, int nextOffset) { if (psiManager.areElementsEquivalent(instruction.variable, variable)) { maybeUnassigned[offset] = false; } else { visitInstruction(instruction, offset, nextOffset); } } @Override public void visitConditionalThrowToInstruction(ConditionalThrowToInstruction instruction, int offset, int nextOffset) { if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); boolean unassigned = offset == flow.getSize() - 1 || !isLeaf(nextOffset) && maybeUnassigned[nextOffset]; maybeUnassigned[offset] |= unassigned; } @Override public void visitCallInstruction(CallInstruction instruction, int offset, int nextOffset) { visitInstruction(instruction, offset, nextOffset); // clear return statements after procedure as well for (int i = instruction.procBegin; i < instruction.procEnd + 3; i++) { maybeUnassigned[i] = false; } } @Override public void visitGoToInstruction(GoToInstruction instruction, int offset, int nextOffset) { if (instruction.isReturn && variable instanceof PsiLocalVariable) { if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); boolean unassigned = !isLeaf(nextOffset) && maybeUnassigned[nextOffset]; maybeUnassigned[offset] |= unassigned; } else { super.visitGoToInstruction(instruction, offset, nextOffset); } } @Override public void visitThrowToInstruction(ThrowToInstruction instruction, int offset, int nextOffset) { if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); boolean unassigned = !isLeaf(nextOffset) && maybeUnassigned[nextOffset]; maybeUnassigned[offset] |= unassigned; } @Override public void visitInstruction(Instruction instruction, int offset, int nextOffset) { if (nextOffset > flow.getSize()) nextOffset = flow.getSize(); boolean unassigned = isLeaf(nextOffset) || maybeUnassigned[nextOffset]; maybeUnassigned[offset] |= unassigned; } @Override public boolean @NotNull [] getResult() { return maybeUnassigned; } } if (flow.getSize() == 0) return new boolean[] {true}; MyVisitor visitor = new MyVisitor(); depthFirstSearch(flow, visitor); return visitor.getResult(); }