diff --git a/java/java-impl/src/META-INF/JavaPlugin.xml b/java/java-impl/src/META-INF/JavaPlugin.xml
index dd62378296b6..f265a1507e0a 100644
--- a/java/java-impl/src/META-INF/JavaPlugin.xml
+++ b/java/java-impl/src/META-INF/JavaPlugin.xml
@@ -2088,6 +2088,14 @@
com.intellij.codeInsight.intention.impl.lists.JavaJoinArgumentsAction
Java/Other
+
+ com.intellij.codeInsight.intention.impl.lists.JavaChopRecordComponentsAction
+ Java/Other
+
+
+ com.intellij.codeInsight.intention.impl.lists.JavaJoinRecordComponentsAction
+ Java/Other
+
com.intellij.codeInsight.intention.impl.ConvertCompactConstructorToCanonicalAction
Java/Declaration
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaChopRecordComponentsAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaChopRecordComponentsAction.java
new file mode 100644
index 000000000000..1c0d0b752d3f
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaChopRecordComponentsAction.java
@@ -0,0 +1,47 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.codeInsight.intention.impl.lists;
+
+import com.intellij.java.JavaBundle;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class JavaChopRecordComponentsAction extends AbstractJavaChopListAction {
+ @Override
+ @Nullable("When failed") PsiRecordHeader extractList(@NotNull PsiElement element) {
+ return PsiTreeUtil.getParentOfType(element, PsiRecordHeader.class, false, PsiCodeBlock.class, PsiExpression.class);
+ }
+
+ @Override
+ @Nullable("When failed") List getElements(@NotNull PsiRecordHeader list) {
+ return Arrays.asList(list.getRecordComponents());
+ }
+
+ @Override
+ boolean needTailBreak(@NotNull PsiRecordComponent last) {
+ return true;
+ }
+
+ @Override
+ boolean needHeadBreak(@NotNull PsiRecordComponent first) {
+ return true;
+ }
+
+ @Nls(capitalization = Nls.Capitalization.Sentence)
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return JavaBundle.message("intention.family.put.record.components.on.separate.lines");
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ return getFamilyName();
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaJoinRecordComponentsAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaJoinRecordComponentsAction.java
new file mode 100644
index 000000000000..916edd8d5ccb
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaJoinRecordComponentsAction.java
@@ -0,0 +1,47 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.codeInsight.intention.impl.lists;
+
+import com.intellij.java.JavaBundle;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class JavaJoinRecordComponentsAction extends AbstractJavaJoinListAction {
+ @Override
+ @Nullable("When failed") PsiRecordHeader extractList(@NotNull PsiElement element) {
+ return PsiTreeUtil.getParentOfType(element, PsiRecordHeader.class, false, PsiCodeBlock.class, PsiExpression.class);
+ }
+
+ @Override
+ @Nullable("When failed") List getElements(@NotNull PsiRecordHeader list) {
+ return Arrays.asList(list.getRecordComponents());
+ }
+
+ @Override
+ boolean needTailBreak(@NotNull PsiRecordComponent last) {
+ return false;
+ }
+
+ @Override
+ boolean needHeadBreak(@NotNull PsiRecordComponent first) {
+ return false;
+ }
+
+ @Nls(capitalization = Nls.Capitalization.Sentence)
+ @NotNull
+ @Override
+ public String getFamilyName() {
+ return JavaBundle.message("intention.family.put.record.components.on.one.line");
+ }
+
+ @NotNull
+ @Override
+ public String getText() {
+ return getFamilyName();
+ }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaListUtils.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaListUtils.java
index 697962f67da1..fcc0a84412cb 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaListUtils.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/lists/JavaListUtils.java
@@ -44,7 +44,8 @@ final class JavaListUtils {
private static boolean isValidIntermediateElement(@NotNull PsiElement element) {
return element instanceof PsiWhiteSpace ||
- (element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.COMMA);
+ (element instanceof PsiJavaToken && ((PsiJavaToken)element).getTokenType() == JavaTokenType.COMMA) ||
+ (element instanceof PsiComment && ((PsiComment)element).getTokenType() == JavaTokenType.C_STYLE_COMMENT);
}
@Nullable
diff --git a/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/after.java.template b/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/after.java.template
new file mode 100644
index 000000000000..0dc3e88b8ba6
--- /dev/null
+++ b/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/after.java.template
@@ -0,0 +1,4 @@
+record R(
+ int i,
+ String s
+) {}
\ No newline at end of file
diff --git a/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/before.java.template b/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/before.java.template
new file mode 100644
index 000000000000..68ae37683bbf
--- /dev/null
+++ b/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/before.java.template
@@ -0,0 +1 @@
+record R(int i, String s) {}
\ No newline at end of file
diff --git a/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/description.html b/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/description.html
new file mode 100644
index 000000000000..24b0633f0065
--- /dev/null
+++ b/java/java-impl/src/intentionDescriptions/JavaChopRecordComponentsAction/description.html
@@ -0,0 +1,5 @@
+
+
+Puts record components on separate lines.
+
+
\ No newline at end of file
diff --git a/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/after.java.template b/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/after.java.template
new file mode 100644
index 000000000000..68ae37683bbf
--- /dev/null
+++ b/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/after.java.template
@@ -0,0 +1 @@
+record R(int i, String s) {}
\ No newline at end of file
diff --git a/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/before.java.template b/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/before.java.template
new file mode 100644
index 000000000000..0dc3e88b8ba6
--- /dev/null
+++ b/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/before.java.template
@@ -0,0 +1,4 @@
+record R(
+ int i,
+ String s
+) {}
\ No newline at end of file
diff --git a/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/description.html b/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/description.html
new file mode 100644
index 000000000000..6ce809167c93
--- /dev/null
+++ b/java/java-impl/src/intentionDescriptions/JavaJoinRecordComponentsAction/description.html
@@ -0,0 +1,5 @@
+
+
+Puts record components on a single line.
+
+
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/afterAllOnOneLine.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/afterAllOnOneLine.java
new file mode 100644
index 000000000000..5bd033c017f4
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/afterAllOnOneLine.java
@@ -0,0 +1,6 @@
+// "Put record components on separate lines" "true"
+
+record R(
+ int i,
+ String s
+)
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/beforeAllOnOneLine.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/beforeAllOnOneLine.java
new file mode 100644
index 000000000000..36de421aa248
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/beforeAllOnOneLine.java
@@ -0,0 +1,3 @@
+// "Put record components on separate lines" "true"
+
+record R(int i, String s)
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/beforeComment.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/beforeComment.java
new file mode 100644
index 000000000000..eedfe364c233
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents/beforeComment.java
@@ -0,0 +1,6 @@
+// "Put record components on separate lines" "false"
+
+record A(
+ String s/**/,
+ int i
+) {}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/joinRecordComponents/afterAllOnSeparateLines.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/joinRecordComponents/afterAllOnSeparateLines.java
new file mode 100644
index 000000000000..7db9925b427a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/joinRecordComponents/afterAllOnSeparateLines.java
@@ -0,0 +1,3 @@
+// "Put record components on one line" "true"
+
+record R(int i, String s)
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/joinRecordComponents/beforeAllOnSeparateLines.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/joinRecordComponents/beforeAllOnSeparateLines.java
new file mode 100644
index 000000000000..e233e0e67868
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/lists/joinRecordComponents/beforeAllOnSeparateLines.java
@@ -0,0 +1,6 @@
+// "Put record components on one line" "true"
+
+record R(
+ int i,
+ String s
+)
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/JavaChopRecordComponentsActionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/JavaChopRecordComponentsActionTest.java
new file mode 100644
index 000000000000..be1033e23b8e
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/JavaChopRecordComponentsActionTest.java
@@ -0,0 +1,19 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.java.codeInsight.intention;
+
+import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
+
+public class JavaChopRecordComponentsActionTest extends LightIntentionActionTestCase {
+ @Override
+ protected String getBasePath() {
+ return "/codeInsight/daemonCodeAnalyzer/quickFix/lists/chopRecordComponents";
+ }
+
+ @Override
+ protected @NotNull LightProjectDescriptor getProjectDescriptor() {
+ return LightJavaCodeInsightFixtureTestCase.JAVA_16;
+ }
+}
diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/JavaJoinRecordComponentsActionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/JavaJoinRecordComponentsActionTest.java
new file mode 100644
index 000000000000..40c57a0bce7e
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/JavaJoinRecordComponentsActionTest.java
@@ -0,0 +1,19 @@
+// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+package com.intellij.java.codeInsight.intention;
+
+import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
+import org.jetbrains.annotations.NotNull;
+
+public class JavaJoinRecordComponentsActionTest extends LightIntentionActionTestCase {
+ @Override
+ protected String getBasePath() {
+ return "/codeInsight/daemonCodeAnalyzer/quickFix/lists/joinRecordComponents";
+ }
+
+ @Override
+ protected @NotNull LightProjectDescriptor getProjectDescriptor() {
+ return LightJavaCodeInsightFixtureTestCase.JAVA_16;
+ }
+}
diff --git a/java/openapi/resources/messages/JavaBundle.properties b/java/openapi/resources/messages/JavaBundle.properties
index abfecd098cfc..103c8f5ed68c 100644
--- a/java/openapi/resources/messages/JavaBundle.properties
+++ b/java/openapi/resources/messages/JavaBundle.properties
@@ -802,6 +802,8 @@ intention.family.put.arguments.on.one.line=Put arguments on one line
intention.family.put.arguments.on.separate.lines=Put arguments on separate lines
intention.family.put.parameters.on.one.line=Put parameters on one line
intention.family.put.parameters.on.separate.lines=Put parameters on separate lines
+intention.family.put.record.components.on.one.line=Put record components on one line
+intention.family.put.record.components.on.separate.lines=Put record components on separate lines
intention.family.replace.optional.ispresent.condition.with.functional.style.expression=Replace Optional.isPresent() condition with functional style expression
intention.family.sort.content=Sort content
intention.family.swap.if.statements=Swap 'if' statements