IDEA-CR-49176: disallow function inlining for python special methods (PY-36461)

GitOrigin-RevId: e1049aec62e8c8240a555fdf818820e797d5c9a6
This commit is contained in:
Aleksei Kniazev
2019-07-08 18:05:36 +03:00
committed by intellij-monorepo-bot
parent 3749eba8e1
commit 72e1763f81
4 changed files with 16 additions and 0 deletions
@@ -657,6 +657,7 @@ refactoring.inline.function.generator=Cannot inline generators
refactoring.inline.function.async=Cannot inline async functions
refactoring.inline.function.constructor=Cannot inline constructor calls
refactoring.inline.function.builtin=Cannot inline builtin functions
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
@@ -37,6 +37,7 @@ class PyInlineFunctionHandler : InlineActionHandler() {
element.isGenerator -> "refactoring.inline.function.generator"
PyNames.INIT == element.name -> "refactoring.inline.function.constructor"
PyBuiltinCache.getInstance(element).isBuiltin(element) -> "refactoring.inline.function.builtin"
isSpecialMethod(element) -> "refactoring.inline.function.special.method"
hasDecorators(element) -> "refactoring.inline.function.decorator"
hasReferencesToSelf(element) -> "refactoring.inline.function.self.referrent"
hasStarArgs(element) -> "refactoring.inline.function.star"
@@ -56,6 +57,10 @@ class PyInlineFunctionHandler : InlineActionHandler() {
}
}
private fun isSpecialMethod(function: PyFunction): Boolean {
return function.containingClass != null && PyNames.getBuiltinMethods(LanguageLevel.forElement(function)).contains(function.name)
}
private fun hasNestedFunction(function: PyFunction): Boolean = SyntaxTraverser.psiTraverser(function.statementList).traverse().any { it is PyFunction }
private fun hasNonExhaustiveIfs(function: PyFunction): Boolean {
@@ -0,0 +1,9 @@
class Additive:
def __init__(self, value):
self.value = value
def __add__(self, other):
return Additive(self.value + other.value)
Additive(1) +<caret> Additive(1)
@@ -90,6 +90,7 @@ class PyInlineFunctionTest : PyTestCase() {
}
fun testConstructor() = doTestError("Cannot inline constructor calls")
fun testBuiltin() = doTestError("Cannot inline builtin functions")
fun testSpecialMethod() = doTestError("Cannot inline special methods")
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")