diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt index 3a7b47ce9ba..eb0f15bcb11 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/KtSimpleNameReference.kt @@ -28,10 +28,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference import org.jetbrains.kotlin.idea.codeInsight.shorten.addDelayedImportRequest import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet -import org.jetbrains.kotlin.idea.core.ShortenReferences -import org.jetbrains.kotlin.idea.core.copied -import org.jetbrains.kotlin.idea.core.quoteIfNeeded -import org.jetbrains.kotlin.idea.core.replaced +import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName import org.jetbrains.kotlin.lexer.KtToken @@ -39,6 +36,7 @@ import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.isOneSegmentFQN import org.jetbrains.kotlin.plugin.references.SimpleNameReferenceExtension import org.jetbrains.kotlin.psi.* @@ -108,6 +106,20 @@ class KtSimpleNameReference(expression: KtSimpleNameExpression) : KtSimpleRefere if (!canRename()) throw IncorrectOperationException() if (newElementName == null) return expression + if (newElementName.unquote() == "") { + val qualifiedElement = expression.getQualifiedElement() + return when (qualifiedElement) { + is KtQualifiedExpression -> { + expression.replace(qualifiedElement.receiverExpression) + qualifiedElement.replaced(qualifiedElement.selectorExpression!!) + } + is KtUserType -> { + expression.replaced(KtPsiFactory(expression).createSimpleName(SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.asString())) + } + else -> expression + } + } + // Do not rename if the reference corresponds to synthesized component function val expressionText = expression.text if (expressionText != null && Name.isValidIdentifier(expressionText)) { 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 3c754e5823c..331b4dbd258 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinMemberInplaceRenameHandler.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/KotlinMemberInplaceRenameHandler.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.idea.refactoring.rename +import com.intellij.lang.Language import com.intellij.openapi.editor.Editor import com.intellij.psi.* import com.intellij.refactoring.RefactoringActionHandler @@ -24,6 +25,7 @@ import com.intellij.refactoring.rename.inplace.MemberInplaceRenamer import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer import org.jetbrains.kotlin.idea.core.unquote import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtObjectDeclaration import org.jetbrains.kotlin.psi.KtPrimaryConstructor class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() { @@ -34,6 +36,11 @@ class KotlinMemberInplaceRenameHandler : MemberInplaceRenameHandler() { currentName: String, oldName: String ) : MemberInplaceRenamer(elementToRename, substitutedElement, editor, currentName, oldName) { + override fun isIdentifier(newName: String?, language: Language?): Boolean { + if (newName == "" && (variable as? KtObjectDeclaration)?.isCompanion() == true) return true + return super.isIdentifier(newName, language) + } + override fun acceptReference(reference: PsiReference): Boolean { val refElement = reference.element val textRange = reference.rangeInElement diff --git a/idea/testData/refactoring/rename/inplace/EraseCompanionName.kt b/idea/testData/refactoring/rename/inplace/EraseCompanionName.kt new file mode 100644 index 00000000000..b3788ba4942 --- /dev/null +++ b/idea/testData/refactoring/rename/inplace/EraseCompanionName.kt @@ -0,0 +1,16 @@ +class Foo { + companion object Bar { + fun bar(n: Int) {} + operator fun invoke(n: Int) {} + operator fun get(n: Int) {} + } +} + +fun test() { + val x = 1 + Foo.Bar.bar(123) + Foo.Bar(123) + Foo.Bar[123] + val y: Foo.Bar + val z: Foo.Bar? +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/inplace/EraseCompanionName.kt.after b/idea/testData/refactoring/rename/inplace/EraseCompanionName.kt.after new file mode 100644 index 00000000000..df62f1f8190 --- /dev/null +++ b/idea/testData/refactoring/rename/inplace/EraseCompanionName.kt.after @@ -0,0 +1,16 @@ +class Foo { + companion object { + fun bar(n: Int) {} + operator fun invoke(n: Int) {} + operator fun get(n: Int) {} + } +} + +fun test() { + val x = 1 + Foo.bar(123) + Foo(123) + Foo[123] + val y: Foo.Companion + val z: Foo.Companion? +} \ 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 86ace25c444..9b40ad2f071 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/InplaceRenameTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/InplaceRenameTest.kt @@ -151,6 +151,10 @@ class InplaceRenameTest : LightPlatformCodeInsightTestCase() { doTestMemberInplaceRename("x") } + fun testEraseCompanionName() { + doTestMemberInplaceRename("") + } + private fun doTestImplicitLambdaParameter(newName: String) { configureByFile(getTestName(false) + ".kt")