Java 如何将访问者端到端地链接起来

Java 如何将访问者端到端地链接起来,java,java-bytecode-asm,Java,Java Bytecode Asm,我试图在ASM中实现一个转换,每个方法需要两次转换。第一个用于收集有关需要插装的位置的信息(与跳转目标有关,这就是我需要两次传递的原因),第二个用于完成收集的信息并添加插装。这也意味着我必须在开始第二遍之前完成第一遍(即处理所有指令)。这就是为什么手册中讨论的正常链接模式不起作用的原因 我的问题是:有没有一种优雅而方便的方法 到目前为止,我能想到的唯一解决方案是在第一个访问者中从visitEnd()调用第二个访问者。轮廓是这样的 public class Pass1Visitor extends

我试图在ASM中实现一个转换,每个方法需要两次转换。第一个用于收集有关需要插装的位置的信息(与跳转目标有关,这就是我需要两次传递的原因),第二个用于完成收集的信息并添加插装。这也意味着我必须在开始第二遍之前完成第一遍(即处理所有指令)。这就是为什么手册中讨论的正常链接模式不起作用的原因

我的问题是:有没有一种优雅而方便的方法

到目前为止,我能想到的唯一解决方案是在第一个访问者中从visitEnd()调用第二个访问者。轮廓是这样的

public class Pass1Visitor extends MethodVisitor {
  ...
  public void visitEnd() {
    //do stuff the call the second visitor
    thisMethodNode.accept( new Pass2Visitor() );
  }
}

我不太喜欢这个解决方案,因为我怀疑在未来我将不得不链接更多的访问者,我可能希望能够挑选和选择。这是不可能的

如果需要通过字节码进行两次传递,那么ASM就是这样做的。树包(即MethodNode)将保存所有访问事件,并可以在调用accept()方法时重播它们。内联创建下一个访问者是个坏主意,但传递访问者并没有什么错。请参阅关于ASM中“内联方法”部分的实现或示例

因此,您的示例如下所示:

public class Pass1Visitor extends MethodNode {
  MethodVisitor nextVisitor;

  public Pass1Visitor(MethodVisitor nextVisitor) {
    this.nextVisitor= nextVisitor;
  }

  ...

  public void visitEnd() {
    //do stuff the call the second visitor
    thisMethodNode.accept( nextVisitor );
  }
}

这就是我所拥有的。我希望有一个更简单的方法。(这需要传递访问者和MethodNode以及我需要的所有东西)。我已经更新了我的答案,并提供了更多的细节和示例。传递访问者是ASMAPI设计的主要思想。那么,我想我必须这样做…:)