[Java. Code Formatting] Format records annotations similar to java fields

IDEA-298007

GitOrigin-RevId: 685e8020cef634d3554a70cbb35d9c5fd2fc33d1
This commit is contained in:
Georgii Ustinov
2024-11-14 19:02:05 +00:00
committed by intellij-monorepo-bot
parent 32278698e5
commit abfeea2b41
45 changed files with 425 additions and 21 deletions

View File

@@ -116,6 +116,8 @@ public class JavaCodeStyleSettings extends CustomCodeStyleSettings implements Im
// @Foo int param
public boolean DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION_IN_PARAMETER = false;
public boolean ANNOTATION_NEW_LINE_IN_RECORD_COMPONENT = false;
@WrapConstant
public int ANNOTATION_PARAMETER_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP;
@@ -133,6 +135,8 @@ public class JavaCodeStyleSettings extends CustomCodeStyleSettings implements Im
public int BLANK_LINES_AROUND_INITIALIZER = 1;
public int BLANK_LINES_AROUND_FIELD_WITH_ANNOTATIONS = 0;
public int BLANK_LINES_BETWEEN_RECORD_COMPONENTS = 0;
public static final int FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED = 1;
public static final int FULLY_QUALIFY_NAMES_ALWAYS = 2;
public static final int SHORTEN_NAMES_ALWAYS_AND_ADD_IMPORT = 3;

View File

@@ -262,6 +262,10 @@ public final class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeSty
"RPAREN_ON_NEW_LINE_IN_RECORD_HEADER",
ApplicationBundle.message("wrapping.rpar.on.new.line"),
recordComponentsGroup);
consumer.showCustomOption(JavaCodeStyleSettings.class,
"ANNOTATION_NEW_LINE_IN_RECORD_COMPONENT",
JavaBundle.message("annotations.new.line.record.component"),
recordComponentsGroup);
// Try statement
consumer.showCustomOption(JavaCodeStyleSettings.class,
@@ -320,6 +324,11 @@ public final class JavaLanguageCodeStyleSettingsProvider extends LanguageCodeSty
getInstance().BLANK_LINES,
OptionAnchor.AFTER,
"BLANK_LINES_AROUND_FIELD");
consumer.showCustomOption(JavaCodeStyleSettings.class,
"BLANK_LINES_BETWEEN_RECORD_COMPONENTS",
JavaBundle.message("editbox.blank.lines.record.components"),
getInstance().BLANK_LINES);
}
else if (settingsType == SettingsType.COMMENTER_SETTINGS) {
consumer.showStandardOptions(

View File

@@ -169,7 +169,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
@NotNull AlignmentStrategy alignmentStrategy,
int startOffset,
@NotNull FormattingMode formattingMode) {
Indent actualIndent = indent == null ? getDefaultSubtreeIndent(child, settings) : indent;
Indent actualIndent = indent == null ? getDefaultSubtreeIndent(child, settings, javaSettings) : indent;
IElementType elementType = child.getElementType();
Alignment alignment = alignmentStrategy.getAlignment(elementType);
PsiElement childPsi = child.getPsi();
@@ -237,7 +237,7 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
@NotNull CommonCodeStyleSettings settings,
@NotNull JavaCodeStyleSettings javaSettings,
@NotNull FormattingMode formattingMode) {
final Indent indent = getDefaultSubtreeIndent(child, settings);
final Indent indent = getDefaultSubtreeIndent(child, settings, javaSettings);
return newJavaBlock(child, settings, javaSettings, indent, null, AlignmentStrategy.getNullStrategy(), formattingMode);
}
@@ -287,20 +287,27 @@ public abstract class AbstractJavaBlock extends AbstractBlock implements JavaBlo
}
private static @Nullable Indent getDefaultSubtreeIndent(@NotNull ASTNode child, @NotNull CommonCodeStyleSettings settings) {
private static @Nullable Indent getDefaultSubtreeIndent(@NotNull ASTNode child, @NotNull CommonCodeStyleSettings settings, @NotNull JavaCodeStyleSettings javaSettings) {
CommonCodeStyleSettings.IndentOptions indentOptions= getJavaIndentOptions(settings);
final ASTNode parent = child.getTreeParent();
final IElementType childNodeType = child.getElementType();
if (childNodeType == JavaElementType.ANNOTATION) {
if (parent.getPsi() instanceof PsiArrayInitializerMemberValue) {
return Indent.getNormalIndent();
} else if (JavaFormatterRecordUtil.shouldAdjustIndentForRecordComponentChild(child, javaSettings)) {
return Indent.getContinuationIndent();
}
return Indent.getNoneIndent();
}
final ASTNode prevElement = skipCommentsAndWhitespacesBackwards(child);
if (prevElement != null && prevElement.getElementType() == JavaElementType.MODIFIER_LIST) {
return Indent.getNoneIndent();
if (prevElement != null) {
if (JavaFormatterRecordUtil.shouldAdjustIndentForRecordComponentChild(child, javaSettings)) {
return Indent.getContinuationIndent();
}
else if (prevElement.getElementType() == JavaElementType.MODIFIER_LIST) {
return Indent.getNoneIndent();
}
}
if (childNodeType == JavaDocElementType.DOC_TAG) return Indent.getNoneIndent();

View File

@@ -0,0 +1,56 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.psi.formatter.java
import com.intellij.lang.ASTNode
import com.intellij.psi.JavaTokenType
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
import com.intellij.psi.codeStyle.JavaCodeStyleSettings
import com.intellij.psi.formatter.FormatterUtil
import com.intellij.psi.impl.source.tree.JavaElementType
object JavaFormatterRecordUtil {
/**
* In some option configurations, the formatter removes prefix spaces from the record components, consider this java example:
* ```java
* public record(@FirstAnno @SecondAnno String s) {}
* ```
* might be formatted to
* ```java
* public record(@FirstAnno
* @SecondAnno String s) {
* }
* ```
* This method helps to detect such cases based on the given [node]
*/
@JvmStatic
fun shouldAdjustIndentForRecordComponentChild(node: ASTNode, javaSettings: JavaCodeStyleSettings): Boolean {
if(javaSettings.NEW_LINE_AFTER_LPAREN_IN_RECORD_HEADER ||
javaSettings.ALIGN_MULTILINE_RECORDS ||
javaSettings.RECORD_COMPONENTS_WRAP != CommonCodeStyleSettings.WRAP_ALWAYS ||
!javaSettings.ANNOTATION_NEW_LINE_IN_RECORD_COMPONENT) return false
return isInFirstRecordComponent(node)
}
/**
* Checks if the given [node] belongs to the record component. Node might be either an annotation or a type element.
*/
@JvmStatic
fun isInRecordComponent(node: ASTNode): Boolean = findRecordComponent(node) != null
private fun isInFirstRecordComponent(node: ASTNode): Boolean {
val parent = findRecordComponent(node) ?: return false
val prev = FormatterUtil.getPreviousNonWhitespaceSibling(parent)
return prev?.elementType == JavaTokenType.LPARENTH
}
private fun findRecordComponent(node : ASTNode): ASTNode? {
val parent = node.treeParent ?: return null
if (parent.elementType == JavaElementType.RECORD_COMPONENT) return parent
else if (parent.elementType != JavaElementType.MODIFIER_LIST) return null
val grandParent = parent.treeParent ?: return null
return if (grandParent.elementType == JavaElementType.RECORD_COMPONENT) grandParent else null
}
}

View File

@@ -292,7 +292,7 @@ public final class JavaFormatterUtil {
if (prev != null && prev.getElementType() == JavaElementType.MODIFIER_LIST) {
ASTNode last = prev.getLastChildNode();
if (last != null && last.getElementType() == JavaElementType.ANNOTATION) {
if (isTypeAnnotation(last) ||
if (isTypeAnnotation(last) && parent.getElementType() != JavaElementType.RECORD_COMPONENT ||
javaSettings.DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION && isModifierListWithSingleAnnotation(prev, JavaElementType.FIELD) ||
javaSettings.DO_NOT_WRAP_AFTER_SINGLE_ANNOTATION_IN_PARAMETER &&
isModifierListWithSingleAnnotation(prev, JavaElementType.PARAMETER) ||
@@ -316,12 +316,12 @@ public final class JavaFormatterUtil {
return null;
}
else if (isAnnoInsideModifierListWithAtLeastOneKeyword(child, parent)) {
else if (isAnnoInsideModifierListWithAtLeastOneKeyword(child, parent) || (JavaFormatterRecordUtil.isInRecordComponent(child) && prev == null)) {
return Wrap.createWrap(WrapType.NONE, false);
}
if (isTypeAnnotation(child)) {
if (prev == null || prev.getElementType() != JavaElementType.ANNOTATION || isTypeAnnotation(prev)) {
if (prev == null || prev.getElementType() != JavaElementType.ANNOTATION || (isTypeAnnotation(prev) && !JavaFormatterRecordUtil.isInRecordComponent(child))) {
return Wrap.createWrap(WrapType.NONE, false);
}
}
@@ -506,6 +506,10 @@ public final class JavaFormatterUtil {
return settings.FIELD_ANNOTATION_WRAP;
}
if (nodeType == JavaElementType.RECORD_COMPONENT) {
return isAnnotationOnNewLineInRecordComponent(javaSettings) ? CommonCodeStyleSettings.WRAP_ALWAYS : CommonCodeStyleSettings.DO_NOT_WRAP;
}
if (nodeType == JavaElementType.PARAMETER ||
nodeType == JavaElementType.RECEIVER_PARAMETER ||
nodeType == JavaElementType.RESOURCE_VARIABLE) {
@@ -527,6 +531,11 @@ public final class JavaFormatterUtil {
return CommonCodeStyleSettings.DO_NOT_WRAP;
}
private static boolean isAnnotationOnNewLineInRecordComponent(JavaCodeStyleSettings javaSettings) {
return CommonCodeStyleSettings.WRAP_ALWAYS == javaSettings.RECORD_COMPONENTS_WRAP &&
javaSettings.ANNOTATION_NEW_LINE_IN_RECORD_COMPONENT;
}
private static boolean isAnnoInsideModifierListWithAtLeastOneKeyword(@NotNull ASTNode current, @NotNull ASTNode parent) {
if (current.getElementType() != JavaElementType.ANNOTATION || parent.getElementType() != JavaElementType.MODIFIER_LIST) return false;
while (true) {

View File

@@ -1305,7 +1305,8 @@ public final class JavaSpacePropertyProcessor extends JavaElementVisitor {
createParenthSpace(myJavaSettings.NEW_LINE_AFTER_LPAREN_IN_RECORD_HEADER, myJavaSettings.SPACE_WITHIN_RECORD_HEADER);
}
else if (myType1 == JavaTokenType.COMMA) {
createSpaceInCode(mySettings.SPACE_AFTER_COMMA);
int minLineFeed = myJavaSettings.BLANK_LINES_BETWEEN_RECORD_COMPONENTS == 0 ? 0 : myJavaSettings.BLANK_LINES_BETWEEN_RECORD_COMPONENTS + 1;
createSpaceProperty(mySettings.SPACE_AFTER_COMMA, mySettings.KEEP_LINE_BREAKS, minLineFeed, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS);
}
else if (myType2 == JavaTokenType.COMMA) {
createSpaceInCode(mySettings.SPACE_BEFORE_COMMA);
@@ -1663,6 +1664,10 @@ public final class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
private void createSpaceProperty(boolean space, boolean keepLineBreaks, int keepBlankLines) {
createSpaceProperty(space, keepLineBreaks, 0, keepBlankLines);
}
private void createSpaceProperty(boolean space, boolean keepLineBreaks, int minLineFeeds, int keepBlankLines) {
ASTNode prev = getPrevElementType(myChild2);
if (prev != null && prev.getElementType() == JavaTokenType.END_OF_LINE_COMMENT) {
myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE);
@@ -1671,7 +1676,7 @@ public final class JavaSpacePropertyProcessor extends JavaElementVisitor {
if (!space && !canStickChildrenTogether(myChild1, myChild2)) {
space = true;
}
myResult = Spacing.createSpacing(space ? 1 : 0, space ? 1 : 0, 0, keepLineBreaks, keepBlankLines);
myResult = Spacing.createSpacing(space ? 1 : 0, space ? 1 : 0, minLineFeeds, keepLineBreaks, keepBlankLines);
}
}

View File

@@ -26,6 +26,7 @@
"align_subsequent_simple_methods": false,
"align_throws_keyword": false,
"align_types_in_multi_catch": true,
"annotation_new_line_in_record_component": false,
"annotation_parameter_wrap": "off",
"array_initializer_new_line_after_left_brace": false,
"array_initializer_right_brace_on_new_line": false,
@@ -50,6 +51,7 @@
"blank_lines_before_imports": 1,
"blank_lines_before_method_body": 0,
"blank_lines_before_package": 0,
"blank_lines_between_record_components": 0,
"block_brace_style": "end_of_line",
"block_comment_add_space": false,
"block_comment_at_first_column": true,

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,10 @@
public record FormatRecord(
@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t
) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,9 @@
public record FormatRecord(
@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,9 @@
public record FormatRecord(@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t
) {
}

View File

@@ -0,0 +1,8 @@
public record FormatRecord(@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,10 @@
public record FormatRecord(@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t) {
}

View File

@@ -0,0 +1,6 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s,
@EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,7 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s,
@EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,12 @@
public record FormatRecord(
@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t
) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,10 @@
public record FormatRecord(@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t) {
}

View File

@@ -0,0 +1,5 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record FormatRecord(@NotNull @Nullable String t) {
}

View File

@@ -0,0 +1,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public record FormatRecord(@NotNull
@Nullable
String t) {
}

View File

@@ -0,0 +1,4 @@
import org.jetbrains.annotations.NotNull;
public record FormatRecord(@NotNull @FieldAnnoWithParameters String t) {
}

View File

@@ -0,0 +1,6 @@
import org.jetbrains.annotations.NotNull;
public record FormatRecord(@NotNull
@FieldAnnoWithParameters
String t) {
}

View File

@@ -0,0 +1,4 @@
import org.jetbrains.annotations.NotNull;
public record FormatRecord(@FieldAnnoWithParameters @NotNull @EmptyFieldAnno1 String t) {
}

View File

@@ -0,0 +1,7 @@
import org.jetbrains.annotations.NotNull;
public record FormatRecord(@FieldAnnoWithParameters
@NotNull
@EmptyFieldAnno1
String t) {
}

View File

@@ -0,0 +1,4 @@
import org.jetbrains.annotations.NotNull;
public record FormatRecord(@FieldAnnoWithParameters @NotNull String t) {
}

View File

@@ -0,0 +1,6 @@
import org.jetbrains.annotations.NotNull;
public record FormatRecord(@FieldAnnoWithParameters
@NotNull
String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,10 @@
public record FormatRecord(
@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t
) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,9 @@
public record FormatRecord(
@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t) {
}

View File

@@ -0,0 +1,2 @@
public record FormatRecord(@EmptyFieldAnno1 @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String s, @EmptyFieldAnno2 @FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"}) String t) {
}

View File

@@ -0,0 +1,9 @@
public record FormatRecord(@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t
) {
}

View File

@@ -0,0 +1,8 @@
public record FormatRecord(@EmptyFieldAnno1
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String s,
@EmptyFieldAnno2
@FieldAnnoWithParameters(value = "val", arr = {"foo", "bar", "baz"})
String t) {
}

View File

@@ -0,0 +1,16 @@
// Copyright 2000-2024 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
import com.intellij.lang.java.JavaLanguage
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
abstract class JavaFormatterIdempotencyTestCase : JavaFormatterTestCase() {
protected val commonSettings: CommonCodeStyleSettings
get() = getSettings(JavaLanguage.INSTANCE)
protected fun doIdempotentTest() {
val testName = getTestName(false)
doTest(testName, "${testName}_after")
doTest("${testName}_after", "${testName}_after")
}
}

View File

@@ -1,15 +1,11 @@
// Copyright 2000-2024 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
import com.intellij.lang.java.JavaLanguage
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
class JavaFormatterNewLineAfterLBraceTest : JavaFormatterTestCase() {
class JavaFormatterNewLineAfterLBraceTest : JavaFormatterIdempotencyTestCase() {
override fun getBasePath(): String = "psi/formatter/java/newLineAfterLBrace"
private val commonSettings: CommonCodeStyleSettings
get() = getSettings(JavaLanguage.INSTANCE)
override fun setUp() {
super.setUp()
commonSettings.CALL_PARAMETERS_LPAREN_ON_NEXT_LINE = true
@@ -73,12 +69,6 @@ class JavaFormatterNewLineAfterLBraceTest : JavaFormatterTestCase() {
doIdempotentTest()
}
private fun doIdempotentTest() {
val testName = getTestName(false)
doTest(testName, "${testName}_after")
doTest("${testName}_after", "${testName}_after")
}
private fun setupAlignWhenMultiline() {
commonSettings.ALIGN_MULTILINE_PARAMETERS = true
commonSettings.ALIGN_MULTILINE_PARAMETERS_IN_CALLS = true

View File

@@ -0,0 +1,118 @@
// Copyright 2000-2024 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
import com.intellij.psi.codeStyle.CommonCodeStyleSettings
class JavaRecordAnnotationsFormatterTest : JavaFormatterIdempotencyTestCase() {
override fun getBasePath(): String = "psi/formatter/java/recordAnnotations"
override fun setUp() {
super.setUp()
customJavaSettings.RECORD_COMPONENTS_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS
customJavaSettings.ANNOTATION_NEW_LINE_IN_RECORD_COMPONENT = true
}
fun testNoAlignment() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = false
doIdempotentTest()
}
fun testNoAlignmentWithNewLineAfterLParen() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = false
customJavaSettings.NEW_LINE_AFTER_LPAREN_IN_RECORD_HEADER = true
doIdempotentTest()
}
fun testNoAlignmentWithNewLineBeforeRParen() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = false
customJavaSettings.RPAREN_ON_NEW_LINE_IN_RECORD_HEADER = true
doIdempotentTest()
}
fun testNoAlignmentWithBothParensOnNewLine() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = false
customJavaSettings.NEW_LINE_AFTER_LPAREN_IN_RECORD_HEADER = true
customJavaSettings.RPAREN_ON_NEW_LINE_IN_RECORD_HEADER = true
doIdempotentTest()
}
fun testAlignment() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testAlignmentWithNewLineAfterLParen() {
customJavaSettings.NEW_LINE_AFTER_LPAREN_IN_RECORD_HEADER = true
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testAlignmentWithNewLineBeforeRParen() {
customJavaSettings.RPAREN_ON_NEW_LINE_IN_RECORD_HEADER = true
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testAlignmentWithBothParensOnNewLine() {
customJavaSettings.RPAREN_ON_NEW_LINE_IN_RECORD_HEADER = true
customJavaSettings.NEW_LINE_AFTER_LPAREN_IN_RECORD_HEADER = true
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testIgnoresFormattingKnownTypeAnnotationsWhenItIsLast() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testIgnoresFormattingKnownTypeAnnotationsWhenItIsFirst() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testIgnoresFormattingKnownTypeAnnotationsWhenItIsInMiddle() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testIgnoresFormattingKnownConsecutiveTypeAnnotations() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
doIdempotentTest()
}
fun testBlankLinesBetweenRecordComponents() {
customJavaSettings.ANNOTATION_NEW_LINE_IN_RECORD_COMPONENT = false
customJavaSettings.RECORD_COMPONENTS_WRAP = CommonCodeStyleSettings.WRAP_ALWAYS
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
customJavaSettings.BLANK_LINES_BETWEEN_RECORD_COMPONENTS = 3
doIdempotentTest()
}
fun testBlankLinesBetweenRecordComponentsWithAnnotations() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
customJavaSettings.BLANK_LINES_BETWEEN_RECORD_COMPONENTS = 2
doIdempotentTest()
}
fun testBlankLinesIgnoresWrapping() {
customJavaSettings.RECORD_COMPONENTS_WRAP = CommonCodeStyleSettings.DO_NOT_WRAP
customJavaSettings.ALIGN_MULTILINE_RECORDS = true
customJavaSettings.BLANK_LINES_BETWEEN_RECORD_COMPONENTS = 4
doIdempotentTest()
}
fun testBlankLinesWithAnnotationsWithoutAlignment() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = false
customJavaSettings.BLANK_LINES_BETWEEN_RECORD_COMPONENTS = 2
doIdempotentTest()
}
fun testBlankLinesWithAnnotationsRespectsNewLinesAfterParens() {
customJavaSettings.ALIGN_MULTILINE_RECORDS = false
customJavaSettings.BLANK_LINES_BETWEEN_RECORD_COMPONENTS = 2
customJavaSettings.NEW_LINE_AFTER_LPAREN_IN_RECORD_HEADER = true
customJavaSettings.RPAREN_ON_NEW_LINE_IN_RECORD_HEADER = true
doIdempotentTest()
}
}

View File

@@ -223,6 +223,7 @@ editbox.blanklines.around.initializer=Around initializer:
editbox.blank.lines.field.in.interface=Before field in interface
editbox.blank.lines.field.without.annotations=Before field without annotations:
editbox.blank.lines.field.with.annotations=Before field with annotations:
editbox.blank.lines.record.components=Between record components:
editbox.class.count.to.use.import.with.star=Class count to use import with '*':
editbox.names.count.to.use.static.import.with.star=Names count to use static import with '*':
enum.not.allowed=Enum is not allowed
@@ -1366,6 +1367,7 @@ wrapping.annotation.parameters=Annotation parameters
wrapping.record.components=Record components
wrapping.multi.catch.types=Types in multi-catch
wrapping.deconstruction.patterns=Deconstruction patterns
annotations.new.line.record.component=New line for annotations
align.types.in.multi.catch=Align types in multi-catch
wrapping.text.blocks=Text blocks
wrapping.switch.statement.or.expression='switch' statement/expression