mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
Quick fix to add abc.ABC to superclasses (PY-30789)
This commit is contained in:
@@ -210,6 +210,7 @@ public class PyNames {
|
||||
public static final String ABSTRACTMETHOD = "abstractmethod";
|
||||
public static final String ABSTRACTPROPERTY = "abstractproperty";
|
||||
public static final String ABC_META_CLASS = "ABCMeta";
|
||||
public static final String ABC = "abc.ABC";
|
||||
|
||||
public static final String TUPLE = "tuple";
|
||||
public static final String SET = "set";
|
||||
|
||||
@@ -2,18 +2,21 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.override.PyOverrideImplementUtil;
|
||||
import com.jetbrains.python.codeInsight.typing.PyProtocolsKt;
|
||||
import com.jetbrains.python.inspections.quickfix.PyImplementMethodsQuickFix;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyKnownDecoratorUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType;
|
||||
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -49,9 +52,14 @@ public class PyAbstractClassInspection extends PyInspection {
|
||||
final List<PyFunction> toImplement = PyOverrideImplementUtil.getAllSuperAbstractMethods(pyClass, myTypeEvalContext);
|
||||
final ASTNode nameNode = pyClass.getNameNode();
|
||||
if (!toImplement.isEmpty() && nameNode != null) {
|
||||
final SmartList<LocalQuickFix> quickFixes = new SmartList<>(new PyImplementMethodsQuickFix(pyClass, toImplement));
|
||||
if (LanguageLevel.forElement(pyClass).isPy3K()) {
|
||||
quickFixes.add(new AddABCToSuperclassesQuickFix());
|
||||
}
|
||||
|
||||
registerProblem(nameNode.getPsi(),
|
||||
PyBundle.message("INSP.NAME.abstract.class.$0.must.implement", pyClass.getName()),
|
||||
new PyImplementMethodsQuickFix(pyClass, toImplement));
|
||||
quickFixes.toArray(LocalQuickFix.EMPTY_ARRAY));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +69,7 @@ public class PyAbstractClassInspection extends PyInspection {
|
||||
return true;
|
||||
}
|
||||
for (PyClassLikeType superClassType : pyClass.getSuperClassTypes(myTypeEvalContext)) {
|
||||
if (superClassType != null && "abc.ABC".equals(superClassType.getClassQName())) {
|
||||
if (superClassType != null && PyNames.ABC.equals(superClassType.getClassQName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -72,5 +80,26 @@ public class PyAbstractClassInspection extends PyInspection {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class AddABCToSuperclassesQuickFix implements LocalQuickFix {
|
||||
|
||||
@Nls(capitalization = Nls.Capitalization.Sentence)
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Add '" + PyNames.ABC + "' to superclasses";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PyClass cls = PyUtil.as(descriptor.getPsiElement().getParent(), PyClass.class);
|
||||
if (cls == null) return;
|
||||
|
||||
final PyClass abcClass = PyPsiFacade.getInstance(project).createClassByQName(PyNames.ABC, cls);
|
||||
if (abcClass == null) return;
|
||||
|
||||
PyClassRefactoringUtil.addSuperclasses(project, cls, abcClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
from PyAbstractClassInspection.quickFix.AddABCToSuperclasses.main_import import A1
|
||||
|
||||
class A<caret>2(A1):
|
||||
pass
|
||||
@@ -0,0 +1,6 @@
|
||||
from abc import ABC
|
||||
|
||||
from PyAbstractClassInspection.quickFix.AddABCToSuperclasses.main_import import A1
|
||||
|
||||
class A2(A1, ABC):
|
||||
pass
|
||||
@@ -0,0 +1,6 @@
|
||||
import abc
|
||||
|
||||
class A1(abc.ABC):
|
||||
@abc.abstractmethod
|
||||
def m1(self):
|
||||
pass
|
||||
@@ -0,0 +1,9 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
class A1(ABC):
|
||||
@abstractmethod
|
||||
def m1(self):
|
||||
pass
|
||||
|
||||
class A<caret>2(A1):
|
||||
pass
|
||||
@@ -0,0 +1,9 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
class A1(ABC):
|
||||
@abstractmethod
|
||||
def m1(self):
|
||||
pass
|
||||
|
||||
class A2(A1, ABC):
|
||||
pass
|
||||
@@ -20,6 +20,7 @@ import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.TestDataFile;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.inspections.PyAbstractClassInspection;
|
||||
import com.jetbrains.python.inspections.PyMissingConstructorInspection;
|
||||
import com.jetbrains.python.inspections.PyStatementEffectInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
@@ -94,19 +95,19 @@ public class Py3QuickFixTest extends PyTestCase {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON34,
|
||||
() -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true));
|
||||
}
|
||||
|
||||
|
||||
// PY-16421
|
||||
public void testAddCallSuperSingleStarParamPreserved() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON34,
|
||||
() -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true));
|
||||
}
|
||||
|
||||
|
||||
// PY-15867
|
||||
public void testAddCallSuperRequiredKeywordOnlyParamAfterSingleStarInSuperInitIsMerged() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON34,
|
||||
() -> doInspectionTest(PyMissingConstructorInspection.class, PyBundle.message("QFIX.add.super"), true, true));
|
||||
}
|
||||
|
||||
|
||||
// PY-16428
|
||||
public void testAddParameterNotAvailableInsideAnnotation() {
|
||||
runWithLanguageLevel(LanguageLevel.PYTHON34, () -> doInspectionTest(PyUnresolvedReferencesInspection.class,
|
||||
@@ -137,6 +138,29 @@ public class Py3QuickFixTest extends PyTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
// PY-30789
|
||||
public void testAddABCToSuperclasses() {
|
||||
final String[] testFiles = {
|
||||
"PyAbstractClassInspection/quickFix/AddABCToSuperclasses/main.py",
|
||||
"PyAbstractClassInspection/quickFix/AddABCToSuperclasses/main_import.py"
|
||||
};
|
||||
|
||||
doInspectionTest(testFiles,
|
||||
PyAbstractClassInspection.class,
|
||||
"Add '" + PyNames.ABC + "' to superclasses",
|
||||
true,
|
||||
true);
|
||||
}
|
||||
|
||||
// PY-30789
|
||||
public void testAddImportedABCToSuperclasses() {
|
||||
doInspectionTest("PyAbstractClassInspection/quickFix/AddImportedABCToSuperclasses/main.py",
|
||||
PyAbstractClassInspection.class,
|
||||
"Add '" + PyNames.ABC + "' to superclasses",
|
||||
true,
|
||||
true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
protected String getTestDataPath() {
|
||||
|
||||
Reference in New Issue
Block a user