kotlin - Kotlin Linting RuleSetProvider '尾随逗号'
问题描述
我一直在尝试使用 Pinterest ktlint库创建一个规则集,但我无法删除子参数列表的一部分。
https://github.com/pinterest/ktlint/issues/709
由于 Kotlin 更新以支持“尾随逗号”,这打破了我所有的静态代码分析(SonarQube Gradle 插件 2.8)。所以我决定创建一个 RuleSetProvider 来从代码中删除这个烦人的逗号 ',' 在项目中找到的所有参数列表的末尾。
class NoTrailingCommaRule : Rule("no-trailing-comma") {
override fun visit(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
) {
if (node.elementType == ElementType.COMMA) {
node.parents().forEach {
if (it.elementType == ElementType.VALUE_PARAMETER_LIST) {
if (it.text.contains("pepe")) {
println("############# IS PEPE ###############")
println("ParamList-> " + it.text)
println("-------------------------------------")
if (it is PsiParameterList) {
it.parameters.forEach { param ->
println(" -> ${param.text}")
// if (next.elementType == ElementType.COMMA)
// println(" -> comma,")
println("---==---")
}
println("#####################################")
}
}
}
}
}
}
}
/// Sample class to lint
data class PEPE(
val pepe: String,
var pepe1: List<String> = emptyList(), //<- This is the kind of comma I want to remove
)
那是我当前尝试获取逗号并替换的尝试,但是当我能够打印参数行时,逗号不存在。
解决方案
请参阅以下我已发送 PR 的规则:
package com.pinterest.ktlint.ruleset.experimental
import com.pinterest.ktlint.core.Rule
import com.pinterest.ktlint.core.ast.ElementType
import com.pinterest.ktlint.core.ast.children
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import org.jetbrains.kotlin.psi.psiUtil.endOffset
class NoTrailingCommaRule : Rule("no-trailing-comma") {
override fun visit(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit
) {
if (node.elementType == ElementType.VALUE_ARGUMENT_LIST || node.elementType == ElementType.VALUE_PARAMETER_LIST) {
val lastNode = node
.children()
.filter { it.elementType != ElementType.WHITE_SPACE }
.filter { it.elementType != ElementType.EOL_COMMENT }
.filter { it.elementType != ElementType.RPAR }
.last()
if (lastNode.elementType == ElementType.COMMA) {
emit(lastNode.psi.endOffset - 1, "Trailing command in argument list is redundant", true)
if (autoCorrect) {
node.removeChild(lastNode)
}
}
}
}
}
和测试:
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.Test
class NoTrailingCommaRuleTest {
@Test
fun testFormatIsCorrectWithArgumentList() {
val code =
"""
val list1 = listOf("a", "b",)
val list2 = listOf(
"a",
"b", // The comma before the comment should be removed without removing the comment itself
)
""".trimIndent()
val autoCorrectedCode =
"""
val list1 = listOf("a", "b")
val list2 = listOf(
"a",
"b" // The comma before the comment should be removed without removing the comment itself
)
""".trimIndent()
assertThat(NoTrailingCommaRule().lint(code)).isEqualTo(
listOf(
LintError(line = 1, col = 28, ruleId = "no-trailing-comma", detail = "Trailing command in argument list is redundant"),
LintError(line = 4, col = 8, ruleId = "no-trailing-comma", detail = "Trailing command in argument list is redundant"),
)
)
assertThat(NoTrailingCommaRule().format(code))
.isEqualTo(autoCorrectedCode)
}
@Test
fun testFormatIsCorrectWithValueList() {
val code =
"""
data class Foo1(
val bar: Int, // The comma before the comment should be removed without removing the comment itself
)
data class Foo2(val bar: Int,)
""".trimIndent()
val autoCorrectedCode =
"""
data class Foo1(
val bar: Int // The comma before the comment should be removed without removing the comment itself
)
data class Foo2(val bar: Int)
""".trimIndent()
assertThat(NoTrailingCommaRule().lint(code)).isEqualTo(
listOf(
LintError(line = 2, col = 16, ruleId = "no-trailing-comma", detail = "Trailing command in argument list is redundant"),
LintError(line = 4, col = 29, ruleId = "no-trailing-comma", detail = "Trailing command in argument list is redundant"),
)
)
assertThat(NoTrailingCommaRule().format(code))
.isEqualTo(autoCorrectedCode)
}
}
推荐阅读
- firebase - 在 Cloud Firestore 安全规则中将字符串转换为 Int
- asp.net - IIS/ASP.NET 接收从外部应用程序到 SOAP 代理服务器的调用
- c# - StringBuilder("...").ToString() 和 new String() 的行为不同。为什么?
- python-2.7 - 使用 Dataflow 发布到 Bigquery
- python - Python Kivy TabbedPanel - 设置自定义标签宽度
- javascript - 本地存储,以及如何延迟 div 可见性
- raku - 从另一个 Perl 6 文件访问 POD
- java - Java中的ArrayList和泛型
- linux - 负载段错位
- c# - Azure Active Directory B2C 与 xamarin pcl 应用程序集成时发生 System.Runtime.Seralization.SeralizationEception 错误