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

annotations-and-metadata.mddocs/

Annotations and Metadata

Complete support for Kotlin and Java annotations including annotation specifications, JVM-specific annotations, and metadata generation for annotation processors.

Capabilities

Annotation Specification

Creates annotation instances with support for all annotation parameter types and complex nested structures.

/**
 * Specification for generating annotations
 */
class AnnotationSpec private constructor() {
    /** The type name of this annotation */
    val typeName: TypeName
    
    /** The member values for this annotation */
    val members: Map<String, List<CodeBlock>>
    
    /** String representation for use in generated code */
    val useSiteTarget: UseSiteTarget?
    
    companion object {
        /** Creates a builder for an annotation */
        fun builder(type: ClassName): Builder
        fun builder(type: Class<*>): Builder
        fun builder(type: KClass<*>): Builder
        
        /** Creates a simple annotation without parameters */
        fun get(type: ClassName): AnnotationSpec
        fun get(type: Class<*>): AnnotationSpec
        fun get(type: KClass<*>): AnnotationSpec
    }
    
    /** Builder for constructing AnnotationSpec instances */
    class Builder {
        /** Adds a member value to the annotation */
        fun addMember(name: String, format: String, vararg args: Any?): Builder
        fun addMember(name: String, codeBlock: CodeBlock): Builder
        
        /** Sets the use-site target for the annotation */
        fun useSiteTarget(useSiteTarget: UseSiteTarget): Builder
        
        /** Builds the AnnotationSpec */
        fun build(): AnnotationSpec
    }
    
    /** Use-site targets for annotations */
    enum class UseSiteTarget {
        FILE, PROPERTY, FIELD, GET, SET, RECEIVER, PARAM, SETPARAM, DELEGATE
    }
}

Usage Examples:

import com.squareup.kotlinpoet.*

// Simple annotation without parameters
val deprecatedAnnotation = AnnotationSpec.get(Deprecated::class)

// Annotation with string parameter
val deprecatedWithMessage = AnnotationSpec.builder(Deprecated::class)
    .addMember("message = %S", "Use newMethod() instead")
    .build()

// Annotation with multiple parameters
val suppressWarnings = AnnotationSpec.builder(Suppress::class)
    .addMember("names = [%S, %S]", "UNCHECKED_CAST", "DEPRECATION")
    .build()

// Custom annotation with complex parameters
val customAnnotation = AnnotationSpec.builder(ClassName.get("com.example", "Configuration"))
    .addMember("name = %S", "database")
    .addMember("timeout = %L", 30)
    .addMember("enabled = %L", true)
    .addMember("tags = [%S, %S]", "production", "critical")
    .build()

// Annotation with enum parameter
val requestMapping = AnnotationSpec.builder(ClassName.get("", "RequestMapping"))
    .addMember("method = %T.%L", ClassName.get("", "RequestMethod"), "GET")
    .addMember("path = %S", "/users/{id}")
    .build()

// Annotation with class parameter
val jsonDeserialize = AnnotationSpec.builder(ClassName.get("com.fasterxml.jackson.databind.annotation", "JsonDeserialize"))
    .addMember("using = %T::class", ClassName.get("com.example", "CustomDeserializer"))
    .build()

// Annotation with nested annotation
val validatedAnnotation = AnnotationSpec.builder(ClassName.get("", "Validated"))
    .addMember("constraints = [%L]", 
        AnnotationSpec.builder(ClassName.get("", "NotNull")).build()
    )
    .build()

// Use-site targets for property annotations
val fieldAnnotation = AnnotationSpec.builder(ClassName.get("", "Inject"))
    .useSiteTarget(AnnotationSpec.UseSiteTarget.FIELD)
    .build()

val getterAnnotation = AnnotationSpec.builder(ClassName.get("", "JsonProperty"))
    .useSiteTarget(AnnotationSpec.UseSiteTarget.GET)
    .addMember("value = %S", "user_name")
    .build()

Type Alias Specification

Creates type aliases for improving code readability and providing semantic meaning to complex types.

/**
 * Specification for generating type aliases
 */
class TypeAliasSpec private constructor() {
    /** The name of the type alias */
    val name: String
    
    /** The type this alias refers to */
    val type: TypeName
    
    /** Modifiers applied to the type alias */
    val modifiers: Set<KModifier>
    
    /** Type parameters for generic type aliases */
    val typeVariables: List<TypeVariableName>
    
    companion object {
        /** Creates a builder for a type alias */
        fun builder(name: String, type: TypeName): Builder
        fun builder(name: String, type: KClass<*>): Builder
    }
    
    /** Builder for constructing TypeAliasSpec instances */
    class Builder {
        /** Adds modifiers to the type alias */
        fun addModifiers(vararg modifiers: KModifier): Builder
        fun addModifiers(modifiers: Iterable<KModifier>): Builder
        
        /** Adds type parameters */
        fun addTypeVariable(typeVariable: TypeVariableName): Builder
        fun addTypeVariables(typeVariables: Iterable<TypeVariableName>): Builder
        
        /** Adds annotations */
        fun addAnnotation(annotationSpec: AnnotationSpec): Builder
        fun addAnnotation(annotation: ClassName): Builder
        fun addAnnotation(annotation: Class<*>): Builder
        fun addAnnotation(annotation: KClass<*>): Builder
        
        /** Adds KDoc documentation */
        fun addKdoc(format: String, vararg args: Any?): Builder
        fun addKdoc(block: CodeBlock): Builder
        
        /** Builds the TypeAliasSpec */
        fun build(): TypeAliasSpec
    }
}

Usage Examples:

// Simple type alias
val stringMap = TypeAliasSpec.builder(
    "StringMap",
    MAP.parameterizedBy(STRING, STRING)
).build()

// Generic type alias
val result = TypeAliasSpec.builder(
    "Result", 
    ClassName.get("kotlin", "Result").parameterizedBy(TypeVariableName.get("T"))
)
.addTypeVariable(TypeVariableName.get("T"))
.build()

// Type alias for complex function type
val eventHandler = TypeAliasSpec.builder(
    "EventHandler",
    LambdaTypeName.get(
        parameters = listOf(
            ParameterSpec.builder("event", ClassName.get("", "Event")).build()
        ),
        returnType = UNIT
    )
).build()

// Type alias with annotations and documentation
val userId = TypeAliasSpec.builder("UserId", STRING)
    .addKdoc("Represents a unique identifier for a user")
    .addAnnotation(ClassName.get("", "JvmInline"))
    .build()

// Internal type alias
val internalCache = TypeAliasSpec.builder(
    "Cache",
    MAP.parameterizedBy(STRING, ANY.copy(nullable = true))
)
.addModifiers(KModifier.INTERNAL)
.build()

// Complex generic type alias
val repository = TypeAliasSpec.builder("Repository", ClassName.get("", "BaseRepository"))
    .addTypeVariable(TypeVariableName.get("T"))
    .addTypeVariable(TypeVariableName.get("ID"))
    .build()

JVM-Specific Annotations

Support for JVM-specific annotations and interoperability features through the com.squareup.kotlinpoet.jvm package.

/**
 * Utilities for JVM-specific annotations
 */
object JvmAnnotations {
    /** Adds @JvmOverloads annotation to a function for Java interop */
    fun overloads(funSpec: FunSpec): FunSpec
    
    /** Creates @Throws annotation with specified exception classes */
    fun throws(vararg exceptionClasses: ClassName): AnnotationSpec
    fun throws(vararg exceptionClasses: Class<out Throwable>): AnnotationSpec
    fun throws(vararg exceptionClasses: KClass<out Throwable>): AnnotationSpec
    
    /** Creates @JvmStatic annotation */
    fun jvmStatic(): AnnotationSpec
    
    /** Creates @JvmField annotation */
    fun jvmField(): AnnotationSpec
    
    /** Creates @JvmName annotation */
    fun jvmName(name: String): AnnotationSpec
    
    /** Creates @JvmMultifileClass annotation */
    fun jvmMultifileClass(): AnnotationSpec
}

Usage Examples:

import com.squareup.kotlinpoet.jvm.JvmAnnotations
import com.squareup.kotlinpoet.*

// Function with JVM overloads for Java interop
val functionWithDefaults = FunSpec.builder("processData")
    .addParameter("data", STRING)
    .addParameter(
        ParameterSpec.builder("timeout", INT)
            .defaultValue("%L", 5000)
            .build()
    )
    .addParameter(
        ParameterSpec.builder("retries", INT)
            .defaultValue("%L", 3)
            .build()
    )
    .returns(STRING)
    .addStatement("return data.process()")
    .build()

val jvmFunction = JvmAnnotations.overloads(functionWithDefaults)

// Function that throws exceptions for Java callers
val throwingFunction = FunSpec.builder("readFile")
    .addParameter("filename", STRING)
    .returns(STRING)
    .addAnnotation(JvmAnnotations.throws(IOException::class, SecurityException::class))
    .addStatement("return File(filename).readText()")
    .build()

// Companion object function accessible as static from Java
val staticFunction = FunSpec.builder("getInstance")
    .addAnnotation(JvmAnnotations.jvmStatic())
    .returns(ClassName("", "Singleton"))
    .addStatement("return instance")
    .build()

// Property exposed as field to Java
val jvmFieldProperty = PropertySpec.builder("CONSTANT", STRING)
    .addModifiers(KModifier.CONST)
    .addAnnotation(JvmAnnotations.jvmField())
    .initializer("%S", "constant_value")
    .build()

// Function with custom JVM name
val kotlinFunction = FunSpec.builder("kotlinSpecificName")
    .addAnnotation(JvmAnnotations.jvmName("javaFriendlyName"))
    .returns(UNIT)
    .addStatement("// Implementation")
    .build()

// File-level annotation for multifile classes
val multifileClass = FileSpec.builder("com.example", "Utils")
    .addAnnotation(JvmAnnotations.jvmMultifileClass())
    .addFunction(staticFunction)
    .build()

Annotation Processing Support

Features specifically designed for annotation processors and code generation frameworks.

// Originating elements for annotation processors
interface OriginatingElementsHolder {
    val originatingElements: List<Element>
}

// Context parameters for context receivers
class ContextParameter {
    companion object {
        fun get(name: String, type: TypeName): ContextParameter
    }
}

Usage Examples:

// Annotation processor generated class
val generatedClass = TypeSpec.classBuilder("Generated_UserRepository")
    .addOriginatingElement(userElement) // From annotation processor
    .addFunction(
        FunSpec.builder("save")
            .addParameter("user", ClassName.get("", "User"))
            .addStatement("database.save(user)")
            .build()
    )
    .build()

// Generated annotation for tracking
val generatedAnnotation = AnnotationSpec.builder(ClassName.get("javax.annotation.processing", "Generated"))
    .addMember("value = [%S]", "com.example.processor.UserProcessor")
    .addMember("date = %S", Instant.now().toString())
    .build()

val annotatedClass = TypeSpec.classBuilder("ProcessedUser")
    .addAnnotation(generatedAnnotation)
    .build()

Metadata and Documentation Annotations

Support for documentation and metadata annotations that enhance code comprehension and tooling.

Usage Examples:

// Comprehensive documentation with multiple annotations
val documentedFunction = FunSpec.builder("complexOperation")
    .addKdoc("""
        Performs a complex operation on the input data.
        
        This function processes the input through multiple stages:
        1. Validation
        2. Transformation  
        3. Persistence
        
        @param data The input data to process
        @param options Configuration options for processing
        @return The processed result
        @throws IllegalArgumentException if data is invalid
        @throws ProcessingException if processing fails
        @since 1.2.0
        @see SimpleOperation for a simpler alternative
    """.trimIndent())
    .addAnnotation(
        AnnotationSpec.builder(ClassName.get("", "ApiStatus"))
            .addMember("value = %T.%L", ClassName.get("", "ApiStatus", "Stability"), "STABLE")
            .build()
    )
    .addAnnotation(
        AnnotationSpec.builder(ClassName.get("", "Contract"))
            .addMember("pure = %L", true)
            .build()
    )
    .addParameter("data", STRING)
    .addParameter("options", ClassName.get("", "ProcessingOptions"))
    .returns(ClassName.get("", "ProcessingResult"))
    .addAnnotation(JvmAnnotations.throws(
        ClassName.get("", "IllegalArgumentException"),
        ClassName.get("", "ProcessingException")
    ))
    .build()

// Experimental API annotation
val experimentalFunction = FunSpec.builder("experimentalFeature")
    .addAnnotation(
        AnnotationSpec.builder(ClassName.get("", "ExperimentalApi"))
            .addMember("message = %S", "This API is experimental and may change")
            .build()
    )
    .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