diff --git a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java index 5a85a68ab396..78c2b78ff8d6 100644 --- a/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java +++ b/java/java-impl/src/com/intellij/ide/JavaLanguageCodeStyleSettingsProvider.java @@ -153,7 +153,8 @@ public class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSett "INDENT_CASE_FROM_SWITCH", "SPECIAL_ELSE_IF_TREATMENT", "ENUM_CONSTANTS_WRAP", - "ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS"); + "ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS", + "WRAP_FIRST_METHOD_IN_CALL_CHAIN"); consumer.showCustomOption(JavaCodeStyleSettings.class, "ANNOTATION_PARAMETER_WRAP", diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/ChainMethodCallsBlockBuilder.java b/java/java-impl/src/com/intellij/psi/formatter/java/ChainMethodCallsBlockBuilder.java index 495629831d96..962cdc8a9f78 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/ChainMethodCallsBlockBuilder.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/ChainMethodCallsBlockBuilder.java @@ -58,9 +58,6 @@ class ChainMethodCallsBlockBuilder { } public Block build(List nodes) { - myWrap = getNewWrap(); - myChainedCallsAlignment = getNewAlignment(); - List blocks = buildBlocksFrom(nodes); Indent indent = myBlockIndent != null ? myBlockIndent : Indent.getContinuationWithoutFirstIndent(myIndentSettings.USE_RELATIVE_INDENTS); @@ -69,6 +66,10 @@ class ChainMethodCallsBlockBuilder { private List buildBlocksFrom(List nodes) { List methodCall = splitMethodCallOnChunksByDots(nodes); + + myWrap = getNewWrap(mySettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN); + myChainedCallsAlignment = getNewAlignment(); + Wrap wrapToUse = null; Alignment alignmentToUse = null; @@ -84,7 +85,7 @@ class ChainMethodCallsBlockBuilder { alignmentToUse = null; myChainedCallsAlignment = getNewAlignment(); - myWrap = getNewWrap(); + myWrap = getNewWrap(mySettings.WRAP_FIRST_METHOD_IN_CALL_CHAIN); } SyntheticBlockBuilder builder = new SyntheticBlockBuilder(mySettings, myJavaSettings); @@ -125,8 +126,8 @@ class ChainMethodCallsBlockBuilder { return AbstractJavaBlock.createAlignment(mySettings.ALIGN_MULTILINE_CHAINED_METHODS, null); } - private Wrap getNewWrap() { - return Wrap.createWrap(getWrapType(mySettings.METHOD_CALL_CHAIN_WRAP), false); + private Wrap getNewWrap(boolean wrapFirst) { + return Wrap.createWrap(getWrapType(mySettings.METHOD_CALL_CHAIN_WRAP), wrapFirst); } private boolean isMethodCall(@NotNull ChainedCallChunk callChunk) { diff --git a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java index b9cc25df0037..87c9f2648d9a 100644 --- a/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/formatter/java/JavaFormatterWrapTest.java @@ -590,5 +590,33 @@ public class JavaFormatterWrapTest extends AbstractJavaFormatterTest { } + public void test_ChainedCalls_FirstOnNewLine() { + getSettings().METHOD_CALL_CHAIN_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS; + getSettings().WRAP_FIRST_METHOD_IN_CALL_CHAIN = true; + doMethodTest( + "obj.call().call().call().call();", + "obj\n" + + " .call()\n" + + " .call()\n" + + " .call()\n" + + " .call();" + ); + + doMethodTest( + "call().call().call().call();", + "call()\n" + + " .call()\n" + + " .call()\n" + + " .call();" + ); + + doMethodTest( + "nestedCall(call().call().call().call());", + "nestedCall(call()\n" + + " .call()\n" + + " .call()\n" + + " .call());" + ); + } } diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java index 0f52d23a5c14..5ddf99d92b58 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsCustomizable.java @@ -167,6 +167,7 @@ public interface CodeStyleSettingsCustomizable { PARAMETER_ANNOTATION_WRAP, VARIABLE_ANNOTATION_WRAP, ALIGN_MULTILINE_CHAINED_METHODS, + WRAP_FIRST_METHOD_IN_CALL_CHAIN, ALIGN_MULTILINE_PARAMETERS, ALIGN_MULTILINE_PARAMETERS_IN_CALLS, ALIGN_MULTILINE_RESOURCES, diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java index f1d9da5f7460..6c01003b365d 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CommonCodeStyleSettings.java @@ -812,6 +812,7 @@ public class CommonCodeStyleSettings { public int THROWS_KEYWORD_WRAP = DO_NOT_WRAP; public int METHOD_CALL_CHAIN_WRAP = DO_NOT_WRAP; + public boolean WRAP_FIRST_METHOD_IN_CALL_CHAIN = false; public boolean PARENTHESES_EXPRESSION_LPAREN_WRAP = false; public boolean PARENTHESES_EXPRESSION_RPAREN_WRAP = false; diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java index d25c6f964e2a..098bd5b5f7aa 100644 --- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java +++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/WrappingAndBracesPanel.java @@ -101,6 +101,7 @@ public class WrappingAndBracesPanel extends OptionTableWithPreviewPanel { addOption("ALIGN_MULTILINE_METHOD_BRACKETS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_METHOD_PARENTHESES); addOption("METHOD_CALL_CHAIN_WRAP", WRAPPING_CALL_CHAIN, WRAP_OPTIONS, WRAP_VALUES); + addOption("WRAP_FIRST_METHOD_IN_CALL_CHAIN", ApplicationBundle.message("wrapping.chained.method.call.first.on.new.line"), WRAPPING_CALL_CHAIN); addOption("ALIGN_MULTILINE_CHAINED_METHODS", ApplicationBundle.message("wrapping.align.when.multiline"), WRAPPING_CALL_CHAIN); addOption("IF_BRACE_FORCE", ApplicationBundle.message("wrapping.force.braces"), WRAPPING_IF_STATEMENT, BRACE_OPTIONS, BRACE_VALUES); diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 37550debb168..42de805294e4 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -181,6 +181,7 @@ wrapping.force.braces=Force braces wrapping.method.parameters=Method declaration parameters wrapping.method.arguments=Method call arguments wrapping.chained.method.calls=Chained method calls +wrapping.chained.method.call.first.on.new.line=Wrap first call wrapping.for.statement='for()' statement wrapping.if.statement='if()' statement wrapping.while.statement='while()' statement