Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlin data class compile-time error #53

Open
ghost opened this issue Feb 17, 2017 · 11 comments
Open

Kotlin data class compile-time error #53

ghost opened this issue Feb 17, 2017 · 11 comments
Labels
Milestone

Comments

@ghost
Copy link

ghost commented Feb 17, 2017

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 ghost changed the title Kotlin data class problem Kotlin data class compile-time error Feb 17, 2017
@sockeqwe
Copy link
Contributor

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

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

@ghost
Copy link
Author

ghost commented Feb 17, 2017

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'
    }
}

@sockeqwe
Copy link
Contributor

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

@ghost
Copy link
Author

ghost commented Feb 17, 2017

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
Copy link
Author

ghost commented Feb 17, 2017

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
Copy link
Author

ghost commented Feb 17, 2017

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

@sockeqwe sockeqwe reopened this Feb 17, 2017
@sockeqwe
Copy link
Contributor

sockeqwe commented Feb 17, 2017

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

@ghost
Copy link
Author

ghost commented Feb 17, 2017

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)

@sockeqwe
Copy link
Contributor

sockeqwe commented Feb 17, 2017 via email

@ghost
Copy link
Author

ghost commented Feb 17, 2017

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!

@sockeqwe sockeqwe added the bug label Feb 19, 2017
@sockeqwe sockeqwe added this to the 1.0 milestone Feb 19, 2017
@iNoles
Copy link
Contributor

iNoles commented Aug 20, 2017

List<@JvmSuppressWildcards Part>

might be useful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants