IDEA-CR-49176: function inline: only inline all is available if it is called on import reference (PY-36658)

GitOrigin-RevId: 79d6ac71e03f946140b52b321571bdb04f7550ee
This commit is contained in:
Aleksei Kniazev
2019-07-08 18:05:36 +03:00
committed by intellij-monorepo-bot
parent cb1875f3c6
commit 2f2da7bc03
2 changed files with 31 additions and 5 deletions
@@ -3,12 +3,17 @@ package com.jetbrains.python.refactoring.inline
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.PsiReference
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.refactoring.inline.InlineOptionsDialog
import com.jetbrains.python.PyBundle
import com.jetbrains.python.psi.PyFunction
import com.jetbrains.python.psi.PyImportStatementBase
import com.jetbrains.python.psi.PyReferenceExpression
import com.jetbrains.python.pyi.PyiUtil
/**
* @author Aleksei.Kniazev
@@ -22,13 +27,17 @@ class PyInlineFunctionDialog(project: Project,
private val myNumberOfOccurrences: Int = getNumberOfOccurrences(myFunction)
init {
myInvokedOnReference = myReference != null
myInvokedOnReference = if (myReference != null) {
val expression = myReference.element as PyReferenceExpression
PsiTreeUtil.getParentOfType(expression, PyImportStatementBase::class.java) == null
} else false
title = if (isMethod) "Inline method $myFunctionName" else "Inline function $myFunctionName"
init()
}
override fun doAction() {
invokeRefactoring(PyInlineFunctionProcessor(myProject, myEditor, myFunction, myReference, isInlineThisOnly, !isKeepTheDeclaration))
val originalFunction = PyiUtil.getOriginalElement(myFunction) as PyFunction?
invokeRefactoring(PyInlineFunctionProcessor(myProject, myEditor, originalFunction ?: myFunction, myReference, isInlineThisOnly, !isKeepTheDeclaration))
}
override fun getNameLabelText(): String {
@@ -50,4 +59,17 @@ class PyInlineFunctionDialog(project: Project,
override fun ignoreOccurrence(reference: PsiReference): Boolean {
return PsiTreeUtil.getParentOfType(reference.element, PyImportStatementBase::class.java) == null
}
override fun getNumberOfOccurrences(nameIdentifierOwner: PsiNameIdentifierOwner?): Int {
// TODO: this override will be redundant after PY-26881 is fixed and should be deleted then
val originalNum = super.getNumberOfOccurrences(nameIdentifierOwner)
val stubOrImplementation = if (PyiUtil.isInsideStub(myFunction)) PyiUtil.getOriginalElement(myFunction) else PyiUtil.getPythonStub(myFunction)
if (originalNum != -1 && stubOrImplementation != null) {
val fromDeclaration = ReferencesSearch.search(stubOrImplementation, GlobalSearchScope.projectScope(myProject)).asSequence()
.filter(this::ignoreOccurrence)
.count()
return originalNum + fromDeclaration
}
return originalNum
}
}
@@ -95,12 +95,16 @@ class PyInlineFunctionProcessor(project: Project,
override fun findUsages(): Array<UsageInfo> {
if (myInlineThis) {
val element = myReference!!.element as PyReferenceExpression
val isImport = PsiTreeUtil.getParentOfType(element, PyImportStatementBase::class.java) != null
val localImport = PyResolveUtil.resolveLocally(ScopeUtil.getScopeOwner(element)!!, element.name!!).firstOrNull { it is PyImportElement }
return if (!isImport && localImport != null) arrayOf(UsageInfo(element), UsageInfo(localImport)) else arrayOf(UsageInfo(element))
return if (localImport != null) arrayOf(UsageInfo(element), UsageInfo(localImport)) else arrayOf(UsageInfo(element))
}
return ReferencesSearch.search(myFunction, myRefactoringScope).asSequence()
// TODO: replace with PyRefactoringUtil#findUsages after PY-26881 and PY-36493 are fixed
var references = ReferencesSearch.search(myFunction, myRefactoringScope).findAll().asSequence()
PyiUtil.getPythonStub(myFunction)?.let { stub ->
references += ReferencesSearch.search(stub, myRefactoringScope).asSequence()
}
return references
.distinct()
.map(PsiReference::getElement)
.map(::UsageInfo)