[formatter] line indent provider: fix indent for empty braces
^KT-42411 Fixed
This commit is contained in:
+36
-28
@@ -46,13 +46,20 @@ abstract class KotlinLangLineIndentProvider : JavaLikeLangLineIndentProvider() {
|
||||
|
||||
when {
|
||||
after.isAt(BlockClosingBrace) && !currentPosition.hasLineBreaksAfter(offset) ->
|
||||
return factory.createIndentCalculatorForBrace(before, after, BlockOpeningBrace, BlockClosingBrace)
|
||||
return factory.createIndentCalculatorForBrace(before, after, BlockOpeningBrace, BlockClosingBrace, Indent.getNoneIndent())
|
||||
|
||||
before.isAt(BlockOpeningBrace) && after.isAt(BlockClosingBrace) ->
|
||||
return factory.createIndentCalculator(Indent.getNormalIndent(), before.startOffset)
|
||||
before.isAt(BlockOpeningBrace) && after.isAt(BlockClosingBrace) -> {
|
||||
return factory.createIndentCalculatorForBrace(before, after, BlockOpeningBrace, BlockClosingBrace, Indent.getNormalIndent())
|
||||
}
|
||||
|
||||
after.isAt(ArrayClosingBracket) && !currentPosition.hasLineBreaksAfter(offset) ->
|
||||
return factory.createIndentCalculatorForBrace(before, after, ArrayOpeningBracket, ArrayClosingBracket)
|
||||
return factory.createIndentCalculatorForBrace(
|
||||
before,
|
||||
after,
|
||||
ArrayOpeningBracket,
|
||||
ArrayClosingBracket,
|
||||
Indent.getNoneIndent()
|
||||
)
|
||||
|
||||
before.isAt(ArrayOpeningBracket) && after.isAt(ArrayClosingBracket) -> {
|
||||
val indent = if (isSimilarToFunctionInvocation(before))
|
||||
@@ -63,18 +70,15 @@ abstract class KotlinLangLineIndentProvider : JavaLikeLangLineIndentProvider() {
|
||||
return factory.createIndentCalculator(indent, before.startOffset)
|
||||
}
|
||||
|
||||
before.isAt(BlockOpeningBrace) && before.beforeIgnoringWhiteSpaceOrComment().isFunctionDeclaration() ->
|
||||
return factory.createIndentCalculator(Indent.getNormalIndent(), before.startOffset)
|
||||
|
||||
// KT-39716
|
||||
// after.isAt(Quest) && after.after().isAt(Colon) -> {
|
||||
// val indent = if (settings.continuationIndentInElvis)
|
||||
// Indent.getContinuationIndent()
|
||||
// else
|
||||
// Indent.getNormalIndent()
|
||||
//
|
||||
// return factory.createIndentCalculator(indent, before.startOffset)
|
||||
// }
|
||||
// KT-39716
|
||||
// after.isAt(Quest) && after.after().isAt(Colon) -> {
|
||||
// val indent = if (settings.continuationIndentInElvis)
|
||||
// Indent.getContinuationIndent()
|
||||
// else
|
||||
// Indent.getNormalIndent()
|
||||
//
|
||||
// return factory.createIndentCalculator(indent, before.startOffset)
|
||||
// }
|
||||
|
||||
before.isAt(Colon) && before.before().isAt(Quest) ->
|
||||
return factory.createIndentCalculator(Indent.getNoneIndent(), before.startOffset)
|
||||
@@ -214,18 +218,27 @@ abstract class KotlinLangLineIndentProvider : JavaLikeLangLineIndentProvider() {
|
||||
before: SemanticEditorPosition,
|
||||
after: SemanticEditorPosition,
|
||||
leftBraceType: SemanticEditorPosition.SyntaxElement,
|
||||
rightBraceType: SemanticEditorPosition.SyntaxElement
|
||||
): IndentCalculator? {
|
||||
rightBraceType: SemanticEditorPosition.SyntaxElement,
|
||||
defaultIndent: Indent
|
||||
): IndentCalculator {
|
||||
val leftBrace = before.copyAnd {
|
||||
it.moveToLeftParenthesisBackwardsSkippingNested(leftBraceType, rightBraceType)
|
||||
}
|
||||
|
||||
val indent = if (after.after().afterOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET).isAt(Comma))
|
||||
createAlignMultilineIndent(leftBrace)
|
||||
else
|
||||
Indent.getNoneIndent()
|
||||
if (after.after().afterOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET).isAt(Comma)) {
|
||||
return createIndentCalculator(createAlignMultilineIndent(leftBrace), leftBrace.startOffset)
|
||||
}
|
||||
|
||||
return createIndentCalculator(indent, leftBrace.startOffset)
|
||||
val beforeLeftBrace = leftBrace.copyAnd { it.moveBeforeIgnoringWhiteSpaceOrComment() }
|
||||
val leftAnchor = if (beforeLeftBrace.isAt(RightParenthesis)) {
|
||||
beforeLeftBrace.moveBeforeParentheses(LeftParenthesis, RightParenthesis)
|
||||
beforeLeftBrace
|
||||
} else {
|
||||
findFunctionDeclarationBeforeBody(beforeLeftBrace)
|
||||
}
|
||||
|
||||
val resultPosition = leftAnchor?.takeIf { !it.isAtEnd } ?: leftBrace
|
||||
return createIndentCalculator(defaultIndent, resultPosition.startOffset)
|
||||
}
|
||||
|
||||
private fun IndentCalculatorFactory.createIndentCalculatorForParenthesis(
|
||||
@@ -274,11 +287,6 @@ abstract class KotlinLangLineIndentProvider : JavaLikeLangLineIndentProvider() {
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* @receiver is position before '=' for expression body or '{' for block body
|
||||
*/
|
||||
private fun SemanticEditorPosition.isFunctionDeclaration(): Boolean = findFunctionDeclarationBeforeBody(this) != null
|
||||
|
||||
/**
|
||||
* @param endOfDeclaration is position before '=' for expression body or '{' for block body
|
||||
*/
|
||||
|
||||
+58
-10
@@ -93,16 +93,6 @@ public class PerformanceTypingIndentationTestGenerated extends AbstractPerforman
|
||||
runTest("idea/testData/indentationOnNewline/ConsecutiveCallsInSafeCallsEnd.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock.kt")
|
||||
public void testFunctionBlock() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/FunctionBlock.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock2.kt")
|
||||
public void testFunctionBlock2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/FunctionBlock2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("HigherOrderFunction.kt")
|
||||
public void testHigherOrderFunction() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/HigherOrderFunction.kt");
|
||||
@@ -567,6 +557,64 @@ public class PerformanceTypingIndentationTestGenerated extends AbstractPerforman
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/indentationOnNewline/emptyBraces")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EmptyBraces extends AbstractPerformanceTypingIndentationTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doPerfTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEmptyBraces() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/indentationOnNewline/emptyBraces"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstructor.kt")
|
||||
public void testClassWithConstructor() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/ClassWithConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstructor2.kt")
|
||||
public void testClassWithConstructor2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/ClassWithConstructor2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithoutConstructor.kt")
|
||||
public void testClassWithoutConstructor() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/ClassWithoutConstructor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock.kt")
|
||||
public void testFunctionBlock() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBlock.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock2.kt")
|
||||
public void testFunctionBlock2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBlock2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBody3.kt")
|
||||
public void testFunctionBody3() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBody3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBody4.kt")
|
||||
public void testFunctionBody4() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBody4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBodyInsideClass.kt")
|
||||
public void testFunctionBodyInsideClass() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBodyInsideClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBodyInsideClass2.kt")
|
||||
public void testFunctionBodyInsideClass2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBodyInsideClass2.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/indentationOnNewline/emptyParameters")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class A() {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
class A() {<caret>}
|
||||
@@ -0,0 +1,5 @@
|
||||
// IGNORE_FORMATTER
|
||||
class A(a: Int,
|
||||
b: Int) {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// IGNORE_FORMATTER
|
||||
class A(a: Int,
|
||||
b: Int) {<caret>}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class A {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
class A {<caret>}
|
||||
+1
-1
@@ -6,4 +6,4 @@ fun main(args: Array<String>) {
|
||||
times(3) {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -4,4 +4,4 @@ private fun <T> times(times : Int, body : () -> T) {}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
times(3) {<caret>}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// IGNORE_FORMATTER
|
||||
fun getLibraryModule(symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean): SwiftModule {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// IGNORE_FORMATTER
|
||||
fun getLibraryModule(symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean): SwiftModule {<caret>}
|
||||
@@ -0,0 +1,9 @@
|
||||
// IGNORE_FORMATTER
|
||||
fun getLibraryModule(
|
||||
symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean
|
||||
): SwiftModule {
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// IGNORE_FORMATTER
|
||||
fun getLibraryModule(
|
||||
symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean
|
||||
): SwiftModule { <caret> }
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// IGNORE_FORMATTER
|
||||
class A {
|
||||
fun getLibraryModule(symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean): SwiftModule {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// IGNORE_FORMATTER
|
||||
class A {
|
||||
fun getLibraryModule(symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean): SwiftModule { <caret> }
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// IGNORE_FORMATTER
|
||||
class A {
|
||||
fun getLibraryModule(
|
||||
symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean
|
||||
): SwiftModule {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// IGNORE_FORMATTER
|
||||
class A {
|
||||
fun getLibraryModule(
|
||||
symbol: ModuleMapSymbol,
|
||||
headersSearchRoot: HeadersSearchRoot,
|
||||
configuration: OCResolveConfiguration,
|
||||
isRootUpToDate: Boolean
|
||||
): SwiftModule { <caret> }
|
||||
}
|
||||
+71
-10
@@ -95,16 +95,6 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
|
||||
runTest("idea/testData/indentationOnNewline/ConsecutiveCallsInSafeCallsEnd.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock.after.kt")
|
||||
public void testFunctionBlock() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/FunctionBlock.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock2.after.kt")
|
||||
public void testFunctionBlock2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/FunctionBlock2.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("HigherOrderFunction.after.kt")
|
||||
public void testHigherOrderFunction() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/HigherOrderFunction.after.kt");
|
||||
@@ -569,6 +559,64 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/indentationOnNewline/emptyBraces")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EmptyBraces extends AbstractTypingIndentationTestBase {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doNewlineTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEmptyBraces() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/indentationOnNewline/emptyBraces"), Pattern.compile("^([^\\.]+)\\.after\\.kt.*$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstructor.after.kt")
|
||||
public void testClassWithConstructor() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/ClassWithConstructor.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithConstructor2.after.kt")
|
||||
public void testClassWithConstructor2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/ClassWithConstructor2.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ClassWithoutConstructor.after.kt")
|
||||
public void testClassWithoutConstructor() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/ClassWithoutConstructor.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock.after.kt")
|
||||
public void testFunctionBlock() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBlock.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBlock2.after.kt")
|
||||
public void testFunctionBlock2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBlock2.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBody3.after.kt")
|
||||
public void testFunctionBody3() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBody3.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBody4.after.kt")
|
||||
public void testFunctionBody4() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBody4.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBodyInsideClass.after.kt")
|
||||
public void testFunctionBodyInsideClass() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBodyInsideClass.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("FunctionBodyInsideClass2.after.kt")
|
||||
public void testFunctionBodyInsideClass2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/emptyBraces/FunctionBodyInsideClass2.after.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/indentationOnNewline/emptyParameters")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -1346,6 +1394,19 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/indentationOnNewline/emptyBraces")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EmptyBraces extends AbstractTypingIndentationTestBase {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doNewlineTestWithInvert, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEmptyBraces() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/indentationOnNewline/emptyBraces"), Pattern.compile("^([^\\.]+)\\.after\\.inv\\.kt.*$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/indentationOnNewline/emptyParameters")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user