KT-6159: rename duplicates met

This commit is contained in:
Mikhail Glukhikh
2017-03-21 18:42:06 +03:00
parent 342118dfa8
commit 77888349cd
4 changed files with 37 additions and 14 deletions
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.codeInliner
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.refactoring.rename.RenameProcessor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
@@ -26,11 +27,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
import org.jetbrains.kotlin.idea.core.* import org.jetbrains.kotlin.idea.core.*
import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention
import org.jetbrains.kotlin.idea.util.CommentSaver import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.* import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
@@ -40,6 +39,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addIfNotNull
@@ -95,6 +95,9 @@ class CodeInliner<TCallElement : KtElement>(
processTypeParameterUsages() processTypeParameterUsages()
val lexicalScope = callElement.parent.getResolutionScope(bindingContext)
if (elementToBeReplaced is KtSafeQualifiedExpression) { if (elementToBeReplaced is KtSafeQualifiedExpression) {
wrapCodeForSafeCall(receiver!!, receiverType, elementToBeReplaced) wrapCodeForSafeCall(receiver!!, receiverType, elementToBeReplaced)
} }
@@ -127,7 +130,7 @@ class CodeInliner<TCallElement : KtElement>(
} }
return replacementPerformer.doIt(postProcessing = { range -> return replacementPerformer.doIt(postProcessing = { range ->
val newRange = postProcessInsertedCode(range) val newRange = postProcessInsertedCode(range, lexicalScope)
if (!newRange.isEmpty) { if (!newRange.isEmpty) {
commentSaver.restore(newRange) commentSaver.restore(newRange)
} }
@@ -135,6 +138,24 @@ class CodeInliner<TCallElement : KtElement>(
}) })
} }
private fun renameDuplicates(declarations: List<KtNamedDeclaration>,
lexicalScope: LexicalScope) {
fun String.hasConflicts() = lexicalScope.getAllAccessibleVariables(Name.identifier(this)).any {
!it.isExtension && it.isVisible(lexicalScope.ownerDescriptor)
}
val validator = CollectingNameValidator { !it.hasConflicts() }
for (declaration in declarations) {
val oldName = declaration.name
if (oldName != null && oldName.hasConflicts()) {
val newName = KotlinNameSuggester.suggestNameByName(oldName, validator)
val renameProcessor = RenameProcessor(project, declaration, newName, false, false)
renameProcessor.run()
}
}
}
private fun processValueParameterUsages(): Collection<IntroduceValueForParameter> { private fun processValueParameterUsages(): Collection<IntroduceValueForParameter> {
val introduceValuesForParameters = ArrayList<IntroduceValueForParameter>() val introduceValuesForParameters = ArrayList<IntroduceValueForParameter>()
@@ -356,10 +377,14 @@ class CodeInliner<TCallElement : KtElement>(
} }
} }
private fun postProcessInsertedCode(range: PsiChildRange): PsiChildRange { private fun postProcessInsertedCode(range: PsiChildRange, lexicalScope: LexicalScope?): PsiChildRange {
val elements = range.filterIsInstance<KtElement>().toList() val elements = range.filterIsInstance<KtElement>().toList()
if (elements.isEmpty()) return PsiChildRange.EMPTY if (elements.isEmpty()) return PsiChildRange.EMPTY
lexicalScope?.let {
renameDuplicates(elements.dropLast(1).filterIsInstance<KtNamedDeclaration>(), it)
}
elements.forEach { elements.forEach {
introduceNamedArguments(it) introduceNamedArguments(it)
@@ -1,8 +1,8 @@
class Point(val x: Double, val y: Double) { class Point(val x: Double, val y: Double) {
// After sqr inlining, only first usage of sqr is replaced // After sqr inlining, only first usage of sqr is replaced
fun distance(other: Point): Double { fun distance(other: Point): Double {
val x = x - other.x val x1 = x - other.x
// See KT-17022 // See KT-17022
return Math.sqrt(x * x + sqr(y - other.y)) return Math.sqrt(x1 * x1 + sqr(y - other.y))
} }
} }
@@ -1,8 +1,7 @@
class My { class My {
fun run() { fun run() {
// foo1 should be here val foo1 = 1 + 2
val foo = 1 + 2 val foo = foo1
val foo = foo
System.out.println(foo) System.out.println(foo)
} }
@@ -1,8 +1,7 @@
class My { class My {
fun run() { fun run() {
// foo1 should be here val foo1 = 1 + 2
val foo = 1 + 2 val foo = foo1
val foo = foo
System.out.println(foo) System.out.println(foo)
} }