Проблема с аргументом типа Kotlin generic в интерфейсе после обфускации R8

Не могу понять, как правильно настроить правило обфускации R8, чтобы мой интерфейс работал.

Выпускаю библиотеку. Он имеет запутанный код везде, кроме публичного API.

Существует базовый интерфейс BaseFoo, в сигнатуре которого указаны параметры типа:

interface BaseFoo<D, E> {
    fun handle(result: SomeOtherClass<D, E>): Boolean
}

Затем есть класс Bar с объявленным внутри производным интерфейсом DerivedFoo:

class Bar {
    interface DerivedFoo : BaseFoo<Alice, Bob>
}

После публикации этого кода с обфускацией с использованием R8 попытка использовать интерфейс этой библиотеки DerivedFoo завершается неудачей:

val myDerivedFoo = object : Bar.DerivedFoo {
    override fun handle(result: SomeOtherClass<Alice, Bob>): Boolean {
        return false
    }
}

object здесь показывает ошибку:

Объект не является абстрактным и не реализует публичный абстрактный забавный дескриптор абстрактного члена (результат: SomeOtherClass ‹Alice, Bob›): Boolean, определенный в com.example.Bar.DerivedFoo

Соответственно метод handle дает

'handle' ничего не отменяет

ошибка. Если вы сделаете здесь функцию переопределения с помощью автозаполнения, вы получите:

override fun handle(result: SomeOtherClass<D, E>): Boolean {
}

То есть - именно с <D, E> универсальными аргументами (вместо <Alice, Bob>), несмотря на то, что компилятор не знает, что это за D и E.

Конфигурация обфускации пока имеет следующие правила:

-keeppackagenames com.example.**
-keep public class com.example.Bar { *; }
-keep public interface com.example.Bar$DerivedFoo { *; }

# Common rules:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-dontshrink
-verbose
-ignorewarnings
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable,*Annotation*,Signature,InnerClasses,EnclosingMethod,MethodParameters,Exceptions
-keepparameternames
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable

Может ли кто-нибудь пролить свет на то, как лечить эту недостающую производную подпись интерфейса?

ОБНОВЛЕНИЕ: образец с проблемой воспроизведения можно найти здесь


person Den Drobiazko    schedule 21.07.2020    source источник
comment
Я не слежу. Описываемые вами ошибки - это ошибки компилятора, верно? Но разве R8 не запутывает байт-код после того, как он уже скомпилирован?   -  person Tenfour04    schedule 21.07.2020
comment
Хороший. Забыл упомянуть, что я запутываю библиотеку. Эти ошибки компиляции возникают, когда я пытаюсь использовать выпущенный (запутанный) файл aar.   -  person Den Drobiazko    schedule 23.07.2020


Ответы (1)


Похоже, что конфиг правильный и все должно работать. Но я думаю, это не из-за каких-то проблем с совместимостью с Kotlin.

Хорошей новостью является то, что наряду с другими проблемами, связанными с Kotlin, это было исправлено в версии 2.1.42.

Таким образом, решение данной проблемы - принудительное использование соответствующей версии R8:

buildscript {

    repositories {
        maven {
            url 'https://storage.googleapis.com/r8-releases/raw'
        }
    }

    dependencies {
        classpath 'com.android.tools:r8:2.1.42'          // Must be before the Gradle Plugin for Android.
        classpath 'com.android.tools.build:gradle:X.Y.Z' // Your current AGP version.
     }
}

Кредиты переходят к этому ответу

person Den Drobiazko    schedule 27.07.2020