CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-squareup--kotlinpoet

Kotlin and Java API for generating Kotlin source files (.kt) with type-safe, fluent builder patterns

Pending
Overview
Eval results
Files

type-system.mddocs/

Type System

Complete representation of Kotlin's type system including classes, generics, wildcards, lambda types, and type variables. Provides type-safe APIs for working with complex type hierarchies and generic type parameters.

Capabilities

Base Type Representation

The foundation of KotlinPoet's type system providing nullability and annotation support for all type representations.

/**
 * Base class for all type representations in KotlinPoet
 */
abstract class TypeName {
    /** Whether this type is nullable */
    val isNullable: Boolean
    
    /** Annotations applied to this type */
    val annotations: List<AnnotationSpec>
    
    /** Creates a copy of this type with modified nullability and annotations */
    fun copy(nullable: Boolean = this.isNullable, annotations: List<AnnotationSpec> = this.annotations): TypeName
    
    companion object {
        /** Gets the TypeName for a KClass */
        fun get(type: KClass<*>): TypeName
        
        /** Gets the TypeName for a Java Class */
        fun get(type: Type): TypeName
        
        /** Gets the TypeName for a Java Class with variance */
        fun get(type: Type, map: Map<TypeVariable<*>, TypeName>): TypeName
    }
}

Class and Interface Types

Represents references to classes, interfaces, and objects with full package qualification and parameterization support.

/**
 * Type name for classes, interfaces, and objects
 */
class ClassName : TypeName {
    /** The package name containing this class */
    val packageName: String
    
    /** The simple name of this class */
    val simpleName: String
    
    /** Nested class names if this represents a nested class */
    val simpleNames: List<String>
    
    /** The enclosing class if this is a nested class */
    val enclosingClassName: ClassName?
    
    /** Creates a nested class name within this class */
    fun nestedClass(simpleName: String): ClassName
    
    /** Creates a sibling class name in the same package */
    fun peerClass(simpleName: String): ClassName
    
    /** Creates a parameterized type using this class as the raw type */
    fun parameterizedBy(vararg typeArguments: TypeName): ParameterizedTypeName
    fun parameterizedBy(typeArguments: Iterable<TypeName>): ParameterizedTypeName
    
    companion object {
        /** Creates a ClassName from package and simple names */
        fun get(packageName: String, simpleName: String, vararg simpleNames: String): ClassName
        
        /** Creates a ClassName from a KClass */
        fun get(klass: KClass<*>): ClassName
        
        /** Creates a ClassName from a Java Class */
        fun get(clazz: Class<*>): ClassName
        
        /** Attempts to create a ClassName from a string representation */
        fun bestGuess(classNameString: String): ClassName
    }
}

Usage Examples:

import com.squareup.kotlinpoet.*

// Basic class names
val stringClass = ClassName.get("kotlin", "String")
val listClass = ClassName.get("kotlin.collections", "List")
val mapClass = ClassName.get(Map::class)

// Nested class names
val outerClass = ClassName.get("com.example", "Outer")
val innerClass = outerClass.nestedClass("Inner")
val siblingClass = outerClass.peerClass("Sibling")

// From string guessing
val guessedClass = ClassName.bestGuess("java.util.concurrent.ConcurrentHashMap")

// Creating parameterized types
val stringList = listClass.parameterizedBy(STRING)
val stringIntMap = mapClass.parameterizedBy(STRING, INT)

// Custom classes for domain modeling
val userClass = ClassName.get("com.example.model", "User")
val repositoryClass = ClassName.get("com.example.repository", "UserRepository")

Parameterized (Generic) Types

Represents generic types with type arguments, supporting complex nested generics and variance.

/**
 * Type name for parameterized types (generics like List<String>)
 */
class ParameterizedTypeName : TypeName {
    /** The raw type without type parameters */
    val rawType: ClassName
    
    /** The type arguments for this parameterized type */
    val typeArguments: List<TypeName>
    
    companion object {
        /** Creates a parameterized type from a raw type and type arguments */
        fun get(rawType: ClassName, vararg typeArguments: TypeName): ParameterizedTypeName
        fun get(rawType: ClassName, typeArguments: List<TypeName>): ParameterizedTypeName
    }
}

Usage Examples:

// Basic parameterized types
val stringList = ParameterizedTypeName.get(LIST, STRING)
val intSet = ParameterizedTypeName.get(SET, INT)
val stringIntMap = ParameterizedTypeName.get(MAP, STRING, INT)

// Nested generics
val listOfStringLists = ParameterizedTypeName.get(LIST, stringList)
val mapOfStringToIntList = ParameterizedTypeName.get(
    MAP, 
    STRING, 
    ParameterizedTypeName.get(LIST, INT)
)

// Complex generic hierarchies
val repositoryType = ParameterizedTypeName.get(
    ClassName.get("com.example", "Repository"),
    ClassName.get("com.example.model", "User")
)

// Generic with wildcards  
val wildcardList = ParameterizedTypeName.get(
    LIST,
    WildcardTypeName.producerOf(ClassName.get("", "Number"))
)

Type Variables

Represents type parameters in generic declarations (T, E, K, V, etc.) with optional bounds.

/**
 * Type name for type variables (generic type parameters like T, E, etc.)
 */
class TypeVariableName : TypeName {
    /** The name of the type variable */
    val name: String
    
    /** Upper bounds for this type variable */
    val bounds: List<TypeName>
    
    /** Variance of this type variable (in, out, or invariant) */
    val variance: KModifier?
    
    /** Whether this type variable is reified */
    val isReified: Boolean
    
    companion object {
        /** Creates a type variable with the given name */
        fun get(name: String): TypeVariableName
        
        /** Creates a bounded type variable */
        fun get(name: String, vararg bounds: TypeName): TypeVariableName
        fun get(name: String, bounds: List<TypeName>): TypeVariableName
        
        /** Creates a type variable from a Java TypeVariable */
        fun get(typeVariable: java.lang.reflect.TypeVariable<*>): TypeVariableName
        fun get(typeVariable: java.lang.reflect.TypeVariable<*>, map: Map<java.lang.reflect.TypeVariable<*>, TypeName>): TypeVariableName
    }
}

Usage Examples:

// Simple type variables
val tVar = TypeVariableName.get("T")
val eVar = TypeVariableName.get("E")
val kVar = TypeVariableName.get("K")
val vVar = TypeVariableName.get("V")

// Bounded type variables
val numberVar = TypeVariableName.get("T", NUMBER)
val comparableVar = TypeVariableName.get("T", COMPARABLE.parameterizedBy(TypeVariableName.get("T")))

// Multiple bounds
val serializableComparableVar = TypeVariableName.get(
    "T",
    ClassName.get("java.io", "Serializable"),
    COMPARABLE.parameterizedBy(TypeVariableName.get("T"))
)

// Reified type variables (for inline functions)
val reifiedVar = TypeVariableName.get("T").copy(reified = true)

// Variance annotations
val covariantVar = TypeVariableName.get("T").copy(variance = KModifier.OUT)
val contravariantVar = TypeVariableName.get("T").copy(variance = KModifier.IN)

// Using in generic function
val genericFunction = FunSpec.builder("process")
    .addTypeVariable(TypeVariableName.get("T", ClassName.get("", "Processable")))
    .addParameter("item", TypeVariableName.get("T"))
    .returns(TypeVariableName.get("T"))
    .addStatement("return item.process()")
    .build()

Wildcard Types

Represents wildcard types with variance (*, out T, in T) for use-site variance in generic types.

/**
 * Type name for wildcard types (*, out Type, in Type)
 */
class WildcardTypeName : TypeName {
    /** Upper bounds for this wildcard */
    val upperBounds: List<TypeName>
    
    /** Lower bounds for this wildcard */
    val lowerBounds: List<TypeName>
    
    companion object {
        /** Creates a producer wildcard (out Type) */
        fun producerOf(upperBound: TypeName): WildcardTypeName
        
        /** Creates a consumer wildcard (in Type) */
        fun consumerOf(lowerBound: TypeName): WildcardTypeName
        
        /** Creates an unbounded wildcard (*) */
        fun subtypeOf(upperBound: TypeName): WildcardTypeName
        fun supertypeOf(lowerBound: TypeName): WildcardTypeName
    }
}

Usage Examples:

// Producer wildcards (covariant - out)
val producerOfNumber = WildcardTypeName.producerOf(NUMBER)
val listOfProducerNumber = LIST.parameterizedBy(producerOfNumber)

// Consumer wildcards (contravariant - in)  
val consumerOfString = WildcardTypeName.consumerOf(STRING)
val comparatorOfConsumerString = ClassName.get("java.util", "Comparator").parameterizedBy(consumerOfString)

// Unbounded wildcards
val unboundedList = LIST.parameterizedBy(WildcardTypeName.subtypeOf(ANY))

// Complex variance scenarios
val complexWildcard = ParameterizedTypeName.get(
    MAP,
    STRING,
    WildcardTypeName.producerOf(ClassName.get("", "Value"))
)

Lambda and Function Types

Represents function types and lambda expressions with support for receivers, suspending functions, and parameter specifications.

/**
 * Type name for function/lambda types like (String, Int) -> Boolean
 */
class LambdaTypeName : TypeName {
    /** The receiver type for extension lambdas */
    val receiver: TypeName?
    
    /** Parameter specifications for the lambda */
    val parameters: List<ParameterSpec>
    
    /** Return type of the lambda */
    val returnType: TypeName
    
    /** Whether this is a suspending function type */
    val isSuspending: Boolean
    
    companion object {
        /** Creates a lambda type with the given parameters and return type */
        fun get(
            receiver: TypeName? = null,
            parameters: List<ParameterSpec> = emptyList(),
            returnType: TypeName
        ): LambdaTypeName
        
        /** Creates a lambda type with unnamed parameters */
        fun get(
            receiver: TypeName? = null,
            vararg parameters: TypeName,
            returnType: TypeName
        ): LambdaTypeName
    }
}

Usage Examples:

// Simple function types
val stringToInt = LambdaTypeName.get(returnType = INT, parameters = *arrayOf(STRING))
val binaryIntOperation = LambdaTypeName.get(returnType = INT, parameters = *arrayOf(INT, INT))

// Function type with no parameters
val supplier = LambdaTypeName.get(returnType = STRING)

// Function type with named parameters
val namedParamFunction = LambdaTypeName.get(
    parameters = listOf(
        ParameterSpec.builder("name", STRING).build(),
        ParameterSpec.builder("age", INT).build()
    ),
    returnType = STRING
)

// Extension function type (with receiver)
val stringExtension = LambdaTypeName.get(
    receiver = STRING,
    returnType = BOOLEAN
)

// Suspending function type
val suspendingFunction = LambdaTypeName.get(
    parameters = listOf(ParameterSpec.unnamed(STRING)),
    returnType = STRING,
    isSuspending = true
)

// Higher-order function parameter
val higherOrderFunction = FunSpec.builder("processAsync")
    .addParameter(
        "callback", 
        LambdaTypeName.get(
            parameters = listOf(ParameterSpec.unnamed(STRING)),
            returnType = UNIT,
            isSuspending = true
        )
    )
    .build()

// Complex function type with multiple parameters
val complexCallback = LambdaTypeName.get(
    parameters = listOf(
        ParameterSpec.builder("success", BOOLEAN).build(),
        ParameterSpec.builder("data", STRING.copy(nullable = true)).build(),
        ParameterSpec.builder("error", ClassName.get("", "Exception").copy(nullable = true)).build()
    ),
    returnType = UNIT
)

Dynamic Type

Represents Kotlin's dynamic type for JavaScript interoperability.

/**
 * Represents Kotlin's dynamic type
 */
object Dynamic : TypeName

Usage Examples:

// Dynamic type for JavaScript interop
val dynamicProperty = PropertySpec.builder("jsObject", Dynamic)
    .initializer("js(%S)", "{}")
    .build()

val dynamicFunction = FunSpec.builder("callJsFunction")
    .addParameter("obj", Dynamic)
    .addParameter("method", STRING)
    .returns(Dynamic)
    .addStatement("return obj[method]()")
    .build()

Built-in Type Constants

KotlinPoet provides convenient constants for common Kotlin types:

// Primitive types
val UNIT: ClassName
val BOOLEAN: ClassName  
val BYTE: ClassName
val SHORT: ClassName
val INT: ClassName
val LONG: ClassName
val CHAR: ClassName
val FLOAT: ClassName
val DOUBLE: ClassName
val STRING: ClassName

// Unsigned primitive types
val U_BYTE: ClassName
val U_SHORT: ClassName
val U_INT: ClassName
val U_LONG: ClassName

// Common reference types
val ANY: ClassName
val NOTHING: ClassName
val NUMBER: ClassName
val COMPARABLE: ClassName
val CHAR_SEQUENCE: ClassName
val THROWABLE: ClassName
val ANNOTATION: ClassName

// Collection types
val ITERABLE: ClassName
val COLLECTION: ClassName
val LIST: ClassName
val SET: ClassName
val MAP: ClassName
val MUTABLE_ITERABLE: ClassName
val MUTABLE_COLLECTION: ClassName
val MUTABLE_LIST: ClassName
val MUTABLE_SET: ClassName
val MUTABLE_MAP: ClassName

// Array types
val ARRAY: ClassName
val BOOLEAN_ARRAY: ClassName
val BYTE_ARRAY: ClassName
val CHAR_ARRAY: ClassName
val SHORT_ARRAY: ClassName
val INT_ARRAY: ClassName
val LONG_ARRAY: ClassName
val FLOAT_ARRAY: ClassName
val DOUBLE_ARRAY: ClassName

// Unsigned array types
val U_BYTE_ARRAY: ClassName
val U_SHORT_ARRAY: ClassName
val U_INT_ARRAY: ClassName
val U_LONG_ARRAY: ClassName

// Additional type constants
val STAR: WildcardTypeName // Represents * wildcard
val ENUM: ClassName
val MAP_ENTRY: ClassName
val MUTABLE_MAP_ENTRY: ClassName

Usage Examples:

// Using built-in type constants
val stringList = LIST.parameterizedBy(STRING)
val intArray = INT_ARRAY
val stringIntMap = MAP.parameterizedBy(STRING, INT)

// Nullable variants
val nullableString = STRING.copy(nullable = true)
val nullableInt = INT.copy(nullable = true)

// Functions using built-in types
val utilityFunction = FunSpec.builder("processData")
    .addParameter("items", LIST.parameterizedBy(STRING))
    .addParameter("mapper", LambdaTypeName.get(STRING, returnType = INT))
    .returns(LIST.parameterizedBy(INT))
    .addStatement("return items.map(mapper)")
    .build()

Install with Tessl CLI

npx tessl i tessl/maven-com-squareup--kotlinpoet

docs

annotations-and-metadata.md

code-generation.md

file-and-type-generation.md

function-and-property-generation.md

index.md

type-system.md

utilities.md

tile.json