xref: /aosp_15_r20/external/kotlinpoet/docs/m-for-members.md (revision 3c321d951dd070fb96f8ba59e952ffc3131379a0)
1%M for Members
2==============
3
4Similar to types, KotlinPoet has a special placeholder for **members** (functions and properties),
5which comes handy when your code needs to access top-level members and members declared inside
6objects. Use **`%M`** to reference members, pass an instance of `MemberName` as the argument for the
7placeholder, and KotlinPoet will handle imports automatically:
8
9```kotlin
10val createTaco = MemberName("com.squareup.tacos", "createTaco")
11val isVegan = MemberName("com.squareup.tacos", "isVegan")
12val file = FileSpec.builder("com.squareup.example", "TacoTest")
13  .addFunction(
14    FunSpec.builder("main")
15      .addStatement("val taco = %M()", createTaco)
16      .addStatement("println(taco.%M)", isVegan)
17      .build()
18  )
19  .build()
20println(file)
21```
22
23The code above generates the following file:
24
25```kotlin
26package com.squareup.example
27
28import com.squareup.tacos.createTaco
29import com.squareup.tacos.isVegan
30
31fun main() {
32  val taco = createTaco()
33  println(taco.isVegan)
34}
35```
36
37As you can see, it's also possible to use `%M` to reference extension functions and properties. You
38just need to make sure the member can be imported without simple name collisions, otherwise
39importing will fail and the code generator output will not pass compilation. There's a way to work
40around such cases though - use `FileSpec.addAliasedImport()` to create an alias for a clashing
41`MemberName`:
42
43```kotlin
44val createTaco = MemberName("com.squareup.tacos", "createTaco")
45val createCake = MemberName("com.squareup.cakes", "createCake")
46val isTacoVegan = MemberName("com.squareup.tacos", "isVegan")
47val isCakeVegan = MemberName("com.squareup.cakes", "isVegan")
48val file = FileSpec.builder("com.squareup.example", "Test")
49  .addAliasedImport(isTacoVegan, "isTacoVegan")
50  .addAliasedImport(isCakeVegan, "isCakeVegan")
51  .addFunction(
52    FunSpec.builder("main")
53      .addStatement("val taco = %M()", createTaco)
54      .addStatement("val cake = %M()", createCake)
55      .addStatement("println(taco.%M)", isTacoVegan)
56      .addStatement("println(cake.%M)", isCakeVegan)
57      .build()
58  )
59  .build()
60println(file)
61```
62
63KotlinPoet will produce an aliased import for `com.squareup.tacos2.isVegan`:
64
65```kotlin
66package com.squareup.example
67
68import com.squareup.cakes.createCake
69import com.squareup.tacos.createTaco
70import com.squareup.cakes.isVegan as isCakeVegan
71import com.squareup.tacos.isVegan as isTacoVegan
72
73fun main() {
74  val taco = createTaco()
75  val cake = createCake()
76  println(taco.isTacoVegan)
77  println(cake.isCakeVegan)
78}
79```
80
81## MemberName and operators
82
83MemberName also supports operators, you can use `MemberName(String, KOperator)`
84or `MemberName(ClassName, KOperator)` to import and reference operators.
85
86```kotlin
87val taco = ClassName("com.squareup.tacos", "Taco")
88val meat = ClassName("com.squareup.tacos.ingredient", "Meat")
89val iterator = MemberName("com.squareup.tacos.internal", KOperator.ITERATOR)
90val minusAssign = MemberName("com.squareup.tacos.internal", KOperator.MINUS_ASSIGN)
91val file = FileSpec.builder("com.example", "Test")
92  .addFunction(
93    FunSpec.builder("makeTacoHealthy")
94      .addParameter("taco", taco)
95      .beginControlFlow("for (ingredient %M taco)", iterator)
96      .addStatement("if (ingredient is %T) taco %M ingredient", meat, minusAssign)
97      .endControlFlow()
98      .addStatement("return taco")
99      .build()
100  )
101  .build()
102println(file)
103```
104
105KotlinPoet will import the extension operator functions and emit the operator.
106
107```kotlin
108package com.example
109
110import com.squareup.tacos.Taco
111import com.squareup.tacos.ingredient.Meat
112import com.squareup.tacos.internal.iterator
113import com.squareup.tacos.internal.minusAssign
114
115fun makeTacoHealthy(taco: Taco) {
116  for (ingredient in taco) {
117    if (ingredient is Meat) taco -= ingredient
118  }
119  return taco
120}
121
122```
123