Extract Function: Generate function in property's enclosing declaration if original expression belongs to initializer of that property
#KT-6290 Fixed
This commit is contained in:
@@ -73,6 +73,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.jet.plugin.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
|
||||
fun <T: Any> PsiElement.getAndRemoveCopyableUserData(key: Key<T>): T? {
|
||||
val data = getCopyableUserData(key)
|
||||
@@ -137,27 +138,27 @@ public fun PsiElement.getAllExtractionContainers(strict: Boolean = true): List<J
|
||||
}
|
||||
|
||||
public fun PsiElement.getExtractionContainers(strict: Boolean = true, includeAll: Boolean = false): List<JetElement> {
|
||||
fun getEnclosingDeclaration(element: PsiElement, strict: Boolean): PsiElement? {
|
||||
return element.parents(!strict)
|
||||
.filter {
|
||||
(it is JetDeclarationWithBody && it !is JetFunctionLiteral)
|
||||
|| it is JetClassInitializer
|
||||
|| it is JetClassBody
|
||||
|| it is JetFile
|
||||
}
|
||||
.firstOrNull()
|
||||
}
|
||||
|
||||
if (includeAll) return getAllExtractionContainers(strict)
|
||||
|
||||
val declaration = getParentOfType<JetDeclaration>(strict)?.let { declaration ->
|
||||
stream(declaration) { it.getStrictParentOfType<JetDeclaration>() }.firstOrNull { it !is JetFunctionLiteral }
|
||||
} ?: return Collections.emptyList()
|
||||
|
||||
val parent = declaration.getParent()?.let {
|
||||
when (it) {
|
||||
is JetProperty, is JetMultiDeclaration -> it.getParent()
|
||||
is JetParameterList -> it.getParent()?.getParent()
|
||||
else -> it
|
||||
}
|
||||
val enclosingDeclaration = getEnclosingDeclaration(this, strict)?.let {
|
||||
if (it is JetDeclarationWithBody || it is JetClassInitializer) getEnclosingDeclaration(it, true) else it
|
||||
}
|
||||
return when (parent) {
|
||||
is JetFile -> Collections.singletonList(parent)
|
||||
is JetClassBody -> {
|
||||
getAllExtractionContainers(strict).filterIsInstance<JetClassBody>()
|
||||
}
|
||||
|
||||
return when (enclosingDeclaration) {
|
||||
is JetFile -> Collections.singletonList(enclosingDeclaration)
|
||||
is JetClassBody -> getAllExtractionContainers(strict).filterIsInstance<JetClassBody>()
|
||||
else -> {
|
||||
val enclosingDeclaration =
|
||||
PsiTreeUtil.getNonStrictParentOfType(parent, javaClass<JetDeclarationWithBody>(), javaClass<JetClassInitializer>())
|
||||
val targetContainer = when (enclosingDeclaration) {
|
||||
is JetDeclarationWithBody -> enclosingDeclaration.getBodyExpression()
|
||||
is JetClassInitializer -> enclosingDeclaration.getBody()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// ACTION: Create class 'SomeTest'
|
||||
// ACTION: Create enum 'SomeTest'
|
||||
// ACTION: Create object 'SomeTest'
|
||||
// ACTION: Create property 'SomeTest'
|
||||
// ACTION: Create trait 'SomeTest'
|
||||
// ERROR: Unresolved reference: SomeTest
|
||||
|
||||
|
||||
+1
@@ -2,6 +2,7 @@
|
||||
// ACTION: Create class 'A'
|
||||
// ACTION: Create trait 'A'
|
||||
// ACTION: Create object 'A'
|
||||
// ACTION: Create property 'A'
|
||||
// ACTION: Create enum 'A'
|
||||
// ACTION: Create annotation 'A'
|
||||
// ERROR: Unresolved reference: A
|
||||
|
||||
+1
@@ -2,6 +2,7 @@
|
||||
// ACTION: Create class 'A'
|
||||
// ACTION: Create trait 'A'
|
||||
// ACTION: Create object 'A'
|
||||
// ACTION: Create property 'A'
|
||||
// ACTION: Create enum 'A'
|
||||
// ACTION: Create annotation 'A'
|
||||
// ERROR: Unresolved reference: A
|
||||
|
||||
+1
@@ -1,5 +1,6 @@
|
||||
// "Create parameter 'foo'" "false"
|
||||
// ACTION: Create local variable 'foo'
|
||||
// ACTION: Create property 'foo'
|
||||
// ACTION: Split property declaration
|
||||
// ERROR: Unresolved reference: foo
|
||||
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
fun foo() {
|
||||
fun i(): Int {
|
||||
return 1 + 1
|
||||
}
|
||||
|
||||
val x = i()
|
||||
val y = i()
|
||||
}
|
||||
|
||||
private fun i(): Int {
|
||||
return 1 + 1
|
||||
}
|
||||
@@ -1,3 +1,7 @@
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_DESCRIPTOR: value-parameter val a: kotlin.Int defined in bar
|
||||
// PARAM_DESCRIPTOR: value-parameter val b: kotlin.Int defined in bar
|
||||
fun bar(a: Int, b: Int) {
|
||||
val foo = <selection>a + b</selection> - 1
|
||||
}
|
||||
+8
-4
@@ -1,7 +1,11 @@
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_DESCRIPTOR: value-parameter val a: kotlin.Int defined in bar
|
||||
// PARAM_DESCRIPTOR: value-parameter val b: kotlin.Int defined in bar
|
||||
fun bar(a: Int, b: Int) {
|
||||
fun i(): Int {
|
||||
return a + b
|
||||
}
|
||||
val foo = i(a, b) - 1
|
||||
}
|
||||
|
||||
val foo = i() - 1
|
||||
private fun i(a: Int, b: Int): Int {
|
||||
return a + b
|
||||
}
|
||||
+4
@@ -1,3 +1,7 @@
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_DESCRIPTOR: value-parameter val a: kotlin.Int defined in bar
|
||||
// PARAM_DESCRIPTOR: value-parameter val b: kotlin.Int defined in bar
|
||||
fun bar(a: Int, b: Int) {
|
||||
val foo = { <selection>a + b</selection> - 1 }.invoke()
|
||||
}
|
||||
+8
-4
@@ -1,7 +1,11 @@
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_TYPES: kotlin.Int
|
||||
// PARAM_DESCRIPTOR: value-parameter val a: kotlin.Int defined in bar
|
||||
// PARAM_DESCRIPTOR: value-parameter val b: kotlin.Int defined in bar
|
||||
fun bar(a: Int, b: Int) {
|
||||
fun i(): Int {
|
||||
return a + b
|
||||
}
|
||||
val foo = { i(a, b) - 1 }.invoke()
|
||||
}
|
||||
|
||||
val foo = { i() - 1 }.invoke()
|
||||
private fun i(a: Int, b: Int): Int {
|
||||
return a + b
|
||||
}
|
||||
Reference in New Issue
Block a user