Status Update
Comments
to...@gmail.com <to...@gmail.com> #2
For completion and analysis
-keep @com.squareup.moshi.JsonClass public class * {
public <init>(...);
}
Properly workaround the issue.
What's interesting is the resulting bytecode is now:
.class public final Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;
.super Ljava/lang/Object;
.source "Application.kt"
# annotations
.annotation runtime Lm5/l/a/r;
generateAdapter = true
.end annotation
.annotation runtime Lo5/e;
bv = {
0x1,
0x0,
0x3
}
d1 = {
"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0008\n\u0002\u0008\u0003\n\u0002\u0010\u000e\n\u0002\u0008\u0006\u0008\u0007\u0018\u0000B/\u0012\u0008\u0008\u0002\u0010\u0002\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0004\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0006\u001a\u00020\u0005\u0012\u0008\u0008\u0002\u0010\u0008\u001a\u00020\u0005\u00a2\u0006\u0004\u0008\t\u0010\nR\u0016\u0010\u0002\u001a\u00020\u00018\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0002\u0010\u0003R\u0016\u0010\u0004\u001a\u00020\u00018\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0004\u0010\u0003R\u0016\u0010\u0006\u001a\u00020\u00058\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0006\u0010\u0007R\u0016\u0010\u0008\u001a\u00020\u00058\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0008\u0010\u0007\u00a8\u0006\u000b"
}
d2 = {
"Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;",
"",
"major",
"I",
"minor",
"",
"revision",
"Ljava/lang/String;",
"tag",
"<init>",
"(IILjava/lang/String;Ljava/lang/String;)V",
"kodi_release"
}
k = 0x1
mv = {
0x1,
0x1,
0xf
}
pn = ""
xi = 0x0
xs = ""
.end annotation
# instance fields
.field public final a:I
.field public final b:I
.field public final c:Ljava/lang/String;
.field public final d:Ljava/lang/String;
# direct methods
.method public constructor <init>()V
.registers 8
const/4 v1, 0x0
const/4 v2, 0x0
const/4 v3, 0x0
const/4 v4, 0x0
const/16 v5, 0xf
const/4 v6, 0x0
move-object v0, p0
invoke-direct/range {v0 .. v6}, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;-><init>(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
return-void
.end method
.method public constructor <init>(IILjava/lang/String;Ljava/lang/String;)V
.registers 5
.line 1
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
iput p1, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->a:I
iput p2, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->b:I
iput-object p3, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->c:Ljava/lang/String;
iput-object p4, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->d:Ljava/lang/String;
return-void
.end method
.method public synthetic constructor <init>(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
.registers 8
and-int/lit8 p6, p5, 0x1
const/4 v0, 0x0
if-eqz p6, :cond_6
const/4 p1, 0x0
:cond_6
and-int/lit8 p6, p5, 0x2
if-eqz p6, :cond_b
const/4 p2, 0x0
:cond_b
and-int/lit8 p6, p5, 0x4
const-string v0, ""
if-eqz p6, :cond_12
move-object p3, v0
:cond_12
and-int/lit8 p5, p5, 0x8
if-eqz p5, :cond_17
move-object p4, v0
.line 2
:cond_17
invoke-direct {p0, p1, p2, p3, p4}, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;-><init>(IILjava/lang/String;Ljava/lang/String;)V
return-void
.end method
So the kept synthetic constructor correctly references the public constructor (it's a throw in previous byte code), so this sounds more like an R8 issue in identifying that constructor call and keeping it than a missing rule.
ch...@google.com <ch...@google.com> #3
Thanks for reporting this.
It seems that R8 may have removed the synthetic bit from void Application$Property$Version.<init>(int, int, java.lang.String, java.lang.String, int, kotlin.jvm.internal.DefaultConstructorMarker)
.
Could you please check if it works if you remove the synthetic
condition from the following rule:
-keepclassmembers class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version {
public synthetic <init>(int,int,java.lang.String,java.lang.String,int,kotlin.jvm.internal.DefaultConstructorMarker);
}
If not, would it be possible for you to share an Android Studio reproduction project?
ch...@google.com <ch...@google.com> #4
I have managed to reproduce two problems related to this. I will add a regression test and start working on a fix.
to...@gmail.com <to...@gmail.com> #5
Ok for completion adding the rule without synthetic (did not remove the other as auto generated) generate what seems the correct byte code.
.class public final Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;
.super Ljava/lang/Object;
.source "Application.kt"
# annotations
.annotation runtime Lf5/l/a/r;
generateAdapter = true
.end annotation
.annotation runtime Lh5/e;
bv = {
0x1,
0x0,
0x3
}
d1 = {
"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0008\n\u0002\u0008\u0003\n\u0002\u0010\u000e\n\u0002\u0008\u0006\u0008\u0007\u0018\u0000B/\u0012\u0008\u0008\u0002\u0010\u0002\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0004\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0006\u001a\u00020\u0005\u0012\u0008\u0008\u0002\u0010\u0008\u001a\u00020\u0005\u00a2\u0006\u0004\u0008\t\u0010\nR\u0016\u0010\u0002\u001a\u00020\u00018\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0002\u0010\u0003R\u0016\u0010\u0004\u001a\u00020\u00018\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0004\u0010\u0003R\u0016\u0010\u0006\u001a\u00020\u00058\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0006\u0010\u0007R\u0016\u0010\u0008\u001a\u00020\u00058\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0008\u0010\u0007\u00a8\u0006\u000b"
}
d2 = {
"Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;",
"",
"major",
"I",
"minor",
"",
"revision",
"Ljava/lang/String;",
"tag",
"<init>",
"(IILjava/lang/String;Ljava/lang/String;)V",
"kodi_release"
}
k = 0x1
mv = {
0x1,
0x1,
0xf
}
pn = ""
xi = 0x0
xs = ""
.end annotation
# instance fields
.field public final a:I
.field public final b:I
.field public final c:Ljava/lang/String;
.field public final d:Ljava/lang/String;
# direct methods
.method public constructor <init>(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
.registers 8
and-int/lit8 p6, p5, 0x1
const/4 v0, 0x0
if-eqz p6, :cond_6
const/4 p1, 0x0
:cond_6
and-int/lit8 p6, p5, 0x2
if-eqz p6, :cond_b
const/4 p2, 0x0
:cond_b
and-int/lit8 p6, p5, 0x4
const-string v0, ""
if-eqz p6, :cond_12
move-object p3, v0
:cond_12
and-int/lit8 p5, p5, 0x8
if-eqz p5, :cond_17
move-object p4, v0
.line 1
:cond_17
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
iput p1, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->a:I
iput p2, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->b:I
iput-object p3, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->c:Ljava/lang/String;
iput-object p4, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->d:Ljava/lang/String;
return-void
.end method
to...@gmail.com <to...@gmail.com> #6
In order to be able to move on I've updated Moshi to generate the rules:
-if class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version
-keepnames class kotlin.jvm.internal.DefaultConstructorMarker
-if class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version
-keepclassmembers class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version {
public synthetic <init>(int,int,java.lang.String,java.lang.String,int,kotlin.jvm.internal.DefaultConstructorMarker);
public <init>(int,int,java.lang.String,java.lang.String,int,kotlin.jvm.internal.DefaultConstructorMarker);
}
And it did not work, the class ended up as abstract too. Don't know if your repro / tests take the if in account too as it seems it matters too.
ap...@google.com <ap...@google.com> #7
Branch: master
commit 695c52b0d65c21ca5a1e09d6fe98cc55bd04aa98
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Tue Apr 14 11:27:39 2020
Keep bridge and synthetic information for conditional rules
Bug: 153858923
Change-Id: I4f32a5d34459c4fff4467ea19997a58af9a455f2
M src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
M src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
M src/test/java/com/android/tools/r8/shaking/ifrule/NoLongerSyntheticConstructorTest.java
ap...@google.com <ap...@google.com> #8
Branch: master
commit 4d58faf6cb6d5f951e423cbae86f96037e75a1d9
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Tue Apr 14 09:35:23 2020
Add a regression test for inadequate tracing of consequent root set
Bug: 153858923, 153926577
Change-Id: I7f71e91081a4e07881616a94453139cd19c4ec7c
A src/test/java/com/android/tools/r8/shaking/ifrule/ConsequentRootSetWithSatisfiedDependentItemsTest.java
A src/test/java/com/android/tools/r8/shaking/ifrule/NoLongerSyntheticConstructorTest.java
M src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
ap...@google.com <ap...@google.com> #9
Branch: master
commit 9e4336d889e6b3950743f18cfa0cdb491f9d8cb5
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Tue Apr 14 14:35:48 2020
Trace dependent items from consequent root set with already satisfied precondition
Bug: 153858923, 153926577, 132828740
Change-Id: I334a36b053e044e1d60d5f257276f401a512455d
M src/main/java/com/android/tools/r8/graph/DexDefinitionSupplier.java
M src/main/java/com/android/tools/r8/shaking/Enqueuer.java
M src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
M src/test/java/com/android/tools/r8/shaking/ifrule/ConsequentRootSetWithSatisfiedDependentItemsTest.java
M src/test/java/com/android/tools/r8/shaking/ifrule/IfOnClassTest.java
ch...@google.com <ch...@google.com> #10
I expect this to be fixed on ToT now. Before merging this to 2.0, could you please check if 9e4336d889e6b3950743f18cfa0cdb491f9d8cb5 works for you (and maybe also that 4d58faf6cb6d5f951e423cbae86f96037e75a1d9 doesn't)?
buildscript {
repositories {
maven {
url "https://storage.googleapis.com/r8-releases/raw/master"
}
}
dependencies {
classpath 'com.android.tools:r8:9e4336d889e6b3950743f18cfa0cdb491f9d8cb5' // Must be before the Gradle Plugin for Android.
classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
}
}
Thanks.
to...@gmail.com <to...@gmail.com> #11
9e4336d889e6b3950743f18cfa0cdb491f9d8cb5 Seems to work, the constructor is not synthetic but no one complains.
But there's something wrong on TOT not in 2.0.X, the final dex file is 500KB bigger!
.class public final Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;
.super Ljava/lang/Object;
.source "Application.kt"
# annotations
.annotation runtime Lx5/l/a/r;
generateAdapter = true
.end annotation
.annotation runtime Lz5/e;
bv = {
0x1,
0x0,
0x3
}
d1 = {
"\u0000\u001c\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0008\u0003\n\u0002\u0018\u0002\n\u0002\u0008\u0008\n\u0002\u0018\u0002\n\u0002\u0008\u0004\u0008\u0007\u0018\u0000B?\u0012\u0008\u0008\u0002\u0010\t\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\n\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u000b\u001a\u00020\u0005\u0012\u0008\u0008\u0002\u0010\u000c\u001a\u00020\u0005\u0012\u0006\u0010\r\u001a\u00020\u0001\u0012\u0006\u0010\u000f\u001a\u00020\u000e\u00a2\u0006\u0004\u0008\u0010\u0010\u0011R\u0016\u0010\u0002\u001a\u00020\u00018\u0000@\u0000X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0002\u0010\u0003R\u0016\u0010\u0004\u001a\u00020\u00018\u0000@\u0000X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0004\u0010\u0003R\u0016\u0010\u0006\u001a\u00020\u00058\u0000@\u0000X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0006\u0010\u0007R\u0016\u0010\u0008\u001a\u00020\u00058\u0000@\u0000X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0008\u0010\u0007\u00a8\u0006\u0012"
}
d2 = {
"Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;",
"Lkotlin/Int;",
"b",
"I",
"a",
"Lkotlin/String;",
"d",
"Ljava/lang/String;",
"c",
"major",
"minor",
"revision",
"tag",
"p4",
"Lkotlin/jvm/internal/DefaultConstructorMarker;",
"p5",
"<init>",
"(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V",
"kodi_release"
}
k = 0x1
mv = {
0x1,
0x1,
0xf
}
pn = ""
xi = 0x0
xs = ""
.end annotation
# instance fields
.field public final a:I
.field public final b:I
.field public final c:Ljava/lang/String;
.field public final d:Ljava/lang/String;
# direct methods
.method public constructor <init>(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
.registers 8
and-int/lit8 p6, p5, 0x1
const/4 v0, 0x0
if-eqz p6, :cond_6
const/4 p1, 0x0
:cond_6
and-int/lit8 p6, p5, 0x2
if-eqz p6, :cond_b
const/4 p2, 0x0
:cond_b
and-int/lit8 p6, p5, 0x4
const-string v0, ""
if-eqz p6, :cond_12
move-object p3, v0
:cond_12
and-int/lit8 p5, p5, 0x8
if-eqz p5, :cond_17
move-object p4, v0
.line 1
:cond_17
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
iput p1, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->a:I
iput p2, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->b:I
iput-object p3, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->c:Ljava/lang/String;
iput-object p4, p0, Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;->d:Ljava/lang/String;
return-void
.end method
4d58faf6cb6d5f951e423cbae86f96037e75a1d9 does not work
.class public abstract Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;
.super Ljava/lang/Object;
.source "Application.kt"
# annotations
.annotation runtime Lq5/l/a/r;
generateAdapter = true
.end annotation
.annotation runtime Ls5/e;
bv = {
0x1,
0x0,
0x3
}
d1 = {
"\u0000\u001c\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0008\u0002\n\u0002\u0018\u0002\n\u0002\u0008\u0003\n\u0002\u0018\u0002\n\u0002\u0008\u0004\u0008\u0007\u0018\u0000B?\u0012\u0008\u0008\u0002\u0010\u0002\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0003\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0005\u001a\u00020\u0004\u0012\u0008\u0008\u0002\u0010\u0006\u001a\u00020\u0004\u0012\u0006\u0010\u0007\u001a\u00020\u0001\u0012\u0006\u0010\t\u001a\u00020\u0008\u00a2\u0006\u0004\u0008\n\u0010\u000b\u00a8\u0006\u000c"
}
d2 = {
"Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;",
"Lkotlin/Int;",
"major",
"minor",
"Lkotlin/String;",
"revision",
"tag",
"p4",
"Lkotlin/jvm/internal/DefaultConstructorMarker;",
"p5",
"<init>",
"(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V",
"kodi_release"
}
k = 0x1
mv = {
0x1,
0x1,
0xf
}
pn = ""
xi = 0x0
xs = ""
.end annotation
# direct methods
.method public constructor <init>(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
.registers 7
and-int/lit8 p1, p5, 0x1
and-int/lit8 p1, p5, 0x2
and-int/lit8 p1, p5, 0x4
and-int/lit8 p1, p5, 0x8
const/4 p1, 0x0
.line 1
throw p1
.end method
ch...@google.com <ch...@google.com> #12
Thanks for the quick turnaround. I have prepared a cherry-pick to 2.0. Could you please try to build with deefd3d14a4cc639ee4a537c45eac6da72a587fc (2.0.66 candidate) and report back if you are seeing the 500KB regression with this? If so, the regression must be due to
It is expected that this will increase the dex size since the interpretation of if rules was incomplete prior to this CL (hence the abstract class issue). That said, there may be classes, fields or methods that are being retained that should not. If you would be able to share a project where a similar regression can be reproduced, or two (unobfuscated) APKs built with 2.0.65 and 2.0.66, then we would be able to look further into this.
to...@gmail.com <to...@gmail.com> #13
deefd3d14a4cc639ee4a537c45eac6da72a587fc works have have similar dex size (I did compare comparable things ;))
For TOT dex size I worked a lot with Jinseong directly by mail before he moved to Kotlin side, the project is private but I can share the APK and mapping to 1 person by mail with confidence that it won't ends up in public issues or shared in full to others.
ap...@google.com <ap...@google.com> #14
Branch: 2.0
commit f31fba8863759c2158502f8df5319294a0efc71b
Author: Christoffer Quist Adamsen <christofferqa@google.com>
Date: Wed Apr 15 11:29:39 2020
Version 2.0.66
Cherry pick: Trace dependent items from consequent root set with already satisfied precondition
CL:
Cherry pick: Keep bridge and synthetic information for conditional rules
CL:
Cherry pick: Add a regression test for inadequate tracing of consequent root set
CL:
Cherry pick: Add a format diff script in tools
CL:
Bug: 153858923, 153926577, 132828740
Change-Id: Ibaa1d5b757c605b8f50881bdbf3998a3c200f3e6
M src/main/java/com/android/tools/r8/Version.java
M src/main/java/com/android/tools/r8/graph/AccessFlags.java
M src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
M src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
M src/main/java/com/android/tools/r8/shaking/Enqueuer.java
M src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
A src/test/java/com/android/tools/r8/shaking/ifrule/ConsequentRootSetWithSatisfiedDependentItemsTest.java
M src/test/java/com/android/tools/r8/shaking/ifrule/IfOnClassTest.java
A src/test/java/com/android/tools/r8/shaking/ifrule/NoLongerSyntheticConstructorTest.java
M src/test/java/com/android/tools/r8/transformers/ClassFileTransformer.java
A tools/fmt-diff.py
to...@gmail.com <to...@gmail.com> #15
2.0.66 works too, issue can be closed :)
For the dex size usually I start tests and report issues when it's branched, but if you want to investigate now, you have my mail, you can contact me there for sharing what would be necessary.
an...@google.com <an...@google.com> #16
ch...@google.com <ch...@google.com> #17
Thanks for the confirmation, marking this as fixed.
I filed
Description
And all known issues seems to be closed.
```
@Suppress("MemberNameEqualsClassName")
class Application {
class Property {
@JsonClass(generateAdapter = true, readOnly = false, writeOnly = false)
class Version(
@JvmField val major: Int = 0,
@JvmField val minor: Int = 0,
@JvmField val revision: String = "",
@JvmField val tag: String = ""
)
}
}
```
Generates the adapter
```
// Code generated by moshi-kotlin-codegen. Do not edit.
package com.genimee.android.yatse.mediacenters.kodi.api.model
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.internal.Util
import java.lang.NullPointerException
import java.lang.reflect.Constructor
import kotlin.Int
import kotlin.String
import kotlin.Suppress
import kotlin.collections.emptySet
import kotlin.jvm.Volatile
import kotlin.text.buildString
@Suppress("DEPRECATION", "unused", "ClassName", "REDUNDANT_PROJECTION", "LocalVariableName")
class Application_Property_VersionJsonAdapter(
moshi: Moshi
) : JsonAdapter<Application.Property.Version>() {
private val options: JsonReader.Options = JsonReader.Options.of("major", "minor", "revision",
"tag")
private val intAdapter: JsonAdapter<Int> = moshi.adapter(Int::class.java, emptySet(), "major")
private val stringAdapter: JsonAdapter<String> = moshi.adapter(String::class.java, emptySet(),
"revision")
@Volatile
private var constructorRef: Constructor<Application.Property.Version>? = null
override fun toString(): String = buildString(50) {
append("GeneratedJsonAdapter(").append("Application.Property.Version").append(')') }
override fun fromJson(reader: JsonReader): Application.Property.Version {
var major: Int? = 0
var minor: Int? = 0
var revision: String? = null
var tag: String? = null
var mask0 = -1
reader.beginObject()
while (reader.hasNext()) {
when (reader.selectName(options)) {
0 -> {
major = intAdapter.fromJson(reader) ?: throw Util.unexpectedNull("major", "major", reader)
// $mask = $mask and (1 shl 0).inv()
mask0 = mask0 and 0xfffffffe.toInt()
}
1 -> {
minor = intAdapter.fromJson(reader) ?: throw Util.unexpectedNull("minor", "minor", reader)
// $mask = $mask and (1 shl 1).inv()
mask0 = mask0 and 0xfffffffd.toInt()
}
2 -> {
revision = stringAdapter.fromJson(reader) ?: throw Util.unexpectedNull("revision",
"revision", reader)
// $mask = $mask and (1 shl 2).inv()
mask0 = mask0 and 0xfffffffb.toInt()
}
3 -> {
tag = stringAdapter.fromJson(reader) ?: throw Util.unexpectedNull("tag", "tag", reader)
// $mask = $mask and (1 shl 3).inv()
mask0 = mask0 and 0xfffffff7.toInt()
}
-1 -> {
// Unknown name, skip it.
reader.skipName()
reader.skipValue()
}
}
}
reader.endObject()
@Suppress("UNCHECKED_CAST")
val localConstructor: Constructor<Application.Property.Version> = this.constructorRef ?:
Application.Property.Version::class.java.getDeclaredConstructor(Int::class.javaPrimitiveType,
Int::class.javaPrimitiveType, String::class.java, String::class.java,
Int::class.javaPrimitiveType, Util.DEFAULT_CONSTRUCTOR_MARKER).also { this.constructorRef =
it }
return localConstructor.newInstance(
major,
minor,
revision,
tag,
mask0,
null
)
}
override fun toJson(writer: JsonWriter, value: Application.Property.Version?) {
if (value == null) {
throw NullPointerException("value was null! Wrap in .nullSafe() to write nullable values.")
}
writer.beginObject()
intAdapter.toJson(writer, value.major)
intAdapter.toJson(writer, value.minor)
stringAdapter.toJson(writer, value.revision)
stringAdapter.toJson(writer, value.tag)
writer.endObject()
}
}
```
And the associated R8 rule:
```
-if class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version
-keepnames class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version
-if class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version
-keep class com.genimee.android.yatse.mediacenters.kodi.api.model.Application_Property_VersionJsonAdapter {
public <init>(com.squareup.moshi.Moshi);
}
-if class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version
-keepnames class kotlin.jvm.internal.DefaultConstructorMarker
-if class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version
-keepclassmembers class com.genimee.android.yatse.mediacenters.kodi.api.model.Application$Property$Version {
public synthetic <init>(int,int,java.lang.String,java.lang.String,int,kotlin.jvm.internal.DefaultConstructorMarker);
}
```
Final bytecode is
```
.class public abstract Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;
.super Ljava/lang/Object;
.source "Application.kt"
# annotations
.annotation runtime Lf5/l/a/r;
generateAdapter = true
.end annotation
.annotation runtime Lh5/e;
bv = {
0x1,
0x0,
0x3
}
d1 = {
"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0008\n\u0002\u0008\u0003\n\u0002\u0010\u000e\n\u0002\u0008\u0006\u0008\u0007\u0018\u0000B/\u0012\u0008\u0008\u0002\u0010\u0002\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0004\u001a\u00020\u0001\u0012\u0008\u0008\u0002\u0010\u0006\u001a\u00020\u0005\u0012\u0008\u0008\u0002\u0010\u0008\u001a\u00020\u0005\u00a2\u0006\u0004\u0008\t\u0010\nR\u0016\u0010\u0002\u001a\u00020\u00018\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0002\u0010\u0003R\u0016\u0010\u0004\u001a\u00020\u00018\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0004\u0010\u0003R\u0016\u0010\u0006\u001a\u00020\u00058\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0006\u0010\u0007R\u0016\u0010\u0008\u001a\u00020\u00058\u0006@\u0007X\u0087\u0004\u00a2\u0006\u0006\n\u0004\u0008\u0008\u0010\u0007\u00a8\u0006\u000b"
}
d2 = {
"Lcom/genimee/android/yatse/mediacenters/kodi/api/model/Application$Property$Version;",
"",
"major",
"I",
"minor",
"",
"revision",
"Ljava/lang/String;",
"tag",
"<init>",
"(IILjava/lang/String;Ljava/lang/String;)V",
"kodi_release"
}
k = 0x1
mv = {
0x1,
0x1,
0xf
}
pn = ""
xi = 0x0
xs = ""
.end annotation
# direct methods
.method public constructor <init>(IILjava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
.registers 7
and-int/lit8 p1, p5, 0x1
and-int/lit8 p1, p5, 0x2
and-int/lit8 p1, p5, 0x4
and-int/lit8 p1, p5, 0x8
const/4 p1, 0x0
.line 1
throw p1
.end method
```
So abstract and fails.