Verify Generics
Type parameter vs type argument
To undersigned Konsist API let's look at the difference between generic type parameters and generic type arguments:
Type Parameter is the placeholder (like
T) you write when creating a class or function (declaration site)Type Argument is the actual type (like
StringorInt) you provide when using that class or function (use site)
Simple Examples:
// Example 1: Class
// Here 'T' is a TYPE PARAMETER
class Box<T>(val item: T)
// Here 'String' is a TYPE ARGUMENT
val stringBox = Box<String>("Hello")
// Example 2: Function
// Here 'T' is a TYPE PARAMETER
fun <T> printWithType(item: T) {
println("Type is: ${item::class.simpleName}")
}
// Here 'String' and 'Int' are TYPE ARGUMENTS
printWithType<String>("Hello") // prints: Type is: StringVerify Type Parameters
Type parameters can be defined, for example, inside class or function.
Check whether a class's generic type parameter has the name UiState:
UiState:// Code Snippet
class View<UiState>(val state: UiState) // UiState is typeParamener
// Konsist
Konsist
.scopeFromProject()
.classes()
.typeParameters // access type parameters
.assertTrue {
it.name == "UiState" // true
}Check whether function type parameters has out modifier:
type parameters has out modifier://Code Snippet
fun <out T> setState(item: T?) {
// ...
}
// Konsist
Konsist
.scopeFromProject()
.functions()
.typeParameters // access type parameters
.assertTrue {
it.hasOutModifier // true
}Verify Type Arguments
Check whether a property generic type argument has the name Service:
Service://Code Snippet
val services: List<Service> = emptyList()
// Konsist
Konsist
.scopeFromProject()
.properties()
.assertTrue { property ->
property
.type
?.typeArguments
?.flatten()
?.any { typeArgument -> typeArgument.name == "Service" }
}The flatten() extension method allows to flatten type parameters structure:
For a type argument like
String, it returnslistOf().For a type argument like
List<String>, it returnslistOf(String).For a type argument like
Map<List<String>, Int>, it returnslistOf("List, String, Int).
Check if all functions parameters are have generic type argument ending with UIState:
UIState:// Snippet
fun setState(uiState: View<WelcomeUIState>)
// Konsist Test
Konsist
.scopeFromProject()
.properties()
.parameters
.types
.typeArguments
.assertTrue {
it.hasNameEndingWith("UIState") // true
}Check all parents have `String` type argument:
// Snippet
open class Container<T>(private val item: T) { }
class StringContainer(text: String) : Container<String>(text) { }
// Konsist Test
Konsist
.scopeFromProject()
.classes()
.parents()
.typeArguments
.flatten()
.assertTrue {
it.name == "String" // true
}Last updated