vert-x3 / vertx-lang-kotlin

Vert.x for Kotlin
Apache License 2.0
293 stars 67 forks source link

Generate DataObject from Kotlin Class #17

Open milo2005 opened 7 years ago

milo2005 commented 7 years ago

I want to generate a data object from a kotlin class (Author), but it generates an error that I could not solve

Could not generate element for org.vult.services.Author: null

I think it may be because when generating the kotlin stub add annotations to the attributes and thus error in the generation of the converter.

EJ. @org.jetbrains.annotations.NotNull()

it is possible to generate from a kotlin class or is there an example?

This is my Gradle.Script

buildscript{
    ext.kotlin_version = '1.1.3-2'
    ext.shadow_version = '2.0.1'

    repositories{
        jcenter()
    }
    dependencies{
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath "com.github.jengelman.gradle.plugins:shadow:$shadow_version"
    }
}

apply plugin: 'kotlin'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.github.johnrengelman.shadow'

ext.vertx_version = '3.4.2'

repositories {
    jcenter()
}

dependencies {
    implementation "io.vertx:vertx-core:$vertx_version"
    implementation "io.vertx:vertx-web-client:$vertx_version"
    implementation "io.vertx:vertx-rx-java:$vertx_version"
    implementation "io.vertx:vertx-service-proxy:$vertx_version"
    implementation "io.vertx:vertx-codegen:$vertx_version"
    implementation "io.vertx:vertx-lang-kotlin:$vertx_version"
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    compile "org.jetbrains:annotations:13.0"
    kapt "io.vertx:vertx-service-proxy:$vertx_version:processor"

    testImplementation 'junit:junit:4.12'
}

compileKotlin{
    kotlinOptions.jvmTarget = "1.8"
}

kapt{

}

sourceSets {
    main.java.srcDirs += [file("$buildDir/generated/source/kapt/main")]
}

Author.kt

@DataObject(generateConverter = true)
class Author(){

    lateinit var name:String
    lateinit var email:String

    constructor(json:JsonObject?):this(){}

    fun toJson():JsonObject{
        val json =  JsonObject()
        return json
    }
}

thanks

altarit commented 7 years ago

DataObject.doc says setters shall return "this". Kotlin generates properties that return Unit (void). @Fluent properties required only for the vertx code generation.

I guess you are looking for a @DataObject class to pass it through EventBus instead of JsonObject.

I found two ways to solve this:

  1. Manually create set props (not a good thing in kotlin)

    @DataObject(generateConverter = true)
    class Author() {
    private var _name: String = ""
    private var _email: String = ""
    
    fun getName(): String {
    return _name
    }
    fun setName(value: String): Author {
    _name = value
    return this
    }
    fun getEmail(): String {
    return _email
    }
    fun setEmail(value: String): Author {
    _email = value
    return this
    }
    
    constructor(json: JsonObject) : this() {
    AuthorConverter.fromJson(json, this)
    }
    
    fun toJson(): JsonObject {
    return JsonObject.mapFrom(this)
    }
    }

    This way you can use generated <ClassName>Converter . Code generation works if there is package-info.java with the package marked @ModuleGen .

I hope Jetbrains adds @Fluent properties in kotlin somewhen.

  1. Don't use code generation Remove the package from package-info.java and generateConverter param

    @DataObject
    class Author() {
    lateinit var name: String
    lateinit var email: String
    
    constructor(json: JsonObject) : this() {
    this.name = json.getString("name", "")
    this.email = json.getString("email", "")
    }
    
    fun toJson(): JsonObject {
    return JsonObject.mapFrom(this)
    }
    }

    This way you need to set fields manually. Author can be passed through EventBus now.