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 e4704607bc0..b8c432a726d 100644 --- a/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCommonBlock.kt +++ b/idea/formatter/src/org/jetbrains/kotlin/idea/formatter/KotlinCommonBlock.kt @@ -615,6 +615,10 @@ abstract class KotlinCommonBlock( trailingCommaWrappingStrategyWithMultiLineCheck(LBRACKET, RBRACKET)(childElement) } + elementType === TYPE_PARAMETER_LIST -> return { childElement -> + trailingCommaWrappingStrategyWithMultiLineCheck(LT, GT)(childElement) + } + elementType === SUPER_TYPE_LIST -> { val wrap = Wrap.createWrap(commonSettings.EXTENDS_LIST_WRAP, false) return { childElement -> if (childElement.psi is KtSuperTypeListEntry) wrap else null } diff --git a/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt index 7a3880ad5f7..4b7dc65fbf8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/formatter/TrailingCommaPostFormatProcessor.kt @@ -46,6 +46,10 @@ private class TrailingCommaVisitor(val settings: CodeStyleSettings) : KtTreeVisi super.visitArrayAccessExpression(expression) } + override fun visitTypeParameterList(list: KtTypeParameterList) = processCommaOwnerIfInRange(list) { + super.visitTypeParameterList(list) + } + private fun processCommaOwnerIfInRange(element: KtElement, preHook: () -> Unit = {}) { if (myPostProcessor.isElementPartlyInRange(element)) { preHook() diff --git a/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.inv.kt b/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.inv.kt new file mode 100644 index 00000000000..a5fb3abb4ae --- /dev/null +++ b/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.inv.kt @@ -0,0 +1,242 @@ +class A1< + x : String, + y : String, + > + +class F + +class F2 + +class B1< + x : String, + y : String + > + +class C1< + x : String, + y : String, + > + +class D1< + x : String, + y : String, + > + +class A2< + x : String, + y : String, + z : String, + > + +class B2< + x : String, + y : String, + z : String + > + +class C2< + x : String, + y : String, + z : String, + > + +class D2< + x : String, + y : String, + z : String, + > + +class A3< + x : String, + > + +class B3< + x : String + > + +class C3< + x : String, + > + +class D3< + x : String, + > + +class A4< + x : String, + y : String, + z, + > + +class B4< + x : String, + y, + z : String + > + +class C4< + x : String, + y : String, + z : String, + > + +class D4< + x : String, + y, + z : String, + > + +class E1< + x, y : String, + z : String, + > + +class E2< + x : String, y : String, z : String + > + +class C< + z : String, v + + > + +fun < + x : String, + y : String, + > a1() = Unit + +fun b1() = Unit + +fun < + x : String, + y : String, + > c1() = Unit + +fun < + x : String, + y : String, + > d1() = Unit + +fun < + x : String, + y : String, + z : String, + > a2() = Unit + +fun < + x : String, + y : String, + z : String + > b2() = Unit + +fun < + x : String, + y : String, + z : String, + > c2() = Unit + +fun < + x : String, + y : String, + z : String, + > d2() = Unit + +fun < + x : String, + > a3() = Unit + +fun < + x : String + > b3() = Unit + +fun < + x : String, + > c3() = Unit + +fun < + x : String, + > d3() = Unit + +fun < + x : String, + y : String, + z : String, + > a4() = Unit + +fun < + x : String, + y : String, + z : String + > b4() = Unit + +fun < + x : String, + y : String, + z : String, + > c4() = Unit + +fun < + x : String, + y : String, + z : String, + > d4() = Unit + +fun < + x + > foo() { +} + +fun ag() { + +} + +fun < + T, + > ag() { + +} + +fun < + T> ag() { + +} + +class C< + x : Int + > + +class G< + x : String, y : String, /* */ z : String + > + +class G< + x : String, y : String + /* */, /* */ z : String + >() + +class H< + x : String, /* + */ + y : String, + z : String, + > + +class J< + x : String, y : String, + z : String /* + */, + > + +class K< + x : String, y : String, + z : String, + > + +class L< + x : String, y : String, z : String + > + +// SET_TRUE: ALLOW_TRAILING_COMMA diff --git a/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.kt b/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.kt new file mode 100644 index 00000000000..6b945282451 --- /dev/null +++ b/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.kt @@ -0,0 +1,250 @@ +class A1< + x : String, + y : String, + > + +class F + +class F2< + x : String, + y + : String, + > + +class B1< + x : String, + y : String, + > + +class C1< + x : String, + y : String, + > + +class D1< + x : String, + y : String, + > + +class A2< + x : String, + y : String, + z : String, + > + +class B2< + x : String, + y : String, + z : String, + > + +class C2< + x : String, + y : String, + z : String, + > + +class D2< + x : String, + y : String, + z : String, + > + +class A3< + x : String, + > + +class B3< + x : String, + > + +class C3< + x : String, + > + +class D3< + x : String, + > + +class A4< + x : String, + y : String, + z, + > + +class B4< + x : String, + y, + z : String, + > + +class C4< + x : String, + y : String, + z : String, + > + +class D4< + x : String, + y, + z : String, + > + +class E1< + x, y : String, + z : String, + > + +class E2< + x : String, y : String, z : String, + > + +class C< + z : String, v, + + > + +fun < + x : String, + y : String, + > a1() = Unit + +fun < + x : String, + y : String, + > b1() = Unit + +fun < + x : String, + y : String, + > c1() = Unit + +fun < + x : String, + y : String, + > d1() = Unit + +fun < + x : String, + y : String, + z : String, + > a2() = Unit + +fun < + x : String, + y : String, + z : String, + > b2() = Unit + +fun < + x : String, + y : String, + z : String, + > c2() = Unit + +fun < + x : String, + y : String, + z : String, + > d2() = Unit + +fun < + x : String, + > a3() = Unit + +fun < + x : String, + > b3() = Unit + +fun < + x : String, + > c3() = Unit + +fun < + x : String, + > d3() = Unit + +fun < + x : String, + y : String, + z : String, + > a4() = Unit + +fun < + x : String, + y : String, + z : String, + > b4() = Unit + +fun < + x : String, + y : String, + z : String, + > c4() = Unit + +fun < + x : String, + y : String, + z : String, + > d4() = Unit + +fun < + x, + > foo() { +} + +fun ag() { + +} + +fun < + T, + > ag() { + +} + +fun < + T, + > ag() { + +} + +class C< + x : Int, + > + +class G< + x : String, y : String, /* */ + z : String, + > + +class G< + x : String, + y : String, + /* */ /* */ + z : String, + >() + +class H< + x : String, /* + */ + y : String, + z : String, + > + +class J< + x : String, y : String, + z : String /* + */, + > + +class K< + x : String, y : String, + z : String, + > + +class L< + x : String, y : String, z : String, + > + +// SET_TRUE: ALLOW_TRAILING_COMMA diff --git a/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.kt b/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.kt new file mode 100644 index 00000000000..62ada0732a3 --- /dev/null +++ b/idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.kt @@ -0,0 +1,229 @@ +class A1< + x: String, + y: String, +> + +class F + +class F2 + +class B1< + x: String, + y: String +> + +class C1< + x: String, + y: String,> + +class D1< + x: String, + y: String + ,> + +class A2< + x: String, + y: String, + z: String, +> + +class B2< + x: String, + y: String, + z: String +> + +class C2< + x: String, + y: String, + z: String,> + +class D2< + x: String, + y: String, + z: String + ,> + +class A3< + x: String, +> + +class B3< + x: String +> + +class C3< + x: String,> + +class D3< + x: String + ,> + +class A4< + x: String , + y: String, + z , +> + +class B4< + x: String, + y, + z: String +> + +class C4< + x: String, + y: String, + z: String ,> + +class D4< + x: String, + y, + z: String + , > + +class E1< + x, y: String, + z: String + , > + +class E2< + x: String, y: String, z: String +> + +class C< + z: String, v + +> + +fun a1() = Unit + +fun b1() = Unit + +fun < + x: String, + y: String,> c1() = Unit + +fun < + x: String, + y: String + ,> d1() = Unit + +fun < + x: String, + y: String, + z: String, +> a2() = Unit + +fun < + x: String, + y: String, + z: String +> b2() = Unit + +fun < + x: String, + y: String, + z: String,> c2() = Unit + +fun < + x: String, + y: String, + z: String + ,> d2() = Unit + +fun < + x: String, +> a3() = Unit + +fun < + x: String +> b3() = Unit + +fun < + x: String,> c3() = Unit + +fun < + x: String + ,> d3() = Unit + +fun < + x: String + , + y: String, + z: String , +> a4() = Unit + +fun < + x: String, + y: String, + z: String +> b4() = Unit + +fun c4() = Unit + +fun < + x: String, + y: String, + z: String + , > d4() = Unit + +fun < + x +> foo() { +} + +fun ag() { + +} + +fun ag() { + +} + +fun < + T> ag() { + +} + +class C< + x: Int +> + +class G< + x: String, y: String + , /* */ z: String +> + +class G< + x: String, y: String + /* */, /* */ z: String +>() + +class H< + x: String, /* + */ y: String, + z: String ,> + +class J< + x: String, y: String , z: String /* + */ + , > + +class K< + x: String, y: String, + z: String + , > + +class L< + x: String, y: String, z: String +> + +// SET_TRUE: ALLOW_TRAILING_COMMA diff --git a/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java b/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java index ec2255738cd..61ccdbcce10 100644 --- a/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/formatter/FormatterTestGenerated.java @@ -1182,6 +1182,24 @@ public class FormatterTestGenerated extends AbstractFormatterTest { } } + @TestMetadata("idea/testData/formatter/trailingComma/typeParameters") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeParameters extends AbstractFormatterTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInTypeParameters() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma/typeParameters"), Pattern.compile("^([^\\.]+)\\.after\\.kt.*$"), null, true); + } + + @TestMetadata("TypeParameterList.after.kt") + public void testTypeParameterList() throws Exception { + runTest("idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.kt"); + } + } + @TestMetadata("idea/testData/formatter/trailingComma/valueArguments") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -1644,6 +1662,24 @@ public class FormatterTestGenerated extends AbstractFormatterTest { } } + @TestMetadata("idea/testData/formatter/trailingComma/typeParameters") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class TypeParameters extends AbstractFormatterTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestInverted, this, testDataFilePath); + } + + public void testAllFilesPresentInTypeParameters() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma/typeParameters"), Pattern.compile("^([^\\.]+)\\.after\\.inv\\.kt.*$"), null, true); + } + + @TestMetadata("TypeParameterList.after.inv.kt") + public void testTypeParameterList() throws Exception { + runTest("idea/testData/formatter/trailingComma/typeParameters/TypeParameterList.after.inv.kt"); + } + } + @TestMetadata("idea/testData/formatter/trailingComma/valueArguments") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)