【问题标题】:Kotlin Linting RuleSetProvider 'trailing-comma'Kotlin Linting RuleSetProvider '尾随逗号'
【发布时间】:2021-03-11 07:49:38
【问题描述】:

我一直在尝试使用 Pinterest ktlint Library 创建一个规则集,但我无法删除子参数列表的一部分。

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
) 

这是我当前尝试获取逗号并替换的尝试,但是当我能够打印参数行时,逗号不存在。 ????

【问题讨论】:

    标签: kotlin gradle sonarqube ktlint


    【解决方案1】:

    请参阅以下我已发送 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)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-02-12
      • 2021-01-25
      • 1970-01-01
      • 1970-01-01
      • 2014-01-30
      • 2018-01-10
      • 2014-01-19
      • 2013-04-08
      相关资源
      最近更新 更多