Create From Usage: Place generated declarations next to original element container if they have common parent
#KT-6687 Fixed
This commit is contained in:
+29
-18
@@ -529,12 +529,37 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
return Math.max(lineBreaksNeeded - lineBreaksPresent, 0)
|
return Math.max(lineBreaksNeeded - lineBreaksPresent, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
val declarationInPlace = when (containingElement) {
|
fun addNextToOriginalElementContainer(addBefore: Boolean): JetNamedDeclaration {
|
||||||
is JetFile -> containingElement.add(declaration) as JetNamedDeclaration
|
val actualContainer = (containingElement as? JetClassOrObject)?.getBody() ?: containingElement
|
||||||
|
val sibling = config.originalElement.parents().first { it.getParent() == actualContainer }
|
||||||
|
return if (addBefore) {
|
||||||
|
actualContainer.addBefore(declaration, sibling)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
actualContainer.addAfter(declaration, sibling)
|
||||||
|
} as JetNamedDeclaration
|
||||||
|
}
|
||||||
|
|
||||||
is PsiClass -> jetFileToEdit.add(declaration) as JetNamedDeclaration
|
val declarationInPlace = when {
|
||||||
|
containingElement.isAncestor(config.originalElement, true) -> {
|
||||||
|
val insertToBlock = containingElement is JetBlockExpression
|
||||||
|
if (insertToBlock) {
|
||||||
|
val parent = containingElement.getParent()
|
||||||
|
if (parent is JetFunctionLiteral) {
|
||||||
|
if (!parent.isMultiLine()) {
|
||||||
|
parent.addBefore(newLine, containingElement)
|
||||||
|
parent.addAfter(newLine, containingElement)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addNextToOriginalElementContainer(insertToBlock || declaration is JetProperty)
|
||||||
|
}
|
||||||
|
|
||||||
is JetClassOrObject -> {
|
containingElement is JetFile -> containingElement.add(declaration) as JetNamedDeclaration
|
||||||
|
|
||||||
|
containingElement is PsiClass -> jetFileToEdit.add(declaration) as JetNamedDeclaration
|
||||||
|
|
||||||
|
containingElement is JetClassOrObject -> {
|
||||||
var classBody = containingElement.getBody()
|
var classBody = containingElement.getBody()
|
||||||
if (classBody == null) {
|
if (classBody == null) {
|
||||||
classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody
|
classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody
|
||||||
@@ -550,20 +575,6 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
else classBody.addAfter(declaration, classBody!!.getLBrace()!!) as JetNamedDeclaration
|
else classBody.addAfter(declaration, classBody!!.getLBrace()!!) as JetNamedDeclaration
|
||||||
}
|
}
|
||||||
|
|
||||||
is JetBlockExpression -> {
|
|
||||||
val parent = containingElement.getParent()
|
|
||||||
if (parent is JetFunctionLiteral) {
|
|
||||||
if (!parent.isMultiLine()) {
|
|
||||||
parent.addBefore(newLine, containingElement)
|
|
||||||
parent.addAfter(newLine, containingElement)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val sibling = config.originalElement.parents().first { it.getParent() == containingElement }
|
|
||||||
containingElement.addBefore(declaration, sibling) as JetNamedDeclaration
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> throw AssertionError("Invalid containing element: ${containingElement.getText()}")
|
else -> throw AssertionError("Invalid containing element: ${containingElement.getText()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
// "Create class 'Foo'" "true"
|
// "Create class 'Foo'" "true"
|
||||||
|
|
||||||
class A<T>(val n: T) {
|
class A<T>(val n: T) {
|
||||||
|
fun test() = this.Foo(2, "2")
|
||||||
|
|
||||||
inner class Foo(i: Int, s: String) {
|
inner class Foo(i: Int, s: String) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() = this.Foo(2, "2")
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
class A<T>(val n: T) {
|
class A<T>(val n: T) {
|
||||||
inner class B<U>(val m: U) {
|
inner class B<U>(val m: U) {
|
||||||
|
fun test() = this.Foo(2, "2")
|
||||||
|
|
||||||
inner class Foo(i: Int, s: String) {
|
inner class Foo(i: Int, s: String) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test() = this.Foo(2, "2")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-4
@@ -1,11 +1,11 @@
|
|||||||
// "Create class 'Foo'" "true"
|
// "Create class 'Foo'" "true"
|
||||||
|
|
||||||
class A<T>(val n: T) {
|
class A<T>(val n: T) {
|
||||||
inner class Foo(i: Int, s: String) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class B<U>(val m: U) {
|
inner class B<U>(val m: U) {
|
||||||
fun test() = this@A.Foo(2, "2")
|
fun test() = this@A.Foo(2, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner class Foo(i: Int, s: String) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+4
-4
@@ -3,10 +3,10 @@ package p
|
|||||||
|
|
||||||
fun foo(): X = A
|
fun foo(): X = A
|
||||||
|
|
||||||
open class X {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object A : X() {
|
object A : X() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class X {
|
||||||
|
|
||||||
|
}
|
||||||
+4
-4
@@ -3,10 +3,10 @@ package p
|
|||||||
|
|
||||||
fun foo(): X = A
|
fun foo(): X = A
|
||||||
|
|
||||||
trait X {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
object A : X {
|
object A : X {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait X {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val baz = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a: A = foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun foo(): A {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
val baz = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a: Int = foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(): Int {
|
||||||
|
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
class A {
|
||||||
|
val baz = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a: A = <caret>foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// "Create function 'foo'" "true"
|
||||||
|
|
||||||
|
val baz = 1
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a: Int = <caret>foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
// "Create property 'foo'" "true"
|
// "Create property 'foo'" "true"
|
||||||
// ERROR: Property must be initialized
|
// ERROR: Property must be initialized
|
||||||
|
|
||||||
|
val foo: String
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
println("a = $foo")
|
println("a = $foo")
|
||||||
}
|
}
|
||||||
|
|
||||||
val foo: String
|
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
// "Create property 'foo'" "true"
|
// "Create property 'foo'" "true"
|
||||||
// ERROR: Property must be initialized
|
// ERROR: Property must be initialized
|
||||||
|
|
||||||
|
val foo: Int
|
||||||
|
|
||||||
fun test(): Int {
|
fun test(): Int {
|
||||||
return foo
|
return foo
|
||||||
}
|
}
|
||||||
|
|
||||||
val foo: Int
|
|
||||||
|
|||||||
+2
-2
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
package foo
|
package foo
|
||||||
|
|
||||||
|
val foo: Int
|
||||||
|
|
||||||
fun test(): Int {
|
fun test(): Int {
|
||||||
return foo
|
return foo
|
||||||
}
|
}
|
||||||
|
|
||||||
val foo: Int
|
|
||||||
|
|||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
// "Create extension property 'foo'" "true"
|
// "Create extension property 'foo'" "true"
|
||||||
// ERROR: Property must be initialized
|
// ERROR: Property must be initialized
|
||||||
|
|
||||||
|
val Unit.foo: Int
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val a: Int = Unit.foo
|
val a: Int = Unit.foo
|
||||||
}
|
}
|
||||||
|
|
||||||
val Unit.foo: Int
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
class A<T>(val n: T)
|
class A<T>(val n: T)
|
||||||
|
|
||||||
|
val Int.foo: A<Int>
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val a: A<Int> = 2.foo
|
val a: A<Int> = 2.foo
|
||||||
}
|
}
|
||||||
|
|
||||||
val Int.foo: A<Int>
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
class A<T>(val n: T)
|
class A<T>(val n: T)
|
||||||
|
|
||||||
|
var Int.foo: A<String>
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
2.foo = A("2")
|
2.foo = A("2")
|
||||||
}
|
}
|
||||||
|
|
||||||
var Int.foo: A<String>
|
|
||||||
|
|||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
// "Create extension property 'foo'" "true"
|
// "Create extension property 'foo'" "true"
|
||||||
// ERROR: Unresolved reference: foo
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
val A.foo: String?
|
||||||
|
|
||||||
fun test(): String? {
|
fun test(): String? {
|
||||||
return A().foo
|
return A().foo
|
||||||
}
|
}
|
||||||
|
|
||||||
val A.foo: String?
|
|
||||||
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
// "Create extension property 'foo'" "true"
|
// "Create extension property 'foo'" "true"
|
||||||
// ERROR: Unresolved reference: foo
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
val A.foo: String?
|
||||||
|
|
||||||
fun test(): String? {
|
fun test(): String? {
|
||||||
return A().foo
|
return A().foo
|
||||||
}
|
}
|
||||||
|
|
||||||
val A.foo: String?
|
|
||||||
@@ -1680,6 +1680,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeFunPlacement.kt")
|
||||||
|
public void testFunPlacement() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeFunPlacement.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("beforeFunWithExplicitParamNamesOnUserType.kt")
|
@TestMetadata("beforeFunWithExplicitParamNamesOnUserType.kt")
|
||||||
public void testFunWithExplicitParamNamesOnUserType() throws Exception {
|
public void testFunWithExplicitParamNamesOnUserType() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeFunWithExplicitParamNamesOnUserType.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeFunWithExplicitParamNamesOnUserType.kt");
|
||||||
@@ -1806,6 +1812,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("beforeTopLevelFunPlacement.kt")
|
||||||
|
public void testTopLevelFunPlacement() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeTopLevelFunPlacement.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("beforeUnitFun.kt")
|
@TestMetadata("beforeUnitFun.kt")
|
||||||
public void testUnitFun() throws Exception {
|
public void testUnitFun() throws Exception {
|
||||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeUnitFun.kt");
|
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeUnitFun.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user