diff --git a/platform/lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java b/platform/lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java index f6f2a31fa070..5052f976e7ff 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java +++ b/platform/lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java @@ -19,6 +19,7 @@ package com.intellij.refactoring.classMembers; import com.intellij.psi.NavigatablePsiElement; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Dennis.Ushakov @@ -26,7 +27,7 @@ import org.jetbrains.annotations.NotNull; public abstract class AbstractUsesDependencyMemberInfoModel> extends DependencyMemberInfoModel { protected final C myClass; - public AbstractUsesDependencyMemberInfoModel(C aClass, C superClass, boolean recursive) { + public AbstractUsesDependencyMemberInfoModel(C aClass, @Nullable C superClass, boolean recursive) { super(new UsesMemberDependencyGraph(aClass, superClass, recursive), ERROR); myClass = aClass; setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index f572872ec2c7..329116b1d9b0 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -107,7 +107,10 @@ public class PyUtil { return node != null && node.getElementType().equals(TokenType.WHITE_SPACE); } - //TODO: Doctg + /** + * @param function function to check + * @return true if function is init + */ public static boolean isInit(@NotNull final PyFunction function) { return PyNames.INIT.equals(function.getName()); } diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java index 875a07f58ab6..d970fbf7efad 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java @@ -15,8 +15,8 @@ */ package com.jetbrains.python.refactoring.classes; -import com.google.common.base.Function; import com.google.common.collect.Collections2; +import com.intellij.lang.ASTNode; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -40,7 +40,10 @@ import com.jetbrains.python.psi.resolve.QualifiedNameFinder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; import static com.jetbrains.python.psi.PyFunction.Modifier.CLASSMETHOD; import static com.jetbrains.python.psi.PyFunction.Modifier.STATICMETHOD; @@ -48,30 +51,29 @@ import static com.jetbrains.python.psi.PyFunction.Modifier.STATICMETHOD; /** * @author Dennis.Ushakov */ -public class PyClassRefactoringUtil { +public final class PyClassRefactoringUtil { private static final Logger LOG = Logger.getInstance(PyClassRefactoringUtil.class.getName()); private static final Key ENCODED_IMPORT = Key.create("PyEncodedImport"); private static final Key ENCODED_USE_FROM_IMPORT = Key.create("PyEncodedUseFromImport"); private static final Key ENCODED_IMPORT_AS = Key.create("PyEncodedImportAs"); - private static final InitFirst INIT_FIRST = new InitFirst(); private PyClassRefactoringUtil() { } /** - * TODO: Doc * Copies class field declarations to some other place * * @param assignmentStatement list of class fields + * @return new (copied) fields */ @NotNull public static List copyFieldDeclarationToStatement(@NotNull final Collection assignmentStatement, @NotNull final PyStatementList superClassStatement) { - List declations = new ArrayList(assignmentStatement.size()); + final List declations = new ArrayList(assignmentStatement.size()); for (final PyAssignmentStatement expression : assignmentStatement) { - PyAssignmentStatement newDeclaration = (PyAssignmentStatement)expression.copy(); + final PyAssignmentStatement newDeclaration = (PyAssignmentStatement)expression.copy(); declations.add(newDeclaration); declations.add((PyAssignmentStatement)PyUtil.addElementToStatementList(newDeclaration, superClassStatement, true)); PyPsiUtils.removeRedundantPass(superClassStatement); @@ -88,23 +90,27 @@ public class PyClassRefactoringUtil { return addMethods(superClass, elements); } - //TODO: Doct + /** + * Adds methods to class. + * + * @param destination where to add methods + * @param methods methods + * @return newly added methods + */ @NotNull - public static List addMethods(@NotNull PyClass destination, @NotNull PyFunction... methods) { - List methodsToAdd = new ArrayList(Arrays.asList(methods)); - Collections.sort(methodsToAdd, INIT_FIRST); + public static List addMethods(@NotNull final PyClass destination, @NotNull final PyFunction... methods) { - PyStatementList destStatementList = destination.getStatementList(); - List newlyCreatedMethods = new ArrayList(methods.length); + final PyStatementList destStatementList = destination.getStatementList(); + final List newlyCreatedMethods = new ArrayList(methods.length); - for (PyFunction method : methodsToAdd) { + for (final PyFunction method : methods) { if (destination.findMethodByName(method.getName(), false) != null) { - continue; //TODO: Doc why + continue; //We skip adding if class already has this method. I am not sure if this behaviour is correct, but it was here, so I left if for backward compatibility } - PyFunction newMethod = insertMethodInProperPlace(destStatementList, method); + final PyFunction newMethod = insertMethodInProperPlace(destStatementList, method); newlyCreatedMethods.add(newMethod); restoreNamedReferences(newMethod); } @@ -113,11 +119,18 @@ public class PyClassRefactoringUtil { return newlyCreatedMethods; } - //TODO: Doc algo + /** + * Adds init methods before all other methods (but after class vars and docs). + * Adds all other methods to the bottom + * + * @param destStatementList where to add methods + * @param method method to add + * @return newlty added method + */ @NotNull private static PyFunction insertMethodInProperPlace( - @NotNull PyStatementList destStatementList, - @NotNull PyFunction method) { + @NotNull final PyStatementList destStatementList, + @NotNull final PyFunction method) { boolean methodIsInit = PyUtil.isInit(method); if (!methodIsInit) { //Not init method could be inserted in the bottom @@ -125,11 +138,11 @@ public class PyClassRefactoringUtil { } //We should find appropriate place for init - for (PsiElement element : destStatementList.getChildren()) { - boolean elementComment = element instanceof PyExpressionStatement; - boolean elementClassField = element instanceof PyAssignmentStatement; + for (final PsiElement element : destStatementList.getChildren()) { + final boolean elementComment = element instanceof PyExpressionStatement; + final boolean elementClassField = element instanceof PyAssignmentStatement; - if ((!(elementComment || elementClassField))) { + if (!(elementComment || elementClassField)) { return (PyFunction)destStatementList.addBefore(method, element); } } @@ -419,51 +432,47 @@ public class PyClassRefactoringUtil { return addMethods(pyClass, function).get(0); } - //TODO: Doc - @NotNull + /** + * Adds super classes to certain class. + * + * @param project project where refactoring takes place + * @param clazz destination + * @param superClasses classes to add + */ public static void addSuperclasses(@NotNull final Project project, @NotNull final PyClass clazz, @NotNull final PyClass... superClasses) { - final List superClassNames = new ArrayList(); + final Collection superClassNames = new ArrayList(); for (final PyClass superClass : Collections2.filter(Arrays.asList(superClasses), NotNullPredicate.INSTANCE)) { if (superClass.getName() != null) { superClassNames.add(superClass.getName()); - PyClassRefactoringUtil.insertImport(clazz, superClass); + insertImport(clazz, superClass); } } - PyArgumentList superClassExpressionList = clazz.getSuperClassExpressionList(); - PyElementGenerator generator = PyElementGenerator.getInstance(project); + final PyArgumentList superClassExpressionList = clazz.getSuperClassExpressionList(); + final PyElementGenerator generator = PyElementGenerator.getInstance(project); if (superClassExpressionList != null) { - for (String superClassName : superClassNames) { + for (final String superClassName : superClassNames) { superClassExpressionList.addArgument(generator.createExpressionFromText(superClassName)); } } - //TODO: Doc why we do it manually + //If class has no expression list, then we need to add it manually. + //TODO: Investigate how to do that on PSI level, with out of stupid string concatenation else { - String superClassText = String.format("(%s)", StringUtil.join(superClassNames, ",")); - clazz.addAfter(generator.createExpressionFromText(superClassText), - clazz.getNameNode().getPsi()); - } - } - - private static class NameExtractor implements Function { - @SuppressWarnings("NullableProblems") //We sure collection has no null - @Nullable - @Override - public String apply(@NotNull final PyElement input) { - return input.getName(); - } - } - - private static class InitFirst implements Comparator { - @Override - public int compare(PyFunction o1, PyFunction o2) { - return (PyUtil.isInit(o1) ? 1 : 0) - (PyUtil.isInit(o2) ? 1 : 0); + final String superClassText = String.format("(%s)", StringUtil.join(superClassNames, ",")); + final ASTNode node = clazz.getNameNode(); + if (node != null) { + clazz.addAfter(generator.createExpressionFromText(superClassText), + node.getPsi()); + } + else { + LOG.error("Class has no name node nor superclass list " + clazz); + } } } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java index 915d53ab5410..3274b65364c7 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java @@ -16,7 +16,6 @@ package com.jetbrains.python.refactoring.classes.extractSuperclass; import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Document; @@ -24,16 +23,15 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.vfs.LocalFileSystem; -import com.intellij.openapi.vfs.VfsUtil; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; +import com.intellij.openapi.vfs.*; import com.intellij.psi.*; import com.intellij.util.PathUtil; -import com.jetbrains.NotNullPredicate; import com.jetbrains.python.PyNames; import com.jetbrains.python.PythonFileType; -import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.LanguageLevel; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyElementGenerator; +import com.jetbrains.python.psi.PyUtil; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; @@ -80,12 +78,11 @@ public final class PyExtractSuperclassHelper { MembersManager.moveAllMembers(selectedMemberInfos, clazz, newClass); PyClassRefactoringUtil.addSuperclasses(project, clazz, null, newClass); - } private static PyClass placeNewClass(Project project, PyClass newClass, @NotNull PyClass clazz, String targetFile) { VirtualFile file = VirtualFileManager.getInstance() - .findFileByUrl(ApplicationManagerEx.getApplicationEx().isUnitTestMode() ? targetFile : VfsUtil.pathToUrl(targetFile)); + .findFileByUrl(ApplicationManagerEx.getApplicationEx().isUnitTestMode() ? targetFile : VfsUtilCore.pathToUrl(targetFile)); // file is the same as the source if (Comparing.equal(file, clazz.getContainingFile().getVirtualFile())) { return (PyClass)clazz.getParent().addBefore(newClass, clazz); diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java index fefa4cfc9e3a..d13d48690ee6 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java @@ -22,11 +22,11 @@ class ClassFieldsManager extends FieldsManager { @Override - protected void moveAssignments(@NotNull PyClass from, - @NotNull Collection statements, - @NotNull PyClass... to) { + protected void moveAssignments(@NotNull final PyClass from, + @NotNull final Collection statements, + @NotNull final PyClass... to) { //TODO: Copy/paste with InstanceFieldsManager. Move to parent? - for (PyClass destClass : to) { + for (final PyClass destClass : to) { PyClassRefactoringUtil.copyFieldDeclarationToStatement(statements, destClass.getStatementList()); } deleteElements(statements); diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java index ca8729cb7a1c..9d8cb1e0c74a 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/FieldsManager.java @@ -39,17 +39,16 @@ abstract class FieldsManager extends MembersManager { return Lists.newArrayList(Collections2.filter(getFieldsByClass(pyClass), SIMPLE_ASSIGNMENTS_ONLY)); } - @NotNull @Override - protected void moveMembers(@NotNull PyClass from, - @NotNull Collection members, - @NotNull PyClass... to) { + protected void moveMembers(@NotNull final PyClass from, + @NotNull final Collection members, + @NotNull final PyClass... to) { moveAssignments(from, Collections2.transform(members, new AssignmentTransform()), to); } - protected abstract void moveAssignments(@NotNull PyClass from, - @NotNull Collection statements, - @NotNull PyClass... to); + protected abstract void moveAssignments(@NotNull PyClass from, + @NotNull Collection statements, + @NotNull PyClass... to); /** * Checks if class has fields. Only child may know how to obtain field diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java index 53dfcc7cd236..027462e90030 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/InstanceFieldsManager.java @@ -5,9 +5,7 @@ import com.jetbrains.python.psi.*; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.List; /** @@ -20,12 +18,12 @@ class InstanceFieldsManager extends FieldsManager { @Override - protected void moveAssignments(@NotNull PyClass from, - @NotNull Collection statements, - @NotNull PyClass... to) { + protected void moveAssignments(@NotNull final PyClass from, + @NotNull final Collection statements, + @NotNull final PyClass... to) { //TODO: Copy/paste with ClassFieldsManager. Move to parent? - for (PyClass destClass : to) { + for (final PyClass destClass : to) { copyInstanceFields(statements, destClass); } @@ -38,7 +36,13 @@ class InstanceFieldsManager extends FieldsManager { } } - //TODO: Doc + /** + * Copies class' fields in form of assignments (instance fields) to another class. + * Creates init method if there is no any + * @param members assignments to copy + * @param to destination + * @return newly created fields + */ @NotNull private static List copyInstanceFields(@NotNull final Collection members, @NotNull final PyClass to) { diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java index 2fd737fb7b21..2e56c6e5b469 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java @@ -11,13 +11,15 @@ import com.intellij.psi.PsiNamedElement; import com.jetbrains.NotNullPredicate; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.psi.PyUtil; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; /** * TODO: Extract "from, to[], members, deleteFromOrigin" to separate class? @@ -68,7 +70,6 @@ public abstract class MembersManager implements Function implements Function members, @NotNull final Predicate predicate) { @@ -130,7 +135,11 @@ public abstract class MembersManager implements Function predicate) { @@ -178,12 +187,8 @@ public abstract class MembersManager implements Function - * TODO: Doc - * TODO: Doc who and what should return (write about elemnents) */ - @NotNull - protected abstract void moveMembers( + protected abstract void moveMembers( @NotNull PyClass from, @NotNull Collection members, @NotNull PyClass... to); diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java index d9643e976911..7e6ee1c59015 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java @@ -29,14 +29,14 @@ class MethodsManager extends MembersManager { } @Override - protected void moveMembers(@NotNull PyClass from, - @NotNull Collection members, - @NotNull PyClass... to) { - for (PyClass destClass : to) { - //We move copies here becase we there may be several destinations - List copies = new ArrayList(members.size()); - for (PyFunction member : members) { - PyFunction newMethod = (PyFunction)member.copy(); + protected void moveMembers(@NotNull final PyClass from, + @NotNull final Collection members, + @NotNull final PyClass... to) { + for (final PyClass destClass : to) { + //We move copies here because we there may be several destinations + final List copies = new ArrayList(members.size()); + for (final PyFunction member : members) { + final PyFunction newMethod = (PyFunction)member.copy(); copies.add(newMethod); } diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java index e923ea8b611b..3aa195514db1 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMembersRefactoringBaseProcessor.java @@ -12,7 +12,8 @@ import java.util.Collection; import java.util.List; /** - * TODO: Doc (and why it extends 2 classes) + * Processor for member-based refactorings. It moves members from one place to another using {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager}. + * Inheritors only need to implement {@link com.intellij.usageView.UsageViewDescriptor} methods (while this interface is also implemented by this class) * * @author Ilya.Kazakevich */ @@ -25,7 +26,11 @@ public abstract class PyMembersRefactoringBaseProcessor extends BaseRefactoringP @NotNull private final PyClass[] myTo; - //TODO: Doc + /** + * @param membersToMove what to move + * @param from source + * @param to where to move + */ protected PyMembersRefactoringBaseProcessor( @NotNull final Collection membersToMove, @NotNull final PyClass from, @@ -48,7 +53,9 @@ public abstract class PyMembersRefactoringBaseProcessor extends BaseRefactoringP return myTo.clone(); } - //TODO: Doc + /** + * @return destinations (so user would be able to choose if she wants to move member to certain place or not) + */ @NotNull @Override protected final PyUsageInfo[] findUsages() { @@ -59,7 +66,6 @@ public abstract class PyMembersRefactoringBaseProcessor extends BaseRefactoringP return result.toArray(new PyUsageInfo[result.size()]); } - //TODO: Doc @Override protected final void performRefactoring(final UsageInfo[] usages) { final Collection destinations = new ArrayList(usages.length); @@ -67,7 +73,7 @@ public abstract class PyMembersRefactoringBaseProcessor extends BaseRefactoringP if (!(usage instanceof PyUsageInfo)) { throw new IllegalArgumentException("Only PyUsageInfo is accepted here"); } - //TODO: Doc + //We collect destination info to pass it to members manager destinations.add(((PyUsageInfo)usage).getTo()); } MembersManager.moveAllMembers(myMembersToMove, myFrom, destinations.toArray(new PyClass[destinations.size()])); diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyUsageInfo.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyUsageInfo.java index 81d811316818..c8e1f1ff4fcb 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyUsageInfo.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyUsageInfo.java @@ -6,7 +6,7 @@ import org.jetbrains.annotations.NotNull; /** * TODO: Make it generic to allow to reuse in another projects? - * TODO: Document + * Usage info that displays destination (where should member be moved) * * @author Ilya.Kazakevich */ @@ -14,9 +14,9 @@ class PyUsageInfo extends UsageInfo { @NotNull private final PyClass myTo; - PyUsageInfo(@NotNull PyClass to) { + PyUsageInfo(@NotNull final PyClass to) { super(to, true); //TODO: Make super generic and get rid of field? - this.myTo = to; + myTo = to; } @NotNull diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java index 0b238a552239..c070f4448d5e 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java @@ -31,13 +31,13 @@ class SuperClassesManager extends MembersManager { } @Override - protected void moveMembers(@NotNull PyClass from, @NotNull Collection members, @NotNull PyClass... to) { - for (PyClass destClass : to) { + protected void moveMembers(@NotNull final PyClass from, @NotNull final Collection members, @NotNull final PyClass... to) { + for (final PyClass destClass : to) { PyClassRefactoringUtil.addSuperclasses(from.getProject(), destClass, members.toArray(new PyClass[members.size()])); } - for (PyExpression expression : from.getSuperClassExpressions()) { - for (PyClass member : members) { + for (final PyExpression expression : from.getSuperClassExpressions()) { + for (final PyClass member : members) { if (expression.getText().equals(member.getName())) { expression.delete(); } diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java index a660056a9092..d87195551ed1 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpProcessor.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Collection; /** - * TODO: Doc + * * * @author Ilya.Kazakevich */