xref: /aosp_15_r20/external/kotlinpoet/docs/annotations.md (revision 3c321d951dd070fb96f8ba59e952ffc3131379a0)
1Annotations
2===========
3
4Simple annotations are easy:
5
6```kotlin
7val test = FunSpec.builder("test string equality")
8  .addAnnotation(Test::class)
9  .addStatement("assertThat(%1S).isEqualTo(%1S)", "foo")
10  .build()
11```
12
13Which generates this function with an `@Test` annotation:
14
15```kotlin
16@Test
17fun `test string equality`() {
18  assertThat("foo").isEqualTo("foo")
19}
20```
21
22Use `AnnotationSpec.builder()` to set properties on annotations:
23
24```kotlin
25val logRecord = FunSpec.builder("recordEvent")
26  .addModifiers(KModifier.ABSTRACT)
27  .addAnnotation(
28    AnnotationSpec.builder(Headers::class)
29      .addMember("accept = %S", "application/json; charset=utf-8")
30      .addMember("userAgent = %S", "Square Cash")
31      .build()
32  )
33  .addParameter("logRecord", LogRecord::class)
34  .returns(LogReceipt::class)
35  .build()
36```
37
38Which generates this annotation with `accept` and `userAgent` properties:
39
40```kotlin
41@Headers(
42  accept = "application/json; charset=utf-8",
43  userAgent = "Square Cash"
44)
45abstract fun recordEvent(logRecord: LogRecord): LogReceipt
46```
47
48When you get fancy, annotation values can be annotations themselves. Use `%L` for embedded
49annotations:
50
51```kotlin
52val headerList = ClassName("", "HeaderList")
53val header = ClassName("", "Header")
54val logRecord = FunSpec.builder("recordEvent")
55  .addModifiers(KModifier.ABSTRACT)
56  .addAnnotation(
57    AnnotationSpec.builder(headerList)
58      .addMember(
59        "[\n⇥%L,\n%L⇤\n]",
60        AnnotationSpec.builder(header)
61          .addMember("name = %S", "Accept")
62          .addMember("value = %S", "application/json; charset=utf-8")
63          .build(),
64        AnnotationSpec.builder(header)
65          .addMember("name = %S", "User-Agent")
66          .addMember("value = %S", "Square Cash")
67          .build()
68      )
69      .build()
70  )
71  .addParameter("logRecord", logRecordName)
72  .returns(logReceipt)
73  .build()
74```
75
76Which generates this:
77
78```kotlin
79@HeaderList(
80  [
81    Header(name = "Accept", value = "application/json; charset=utf-8"),
82    Header(name = "User-Agent", value = "Square Cash")
83  ]
84)
85abstract fun recordEvent(logRecord: LogRecord): LogReceipt
86```
87
88KotlinPoet supports use-site targets for annotations:
89
90```kotlin
91val utils = FileSpec.builder("com.example", "Utils")
92  .addAnnotation(
93    AnnotationSpec.builder(JvmName::class)
94      .useSiteTarget(UseSiteTarget.FILE)
95      .build()
96  )
97  .addFunction(
98    FunSpec.builder("abs")
99      .receiver(Int::class)
100      .returns(Int::class)
101      .addStatement("return if (this < 0) -this else this")
102      .build()
103  )
104  .build()
105```
106
107Will output this:
108
109```kotlin
110@file:JvmName
111
112package com.example
113
114import kotlin.Int
115import kotlin.jvm.JvmName
116
117fun Int.abs(): Int = if (this < 0) -this else this
118```
119