mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-15 20:26:04 +07:00
fixed PY-9654 Make function from method/Make method static: correctly update class calls with first instance argument
This commit is contained in:
@@ -4,9 +4,12 @@ import com.intellij.codeInspection.LocalQuickFix;
|
|||||||
import com.intellij.codeInspection.ProblemDescriptor;
|
import com.intellij.codeInspection.ProblemDescriptor;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.PsiReference;
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.usageView.UsageInfo;
|
||||||
import com.jetbrains.python.PyBundle;
|
import com.jetbrains.python.PyBundle;
|
||||||
import com.jetbrains.python.psi.*;
|
import com.jetbrains.python.psi.*;
|
||||||
|
import com.jetbrains.python.refactoring.PyRefactoringUtil;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -35,8 +38,9 @@ public class PyMakeMethodStaticQuickFix implements LocalQuickFix {
|
|||||||
final PsiElement element = descriptor.getPsiElement();
|
final PsiElement element = descriptor.getPsiElement();
|
||||||
final PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class);
|
final PyFunction problemFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class);
|
||||||
if (problemFunction == null) return;
|
if (problemFunction == null) return;
|
||||||
PyUtil.deleteParameter(problemFunction, 0);
|
final List<UsageInfo> usages = PyRefactoringUtil.findUsages(problemFunction, false);
|
||||||
|
|
||||||
|
PyUtil.deleteParameter(problemFunction, 0);
|
||||||
final PyDecoratorList problemDecoratorList = problemFunction.getDecoratorList();
|
final PyDecoratorList problemDecoratorList = problemFunction.getDecoratorList();
|
||||||
List<String> decoTexts = new ArrayList<String>();
|
List<String> decoTexts = new ArrayList<String>();
|
||||||
decoTexts.add("@staticmethod");
|
decoTexts.add("@staticmethod");
|
||||||
@@ -56,5 +60,36 @@ public class PyMakeMethodStaticQuickFix implements LocalQuickFix {
|
|||||||
else {
|
else {
|
||||||
problemFunction.addBefore(decoratorList, problemFunction.getFirstChild());
|
problemFunction.addBefore(decoratorList, problemFunction.getFirstChild());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (UsageInfo usage : usages) {
|
||||||
|
final PsiElement usageElement = usage.getElement();
|
||||||
|
if (usageElement instanceof PyReferenceExpression) {
|
||||||
|
updateUsage((PyReferenceExpression)usageElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateUsage(@NotNull final PyReferenceExpression element) {
|
||||||
|
final PyExpression qualifier = element.getQualifier();
|
||||||
|
if (qualifier == null) return;
|
||||||
|
final PsiReference reference = qualifier.getReference();
|
||||||
|
if (reference == null) return;
|
||||||
|
final PsiElement resolved = reference.resolve();
|
||||||
|
if (resolved instanceof PyClass) { //call with first instance argument A.m(A())
|
||||||
|
updateArgumentList(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateArgumentList(@NotNull final PyReferenceExpression element) {
|
||||||
|
final PyCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PyCallExpression.class);
|
||||||
|
if (callExpression == null) return;
|
||||||
|
PyArgumentList argumentList = callExpression.getArgumentList();
|
||||||
|
if (argumentList == null) return;
|
||||||
|
final PyExpression[] arguments = argumentList.getArguments();
|
||||||
|
if (arguments.length > 0) {
|
||||||
|
final PyExpression argument = arguments[0];
|
||||||
|
PyUtil.eraseWhitespaceAndComma(argument.getParent().getNode(), argument, false);
|
||||||
|
argument.delete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
__author__ = 'ktisha'
|
||||||
|
|
||||||
|
class A:
|
||||||
|
def fo<caret>o(self):
|
||||||
|
print("Hello Pycharm!")
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class A:
|
||||||
|
def m<caret>(self, x):
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
print A.m(A(), 1)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import test
|
||||||
|
|
||||||
|
test.A().foo(1)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import test
|
||||||
|
|
||||||
|
test.A().foo(1)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A:
|
||||||
|
@staticmethod
|
||||||
|
def m(x):
|
||||||
|
return x
|
||||||
|
|
||||||
|
|
||||||
|
print A.m(1)
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.jetbrains.python.quickFixes;
|
package com.jetbrains.python.quickFixes;
|
||||||
|
|
||||||
import com.intellij.codeInsight.intention.IntentionAction;
|
|
||||||
import com.jetbrains.python.PyBundle;
|
import com.jetbrains.python.PyBundle;
|
||||||
import com.jetbrains.python.inspections.PyMethodMayBeStaticInspection;
|
import com.jetbrains.python.inspections.PyMethodMayBeStaticInspection;
|
||||||
|
|
||||||
@@ -46,21 +45,10 @@ public class PyMakeFunctionFromMethodQuickFixTest extends PyQuickFixTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testUsageImport() {
|
public void testUsageImport() {
|
||||||
doTest();
|
doMultifilesTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.function"), new String[]{"test.py"});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testUsageImport1() {
|
public void testUsageImport1() {
|
||||||
doTest();
|
doMultifilesTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.function"), new String[]{"test.py"});
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected void doTest() {
|
|
||||||
final String testFileName = getTestName(true);
|
|
||||||
myFixture.enableInspections(PyMethodMayBeStaticInspection.class);
|
|
||||||
myFixture.configureByFiles("test.py", testFileName + ".py");
|
|
||||||
final IntentionAction intentionAction = myFixture.findSingleIntention(PyBundle.message("QFIX.NAME.make.function"));
|
|
||||||
assertNotNull(intentionAction);
|
|
||||||
myFixture.launchAction(intentionAction);
|
|
||||||
myFixture.checkResultByFile(testFileName + ".py", testFileName + "_after.py", true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,4 +32,12 @@ public class PyMakeMethodStaticQuickFixTest extends PyQuickFixTestCase {
|
|||||||
doInspectionTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"));
|
doInspectionTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testUsage() {
|
||||||
|
doInspectionTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testUsageImport() {
|
||||||
|
doMultifilesTest(PyMethodMayBeStaticInspection.class, PyBundle.message("QFIX.NAME.make.static"), new String[]{"test.py"});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import com.intellij.codeInsight.intention.IntentionAction;
|
|||||||
import com.jetbrains.python.PythonTestUtil;
|
import com.jetbrains.python.PythonTestUtil;
|
||||||
import com.jetbrains.python.fixtures.PyTestCase;
|
import com.jetbrains.python.fixtures.PyTestCase;
|
||||||
import org.jetbrains.annotations.NonNls;
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: ktisha
|
* User: ktisha
|
||||||
@@ -25,4 +28,17 @@ public abstract class PyQuickFixTestCase extends PyTestCase {
|
|||||||
myFixture.launchAction(intentionAction);
|
myFixture.launchAction(intentionAction);
|
||||||
myFixture.checkResultByFile(testFileName + "_after.py", true);
|
myFixture.checkResultByFile(testFileName + "_after.py", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void doMultifilesTest(@NotNull final Class inspectionClass, @NotNull final String hint, @NotNull final String[] files) {
|
||||||
|
final String testFileName = getTestName(true);
|
||||||
|
myFixture.enableInspections(inspectionClass);
|
||||||
|
String [] filenames = Arrays.copyOf(files, files.length + 1);
|
||||||
|
|
||||||
|
filenames[files.length] = testFileName + ".py";
|
||||||
|
myFixture.configureByFiles(filenames);
|
||||||
|
final IntentionAction intentionAction = myFixture.findSingleIntention(hint);
|
||||||
|
assertNotNull(intentionAction);
|
||||||
|
myFixture.launchAction(intentionAction);
|
||||||
|
myFixture.checkResultByFile(testFileName + ".py", testFileName + "_after.py", true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user