stag-java icon indicating copy to clipboard operation
stag-java copied to clipboard

Unable to find getter for List<Map<String, String>>

Open MRezaNasirloo opened this issue 6 years ago • 1 comments

Issue Summary

Stag fails to find the getter for a list of maps,

Reproduction Steps

@UseStag
@Generated("com.robohorse.robopojogenerator")
data class RequestBodyTransaction(
        @field:SerializedName("restrictions")
        var listOfMaps: List<Map<String, String>> = emptyList()
)

Expected Behavior

To work and parse a list of maps

Actual Behavior

A Compile error as below

RequestBodyTransaction.java:16: error: Unable to find getter for variable: restrictions
    private java.util.List<? extends java.util.Map<java.lang.String, java.lang.String>> restrictions;
                                                                                        ^

MRezaNasirloo avatar Aug 29 '18 19:08 MRezaNasirloo

This is caused by Kotlin's use of type variance and Stag's only partial support for kotlin. The generated bytecodecode resolves to:

private List<? extends Map<String, String> restrictions;

public List<Map<String, String> getRestrictions() { ... }

public void setRestrictions(List<? extends Map<String, String> restrictions) { ... }

Exact equality between types is expected using Types.isSameAs within Stag. This does not return true for the two types List<? extends T> and List<T>`, and therefore causes a build error. The long-term solution would be to build support for type variance into the processor, but short-term this isn't feasible as it will be quite difficult.

The workaround for this is to utilize the @JvmSuppressWildcards annotation. You can apply it to the type parameter of any generic collection that you are getting the error for. For instance, the above failing example you provided will compile when changed to this:

@UseStag
@Generated("com.robohorse.robopojogenerator")
data class RequestBodyTransaction(
        @field:SerializedName("restrictions")
        var listOfMaps: List<@JvmSuppressWildcards Map<String, String>> = emptyList()
)

anthonycr avatar Sep 11 '18 15:09 anthonycr