diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index db738e9ef448..a336cd982316 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -661,7 +661,8 @@ refactoring.inline.function.special.method=Cannot inline special methods refactoring.inline.function.decorator=Cannot inline functions with decorators refactoring.inline.function.self.referrent=Cannot inline functions that reference themselves refactoring.inline.function.star=Cannot inline functions with * arguments -refactoring.inline.function.overridden=Cannot inline overridden functions +refactoring.inline.function.overrides.method=Cannot inline methods that override other methods +refactoring.inline.function.is.overridden=Cannot inline overridden methods refactoring.inline.function.global=Cannot inline functions with global variables refactoring.inline.function.nonlocal=Cannot inline functions with nonlocals variables refactoring.inline.function.nested=Cannot inline functions with another function declaration diff --git a/python/src/com/jetbrains/python/refactoring/inline/PyInlineFunctionHandler.kt b/python/src/com/jetbrains/python/refactoring/inline/PyInlineFunctionHandler.kt index 2ee32b72d47f..759bbfe14178 100644 --- a/python/src/com/jetbrains/python/refactoring/inline/PyInlineFunctionHandler.kt +++ b/python/src/com/jetbrains/python/refactoring/inline/PyInlineFunctionHandler.kt @@ -17,6 +17,7 @@ import com.jetbrains.python.PythonLanguage import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache import com.jetbrains.python.psi.* import com.jetbrains.python.psi.impl.PyBuiltinCache +import com.jetbrains.python.psi.search.PyOverridingMethodsSearch import com.jetbrains.python.psi.search.PySuperMethodsSearch import com.jetbrains.python.psi.types.TypeEvalContext import com.jetbrains.python.pyi.PyiFile @@ -41,7 +42,8 @@ class PyInlineFunctionHandler : InlineActionHandler() { hasDecorators(element) -> "refactoring.inline.function.decorator" hasReferencesToSelf(element) -> "refactoring.inline.function.self.referrent" hasStarArgs(element) -> "refactoring.inline.function.star" - isOverride(element, project) -> "refactoring.inline.function.overridden" + overridesMethod(element, project) -> "refactoring.inline.function.overrides.method" + isOverridden(element) -> "refactoring.inline.function.is.overridden" functionScope.hasGlobals() -> "refactoring.inline.function.global" functionScope.hasNonLocals() -> "refactoring.inline.function.nonlocal" hasNestedFunction(element) -> "refactoring.inline.function.nested" @@ -108,11 +110,15 @@ class PyInlineFunctionHandler : InlineActionHandler() { private fun hasDecorators(function: PyFunction): Boolean = function.decoratorList?.decorators?.isNotEmpty() == true - private fun isOverride(function: PyFunction, project: Project): Boolean { + private fun overridesMethod(function: PyFunction, project: Project): Boolean { return function.containingClass != null && PySuperMethodsSearch.search(function, TypeEvalContext.codeAnalysis(project, function.containingFile)).any() } + private fun isOverridden(function: PyFunction): Boolean { + return function.containingClass != null && PyOverridingMethodsSearch.search(function, true).any() + } + private fun hasStarArgs(function: PyFunction): Boolean { return function.parameterList.parameters.asSequence() .filterIsInstance() diff --git a/python/testData/refactoring/inlineFunction/overridden.py b/python/testData/refactoring/inlineFunction/overridden.py index fe01764358d4..69c0dc02a041 100644 --- a/python/testData/refactoring/inlineFunction/overridden.py +++ b/python/testData/refactoring/inlineFunction/overridden.py @@ -8,5 +8,5 @@ class B(A): print(2) -b = B() -b.method() \ No newline at end of file +a = A() +a.method() \ No newline at end of file diff --git a/python/testData/refactoring/inlineFunction/overrides.py b/python/testData/refactoring/inlineFunction/overrides.py new file mode 100644 index 000000000000..fe01764358d4 --- /dev/null +++ b/python/testData/refactoring/inlineFunction/overrides.py @@ -0,0 +1,12 @@ +class A(): + def method(self): + print(1) + + +class B(A): + def method(self): + print(2) + + +b = B() +b.method() \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/refactoring/PyInlineFunctionTest.kt b/python/testSrc/com/jetbrains/python/refactoring/PyInlineFunctionTest.kt index 4e69869a007e..f59ef039933f 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/PyInlineFunctionTest.kt +++ b/python/testSrc/com/jetbrains/python/refactoring/PyInlineFunctionTest.kt @@ -94,7 +94,8 @@ class PyInlineFunctionTest : PyTestCase() { fun testDecorator() = doTestError("Cannot inline functions with decorators") fun testRecursive() = doTestError("Cannot inline functions that reference themselves") fun testStar() = doTestError("Cannot inline functions with * arguments") - fun testOverridden() = doTestError("Cannot inline overridden functions") + fun testOverrides() = doTestError("Cannot inline methods that override other methods") + fun testOverridden() = doTestError("Cannot inline overridden methods") fun testNested() = doTestError("Cannot inline functions with another function declaration") fun testInterruptedFlow() = doTestError("Cannot inline functions that interrupt control flow") fun testUsedAsDecorator() = doTestError("Function foo is used as a decorator and cannot be inlined. Function definition will not be removed", isReferenceError = true)