Reputation: 23262
I have lots of external classes (generated externally; not under my control), which do not come with a builder and which are rather cumbersome to create. However using apply
it is rather easy to build them, e.g.:
SomeOfTheObjects().apply {
someProperty = SomeOtherComplexObject().apply {
someOtherProperty = "..."
}
}
Now I like the way it works with the receiver, but I would like to prevent that I can set someProperty
within SomeOtherComplexObject
. If the classes were under my control, it would suffice to put a @DslMarker
on that class, but as they aren't, the only other way that came to my mind, was to use also
instead without renaming the parameter, e.g.:
SomeOfTheObjects().also {
it.someProperty = SomeOtherComplexObject().also {
it.someOtherProperty = "..."
//it.someProperty will not work if SomeOtherComplexObject has no such property
}
}
While it works, it now has tons of it.
in the code and I was wondering, whether it is possible to have some similar behaviour as with the @DslMarker
in place.
What I tried is a mixture of the following:
@DslMarker
annotation class DemoMarker
@DemoMarker
inline fun <T> T.build(@DemoMarker builder : T.() -> Unit) = this.apply(builder)
"mixture", because I ended up putting the annotation everywhere, but this doesn't have any effect. If I put it on a class it works as expected. Did I miss something and it is actually possible somehow? Or does anyone have an appropriate workaround for this, besides using also
?
Upvotes: 1
Views: 589
Reputation: 842
For third party classes you can use the DslMarker annotation on receiver types as explained here.
@DslMarker
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
annotation class TestDsl
fun build1(builder: (@TestDsl DslReceiver1).() -> Unit) {}
Upvotes: 5