diff --git a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRule.kt b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRule.kt index 848c09a367..055609684a 100644 --- a/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRule.kt +++ b/ktlint-ruleset-experimental/src/main/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRule.kt @@ -326,41 +326,18 @@ class IndentationRule : Rule("indent"), Rule.Modifier.RestrictToRootLast { autoCorrect: Boolean, emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit ) { - if ( - !node.nextCodeSibling()?.elementType.let { - it == DOT_QUALIFIED_EXPRESSION || - it == SAFE_ACCESS_EXPRESSION || - it == BINARY_EXPRESSION || - it == BINARY_WITH_TYPE - } || - !node.nextSubstringContains('\n') || - ( - mustBeFollowedByNewline(node) && - // force """ to be on a separate line - !node.nextCodeLeaf().let { it?.elementType == OPEN_QUOTE && it.text == "\"\"\"" } - ) - ) { + // force """ to be on a separate line + if (!node.nextCodeLeaf().isRawString()) { return } val nextCodeLeaf = node.nextCodeLeaf()!! - // val v = (... - if (nextCodeLeaf.elementType in lTokenSet) { - return - } if (!nextCodeLeaf.prevLeaf().isWhiteSpaceWithNewline()) { requireNewlineAfterLeaf(node, autoCorrect, emit) } } - private fun ASTNode.nextSubstringContains(c: Char): Boolean { - var n = this.treeNext - while (n != null) { - if (n.textContains(c)) { - return true - } - n = n.treeNext - } - return false + private fun ASTNode?.isRawString(): Boolean { + return this?.elementType == OPEN_QUOTE && this.text == "\"\"\"" } private fun mustBeFollowedByNewline(node: ASTNode): Boolean { diff --git a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRuleTest.kt b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRuleTest.kt index 29a1275c8a..f1a8972ee1 100644 --- a/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRuleTest.kt +++ b/ktlint-ruleset-experimental/src/test/kotlin/com/pinterest/ktlint/ruleset/experimental/IndentationRuleTest.kt @@ -304,4 +304,22 @@ class IndentationRuleTest { assertThat(IndentationRule().format(ktScript, mapOf("indent_size" to "2"))) .isEqualTo("fun main() {\n return 0\n}") } + + @Test + fun testLintNewlineAfterEqAllowed() { + assertThat( + IndentationRule().lint( + // Previously the IndentationRule would force the line break after the `=`. Verify that it is + // still allowed. + """ + private fun getImplementationVersion() = + javaClass.`package`.implementationVersion + ?: javaClass.getResourceAsStream("/META-INF/MANIFEST.MF") + ?.let { stream -> + Manifest(stream).mainAttributes.getValue("Implementation-Version") + } + """.trimIndent() + ) + ).isEmpty() + } } diff --git a/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-dot-qualified-expression-expected.kt.spec b/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-dot-qualified-expression-expected.kt.spec index e553cd2cc8..ae0564eb1f 100644 --- a/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-dot-qualified-expression-expected.kt.spec +++ b/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-dot-qualified-expression-expected.kt.spec @@ -1,10 +1,9 @@ class A { - private fun getImplementationVersion() = - javaClass.`package`.implementationVersion - ?: javaClass.getResourceAsStream("/META-INF/MANIFEST.MF") - ?.let { stream -> - Manifest(stream).mainAttributes.getValue("Implementation-Version") - } + private fun getImplementationVersion() = javaClass.`package`.implementationVersion + ?: javaClass.getResourceAsStream("/META-INF/MANIFEST.MF") + ?.let { stream -> + Manifest(stream).mainAttributes.getValue("Implementation-Version") + } fun f() { x()?.apply { diff --git a/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-eq-expected.kt.spec b/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-eq-expected.kt.spec index 70da5957f1..c34e74c9c3 100644 --- a/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-eq-expected.kt.spec +++ b/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-eq-expected.kt.spec @@ -5,21 +5,19 @@ class C { } fun f() { - val x = - "a" + - "b2" + val x = "a" + + "b2" val x = "a" + "b2" - val x = - paths.flatMap { dir -> - "hello" - } + f0( - "there" - ) + f1( - "sssss" - ) + val x = paths.flatMap { dir -> + "hello" + } + f0( + "there" + ) + f1( + "sssss" + ) fun Exception.toLintError(): LintError = this.let { e -> // diff --git a/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-property-accessor-expected.kt.spec b/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-property-accessor-expected.kt.spec index 79e52febef..e7cc860f32 100644 --- a/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-property-accessor-expected.kt.spec +++ b/ktlint-ruleset-experimental/src/test/resources/spec/indent/format-property-accessor-expected.kt.spec @@ -1,9 +1,8 @@ class C { private val Any.className - get() = - this.javaClass.name - .fn() + get() = this.javaClass.name + .fn() private fun String.escape() = this.fn() diff --git a/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt b/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt index 65ccba3af7..41a47f68b1 100644 --- a/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt +++ b/ktlint/src/main/kotlin/com/pinterest/ktlint/Main.kt @@ -53,7 +53,8 @@ import picocli.CommandLine.Option import picocli.CommandLine.Parameters @Command( - headerHeading = """An anti-bikeshedding Kotlin linter with built-in formatter + headerHeading = +"""An anti-bikeshedding Kotlin linter with built-in formatter (https://github.com/shyiko/ktlint). Usage: