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