1%T for Types 2============ 3 4KotlinPoet has rich built-in support for types, including automatic generation of `import` 5statements. Just use **`%T`** to reference **types**: 6 7```kotlin 8val today = FunSpec.builder("today") 9 .returns(Date::class) 10 .addStatement("return %T()", Date::class) 11 .build() 12 13val helloWorld = TypeSpec.classBuilder("HelloWorld") 14 .addFunction(today) 15 .build() 16 17val kotlinFile = FileSpec.builder("com.example.helloworld", "HelloWorld") 18 .addType(helloWorld) 19 .build() 20 21kotlinFile.writeTo(System.out) 22``` 23 24That generates the following `.kt` file, complete with the necessary `import`: 25 26```kotlin 27package com.example.helloworld 28 29import java.util.Date 30 31class HelloWorld { 32 fun today(): Date = Date() 33} 34``` 35 36We passed `Date::class` to reference a class that just-so-happens to be available when we're 37generating code. This doesn't need to be the case. Here's a similar example, but this one 38references a class that doesn't exist (yet): 39 40```kotlin 41val hoverboard = ClassName("com.mattel", "Hoverboard") 42 43val tomorrow = FunSpec.builder("tomorrow") 44 .returns(hoverboard) 45 .addStatement("return %T()", hoverboard) 46 .build() 47``` 48 49And that not-yet-existent class is imported as well: 50 51```kotlin 52package com.example.helloworld 53 54import com.mattel.Hoverboard 55 56class HelloWorld { 57 fun tomorrow(): Hoverboard = Hoverboard() 58} 59``` 60 61The `ClassName` type is very important, and you'll need it frequently when you're using KotlinPoet. 62It can identify any _declared_ class. Declared types are just the beginning of Kotlin's rich type 63system: we also have arrays, parameterized types, wildcard types, lambda types and type variables. 64KotlinPoet has classes for building each of these: 65 66```kotlin 67import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy 68import com.squareup.kotlinpoet.STAR 69 70val hoverboard = ClassName("com.mattel", "Hoverboard") 71val list = ClassName("kotlin.collections", "List") 72val arrayList = ClassName("kotlin.collections", "ArrayList") 73val listOfHoverboards = list.parameterizedBy(hoverboard) 74val arrayListOfHoverboards = arrayList.parameterizedBy(hoverboard) 75 76val thing = ClassName("com.misc", "Thing") 77val array = ClassName("kotlin", "Array") 78val producerArrayOfThings = array.parameterizedBy(WildcardTypeName.producerOf(thing)) 79 80val beyond = FunSpec.builder("beyond") 81 .returns(listOfHoverboards) 82 .addStatement("val result = %T()", arrayListOfHoverboards) 83 .addStatement("result += %T()", hoverboard) 84 .addStatement("result += %T()", hoverboard) 85 .addStatement("result += %T()", hoverboard) 86 .addStatement("return result") 87 .build() 88 89val printThings = FunSpec.builder("printThings") 90 .addParameter("things", producerArrayOfThings) 91 .addStatement("println(things)") 92 .build() 93 94val printKClass = FunSpec.builder("printKClass") 95 .addParameter("kClass", KClass::class.asClassName().parameterizedBy(STAR)) 96 .addStatement("println(kClass)") 97 .build() 98``` 99 100The `STAR` is represented as `*` in KotlinPoet. You can find more in the [KDoc][kdoc]. 101 102KotlinPoet will decompose each type and import its components where possible. 103 104```kotlin 105package com.example.helloworld 106 107import com.mattel.Hoverboard 108import com.misc.Thing 109import kotlin.Array 110import kotlin.collections.ArrayList 111import kotlin.collections.List 112import kotlin.reflect.KClass 113 114class HelloWorld { 115 fun beyond(): List<Hoverboard> { 116 val result = ArrayList<Hoverboard>() 117 result += Hoverboard() 118 result += Hoverboard() 119 result += Hoverboard() 120 return result 121 } 122 123 fun printThings(things: Array<out Thing>) { 124 println(things) 125 } 126 127 fun printKClass(kClass: KClass<*>) { 128 println(kClass) 129 } 130} 131``` 132 133## Nullable Types 134 135KotlinPoet supports nullable types. To convert a `TypeName` into its nullable counterpart, use the 136`copy()` method with `nullable` parameter set to `true`: 137 138```kotlin 139val java = PropertySpec.builder("java", String::class.asTypeName().copy(nullable = true)) 140 .mutable() 141 .addModifiers(KModifier.PRIVATE) 142 .initializer("null") 143 .build() 144 145val helloWorld = TypeSpec.classBuilder("HelloWorld") 146 .addProperty(java) 147 .addProperty("kotlin", String::class, KModifier.PRIVATE) 148 .build() 149``` 150 151generates: 152 153```kotlin 154class HelloWorld { 155 private var java: String? = null 156 157 private val kotlin: String 158} 159``` 160 161 [kdoc]: https://square.github.io/kotlinpoet/1.x/kotlinpoet/kotlinpoet/com.squareup.kotlinpoet/ 162