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

Commit

Permalink
Remove extra blank lines which appear when all imports are removed fr…
Browse files Browse the repository at this point in the history
…om a file.
  • Loading branch information
hovinen committed Feb 18, 2021
1 parent cf0ba80 commit 4113647
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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.ForcedBreakToken
import org.kotlin.formatter.LeafNodeToken
import org.kotlin.formatter.Token
import org.kotlin.formatter.scanning.nodepattern.NodePatternBuilder
import org.kotlin.formatter.scanning.nodepattern.nodePattern

/** A [NodeScanner] for a full Kotlin file. */
internal class KotlinFileScanner(private val kotlinScanner: KotlinScanner) : NodeScanner {
private val nodePattern =
nodePattern {
either {
nonEmptyPackageDirective() thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.BLOCK)
}
possibleWhitespace()
exactlyOne {
nodeOfType(KtNodeTypes.IMPORT_LIST) thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.BLOCK)
}
} thenMapTokens { tokens ->
if (tokens.filterIsInstance<LeafNodeToken>().isNotEmpty()) {
listOf(ForcedBreakToken(count = 2)).plus(tokens)
} else {
listOf()
}
}
nodeOfType(KtNodeTypes.SCRIPT) thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.BLOCK)
}
} or {
nodeOfType(KtNodeTypes.PACKAGE_DIRECTIVE)
possibleWhitespace()
nodeOfType(KtNodeTypes.IMPORT_LIST) thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.BLOCK)
}
nodeOfType(KtNodeTypes.SCRIPT) thenMapToTokens { nodes ->
kotlinScanner.scanNodes(nodes, ScannerState.BLOCK)
}
}
end()
}

private fun NodePatternBuilder.nonEmptyPackageDirective(): NodePatternBuilder =
nodeMatching { it.elementType == KtNodeTypes.PACKAGE_DIRECTIVE && it.text.isNotBlank() }

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 @@ -23,6 +23,7 @@ internal class NodeScannerProvider(
private val kotlinScanner: KotlinScanner,
private val importPolicy: (String, String) -> Boolean
) {
private val kotlinFileScanner = lazy { KotlinFileScanner(kotlinScanner) }
private val blockScanner = lazy { BlockScanner(kotlinScanner) }
private val whenExpressionScanner = lazy { WhenExpressionScanner(kotlinScanner) }
private val ifExpressionScanner = lazy { IfExpressionScanner(kotlinScanner) }
Expand Down Expand Up @@ -116,6 +117,7 @@ internal class NodeScannerProvider(
KtNodeTypes.PARENTHESIZED -> parenthesizedScanner.value
KtNodeTypes.LABELED_EXPRESSION -> labeledExpressionScanner.value
KtNodeTypes.ANNOTATED_EXPRESSION -> annotatedExpressionScanner.value
KtFileElementType.INSTANCE -> kotlinFileScanner.value
KtFileElementType.INSTANCE, is KtScriptElementType,
KtNodeTypes.LITERAL_STRING_TEMPLATE_ENTRY -> simpleScannerForBlock.value
KtNodeTypes.WHEN_ENTRY, KtNodeTypes.ANNOTATION_ENTRY, KtNodeTypes.PREFIX_EXPRESSION,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5406,6 +5406,29 @@ class KotlinFormatterTest {
)
}

@Test
fun `removes the spacing for imports when all imports are removed`() {
val result =
KotlinFormatter()
.format(
"""
package apackage
import apackage.AClass
class MyClass
""".trimIndent()
)

assertThat(result).isEqualTo(
"""
package apackage
class MyClass
""".trimIndent()
)
}

@Test
fun `removes imports when directed`() {
val importPolicy: ImportPolicy = { importName, importPath ->
Expand Down

0 comments on commit 4113647

Please sign in to comment.