Can not preserve class member names

Issue

ProGuard is unable to preserve class members when specified correctly.

Assume the following class:

package com.package.some;

class SomeClass {
 void someMember() {
  var someVariable = () => {};
 }
}

Java compiled a synthetic class for the lambda. ProGuard moved it to another synthetic class, which was compiled for another class.

Solutions

The following rule for ProGuard solves this issue:

-keepclassmembernames ** {
 *;
}

This solution is not practical, because it applies to any class due to the wildcard. The following rule solves the issue as well:

-keepclassmembernames class ** {
 synthetic *** *(...);
}

Unfortunately, this solution is not practical as well, because it applies to unrelated classes as well. The following solution does not work:

-keepclassmembernames class com.package.some.**

Unfortunately, it is unknown why it does not.

References

  • The issue has been discovered and discussed in this GitHub issue for a complete reference.
  • The issue can be reproduced fully with the following steps:
    1. Clone git@github.com:revanced/revanced-integrations.git
    2. Checkout revision 3f5e27d6b16d7aa73eef2ffb201e9f462eb84487
    3. Run ./gradlew build in the root directory and save the release apk file
    4. Apply a working rule from Solutions above and build the project again
    5. Compare the release apk files:
      • The release apk file differs for class app.revanced.all.connectivity.wifi.spoof.SpoofWifiPatch.
      • For class app.revanced.integrations.patches.LithoBlockRegister the synthetic class LithoBlockRegister$$ExternalSyntheticApiModelOutline0 contains code from class SpoofWifiPatch when no rule from Solutions is applied.

Hi @oSumAtrIX,

Thank you for the question! Try giving the below a try:

-keepclassmembernames class com.package.some.** { *; }

I would also recommend experimenting your keep rules using ProGuard Playground.

I hope this helps, and have a great weekend!

Hi @Jesse,

Thank you for replying back!

Unfortunately, the issue is still reproducible with this rule. This specific rule uses the class specification. The class specification allows to optionally specify members.
Because it is optional, the rule ˋ-keepclassmembernames class com.package.some.**ˋ should’ve worked as well due to the wildcard for the classname.
Either way your suggested rule ˋ-keepclassmembernames class com.package.some.** { *; }ˋ did not solve the issue as well.
You can reproduce this issue with your rule via the reproduction steps given in my original issue.

Sincerely,
Ohan