/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file is available under and governed by the GNU General Public
* License version 2 only, as published by the Free Software Foundation.
* However, the following notice accompanied the original version of this
* file:
*
* 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.
*/
package jdk.internal.org.objectweb.asm;
/**
* A visitor to visit a Java method. The methods of this class must be
* called in the following order: [ visitAnnotationDefault ] (
* visitAnnotation | visitParameterAnnotation |
* visitAttribute )* [ visitCode ( visitFrame |
* visitXInsn | visitLabel | visitTryCatchBlock |
* visitLocalVariable | visitLineNumber )* visitMaxs ]
* visitEnd. In addition, the visitXInsn
* and visitLabel methods must be called in the sequential order of
* the bytecode instructions of the visited code, visitTryCatchBlock
* must be called before the labels passed as arguments have been
* visited, and the visitLocalVariable and visitLineNumber
* methods must be called after the labels passed as arguments have been
* visited.
*
* @author Eric Bruneton
*/
public abstract class MethodVisitor {
/**
* The ASM API version implemented by this visitor. The value of this field
* must be one of {@link Opcodes#ASM4}.
*/
protected final int api;
/**
* The method visitor to which this visitor must delegate method calls. May
* be null.
*/
protected MethodVisitor mv;
/**
* Constructs a new {@link MethodVisitor}.
*
* @param api the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
*/
public MethodVisitor(final int api) {
this(api, null);
}
/**
* Constructs a new {@link MethodVisitor}.
*
* @param api the ASM API version implemented by this visitor. Must be one
* of {@link Opcodes#ASM4}.
* @param mv the method visitor to which this visitor must delegate method
* calls. May be null.
*/
public MethodVisitor(final int api, final MethodVisitor mv) {
/*if (api != Opcodes.ASM4) {
throw new IllegalArgumentException();
}*/
this.api = api;
this.mv = mv;
}
// -------------------------------------------------------------------------
// Annotations and non standard attributes
// -------------------------------------------------------------------------
/**
* Visits the default value of this annotation interface method.
*
* @return a visitor to the visit the actual default value of this
* annotation interface method, or null if this visitor
* is not interested in visiting this default value. The 'name'
* parameters passed to the methods of this annotation visitor are
* ignored. Moreover, exacly one visit method must be called on this
* annotation visitor, followed by visitEnd.
*/
public AnnotationVisitor visitAnnotationDefault() {
if (mv != null) {
return mv.visitAnnotationDefault();
}
return null;
}
/**
* Visits an annotation of this method.
*
* @param desc the class descriptor of the annotation class.
* @param visible true if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or null if
* this visitor is not interested in visiting this annotation.
*/
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
if (mv != null) {
return mv.visitAnnotation(desc, visible);
}
return null;
}
/**
* Visits an annotation of a parameter this method.
*
* @param parameter the parameter index.
* @param desc the class descriptor of the annotation class.
* @param visible true if the annotation is visible at runtime.
* @return a visitor to visit the annotation values, or null if
* this visitor is not interested in visiting this annotation.
*/
public AnnotationVisitor visitParameterAnnotation(
int parameter,
String desc,
boolean visible)
{
if (mv != null) {
return mv.visitParameterAnnotation(parameter, desc, visible);
}
return null;
}
/**
* Visits a non standard attribute of this method.
*
* @param attr an attribute.
*/
public void visitAttribute(Attribute attr) {
if (mv != null) {
mv.visitAttribute(attr);
}
}
/**
* Starts the visit of the method's code, if any (i.e. non abstract method).
*/
public void visitCode() {
if (mv != null) {
mv.visitCode();
}
}
/**
* Visits the current state of the local variables and operand stack
* elements. This method must(*) be called just before any
* instruction i that follows an unconditional branch instruction
* such as GOTO or THROW, that is the target of a jump instruction, or that
* starts an exception handler block. The visited types must describe the
* values of the local variables and of the operand stack elements just
* before i is executed.
(*) this is mandatory only
* for classes whose version is greater than or equal to
* {@link Opcodes#V1_6 V1_6}.
Packed frames are basically
* "deltas" from the state of the previous frame (very first frame is
* implicitly defined by the method's parameters and access flags):
nStack
is 1 and
* stack[0]
contains value for the type of the stack item).nLocal
is 1, 2 or 3 and
* local
elements contains values representing added types).nLocals
is 1,
* 2 or 3). * if (cst instanceof Integer) { * // ... * } else if (cst instanceof Float) { * // ... * } else if (cst instanceof Long) { * // ... * } else if (cst instanceof Double) { * // ... * } else if (cst instanceof String) { * // ... * } else if (cst instanceof Type) { * int sort = ((Type) cst).getSort(); * if (sort == Type.OBJECT) { * // ... * } else if (sort == Type.ARRAY) { * // ... * } else if (sort == Type.METHOD) { * // ... * } else { * // throw an exception * } * } else if (cst instanceof Handle) { * // ... * } else { * // throw an exception * }* * @param cst the constant to be loaded on the stack. This parameter must be * a non null {@link Integer}, a {@link Float}, a {@link Long}, a * {@link Double}, a {@link String}, a {@link Type} of OBJECT or ARRAY * sort for .class constants, for classes whose version is * 49.0, a {@link Type} of METHOD sort or a {@link Handle} for * MethodType and MethodHandle constants, for classes whose version * is 51.0. */ public void visitLdcInsn(Object cst) { if (mv != null) { mv.visitLdcInsn(cst); } } /** * Visits an IINC instruction. * * @param var index of the local variable to be incremented. * @param increment amount to increment the local variable by. */ public void visitIincInsn(int var, int increment) { if (mv != null) { mv.visitIincInsn(var, increment); } } /** * Visits a TABLESWITCH instruction. * * @param min the minimum key value. * @param max the maximum key value. * @param dflt beginning of the default handler block. * @param labels beginnings of the handler blocks. labels[i] is * the beginning of the handler block for the min + i key. */ public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { if (mv != null) { mv.visitTableSwitchInsn(min, max, dflt, labels); } } /** * Visits a LOOKUPSWITCH instruction. * * @param dflt beginning of the default handler block. * @param keys the values of the keys. * @param labels beginnings of the handler blocks. labels[i] is * the beginning of the handler block for the keys[i] key. */ public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { if (mv != null) { mv.visitLookupSwitchInsn(dflt, keys, labels); } } /** * Visits a MULTIANEWARRAY instruction. * * @param desc an array type descriptor (see {@link Type Type}). * @param dims number of dimensions of the array to allocate. */ public void visitMultiANewArrayInsn(String desc, int dims) { if (mv != null) { mv.visitMultiANewArrayInsn(desc, dims); } } // ------------------------------------------------------------------------- // Exceptions table entries, debug information, max stack and max locals // ------------------------------------------------------------------------- /** * Visits a try catch block. * * @param start beginning of the exception handler's scope (inclusive). * @param end end of the exception handler's scope (exclusive). * @param handler beginning of the exception handler's code. * @param type internal name of the type of exceptions handled by the * handler, or null to catch any exceptions (for "finally" * blocks). * @throws IllegalArgumentException if one of the labels has already been * visited by this visitor (by the {@link #visitLabel visitLabel} * method). */ public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { if (mv != null) { mv.visitTryCatchBlock(start, end, handler, type); } } /** * Visits a local variable declaration. * * @param name the name of a local variable. * @param desc the type descriptor of this local variable. * @param signature the type signature of this local variable. May be * null if the local variable type does not use generic * types. * @param start the first instruction corresponding to the scope of this * local variable (inclusive). * @param end the last instruction corresponding to the scope of this local * variable (exclusive). * @param index the local variable's index. * @throws IllegalArgumentException if one of the labels has not already * been visited by this visitor (by the * {@link #visitLabel visitLabel} method). */ public void visitLocalVariable( String name, String desc, String signature, Label start, Label end, int index) { if (mv != null) { mv.visitLocalVariable(name, desc, signature, start, end, index); } } /** * Visits a line number declaration. * * @param line a line number. This number refers to the source file from * which the class was compiled. * @param start the first instruction corresponding to this line number. * @throws IllegalArgumentException if start has not already been * visited by this visitor (by the {@link #visitLabel visitLabel} * method). */ public void visitLineNumber(int line, Label start) { if (mv != null) { mv.visitLineNumber(line, start); } } /** * Visits the maximum stack size and the maximum number of local variables * of the method. * * @param maxStack maximum stack size of the method. * @param maxLocals maximum number of local variables for the method. */ public void visitMaxs(int maxStack, int maxLocals) { if (mv != null) { mv.visitMaxs(maxStack, maxLocals); } } /** * Visits the end of the method. This method, which is the last one to be * called, is used to inform the visitor that all the annotations and * attributes of the method have been visited. */ public void visitEnd() { if (mv != null) { mv.visitEnd(); } } }