Generate data class with KotlinPoet
Asked Answered
B

1

9

I want to generate simple data class with KotlinPoet:

data class User(val id: Int)

I do it like that:

val builder = KotlinFile.builder("", "Foo")
val classBuilder = TypeSpec.classBuilder("User").addModifiers(KModifier.DATA)
val ctor = FunSpec.constructorBuilder()
ctor.addParameter("id", Int::class)
classBuilder.primaryConstructor(ctor.build())
builder.addType(classBuilder.build())
builder.build().writeTo(System.out)

But what I get is this:

data class User(id: Int) {
}

How can I add val modifier to constructor parameter?

Boehmenism answered 11/6, 2017 at 12:25 Comment(0)
U
11

Here is an issue discussing this problem.

The conclusion is that the way to write this code is to create a property that matches the constructor parameter's name, and is initialized by it:

KotlinFile.builder("", "Foo")
        .addType(TypeSpec.classBuilder("User")
                .addModifiers(KModifier.DATA)
                .primaryConstructor(FunSpec.constructorBuilder()
                        .addParameter("id", Int::class)
                        .build())
                .addProperty(PropertySpec.builder("id", Int::class)
                        .initializer("id")
                        .build())
                .build()
        )
        .build()
        .writeTo(System.out)

However, this feature is not available as of the 0.2.0 release of KotlinPoet. It is already implemented, and there is a test for this in the repository that is passing, but you'll have to wait for the 0.3.0 release of KotlinPoet to be able to use this feature, which is supposed to come in the next few days.

This feature is available from 0.3.0, which is out now.


The previous code with an alternative formatting that matches your original style:

val builder = KotlinFile.builder("", "Foo")
val classBuilder = TypeSpec.classBuilder("User").addModifiers(KModifier.DATA)

val ctor = FunSpec.constructorBuilder()
ctor.addParameter("id", Int::class)
classBuilder.primaryConstructor(ctor.build())

val idProperty = PropertySpec.builder("id", Int::class).initializer("id").build()
classBuilder.addProperty(idProperty)

builder.addType(classBuilder.build())
builder.build().writeTo(System.out)
Utopianism answered 11/6, 2017 at 12:56 Comment(2)
Are there any plans to add idiomatic data class field declaration support?Boehmenism
Not sure, you'd have to ask them. In the meantime, 0.3.0 is out as of 23 hours ago, you can go ahead and update to it. I'll edit my answer too.Utopianism

© 2022 - 2024 — McMap. All rights reserved.