diff --git a/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCommonBlock.kt b/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCommonBlock.kt index fccbb99d772..c5aba0da1a1 100644 --- a/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCommonBlock.kt +++ b/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCommonBlock.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.formatter import com.intellij.formatting.* import com.intellij.lang.ASTNode +import com.intellij.psi.PsiElement import com.intellij.psi.TokenType import com.intellij.psi.codeStyle.CodeStyleSettings import com.intellij.psi.codeStyle.CommonCodeStyleSettings @@ -370,8 +371,15 @@ abstract class KotlinCommonBlock( val nodePsi = node.psi when { - elementType === KtNodeTypes.VALUE_ARGUMENT_LIST -> - return getWrappingStrategyForItemList(commonSettings.CALL_PARAMETERS_WRAP, KtNodeTypes.VALUE_ARGUMENT) + elementType === KtNodeTypes.VALUE_ARGUMENT_LIST -> { + val wrapSetting = commonSettings.CALL_PARAMETERS_WRAP + if ((wrapSetting == CommonCodeStyleSettings.WRAP_AS_NEEDED || wrapSetting == CommonCodeStyleSettings.WRAP_ON_EVERY_ITEM) && + !needWrapArgumentList(nodePsi) + ) { + return WrappingStrategy.NoWrapping + } + return getWrappingStrategyForItemList(wrapSetting, KtNodeTypes.VALUE_ARGUMENT) + } elementType === KtNodeTypes.VALUE_PARAMETER_LIST -> { if (parentElementType === KtNodeTypes.FUN || @@ -512,6 +520,11 @@ private fun getWrapAfterAnnotation(childElement: ASTNode, wrapType: Int): Wrap? return null } +fun needWrapArgumentList(psi: PsiElement): Boolean { + val args = (psi as? KtValueArgumentList)?.arguments + return args?.singleOrNull()?.getArgumentExpression() !is KtObjectLiteralExpression +} + private val INDENT_RULES = arrayOf( strategy("No indent for braces in blocks") .within(KtNodeTypes.BLOCK, KtNodeTypes.CLASS_BODY, KtNodeTypes.FUNCTION_LITERAL) diff --git a/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt b/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt index c5f7abc62c9..c27c3246d72 100644 --- a/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt +++ b/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/kotlinSpacingRules.kt @@ -159,6 +159,17 @@ fun createSpacingBuilder(settings: CodeStyleSettings, builderUtil: KotlinSpacing false, 0) } + 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, + commonCodeStyleSettings.KEEP_LINE_BREAKS, + commonCodeStyleSettings.KEEP_BLANK_LINES_IN_CODE) + } + else { + createSpacing(0) + } + } } simple { @@ -277,7 +288,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) - afterInside(LPAR, VALUE_ARGUMENT_LIST).spaces(0, kotlinCommonSettings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE) 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) diff --git a/idea/testData/formatter/parameterList/ArgumentListWrapLParen.after.kt b/idea/testData/formatter/parameterList/ArgumentListWrapLParen.after.kt new file mode 100644 index 00000000000..2b60cd24df6 --- /dev/null +++ b/idea/testData/formatter/parameterList/ArgumentListWrapLParen.after.kt @@ -0,0 +1,11 @@ +// SET_INT: CALL_PARAMETERS_WRAP = 4 +// SET_TRUE: CALL_PARAMETERS_LPAREN_ON_NEXT_LINE + +fun foo() { + foo(bar, baz) + + foo(object : Quux { + override fun foo() { + } + }) +} diff --git a/idea/testData/formatter/parameterList/ArgumentListWrapLParen.kt b/idea/testData/formatter/parameterList/ArgumentListWrapLParen.kt new file mode 100644 index 00000000000..2b60cd24df6 --- /dev/null +++ b/idea/testData/formatter/parameterList/ArgumentListWrapLParen.kt @@ -0,0 +1,11 @@ +// SET_INT: CALL_PARAMETERS_WRAP = 4 +// SET_TRUE: CALL_PARAMETERS_LPAREN_ON_NEXT_LINE + +fun foo() { + foo(bar, baz) + + foo(object : Quux { + override fun foo() { + } + }) +} diff --git a/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java b/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java index 809d0182f59..45bf0d032d5 100644 --- a/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java @@ -1126,6 +1126,12 @@ public class FormatterTestGenerated extends AbstractFormatterTest { doTest(fileName); } + @TestMetadata("ArgumentListWrapLParen.after.kt") + public void testArgumentListWrapLParen() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/formatter/parameterList/ArgumentListWrapLParen.after.kt"); + doTest(fileName); + } + @TestMetadata("ParameterListChopAsNeeded.after.kt") public void testParameterListChopAsNeeded() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/formatter/parameterList/ParameterListChopAsNeeded.after.kt");