tikxml icon indicating copy to clipboard operation
tikxml copied to clipboard

Kotlin data class compile-time error

Open ghost opened this issue 8 years ago • 11 comments

I see such compile-time error: Error:Gradle: The constructor parameter 'arg0' in constructor Narration(java.lang.String) in class red.kometa.quest.common.entities.Paragraph.Part.Narration is annotated with a TikXml annotation. Therefore a getter method with minimum package visibility with the name getArg0() or isArg0() in case of a boolean must be provided. Unfortunately, there is no such getter method. Please provide one!

there is my data classes:

@Xml(name = "paragraph")
data class Paragraph(
        @Attribute(name = "key") val key: String,
        @Element(
                typesByElement = arrayOf(
                        ElementNameMatcher(type = Part.Replica::class),
                        ElementNameMatcher(type = Part.Narration::class),
                        ElementNameMatcher(type = Part.Actions::class),
                        ElementNameMatcher(type = Part.GameOver::class),
                        ElementNameMatcher(type = Part.GameWin::class)
                )
        ) val parts: List<Part>
) {

    interface Part {
        @Xml(name = "replica")
        data class Replica(
                @Attribute(name = "text_key") val textKey: String,
                @Attribute(name = "character_key") val characterKey: String
        ) : Part

        @Xml(name = "narration")
        data class Narration(
                @Attribute(name = "text_key") val textKey: String
        ) : Part

        @Xml(name = "actions")
        data class Actions(
                @Element(
                        typesByElement = arrayOf(
                                ElementNameMatcher(type = Action.Way::class)
                        )
                )
                val actions: List<Action>
        ) : Part

        interface Action {

            val force: Boolean
            val textKey: String?

            @Xml(name = "way")
            data class Way(
                    @Attribute(name = "force") override val force: Boolean,
                    @Attribute(name = "text_key") override val textKey: String?,
                    @Attribute(name = "to") val to: String,
                    @Element(name = "behaviour", typesByElement = arrayOf(
                            ElementNameMatcher(type = NormalBehaviour::class),
                            ElementNameMatcher(type = WaitBehaviour::class)
                    )) val behaviour: Behaviour
            ) : Action {

                /**
                 * Do not use annotations as using
                 * @see red.kometa.quest.common.utils.BehaviourTypeAdapter
                 */

                interface Behaviour

                class NormalBehaviour : Behaviour

                data class WaitBehaviour(
                        val duration: Long
                ) : Behaviour

            }
        }

        @Xml(name = "gameover")
        data class GameOver(
                @Attribute(name = "text_key") val textKey: String,
                @Attribute(name = "restart") val restart: Boolean,
                @Attribute(name = "checkpoint_paragraph_key") val checkpointParagraphKey: String?
        ) : Part

        @Xml(name = "gamewin")
        data class GameWin(
                @get:Attribute(name = "text_key") @param:Attribute(name = "text_key") val textKey: String
        ) : Part

    }

}

Kotlin must generate such getters&setters.

kotlin_version = '1.0.6' tikxml_verions = '0.8.9-SNAPSHOT'

ghost avatar Feb 17 '17 13:02 ghost

This is a kotlin kapt issue. You have to use kapt2 by explicitly use

apply plugin: 'kotlin-kapt'    // this uses kapt2

sockeqwe avatar Feb 17 '17 13:02 sockeqwe

Thanks, it's done.

Now there is another error: Error:The constructor parameter 'storyPath' in constructor StoryState(java.util.List<? extends red.kometa.quest.player.model.managers.story.state.StoryPathElement>) in class red.kometa.quest.player.model.managers.story.state.StoryState is annotated with a TikXml annotation. Therefore a getter method with minimum package visibility with the name getStoryPath() or isStoryPath() in case of a boolean must be provided. Unfortunately, there is no such getter method. Please provide one!

data class:

@Xml(name = "story-state")
data class StoryState(
        @Element(
                typesByElement = arrayOf(
                        ElementNameMatcher(type = StoryPathElement.Telling::class),
                        ElementNameMatcher(type = StoryPathElement.Actions::class),
                        ElementNameMatcher(type = StoryPathElement.GameOver::class),
                        ElementNameMatcher(type = StoryPathElement.GameWin::class)
                )
        ) val storyPath: List<StoryPathElement> = emptyList()
)

gradle module setups:

project(":krq-common") {
    apply plugin: "java"
    apply plugin: "kotlin"
    apply plugin: 'kotlin-kapt'

    dependencies {
        compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

        compile "org.slf4j:slf4j-api:1.7.21"

        compile 'org.threeten:threetenbp:1.3.2'

        compile 'com.tickaroo.tikxml:annotation:0.8.9-SNAPSHOT'
        compile 'com.tickaroo.tikxml:core:0.8.9-SNAPSHOT'

        kapt 'com.tickaroo.tikxml:processor:0.8.9-SNAPSHOT'
    }
}

ghost avatar Feb 17 '17 14:02 ghost

Hm, is it because of the default value emptyList()? Please try it without the default value.

sockeqwe avatar Feb 17 '17 14:02 sockeqwe

Nope, the same error:

error: The constructor parameter 'storyPath' in constructor StoryState(java.util.List<? extends red.kometa.quest.player.model.managers.story.state.StoryPathElement>) in class red.kometa.quest.player.model.managers.story.state.StoryState  is annotated with a TikXml annotation. Therefore a getter method with minimum package visibility with the name getStoryPath() or isStoryPath() in case of a boolean must be provided. Unfortunately, there is no such getter method. Please provide one!
e: java.lang.IllegalArgumentException: Don't know how to render diagnostic of type KAPT3_PROCESSING_ERROR with the following renderer maps: [DiagnosticFactory#JVM, DiagnosticFactory#JS, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#AnnotationProcessing, DiagnosticFactory#Default]
	at org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages.render(DefaultErrorMessages.java:83)
	at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport$Companion.reportDiagnostic(AnalyzerWithCompilerReport.kt:134)

it also occur for val parts: List<Part> in code attached to the first message of issue.

Maybe it happens because of Kotlin's generic system? image image

For example, TikXml expect getXXX(): List<XXX> but kotlin generate: getXXX(): List<? extends XXX>

ghost avatar Feb 17 '17 14:02 ghost

Looks like there is another problem related to kapt3 in Kotlin 1.0.6 as on 1.0.5 TikXml works okay on simple data classes.

[kapt] An exception occurred:
java.lang.NoClassDefFoundError: com/sun/tools/javac/code/TypeTag
	at org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker.convertBuiltinType(KaptTreeMaker.kt:56)
	at org.jetbrains.kotlin.kapt3.javac.KaptTreeMaker.Type(KaptTreeMaker.kt:31)
	at org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.convertField(ClassFileToSourceStubConverter.kt:219)
	at org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.convertClass(ClassFileToSourceStubConverter.kt:183)
	at org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.convertTopLevelClass(ClassFileToSourceStubConverter.kt:118)
	at org.jetbrains.kotlin.kapt3.stubs.ClassFileToSourceStubConverter.convert(ClassFileToSourceStubConverter.kt:83)
	at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.generateKotlinSourceStubs(Kapt3Extension.kt:209)
	at org.jetbrains.kotlin.kapt3.AbstractKapt3Extension.analysisCompleted(Kapt3Extension.kt:146)
	at org.jetbrains.kotlin.kapt3.ClasspathBasedKapt3Extension.analysisCompleted(Kapt3Extension.kt:67)

ghost avatar Feb 17 '17 17:02 ghost

Example project that represent my problem: https://github.com/Try4W/tikxml-example/ (Kotlin 1.0.4)

ghost avatar Feb 17 '17 17:02 ghost

Please try it with kotlin 1.1.0-RC. Maybe this is an kapt3 error and is already fixed in kapt 3 in 1.1.0. Otherwise please file an issue in kotlin issue tracker: https://youtrack.jetbrains.com/issues/KT

https://blog.jetbrains.com/kotlin/2017/02/kotlin-1-1-release-candidate-is-here/#more-4589

sockeqwe avatar Feb 17 '17 18:02 sockeqwe

1.1.0-RC prints warning like:

w: Running the Kotlin compiler under Java 6 or 7 is unsupported and will no longer be possible in a future update.

com/sun/tools/javac/code/TypeTag fixed via using Java 8 to run gradle

Now error rendered and looks like that:

e: C:\Users\Alexandr\AndroidStudioProjects\tikxml-example\build\tmp\kapt3\stubs\main\Paragraph.java:23: error: The constructor parameter 'parts' in constructor Paragraph(java.lang.String,java.util.List<? extends Paragraph.Part>) in class Paragraph  is annotated with a TikXml annotation. Therefore a getter method with minimum package visibility with the name getParts() or isParts() in case of a boolean must be provided. Unfortunately, there is no such getter method. Please provide one!
e: 

e:     java.util.List<? extends Paragraph.Part> parts) {
e:                                              ^
e: C:\Users\Alexandr\AndroidStudioProjects\tikxml-example\src\main\kotlin\Paragraph.kt: (1, 1): Some error(s) occurred while processing annotations. Please see the error messages above.

It seems to be TikXml's problem. Should I report it to kotlin issue tracker?

(repo with demo updated)

ghost avatar Feb 17 '17 19:02 ghost

that seems to be the same error as originally reported. Maybe it is because of List<? extends Paragraph.Part> as you have already suggested. I will take a look next week.

The strange thing is, that we are using kotlin (with all various versions) and use polymorphic lists quite often at work without seeing such an issue.

I just did a quick check in our code base and we mainly use var which are defined in the class body and not in constructor parameters. Maybe it is worth trying that too in your example, but as far as I remember it should not make a difference because it is using internally the same code.

Alexandr [email protected] schrieb am Fr., 17. Feb. 2017, 20:28:

1.1.0-RC prints warning like:

w: Running the Kotlin compiler under Java 6 or 7 is unsupported and will no longer be possible in a future update.

com/sun/tools/javac/code/TypeTag fixed via using Java 8 to run gradle

Now error rendered and looks like that:

e: C:\Users\Alexandr\AndroidStudioProjects\tikxml-example\build\tmp\kapt3\stubs\main\Paragraph.java:23: error: The constructor parameter 'parts' in constructor Paragraph(java.lang.String,java.util.List<? extends Paragraph.Part>) in class Paragraph is annotated with a TikXml annotation. Therefore a getter method with minimum package visibility with the name getParts() or isParts() in case of a boolean must be provided. Unfortunately, there is no such getter method. Please provide one! e:

e: java.util.List<? extends Paragraph.Part> parts) { e: ^ e: C:\Users\Alexandr\AndroidStudioProjects\tikxml-example\src\main\kotlin\Paragraph.kt: (1, 1): Some error(s) occurred while processing annotations. Please see the error messages above.

It seems to be TikXml's problem. Should I report it to kotlin issue tracker?

(repo with demo updated)

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/Tickaroo/tikxml/issues/53#issuecomment-280743855, or mute the thread https://github.com/notifications/unsubscribe-auth/AAjnrvaS8Z4NiFx26qSQACiGIZEl_Is9ks5rdfTggaJpZM4MEPoK .

sockeqwe avatar Feb 17 '17 19:02 sockeqwe

Some examples.

Working:

@Xml(name = "paragraph")
data class Paragraph(
        @get:Attribute(name = "key") var key: String = "",
        @get:Element(
                name = "parts",
                typesByElement = arrayOf(
                        ElementNameMatcher(type = Part.Replica::class),
                        ElementNameMatcher(type = Part.Narration::class),
                        ElementNameMatcher(type = Part.Actions::class),
                        ElementNameMatcher(type = Part.GameOver::class),
                        ElementNameMatcher(type = Part.GameWin::class)
                )
        ) var parts: List<Part> = emptyList()
)

Working:

@Xml(name = "paragraph")
class Paragraph {

    @Attribute(name = "key") lateinit var key: String
    @Element(
            name = "parts",
            typesByElement = arrayOf(
                    ElementNameMatcher(type = Part.Replica::class),
                    ElementNameMatcher(type = Part.Narration::class),
                    ElementNameMatcher(type = Part.Actions::class),
                    ElementNameMatcher(type = Part.GameOver::class),
                    ElementNameMatcher(type = Part.GameWin::class)
            )
    ) lateinit var parts: List<Part>

Working:

@Xml(name = "paragraph")
class Paragraph {

    @get:Attribute(name = "key") var key: String
    @get:Element(
            name = "parts",
            typesByElement = arrayOf(
                    ElementNameMatcher(type = Part.Replica::class),
                    ElementNameMatcher(type = Part.Narration::class),
                    ElementNameMatcher(type = Part.Actions::class),
                    ElementNameMatcher(type = Part.GameOver::class),
                    ElementNameMatcher(type = Part.GameWin::class)
            )
    ) var parts: List<Part>
    
    constructor(): this("none", emptyList())

    constructor(key: String, parts: List<Part>) {
        this.key = key
        this.parts = parts
    }

Not working:

@Xml(name = "paragraph")
class Paragraph {

    @Attribute(name = "key") var key: String
    @Element(
            name = "parts",
            typesByElement = arrayOf(
                    ElementNameMatcher(type = Part.Replica::class),
                    ElementNameMatcher(type = Part.Narration::class),
                    ElementNameMatcher(type = Part.Actions::class),
                    ElementNameMatcher(type = Part.GameOver::class),
                    ElementNameMatcher(type = Part.GameWin::class)
            )
    ) var parts: List<Part>

    constructor(): this("none", emptyList<Part>())

    constructor(key: String, parts: List<Part>) {
        this.key = key
        this.parts = parts
    }

The field 'parts' in class Paragraph has private or protected visibility. Hence a corresponding getter method must be provided with minimum package visibility (or public visibility if this is a super class in a different package) with the name getParts() or isParts() in case of a boolean. Unfortunately, there is no such getter method. Please provide one!

Not working:

@Xml(name = "paragraph")
class Paragraph {

    var key: String
    var parts: List<Part>

    constructor(@Attribute(name = "key") key: String, @Element(
            name = "parts",
            typesByElement = arrayOf(
                    ElementNameMatcher(type = Part.Replica::class),
                    ElementNameMatcher(type = Part.Narration::class),
                    ElementNameMatcher(type = Part.Actions::class),
                    ElementNameMatcher(type = Part.GameOver::class),
                    ElementNameMatcher(type = Part.GameWin::class)
            )
    ) parts: List<Part>) {
        this.key = key
        this.parts = parts
    }

The constructor parameter 'parts' in constructor Paragraph(java.lang.String,java.util.List<? extends Paragraph.Part>) in class Paragraph is annotated with a TikXml annotation. Therefore a getter method with minimum package visibility with the name getParts() or isParts() in case of a boolean must be provided. Unfortunately, there is no such getter method. Please provide one!

ghost avatar Feb 17 '17 21:02 ghost

List<@JvmSuppressWildcards Part>

might be useful.

iNoles avatar Aug 20 '17 04:08 iNoles