2011-10-30 43 views
1

我目前正在实现一些代码,对于类的每个方法,应该在.class文件上运行几个访问者,以便测试它的字节码。目前,我只是实现了一个MethodRenamerVisitor,但是这已经变得相当尴尬:简单的方法来堆积几个ASM-Bytecode访问者?

ClassReader classReader = null; 
    try { 
     classReader = new ClassReader(monitoringFile.getCannonicalName()); 
    } catch (IOException e1) { 
     e1.printStackTrace(); 
    } 

    ClassWriter classWriter = null; 

    for (BytecodeMethod bytecodeMethod : bytecodeClass.bytecodeMethods) { 
     System.out.println("\t" + bytecodeMethod.getName()); 

     classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 

     MethodRenamerVisitor methodRenamerVisitor = new MethodRenamerVisitor(classWriter, bytecodeMethod); 
     classReader.accept(methodRenamerVisitor, 0); 

     String outputFile = monitoringFile.getCannonicalName(); 
     outputFile = outputFile.replace('.', File.separatorChar)+".class"; 

     classReader = new ClassReader(classWriter.toByteArray()); 
    } 

    try { 
     fileSystem.writeToDisk(
       classFilename, 
       classWriter.toByteArray() 
       ); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

我现在在想其他游客应用于BytecodeMethods的每一个过程。我是否过分复杂化了这个?这将会是理想的,如果我能有形式的东西:

MultiVisitors multiVisitors = new MultiVisitors(); 
visitors.add(new AVisitor(...)); 
visitors.add(new BVisitor(...)); 
... 
visitors.run(); 

,所以我可以很容易地堆放所有我想要运行,然后只在最后,我不得不将它们保存在磁盘上的游客。请记住,每个访问者都会添加/删除/修改正在访问的方法!

回答

0

您已经堆叠了两位访问者 - ClassWriter和MethodRenamerVisitor。基本上,链中的下一个访问者作为构造函数的第一个参数传递。所以第三个可以像这样添加:

ThirdVisitor v3 = new ThirdVisitor(methodRenamerVisitor); ForthVisitor v4 =新ForthVisitor(v3); 等

+0

这样他们是可怕的耦合。例如,我不能在运行时选择我想运行的访问者。 –

+0

没有耦合。构造函数接受一个ClassVisitor实例。如果你真的想在运行时对它们进行洗牌,你可以创建工厂集合,每个工厂将采用“先前访问者”的实例并为该工厂创建特定访问者的实例。很简单。虽然根据我的经验,如果有必要的话,我还没有看到用例。 –

+0

尴尬,至多。但是,因为似乎没有其他的选择。 –

相关问题