void (@NotNull final GrControlFlowOwner owner, @NotNull final ProblemsHolder problemsHolder) { final Instruction[] flow = owner.getControlFlow(); final ReachingDefinitionsDfaInstance dfaInstance = new ReachingDefinitionsDfaInstance(); final ReachingDefinitionsSemilattice lattice = new ReachingDefinitionsSemilattice(); final DFAEngine<DefinitionMap> engine = new DFAEngine<>(flow, dfaInstance, lattice); final List<DefinitionMap> dfaResult = engine.performDFAWithTimeout(); if (dfaResult == null) { return; } final IntSet unusedDefs = new IntOpenHashSet(); for (Instruction instruction : flow) { if (instruction instanceof ReadWriteVariableInstruction && ((ReadWriteVariableInstruction) instruction).isWrite()) { unusedDefs.add(instruction.num()); } } for (int i = 0; i < dfaResult.size(); i++) { final Instruction instruction = flow[i]; if (instruction instanceof ReadWriteVariableInstruction varInst) { if (!varInst.isWrite()) { final int descriptor = varInst.getDescriptor(); DefinitionMap e = dfaResult.get(i); if (e == null) { continue; } e.forEachValue(reaching -> { reaching.forEach((IntConsumer)defNum -> { final int defDescriptor = ((ReadWriteVariableInstruction)flow[defNum]).getDescriptor(); if (descriptor == defDescriptor) { unusedDefs.remove(defNum); } }); }); } } } final Set<PsiElement> checked = new HashSet<>(); unusedDefs.forEach((IntConsumer)num -> { final ReadWriteVariableInstruction instruction = (ReadWriteVariableInstruction)flow[num]; final PsiElement element = instruction.getElement(); process(element, checked, problemsHolder, GroovyBundle.message("unused.assignment.tooltip")); }); owner.acceptChildren(new PsiRecursiveElementWalkingVisitor() { @Override public void visitElement(@NotNull PsiElement element) { if (element instanceof GrControlFlowOwner) { // don't go deeper } else if (element instanceof GrVariable variable && !(element instanceof GrField)) { if (checked.contains(variable) || variable.getInitializerGroovy() != null) return; if (ReferencesSearch.search(variable, variable.getUseScope()).findFirst() == null) { process(variable, checked, problemsHolder, GroovyBundle.message("unused.variable")); } } else { super.visitElement(element); } } }); }