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:
Alexey Sedunov
2014-12-26 11:53:44 +03:00
parent 22f4caa78d
commit 59d646bc16
10 changed files with 50 additions and 29 deletions
@@ -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
@@ -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
@@ -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,5 +1,6 @@
// "Create parameter 'foo'" "false"
// ACTION: Create local variable 'foo'
// ACTION: Create property 'foo'
// ACTION: Split property declaration
// ERROR: Unresolved reference: foo
@@ -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
}
@@ -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
}
@@ -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()
}
@@ -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
}