-
Notifications
You must be signed in to change notification settings - Fork 512
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add rule to report discouraged comment locations (#1365)
Autocorrect is not implemented. This is an error which only happens rarely. Its value is that it makes implementation of some rules way easier when comment do not have to be taken into account. Initial implementation just contains one single discouraged location. More will follow when implementing the rule to rewrite the function signature automatically as is described in #1341.
- Loading branch information
1 parent
14c0adf
commit ec1f3f3
Showing
5 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...c/main/kotlin/com/pinterest/ktlint/ruleset/experimental/DiscouragedCommentLocationRule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.pinterest.ktlint.ruleset.experimental | ||
|
||
import com.pinterest.ktlint.core.Rule | ||
import com.pinterest.ktlint.core.ast.ElementType.TYPE_PARAMETER_LIST | ||
import com.pinterest.ktlint.core.ast.isPartOfComment | ||
import com.pinterest.ktlint.core.ast.prevCodeSibling | ||
import org.jetbrains.kotlin.com.intellij.lang.ASTNode | ||
|
||
/** | ||
* The AST allows comments to be placed anywhere. This however can lead to code which is unnecessarily hard to read. | ||
* Disallowing comments at certain positions in the AST makes development of a rule easier as they have not to be taken | ||
* into account in that rule. | ||
* | ||
* In examples below, a comment is placed between a type parameter list and the function name. Such comments are badly | ||
* handled by default IntelliJ IDEA code formatter. We should put no effort in making and keeping ktlint in sync with | ||
* such bad code formatting. | ||
* | ||
* ``` | ||
* fun <T> | ||
* // some comment | ||
* foo(t: T) = "some-result" | ||
* | ||
* fun <T> | ||
* /* some comment | ||
* * | ||
* */ | ||
* foo(t: T) = "some-result" | ||
* ``` | ||
*/ | ||
public class DiscouragedCommentLocationRule : Rule("discouraged-comment-location") { | ||
override fun visit( | ||
node: ASTNode, | ||
autoCorrect: Boolean, | ||
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit | ||
) { | ||
node | ||
.takeIf { it.isPartOfComment() } | ||
?.prevCodeSibling() | ||
?.let { codeSiblingBeforeComment -> | ||
// Be restrictive when adding new locations at which comments are discouraged. Always run against major | ||
// open source projects first to verify whether valid cases are found to comment at this location. | ||
if (codeSiblingBeforeComment.elementType == TYPE_PARAMETER_LIST) { | ||
emit( | ||
node.startOffset, | ||
"No comment expected at this location", | ||
false | ||
) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
...c/test/kotlin/com/pinterest/ktlint/ruleset/experimental/DiscouragedCommentLocationTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package com.pinterest.ktlint.ruleset.experimental | ||
|
||
import com.pinterest.ktlint.core.LintError | ||
import com.pinterest.ktlint.test.format | ||
import com.pinterest.ktlint.test.lint | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.Test | ||
|
||
class DiscouragedCommentLocationTest { | ||
@Test | ||
fun `Given an EOL comment after a type parameter then report a discouraged comment location`() { | ||
val code = | ||
""" | ||
fun <T> // some comment | ||
foo(t: T) = "some-result" | ||
""".trimIndent() | ||
assertThat(DiscouragedCommentLocationRule().lint(code)).containsExactly( | ||
LintError(1, 9, "discouraged-comment-location", "No comment expected at this location") | ||
) | ||
assertThat(DiscouragedCommentLocationRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given an EOL comment on a newline after a type parameter then report a discouraged comment location`() { | ||
val code = | ||
""" | ||
fun <T> | ||
// some comment | ||
foo(t: T) = "some-result" | ||
""".trimIndent() | ||
assertThat(DiscouragedCommentLocationRule().lint(code)).containsExactly( | ||
LintError(2, 1, "discouraged-comment-location", "No comment expected at this location") | ||
) | ||
assertThat(DiscouragedCommentLocationRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given a block comment after a type parameter then report a discouraged comment location`() { | ||
val code = | ||
""" | ||
fun <T> /* some comment */ | ||
foo(t: T) = "some-result" | ||
""".trimIndent() | ||
assertThat(DiscouragedCommentLocationRule().lint(code)).containsExactly( | ||
LintError(1, 9, "discouraged-comment-location", "No comment expected at this location") | ||
) | ||
assertThat(DiscouragedCommentLocationRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given a block comment on a newline after a type parameter then report a discouraged comment location`() { | ||
val code = | ||
""" | ||
fun <T> | ||
/* some comment */ | ||
foo(t: T) = "some-result" | ||
""".trimIndent() | ||
assertThat(DiscouragedCommentLocationRule().lint(code)).containsExactly( | ||
LintError(2, 1, "discouraged-comment-location", "No comment expected at this location") | ||
) | ||
assertThat(DiscouragedCommentLocationRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given a KDOC comment after a type parameter then report a discouraged comment location`() { | ||
val code = | ||
""" | ||
fun <T> /** some comment */ | ||
foo(t: T) = "some-result" | ||
""".trimIndent() | ||
assertThat(DiscouragedCommentLocationRule().lint(code)).containsExactly( | ||
LintError(1, 9, "discouraged-comment-location", "No comment expected at this location") | ||
) | ||
assertThat(DiscouragedCommentLocationRule().format(code)).isEqualTo(code) | ||
} | ||
|
||
@Test | ||
fun `Given a KDOC comment on a newline after a type parameter then report a discouraged comment location`() { | ||
val code = | ||
""" | ||
fun <T> | ||
/** | ||
* some comment | ||
*/ | ||
foo(t: T) = "some-result" | ||
""".trimIndent() | ||
assertThat(DiscouragedCommentLocationRule().lint(code)).containsExactly( | ||
LintError(2, 1, "discouraged-comment-location", "No comment expected at this location") | ||
) | ||
assertThat(DiscouragedCommentLocationRule().format(code)).isEqualTo(code) | ||
} | ||
} |