Fix caret position in "Convert function to property" intention
#KT-19944 Fixed
This commit is contained in:
+13
-9
@@ -45,10 +45,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory.CallableBuilder.Target.READ_ONLY_PROPERTY
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStartOffsetIn
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findVariable
|
||||
@@ -64,6 +61,7 @@ class ConvertFunctionToPropertyIntention :
|
||||
|
||||
private inner class Converter(
|
||||
project: Project,
|
||||
private val file: KtFile,
|
||||
private val editor: Editor?,
|
||||
descriptor: FunctionDescriptor
|
||||
) : CallableRefactoring<FunctionDescriptor>(project, descriptor, text) {
|
||||
@@ -74,7 +72,7 @@ class ConvertFunctionToPropertyIntention :
|
||||
(SyntheticJavaPropertyDescriptor.propertyNameByGetMethodName(name) ?: name).asString()
|
||||
}
|
||||
|
||||
private fun convertFunction(originalFunction: KtNamedFunction, psiFactory: KtPsiFactory) {
|
||||
private fun convertFunction(originalFunction: KtNamedFunction, psiFactory: KtPsiFactory, moveCaret: Boolean) {
|
||||
val propertyString = KtPsiFactory.CallableBuilder(READ_ONLY_PROPERTY).apply {
|
||||
// make sure to capture all comments and line breaks
|
||||
modifier(originalFunction.text.substring(0, originalFunction.funKeyword!!.getStartOffsetIn(originalFunction)))
|
||||
@@ -97,14 +95,14 @@ class ConvertFunctionToPropertyIntention :
|
||||
}.asString()
|
||||
|
||||
val replaced = originalFunction.replaced(psiFactory.createDeclaration<KtProperty>(propertyString))
|
||||
|
||||
editor?.caretModel?.moveToOffset(replaced.nameIdentifier!!.endOffset)
|
||||
if (editor != null && moveCaret) editor.caretModel.moveToOffset(replaced.nameIdentifier!!.endOffset)
|
||||
}
|
||||
|
||||
override fun performRefactoring(descriptorsForChange: Collection<CallableDescriptor>) {
|
||||
val conflicts = MultiMap<PsiElement, String>()
|
||||
val getterName = JvmAbi.getterName(callableDescriptor.name.asString())
|
||||
val callables = getAffectedCallables(project, descriptorsForChange)
|
||||
val mainElement = findMainElement(callables)
|
||||
val kotlinCalls = ArrayList<KtCallElement>()
|
||||
val kotlinRefsToRename = ArrayList<PsiReference>()
|
||||
val foreignRefs = ArrayList<PsiReference>()
|
||||
@@ -177,7 +175,7 @@ class ConvertFunctionToPropertyIntention :
|
||||
foreignRefs.forEach { it.handleElementRename(newGetterName) }
|
||||
callables.forEach {
|
||||
when (it) {
|
||||
is KtNamedFunction -> convertFunction(it, psiFactory)
|
||||
is KtNamedFunction -> convertFunction(it, psiFactory, moveCaret = it == mainElement)
|
||||
is PsiMethod -> it.name = newGetterName
|
||||
}
|
||||
}
|
||||
@@ -186,6 +184,12 @@ class ConvertFunctionToPropertyIntention :
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun findMainElement(callables: List<PsiElement>): PsiElement? {
|
||||
if (editor == null) return null
|
||||
val offset = editor.caretModel.offset
|
||||
return callables.find { file == it.containingFile && offset in it.textRange }
|
||||
}
|
||||
}
|
||||
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
@@ -208,6 +212,6 @@ class ConvertFunctionToPropertyIntention :
|
||||
|
||||
override fun applyTo(element: KtNamedFunction, editor: Editor?) {
|
||||
val descriptor = element.unsafeResolveToDescriptor(BodyResolveMode.PARTIAL) as FunctionDescriptor
|
||||
Converter(element.project, editor, descriptor).run()
|
||||
Converter(element.project, element.containingKtFile, editor, descriptor).run()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ interface T {
|
||||
}
|
||||
|
||||
class A(val n: Int) {
|
||||
val foo
|
||||
val foo<caret>
|
||||
get() = object : T {
|
||||
override fun bar() {
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ fun test() {
|
||||
class X
|
||||
|
||||
class A(val n: Int) {
|
||||
val foo get() = X()
|
||||
val foo<caret> get() = X()
|
||||
}
|
||||
|
||||
val t = A(1).foo
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
class A(val n: Int) {
|
||||
val foo get() = n > 1
|
||||
val foo<caret> get() = n > 1
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class A(val n: Int) {
|
||||
val foo: Boolean
|
||||
val foo<caret>: Boolean
|
||||
get() {
|
||||
return n > 1
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ annotation class X(val s: String)
|
||||
|
||||
// 1
|
||||
@X("") // 2
|
||||
/* 3 */ fun foo<caret>(): String {
|
||||
/* 3 */ fun fo<caret>o(): String {
|
||||
// 4
|
||||
return ""
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
class A(val n: Int) {
|
||||
val foo: Boolean
|
||||
val foo<caret>: Boolean
|
||||
get() = n > 1
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package test
|
||||
|
||||
val foo: Boolean
|
||||
val foo<caret>: Boolean
|
||||
get() = true
|
||||
@@ -1,4 +1,4 @@
|
||||
package test
|
||||
|
||||
val foo: Boolean
|
||||
val foo<caret>: Boolean
|
||||
get() = true
|
||||
@@ -1,4 +1,4 @@
|
||||
package test
|
||||
|
||||
val isFoo: Boolean
|
||||
val isFoo<caret>: Boolean
|
||||
get() = true
|
||||
@@ -5,7 +5,7 @@ import p.foo
|
||||
|
||||
class A(val n: Int)
|
||||
|
||||
val A.foo: Boolean
|
||||
val A.foo<caret>: Boolean
|
||||
get() = n > 1
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -5,7 +5,7 @@ import p.foo
|
||||
|
||||
class A(val n: Int)
|
||||
|
||||
val A.foo: Boolean
|
||||
val A.foo<caret>: Boolean
|
||||
get() = n > 1
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -5,7 +5,7 @@ import p.isFoo
|
||||
|
||||
class A(val n: Int)
|
||||
|
||||
val A.isFoo: Boolean
|
||||
val A.isFoo<caret>: Boolean
|
||||
get() = n > 1
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -10,7 +10,7 @@ open class A(val n: Int): T {
|
||||
}
|
||||
|
||||
class B: A(1) {
|
||||
override val foo: Boolean
|
||||
override val foo<caret>: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
// WITH_RUNTIME
|
||||
val String.foo: String
|
||||
val String.foo<caret>: String
|
||||
get() = if (isEmpty()) "" else substring(1).foo
|
||||
+1
-1
@@ -5,7 +5,7 @@ annotation class X(val s: String)
|
||||
class A(val n: Int) {
|
||||
val t = 1
|
||||
internal @X("1")
|
||||
val <T : Number> T.foo: Boolean
|
||||
val <T : Number> T.foo<caret>: Boolean
|
||||
get() = toInt() - n > 1
|
||||
val u = 2
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user