我有一个您可能会觉得有用的框架(特别是procyon-compilertools
)。它将使您能够以比 ASM 更面向对象的方式完成您所要求的工作。但是,该项目仍处于开发初期,可能会发生变化,因此我不建议在生产项目中使用它。
您可以以此为起点:
public class CallInspectionSample {
static class Target {
public static void main(String[] args) {
new Target().getText("MyKey");
}
public String getText(final String key) {
return null;
}
}
public static void main(String[] args) {
final TypeReference targetType = MetadataSystem.instance().lookupType("CallInspectionSample$Target");
final TypeDefinition resolvedType = targetType.resolve();
final MethodDefinition mainMethod = resolvedType.getDeclaredMethods().get(1);
final MethodDefinition getTextMethod = resolvedType.getDeclaredMethods().get(2);
final MethodBody mainBody = mainMethod.getBody();
final Block methodAst = new Block();
final DecompilerContext context = new DecompilerContext();
context.setCurrentType(resolvedType);
context.setCurrentMethod(mainMethod);
methodAst.getBody().addAll(AstBuilder.build(mainBody, true, context));
AstOptimizer.optimize(context, methodAst);
for (final Expression e : methodAst.getChildrenAndSelfRecursive(Expression.class)) {
if (e.getCode() == AstCode.InvokeVirtual &&
((MethodReference) e.getOperand()).resolve() == getTextMethod) {
// Analyze arguments here (skip first for instance methods)...
System.out.println(e.getArguments());
}
}
}
}
(示例输出[initobject:Target(Target::<init>), ldc:String("MyKey")]
)