From a96cafe066b2244bea9e501f93801405dfefaf1e Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Wed, 12 Feb 2020 05:28:44 +0100 Subject: [PATCH] Extract property: do not suggest duplicate property name #KT-36504 Fixed --- .../extractionEngine/extractorUtil.kt | 22 +++++++++++++++---- .../conflictWithParentClass.kt | 8 +++++++ .../conflictWithParentClass.kt.after | 10 +++++++++ .../introduceProperty/kt24615.kt.after | 4 ++-- .../introduce/ExtractionTestGenerated.java | 5 +++++ 5 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt create mode 100644 idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt index 212bf1abb46..42ee9765153 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt @@ -16,6 +16,7 @@ import com.intellij.refactoring.BaseRefactoringProcessor import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.core.util.isMultiLine @@ -29,11 +30,15 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.* import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValue.* import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValueBoxer.AsTuple import org.jetbrains.kotlin.idea.refactoring.removeTemplateEntryBracesIfPossible +import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.idea.util.getAllAccessibleVariables +import org.jetbrains.kotlin.idea.util.getResolutionScope import org.jetbrains.kotlin.idea.util.psi.patternMatching.* import org.jetbrains.kotlin.idea.util.psi.patternMatching.UnificationResult.StronglyMatched import org.jetbrains.kotlin.idea.util.psi.patternMatching.UnificationResult.WeaklyMatched import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.KtPsiFactory.CallableBuilder import org.jetbrains.kotlin.psi.psiUtil.* @@ -681,10 +686,19 @@ fun ExtractionGeneratorConfiguration.generateDeclaration( } } - if (declaration is KtProperty && declaration.isExtensionDeclaration() && !declaration.isTopLevel) { - val receiverTypeReference = (declaration as? KtCallableDeclaration)?.receiverTypeReference - receiverTypeReference?.siblings(withItself = false)?.firstOrNull { it.node.elementType == KtTokens.DOT }?.delete() - receiverTypeReference?.delete() + if (declaration is KtProperty) { + if (declaration.isExtensionDeclaration() && !declaration.isTopLevel) { + val receiverTypeReference = (declaration as? KtCallableDeclaration)?.receiverTypeReference + receiverTypeReference?.siblings(withItself = false)?.firstOrNull { it.node.elementType == KtTokens.DOT }?.delete() + receiverTypeReference?.delete() + } + if ((declaration.descriptor as? PropertyDescriptor)?.let { DescriptorUtils.isOverride(it) } == true) { + val scope = declaration.getResolutionScope() + val newName = KotlinNameSuggester.suggestNameByName(descriptor.name) { + it != descriptor.name && scope.getAllAccessibleVariables(Name.identifier(it)).isEmpty() + } + declaration.setName(newName) + } } CodeStyleManager.getInstance(descriptor.extractionData.project).reformat(declaration) diff --git a/idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt b/idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt new file mode 100644 index 00000000000..b990e903314 --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt @@ -0,0 +1,8 @@ +// EXTRACTION_TARGET: property with initializer +open class Base(protected val i: Int) + +class Impl(z: Int) : Base(z) { + fun foo(): Int { + return 2 + 3 + i + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt.after b/idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt.after new file mode 100644 index 00000000000..f152cc3596d --- /dev/null +++ b/idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt.after @@ -0,0 +1,10 @@ +// EXTRACTION_TARGET: property with initializer +open class Base(protected val i: Int) + +class Impl(z: Int) : Base(z) { + private val i1 = 2 + 3 + i + + fun foo(): Int { + return i1 + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/introduceProperty/kt24615.kt.after b/idea/testData/refactoring/introduceProperty/kt24615.kt.after index faeb1eba715..fb70b5e86c4 100644 --- a/idea/testData/refactoring/introduceProperty/kt24615.kt.after +++ b/idea/testData/refactoring/introduceProperty/kt24615.kt.after @@ -3,10 +3,10 @@ open class Base(protected val i: Int) class Impl(i: Int) : Base(i) { - private val i: Int + private val i1: Int get() = 2 + 3 + i fun foo(): Int { - return i + return i1 } } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java index 5ee5a5322b6..36365bb372c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/introduce/ExtractionTestGenerated.java @@ -2787,6 +2787,11 @@ public class ExtractionTestGenerated extends AbstractExtractionTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/refactoring/introduceProperty"), Pattern.compile("^(.+)\\.(kt|kts)$"), null, true); } + @TestMetadata("conflictWithParentClass.kt") + public void testConflictWithParentClass() throws Exception { + runTest("idea/testData/refactoring/introduceProperty/conflictWithParentClass.kt"); + } + @TestMetadata("extractExtensionWithInitializer.kt") public void testExtractExtensionWithInitializer() throws Exception { runTest("idea/testData/refactoring/introduceProperty/extractExtensionWithInitializer.kt");