Rename: Introduce dispatching handler

The goal is to filter out KotlinMemberInplaceHandler similar to how
RenameHandlerRegistry does with MemberInplaceHandler
This commit is contained in:
Alexey Sedunov
2017-11-03 19:38:15 +03:00
parent 56746380f7
commit 2792e0c412
4 changed files with 74 additions and 28 deletions
@@ -51,5 +51,7 @@
<extensionPoint name="defaultScriptDependenciesProvider"
interface="org.jetbrains.kotlin.idea.core.script.DefaultScriptDependenciesProvider"
area="IDEA_PROJECT"/>
<extensionPoint name="renameHandler"
interface="com.intellij.refactoring.rename.RenameHandler"/>
</extensionPoints>
</idea-plugin>
+14 -12
View File
@@ -537,18 +537,7 @@
id="KotlinTypeParameter"/>
<renamePsiElementProcessor implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler$Processor"
id="JavaSyntheticPropertyFromKotlin"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinImplicitLambdaParameter"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameDynamicMemberHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameOnSecondaryConstructorHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.JavaMemberByKotlinReferenceInplaceRenameHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameJvmNameHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinDirectoryAsPackageRenameHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameBackingFieldReferenceHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameClassByCompanionObjectShortReferenceHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameByLabeledReferenceInLambdaArgumentHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameImportAliasByReferenceHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinMemberInplaceRenameHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinRenameDispatcherHandler"/>
<automaticRenamerFactory implementation="org.jetbrains.kotlin.idea.refactoring.rename.AutomaticVariableRenamerFactory"/>
<automaticRenamerFactory implementation="org.jetbrains.kotlin.idea.refactoring.rename.AutomaticVariableRenamerFactoryForJavaClass"/>
<automaticRenamerFactory implementation="org.jetbrains.kotlin.idea.refactoring.rename.AutomaticVariableInJavaRenamerFactory"/>
@@ -2727,6 +2716,19 @@
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<quickFixContributor implementation="org.jetbrains.kotlin.idea.quickfix.QuickFixRegistrar"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinImplicitLambdaParameter"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameDynamicMemberHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameOnSecondaryConstructorHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameJavaSyntheticPropertyHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.JavaMemberByKotlinReferenceInplaceRenameHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameJvmNameHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinDirectoryAsPackageRenameHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameBackingFieldReferenceHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameClassByCompanionObjectShortReferenceHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameByLabeledReferenceInLambdaArgumentHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameImportAliasByReferenceHandler"/>
<renameHandler implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinMemberInplaceRenameHandler"/>
<declarationAttributeAltererExtension implementation="org.jetbrains.kotlin.allopen.ide.IdeAllOpenDeclarationAttributeAltererExtension"/>
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
@@ -17,19 +17,13 @@
package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.Comparing
import com.intellij.psi.*
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.caches.resolve.analyze
import org.jetbrains.kotlin.idea.core.unquote
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtLabelReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() {
companion object {
@@ -65,15 +59,8 @@ class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() {
}
override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean {
if (variableInplaceHandler.isAvailable(element, editor, file)) return false
if (element !is KtElement) return false
if (!super.isAvailable(element, editor, file)) return false
val referenceExpression = AbstractReferenceSubstitutionRenameHandler.getReferenceExpression(file, editor.caretModel.offset) ?: return true
if (referenceExpression is KtLabelReferenceExpression) return false
if (referenceExpression.mainReference.getImportAlias() != null) return false
if (referenceExpression.analyze(BodyResolveMode.PARTIAL)[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, referenceExpression] != null) return false
return true
return element is KtElement &&
!variableInplaceHandler.isAvailable(element, editor, file) &&
super.isAvailable(element, editor, file)
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.refactoring.rename.RenameHandler
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.util.*
class KotlinRenameDispatcherHandler : RenameHandler {
companion object {
val EP_NAME = ExtensionPointName<RenameHandler>("org.jetbrains.kotlin.renameHandler")
private val handlers: Array<out RenameHandler> get() = Extensions.getExtensions(EP_NAME)
}
private fun getRenameHandler(dataContext: DataContext?): RenameHandler? {
val availableHandlers = handlers.filterTo(LinkedHashSet()) { it.isRenaming(dataContext) }
availableHandlers.singleOrNull()?.let { return it }
availableHandlers.firstIsInstanceOrNull<KotlinMemberInplaceRenameHandler>()?.let { availableHandlers -= it }
return availableHandlers.firstOrNull()
}
override fun isAvailableOnDataContext(dataContext: DataContext?) = handlers.any { it.isAvailableOnDataContext(dataContext) }
override fun isRenaming(dataContext: DataContext?) = isAvailableOnDataContext(dataContext)
override fun invoke(project: Project, editor: Editor?, file: PsiFile?, dataContext: DataContext?) {
getRenameHandler(dataContext)?.invoke(project, editor, file, dataContext)
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
getRenameHandler(dataContext)?.invoke(project, elements, dataContext)
}
}