Formatter: support trailing comma in collection literal expression
#KT-34744
This commit is contained in:
@@ -611,17 +611,13 @@ abstract class KotlinCommonBlock(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
elementType === INDICES -> return { childElement ->
|
elementType === INDICES -> return defaultTrailingCommaWrappingStrategy(LBRACKET, RBRACKET)
|
||||||
trailingCommaWrappingStrategyWithMultiLineCheck(LBRACKET, RBRACKET)(childElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
elementType === TYPE_PARAMETER_LIST -> return { childElement ->
|
elementType === TYPE_PARAMETER_LIST -> return defaultTrailingCommaWrappingStrategy(LT, GT)
|
||||||
trailingCommaWrappingStrategyWithMultiLineCheck(LT, GT)(childElement)
|
|
||||||
}
|
|
||||||
|
|
||||||
elementType === TYPE_ARGUMENT_LIST -> return { childElement ->
|
elementType === TYPE_ARGUMENT_LIST -> return defaultTrailingCommaWrappingStrategy(LT, GT)
|
||||||
trailingCommaWrappingStrategyWithMultiLineCheck(LT, GT)(childElement)
|
|
||||||
}
|
elementType === COLLECTION_LITERAL_EXPRESSION -> return defaultTrailingCommaWrappingStrategy(LBRACKET, RBRACKET)
|
||||||
|
|
||||||
elementType === SUPER_TYPE_LIST -> {
|
elementType === SUPER_TYPE_LIST -> {
|
||||||
val wrap = Wrap.createWrap(commonSettings.EXTENDS_LIST_WRAP, false)
|
val wrap = Wrap.createWrap(commonSettings.EXTENDS_LIST_WRAP, false)
|
||||||
@@ -719,6 +715,9 @@ abstract class KotlinCommonBlock(
|
|||||||
return ::noWrapping
|
return ::noWrapping
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun defaultTrailingCommaWrappingStrategy(leftAnchor: IElementType, rightAnchor: IElementType): WrappingStrategy =
|
||||||
|
fun(childElement: ASTNode): Wrap? = trailingCommaWrappingStrategyWithMultiLineCheck(leftAnchor, rightAnchor)(childElement)
|
||||||
|
|
||||||
private val ASTNode.withTrailingComma: Boolean
|
private val ASTNode.withTrailingComma: Boolean
|
||||||
get() = when {
|
get() = when {
|
||||||
lastChildNode?.let { getPrevWithoutWhitespaceAndComments(it) }?.elementType === COMMA -> true
|
lastChildNode?.let { getPrevWithoutWhitespaceAndComments(it) }?.elementType === COMMA -> true
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ private class TrailingCommaVisitor(val settings: CodeStyleSettings) : KtTreeVisi
|
|||||||
super.visitTypeArgumentList(typeArgumentList)
|
super.visitTypeArgumentList(typeArgumentList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitCollectionLiteralExpression(expression: KtCollectionLiteralExpression) = processCommaOwnerIfInRange(expression) {
|
||||||
|
super.visitCollectionLiteralExpression(expression)
|
||||||
|
}
|
||||||
|
|
||||||
private fun processCommaOwnerIfInRange(element: KtElement, preHook: () -> Unit = {}) {
|
private fun processCommaOwnerIfInRange(element: KtElement, preHook: () -> Unit = {}) {
|
||||||
if (myPostProcessor.isElementPartlyInRange(element)) {
|
if (myPostProcessor.isElementPartlyInRange(element)) {
|
||||||
preHook()
|
preHook()
|
||||||
|
|||||||
+1
-1
@@ -2,6 +2,6 @@
|
|||||||
modules = [
|
modules = [
|
||||||
AppModule::class,
|
AppModule::class,
|
||||||
DataModule::class,
|
DataModule::class,
|
||||||
DomainModule::class
|
DomainModule::class,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
+131
@@ -0,0 +1,131 @@
|
|||||||
|
// SET_TRUE: ALLOW_TRAILING_COMMA
|
||||||
|
|
||||||
|
@Anno([1])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1,
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1,
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2,
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2,
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2, 2,
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(["1"
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1,
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1/*
|
||||||
|
*/])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, //dw
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1 // ds
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
// d
|
||||||
|
1,/*
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
/*
|
||||||
|
*/ 1])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1/*
|
||||||
|
*/, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1,
|
||||||
|
2/*
|
||||||
|
*/,/*
|
||||||
|
*/
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([/*
|
||||||
|
*/1, 2
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(["1"
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1,
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2 /*
|
||||||
|
*/])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Component(
|
||||||
|
modules = [
|
||||||
|
AppModule::class, DataModule::class,
|
||||||
|
DomainModule::class
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun b() = Unit
|
||||||
+196
@@ -0,0 +1,196 @@
|
|||||||
|
// SET_TRUE: ALLOW_TRAILING_COMMA
|
||||||
|
|
||||||
|
@Anno([1])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, 2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, 2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, 2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, 2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, 2, 2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
"1",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, 2, 2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,/*
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, //dw
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1, // ds
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
// d
|
||||||
|
1,/*
|
||||||
|
*//*
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,/*
|
||||||
|
*/
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2/*
|
||||||
|
*/,/*
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
1, 2,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
"1",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
2, /*
|
||||||
|
*/
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Component(
|
||||||
|
modules = [
|
||||||
|
AppModule::class, DataModule::class,
|
||||||
|
DomainModule::class,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun b() = Unit
|
||||||
Vendored
+114
@@ -0,0 +1,114 @@
|
|||||||
|
// SET_TRUE: ALLOW_TRAILING_COMMA
|
||||||
|
|
||||||
|
@Anno([1])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1,])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1 ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1,2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2,])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2, ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, 2 ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2, 2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2, 2,])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(["1"
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1 , 2 , 2 ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1/*
|
||||||
|
*/])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, //dw
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1 // ds
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([/*
|
||||||
|
*/ // d
|
||||||
|
1/*
|
||||||
|
*/,/*
|
||||||
|
*/ ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
/*
|
||||||
|
*/ 1 ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1/*
|
||||||
|
*/,2])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([1, 2/*
|
||||||
|
*/,/*
|
||||||
|
*/])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([/*
|
||||||
|
*/1, 2
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno(["1"
|
||||||
|
])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1, ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Anno([
|
||||||
|
1 , 2 /*
|
||||||
|
*/ ])
|
||||||
|
fun a() = Unit
|
||||||
|
|
||||||
|
@Component(
|
||||||
|
modules = [
|
||||||
|
AppModule::class, DataModule::class,
|
||||||
|
DomainModule::class
|
||||||
|
],
|
||||||
|
)
|
||||||
|
fun b() = Unit
|
||||||
@@ -1164,6 +1164,24 @@ public class FormatterTestGenerated extends AbstractFormatterTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma"), Pattern.compile("^([^\\.]+)\\.after\\.kt.*$"), null, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma"), Pattern.compile("^([^\\.]+)\\.after\\.kt.*$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/formatter/trailingComma/collectionLiteralExpression")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CollectionLiteralExpression extends AbstractFormatterTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCollectionLiteralExpression() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma/collectionLiteralExpression"), Pattern.compile("^([^\\.]+)\\.after\\.kt.*$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("CollectionLiteralInAnnotation.after.kt")
|
||||||
|
public void testCollectionLiteralInAnnotation() throws Exception {
|
||||||
|
runTest("idea/testData/formatter/trailingComma/collectionLiteralExpression/CollectionLiteralInAnnotation.after.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/formatter/trailingComma/indices")
|
@TestMetadata("idea/testData/formatter/trailingComma/indices")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
@@ -1662,6 +1680,24 @@ public class FormatterTestGenerated extends AbstractFormatterTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma"), Pattern.compile("^([^\\.]+)\\.after\\.inv\\.kt.*$"), null, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma"), Pattern.compile("^([^\\.]+)\\.after\\.inv\\.kt.*$"), null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("idea/testData/formatter/trailingComma/collectionLiteralExpression")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class CollectionLiteralExpression extends AbstractFormatterTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTestInverted, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInCollectionLiteralExpression() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/formatter/trailingComma/collectionLiteralExpression"), Pattern.compile("^([^\\.]+)\\.after\\.inv\\.kt.*$"), null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("CollectionLiteralInAnnotation.after.inv.kt")
|
||||||
|
public void testCollectionLiteralInAnnotation() throws Exception {
|
||||||
|
runTest("idea/testData/formatter/trailingComma/collectionLiteralExpression/CollectionLiteralInAnnotation.after.inv.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/formatter/trailingComma/indices")
|
@TestMetadata("idea/testData/formatter/trailingComma/indices")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user