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

utilities.mddocs/

Utilities and Language Support

Essential utilities for name allocation, modifier management, and platform-specific functionality across JVM, JavaScript, and WebAssembly targets.

Capabilities

Name Allocation and Collision Avoidance

Manages identifier names while avoiding collisions with Kotlin keywords and existing identifiers.

/**
 * Allocates names while avoiding collisions with keywords and existing identifiers
 */
class NameAllocator {
    /** Allocates a new name based on the suggestion, avoiding conflicts */
    fun newName(suggestion: String, tag: Any? = null): String
    
    /** Retrieves the allocated name for the given tag */
    fun get(tag: Any): String
    
    /** Creates a copy of this name allocator with the same allocated names */
    fun copy(): NameAllocator
    
    companion object {
        /** Creates a new NameAllocator instance */
        fun get(): NameAllocator
    }
}

Usage Examples:

import com.squareup.kotlinpoet.*

// Basic name allocation
val allocator = NameAllocator()

// Allocate names avoiding conflicts
val className = allocator.newName("User", "userClass")
val methodName = allocator.newName("process", "processMethod")

// Avoid Kotlin keywords
val safeName = allocator.newName("class", "typeInfo") // Results in "class_" or similar
val safeObject = allocator.newName("object", "instanceRef")

// Use tags to retrieve allocated names later
val userTag = "USER_ENTITY"
val allocatedUserName = allocator.newName("User", userTag)
// Later retrieve the same name
val retrievedName = allocator.get(userTag) // Same as allocatedUserName

// Generate multiple related names
val propertyNames = listOf("name", "age", "email", "class", "object")
val allocatedProperties = propertyNames.mapIndexed { index, name ->
    allocator.newName(name, "property_$index")
}

// Copy allocator for different scopes
val methodAllocator = allocator.copy()
val localVar = methodAllocator.newName("result", "localResult")

// Practical usage in code generation
fun generateDataClass(fields: List<Field>): TypeSpec {
    val allocator = NameAllocator()
    val className = allocator.newName("Generated${fields.first().type}", "mainClass")
    
    return TypeSpec.classBuilder(className)
        .addModifiers(KModifier.DATA)
        .primaryConstructor(
            FunSpec.constructorBuilder()
                .apply {
                    fields.forEach { field ->
                        val paramName = allocator.newName(field.name, field)
                        addParameter(paramName, field.type)
                    }
                }
                .build()
        )
        .apply {
            fields.forEach { field ->
                val propName = allocator.get(field)
                addProperty(
                    PropertySpec.builder(propName, field.type)
                        .initializer(propName)
                        .build()
                )
            }
        }
        .build()
}

Kotlin Modifiers

Comprehensive enumeration of all Kotlin language modifiers with proper categorization.

/**
 * Kotlin language modifiers
 */
enum class KModifier {
    // Visibility modifiers
    PUBLIC, PROTECTED, PRIVATE, INTERNAL,
    
    // Inheritance modifiers  
    FINAL, OPEN, ABSTRACT, SEALED,
    
    // Multiplatform modifiers
    EXPECT, ACTUAL,
    
    // Function/property modifiers
    OVERRIDE, LATEINIT, CONST, EXTERNAL,
    
    // Function-specific modifiers
    TAILREC, OPERATOR, INFIX, INLINE, SUSPEND,
    
    // Parameter modifiers
    VARARG, CROSSINLINE, NOINLINE, REIFIED,
    
    // Class type modifiers
    DATA, INNER, ENUM, ANNOTATION, FUN, COMPANION, VALUE
}

Usage Examples:

// Visibility modifiers
val publicClass = TypeSpec.classBuilder("PublicClass")
    .addModifiers(KModifier.PUBLIC)
    .build()

val privateProperty = PropertySpec.builder("privateField", String::class)
    .addModifiers(KModifier.PRIVATE)
    .build()

val internalFunction = FunSpec.builder("internalHelper")
    .addModifiers(KModifier.INTERNAL)
    .build()

// Inheritance modifiers
val openClass = TypeSpec.classBuilder("BaseClass")
    .addModifiers(KModifier.OPEN)
    .build()

val abstractClass = TypeSpec.classBuilder("AbstractProcessor")
    .addModifiers(KModifier.ABSTRACT)
    .build()

val sealedClass = TypeSpec.classBuilder("Result")
    .addModifiers(KModifier.SEALED)
    .addTypeVariable(TypeVariableName("T"))
    .build()

val finalClass = TypeSpec.classBuilder("ImmutableData")
    .addModifiers(KModifier.FINAL) // Default for classes, explicit here
    .build()

// Class type modifiers  
val dataClass = TypeSpec.classBuilder("Person")
    .addModifiers(KModifier.DATA)
    .build()

val enumClass = TypeSpec.enumBuilder("Status")
    .addModifiers(KModifier.ENUM) // Implicit with enumBuilder
    .build()

val valueClass = TypeSpec.classBuilder("UserId")
    .addModifiers(KModifier.VALUE)
    .build()

val companionObject = TypeSpec.companionObjectBuilder()
    .addModifiers(KModifier.COMPANION) // Implicit with companionObjectBuilder
    .build()

// Function modifiers
val inlineFunction = FunSpec.builder("fastOperation")
    .addModifiers(KModifier.INLINE)
    .build()

val suspendFunction = FunSpec.builder("asyncTask")
    .addModifiers(KModifier.SUSPEND)
    .build()

val operatorFunction = FunSpec.builder("plus")
    .addModifiers(KModifier.OPERATOR)
    .build()

val infixFunction = FunSpec.builder("multiply")
    .addModifiers(KModifier.INFIX)
    .build()

val tailrecFunction = FunSpec.builder("factorial")
    .addModifiers(KModifier.TAILREC)
    .build()

// Property modifiers
val lateInitProperty = PropertySpec.varBuilder("database", ClassName("", "Database"))
    .addModifiers(KModifier.LATEINIT)
    .build()

val constProperty = PropertySpec.builder("MAX_SIZE", Int::class)
    .addModifiers(KModifier.CONST)
    .build()

val overrideProperty = PropertySpec.builder("size", Int::class)
    .addModifiers(KModifier.OVERRIDE)
    .build()

// Parameter modifiers
val varargParameter = ParameterSpec.builder("items", String::class)
    .addModifiers(KModifier.VARARG)
    .build()

val crossInlineParameter = ParameterSpec.builder("block", LambdaTypeName.get(returnType = UNIT))
    .addModifiers(KModifier.CROSSINLINE)
    .build()

val noinlineParameter = ParameterSpec.builder("callback", LambdaTypeName.get(returnType = UNIT))
    .addModifiers(KModifier.NOINLINE)
    .build()

// Multiplatform modifiers
val expectClass = TypeSpec.classBuilder("PlatformSpecific")
    .addModifiers(KModifier.EXPECT)
    .build()

val actualClass = TypeSpec.classBuilder("PlatformSpecific")
    .addModifiers(KModifier.ACTUAL)
    .build()

// External modifier for native interop
val externalFunction = FunSpec.builder("nativeFunction")
    .addModifiers(KModifier.EXTERNAL)
    .build()

Kotlin Operators

Enumeration of all Kotlin operators for operator function overloading.

/**
 * Kotlin operators for operator functions
 */
enum class KOperator {
    // Unary operators
    UNARY_PLUS, UNARY_MINUS, NOT, INC, DEC,
    
    // Binary arithmetic operators
    PLUS, MINUS, TIMES, DIV, REM,
    
    // Range operator
    RANGE_TO,
    
    // Collection operators
    CONTAINS, GET, SET,
    
    // Invoke operator
    INVOKE,
    
    // Compound assignment operators
    PLUS_ASSIGN, MINUS_ASSIGN, TIMES_ASSIGN, DIV_ASSIGN, REM_ASSIGN,
    
    // Comparison operators
    EQUALS, COMPARE_TO
}

Usage Examples:

// Arithmetic operators
val plusOperator = FunSpec.builder("plus")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Vector"))
    .addParameter("other", ClassName("", "Vector"))
    .returns(ClassName("", "Vector"))
    .addStatement("return Vector(x + other.x, y + other.y)")
    .build()

val minusOperator = FunSpec.builder("minus")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Vector"))
    .addParameter("other", ClassName("", "Vector"))
    .returns(ClassName("", "Vector"))
    .addStatement("return Vector(x - other.x, y - other.y)")
    .build()

// Unary operators
val unaryMinusOperator = FunSpec.builder("unaryMinus")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Vector"))
    .returns(ClassName("", "Vector"))
    .addStatement("return Vector(-x, -y)")
    .build()

val incOperator = FunSpec.builder("inc")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Counter"))
    .returns(ClassName("", "Counter"))
    .addStatement("return Counter(value + 1)")
    .build()

// Collection access operators
val getOperator = FunSpec.builder("get")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Matrix"))
    .addParameter("row", Int::class)
    .addParameter("col", Int::class)
    .returns(Double::class)
    .addStatement("return data[row * cols + col]")
    .build()

val setOperator = FunSpec.builder("set")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Matrix"))
    .addParameter("row", Int::class)
    .addParameter("col", Int::class)
    .addParameter("value", Double::class)
    .returns(UNIT)
    .addStatement("data[row * cols + col] = value")
    .build()

// Contains operator
val containsOperator = FunSpec.builder("contains")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Range"))
    .addParameter("value", Int::class)
    .returns(Boolean::class)
    .addStatement("return value >= start && value <= end")
    .build()

// Invoke operator (function-like objects)
val invokeOperator = FunSpec.builder("invoke")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Multiplier"))
    .addParameter("value", Int::class)
    .returns(Int::class)
    .addStatement("return value * factor")
    .build()

// Compound assignment operators
val plusAssignOperator = FunSpec.builder("plusAssign")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "MutableVector"))
    .addParameter("other", ClassName("", "Vector"))
    .returns(UNIT)
    .addStatement("x += other.x")
    .addStatement("y += other.y")
    .build()

// Comparison operators
val compareToOperator = FunSpec.builder("compareTo")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Version"))
    .addParameter("other", ClassName("", "Version"))
    .returns(Int::class)
    .addStatement("return major.compareTo(other.major)")
    .build()

// Range operator
val rangeToOperator = FunSpec.builder("rangeTo")
    .addModifiers(KModifier.OPERATOR)
    .receiver(ClassName("", "Date"))
    .addParameter("other", ClassName("", "Date"))
    .returns(ClassName("", "DateRange"))
    .addStatement("return DateRange(this, other)")
    .build()

Platform-Specific Utilities

Utilities that handle platform differences and provide multiplatform support.

// Common utilities (available on all platforms)
class CodePoint {
    companion object {
        fun isISOControl(codePoint: Int): Boolean
    }
}

// Line wrapping utilities
class LineWrapper {
    // Implementation varies by platform
}

// Platform-specific utility objects
object Util {
    // Common utilities available on all platforms
}

// JVM-specific utilities (only available on JVM)
object JvmUtil {
    // JVM-specific implementation details
}

Usage Examples:

// Unicode handling across platforms
val unicodeChecker = FunSpec.builder("isControlCharacter")
    .addParameter("codePoint", Int::class)
    .returns(Boolean::class)
    .addStatement("return %T.isISOControl(codePoint)", CodePoint::class)
    .build()

// Platform-specific code generation
val platformSpecificFunction = when (targetPlatform) {
    Platform.JVM -> FunSpec.builder("processFile")
        .addParameter("file", File::class)
        .addStatement("// JVM-specific file processing")
        .build()
        
    Platform.JS -> FunSpec.builder("processFile")
        .addParameter("file", Dynamic)
        .addStatement("// JavaScript-specific file processing")
        .build()
        
    Platform.WASM -> FunSpec.builder("processFile")
        .addParameter("file", String::class)
        .addStatement("// WebAssembly-specific file processing")
        .build()
}

Helper Interfaces and Abstractions

Core interfaces that provide common functionality across KotlinPoet specifications.

/**
 * Interface for specs that support tags
 */
interface Taggable {
    val tags: Map<KClass<*>, Any>
}

/**
 * Interface for specs that support KDoc documentation
 */
interface Documentable {
    val kdoc: CodeBlock
}

/**
 * Interface for specs that hold references to originating elements (for annotation processing)
 */
interface OriginatingElementsHolder {
    val originatingElements: List<Element>
}

/**
 * Interface for specs that contain member specifications
 */
interface MemberSpecHolder {
    // Marker interface for type hierarchy
}

Usage Examples:

// Using tagging for metadata
val taggedFunction = FunSpec.builder("processData")
    .tag(String::class, "user-generated")
    .tag(Int::class, 42)
    .build()

// Retrieve tags later
val userTag = taggedFunction.tags[String::class] as? String
val numberTag = taggedFunction.tags[Int::class] as? Int

// Documentation interface usage
val documentedClass = TypeSpec.classBuilder("UserService")
    .addKdoc("""
        Service for managing user operations.
        
        This service provides CRUD operations for user entities
        and handles business logic related to user management.
    """.trimIndent())
    .build()

// Check if a spec is documentable
fun addDocumentationIfSupported(spec: Any, doc: String) {
    if (spec is Documentable && spec.kdoc.isEmpty) {
        // Add documentation
    }
}

Experimental and Delicate APIs

Annotations for marking unstable or dangerous APIs.

/**
 * Marks delicate KotlinPoet APIs that require careful usage
 */
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
annotation class DelicateKotlinPoetApi

/**
 * Marks experimental KotlinPoet APIs
 */
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
annotation class ExperimentalKotlinPoetApi

Usage Examples:

// Using experimental APIs
@OptIn(ExperimentalKotlinPoetApi::class)
fun useExperimentalFeature() {
    // Use experimental KotlinPoet features
}

// Using delicate APIs
@OptIn(DelicateKotlinPoetApi::class)
fun useDelicateApi() {
    // Use delicate KotlinPoet APIs that require careful handling
}

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