<!DOCTYPE html>
<html lang="en">
<!--
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000-2011 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
-->
<head>
  <title>Package org.objectweb.asm.tree</title>
</head>
<body>

<p>
Provides an ASM visitor that constructs a tree representation of the
classes it visits. This class adapter can be useful to implement "complex"
class manipulation operations, i.e., operations that would be very hard to
implement without using a tree representation (such as optimizing the number
of local variables used by a method).
</p>

<p>
However, this class adapter has a cost: it makes ASM bigger and slower. Indeed
it requires more than twenty new classes, and multiplies the time needed to
transform a class by almost two (it is almost two times faster to read, "modify"
and write a class with a ClassVisitor than with a ClassNode). This is why
this package is bundled in an optional <code>asm-tree.jar</code> library that
is separated from (but requires) the <code>asm.jar</code> library, which contains
the core ASM framework. This is also why <em>it is recommended not to use this
class adapter when it is possible</em>.
</p>

<p>
The root class is the ClassNode, that can be created from existing bytecode. For example:
</p>

<pre>
  ClassReader classReader = new ClassReader(source);
  ClassNode classNode = new ClassNode();
  classReader.accept(classNode, 0);
</pre>

<p>
Now the content of ClassNode can be modified and then
serialized back into bytecode:
</p>

<pre>
  ClassWriter classWriter = new ClassWriter(0);
  classNode.accept(classWriter);
</pre>

<p>
Using a simple ClassVisitor it is possible to create MethodNode instances per-method.
In this example MethodNode is acting as a buffer that is flushed out at visitEnd() call:
</p>

<pre>
  ClassReader classReader = new ClassReader(source);
  ClassWriter classWriter = new ClassWriter(0);
  ClassVisitor classVisitor = new ClassVisitor(ASM7, classWriter) {
    public MethodVisitor visitMethod(int access, String name,
        String desc, String signature, String[] exceptions) {
      final MethodVisitor methodVisitor = 
          super.visitMethod(access, name, desc, signature, exceptions);
      MethodNode methodNode = new MethodNode(access, name, desc, signature, exceptions) {
        public void visitEnd() {
          // transform or analyze method code using tree API
          accept(methodVisitor);
        }
      };
    }
  };
  classReader.accept(classVisitor, 0);
</pre>

<p>
Several strategies can be used to construct method code from scratch. The first
option is to create a MethodNode, and then create XxxInsnNode instances and
add them to the instructions list:
</p>

<pre>
MethodNode methodNode = new MethodNode(...);
methodNode.instructions.add(new VarInsnNode(ALOAD, 0));
...
</pre>

<p>
Alternatively, you can use the fact that MethodNode is a MethodVisitor, and use
that to create the XxxInsnNode and add them to the instructions list through
the standard MethodVisitor methods:
</p>

<pre>
MethodNode methodNode = new MethodNode(...);
methodNode.visitVarInsn(ALOAD, 0);
...
</pre>

<p>
If you cannot generate all the instructions in sequential order, i.e. if you
need to save some pointer in the instruction list and then insert instructions
at that place after other instructions have been generated, you can use InsnList
methods insert() and insertBefore() to insert instructions at a saved pointer.
</p>

<pre>
MethodNode methodNode = new MethodNode(...);
methodNode.visitVarInsn(ALOAD, 0);
AbstractInsnNode ptr = methodNode.instructions.getLast();
methodNode.visitVarInsn(ALOAD, 1);
// inserts an instruction between ALOAD 0 and ALOAD 1
methodNode.instructions.insert(ptr, new VarInsnNode(ALOAD, 0));
...
</pre>

<p>
If you need to insert instructions while iterating over an existing instruction
list, you can also use several strategies. The first one is to use a
ListIterator over the instruction list:
</p>

<pre>
ListIterator it = methodNode.instructions.iterator();
while (it.hasNext()) {
    AbstractInsnNode insnNode = (AbstractInsnNode) it.next();
    if (...) {
        it.add(new VarInsnNode(ALOAD, 0));
    }
}
</pre>

<p>
It is also possible to convert an instruction list into an array and iterate through
array elements:
</p>

<pre>
AbstractInsnNode[] insns = methodNode.instructions.toArray();
for(int i = 0; i&lt;insns.length; i++) {
    AbstractInsnNode insn = insns[i];
    if (...) {
        methodNode.instructions.insert(insn, new VarInsnNode(ALOAD, 0));
    }
}
</pre>

<p>
If you want to insert these instructions through the MethodVisitor methods,
you can use another instance of MethodNode as a MethodVisitor and then
insert instructions collected by that instance into the instruction list.
For example:
</p>

<pre>
AbstractInsnNode[] insns = methodNode.instructions.toArray();
for(int i = 0; i&lt;insns.length; i++) {
    AbstractInsnNode insn = insns[i];
    if (...) {
        MethodNode toInsert = new MethodNode();
        toInsert.visitVarInsn(ALOAD, 0);
        toInsert.visitVarInsn(ALOAD, 1);
        m.instructions.insert(insn, toInsert.instructions);
    }
}
</pre>

<p>
@since ASM 1.3.3
</p>

</body>
</html>
