Create Function From Usage: Add empty lines when inserting new function

This commit is contained in:
Alexey Sedunov
2014-09-26 19:31:12 +04:00
parent afd8809ff5
commit ff29e581db
41 changed files with 90 additions and 36 deletions
@@ -53,6 +53,11 @@ import org.jetbrains.jet.plugin.refactoring.CollectingValidator
import org.jetbrains.jet.plugin.util.isUnit
import org.jetbrains.jet.plugin.refactoring.runWriteAction
import com.intellij.util.ArrayUtil
import com.intellij.psi.PsiWhiteSpace
import org.jetbrains.jet.plugin.refactoring.isMultiLine
import org.jetbrains.jet.plugin.refactoring.getLineCount
import com.intellij.psi.PsiElement
import org.jetbrains.jet.lexer.JetTokens
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
@@ -238,42 +243,54 @@ class FunctionBuilder(val config: FunctionBuilderConfiguration) {
with (config) {
val parametersString = functionInfo.parameterInfos.indices.map { i -> "p$i: Any" }.joinToString(", ")
val returnTypeString = if (isUnit) "" else ": Any"
val ownerTypeString = if (isExtension) "${receiverTypeCandidate!!.renderedType!!}." else ""
val psiFactory = JetPsiFactory(currentFile)
if (isExtension) {
// create as extension function
val ownerTypeString = receiverTypeCandidate!!.renderedType!!
val func = psiFactory.createFunction(
"fun $ownerTypeString.${functionInfo.name}($parametersString)$returnTypeString { }"
)
return currentFile.add(func) as JetNamedFunction
val func = psiFactory.createFunction("fun $ownerTypeString${functionInfo.name}($parametersString)$returnTypeString { }")
val newLine = psiFactory.createNewLine()
fun prepend(element: PsiElement, elementBeforeStart: PsiElement): PsiElement {
val parent = elementBeforeStart.getParent()!!
val anchor = PsiTreeUtil.skipSiblingsForward(elementBeforeStart, javaClass<PsiWhiteSpace>())
val addedElement = parent.addBefore(element, anchor)!!
parent.addAfter(newLine, addedElement)
parent.addAfter(newLine, addedElement)
return addedElement
}
else {
// create as regular function
val func = psiFactory.createFunction("fun ${functionInfo.name}($parametersString)$returnTypeString { }")
when (containingElement) {
is JetFile -> {
return currentFile.add(func) as JetNamedFunction
}
is JetClassOrObject -> {
var classBody = containingElement.getBody()
if (classBody == null) {
classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody
containingElement.addBefore(psiFactory.createWhiteSpace(), classBody)
fun append(element: PsiElement, elementAfterEnd: PsiElement, skipInitial: Boolean): PsiElement {
val parent = elementAfterEnd.getParent()!!
val anchor =
if (!skipInitial && elementAfterEnd !is PsiWhiteSpace) {
elementAfterEnd
}
val rBrace = classBody!!.getRBrace()
//TODO: Assert rbrace not null? It can be if the class isn't closed.
return classBody!!.addBefore(func, rBrace) as JetNamedFunction
}
is JetBlockExpression -> {
return containingElement.addAfter(func, containingElement.getLBrace()) as JetNamedFunction
}
else -> throw AssertionError("Invalid containing element: ${containingElement.getText()}")
else {
PsiTreeUtil.skipSiblingsBackward(elementAfterEnd, javaClass<PsiWhiteSpace>())
}
val addedElement = parent.addAfter(element, anchor)!!
if (anchor?.getNode()?.getElementType() != JetTokens.LBRACE) {
parent.addAfter(newLine, anchor)
parent.addAfter(newLine, anchor)
}
return addedElement
}
when (containingElement) {
is JetFile -> return append(func, containingElement.getLastChild()!!, false) as JetNamedFunction
is JetClassOrObject -> {
var classBody = containingElement.getBody()
if (classBody == null) {
classBody = containingElement.add(psiFactory.createEmptyClassBody()) as JetClassBody
containingElement.addBefore(psiFactory.createWhiteSpace(), classBody)
}
val rBrace = classBody!!.getRBrace()
return (rBrace?.let { append(func, it, true) }
?: append(func, classBody!!.getLastChild()!!, false)) as JetNamedFunction
}
is JetBlockExpression -> return prepend(func, containingElement.getLBrace()!!) as JetNamedFunction
else -> throw AssertionError("Invalid containing element: ${containingElement.getText()}")
}
}
}
@@ -2,6 +2,7 @@
class A<T>(val n: T) {
fun plus(): A<T> = throw Exception()
fun plus(arg: T): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -2,6 +2,7 @@
class A<T>(val n: T) {
fun plus(i: Int, s: String): A<T> = throw Exception()
fun plus(arg: T): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class A<T>(val n: T)
fun test() {
val a: A<Int> = 2 + A(1)
}
fun Int.plus(A: A<Int>): A<Int> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -1,10 +1,10 @@
// "Create function 'foo' from usage" "true"
class A<T>(val n: T) {
fun foo(arg: T, s: String, function: Function1<T, T>): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
fun test() {
@@ -1,10 +1,10 @@
// "Create function 'foo' from usage" "true"
class A<T>(val n: T) {
fun foo(function: Function1<T, T>): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
fun test() {
@@ -2,6 +2,7 @@
class A<T>(val n: T) {
fun foo(a: Int): A<T> = throw Exception()
fun foo(arg: T, s: String): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -2,6 +2,7 @@
class A<T>(val n: T) {
fun foo(i: Int, s: String): A<T> = throw Exception()
fun foo(arg: T): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -2,10 +2,10 @@
class A<T>(val n: T) {
class object {
fun foo(i: Int): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
}
@@ -3,6 +3,7 @@
fun test() {
val a: Int = Unit.foo(2)
}
fun Unit.foo(i: Int): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class A<T>(val n: T)
fun test() {
val a: A<Int> = 2.foo(A(1))
}
fun Int.foo(A: A<Int>): A<Int> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -4,6 +4,7 @@ fun test() {
fun foo(i: Int, s: String): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
fun nestedTest(): Int {
return foo(2, "2")
}
@@ -5,6 +5,7 @@ class A {
fun test(): Int {
return foo(2, "2")
}
fun foo(i: Int, s: String): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class A {
fun test(): Int {
return foo(2, "2")
}
fun foo(i: Int, s: String): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -4,6 +4,7 @@ class A<T>(val n: T) {
fun test(): A<Int> {
return this.foo(2, "2")
}
fun foo(i: Int, s: String): A<Int> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class A<T>(val n: T) {
fun test(): A<Int> {
return this.foo(2, "2")
}
fun foo(i: Int, s: String): A<Int> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -6,6 +6,7 @@ class A<T>(val n: T) {
return this@A.foo(2, "2")
}
}
fun foo(i: Int, s: String): A<Int> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@
fun test(): Int {
return foo(2, "2")
}
fun foo(i: Int, s: String): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -2,6 +2,7 @@
class Foo<T> {
fun component1(): Int { return 0 }
fun component2(): Int { return 0 }
fun component3(): Any {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -2,6 +2,7 @@
class Foo<T> {
fun component1(): Int { return 0 }
fun component2(): Int { return 0 }
fun component3(): String {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -16,6 +16,7 @@ fun Any.component1(): Int {
fun foo() {
for ((i: Int, j: Int) in Foo<Int>()) { }
}
fun Any.component2(): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@ class Foo<T> {
fun x (y: Foo<Iterable<T>>) {
val z: Iterable<T> = y[""]
}
fun get(s: String): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@ class Foo<T> {
fun <T> x (y: Foo<List<T>>, w: java.util.ArrayList<T>) {
val z: Iterable<T> = y["", w]
}
fun get(s: String, w: T): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -7,6 +7,7 @@ class Foo<T> {
val z = y["", w]
bar(z)
}
fun <V> get(s: String, w: ArrayList<V>): String {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -2,6 +2,7 @@
fun x (y: Any) {
val z: Any = y[""]
}
fun Any.get(s: String): Any {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
@@ -3,6 +3,7 @@ class Foo<T> {
fun <S> x (y: Foo<Iterable<S>>) {
val z: Iterable<S> = y[""]
}
fun get(s: String): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@ class Foo<T, S: Iterable<T>> {
fun <U> x (y: Foo<U, Iterable<U>>) {
val z: U = y[""]
}
fun get(s: String): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@ class Foo<T> {
fun <T, V> x (y: Foo<Iterable<T>>, w: Iterable<V>) {
val z: Iterable<T> = y["", w]
}
fun <V> get(s: String, w: Iterable<V>): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class Foo<T> {
fun <T, V> x (y: Foo<List<T>>, w: ArrayList<V>, v: T) {
val z: Iterable<T> = y["", w, v]
}
fun <V, T1> get(s: String, w: ArrayList<V>, v: T1): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class Foo<T> {
fun x (y: Foo<List<T>>, w: ArrayList<T>) {
val z: Iterable<T> = y["", w]
}
fun get(s: String, w: T): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class Foo<S> {
fun <T> x (y: Foo<List<T>>, w: ArrayList<T>) {
val z: Iterable<T> = y["", w]
}
fun get(s: String, w: S): S {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@ class FooIterator<T> {
fun next(): Int {
throw Exception("not implemented")
}
fun hasNext(): Boolean {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@ class FooIterator<T> {
fun next(): T {
throw Exception("not implemented")
}
fun hasNext(): Boolean {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -5,6 +5,7 @@ class A<T>(val n: T)
fun test(): A<String> {
return 1(2, "2")
}
fun Int.invoke(i: Int, s: String): A<String> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -1,6 +1,7 @@
// "Create function 'next' from usage" "true"
class FooIterator<T> {
fun hasNext(): Boolean { return false }
fun next(): Any {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -1,6 +1,7 @@
// "Create function 'next' from usage" "true"
class FooIterator<T> {
fun hasNext(): Boolean { return false }
fun next(): Int {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -1,6 +1,7 @@
// "Create function 'next' from usage" "true"
class FooIterator<T> {
fun hasNext(): Boolean { return false }
fun next(): T {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@ class Foo<T> {
fun <T> x (y: Foo<List<T>>, w: java.util.ArrayList<T>) {
y["", w] = w
}
fun set(s: String, w: T, value: T) {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -6,6 +6,7 @@ class Foo<T> {
y["", w] = w
}
}
fun <T> Any.set(s: String, w: ArrayList<T>, value: ArrayList<T>) {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
}
@@ -2,6 +2,7 @@
class A<T>(val n: T) {
fun minus(n: Int): A<T> = throw Exception()
fun minus(): A<T> {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}
@@ -3,6 +3,7 @@
fun test() {
val a = -false
}
fun Boolean.minus(): Any {
throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.
}