Create From Usage: Place generated declarations next to original element container if they have common parent

#KT-6687 Fixed
This commit is contained in:
Alexey Sedunov
2015-03-06 18:08:36 +03:00
parent fe9b08f93d
commit ab5a691612
19 changed files with 136 additions and 53 deletions
@@ -529,12 +529,37 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
return Math.max(lineBreaksNeeded - lineBreaksPresent, 0)
}
val declarationInPlace = when (containingElement) {
is JetFile -> containingElement.add(declaration) as JetNamedDeclaration
fun addNextToOriginalElementContainer(addBefore: Boolean): 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()
if (classBody == null) {
classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody
@@ -550,20 +575,6 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
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()}")
}
@@ -1,9 +1,9 @@
// "Create class 'Foo'" "true"
class A<T>(val n: T) {
fun test() = this.Foo(2, "2")
inner class Foo(i: Int, s: String) {
}
fun test() = this.Foo(2, "2")
}
@@ -2,10 +2,10 @@
class A<T>(val n: T) {
inner class B<U>(val m: U) {
fun test() = this.Foo(2, "2")
inner class Foo(i: Int, s: String) {
}
fun test() = this.Foo(2, "2")
}
}
@@ -1,11 +1,11 @@
// "Create class 'Foo'" "true"
class A<T>(val n: T) {
inner class Foo(i: Int, s: String) {
}
inner class B<U>(val m: U) {
fun test() = this@A.Foo(2, "2")
}
inner class Foo(i: Int, s: String) {
}
}
@@ -3,10 +3,10 @@ package p
fun foo(): X = A
open class X {
}
object A : X() {
}
open class X {
}
@@ -3,10 +3,10 @@ package p
fun foo(): X = A
trait 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() {
}
}
@@ -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() {
}
}
@@ -0,0 +1,12 @@
// "Create function 'foo'" "true"
val baz = 1
fun test() {
val a: Int = <caret>foo()
}
fun bar() {
}
@@ -1,8 +1,8 @@
// "Create property 'foo'" "true"
// ERROR: Property must be initialized
val foo: String
fun test() {
println("a = $foo")
}
val foo: String
}
@@ -1,8 +1,8 @@
// "Create property 'foo'" "true"
// ERROR: Property must be initialized
val foo: Int
fun test(): Int {
return foo
}
val foo: Int
@@ -3,8 +3,8 @@
package foo
val foo: Int
fun test(): Int {
return foo
}
val foo: Int
@@ -1,8 +1,8 @@
// "Create extension property 'foo'" "true"
// ERROR: Property must be initialized
val Unit.foo: Int
fun test() {
val a: Int = Unit.foo
}
val Unit.foo: Int
@@ -3,8 +3,8 @@
class A<T>(val n: T)
val Int.foo: A<Int>
fun test() {
val a: A<Int> = 2.foo
}
val Int.foo: A<Int>
@@ -3,8 +3,8 @@
class A<T>(val n: T)
var Int.foo: A<String>
fun test() {
2.foo = A("2")
}
var Int.foo: A<String>
@@ -1,8 +1,8 @@
// "Create extension property 'foo'" "true"
// ERROR: Unresolved reference: foo
val A.foo: String?
fun test(): String? {
return A().foo
}
val A.foo: String?
}
@@ -1,8 +1,8 @@
// "Create extension property 'foo'" "true"
// ERROR: Unresolved reference: foo
val A.foo: String?
fun test(): String? {
return A().foo
}
val A.foo: String?
}
@@ -1680,6 +1680,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
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")
public void testFunWithExplicitParamNamesOnUserType() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeFunWithExplicitParamNamesOnUserType.kt");
@@ -1806,6 +1812,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
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")
public void testUnitFun() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/call/beforeUnitFun.kt");