diff --git a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java index 2bf3182d09b9..b9d0fef75932 100644 --- a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java +++ b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/AbstractJavaBlock.java @@ -555,10 +555,11 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo else if (childType == JavaTokenType.LBRACE && nodeType == JavaElementType.ANNOTATION_ARRAY_INITIALIZER) { final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.ARRAY_INITIALIZER_WRAP), false); child = processParenthesisBlock(JavaTokenType.LBRACE, JavaTokenType.RBRACE, - result, - child, - WrappingStrategy.createDoNotWrapCommaStrategy(wrap), - mySettings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION); + result, + child, + WrappingStrategy.createDoNotWrapCommaStrategy(wrap), + mySettings.ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION, + JavaTokenType.COMMA); } else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.EXPRESSION_LIST) { final Wrap wrap = Wrap.createWrap(getWrapType(mySettings.CALL_PARAMETERS_WRAP), false); @@ -566,8 +567,9 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo wrap.ignoreParentWraps(); } child = processParenthesisBlock(result, child, - WrappingStrategy.createDoNotWrapCommaStrategy(wrap), - mySettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS); + WrappingStrategy.createDoNotWrapCommaAndCommentStrategy(wrap), + mySettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS, + JavaTokenType.COMMA, JavaTokenType.END_OF_LINE_COMMENT, JavaTokenType.C_STYLE_COMMENT); } else if (childType == JavaTokenType.LPARENTH && nodeType == JavaElementType.PARAMETER_LIST) { ASTNode parent = myNode.getTreeParent(); @@ -945,12 +947,20 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo @NotNull ASTNode child, @NotNull WrappingStrategy wrappingStrategy, final boolean doAlign) { + return processParenthesisBlock(result, child, wrappingStrategy, doAlign, JavaTokenType.COMMA); + } + + private @NotNull ASTNode processParenthesisBlock(@NotNull List result, + @NotNull ASTNode child, + @NotNull WrappingStrategy wrappingStrategy, + final boolean doAlign, + IElementType @NotNull ... ignoreAlignmentTypes) { myUseChildAttributes = true; final IElementType from = JavaTokenType.LPARENTH; final IElementType to = JavaTokenType.RPARENTH; - return processParenthesisBlock(from, to, result, child, wrappingStrategy, doAlign); + return processParenthesisBlock(from, to, result, child, wrappingStrategy, doAlign, ignoreAlignmentTypes); } private @NotNull ASTNode processParenthesisBlock(@NotNull IElementType from, @@ -958,7 +968,8 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo final @NotNull List result, @NotNull ASTNode child, final @NotNull WrappingStrategy wrappingStrategy, - final boolean doAlign) + final boolean doAlign, + IElementType @NotNull ... ignoreAlignmentTypes) { Indent externalIndent = Indent.getNoneIndent(); Indent internalIndent = Indent.getContinuationWithoutFirstIndent(false); @@ -967,7 +978,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo internalIndent = Indent.getSmartIndent(Indent.Type.CONTINUATION); } - AlignmentStrategy alignmentStrategy = AlignmentStrategy.wrap(createAlignment(doAlign, null), JavaTokenType.COMMA); + AlignmentStrategy alignmentStrategy = AlignmentStrategy.wrap(createAlignment(doAlign, null), ignoreAlignmentTypes); setChildIndent(internalIndent); setChildAlignment(alignmentStrategy.getAlignment(null)); boolean methodParametersBlock = true; diff --git a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/WrappingStrategy.java b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/WrappingStrategy.java index 66211f5c755a..863821f281ca 100644 --- a/java/java-frontback-impl/src/com/intellij/psi/formatter/java/WrappingStrategy.java +++ b/java/java-frontback-impl/src/com/intellij/psi/formatter/java/WrappingStrategy.java @@ -19,8 +19,11 @@ import com.intellij.formatting.Wrap; import com.intellij.psi.JavaTokenType; import com.intellij.psi.tree.IElementType; -public abstract class WrappingStrategy { +import java.util.Set; +public abstract class WrappingStrategy { + private static final Set COMMA_TOKENS = Set.of(JavaTokenType.COMMA, JavaTokenType.SEMICOLON); + private static final Set COMMENT_TOKENS = Set.of(JavaTokenType.END_OF_LINE_COMMENT, JavaTokenType.C_STYLE_COMMENT); public static final WrappingStrategy DO_NOT_WRAP = new WrappingStrategy(null) { @Override protected boolean shouldWrap(final IElementType type) { @@ -32,7 +35,19 @@ public abstract class WrappingStrategy { return new WrappingStrategy(wrap) { @Override protected boolean shouldWrap(final IElementType type) { - return type != JavaTokenType.COMMA && type != JavaTokenType.SEMICOLON; + return !COMMA_TOKENS.contains(type); + } + }; + } + + /** + * @return strategy that doesn't wrap blocks if they are commas or plain comments (excluding javadoc) + */ + public static WrappingStrategy createDoNotWrapCommaAndCommentStrategy(Wrap wrap) { + return new WrappingStrategy(wrap) { + @Override + protected boolean shouldWrap(final IElementType type) { + return !COMMA_TOKENS.contains(type) && !COMMENT_TOKENS.contains(type); } }; } diff --git a/java/java-tests/testData/psi/formatter/java/comments/CStyleCommentWithMethodArgumentsAlignment.java b/java/java-tests/testData/psi/formatter/java/comments/CStyleCommentWithMethodArgumentsAlignment.java new file mode 100644 index 000000000000..b7362f0c7a47 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/comments/CStyleCommentWithMethodArgumentsAlignment.java @@ -0,0 +1,14 @@ +class A { + void veryLongMethodName(String... strings) { + veryLongMethodName( /* some comment */ + "name", /* same line comment */ + /* another comment */ + "second name" /* final comment */ + ); + + veryLongMethodName( /* some comment */ + "name", /* same line comment */ + /* another comment */ + "second name" /* final comment */); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/java/comments/CStyleCommentWithMethodArgumentsAlignment_after.java b/java/java-tests/testData/psi/formatter/java/comments/CStyleCommentWithMethodArgumentsAlignment_after.java new file mode 100644 index 000000000000..c8f519926472 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/comments/CStyleCommentWithMethodArgumentsAlignment_after.java @@ -0,0 +1,14 @@ +class A { + void veryLongMethodName(String... strings) { + veryLongMethodName( /* some comment */ + "name", /* same line comment */ + /* another comment */ + "second name" /* final comment */ + ); + + veryLongMethodName( /* some comment */ + "name", /* same line comment */ + /* another comment */ + "second name" /* final comment */); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/java/comments/EndOfLineCommentWithMethodArgumentsAlignment.java b/java/java-tests/testData/psi/formatter/java/comments/EndOfLineCommentWithMethodArgumentsAlignment.java new file mode 100644 index 000000000000..e47128a833b2 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/comments/EndOfLineCommentWithMethodArgumentsAlignment.java @@ -0,0 +1,9 @@ +class A { + void veryLongMethodName(String... strings) { + veryLongMethodName( // some comment + "name", // same line comment + // another comment + "second name" // final comment + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/formatter/java/comments/EndOfLineCommentWithMethodArgumentsAlignment_after.java b/java/java-tests/testData/psi/formatter/java/comments/EndOfLineCommentWithMethodArgumentsAlignment_after.java new file mode 100644 index 000000000000..6914c6469de3 --- /dev/null +++ b/java/java-tests/testData/psi/formatter/java/comments/EndOfLineCommentWithMethodArgumentsAlignment_after.java @@ -0,0 +1,9 @@ +class A { + void veryLongMethodName(String... strings) { + veryLongMethodName( // some comment + "name", // same line comment + // another comment + "second name" // final comment + ); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/psi/formatter/java/JavaFormatterCommentsTest.kt b/java/java-tests/testSrc/com/intellij/java/psi/formatter/java/JavaFormatterCommentsTest.kt new file mode 100644 index 000000000000..65b4cd1e9ba4 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/java/psi/formatter/java/JavaFormatterCommentsTest.kt @@ -0,0 +1,18 @@ +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package com.intellij.java.psi.formatter.java + +class JavaFormatterCommentsTest: JavaFormatterIdempotencyTestCase() { + override fun getBasePath(): String { + return "psi/formatter/java/comments" + } + + fun testEndOfLineCommentWithMethodArgumentsAlignment() { + commonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true + doIdempotentTest() + } + + fun testCStyleCommentWithMethodArgumentsAlignment() { + commonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true + doIdempotentTest() + } +} \ No newline at end of file