【问题标题】:How to convert ClassVisitor to ClassNode in ASM java如何在 ASM java 中将 ClassVisitor 转换为 ClassNode
【发布时间】:2019-10-22 16:57:27
【问题描述】:

我想同时使用 ASM Core 和 Tree API。目前,系统使用一定数量的ClassVisitor链接在一起来分析一个class文件。现在在这个链的末尾,我想添加另一个在 ClassNode 上工作的 Transformer。是否可以将 ClassVisitor 转换为 ClassNode。

...
_cv = new FirstCV(_cv);
_cv = new SecondCV(_cv);
...
_cv = new ClassNodeTransformer((ClassNode) _cv); // Not sure how to achieve this step.

【问题讨论】:

    标签: java bytecode java-bytecode-asm bytecode-manipulation


    【解决方案1】:

    ClassVisitor 代表一个处理步骤,而 ClassNode 代表一个特定的类状态。要集成在 ClassNode 上工作的操作,您需要一个访问者,它在访问类时构建树并在最后开始访问处理后的结果。

    public abstract class IntegrateNodeTransformer extends ClassVisitor {
        ClassVisitor target;
    
        public IntegrateNodeTransformer(int api, ClassVisitor target) {
            super(api, null);
            this.target = target;
        }
    
        /**
         * Initiate the building of a tree when the visit of a class starts.
         */
        @Override
        public void visit(int version, int access, String name, String signature,
                          String superName, String[] interfaces) {
            super.cv = new ClassNode();
            super.visit(version, access, name, signature, superName, interfaces);
        }
    
        /**
         * On completion of visiting the source class, process the tree and initiate
         * visiting of the result by the target visitor, if there is one.
         */
        @Override
        public void visitEnd() {
            super.visitEnd();
            ClassNode source = (ClassNode)super.cv;
            ClassNode result = process(source);
            if(target != null) result.accept(target);
        }
    
        /**
         * Do the actual work with the Tree API.
         * May manipulate {@code source} directly and return it or return an entirely new tree.
         */
        protected abstract ClassNode process(ClassNode source);
    }
    

    如果您只有一个使用 Tree API 的处理步骤,您可以考虑直接执行它而不将其改造成 ClassVisitor

    ClassReader cr = new ClassReader(…);
    // steps before using the tree API
    
    // mind that composed visitor process in the opposite order of their construction
    ClassNode cn = new ClassNode();
    ClassVisitor cv = new SomeClassVisitor(cn); // 3rd step
    cv = new AnotherClassVisitor(cv);           // 2nd step
    cv = new YetAnotherClassVisitor(cv);        // 1st step
    
    cr.accept(cv, 0); // perform steps 1 to 3 and build result tree
    
    cn = process(cn); // the Tree API based operation (4th step)
    
    // steps after using the tree API
    ClassWriter cw = new ClassWriter(cr, 0);    // last generate class
    cv = new YourLastClassVisitor(cw);          // 7th step
    cv = new InCaseYouHaveMoreClassVisitor(cv); // 6th step
    cv = new YouKnowWhatIMean(cv);              // 5th step
    
    cn.accept(cv); // perform steps 5 to 7 on tree input and generate class
    final byte[] code = cw.toByteArray();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      • 2013-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多