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

如何通过Konsist获取父类构造函数调用并验证参数传递?

Konsist验证父类构造函数是否传入所有UseCase参数

要实现这个检查,你可以通过Konsist的KoClassDeclaration提供的superTypeCalls属性获取父类构造函数的调用信息,再和筛选出的UseCase参数做对比,具体步骤如下:

1. 调整UseCase参数的筛选逻辑(保留参数名称)

你原来的代码获取了参数的类型声明,现在需要改为保留参数名称,方便后续对比:

val useCaseParamNames = klass.primaryConstructor
    ?.parameters
    ?.filter { 
        it.type.asClassDeclaration()?.hasParentClassOf(UseCase::class) == true 
    }
    ?.map { it.name }
    .orEmpty()

2. 获取父类构造函数的调用及传入参数

通过superTypeCalls筛选出目标父类(比如BaseViewModel)的构造函数调用,再提取其中传入的参数名称:

// 获取BaseViewModel的父类构造调用
val baseViewModelSuperCall = klass.superTypeCalls
    .firstOrNull { 
        it.type.asClassDeclaration()?.isSubclassOf(BaseViewModel::class) == true 
    }

// 提取父类构造中传入的参数名称
val passedToParentParamNames = baseViewModelSuperCall?.arguments
    ?.mapNotNull { it.value as? KoIdentifier }
    ?.map { it.name }
    .orEmpty()

3. 验证所有UseCase参数是否传入父类构造

最后对比两组参数名称,确保所有UseCase参数都被传入父类:

// 断言检查,未通过时抛出异常
check(useCaseParamNames.all { it in passedToParentParamNames }) {
    "ViewModel ${klass.name} 必须将所有UseCase参数传入父类BaseViewModel的构造函数"
}

完整示例代码

把上述逻辑整合到Konsist的规则中:

fun checkViewModelsPassAllUseCasesToParent() =
    Konsist
        .scopeFromProject()
        .classes()
        .filter { it.hasParentClassOf(BaseViewModel::class) }
        .forEach { klass ->
            val useCaseParamNames = klass.primaryConstructor
                ?.parameters
                ?.filter { 
                    it.type.asClassDeclaration()?.hasParentClassOf(UseCase::class) == true 
                }
                ?.map { it.name }
                .orEmpty()

            val baseViewModelSuperCall = klass.superTypeCalls
                .firstOrNull { 
                    it.type.asClassDeclaration()?.isSubclassOf(BaseViewModel::class) == true 
                }

            val passedToParentParamNames = baseViewModelSuperCall?.arguments
                ?.mapNotNull { it.value as? KoIdentifier }
                ?.map { it.name }
                .orEmpty()

            check(useCaseParamNames.all { it in passedToParentParamNames }) {
                "ViewModel ${klass.name} 必须将所有UseCase参数传入父类BaseViewModel的构造函数"
            }
        }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:26:04