LineIndentProvider: fix for do-while
Part of #KT-22211
This commit is contained in:
+41
-16
@@ -80,43 +80,68 @@ abstract class KotlinLikeLangLineIndentProvider : JavaLikeLangLineIndentProvider
|
||||
Indent.getNoneIndent(),
|
||||
IndentCalculator.LINE_BEFORE,
|
||||
)
|
||||
}
|
||||
|
||||
before.isInControlFlowStatement() -> return factory.createIndentCalculator(
|
||||
before.controlFlowStatementBefore()?.let { controlFlowKeywordPosition ->
|
||||
return factory.createIndentCalculator(
|
||||
when {
|
||||
after.isAt(LeftParenthesis) -> Indent.getContinuationIndent()
|
||||
after.isAtAnyOf(BlockOpeningBrace, Arrow) -> Indent.getNoneIndent()
|
||||
after.isAtAnyOf(BlockOpeningBrace, Arrow) || controlFlowKeywordPosition.isWhileInsideDoWhile() -> Indent.getNoneIndent()
|
||||
else -> Indent.getNormalIndent()
|
||||
},
|
||||
IndentCalculator.LINE_BEFORE,
|
||||
)
|
||||
}
|
||||
|
||||
after
|
||||
.takeIf { it.isAt(TemplateEntryClose) }
|
||||
?.let { templateEntryPosition ->
|
||||
val indent = if (currentPosition.hasEmptyLineAfter(offset)) Indent.getNormalIndent() else Indent.getNoneIndent()
|
||||
templateEntryPosition.moveBeforeParentheses(TemplateEntryOpen, TemplateEntryClose)
|
||||
val baseLineOffset = templateEntryPosition.startOffset
|
||||
return factory.createIndentCalculator(indent) { baseLineOffset }
|
||||
}
|
||||
after.takeIf { it.isAt(TemplateEntryClose) }?.let { templateEntryPosition ->
|
||||
val indent = if (currentPosition.hasEmptyLineAfter(offset)) Indent.getNormalIndent() else Indent.getNoneIndent()
|
||||
templateEntryPosition.moveBeforeParentheses(TemplateEntryOpen, TemplateEntryClose)
|
||||
val baseLineOffset = templateEntryPosition.startOffset
|
||||
return factory.createIndentCalculator(indent) { baseLineOffset }
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun SemanticEditorPosition.isInControlFlowStatement(): Boolean = with(copy()) {
|
||||
private fun SemanticEditorPosition.moveBeforeIfThisIsWhiteSpaceOrComment() = moveBeforeOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
|
||||
|
||||
private fun SemanticEditorPosition.isWhileInsideDoWhile(): Boolean {
|
||||
if (!isAt(WhileKeyword)) return false
|
||||
with(copy()) {
|
||||
moveBefore()
|
||||
var whileKeywordLevel = 1
|
||||
while (!isAtEnd) when {
|
||||
isAt(BlockOpeningBrace) -> return false
|
||||
isAt(DoKeyword) -> {
|
||||
if (--whileKeywordLevel == 0) return true
|
||||
moveBefore()
|
||||
}
|
||||
isAt(WhileKeyword) -> {
|
||||
++whileKeywordLevel
|
||||
moveBefore()
|
||||
}
|
||||
isAt(BlockClosingBrace) -> moveBeforeParentheses(BlockOpeningBrace, BlockClosingBrace)
|
||||
else -> moveBefore()
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun SemanticEditorPosition.controlFlowStatementBefore(): SemanticEditorPosition? = with(copy()) {
|
||||
if (isAt(BlockOpeningBrace)) {
|
||||
moveBefore()
|
||||
moveBeforeParentheses(LeftParenthesis, RightParenthesis)
|
||||
moveBeforeOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
|
||||
moveBeforeIfThisIsWhiteSpaceOrComment()
|
||||
}
|
||||
|
||||
if (currElement in CONTROL_FLOW_CONSTRUCTIONS) return true
|
||||
if (!isAt(RightParenthesis)) return false
|
||||
if (currElement in CONTROL_FLOW_CONSTRUCTIONS) return this
|
||||
if (!isAt(RightParenthesis)) return null
|
||||
|
||||
moveBeforeParentheses(LeftParenthesis, RightParenthesis)
|
||||
moveBeforeOptionalMix(*WHITE_SPACE_OR_COMMENT_BIT_SET)
|
||||
moveBeforeIfThisIsWhiteSpaceOrComment()
|
||||
|
||||
return currElement in CONTROL_FLOW_CONSTRUCTIONS
|
||||
return takeIf { currElement in CONTROL_FLOW_CONSTRUCTIONS }
|
||||
}
|
||||
|
||||
enum class KotlinElement : SemanticEditorPosition.SyntaxElement {
|
||||
|
||||
+35
@@ -118,6 +118,41 @@ public class PerformanceTypingIndentationTestGenerated extends AbstractPerforman
|
||||
runTest("idea/testData/indentationOnNewline/DoInFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile.kt")
|
||||
public void testDoWhile() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile2.kt")
|
||||
public void testDoWhile2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile3.kt")
|
||||
public void testDoWhile3() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile3.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile4.kt")
|
||||
public void testDoWhile4() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile4.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile5.kt")
|
||||
public void testDoWhile5() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile5.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile6.kt")
|
||||
public void testDoWhile6() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile6.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile7.kt")
|
||||
public void testDoWhile7() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile7.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWithBraces.kt")
|
||||
public void testDoWithBraces() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWithBraces.kt");
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
fun some() {
|
||||
do println() while (true)
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun some() {
|
||||
do println() while (true)<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun some() {
|
||||
do do println() while (true) while (true)
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun some() {
|
||||
do do println() while (true) while (true)<caret>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fun some() {
|
||||
do {
|
||||
while (true) println()
|
||||
} while (true)
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some() {
|
||||
do {
|
||||
while (true) println()
|
||||
} while (true)<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun some() {
|
||||
while (true)
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun some() {
|
||||
while (true)<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some() {
|
||||
while (true)
|
||||
while (true)
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
fun some() {
|
||||
while (true)
|
||||
while (true)<caret>
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fun some() {
|
||||
while (true) {
|
||||
println()
|
||||
}
|
||||
|
||||
while (true)
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun some() {
|
||||
while (true) {
|
||||
println()
|
||||
}
|
||||
|
||||
while (true)<caret>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
fun some() {
|
||||
do println() while (true)
|
||||
println()
|
||||
while (true)
|
||||
<caret>
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun some() {
|
||||
do println() while (true)
|
||||
println()
|
||||
while (true)<caret>
|
||||
}
|
||||
+35
@@ -120,6 +120,41 @@ public class TypingIndentationTestBaseGenerated extends AbstractTypingIndentatio
|
||||
runTest("idea/testData/indentationOnNewline/DoInFun.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile.after.kt")
|
||||
public void testDoWhile() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile2.after.kt")
|
||||
public void testDoWhile2() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile2.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile3.after.kt")
|
||||
public void testDoWhile3() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile3.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile4.after.kt")
|
||||
public void testDoWhile4() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile4.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile5.after.kt")
|
||||
public void testDoWhile5() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile5.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile6.after.kt")
|
||||
public void testDoWhile6() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile6.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWhile7.after.kt")
|
||||
public void testDoWhile7() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWhile7.after.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DoWithBraces.after.kt")
|
||||
public void testDoWithBraces() throws Exception {
|
||||
runTest("idea/testData/indentationOnNewline/DoWithBraces.after.kt");
|
||||
|
||||
Reference in New Issue
Block a user