You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Detekt规则禁止将AbstractActor子类引用声明为类属性

核心问题点
  1. 未声明需要类型解析:Detekt 自定义规则默认不会启用类型解析能力,你没有重写requiresTypeAnalysis属性为true,导致bindingContext始终为空,类型判断逻辑直接跳过。
  2. API使用错误:你使用的createTypeBindingForReturnType是用于获取函数/方法的返回类型绑定,对于构造参数、成员属性这类声明,应该使用createTypeBinding获取自身的类型绑定。
  3. 父类检查不完整:当前逻辑仅检查了类型的直接父类,没有递归遍历所有上层父类,无法匹配到Typed1Actor这类间接继承AbstractActor的类型。
  4. 拼写错误:代码中多处把AbstractActor误写为AbsractActor,会导致后续提示信息错误。
修正后的规则代码
package testRuleSet

import io.gitlab.arturbosch.detekt.api.*
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.typeBinding.createTypeBinding
import org.jetbrains.kotlin.types.KtType

class NoExplicitlyReferencingActorRule(config: Config) : Rule(config) {
    override val issue: Issue = Issue(
        javaClass.simpleName,
        Severity.Style,
        "Customized-NoExplicitlyReferencingActor",
        Debt.TEN_MINS,
    )

    // 关键:声明该规则需要类型解析,Detekt才会传入有效的bindingContext
    override val requiresTypeAnalysis: Boolean = true

    override fun visitParameter(parameter: KtParameter) {
        super.visitParameter(parameter)
        if (parameter.hasValOrVar() && validateDeclaration(parameter)) {
            reportCodeSmell(parameter)
        }
    }

    override fun visitProperty(property: KtProperty) {
        super.visitProperty(property)
        if (property.isMember && validateDeclaration(property)) {
            reportCodeSmell(property)
        }
    }

    private fun validateDeclaration(declaration: KtCallableDeclaration): Boolean {
        if (bindingContext == BindingContext.EMPTY) return false
        return isSubClassOfAbstractActor(declaration)
    }

    private fun isSubClassOfAbstractActor(declaration: KtCallableDeclaration): Boolean {
        val type = declaration.createTypeBinding(bindingContext)?.type ?: return false
        // 递归检查所有层级的父类
        fun checkTypeRecursive(type: KtType): Boolean {
            if (type.getJetTypeFqName(false) == "testRule.AbstractActor") return true
            return type.constructor.supertypes.any { checkTypeRecursive(it) }
        }
        return checkTypeRecursive(type)
    }

    private fun reportCodeSmell(declaration: KtCallableDeclaration) {
        report(
            CodeSmell(
                issue,
                Entity.from(requireNotNull(declaration.colon)),
                "do not hold any subclass of AbstractActor as a explicit reference"
            )
        )
    }
}
测试用例注意事项

如果你使用的是Detekt官方的测试工具套件,需要确保测试环境开启了类型解析能力,compileAndLintWithContext方法默认是支持类型解析的,只要规则声明了requiresTypeAnalysis = true就可以正常获取绑定上下文。

内容的提问来源于stack exchange,提问作者Munar Yesen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:36:06