bluelinelabs / LoganSquare

Screaming fast JSON parsing and serialization library for Android.
Apache License 2.0
3.21k stars 306 forks source link

LoganSquare doesn't detect getters and setters on a list in Kotlin #193

Open AndreasBackx opened 7 years ago

AndreasBackx commented 7 years ago

I've got the following Java file that works fine in LoganSquare:

@JsonObject
public class Hours {
    @JsonField(name = "holidayperiods")
    public List<HolidayPeriod> holidayPeriods;

    @JsonField(name = "openingperiods")
    public List<OpeningPeriod> openingPeriods;
}

When it gets converted to Kotlin it spits the following error: error: @JsonField annotation can only be used on private fields if both getter and setter are present.. I would love to give an exact line for where it's happening, but there's a bug in Kotlin 1.0.6 where kapt doesn't show this. The bug has been fixed for future versions, but god knows when 1.0.7 is gonna be here. This is the Kotlin file used: (I kept nullability so it's as close as possible to the Java version)

@JsonObject
open class Hours {
    @JsonField(name = arrayOf("holidayperiods"))
    open var holidayPeriods: List<HolidayPeriod>? = null

    @JsonField(name = arrayOf("openingperiods"))
    open var openingPeriods: List<OpeningPeriod>? = null
}

And it's decompiled to the following Java:

@JsonObject
public class Hours {
   @JsonField(
      name = {"holidayperiods"}
   )
   @Nullable
   private List holidayPeriods;
   @JsonField(
      name = {"openingperiods"}
   )
   @Nullable
   private List openingPeriods;

   @Nullable
   public List getHolidayPeriods() {
      return this.holidayPeriods;
   }

   public void setHolidayPeriods(@Nullable List var1) {
      this.holidayPeriods = var1;
   }

   @Nullable
   public List getOpeningPeriods() {
      return this.openingPeriods;
   }

   public void setOpeningPeriods(@Nullable List var1) {
      this.openingPeriods = var1;
   }
}

HolidayPeriod and OpeningPeriod compile just fine. This class is the only one that was changed. Any reason to why this is happening?

Miha-x64 commented 7 years ago

The only difference between Java List and Kotlin List types is a presence of wildcard: List<X> in Kotlin compiles to wildcard type List<? extends X> because type parameter in Kotlin's List has out variance. Correct workaround is List<@JvmSuppressWildcards X>, but you can also use MutableList<X> or ArrayList<X>. Same true for Sets/Collections/Iterables, Maps, Pairs and so on.