Inline properties

KotlinPoetDSL is more permissive than KotlinPoet

Inlining

In this chapter, I try to explain how KotlinPoets inlining works and why.

Inlined accessor

In kotlin you can inline an accessor:

var a : String
    get() = "hi"
    inline set(value){
        println(value)
    }

When one accessor is inlined, there is no private field generated anymore! The other accessor (function) can still be uninlined, but it can't access the field anymore!

Inlined property

Kotlin also created another way to inline a property: addind inline in front of a property. this means both getter and setter are automatically inlined.

KotlinPoetDSL choose a bit different approach: The meaning of inline property still means that both the getter and setter needs to be inlined, but KotlinPoetDSL doesn't do this for you. This means it's a check which checks if the getter and setter specified are both inlined. the reason behind this approach is that the the inlined accessor-approach doesn't looks very safe, if you don't have immediate compile-checks. Hopefully having to add inline in front of the getter/setter makes it more clear that you can't access the field.

But that means the short code is no more... You're partly correct, but there is hopefully a little bit of good news: KotlinPoetDSL added an easier approach to an inlined val. If you add inline to an initialized field without getter and setter, KotlinPoetDSL puts the initialization inside an inlined get:

inline val a = "hi"
//will become
inline val a get() = "hi"

Hopefully, it's enough to make you happy again?

Show me

blah, blah blah. I want code!!!

Inlined accessor

prop("hi" valOf String::class){
    inline.getter {
        statement("return %S", "hi")
    }
} // inline val hi : String get() = "hi"

prop("hi" varOf String::class){
    inline.getter {
        statement("return %S", "hi")
    }
    setter {  }
} 
// var hi : String 
//     inline get() = "hi"
//     set() {}

Additional constraints

fun buildInlineStringProp(getter: FunSpec, setter: FunSpec) = createProp {
    inline.prop("a" of String::class){
        acceptSetter(setter) 
        acceptGetter(getter)
    }
} // will fail if getter or setter is not inlined 

I know this is not the main purpose of the DSL: composing, but if the class is very big and you forget inline then it's also smart to have this feature. but this is open for discussion, like everything in this guide, while we are still in the prerelease.

Inlined initialized property

// inline val hi get() = "Hello"
inline.prop("hi".valOf<String>("Hello".S()))

Last updated