2011-10-30 1 views
1

Je suis en train d'implémenter du code qui devrait, pour chaque méthode d'une classe, lancer quelques visiteurs sur un fichier .class, comme pour instrumenter son bytecode. À l'heure actuelle, je viens mis en place un MethodRenamerVisitor, mais ça commence à être assez maladroit:Un moyen facile d'accumuler quelques visiteurs 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(); 
    } 

Je suis en train de vouloir appliquer d'autres visiteurs à chacun des BytecodeMethods. Suis-je trop compliquer cela? Il serait idéal si je pouvais avoir quelque chose de la forme:

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

donc je pourrais facilement empiler tous les visiteurs que je veux courir et seulement à la fin je dois les enregistrer sur le disque. Gardez à l'esprit que chacun des visiteurs va ajouter/supprimer/modifier les méthodes qu'il visite!

Répondre

0

Vous avez déjà empilé deux visiteurs - ClassWriter et MethodRenamerVisitor. Fondamentalement, le prochain visiteur de la chaîne est passé en tant que premier paramètre i constructeur. Ainsi, le troisième peut être ajouté comme suit:

ThirdVisitor v3 = new ThirdVisitor (methodRenamerVisitor); ForthVisitor v4 = nouveau ForthVisitor (v3); etc

+0

De cette façon, ils sont terriblement couplés. Je ne peux pas, par exemple, au moment de l'exécution de choisir quels visiteurs je voudrais courir. –

+0

Il n'y a pas de couplage. Le constructeur prend une instance ClassVisitor. Si vous voulez vraiment les mélanger au moment de l'exécution, vous pouvez créer une collection d'usines, chaque usine prendrait exemple de "visiteur précédent" et créer une instance de visiteur spécifique pour cette usine. Assez simple. Bien que dans mon expérience je n'ai pas vu le cas d'utilisation quand quelque chose comme ça serait nécessaire. –

+0

Bizarre, au mieux. Mais comme il semble n'y avoir aucune autre alternative .. –

Questions connexes