At the moment of writing, KotlinPoet doesn't have a ConstructorSpec.
Because KotlinPoetDSL want's to allow building the code in an intuitive way, this means that the primary constructor should be able to define fields.
Therefor, KotlinPoetDSL needs to have a ConstructorSpec
Implementation
ConstructorSpec is a combination of a list of PropertySpecs, a FunctionSpec and a boolean indicates if it is a primary or a secondary constructor.
Asking for the properties will either return its list with PropertySpecs or an empty list, based on if it's a primary or secondary constructor.
the val/var - keywords will be hidden (e.g. the properties will be hidden) if the
Construction
You can build the constructor in a view ways:
implicit from the clazz-call
using buildConstructor
for interoperability, using a funSpec.
Implicit from the clazz-call
When creating a class, you can create a primary constructor implicitly from the clazz-function:
file("", "Hello"){
//--------------------- doesn't create a primary construcor
clazz("First") // class First
//-------------------- interoperability
val param = ParameterSpec.builder("par", String::class).build()
clazz("Second", param)// class Second(par: String)
val immutable = PropertySpec.builder("immutable", String::class).build()
clazz("Third", immutable) //class Third(val prop: String)
val mutableProp = PropertySpec.varBuilder("mutable", String::class).build()
clazz("Fourth", mutableProp) //class Fourth(var prop: String)
//------------------- KotlinPoetDSLs way
clazz("Fifth", "prop" of String::class) // Fifth(prop : String)
clazz("Sixth", "prop" varOf String::class) // Sixth(var prop : String)
clazz("Sixth", "prop" valOf String::class) // Sixth(val prop : String)
}
Stand-alone using buildConstructor
You can create a standalone ConstructorSpec using createConstructor.
Inside the function, you can use the real DSL to create a constructor.
Inside the lambda, you need to return a ConstructorSpec, so the curly brackets.
Technically it's not needed, but overhere I wanted to be strict.
before V0.2, the toPrimary() is not checked for thizz and zuper, meaning it will fail, once it is added to the class.
Adding Stand-alone constructors to the class
you can add those to the class on the following way:
val constr1 = buildConstructor {
primary.constructor()
}
file("", "HelloWorld") {
clazz("One") {
// will always pass the constructor like it is created
// this means private is ignored
private.accept(constr1)
}
clazz("Two") {
// will be dropped in V0.2, due to "strange" working
public.constructor(constr1) // will merge modifiers
}
clazz("Three"){
accept(constr1.buildUpon {
addModifier(KModifier.PUBLIC)
})
}
}
in V0.2, the code of public constructor will be replaced with:
constr1.attach{
addModifiers(KModifier.PUBLIC)
}
Then you can create the function constructor yourself, or give it a different implementation that makes sense to you.
Interoperability
ConstructorSpec is interoperable with KotlinPoet
Creating ConstructorSpec
allowed at the moment
val func = FunSpec.constructorBuilder().addParameter(
ParameterSpec.builder("hi", String::class).build()
).build()
val secondaryConstructor = func.toConstructor()
val primaryConstructor = func.toPrimaryConstructor(
("hi" valOf String::class).toPropertySpec()
)
allowed in V0.2
val option1 = func.toPrimaryConstructor(
"one" of String::class, "two" valOf String::class
)
val option2 = func.toPrimaryConstructor(
"hi" to Variable.Mutability.MUTABLE, //where you import MUTABLE, of course ;-)
"two" to Mutability.NONE
)