List<String> () { final Set<String> attributeNames = new LinkedHashSet<>(); for (ScopeOwner owner : PsiTreeUtil.collectElementsOfType(myFunction, ScopeOwner.class)) { final AnalysisResult result = analyseScope(owner); if (!result.nonlocalWritesToEnclosingScope.isEmpty()) { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.nonlocal.writes")); } if (!result.readsOfSelfParametersFromEnclosingScope.isEmpty()) { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.self.reads")); } if (!result.readsFromEnclosingScope.isEmpty()) { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.outer.scope.reads")); } if (!result.writesToSelfParameter.isEmpty()) { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.special.usage.of.self")); } myReadsOfSelfParam.addAll(result.readsOfSelfParameter); for (PsiElement usage : result.readsOfSelfParameter) { if (usage.getParent() instanceof PyTargetExpression) { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.attribute.writes")); } final PyReferenceExpression parentReference = as(usage.getParent(), PyReferenceExpression.class); if (parentReference != null) { final String attrName = parentReference.getName(); if (attrName != null && PyUtil.isClassPrivateName(attrName)) { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.private.attributes")); } if (parentReference.getParent() instanceof PyCallExpression) { if (!(Objects.equals(myFunction.getName(), parentReference.getName()))) { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.method.calls")); } else { // do not add method itself to its parameters continue; } } attributeNames.add(attrName); myAttributeReferences.putValue(attrName, parentReference); } else { throw new IncorrectOperationException(PyBundle.message("refactoring.make.function.top.level.error.special.usage.of.self")); } } } for (String name : attributeNames) { final Collection<PyReferenceExpression> reads = myAttributeReferences.get(name); final PsiElement anchor = ContainerUtil.getFirstItem(reads); //noinspection ConstantConditions if (!PyRefactoringUtil.isValidNewName(name, anchor)) { final String indexedName = PyRefactoringUtil.appendNumberUntilValid(name, anchor, PyRefactoringUtil::isValidNewName); myAttributeToParameterName.put(name, indexedName); } else { myAttributeToParameterName.put(name, name); } } return Lists.newArrayList(myAttributeToParameterName.values()); }