Reapply moved InterfaceUsageMarker to fx interface constant marking (#510)

This commit is contained in:
piazzesiNiccolo-GS
2025-12-01 09:47:13 +01:00
committed by GitHub
parent 0c51b82946
commit 14dcc28ba2
3 changed files with 77 additions and 0 deletions

View File

@@ -129,6 +129,9 @@ public class UsageMarker
new LocalVariableTypeUsageMarker(classUsageMarker)
))));
// Second Interface Usage marking, this is necessary for marking interface constants that are not directly referenced
// (e.g. interfaces only referenced through annotations). See https://github.com/Guardsquare/proguard/issues/508.
programClassPool.classesAccept(new InterfaceUsageMarker(classUsageMarker));
if (configuration.keepKotlinMetadata)
{

View File

@@ -21,6 +21,74 @@ import proguard.testutils.RequiresJavaVersion
import proguard.util.ProcessingFlagSetter
import proguard.util.ProcessingFlags.DONT_SHRINK
class UsageMarkerTest : BehaviorSpec({
Given("A class pool with interfaces only referenced through annotations") {
val (programClassPool, _) = ClassPoolBuilder.fromSource(
JavaSource("MyInterface.java","""
interface MyInterface {}
""".trimIndent()),
JavaSource("MyAnnotation.java","""
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Retention;
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
Class<?> value();
}
""".trimIndent()),
JavaSource("MyImpl.java","""
class MyImpl implements MyInterface {}
""".trimIndent()),
JavaSource("InterfaceTest.java", """
import java.lang.reflect.Field;
class InterfaceTest {
@MyAnnotation(MyImpl.class)
String s;
public static void main(String... args) throws Exception {
Field f = InterfaceTest.class.getDeclaredField("s");
MyAnnotation annotation = f.getAnnotation(MyAnnotation.class);
Object obj = annotation.value().getDeclaredConstructor().newInstance();
if (obj instanceof MyInterface) {
System.out.println("success");
} else {
throw new Exception(obj.getClass() + " does not implement " + MyInterface.class);
}
}
}
""".trimIndent())
)
val implClass = programClassPool.getClass("MyImpl")
val main = programClassPool.getClass("InterfaceTest")
main.accept(
MultiClassVisitor(ProcessingFlagSetter(DONT_SHRINK), AllMemberVisitor(
ProcessingFlagSetter(DONT_SHRINK)
)))
When("marking") {
val simpleUsageMarker = SimpleUsageMarker()
UsageMarker(Configuration()).mark(programClassPool,ClassPool(), ResourceFilePool(),simpleUsageMarker)
Then("The interface class should be marked as used.") {
val used = object : ConstantVisitor {
var used = false
override fun visitAnyConstant(
clazz: Clazz?,
constant: Constant?
) {
used = used or simpleUsageMarker.isUsed(constant)
}
}
implClass.interfaceConstantsAccept(used)
used.used shouldBe true
}
}
}
})
@RequiresJavaVersion(15)
class Java15UsageMarkerTest : BehaviorSpec({
// Regression test for https://github.com/Guardsquare/proguard/issues/501

View File

@@ -1,3 +1,9 @@
## Version 7.8.2
### Bugfixes
- Fix regression in marking of interface constants (#508).
## Version 7.8.1
### Bugfixes