CWrapCondition - Lenni0451/ClassTransform GitHub Wiki
The CWrapCondition annotation is used to wrap a method call or field put with a condition (if statement).
The return value of the transformer method is used to evaluate the condition.
Only wrapping void methods and field puts are supported.
Targets
The target field of the CWrapCondition annotation specifies the redirected method/field.
Check out the CTarget page for more information about the different targets.
Also, check out CSlice for more information about how slices work.
Method signature
When injecting into a static method, the transformer method also needs to be static and vice versa.
The return type of the transformer method needs to be boolean.
Wrapping a method call
When wrapping a method call, the parameters of the transformer method need to be:
- The instance of the target class, if the method is not static
- The parameters of the target method
The return type of the target method needs to be
void.
//Wrapping a static method call in a non-static method
@CWrapCondition(target = @CTarget(value = "INVOKE", target = "Ljava/lang/String;valueOf(I)Ljava/lang/String;"), ...)
public boolean transform(final int i)
//Wrapping a non-static method call in a static method
@CWrapCondition(target = @CTarget(value = "INVOKE", target = "Ljava/lang/String;substring(I)Ljava/lang/String;"), ...)
public static boolean transform(final String instance, final int i)
Wrapping a field put
When wrapping a field put, the parameters of the transformer method need to be:
- The instance of the target class, if the field is not static
- The new value of the field
//Wrapping a static field put in a non-static method
@CWrapCondition(target = @CTarget(value = "PUTSTATIC", target = "Ljava/lang/System;out:Ljava/io/PrintStream;"), ...)
public boolean transform(final PrintStream out)
//Wrapping a non-static field put in a static method
@CWrapCondition(target = @CTarget(value = "PUTFIELD", target = "Ljava/lang/String;value:Ljava/lang/String;"), ...)
public static boolean transform(final String instance, final String value)
Targets
The target field of the CWrapCondition annotation specifies the wrapped method/field.
Check out the CTarget page for more information about the different targets.
Also, check out CSlice for more information about how slices work.
Targeting multiple methods
The method field can be an array of strings to target multiple methods.
The transformer method needs to be compatible with all targeted methods.
@CWrapCondition(value = {"method1", "method2"}, ...)
public boolean transform(final String s)
Examples
Original method:
public void method() {
this.oldOut = System.out;
System.setOut(null);
}
Wrapping a method call
Transformer method:
@CWrapCondition(method = "method", target = @CTarget(value = "INVOKE", target = "Ljava/lang/System;setOut(Ljava/io/PrintStream;)V"))
public boolean transform(final PrintStream out) {
return out == null;
}
Injected code:
public void method() {
this.oldOut = System.out;
PrintStream printStream = null;
if (this.transform(printStream)) {
System.setOut(printStream);
}
}
Wrapping a field put
Transformer method:
@CWrapCondition(method = "method", target = @CTarget(value = "PUTSTATIC", target = "Ljava/lang/System;out:Ljava/io/PrintStream;"))
public boolean transform(final PrintStream out) {
return out != null;
}
Injected code:
public void method() {
PrintStream printStream = System.out;
if (this.transform(printStream)) {
this.oldOut = printStream;
}
System.setOut(null);
}