Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unwanted whitespace between super class constructor and its argument list #2630

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,21 @@ public class ClassSignatureRule :
}
}

// Disallow:
// class Foo : Bar<String> ("foobar")
superTypes
.filter { it.elementType == SUPER_TYPE_CALL_ENTRY }
.forEach { superTypeCallEntry ->
superTypeCallEntry
.findChildByType(WHITE_SPACE)
?.let { whitespace ->
emit(whitespace.startOffset, "No whitespace expected", true)
if (autoCorrect) {
whitespace.treeParent.removeChild(whitespace)
}
}
}

return whiteSpaceCorrection
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.pinterest.ktlint.rule.engine.core.api.ElementType.LPAR
import com.pinterest.ktlint.rule.engine.core.api.ElementType.PRIMARY_CONSTRUCTOR
import com.pinterest.ktlint.rule.engine.core.api.ElementType.RPAR
import com.pinterest.ktlint.rule.engine.core.api.ElementType.SUPER_KEYWORD
import com.pinterest.ktlint.rule.engine.core.api.ElementType.TYPE_ARGUMENT_LIST
import com.pinterest.ktlint.rule.engine.core.api.ElementType.VALUE_ARGUMENT_LIST
import com.pinterest.ktlint.rule.engine.core.api.ElementType.VALUE_PARAMETER_LIST
import com.pinterest.ktlint.rule.engine.core.api.RuleId
Expand Down Expand Up @@ -46,7 +47,8 @@ public class SpacingAroundParensRule : StandardRule("paren-spacing") {
node.treeParent?.treeParent?.elementType != FUNCTION_TYPE ||
// Super keyword needs special-casing
prevLeaf.prevLeaf()?.elementType == SUPER_KEYWORD ||
prevLeaf.prevLeaf()?.treeParent?.elementType == PRIMARY_CONSTRUCTOR
prevLeaf.prevLeaf()?.treeParent?.elementType == PRIMARY_CONSTRUCTOR ||
prevLeaf.prevLeaf()?.treeParent?.elementType == TYPE_ARGUMENT_LIST
) &&
(
node.treeParent?.elementType == VALUE_PARAMETER_LIST ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,55 @@ class ClassSignatureRuleTest {
.hasNoLintViolations()
}

@Nested
inner class `Issue 2630 - White space in super type call entry` {
@Test
fun `Issue 2630 - Given a super type call entry without type argument list`() {
val code =
"""
class Foo1 : Bar("foobar")
class Foo2 : Bar ("foobar")
class Foo3 : Bar
("foobar")
""".trimIndent()
val formattedCode =
"""
class Foo1 : Bar("foobar")
class Foo2 : Bar("foobar")
class Foo3 : Bar("foobar")
""".trimIndent()
classSignatureWrappingRuleAssertThat(code)
.hasLintViolations(
LintViolation(2, 17, "No whitespace expected"),
LintViolation(3, 14, "Super type should start on a newline"),
LintViolation(3, 17, "No whitespace expected"),
).isFormattedAs(formattedCode)
}

@Test
fun `Issue 2630 - Given a super type call entry with type argument list`() {
val code =
"""
class Foo1 : Bar<String>("foobar")
class Foo2 : Bar<String> ("foobar")
class Foo3 : Bar<String>
("foobar")
""".trimIndent()
val formattedCode =
"""
class Foo1 : Bar<String>("foobar")
class Foo2 : Bar<String>("foobar")
class Foo3 : Bar<String>("foobar")
""".trimIndent()
classSignatureWrappingRuleAssertThat(code)
.hasLintViolations(
LintViolation(2, 25, "No whitespace expected"),
LintViolation(3, 14, "Super type should start on a newline"),
LintViolation(3, 25, "No whitespace expected"),
).isFormattedAs(formattedCode)
}
}

private companion object {
const val UNEXPECTED_SPACES = " "
const val NO_SPACE = ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,40 @@ class SpacingAroundParensRuleTest {
.isFormattedAs(formattedCode)
}

@Test
fun `Given class with superclass constructor call`() {
val code =
"""
open class Bar(param: String)
class Foo : Bar ("test")
""".trimIndent()
val formattedCode =
"""
open class Bar(param: String)
class Foo : Bar("test")
""".trimIndent()
spacingAroundParensRuleAssertThat(code)
.hasLintViolation(2, 16, "Unexpected spacing before \"(\"")
.isFormattedAs(formattedCode)
}

@Test
fun `Given class with superclass constructor call with type parameter`() {
val code =
"""
open class Bar<T>(param: T)
class Foo : Bar<String> ("test")
""".trimIndent()
val formattedCode =
"""
open class Bar<T>(param: T)
class Foo : Bar<String>("test")
""".trimIndent()
spacingAroundParensRuleAssertThat(code)
.hasLintViolation(2, 24, "Unexpected spacing before \"(\"")
.isFormattedAs(formattedCode)
}

@Test
fun `Given a variable declaration with unexpected spacing around the opening parenthesis of the expression`() {
val code =
Expand Down