Skip to content

Commit

Permalink
Give JavaReflectionApiExecutor a more accurate name
Browse files Browse the repository at this point in the history
Renames the JavaReflectionApiExecutor to ObjectGetClassExecutor, since all the other functionality has been moved into the models themselves.
  • Loading branch information
toon.willemot authored and JorenHannes committed Jan 13, 2025
1 parent f67f741 commit fc53fc0
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 271 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import static proguard.classfile.ClassConstants.*;
import static proguard.classfile.util.ClassUtil.internalClassName;
import static proguard.classfile.util.ClassUtil.internalClassNameFromType;
import static proguard.exception.ErrorId.EVALUATION_JAVA_REFLECTION_EXECUTOR;
import static proguard.exception.ErrorId.OBJECT_GET_CLASS_EXECUTOR_UNSUPPORTED_SIGNATURE;

import java.util.HashSet;
import java.util.Optional;
Expand All @@ -23,17 +23,20 @@

/**
* This {@link Executor} provides an implementation for {@link Executor#getMethodResult} which
* resolves a number of simple {@link Class} API methods.
* resolves all types of <code>'Object'.getClass</code> {@link Class} calls based on the classes in
* the class pools.
*
* <p>For example <code>classA.getClass()</code> and <code>classB.getClass()</code>
*/
public class JavaReflectionApiExecutor implements Executor {
public class ObjectGetClassExecutor implements Executor {

private final ClassPool programClassPool;
private final ClassPool libraryClassPool;

private final Set<MethodSignature> supportedMethodSignatures = new HashSet<>();

/** Private constructor reserved for the static {@link Builder}. */
private JavaReflectionApiExecutor(ClassPool programClassPool, ClassPool libraryClassPool) {
private ObjectGetClassExecutor(ClassPool programClassPool, ClassPool libraryClassPool) {
this.programClassPool = programClassPool;
this.libraryClassPool = libraryClassPool;

Expand All @@ -49,26 +52,22 @@ private JavaReflectionApiExecutor(ClassPool programClassPool, ClassPool libraryC
@Override
public MethodResult getMethodResult(
MethodExecutionInfo methodExecutionInfo, ValueCalculator valueCalculator) {
MethodSignature target = methodExecutionInfo.getSignature();

// Handling these signatures only requires the type of the instance.
if (METHOD_NAME_OBJECT_GET_CLASS.equals(target.getMethodName())) {
Value instance = methodExecutionInfo.getInstanceNonStatic();
if (!(instance instanceof TypedReferenceValue)) return MethodResult.invalidResult();
TypedReferenceValue typedInstance = (TypedReferenceValue) instance;

if (typedInstance.getType() == null) return MethodResult.invalidResult();
Optional<Clazz> clazz =
findReferencedClazz(internalClassNameFromType(typedInstance.getType()));
if (clazz.isPresent()) {
return createResult(methodExecutionInfo, valueCalculator, new ClassModel(clazz.get()));
}
if (!METHOD_NAME_OBJECT_GET_CLASS.equals(methodExecutionInfo.getSignature().getMethodName()))
throw new ProguardCoreException(
OBJECT_GET_CLASS_EXECUTOR_UNSUPPORTED_SIGNATURE,
String.format(
"%s is not a supported method signature.", methodExecutionInfo.getSignature()));

Value instance = methodExecutionInfo.getInstanceNonStatic();
if (!(instance instanceof TypedReferenceValue)) return MethodResult.invalidResult();
TypedReferenceValue typedInstance = (TypedReferenceValue) instance;

if (typedInstance.getType() == null) return MethodResult.invalidResult();
Optional<Clazz> clazz = findReferencedClazz(internalClassNameFromType(typedInstance.getType()));
if (clazz.isPresent()) {
return createResult(methodExecutionInfo, valueCalculator, new ClassModel(clazz.get()));
}

throw new ProguardCoreException(
EVALUATION_JAVA_REFLECTION_EXECUTOR,
String.format(
"%s is not a supported method signature.", methodExecutionInfo.getSignature()));
return MethodResult.invalidResult();
}

@Override
Expand Down Expand Up @@ -113,25 +112,24 @@ private static MethodResult createResult(

// Builder class.

/** Builder for {@link JavaReflectionApiExecutor}. */
public static class Builder implements Executor.Builder<JavaReflectionApiExecutor> {
/** Builder for {@link ObjectGetClassExecutor}. */
public static class Builder implements Executor.Builder<ObjectGetClassExecutor> {
private final ClassPool programClassPool;
private final ClassPool libraryClassPool;

private JavaReflectionApiExecutor javaReflectionApiExecutor = null;
private ObjectGetClassExecutor objectGetClassExecutor = null;

public Builder(@NotNull ClassPool programClassPool, @NotNull ClassPool libraryClassPool) {
this.programClassPool = programClassPool;
this.libraryClassPool = libraryClassPool;
}

@Override
public JavaReflectionApiExecutor build() {
if (javaReflectionApiExecutor == null) {
javaReflectionApiExecutor =
new JavaReflectionApiExecutor(programClassPool, libraryClassPool);
public ObjectGetClassExecutor build() {
if (objectGetClassExecutor == null) {
objectGetClassExecutor = new ObjectGetClassExecutor(programClassPool, libraryClassPool);
}
return javaReflectionApiExecutor;
return objectGetClassExecutor;
}
}
}
3 changes: 2 additions & 1 deletion base/src/main/java/proguard/exception/ErrorId.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ public final class ErrorId {
ANALYSIS_JVM_TRANSFER_RELATION_CONSTANT_INSTRUCTION_VISITOR_OPCODE_UNSUPPORTED = 9_044;
public static final int ANALYSIS_JVM_DEFAULT_REDUCE_OPERATOR_STATE_UNSUPPORTED = 9_045;
public static final int ANALYSIS_JVM_TREE_HEAP_STATE_INCOMPATIBLE = 9_046;
public static final int EVALUATION_JAVA_REFLECTION_EXECUTOR = 9_047;

public static final int OBJECT_GET_CLASS_EXECUTOR_UNSUPPORTED_SIGNATURE = 9_047;

/** Private constructor to prevent instantiation of the class. */
private ErrorId() {}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ import proguard.evaluation.value.`object`.model.ClassModel
import proguard.testutils.ClassPoolBuilder
import proguard.testutils.JavaSource
import proguard.testutils.RequiresJavaVersion
import java.util.ArrayList

@RequiresJavaVersion(9)
class Java9ReflectionApiExecutorTest : BehaviorSpec({
class ReflectiveModelExecutorJava9Test : BehaviorSpec({
Given("A method which uses various ways to access class details") {
val (programClassPool, libraryClassPool) = ClassPoolBuilder.fromSource(
JavaSource(
Expand All @@ -47,7 +46,7 @@ class Java9ReflectionApiExecutorTest : BehaviorSpec({
javacArguments = listOf("-source", "1.8", "-target", "1.8"),
)

When("It is partially evaluated with a JavaReflectionExecutor") {
When("It is partially evaluated with a ClassModel executor") {
val particularValueFactory = ParticularValueFactory(
ArrayReferenceValueFactory(),
ParticularReferenceValueFactory(),
Expand All @@ -59,7 +58,6 @@ class Java9ReflectionApiExecutorTest : BehaviorSpec({
ExecutingInvocationUnit.Builder(programClassPool, libraryClassPool)
.setEnableSameInstanceIdApproximation(true)
.useDefaultStringReflectionExecutor(true)
.addExecutor(JavaReflectionApiExecutor.Builder(programClassPool, libraryClassPool))
.addExecutor(ClassModelExecutor.Builder(programClassPool, libraryClassPool))
.build(particularValueFactory),
)
Expand Down
Loading

0 comments on commit fc53fc0

Please sign in to comment.