LineIndentProvider: support elvis operator

Part of #KT-22211
This commit is contained in:
Dmitry Gridin
2020-06-09 12:35:00 +07:00
parent cf655a829c
commit f833b4fe63
20 changed files with 227 additions and 6 deletions
@@ -13,4 +13,8 @@ interface KotlinIndentationAdjuster {
// ALIGN_MULTILINE_BINARY_OPERATION
val alignWhenMultilineBinaryExpression: Boolean
get() = false
// CONTINUATION_INDENT_IN_ELVIS
val continuationIndentInElvis: Boolean
get() = false
}
@@ -68,6 +68,18 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
val before = currentPosition.beforeOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
val after = currentPosition.afterOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
when {
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)
before.isAt(TemplateEntryOpen) -> {
val indent = if (!currentPosition.hasLineBreaksAfter(offset) && after.isAt(TemplateEntryClose))
Indent.getNoneIndent()
@@ -77,10 +89,8 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
return factory.createIndentCalculator(indent, before.startOffset)
}
before.isAtAnyOf(TryKeyword) || before.isFinallyKeyword() -> return factory.createIndentCalculator(
Indent.getNoneIndent(),
IndentCalculator.LINE_BEFORE,
)
before.isAtAnyOf(TryKeyword) || before.isFinallyKeyword() ->
return factory.createIndentCalculator(Indent.getNoneIndent(), IndentCalculator.LINE_BEFORE)
after.isAt(TemplateEntryClose) -> {
val indent = if (currentPosition.hasEmptyLineAfter(offset)) Indent.getNormalIndent() else Indent.getNoneIndent()
@@ -456,8 +466,7 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
private fun JavaLikeLangLineIndentProvider.IndentCalculatorFactory.createIndentCalculator(
indent: Indent,
baseLineOffset: Int,
): IndentCalculator =
createIndentCalculator(indent) { baseLineOffset } ?: error("Contract (null, _ -> null) is broken")
): IndentCalculator = createIndentCalculator(indent) { baseLineOffset } ?: error("Contract (null, _ -> null) is broken")
private fun SemanticEditorPosition.textOfCurrentPosition(): String =
if (isAtEnd) "" else chars.subSequence(startOffset, after().startOffset).toString()
@@ -903,6 +903,44 @@ public class PerformanceTypingIndentationTestGenerated extends AbstractPerforman
runTest("idea/testData/indentationOnNewline/WhileWithoutCondition.kt");
}
@TestMetadata("idea/testData/indentationOnNewline/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Elvis extends AbstractPerformanceTypingIndentationTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doPerfTest, this, testDataFilePath);
}
@TestMetadata("AfterElvis.kt")
public void testAfterElvis() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvis.kt");
}
@TestMetadata("AfterElvis2.kt")
public void testAfterElvis2() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvis2.kt");
}
@TestMetadata("AfterElvisInBinaryExpression.kt")
public void testAfterElvisInBinaryExpression() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvisInBinaryExpression.kt");
}
public void testAllFilesPresentInElvis() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/indentationOnNewline/elvis"), Pattern.compile("^([^.]+)\\.(kt|kts)$"), null, true);
}
@TestMetadata("BeforeElvis.kt")
public void testBeforeElvis() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/BeforeElvis.kt");
}
@TestMetadata("BeforeElvisInBinaryExpression.kt")
public void testBeforeElvisInBinaryExpression() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/BeforeElvisInBinaryExpression.kt");
}
}
@TestMetadata("idea/testData/indentationOnNewline/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -28,6 +28,9 @@ class KotlinLineIndentProvider : KotlinLikeLangLineIndentProvider() {
override val alignWhenMultilineBinaryExpression: Boolean
get() = settings.kotlinCommonSettings.ALIGN_MULTILINE_BINARY_OPERATION
override val continuationIndentInElvis: Boolean
get() = settings.kotlinCustomSettings.CONTINUATION_INDENT_IN_ELVIS
}
companion object {
@@ -0,0 +1,6 @@
fun test(some: Any?, error: Int) {
val test = some ?:
<caret>error
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,6 @@
fun test(some: Any?, error: Int) {
val test = some ?:
<caret>error
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,5 @@
fun test(some: Any?, error: Int) {
val test = some ?:<caret> error
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,8 @@
fun test(some: Any?, error: Int) {
some?.let {
println(some)
} ?:
<caret>println(error)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,8 @@
fun test(some: Any?, error: Int) {
some?.let {
println(some)
} ?:
<caret>println(error)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,7 @@
fun test(some: Any?, error: Int) {
some?.let {
println(some)
} ?: <caret>println(error)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,6 @@
fun a() {
println(1 + null ?:
<caret>2)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,6 @@
fun a() {
println(1 + null ?:
<caret>2)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,5 @@
fun a() {
println(1 + null ?: <caret>2)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,6 @@
fun test(some: Any?, error: Int) {
val test = some
<caret>?: error
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,6 @@
fun test(some: Any?, error: Int) {
val test = some
<caret>?: error
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,5 @@
fun test(some: Any?, error: Int) {
val test = some <caret>?: error
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,6 @@
fun a() {
println(1 + null
<caret>?: 2)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,6 @@
fun a() {
println(1 + null
<caret>?: 2)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -0,0 +1,5 @@
fun a() {
println(1 + null <caret>?: 2)
}
// SET_FALSE: CONTINUATION_INDENT_IN_ELVIS
@@ -900,6 +900,44 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
runTest("idea/testData/indentationOnNewline/WhileWithoutCondition.after.kt");
}
@TestMetadata("idea/testData/indentationOnNewline/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Elvis extends AbstractTypingIndentationTestBase {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doNewlineTest, this, testDataFilePath);
}
@TestMetadata("AfterElvis.after.kt")
public void testAfterElvis() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvis.after.kt");
}
@TestMetadata("AfterElvis2.after.kt")
public void testAfterElvis2() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvis2.after.kt");
}
@TestMetadata("AfterElvisInBinaryExpression.after.kt")
public void testAfterElvisInBinaryExpression() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvisInBinaryExpression.after.kt");
}
public void testAllFilesPresentInElvis() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/indentationOnNewline/elvis"), Pattern.compile("^([^\\.]+)\\.after\\.kt.*$"), null, true);
}
@TestMetadata("BeforeElvis.after.kt")
public void testBeforeElvis() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/BeforeElvis.after.kt");
}
@TestMetadata("BeforeElvisInBinaryExpression.after.kt")
public void testBeforeElvisInBinaryExpression() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/BeforeElvisInBinaryExpression.after.kt");
}
}
@TestMetadata("idea/testData/indentationOnNewline/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -1076,6 +1114,44 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
runTest("idea/testData/indentationOnNewline/SettingAlignMultilineParametersInCalls.after.inv.kt");
}
@TestMetadata("idea/testData/indentationOnNewline/elvis")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Elvis extends AbstractTypingIndentationTestBase {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doNewlineTestWithInvert, this, testDataFilePath);
}
@TestMetadata("AfterElvis.after.inv.kt")
public void testAfterElvis() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvis.after.inv.kt");
}
@TestMetadata("AfterElvis2.after.inv.kt")
public void testAfterElvis2() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvis2.after.inv.kt");
}
@TestMetadata("AfterElvisInBinaryExpression.after.inv.kt")
public void testAfterElvisInBinaryExpression() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/AfterElvisInBinaryExpression.after.inv.kt");
}
public void testAllFilesPresentInElvis() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/indentationOnNewline/elvis"), Pattern.compile("^([^\\.]+)\\.after\\.inv\\.kt.*$"), null, true);
}
@TestMetadata("BeforeElvis.after.inv.kt")
public void testBeforeElvis() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/BeforeElvis.after.inv.kt");
}
@TestMetadata("BeforeElvisInBinaryExpression.after.inv.kt")
public void testBeforeElvisInBinaryExpression() throws Exception {
runTest("idea/testData/indentationOnNewline/elvis/BeforeElvisInBinaryExpression.after.inv.kt");
}
}
@TestMetadata("idea/testData/indentationOnNewline/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)