Rename: @JvmName support

#KT-8044 Fixed
 #KT-9432 Fixed
This commit is contained in:
Alexey Sedunov
2016-05-25 15:26:03 +03:00
parent ff4c16d342
commit 96132fa61a
198 changed files with 1928 additions and 87 deletions
+1
View File
@@ -173,6 +173,7 @@
###### New features
- [`KT-7851`](https://youtrack.jetbrains.com/issue/KT-7851) Respect naming conventions in automatic variable rename
- [`KT-8044`](https://youtrack.jetbrains.com/issue/KT-8044), [`KT-9432`](https://youtrack.jetbrains.com/issue/KT-9432) Support @JvmName annotation in rename refactoring
###### Issues fixed
- [`KT-8860`](https://youtrack.jetbrains.com/issue/KT-8860) Allow renaming class by constructor delegation call referencing primary constructor
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.kotlin
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -45,6 +46,15 @@ object PackagePartClassUtils {
else
"_$str"
private @JvmStatic fun decapitalizeAsJavaClassName(str: String): String =
// NB use Locale.ENGLISH so that build is locale-independent.
// See Javadoc on java.lang.String.toUpperCase() for more details.
when {
Character.isJavaIdentifierStart(str[0]) -> str.substring(0, 1).toLowerCase(Locale.ENGLISH) + str.substring(1)
str[0] == '_' -> str.substring(1)
else -> str
}
@TestOnly
@JvmStatic fun getDefaultPartFqName(facadeClassFqName: FqName, file: VirtualFile): FqName =
getPackagePartFqName(facadeClassFqName.parent(), file.name)
@@ -68,4 +78,10 @@ object PackagePartClassUtils {
@JvmStatic fun getFilePartShortName(fileName: String): String =
getPartClassName(FileUtil.getNameWithoutExtension(fileName))
@JvmStatic fun getFileNameByFacadeName(facadeClassName: String): String? {
if (!facadeClassName.endsWith(PART_CLASS_NAME_SUFFIX)) return null
val baseName = facadeClassName.substring(0, facadeClassName.length - PART_CLASS_NAME_SUFFIX.length)
if (baseName == "_") return null
return "${decapitalizeAsJavaClassName(baseName)}.${KotlinFileType.EXTENSION}"
}
}
@@ -29,12 +29,17 @@ import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.containers.SLRUCache
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils.fileHasTopLevelCallables
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.kotlin.psi.psiUtil.siblings
import javax.swing.Icon
class KtLightClassForFacade private constructor(
@@ -140,7 +145,44 @@ class KtLightClassForFacade private constructor(
override fun getName() = facadeClassFqName.shortName().asString()
override fun setName(name: String): PsiElement? = this
override fun setName(name: String): PsiElement? {
for (file in files) {
val jvmNameEntry = JvmFileClassUtil.findAnnotationEntryOnFileNoResolve(file, JvmFileClassUtil.JVM_NAME_SHORT)
if (PackagePartClassUtils.getFilePartShortName(file.name) == name) {
jvmNameEntry?.delete()
continue
}
if (jvmNameEntry == null) {
val newFileName = PackagePartClassUtils.getFileNameByFacadeName(name)
val facadeDir = file.parent
if (newFileName != null && facadeDir != null && facadeDir.findFile(newFileName) == null) {
file.name = newFileName
continue
}
val psiFactory = KtPsiFactory(this)
val annotationText = "${JvmFileClassUtil.JVM_NAME_SHORT}(\"$name\")"
val newFileAnnotationList = psiFactory.createFileAnnotationListWithAnnotation(annotationText)
val annotationList = file.fileAnnotationList
if (annotationList != null) {
annotationList.add(newFileAnnotationList.annotationEntries.first())
}
else {
val anchor = file.firstChild.siblings().firstOrNull { it !is PsiWhiteSpace && it !is PsiComment }
file.addBefore(newFileAnnotationList, anchor)
}
continue
}
val jvmNameExpression = jvmNameEntry.valueArguments.firstOrNull()?.getArgumentExpression() as? KtStringTemplateExpression
?: continue
ElementManipulators.handleContentChange(jvmNameExpression, name)
}
return this
}
override fun getQualifiedName() = facadeClassFqName.asString()
@@ -26,6 +26,7 @@ import com.intellij.psi.util.*
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
interface KtLightMethod : PsiMethod, KtLightDeclaration<KtDeclaration, PsiMethod> {
@@ -99,8 +100,20 @@ sealed class KtLightMethodImpl(
}
override fun setName(name: String): PsiElement? {
val toRename = kotlinOrigin as? PsiNamedElement ?: throwCanNotModify()
toRename.setName(propertyNameByAccessor(name, this) ?: name)
val jvmNameAnnotation = modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString())
val newNameForOrigin = propertyNameByAccessor(name, this) ?: name
if (newNameForOrigin == kotlinOrigin?.name) {
jvmNameAnnotation?.delete()
return this
}
val nameExpression = jvmNameAnnotation?.findAttributeValue("name")?.unwrapped as? KtStringTemplateExpression
if (nameExpression != null) {
nameExpression.replace(KtPsiFactory(this).createStringTemplate(name))
}
else {
val toRename = kotlinOrigin as? PsiNamedElement ?: throwCanNotModify()
toRename.setName(newNameForOrigin)
}
return this
}
+1
View File
@@ -428,6 +428,7 @@
<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"/>
<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"/>
@@ -24,7 +24,9 @@ import com.intellij.psi.PsiNamedElement
import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.refactoring.util.RefactoringDescriptionLocation
import com.intellij.usageView.UsageViewLongNameLocation
import com.intellij.usageView.UsageViewShortNameLocation
import com.intellij.usageView.UsageViewTypeLocation
import org.jetbrains.kotlin.asJava.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
@@ -36,7 +38,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
class KotlinElementDescriptionProvider : ElementDescriptionProvider {
override fun getElementDescription(element: PsiElement, location: ElementDescriptionLocation): String? {
val targetElement = element.unwrapped
val targetElement = element.unwrapped ?: element
fun elementKind() = when (targetElement) {
is KtClass -> if (targetElement.isInterface()) "interface" else "class"
@@ -48,6 +50,7 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider {
is KtParameter -> "parameter"
is KtDestructuringDeclarationEntry -> "variable"
is RenameJavaSyntheticPropertyHandler.SyntheticPropertyWrapper -> "property"
is KtLightClassForFacade -> "facade class"
else -> null
}
@@ -62,7 +65,7 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider {
if (targetElement !is PsiNamedElement || targetElement.language != KotlinLanguage.INSTANCE) return null
return when(location) {
is UsageViewTypeLocation -> elementKind()
is UsageViewLongNameLocation -> targetElement.getName()
is UsageViewShortNameLocation, is UsageViewLongNameLocation -> targetElement.getName()
is RefactoringDescriptionLocation -> {
val kind = elementKind() ?: return null
val descriptor = targetDescriptor() ?: return null
@@ -0,0 +1,83 @@
/*
* Copyright 2010-2016 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.CommonDataKeys
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 com.intellij.refactoring.rename.PsiElementRenameHandler
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.isPlain
import org.jetbrains.kotlin.psi.psiUtil.plainContent
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class RenameJvmNameHandler : PsiElementRenameHandler() {
private fun getStringTemplate(dataContext: DataContext): KtStringTemplateExpression? {
val caret = CommonDataKeys.CARET.getData(dataContext) ?: return null
val ktFile = CommonDataKeys.PSI_FILE.getData(dataContext) as? KtFile ?: return null
return ktFile.findElementAt(caret.offset)?.getNonStrictParentOfType<KtStringTemplateExpression>()
}
override fun isAvailableOnDataContext(dataContext: DataContext): Boolean {
val nameExpression = getStringTemplate(dataContext) ?: return false
if (!nameExpression.isPlain()) return false
val entry = ((nameExpression.parent as? KtValueArgument)?.parent as? KtValueArgumentList)?.parent as? KtAnnotationEntry
?: return false
val annotationType = entry.analyze(BodyResolveMode.PARTIAL)[BindingContext.TYPE, entry.typeReference]
?: return false
return annotationType.constructor.declarationDescriptor?.importableFqName == DescriptorUtils.JVM_NAME
}
private fun wrapDataContext(dataContext: DataContext): DataContext? {
val nameExpression = getStringTemplate(dataContext) ?: return null
val name = nameExpression.plainContent
val entry = nameExpression.getStrictParentOfType<KtAnnotationEntry>() ?: return null
val annotationList = PsiTreeUtil.getParentOfType(entry, KtModifierList::class.java, KtFileAnnotationList::class.java)
val newElement = when (annotationList) {
is KtModifierList ->
(annotationList.parent as? KtDeclaration)?.toLightMethods()?.firstOrNull { it.name == name } ?: return null
is KtFileAnnotationList -> annotationList.getContainingKtFile().findFacadeClass() ?: return null
else -> return null
}
return DataContext { id ->
if (CommonDataKeys.PSI_ELEMENT.`is`(id)) return@DataContext newElement
dataContext.getData(id)
}
}
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext) {
super.invoke(project, editor, file, wrapDataContext(dataContext) ?: return)
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext) {
super.invoke(project, elements, wrapDataContext(dataContext) ?: return)
}
}
@@ -19,12 +19,9 @@ package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.refactoring.RefactoringBundle
import com.intellij.refactoring.util.CommonRefactoringUtil
import org.jetbrains.kotlin.asJava.KtLightClass
import org.jetbrains.kotlin.asJava.KtLightClassForExplicitDeclaration
import org.jetbrains.kotlin.asJava.KtLightClassForFacade
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -38,12 +35,10 @@ class RenameKotlinClassProcessor : RenameKotlinPsiProcessor() {
return element is KtClassOrObject || element is KtLightClass || element is KtConstructor<*>
}
override fun substituteElementToRename(element: PsiElement, editor: Editor?): PsiElement? {
return getKtClassOrObject(element, true, editor)
}
override fun substituteElementToRename(element: PsiElement, editor: Editor?) = getClassOrObject(element)
override fun prepareRenaming(element: PsiElement, newName: String, allRenames: MutableMap<PsiElement, String>) {
val classOrObject = getKtClassOrObject(element, false, null) ?: return
val classOrObject = getClassOrObject(element) as? KtClassOrObject ?: return
val file = classOrObject.getContainingKtFile()
@@ -71,26 +66,12 @@ class RenameKotlinClassProcessor : RenameKotlinPsiProcessor() {
return bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, element] != null
}
private fun getKtClassOrObject(element: PsiElement?, showErrors: Boolean, editor: Editor?): KtClassOrObject? = when (element) {
private fun getClassOrObject(element: PsiElement?): PsiElement? = when (element) {
is KtLightClass ->
if (element is KtLightClassForExplicitDeclaration) {
element.kotlinOrigin
}
else if (element is KtLightClassForFacade) {
if (showErrors) {
CommonRefactoringUtil.showErrorHint(
element.project, editor,
KotlinBundle.message("rename.kotlin.package.class.error"),
RefactoringBundle.message("rename.title"),
null)
}
// Cancel rename
null
}
else {
assert(false) { "Should not be suggested to rename element of type " + element.javaClass + " " + element }
null
when (element) {
is KtLightClassForExplicitDeclaration -> element.kotlinOrigin
is KtLightClassForFacade -> element
else -> throw AssertionError("Should not be suggested to rename element of type " + element.javaClass + " " + element)
}
is KtConstructor<*> ->
@@ -19,19 +19,22 @@ package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReference
import com.intellij.psi.search.SearchScope
import com.intellij.refactoring.listeners.RefactoringElementListener
import com.intellij.refactoring.rename.RenameJavaMethodProcessor
import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.asJava.KtLightElement
import org.jetbrains.kotlin.asJava.KtLightMethod
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorUtils
class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
private val javaMethodProcessorInstance = RenameJavaMethodProcessor()
@@ -40,6 +43,21 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
return element is KtNamedFunction || (element is KtLightMethod && element.kotlinOrigin is KtNamedFunction)
}
private fun getJvmName(element: PsiElement): String? {
val descriptor = (element.unwrapped as? KtFunction)?.resolveToDescriptor() as? FunctionDescriptor ?: return null
return DescriptorUtils.getJvmName(descriptor)
}
override fun findReferences(element: PsiElement): Collection<PsiReference> {
val allReferences = super.findReferences(element)
return when {
getJvmName(element) == null -> allReferences
element is KtElement -> allReferences.filter { it is KtReference }
element is KtLightElement<*, *> -> allReferences.filterNot { it is KtReference }
else -> emptyList()
}
}
override fun findCollisions(
element: PsiElement?,
newName: String?,
@@ -55,10 +73,11 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
// Use java dialog to ask we should rename function with the base element
val substitutedJavaElement = javaMethodProcessorInstance.substituteElementToRename(wrappedMethod, editor)
return when (substitutedJavaElement) {
is KtLightMethod -> substitutedJavaElement.kotlinOrigin as? KtNamedFunction
else -> substitutedJavaElement
if (substitutedJavaElement is KtLightMethod && element is KtDeclaration) {
return substitutedJavaElement.kotlinOrigin as? KtNamedFunction
}
return substitutedJavaElement
}
override fun prepareRenaming(element: PsiElement?, newName: String?, allRenames: MutableMap<PsiElement, String>, scope: SearchScope) {
@@ -19,24 +19,20 @@ package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.ui.Messages
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.SyntheticElement
import com.intellij.psi.*
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.refactoring.listeners.RefactoringElementListener
import com.intellij.refactoring.rename.RenameProcessor
import com.intellij.refactoring.util.RefactoringUtil
import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.asJava.KtLightMethod
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
import org.jetbrains.kotlin.asJava.propertyNameByAccessor
import org.jetbrains.kotlin.asJava.*
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.lexer.KtTokens
@@ -45,6 +41,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.OverrideResolver
class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
@@ -56,12 +53,32 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
/* Can't properly update getters and setters in Java */
override fun isInplaceRenameSupported() = false
override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? {
val namedUnwrappedElement = element?.namedUnwrappedElement
private fun getJvmNames(element: PsiElement): Pair<String?, String?> {
val descriptor = (element.unwrapped as? KtDeclaration)?.resolveToDescriptor() as? PropertyDescriptor ?: return null to null
val getterName = descriptor.getter?.let { DescriptorUtils.getJvmName(it) }
val setterName = descriptor.setter?.let { DescriptorUtils.getJvmName(it) }
return getterName to setterName
}
val callableDeclaration = namedUnwrappedElement as? KtCallableDeclaration
?: throw IllegalStateException("Can't be for element $element there because of canProcessElement()")
override fun findReferences(element: PsiElement): Collection<PsiReference> {
val allReferences = super.findReferences(element)
val (getterJvmName, setterJvmName) = getJvmNames(element)
return when {
getterJvmName == null && setterJvmName == null -> allReferences
element is KtElement -> allReferences.filter {
it is KtReference
|| (getterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != setterJvmName)
|| (setterJvmName == null && (it.resolve() as? PsiNamedElement)?.name != getterJvmName)
}
element is KtLightElement<*, *> -> {
val name = element.name
if (name == getterJvmName || name == setterJvmName) allReferences.filterNot { it is KtReference } else allReferences
}
else -> emptyList()
}
}
private fun chooseCallableToRename(callableDeclaration: KtCallableDeclaration): KtCallableDeclaration? {
val deepestSuperDeclaration = findDeepestOverriddenDeclaration(callableDeclaration)
if (deepestSuperDeclaration == null || deepestSuperDeclaration == callableDeclaration) {
return callableDeclaration
@@ -86,6 +103,24 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
}
}
override fun substituteElementToRename(element: PsiElement?, editor: Editor?): PsiElement? {
val namedUnwrappedElement = element?.namedUnwrappedElement ?: return null
val callableDeclaration = namedUnwrappedElement as? KtCallableDeclaration
?: throw IllegalStateException("Can't be for element $element there because of canProcessElement()")
val declarationToRename = chooseCallableToRename(callableDeclaration) ?: return null
val (getterJvmName, setterJvmName) = getJvmNames(namedUnwrappedElement)
if (element is KtLightMethod) {
val name = element.name
if (element.name != getterJvmName && element.name != setterJvmName) return declarationToRename
return declarationToRename.toLightMethods().firstOrNull { it.name == name }
}
return declarationToRename
}
override fun prepareRenaming(element: PsiElement?, newName: String?, allRenames: MutableMap<PsiElement, String>, scope: SearchScope) {
val namedUnwrappedElement = element?.namedUnwrappedElement
val propertyMethods = when(namedUnwrappedElement) {
@@ -107,6 +142,10 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
override tailrec fun renameElement(element: PsiElement, newName: String, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) {
if (element is KtLightMethod) {
if (element.modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString()) != null) {
return super.renameElement(element, newName, usages, listener)
}
val origin = element.kotlinOrigin
val newPropertyName = propertyNameByAccessor(newName, element)
// Kotlin references to Kotlin property should not use accessor name
@@ -159,7 +198,8 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
}
private fun addRenameElements(psiMethod: PsiMethod?,
oldName: String?, newName: String?,
oldName: String?,
newName: String?,
allRenames: MutableMap<PsiElement, String>,
scope: SearchScope) {
if (psiMethod == null) return
@@ -0,0 +1,7 @@
package test;
class Test {
{
Foo.foo();
}
}
@@ -0,0 +1,8 @@
// test
@file:JvmName("Foo")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
/*rename*/TestKt.foo();
}
}
@@ -0,0 +1,6 @@
// test
package test
fun foo() {
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "Foo",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
Foo.foo();
}
}
@@ -0,0 +1,7 @@
@file:JvmMultifileClass @file:JvmName("Foo")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
/*rename*/TestKt.foo();
}
}
@@ -0,0 +1,6 @@
@file:JvmMultifileClass
package test
fun foo() {
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "Foo",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
Foo.foo();
}
}
@@ -0,0 +1,7 @@
@file:JvmName("Foo")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
/*rename*/TestKt.foo();
}
}
@@ -0,0 +1,5 @@
package test
fun foo() {
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "Foo",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
FooKt.foo();
}
}
@@ -0,0 +1,5 @@
package test
fun foo() {
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
/*rename*/TestKt.foo();
}
}
@@ -0,0 +1,5 @@
package test
fun foo() {
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "FooKt",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
Bar.foo();
}
}
@@ -0,0 +1,6 @@
@file:JvmName("Bar")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
/*rename*/Foo.foo();
}
}
@@ -0,0 +1,6 @@
@file:JvmName("Foo")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "Bar",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
TestKt.foo();
}
}
@@ -0,0 +1,5 @@
package test
fun foo() {
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
/*rename*/Foo.foo();
}
}
@@ -0,0 +1,6 @@
@file:JvmName("Foo")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "TestKt",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
new A().foo();
}
}
@@ -0,0 +1,10 @@
package test
class A {
@JvmName("foo")
fun second() = 1
}
fun test() {
A().second()
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
new A().foo();
}
}
@@ -0,0 +1,10 @@
package test
class A {
@JvmName("foo")
fun /*rename*/first() = 1
}
fun test() {
A().first()
}
@@ -0,0 +1,6 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/test.kt",
"newName": "second",
"withRuntime": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
new A().bar();
}
}
@@ -0,0 +1,10 @@
package test
class A {
@JvmName("bar")
fun first() = 1
}
fun test() {
A().first()
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
new A()./*rename*/foo();
}
}
@@ -0,0 +1,10 @@
package test
class A {
@JvmName("foo")
fun first() = 1
}
fun test() {
A().first()
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "bar",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
new A().first();
}
}
@@ -0,0 +1,9 @@
package test
class A {
fun first() = 1
}
fun test() {
A().first()
}
@@ -0,0 +1,7 @@
package test;
class Test {
{
new A()./*rename*/foo();
}
}
@@ -0,0 +1,10 @@
package test
class A {
@JvmName("foo")
fun first() = 1
}
fun test() {
A().first()
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "first",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
Bar.foo();
Bar.foo2();
}
}
@@ -0,0 +1,7 @@
@file:JvmMultifileClass
@file:JvmName("Bar")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
@file:JvmMultifileClass
@file:JvmName("Bar")
package test
fun foo2() {
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
/*rename*/Foo.foo();
Foo.foo2();
}
}
@@ -0,0 +1,7 @@
@file:JvmMultifileClass
@file:JvmName("Foo")
package test
fun foo() {
}
@@ -0,0 +1,7 @@
@file:JvmMultifileClass
@file:JvmName("Foo")
package test
fun foo2() {
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "Bar",
"withRuntime": "true",
"byRef": "true"
}
@@ -1,3 +0,0 @@
package testing.rename
fun test() = 12
@@ -1,9 +0,0 @@
package testing;
import testing.rename.RenameKotlinClassKt;
class JavaClient {
void foo() {
RenameKotlinClassKt.test();
}
}
@@ -1,3 +0,0 @@
package testing.rename
fun test() = 12
@@ -1,9 +0,0 @@
package testing;
import testing.rename.RenameKotlinClassKt;
class JavaClient {
void foo() {
RenameKotlinClassKt.test();
}
}
@@ -1,6 +0,0 @@
{
"type": "JAVA_CLASS",
"hint": "Can\u0027t rename Kotlin package facade class",
"classId": "testing/rename/RenameKotlinClassKt",
"newName": "NewPackageName"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A().setSecond(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") var second: Int = 1)
fun test() {
A().second
A().second = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A().setFirst(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") var /*rename*/first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,6 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/test.kt",
"newName": "second",
"withRuntime": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFooNew();
new A().setFirst(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFooNew") var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A()./*rename*/getFoo();
new A().setFirst(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "getFooNew",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A().setSecond(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") var second: Int = 1)
fun test() {
A().second
A().second = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A()./*rename*/setFirst(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "second",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFirst();
new A().setFirst(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A()./*rename*/getFoo();
new A().setFirst(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "getFirst",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A().setBar(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") @set:JvmName("setBar") var second: Int = 1)
fun test() {
A().second
A().second = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A().setBar(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") @set:JvmName("setBar") var /*rename*/first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,6 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/test.kt",
"newName": "second",
"withRuntime": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFooNew();
new A().setBar(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFooNew") @set:JvmName("setBar") var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A()./*rename*/getFoo();
new A().setBar(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") @set:JvmName("setBar") var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,7 @@
{
"type": "MARKED_ELEMENT",
"mainFile": "test/JavaClient.java",
"newName": "getFooNew",
"withRuntime": "true",
"byRef": "true"
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A().setBarNew(1);
}
}
@@ -0,0 +1,8 @@
package test
class A(@get:JvmName("getFoo") @set:JvmName("setBarNew") var first: Int = 1)
fun test() {
A().first
A().first = 1
}
@@ -0,0 +1,8 @@
package test;
class Test {
{
new A().getFoo();
new A()./*rename*/setBar(1);
}
}

Some files were not shown because too many files have changed in this diff Show More