Line breaks in objects and lambdas don't trigger call paren wrapping

#KT-19727 Fixed
This commit is contained in:
Dmitry Jemerov
2017-12-20 15:20:43 +01:00
parent 79a509df7b
commit 06fa61bb6f
5 changed files with 80 additions and 4 deletions
@@ -702,7 +702,7 @@ private val INDENT_RULES = arrayOf<NodeIndentStrategy>(
private fun getOperationType(node: ASTNode): IElementType? = node.findChildByType(KtNodeTypes.OPERATION_REFERENCE)?.firstChildNode?.elementType
private fun hasErrorElementBefore(node: ASTNode): Boolean {
fun hasErrorElementBefore(node: ASTNode): Boolean {
val prevSibling = getPrevWithoutWhitespace(node) ?: return false
if (prevSibling.elementType == TokenType.ERROR_ELEMENT) return true
val lastChild = TreeUtil.getLastChild(prevSibling)
@@ -28,6 +28,7 @@ import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.codeStyle.CodeStyleSettings
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import com.intellij.util.text.TextRangeUtil
import org.jetbrains.kotlin.KtNodeTypes.*
import org.jetbrains.kotlin.idea.formatter.KotlinSpacingBuilder.CustomSpacingBuilder
import org.jetbrains.kotlin.lexer.KtTokens
@@ -162,7 +163,7 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing
inPosition(parent = VALUE_ARGUMENT_LIST, left = LPAR).customRule { parent, _, _ ->
if (kotlinCommonSettings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE && needWrapArgumentList(parent.node.psi)) {
Spacing.createDependentLFSpacing(0, 0,
parent.textRange,
excludeLambdasAndObjects(parent),
commonCodeStyleSettings.KEEP_LINE_BREAKS,
commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE)
}
@@ -170,6 +171,20 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing
createSpacing(0)
}
}
inPosition(parent = VALUE_ARGUMENT_LIST, right = RPAR).customRule { parent, left, _ ->
if (kotlinCommonSettings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE) {
Spacing.createDependentLFSpacing(0, 0,
excludeLambdasAndObjects(parent),
commonCodeStyleSettings.KEEP_LINE_BREAKS,
commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE)
} else if (left.node.elementType == KtTokens.COMMA) {
// incomplete call being edited
createSpacing(1)
} else {
createSpacing(0)
}
}
}
simple {
@@ -288,7 +303,6 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing
beforeInside(RPAR, VALUE_PARAMETER_LIST).spaces(0, kotlinCommonSettings.METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE)
afterInside(LT, TYPE_PARAMETER_LIST).spaces(0)
beforeInside(GT, TYPE_PARAMETER_LIST).spaces(0)
beforeInside(RPAR, VALUE_ARGUMENT_LIST).spaces(0, kotlinCommonSettings.CALL_PARAMETERS_RPAREN_ON_NEXT_LINE)
afterInside(LT, TYPE_ARGUMENT_LIST).spaces(0)
beforeInside(GT, TYPE_ARGUMENT_LIST).spaces(0)
before(TYPE_ARGUMENT_LIST).spaces(0)
@@ -550,4 +564,20 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing
after(EOL_COMMENT).lineBreakInCode()
}
}
}
}
private fun excludeLambdasAndObjects(parent: ASTBlock): List<TextRange> {
val rangesToExclude = mutableListOf<TextRange>()
parent.node.psi.accept(object : KtTreeVisitorVoid() {
override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) {
super.visitLambdaExpression(lambdaExpression)
rangesToExclude.add(lambdaExpression.textRange)
}
override fun visitObjectLiteralExpression(expression: KtObjectLiteralExpression) {
super.visitObjectLiteralExpression(expression)
rangesToExclude.add(expression.textRange)
}
})
return TextRangeUtil.excludeRanges(parent.textRange, rangesToExclude).toList()
}
+20
View File
@@ -0,0 +1,20 @@
fun useCallable(tag: String, callable: Callable<*>) {
}
fun main(args: Array<String>) {
useCallable("A", Callable { println("Hello world") })
useCallable("B", Callable {
println("Hello world")
})
useCallable("C", object : Callable<Unit> {
override fun call() {
println("Hello world")
}
})
}
// SET_TRUE: CALL_PARAMETERS_LPAREN_ON_NEXT_LINE
// SET_TRUE: CALL_PARAMETERS_RPAREN_ON_NEXT_LINE
+20
View File
@@ -0,0 +1,20 @@
fun useCallable(tag: String, callable: Callable<*>) {
}
fun main(args: Array<String>) {
useCallable("A", Callable { println("Hello world") })
useCallable("B", Callable {
println("Hello world")
})
useCallable("C", object : Callable<Unit> {
override fun call() {
println("Hello world")
}
})
}
// SET_TRUE: CALL_PARAMETERS_LPAREN_ON_NEXT_LINE
// SET_TRUE: CALL_PARAMETERS_RPAREN_ON_NEXT_LINE
@@ -1138,6 +1138,12 @@ public class FormatterTestGenerated extends AbstractFormatterTest {
doTest(fileName);
}
@TestMetadata("KT19727.after.kt")
public void testKT19727() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/formatter/parameterList/KT19727.after.kt");
doTest(fileName);
}
@TestMetadata("ParameterListChopAsNeeded.after.kt")
public void testParameterListChopAsNeeded() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/formatter/parameterList/ParameterListChopAsNeeded.after.kt");