Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update ProGuard default shrinking rules #2448

Merged
merged 11 commits into from
Aug 22, 2023
10 changes: 7 additions & 3 deletions gson/src/main/resources/META-INF/proguard/gson.pro
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
# Keep class TypeToken (respectively its generic signature) if present
-if class com.google.gson.reflect.TypeToken
-keep,allowobfuscation class com.google.gson.reflect.TypeToken
#-keep class com.google.gson.reflect.TypeToken { *; }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this commented line intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No removed.


# Keep any (anonymous) classes extending TypeToken
-keep,allowobfuscation class * extends com.google.gson.reflect.TypeToken
Expand Down Expand Up @@ -54,16 +55,19 @@
<init>();
}

# Keep fields annotated with @SerializedName for classes which are present.
# Keep fields annotated with @SerializedName for classes which are referenced.
# If classes with fields annotated with @SerializedName have a no-args
# constructor keep that as well.
# constructor keep that as well. Based on
# https://issuetracker.google.com/issues/150189783#comment11.
# See also https://github.com/google/gson/pull/2420#discussion_r1241813541
# for a more detailed explanation.
-if class *
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this if class *, -classeswithmembers... class <1> doesn't do anything relative to -classeswithmembers... class * , after reading some of the follow-up threads on that change.

Copy link
Collaborator

@Marcono1234 Marcono1234 Jul 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least for R8 it does seem to make a difference: -keepclasseswithmembers ... class * always keeps the class, even if it isn't used. Whereas -if class * ... -keepclasseswithmembers ... class <1> only keeps the class if it is actually used.

Unfortunately this is not covered by the tests yet; have created #2455 to add a test for this.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks also for the other points you raised, but unless sgjesse wants to address them here as well could you please create a separate GitHub issue or pull request? Otherwise the discussion on this pull request here might drift too far away from the original topic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the rules to be two -if rules

  1. Keep all @SerializedName fields for classes which are present after shrinking
  2. If a class with a @SerializedName field is present keep its no-args constructor

-keepclasseswithmembers,allowobfuscation class <1> {
@com.google.gson.annotations.SerializedName <fields>;
}
-if class * {
@com.google.gson.annotations.SerializedName <fields>;
}
-keepclassmembers,allowobfuscation class <1> {
-keepclassmembers,allowobfuscation,allowoptimization class <1> {
Copy link
Collaborator

@Marcono1234 Marcono1234 Aug 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought in #2448 (comment) you just explained that you intentionally removed allowoptimization, but now you are adding it back? Is that intentional?

(Or am I misunderstanding this?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This rule is only covering the no-args constructor (<init>()), so here there is no issue with allowoptimization. For the rule above for the annotated fields it should not be there as otherwise R8 can do value propagation.

<init>();
}
2 changes: 2 additions & 0 deletions shrinker-test/common.pro
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,5 @@
-keepclassmembernames class com.example.ClassWithVersionAnnotations {
<fields>;
}

-dontobfuscate
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this intentional? I think this should not be necessary and there were explicit rules which preserved names where needed for the tests.
Though it looks like you (accidentally?) removed one in proguard.pro:

- -keepclassmembernames class com.example.NoSerializedNameMain$TestClassWithoutDefaultConstructor {
-   <fields>;
- }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this was all for some testing. These changes should not have been there.

6 changes: 0 additions & 6 deletions shrinker-test/proguard.pro
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,3 @@
-keepclassmembernames class com.example.NoSerializedNameMain$TestClassNotAbstract {
<fields>;
}
-keepclassmembernames class com.example.NoSerializedNameMain$TestClassWithoutDefaultConstructor {
<fields>;
}
#-keep class com.example.ClassWithSerializedName {
# <init>(...);
#}