如何通过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
相关产品推荐
相关产品推荐

