Skip to content
This repository has been archived by the owner on Jun 4, 2024. It is now read-only.

Commit

Permalink
Fix the formatting of function parameters whose types are functions w…
Browse files Browse the repository at this point in the history
…ith modifier lists.

These were not treated properly as blocks before, resulting in line breaks being inserted incorrectly and without proper indentation.
  • Loading branch information
hovinen committed Mar 18, 2021
1 parent 837f1c7 commit 2c2cf35
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ internal class NodeScannerProvider(
private val parenthesizedScanner = lazy { ParenthesizedScanner(kotlinScanner) }
private val labeledExpressionScanner = lazy { LabeledExpressionScanner(kotlinScanner) }
private val annotatedExpressionScanner = lazy { AnnotatedExpressionScanner(kotlinScanner) }
private val typeReferenceScanner = lazy { TypeReferenceScanner(kotlinScanner) }
private val simpleScannerForBlock = lazy { SimpleScanner(kotlinScanner, ScannerState.BLOCK) }
private val simpleBlockScanner =
lazy { SimpleBlockScanner(kotlinScanner, ScannerState.STATEMENT, State.CODE) }
Expand Down Expand Up @@ -122,6 +123,7 @@ internal class NodeScannerProvider(
KtFileElementType.INSTANCE -> kotlinFileScanner.value
KtFileElementType.INSTANCE, is KtScriptElementType,
KtNodeTypes.LITERAL_STRING_TEMPLATE_ENTRY -> simpleScannerForBlock.value
KtNodeTypes.TYPE_REFERENCE -> typeReferenceScanner.value
KtNodeTypes.WHEN_ENTRY, KtNodeTypes.ANNOTATION_ENTRY, KtNodeTypes.PREFIX_EXPRESSION,
KtNodeTypes.VALUE_PARAMETER, KtNodeTypes.SUPER_TYPE_ENTRY,
KtNodeTypes.SUPER_TYPE_CALL_ENTRY, KtNodeTypes.USER_TYPE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import org.kotlin.formatter.ClosingSynchronizedBreakToken
import org.kotlin.formatter.ForcedBreakToken
import org.kotlin.formatter.LeafNodeToken
import org.kotlin.formatter.MarkerToken
import org.kotlin.formatter.State
import org.kotlin.formatter.SynchronizedBreakToken
import org.kotlin.formatter.Token
import org.kotlin.formatter.WhitespaceToken
import org.kotlin.formatter.inBeginEndBlock
import org.kotlin.formatter.scanning.nodepattern.NodePatternBuilder
import org.kotlin.formatter.scanning.nodepattern.nodePattern

Expand Down Expand Up @@ -130,8 +132,26 @@ internal class ParameterListScanner(private val kotlinScanner: KotlinScanner) :
tokens
}
}
oneOrMore { anyNode() } thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.STATEMENT).plus(BlockFromMarkerToken)
either {
nodeOfType(KtTokens.IDENTIFIER) thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.STATEMENT)
}
possibleWhitespace()
nodeOfType(KtTokens.COLON) thenMapToTokens { listOf(LeafNodeToken(":")) }
possibleWhitespace() thenMapToTokens { nodes ->
listOf(WhitespaceToken(nodes.map { it.text }.firstOrNull() ?: " "))
}
nodeOfType(KtNodeTypes.TYPE_REFERENCE) thenMapToTokens { nodes ->
inBeginEndBlock(
kotlinScanner.scanNodes(nodes, ScannerState.STATEMENT),
State.CODE
).plus(BlockFromMarkerToken)
}
} or {
oneOrMore { anyNode() } thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.STATEMENT)
.plus(BlockFromMarkerToken)
}
}
end()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.kotlin.formatter.scanning

import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.psi.psiUtil.children
import org.kotlin.formatter.Token
import org.kotlin.formatter.scanning.nodepattern.nodePattern

/** A [NodeScanner] for references to types. */
internal class TypeReferenceScanner(private val kotlinScanner: KotlinScanner) : NodeScanner {
private val nodePattern =
nodePattern {
zeroOrOne {
nodeOfType(KtNodeTypes.MODIFIER_LIST) thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.STATEMENT)
}
}
possibleWhitespace()
oneOrMore { anyNode() } thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.STATEMENT)
}
end()
}

override fun scan(node: ASTNode, scannerState: ScannerState): List<Token> =
nodePattern.matchSequence(node.children().asIterable())
}
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,29 @@ class KotlinFormatterTest {
)
}

@Test
fun `correctly indents parameter list when parameter is a suspend function`() {
val result =
KotlinFormatter(maxLineLength = 31)
.format("""fun aFunction(aParameter: suspend () -> T)""".trimIndent())

assertThat(result)
.isEqualTo(
"""
fun aFunction(
aParameter: suspend () -> T
)
""".trimIndent()
)
}

@Test
fun `fixes spacing around function parameter`() {
val result = KotlinFormatter().format("""fun aFunction(aParameter :T)""".trimIndent())

assertThat(result).isEqualTo("""fun aFunction(aParameter: T)""".trimIndent())
}

@Test
fun `does not break empty parameter list`() {
val result =
Expand Down

0 comments on commit 2c2cf35

Please sign in to comment.