From 0e3e387446549c028b09c921962140e5fdeca1ad Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 22 Feb 2018 22:49:44 +0300 Subject: [PATCH] Rename: Adapt VariableInplaceRenameHandler to Kotlin #KT-16510 Fixed --- idea/src/META-INF/plugin.xml | 1 + .../ScopeFunctionConversionInspection.kt | 4 +- ...thExplicitFunctionLiteralParamIntention.kt | 4 +- .../KotlinRefactoringSupportProvider.kt | 30 +------- .../KotlinMemberInplaceRenameHandler.kt | 41 +++++----- .../KotlinVariableInplaceRenameHandler.kt | 74 +++++++++++++++++++ .../RenameBackingFieldReferenceHandler.kt | 3 +- ...LabeledReferenceInLambdaArgumentHandler.kt | 3 +- .../rename/RenameDynamicMemberHandler.kt | 11 ++- .../RenameImportAliasByReferenceHandler.kt | 4 +- .../RenameKotlinImplicitLambdaParameter.kt | 3 +- ...iableInplaceRenameHandlerWithFinishHook.kt | 10 +-- .../idea/refactoring/rename/renameUtil.kt | 1 + .../rename/inplace/QuotedLocalVar.kt | 7 ++ .../rename/inplace/QuotedLocalVar.kt.after | 7 ++ .../rename/inplace/QuotedParameter.kt | 7 ++ .../rename/inplace/QuotedParameter.kt.after | 7 ++ .../idea/refactoring/InplaceRenameTest.kt | 15 +++- 18 files changed, 154 insertions(+), 78 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt create mode 100644 idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt create mode 100644 idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt.after create mode 100644 idea/testData/refactoring/rename/inplace/QuotedParameter.kt create mode 100644 idea/testData/refactoring/rename/inplace/QuotedParameter.kt.after diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 91cee0b082b..48b9d81a565 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -2782,6 +2782,7 @@ + diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/ScopeFunctionConversionInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/ScopeFunctionConversionInspection.kt index af301727346..979331d7ba4 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/ScopeFunctionConversionInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/ScopeFunctionConversionInspection.kt @@ -13,13 +13,13 @@ import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementVisitor import com.intellij.psi.SmartPsiElementPointer -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.KotlinNameSuggester import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.refactoring.getThisLabelName +import org.jetbrains.kotlin.idea.refactoring.rename.KotlinVariableInplaceRenameHandler import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors import org.jetbrains.kotlin.idea.util.getReceiverTargetDescriptor import org.jetbrains.kotlin.idea.util.getResolutionScope @@ -359,6 +359,6 @@ private fun PsiElement.startInPlaceRename() { PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document) editor.caretModel.moveToOffset(startOffset) - VariableInplaceRenameHandler().doRename(this, editor, null) + KotlinVariableInplaceRenameHandler().doRename(this, editor, null) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt index 2905d7e9aea..88abbc26162 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ReplaceItWithExplicitFunctionLiteralParamIntention.kt @@ -19,8 +19,8 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.codeInsight.intention.LowPriorityAction import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiDocumentManager -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.refactoring.rename.KotlinVariableInplaceRenameHandler import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.psi.KtFunctionLiteral import org.jetbrains.kotlin.psi.KtLambdaExpression @@ -49,6 +49,6 @@ class ReplaceItWithExplicitFunctionLiteralParamIntention : SelfTargetingOffsetIn val paramToRename = functionLiteral.valueParameters.single() editor.caretModel.moveToOffset(element.textOffset) - VariableInplaceRenameHandler().doRename(paramToRename, editor, null) + KotlinVariableInplaceRenameHandler().doRename(paramToRename, editor, null) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSupportProvider.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSupportProvider.kt index aeb6a499e9a..34aac8e9d1f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSupportProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSupportProvider.kt @@ -23,8 +23,8 @@ import com.intellij.psi.PsiNameIdentifierOwner import com.intellij.refactoring.RefactoringActionHandler import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeSignatureHandler import org.jetbrains.kotlin.idea.refactoring.introduce.extractClass.KotlinExtractInterfaceHandler -import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler import org.jetbrains.kotlin.idea.refactoring.introduce.extractClass.KotlinExtractSuperclassHandler +import org.jetbrains.kotlin.idea.refactoring.introduce.extractFunction.ExtractKotlinFunctionHandler import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceLambdaParameterHandler import org.jetbrains.kotlin.idea.refactoring.introduce.introduceParameter.KotlinIntroduceParameterHandler import org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty.KotlinIntroducePropertyHandler @@ -32,7 +32,8 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinI import org.jetbrains.kotlin.idea.refactoring.pullUp.KotlinPullUpHandler import org.jetbrains.kotlin.idea.refactoring.pushDown.KotlinPushDownHandler import org.jetbrains.kotlin.idea.refactoring.safeDelete.canDeleteElement -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.KtConstructor +import org.jetbrains.kotlin.psi.KtElement class KotlinRefactoringSupportProvider : RefactoringSupportProvider() { override fun isSafeDeleteAvailable(element: PsiElement) = element.canDeleteElement() @@ -51,31 +52,6 @@ class KotlinRefactoringSupportProvider : RefactoringSupportProvider() { fun getExtractFunctionToScopeHandler(): RefactoringActionHandler = ExtractKotlinFunctionHandler(true, ExtractKotlinFunctionHandler.InteractiveExtractionHelper) - override fun isInplaceRenameAvailable(element: PsiElement, context: PsiElement?): Boolean { - when (element) { - is KtTypeParameter -> return true - is KtProperty -> { - if (element.isLocal) return true - } - is KtDestructuringDeclarationEntry -> return true - is KtParameter -> { - val parent = element.parent - if (parent is KtForExpression) { - return true - } - if (parent is KtParameterList) { - val grandparent = parent.parent - return grandparent is KtCatchClause || grandparent is KtFunctionLiteral - } - } - is KtLabeledExpression, is KtImportAlias -> return true - } - return false - } - - override fun isMemberInplaceRenameAvailable(element: PsiElement, context: PsiElement?) = - element is KtNamedDeclaration && element.nameIdentifier != null - override fun getChangeSignatureHandler() = KotlinChangeSignatureHandler() override fun getPullUpHandler() = KotlinPullUpHandler() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinMemberInplaceRenameHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinMemberInplaceRenameHandler.kt index 11d61ffebdf..3c754e5823c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinMemberInplaceRenameHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinMemberInplaceRenameHandler.kt @@ -18,29 +18,21 @@ package org.jetbrains.kotlin.idea.refactoring.rename import com.intellij.openapi.editor.Editor import com.intellij.psi.* +import com.intellij.refactoring.RefactoringActionHandler import com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer import org.jetbrains.kotlin.idea.core.unquote -import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtNamedDeclaration import org.jetbrains.kotlin.psi.KtPrimaryConstructor class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() { - companion object { - private val variableInplaceHandler = object : VariableInplaceRenameHandler() { - override public fun isAvailable(element: PsiElement?, editor: Editor?, file: PsiFile?): Boolean { - return super.isAvailable(element, editor, file) - } - } - } - private class RenamerImpl( - elementToRename: PsiNamedElement, - substitutedElement: PsiElement?, - editor: Editor, - currentName: String, - oldName: String + elementToRename: PsiNamedElement, + substitutedElement: PsiElement?, + editor: Editor, + currentName: String, + oldName: String ) : MemberInplaceRenamer(elementToRename, substitutedElement, editor, currentName, oldName) { override fun acceptReference(reference: PsiReference): Boolean { val refElement = reference.element @@ -49,6 +41,10 @@ class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() { return referenceText == myElementToRename.name } + override fun startsOnTheSameElement(handler: RefactoringActionHandler?, element: PsiElement?): Boolean { + return variable == element && (handler is MemberInplaceRenameHandler || handler is KotlinRenameDispatcherHandler) + } + override fun createInplaceRenamerToRestart(variable: PsiNamedElement, editor: Editor, initialName: String): VariableInplaceRenamer { return RenamerImpl(variable, substituted, editor, initialName, myOldName) } @@ -67,10 +63,10 @@ class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() { val offset = editor.caretModel.offset val editorPsiFile = PsiDocumentManager.getInstance(element.project).getPsiFile(editor.document) if (nameIdentifier != null - && editorPsiFile == elementToRename.containingFile - && elementToRename is KtPrimaryConstructor - && offset !in nameIdentifier.textRange - && offset in elementToRename.textRange) { + && editorPsiFile == elementToRename.containingFile + && elementToRename is KtPrimaryConstructor + && offset !in nameIdentifier.textRange + && offset in elementToRename.textRange) { editor.caretModel.moveToOffset(nameIdentifier.textOffset) } @@ -79,9 +75,8 @@ class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() { } override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { - val currentElement = element?.substitute() - return currentElement is KtElement && - !variableInplaceHandler.isAvailable(currentElement, editor, file) && - super.isAvailable(currentElement, editor, file) + if (!editor.settings.isVariableInplaceRenameEnabled) return false + val currentElement = element?.substitute() as? KtNamedDeclaration ?: return false + return currentElement.nameIdentifier != null && !KotlinVariableInplaceRenameHandler.isInplaceRenameAvailable(currentElement) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt new file mode 100644 index 00000000000..aa48fd9f2f9 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinVariableInplaceRenameHandler.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.refactoring.rename + +import com.intellij.openapi.editor.Editor +import com.intellij.psi.* +import com.intellij.refactoring.RefactoringActionHandler +import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler +import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer +import org.jetbrains.kotlin.idea.core.unquote +import org.jetbrains.kotlin.psi.* + +open class KotlinVariableInplaceRenameHandler : VariableInplaceRenameHandler() { + companion object { + fun isInplaceRenameAvailable(element: PsiElement): Boolean { + when (element) { + is KtTypeParameter -> return true + is KtProperty -> { + if (element.isLocal) return true + } + is KtDestructuringDeclarationEntry -> return true + is KtParameter -> { + val parent = element.parent + if (parent is KtForExpression) { + return true + } + if (parent is KtParameterList) { + val grandparent = parent.parent + return grandparent is KtCatchClause || grandparent is KtFunctionLiteral + } + } + is KtLabeledExpression, is KtImportAlias -> return true + } + return false + } + } + + protected open class RenamerImpl : VariableInplaceRenamer { + constructor(elementToRename: PsiNamedElement, editor: Editor): super(elementToRename, editor) + constructor( + elementToRename: PsiNamedElement, + editor: Editor, + currentName: String, + oldName: String + ) : super(elementToRename, editor, editor.project, currentName, oldName) + + override fun acceptReference(reference: PsiReference): Boolean { + val refElement = reference.element + val textRange = reference.rangeInElement + val referenceText = refElement.text.substring(textRange.startOffset, textRange.endOffset).unquote() + return referenceText == myElementToRename.name + } + + override fun startsOnTheSameElement(handler: RefactoringActionHandler?, element: PsiElement?): Boolean { + return variable == element && (handler is VariableInplaceRenameHandler || handler is KotlinRenameDispatcherHandler) + } + + override fun createInplaceRenamerToRestart(variable: PsiNamedElement, editor: Editor, initialName: String): VariableInplaceRenamer { + return RenamerImpl(variable, editor, initialName, myOldName) + } + } + + override fun createRenamer(elementToRename: PsiElement, editor: Editor): VariableInplaceRenamer? { + val currentElementToRename = elementToRename as PsiNameIdentifierOwner + val currentName = currentElementToRename.nameIdentifier?.text ?: "" + return RenamerImpl(currentElementToRename, editor, currentName, currentName) + } + + override public fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile) = + editor.settings.isVariableInplaceRenameEnabled && element != null && isInplaceRenameAvailable(element) +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt index 52b3bec925c..429a0cfb1cd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameBackingFieldReferenceHandler.kt @@ -21,13 +21,12 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils import org.jetbrains.kotlin.psi.KtSimpleNameExpression -class RenameBackingFieldReferenceHandler: VariableInplaceRenameHandler() { +class RenameBackingFieldReferenceHandler: KotlinVariableInplaceRenameHandler() { override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { val refExpression = file.findElementForRename(editor.caretModel.offset) ?: return false if (refExpression.text != "field") return false diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameByLabeledReferenceInLambdaArgumentHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameByLabeledReferenceInLambdaArgumentHandler.kt index b988caed4fd..3e78dc83455 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameByLabeledReferenceInLambdaArgumentHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameByLabeledReferenceInLambdaArgumentHandler.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.refactoring.rename import com.intellij.openapi.actionSystem.DataContext import com.intellij.psi.PsiElement -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde @@ -31,7 +30,7 @@ import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode class RenameByLabeledReferenceInLambdaArgumentHandler : - AbstractReferenceSubstitutionRenameHandler(VariableInplaceRenameHandler()) { + AbstractReferenceSubstitutionRenameHandler(KotlinVariableInplaceRenameHandler()) { override fun getElementToRename(dataContext: DataContext): PsiElement? { val refExpr = getReferenceExpression(dataContext) as? KtLabelReferenceExpression ?: return null val context = refExpr.analyze(BodyResolveMode.PARTIAL) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt index 8e646e410b1..f25b34c26e9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameDynamicMemberHandler.kt @@ -16,19 +16,18 @@ package org.jetbrains.kotlin.idea.refactoring.rename -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler -import com.intellij.psi.PsiElement +import com.intellij.openapi.actionSystem.DataContext import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.psi.util.PsiTreeUtil -import org.jetbrains.kotlin.psi.KtSimpleNameExpression -import com.intellij.openapi.project.Project -import com.intellij.openapi.actionSystem.DataContext import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils +import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic -class RenameDynamicMemberHandler: VariableInplaceRenameHandler() { +class RenameDynamicMemberHandler: KotlinVariableInplaceRenameHandler() { override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { val callee = PsiTreeUtil.findElementOfClassAtOffset( file, editor.caretModel.offset, KtSimpleNameExpression::class.java, false diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameImportAliasByReferenceHandler.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameImportAliasByReferenceHandler.kt index 03cb6789053..d9155b1f26b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameImportAliasByReferenceHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameImportAliasByReferenceHandler.kt @@ -18,11 +18,9 @@ package org.jetbrains.kotlin.idea.refactoring.rename import com.intellij.openapi.actionSystem.DataContext import com.intellij.psi.PsiElement -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import org.jetbrains.kotlin.idea.references.mainReference -import org.jetbrains.kotlin.psi.KtSimpleNameExpression -class RenameImportAliasByReferenceHandler : AbstractReferenceSubstitutionRenameHandler(VariableInplaceRenameHandler()) { +class RenameImportAliasByReferenceHandler : AbstractReferenceSubstitutionRenameHandler(KotlinVariableInplaceRenameHandler()) { override fun getElementToRename(dataContext: DataContext): PsiElement? { val refExpr = getReferenceExpression(dataContext) ?: return null return refExpr.mainReference.getImportAlias() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt index 99cc3fe795f..0223d7fd33d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinImplicitLambdaParameter.kt @@ -21,13 +21,12 @@ import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import org.jetbrains.kotlin.idea.intentions.ReplaceItWithExplicitFunctionLiteralParamIntention import org.jetbrains.kotlin.idea.intentions.isAutoCreatedItUsage import org.jetbrains.kotlin.idea.util.application.executeWriteCommand import org.jetbrains.kotlin.psi.KtNameReferenceExpression -class RenameKotlinImplicitLambdaParameter : VariableInplaceRenameHandler() { +class RenameKotlinImplicitLambdaParameter : KotlinVariableInplaceRenameHandler() { override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean { val nameExpression = file.findElementForRename(editor.caretModel.offset) diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/VariableInplaceRenameHandlerWithFinishHook.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/VariableInplaceRenameHandlerWithFinishHook.kt index f1f04d392a4..397b8ba1067 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/VariableInplaceRenameHandlerWithFinishHook.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/VariableInplaceRenameHandlerWithFinishHook.kt @@ -19,17 +19,15 @@ package org.jetbrains.kotlin.idea.refactoring.rename import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiElement import com.intellij.psi.PsiNamedElement -import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer -class VariableInplaceRenameHandlerWithFinishHook(private val onFinish: () -> Unit) : VariableInplaceRenameHandler() { - override fun createRenamer(elementToRename: PsiElement, editor: Editor?): VariableInplaceRenamer? { - return object : VariableInplaceRenamer(elementToRename as PsiNamedElement, editor) { +class VariableInplaceRenameHandlerWithFinishHook(private val onFinish: () -> Unit) : KotlinVariableInplaceRenameHandler() { + override fun createRenamer(elementToRename: PsiElement, editor: Editor): VariableInplaceRenamer? { + return object : RenamerImpl(elementToRename as PsiNamedElement, editor) { override fun performRefactoring(): Boolean { try { return super.performRefactoring() - } - finally { + } finally { onFinish() } } diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameUtil.kt index 0ed231237ed..efbbc5e5639 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameUtil.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.idea.core.dropDefaultValue import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle import org.jetbrains.kotlin.idea.references.AbstractKtReference import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.KtPrimaryConstructor import org.jetbrains.kotlin.resolve.source.getPsi fun checkConflictsAndReplaceUsageInfos( diff --git a/idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt b/idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt new file mode 100644 index 00000000000..6ce82ff8b7f --- /dev/null +++ b/idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt @@ -0,0 +1,7 @@ +class A(val a: B) +class B(val b: Int) + +fun x(`is`: A) { + val `in` = `is`.a + `in`.b +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt.after b/idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt.after new file mode 100644 index 00000000000..bf71ee7b81f --- /dev/null +++ b/idea/testData/refactoring/rename/inplace/QuotedLocalVar.kt.after @@ -0,0 +1,7 @@ +class A(val a: B) +class B(val b: Int) + +fun x(`is`: A) { + val x = `is`.a + x.b +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/inplace/QuotedParameter.kt b/idea/testData/refactoring/rename/inplace/QuotedParameter.kt new file mode 100644 index 00000000000..d39f9910d67 --- /dev/null +++ b/idea/testData/refactoring/rename/inplace/QuotedParameter.kt @@ -0,0 +1,7 @@ +class A(val a: B) +class B(val b: Int) + +fun x(`is`: A) { + val `in` = `is`.a + `in`.b +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/inplace/QuotedParameter.kt.after b/idea/testData/refactoring/rename/inplace/QuotedParameter.kt.after new file mode 100644 index 00000000000..1272f0e98b8 --- /dev/null +++ b/idea/testData/refactoring/rename/inplace/QuotedParameter.kt.after @@ -0,0 +1,7 @@ +class A(val a: B) +class B(val b: Int) + +fun x(x: A) { + val `in` = x.a + `in`.b +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/InplaceRenameTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/InplaceRenameTest.kt index c55eab7f057..86ace25c444 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/InplaceRenameTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/InplaceRenameTest.kt @@ -11,10 +11,11 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.impl.SimpleDataContext import com.intellij.openapi.command.WriteCommandAction -import com.intellij.refactoring.rename.inplace.MemberInplaceRenameHandler import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler import com.intellij.testFramework.LightPlatformCodeInsightTestCase import com.intellij.testFramework.fixtures.CodeInsightTestUtil +import org.jetbrains.kotlin.idea.refactoring.rename.KotlinMemberInplaceRenameHandler +import org.jetbrains.kotlin.idea.refactoring.rename.KotlinVariableInplaceRenameHandler import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinImplicitLambdaParameter import org.jetbrains.kotlin.idea.refactoring.rename.findElementForRename import org.jetbrains.kotlin.idea.test.PluginTestCaseBase @@ -142,6 +143,14 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() { doTestMemberInplaceRename("example") } + fun testQuotedLocalVar() { + doTestInplaceRename("x") + } + + fun testQuotedParameter() { + doTestMemberInplaceRename("x") + } + private fun doTestImplicitLambdaParameter(newName: String) { configureByFile(getTestName(false) + ".kt") @@ -193,10 +202,10 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() { } private fun doTestMemberInplaceRename(newName: String?) { - doTestInplaceRename(newName, MemberInplaceRenameHandler()) + doTestInplaceRename(newName, KotlinMemberInplaceRenameHandler()) } - private fun doTestInplaceRename(newName: String?, handler: VariableInplaceRenameHandler = VariableInplaceRenameHandler()) { + private fun doTestInplaceRename(newName: String?, handler: VariableInplaceRenameHandler = KotlinVariableInplaceRenameHandler()) { configureByFile(getTestName(false) + ".kt") val element = TargetElementUtil.findTargetElement( LightPlatformCodeInsightTestCase.myEditor,