Inline handler: fix reference detection for properties

This commit is contained in:
Mikhail Glukhikh
2017-12-18 17:21:47 +03:00
parent ce441e2163
commit 41739602bc
3 changed files with 15 additions and 14 deletions
@@ -16,14 +16,12 @@
package org.jetbrains.kotlin.idea.refactoring.inline
import com.intellij.codeInsight.TargetElementUtil
import com.intellij.lang.Language
import com.intellij.lang.refactoring.InlineActionHandler
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.util.CommonRefactoringUtil
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -32,13 +30,11 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
import org.jetbrains.kotlin.idea.codeInliner.CallableUsageReplacementStrategy
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
class KotlinInlineFunctionHandler: InlineActionHandler() {
override fun isEnabledForLanguage(language: Language) = language == KotlinLanguage.INSTANCE
@@ -48,13 +44,8 @@ class KotlinInlineFunctionHandler: InlineActionHandler() {
override fun inlineElement(project: Project, editor: Editor?, element: PsiElement) {
element as KtNamedFunction
val nameReference = editor?.findSimpleNameReference()
val reference = editor?.let { TargetElementUtil.findReference(it, it.caretModel.offset) }
val nameReference = when (reference) {
is KtSimpleNameReference -> reference
is PsiMultiReference -> reference.references.firstIsInstanceOrNull<KtSimpleNameReference>()
else -> null
}
val recursive = element.isRecursive()
if (recursive && nameReference == null) {
val message = RefactoringBundle.getCannotRefactorMessage("Inline recursive function is supported only on references")
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.idea.refactoring.inline
import com.intellij.codeInsight.TargetElementUtil
import com.intellij.lang.Language
import com.intellij.lang.refactoring.InlineActionHandler
import com.intellij.openapi.application.ApplicationManager
@@ -36,7 +35,6 @@ import org.jetbrains.kotlin.idea.codeInliner.CodeToInline
import org.jetbrains.kotlin.idea.codeInliner.PropertyUsageReplacementStrategy
import org.jetbrains.kotlin.idea.project.builtIns
import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.references.ReferenceAccess
import org.jetbrains.kotlin.idea.references.readWriteAccess
import org.jetbrains.kotlin.lexer.KtTokens
@@ -184,8 +182,7 @@ class KotlinInlineValHandler(private val withPrompt: Boolean) : InlineActionHand
hasHighlightings: Boolean
) {
val replacementStrategy = PropertyUsageReplacementStrategy(readReplacement, writeReplacement)
val reference = editor?.let { TargetElementUtil.findReference(it, it.caretModel.offset) } as? KtSimpleNameReference
val reference = editor?.findSimpleNameReference()
val dialog = KotlinInlineValDialog(declaration, reference, replacementStrategy, assignmentToDelete, withPreview = withPrompt)
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.idea.refactoring.inline
import com.intellij.codeInsight.TargetElementUtil
import com.intellij.codeInsight.highlighting.HighlightManager
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
@@ -24,6 +25,7 @@ import com.intellij.openapi.editor.colors.EditorColorsManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference
import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.refactoring.util.RefactoringMessageDialog
@@ -39,6 +41,7 @@ import org.jetbrains.kotlin.idea.refactoring.move.ContainerChangeInfo
import org.jetbrains.kotlin.idea.refactoring.move.ContainerInfo
import org.jetbrains.kotlin.idea.refactoring.move.postProcessMoveUsages
import org.jetbrains.kotlin.idea.refactoring.move.processInternalReferencesToUpdateOnPackageNameChange
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
@@ -47,6 +50,7 @@ import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.util.*
fun highlightElements(project: Project, editor: Editor?, elements: List<PsiElement>) {
@@ -163,3 +167,12 @@ internal fun buildCodeToInline(
return builder.prepareCodeToInline(bodyCopy, emptyList(), ::analyzeBodyCopy, reformat = true)
}
}
internal fun Editor.findSimpleNameReference(): KtSimpleNameReference? {
val reference = TargetElementUtil.findReference(this, caretModel.offset)
return when (reference) {
is KtSimpleNameReference -> reference
is PsiMultiReference -> reference.references.firstIsInstanceOrNull()
else -> null
}
}