void (@NotNull String name, @NotNull ScopeOwner owner, Instruction @NotNull [] instructions, int startInstruction, @Nullable PsiElement scopeAnchor) { // Check if the element is declared out of scope, mark all out of scope write accesses as used if (scopeAnchor != null) { final ScopeOwner declOwner = ScopeUtil.getDeclarationScopeOwner(scopeAnchor, name); if (declOwner != null && declOwner != owner) { final Collection<PsiElement> writeElements = ScopeUtil.getElementsOfAccessType(name, declOwner, ReadWriteInstruction.ACCESS.WRITE); for (PsiElement e : writeElements) { myUsedElements.add(e); myUnusedElements.remove(e); } } } ControlFlowUtil.iteratePrev(startInstruction, instructions, inst -> { final PsiElement instElement = inst.getElement(); // Mark function as used if (instElement instanceof PyFunction) { if (name.equals(((PyFunction)instElement).getName())){ myUsedElements.add(instElement); myUnusedElements.remove(instElement); return ControlFlowUtil.Operation.CONTINUE; } } // Mark write access as used else if (inst instanceof ReadWriteInstruction rwInstruction) { if (rwInstruction.getAccess().isWriteAccess() && name.equals(rwInstruction.getName())) { // Look up higher in CFG for actual definitions if (instElement != null && PyTypeDeclarationStatementNavigator.isTypeDeclarationTarget(instElement)) { return ControlFlowUtil.Operation.NEXT; } // For elements in scope if (instElement != null && PsiTreeUtil.isAncestor(owner, instElement, false)) { myUsedElements.add(instElement); myUnusedElements.remove(instElement); } return ControlFlowUtil.Operation.CONTINUE; } } return ControlFlowUtil.Operation.NEXT; }); }