非Android环境Kotlin项目如何添加Lint规则禁止调用指定方法
针对Kotlin多平台项目的禁止指定方法调用Lint规则实现方案
你找到的Android Lint方案依赖Android生态组件,不适用于无Android依赖的KMP核心代码场景,推荐以下两种纯Kotlin生态的实现方案:
方案1:Detekt(优先推荐)
Detekt是Kotlin原生的静态代码分析工具,原生支持Kotlin多平台,无Android依赖,自定义规则开发简单,天然支持注解豁免。
- 集成Detekt到项目
在根项目build.gradle.kts中引入插件:
plugins { id("io.gitlab.arturbosch.detekt") version "1.23.6" apply false }
在需要应用检查的KMP核心模块的build.gradle.kts中应用插件并配置规则依赖:
plugins { id("io.gitlab.arturbosch.detekt") } dependencies { detekt project(":custom-detekt-rules") // 你的自定义规则模块 }
- 编写自定义禁止调用规则
新建独立的Java/Kotlin模块custom-detekt-rules,添加Detekt API依赖:
dependencies { compileOnly("io.gitlab.arturbosch.detekt:detekt-api:1.23.6") }
新建规则类匹配目标方法:
import io.gitlab.arturbosch.detekt.api.* import org.jetbrains.kotlin.psi.KtCallExpression class ForbidDateTimeTzLocalRule : Rule() { override val issue = Issue( id = "ForbidDateTimeTzLocal", severity = Severity.ERROR, description = "禁止调用Klock的DateTimeTz.local方法,该方法默认使用设备本地时区,易引发多时区数据不一致问题", debt = Debt.FIVE_MINS ) override fun visitCallExpression(expression: KtCallExpression) { super.visitCallExpression(expression) val methodName = expression.calleeExpression?.text ?: return if (methodName != "local") return // 匹配全限定名避免误杀其他同名方法 val methodFqName = expression.resolveCall() ?.resultingDescriptor ?.containingDeclaration ?.fqName ?.asString() if (methodFqName == "com.soywiz.klock.DateTimeTz") { report(CodeSmell(issue, Entity.from(expression), issue.description)) } } }
- 注册规则
在custom-detekt-rules模块的src/main/resources/META-INF/services/io.gitlab.arturbosch.detekt.api.Rule文件中添加规则类的全限定名。 - 启用规则与主动覆盖
在项目根目录新增detekt.yml配置文件启用规则:
ForbidDateTimeTzLocal: active: true
如果需要合法调用该方法,直接在调用处添加注解即可豁免:
@Suppress("ForbidDateTimeTzLocal") val now = DateTimeTz.local // 合法调用会被豁免
方案2:Ktlint 自定义规则
如果你已经在项目中使用Ktlint做代码格式化,也可以基于Ktlint扩展自定义规则,实现逻辑与Detekt类似,同样无Android依赖,支持KMP,通过@Suppress("规则ID")实现主动覆盖。
两种方案都可以集成到CI流程中,代码合入前自动扫描拦截,从流程上避免方法误用。
内容的提问来源于stack exchange,提问作者cam17
相关产品推荐
相关产品推荐

