Replace with for-each: add new-lines using comment saver

Related to KT-15858
This commit is contained in:
Mikhail Glukhikh
2018-02-28 11:25:29 +03:00
parent 7f880bf58c
commit bec28c8388
10 changed files with 27 additions and 25 deletions
@@ -17,11 +17,8 @@
package org.jetbrains.kotlin.idea.intentions package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.refactoring.getLineNumber
import org.jetbrains.kotlin.idea.util.CommentSaver import org.jetbrains.kotlin.idea.util.CommentSaver
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.contentRange import org.jetbrains.kotlin.psi.psiUtil.contentRange
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -40,20 +37,18 @@ class ConvertToForEachFunctionCallIntention : SelfTargetingIntention<KtForExpres
} }
override fun applyTo(element: KtForExpression, editor: Editor?) { override fun applyTo(element: KtForExpression, editor: Editor?) {
val commentSaver = CommentSaver(element) val commentSaver = CommentSaver(element, saveLineBreaks = true)
val labelName = element.getLabelName() val labelName = element.getLabelName()
val body = element.body!! val body = element.body!!
val loopParameter = element.loopParameter!! val loopParameter = element.loopParameter!!
val blockExpression = body as? KtBlockExpression val functionBodyArgument: Any = (body as? KtBlockExpression)?.contentRange() ?: body
val functionBodyArgument: Any = blockExpression?.contentRange() ?: body
val pattern = if (needLineBreaks(blockExpression)) "$0.forEach{$1->\n$2\n}" else "$0.forEach{$1->$2}"
val psiFactory = KtPsiFactory(element) val psiFactory = KtPsiFactory(element)
val foreachExpression = psiFactory.createExpressionByPattern( val foreachExpression = psiFactory.createExpressionByPattern(
pattern, element.loopRange!!, loopParameter, functionBodyArgument "$0.forEach{$1->\n$2}", element.loopRange!!, loopParameter, functionBodyArgument
) )
val result = element.replace(foreachExpression) as KtElement val result = element.replace(foreachExpression) as KtElement
@@ -64,14 +59,6 @@ class ConvertToForEachFunctionCallIntention : SelfTargetingIntention<KtForExpres
commentSaver.restore(result) commentSaver.restore(result)
} }
private fun needLineBreaks(blockExpression: KtBlockExpression?): Boolean {
val contentRange = blockExpression?.contentRange() ?: return false
if ((contentRange.last as? PsiComment)?.tokenType != KtTokens.EOL_COMMENT) return false
val statements = blockExpression.statements
val fistStatementLine = statements.firstOrNull()?.getLineNumber()
return statements.all { it.getLineNumber() == fistStatementLine }
}
private fun KtElement.getContinuesWithLabel(labelName: String?): List<KtContinueExpression> { private fun KtElement.getContinuesWithLabel(labelName: String?): List<KtContinueExpression> {
val continueElements = ArrayList<KtContinueExpression>() val continueElements = ArrayList<KtContinueExpression>()
@@ -1,4 +1,6 @@
// WITH_RUNTIME // WITH_RUNTIME
fun main() { fun main() {
1.rangeTo(2).forEach { x -> x } 1.rangeTo(2).forEach { x ->
x
}
} }
@@ -2,5 +2,7 @@
fun foo() {} fun foo() {}
fun test() { fun test() {
listOf(1, 2).forEach { l -> /* comment */ } listOf(1, 2).forEach { l ->
/* comment */
}
} }
@@ -1,4 +1,5 @@
// WITH_RUNTIME // WITH_RUNTIME
fun foo() { fun foo() {
(1..10/* from 1 to 10 */).forEach { x /* current */ -> } (1..10/* from 1 to 10 */).forEach { x /* current */ ->
}
} }
@@ -1,4 +1,5 @@
// WITH_RUNTIME // WITH_RUNTIME
fun foo() { fun foo() {
(1..10).forEach { x -> } (1..10).forEach { x ->
}
} }
@@ -2,5 +2,7 @@
fun main() { fun main() {
val list = 1..4 val list = 1..4
list.forEach { x: Int -> x } list.forEach { x: Int ->
x
}
} }
@@ -3,6 +3,8 @@ fun foo() {
val list = 1..4 val list = 1..4
val i = 0 val i = 0
list.forEach { i -> i } list.forEach { i ->
i
}
i i
} }
@@ -2,5 +2,6 @@
fun foo() { fun foo() {
val list = 1..4 val list = 1..4
list.forEach { i -> } list.forEach { i ->
}
} }
@@ -2,5 +2,7 @@
fun foo() { fun foo() {
val list = 1..4 val list = 1..4
list.forEach { x -> x } list.forEach { x ->
x
}
} }
@@ -2,5 +2,7 @@
fun main() { fun main() {
val list = 1..4 val list = 1..4
list.forEach { x: Int -> 11 } list.forEach { x: Int ->
11
}
} }