title: Android Kotlin ProGuard Rules Wrong?
body: <p>Currently I have a library that is to be consumed by multiple other projects, however I have a problem with the code obfuscation when consuming the .aar in particular with some classes:</p>
  <p>This one to handle backend responses or asynchronous tasks, etc.</p>
  <pre><code>sealed class Result&lt;out T : Any&gt; {
      open class Success&lt;out T : Any&gt;(val data: T) : Result&lt;T&gt;()
      open class Error(val error: ErrorModel) : Result&lt;Nothing&gt;()
  }
  </code></pre>
  <p>And this one to act as a initializer or something like it to the library:</p>
  <pre><code>class LibApp private constructor(
      val appContext: Context
  ) {
  
      companion object {
          @JvmStatic lateinit var instance: LibApp
              private set
  
          fun init(
              appContext: Context
          ) {
              if (this::instance.isInitialized.not()) {
                  instance = LibApp(appContext)
              }
          }
      }
  }
  </code></pre>
  <p>The rules I'm using are:</p>
  <pre><code>#noinspection ShrinkerUnresolvedReference
  -keep class com.cross.project.compilation.testlib.response.** { *; }
  -keep class com.cross.project.compilation.testlib.LibApp.** { *; }
  </code></pre>
  <p>Currently I have 3 build types and 2 flavors:</p>
  <pre><code>buildTypes {
          release {
              debuggable false
              minifyEnabled true
              proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
          }
  
          releaseDebug{
              debuggable true
              minifyEnabled false
              proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
          }
  
          debug{
              debuggable true
              minifyEnabled false
          }
      }
  
      flavorDimensions &quot;libFlavors&quot;
  
      productFlavors {
  
          dev {
  
          }
  
          prod {
  
          }
  
      }
  </code></pre>
  <p>When I check the decompiled sources for release variants in the consumer project I get:</p>
  <p>Result gets the &lt; T &gt; stripped from the Success return:</p>
  <pre><code>public sealed class Result&lt;out T : kotlin.Any&gt; private constructor() {
      public open class Error public constructor(error: com.cross.project.compilation.testlib.response.ErrorModel) : com.cross.project.compilation.testlib.response.Result {
          public final val error: com.cross.project.compilation.testlib.response.ErrorModel /* compiled code */
      }
  
      public open class Success&lt;out T : kotlin.Any&gt; public constructor(data: T) : com.cross.project.compilation.testlib.response.Result {
          public final val data: T /* compiled code */
      }
  }
  </code></pre>
  <p>This changes the way something is coded within the variants, from something like this in dev:</p>
  <pre><code> return when (val response = accountService.getAccountData()) {
              is Result.Success -&gt; ConsumerResult.Success(response.data)
              is Result.ErrorModel -&gt; ConsumerResult.Failure(response.errorModel)
          }
  </code></pre>
  <p>To this:</p>
  <pre><code> return when (val response = accountService.getAccountData()) {
              is Result.Success&lt;*&gt; -&gt; ConsumerResult.Success((response.data as AccountData))
              is Result.ErrorModel -&gt; ConsumerResult.Failure(response.errorModel)
          }
  </code></pre>
  <p>The LibApp class gets removed for some reason.</p>
  <p>I've tried to modify the rules to avoid these issues, but only succeding in keeping the LibApp class by applying the following:</p>
  <pre><code>-keepclasseswithmembers class com.cross.project.compilation.testlib.LibApp {
      public *;
  }
  
  -keep @interface kotlin.Metadata {
    *;
  }
  -keepattributes RuntimeVisibleAnnotations
  </code></pre>
  <p>And also add the @Keep annotation to every level in the class like:</p>
  <pre><code>@Keep class LibApp private constructor(
      ...
  
      @Keep
      companion object {
         ...
  
          @Keep
          fun init(
          ...
  </code></pre>
  <p>However I've had no luck modifying the rule to keep the generic return of the Result.Success, Any idea of what I'm doing wrong?</p>
  <p>As an additional information, I'm using and building with the maven-publish plugin:</p>
  <p>Android Gradle Plugin 4.0.1
  Gradle Wrapper 6.1.1</p>
  <p>This problem seems to have appeared after I upgraded from:</p>
  <p>Android Gradle Plugin 3.6.3
  Gradle Wrapper 5.6.4</p>