or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations-and-metadata.mdcode-generation.mdfile-and-type-generation.mdfunction-and-property-generation.mdindex.mdtype-system.mdutilities.md

annotations-and-metadata.mddocs/

0

# Annotations and Metadata

1

2

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

3

4

## Capabilities

5

6

### Annotation Specification

7

8

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

9

10

```kotlin { .api }

11

/**

12

* Specification for generating annotations

13

*/

14

class AnnotationSpec private constructor() {

15

/** The type name of this annotation */

16

val typeName: TypeName

17

18

/** The member values for this annotation */

19

val members: Map<String, List<CodeBlock>>

20

21

/** String representation for use in generated code */

22

val useSiteTarget: UseSiteTarget?

23

24

companion object {

25

/** Creates a builder for an annotation */

26

fun builder(type: ClassName): Builder

27

fun builder(type: Class<*>): Builder

28

fun builder(type: KClass<*>): Builder

29

30

/** Creates a simple annotation without parameters */

31

fun get(type: ClassName): AnnotationSpec

32

fun get(type: Class<*>): AnnotationSpec

33

fun get(type: KClass<*>): AnnotationSpec

34

}

35

36

/** Builder for constructing AnnotationSpec instances */

37

class Builder {

38

/** Adds a member value to the annotation */

39

fun addMember(name: String, format: String, vararg args: Any?): Builder

40

fun addMember(name: String, codeBlock: CodeBlock): Builder

41

42

/** Sets the use-site target for the annotation */

43

fun useSiteTarget(useSiteTarget: UseSiteTarget): Builder

44

45

/** Builds the AnnotationSpec */

46

fun build(): AnnotationSpec

47

}

48

49

/** Use-site targets for annotations */

50

enum class UseSiteTarget {

51

FILE, PROPERTY, FIELD, GET, SET, RECEIVER, PARAM, SETPARAM, DELEGATE

52

}

53

}

54

```

55

56

**Usage Examples:**

57

58

```kotlin

59

import com.squareup.kotlinpoet.*

60

61

// Simple annotation without parameters

62

val deprecatedAnnotation = AnnotationSpec.get(Deprecated::class)

63

64

// Annotation with string parameter

65

val deprecatedWithMessage = AnnotationSpec.builder(Deprecated::class)

66

.addMember("message = %S", "Use newMethod() instead")

67

.build()

68

69

// Annotation with multiple parameters

70

val suppressWarnings = AnnotationSpec.builder(Suppress::class)

71

.addMember("names = [%S, %S]", "UNCHECKED_CAST", "DEPRECATION")

72

.build()

73

74

// Custom annotation with complex parameters

75

val customAnnotation = AnnotationSpec.builder(ClassName.get("com.example", "Configuration"))

76

.addMember("name = %S", "database")

77

.addMember("timeout = %L", 30)

78

.addMember("enabled = %L", true)

79

.addMember("tags = [%S, %S]", "production", "critical")

80

.build()

81

82

// Annotation with enum parameter

83

val requestMapping = AnnotationSpec.builder(ClassName.get("", "RequestMapping"))

84

.addMember("method = %T.%L", ClassName.get("", "RequestMethod"), "GET")

85

.addMember("path = %S", "/users/{id}")

86

.build()

87

88

// Annotation with class parameter

89

val jsonDeserialize = AnnotationSpec.builder(ClassName.get("com.fasterxml.jackson.databind.annotation", "JsonDeserialize"))

90

.addMember("using = %T::class", ClassName.get("com.example", "CustomDeserializer"))

91

.build()

92

93

// Annotation with nested annotation

94

val validatedAnnotation = AnnotationSpec.builder(ClassName.get("", "Validated"))

95

.addMember("constraints = [%L]",

96

AnnotationSpec.builder(ClassName.get("", "NotNull")).build()

97

)

98

.build()

99

100

// Use-site targets for property annotations

101

val fieldAnnotation = AnnotationSpec.builder(ClassName.get("", "Inject"))

102

.useSiteTarget(AnnotationSpec.UseSiteTarget.FIELD)

103

.build()

104

105

val getterAnnotation = AnnotationSpec.builder(ClassName.get("", "JsonProperty"))

106

.useSiteTarget(AnnotationSpec.UseSiteTarget.GET)

107

.addMember("value = %S", "user_name")

108

.build()

109

```

110

111

### Type Alias Specification

112

113

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

114

115

```kotlin { .api }

116

/**

117

* Specification for generating type aliases

118

*/

119

class TypeAliasSpec private constructor() {

120

/** The name of the type alias */

121

val name: String

122

123

/** The type this alias refers to */

124

val type: TypeName

125

126

/** Modifiers applied to the type alias */

127

val modifiers: Set<KModifier>

128

129

/** Type parameters for generic type aliases */

130

val typeVariables: List<TypeVariableName>

131

132

companion object {

133

/** Creates a builder for a type alias */

134

fun builder(name: String, type: TypeName): Builder

135

fun builder(name: String, type: KClass<*>): Builder

136

}

137

138

/** Builder for constructing TypeAliasSpec instances */

139

class Builder {

140

/** Adds modifiers to the type alias */

141

fun addModifiers(vararg modifiers: KModifier): Builder

142

fun addModifiers(modifiers: Iterable<KModifier>): Builder

143

144

/** Adds type parameters */

145

fun addTypeVariable(typeVariable: TypeVariableName): Builder

146

fun addTypeVariables(typeVariables: Iterable<TypeVariableName>): Builder

147

148

/** Adds annotations */

149

fun addAnnotation(annotationSpec: AnnotationSpec): Builder

150

fun addAnnotation(annotation: ClassName): Builder

151

fun addAnnotation(annotation: Class<*>): Builder

152

fun addAnnotation(annotation: KClass<*>): Builder

153

154

/** Adds KDoc documentation */

155

fun addKdoc(format: String, vararg args: Any?): Builder

156

fun addKdoc(block: CodeBlock): Builder

157

158

/** Builds the TypeAliasSpec */

159

fun build(): TypeAliasSpec

160

}

161

}

162

```

163

164

**Usage Examples:**

165

166

```kotlin

167

// Simple type alias

168

val stringMap = TypeAliasSpec.builder(

169

"StringMap",

170

MAP.parameterizedBy(STRING, STRING)

171

).build()

172

173

// Generic type alias

174

val result = TypeAliasSpec.builder(

175

"Result",

176

ClassName.get("kotlin", "Result").parameterizedBy(TypeVariableName.get("T"))

177

)

178

.addTypeVariable(TypeVariableName.get("T"))

179

.build()

180

181

// Type alias for complex function type

182

val eventHandler = TypeAliasSpec.builder(

183

"EventHandler",

184

LambdaTypeName.get(

185

parameters = listOf(

186

ParameterSpec.builder("event", ClassName.get("", "Event")).build()

187

),

188

returnType = UNIT

189

)

190

).build()

191

192

// Type alias with annotations and documentation

193

val userId = TypeAliasSpec.builder("UserId", STRING)

194

.addKdoc("Represents a unique identifier for a user")

195

.addAnnotation(ClassName.get("", "JvmInline"))

196

.build()

197

198

// Internal type alias

199

val internalCache = TypeAliasSpec.builder(

200

"Cache",

201

MAP.parameterizedBy(STRING, ANY.copy(nullable = true))

202

)

203

.addModifiers(KModifier.INTERNAL)

204

.build()

205

206

// Complex generic type alias

207

val repository = TypeAliasSpec.builder("Repository", ClassName.get("", "BaseRepository"))

208

.addTypeVariable(TypeVariableName.get("T"))

209

.addTypeVariable(TypeVariableName.get("ID"))

210

.build()

211

```

212

213

### JVM-Specific Annotations

214

215

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

216

217

```kotlin { .api }

218

/**

219

* Utilities for JVM-specific annotations

220

*/

221

object JvmAnnotations {

222

/** Adds @JvmOverloads annotation to a function for Java interop */

223

fun overloads(funSpec: FunSpec): FunSpec

224

225

/** Creates @Throws annotation with specified exception classes */

226

fun throws(vararg exceptionClasses: ClassName): AnnotationSpec

227

fun throws(vararg exceptionClasses: Class<out Throwable>): AnnotationSpec

228

fun throws(vararg exceptionClasses: KClass<out Throwable>): AnnotationSpec

229

230

/** Creates @JvmStatic annotation */

231

fun jvmStatic(): AnnotationSpec

232

233

/** Creates @JvmField annotation */

234

fun jvmField(): AnnotationSpec

235

236

/** Creates @JvmName annotation */

237

fun jvmName(name: String): AnnotationSpec

238

239

/** Creates @JvmMultifileClass annotation */

240

fun jvmMultifileClass(): AnnotationSpec

241

}

242

```

243

244

**Usage Examples:**

245

246

```kotlin

247

import com.squareup.kotlinpoet.jvm.JvmAnnotations

248

import com.squareup.kotlinpoet.*

249

250

// Function with JVM overloads for Java interop

251

val functionWithDefaults = FunSpec.builder("processData")

252

.addParameter("data", STRING)

253

.addParameter(

254

ParameterSpec.builder("timeout", INT)

255

.defaultValue("%L", 5000)

256

.build()

257

)

258

.addParameter(

259

ParameterSpec.builder("retries", INT)

260

.defaultValue("%L", 3)

261

.build()

262

)

263

.returns(STRING)

264

.addStatement("return data.process()")

265

.build()

266

267

val jvmFunction = JvmAnnotations.overloads(functionWithDefaults)

268

269

// Function that throws exceptions for Java callers

270

val throwingFunction = FunSpec.builder("readFile")

271

.addParameter("filename", STRING)

272

.returns(STRING)

273

.addAnnotation(JvmAnnotations.throws(IOException::class, SecurityException::class))

274

.addStatement("return File(filename).readText()")

275

.build()

276

277

// Companion object function accessible as static from Java

278

val staticFunction = FunSpec.builder("getInstance")

279

.addAnnotation(JvmAnnotations.jvmStatic())

280

.returns(ClassName("", "Singleton"))

281

.addStatement("return instance")

282

.build()

283

284

// Property exposed as field to Java

285

val jvmFieldProperty = PropertySpec.builder("CONSTANT", STRING)

286

.addModifiers(KModifier.CONST)

287

.addAnnotation(JvmAnnotations.jvmField())

288

.initializer("%S", "constant_value")

289

.build()

290

291

// Function with custom JVM name

292

val kotlinFunction = FunSpec.builder("kotlinSpecificName")

293

.addAnnotation(JvmAnnotations.jvmName("javaFriendlyName"))

294

.returns(UNIT)

295

.addStatement("// Implementation")

296

.build()

297

298

// File-level annotation for multifile classes

299

val multifileClass = FileSpec.builder("com.example", "Utils")

300

.addAnnotation(JvmAnnotations.jvmMultifileClass())

301

.addFunction(staticFunction)

302

.build()

303

```

304

305

### Annotation Processing Support

306

307

Features specifically designed for annotation processors and code generation frameworks.

308

309

```kotlin { .api }

310

// Originating elements for annotation processors

311

interface OriginatingElementsHolder {

312

val originatingElements: List<Element>

313

}

314

315

// Context parameters for context receivers

316

class ContextParameter {

317

companion object {

318

fun get(name: String, type: TypeName): ContextParameter

319

}

320

}

321

```

322

323

**Usage Examples:**

324

325

```kotlin

326

// Annotation processor generated class

327

val generatedClass = TypeSpec.classBuilder("Generated_UserRepository")

328

.addOriginatingElement(userElement) // From annotation processor

329

.addFunction(

330

FunSpec.builder("save")

331

.addParameter("user", ClassName.get("", "User"))

332

.addStatement("database.save(user)")

333

.build()

334

)

335

.build()

336

337

// Generated annotation for tracking

338

val generatedAnnotation = AnnotationSpec.builder(ClassName.get("javax.annotation.processing", "Generated"))

339

.addMember("value = [%S]", "com.example.processor.UserProcessor")

340

.addMember("date = %S", Instant.now().toString())

341

.build()

342

343

val annotatedClass = TypeSpec.classBuilder("ProcessedUser")

344

.addAnnotation(generatedAnnotation)

345

.build()

346

```

347

348

### Metadata and Documentation Annotations

349

350

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

351

352

**Usage Examples:**

353

354

```kotlin

355

// Comprehensive documentation with multiple annotations

356

val documentedFunction = FunSpec.builder("complexOperation")

357

.addKdoc("""

358

Performs a complex operation on the input data.

359

360

This function processes the input through multiple stages:

361

1. Validation

362

2. Transformation

363

3. Persistence

364

365

@param data The input data to process

366

@param options Configuration options for processing

367

@return The processed result

368

@throws IllegalArgumentException if data is invalid

369

@throws ProcessingException if processing fails

370

@since 1.2.0

371

@see SimpleOperation for a simpler alternative

372

""".trimIndent())

373

.addAnnotation(

374

AnnotationSpec.builder(ClassName.get("", "ApiStatus"))

375

.addMember("value = %T.%L", ClassName.get("", "ApiStatus", "Stability"), "STABLE")

376

.build()

377

)

378

.addAnnotation(

379

AnnotationSpec.builder(ClassName.get("", "Contract"))

380

.addMember("pure = %L", true)

381

.build()

382

)

383

.addParameter("data", STRING)

384

.addParameter("options", ClassName.get("", "ProcessingOptions"))

385

.returns(ClassName.get("", "ProcessingResult"))

386

.addAnnotation(JvmAnnotations.throws(

387

ClassName.get("", "IllegalArgumentException"),

388

ClassName.get("", "ProcessingException")

389

))

390

.build()

391

392

// Experimental API annotation

393

val experimentalFunction = FunSpec.builder("experimentalFeature")

394

.addAnnotation(

395

AnnotationSpec.builder(ClassName.get("", "ExperimentalApi"))

396

.addMember("message = %S", "This API is experimental and may change")

397

.build()

398

)

399

.build()

400

```