1 /*
   2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   3  *
   4  * This code is free software; you can redistribute it and/or modify it
   5  * under the terms of the GNU General Public License version 2 only, as
   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * This file is available under and governed by the GNU General Public
  27  * License version 2 only, as published by the Free Software Foundation.
  28  * However, the following notice accompanied the original version of this
  29  * file:
  30  *
  31  * ASM: a very small and fast Java bytecode manipulation framework
  32  * Copyright (c) 2000-2011 INRIA, France Telecom
  33  * All rights reserved.
  34  *
  35  * Redistribution and use in source and binary forms, with or without
  36  * modification, are permitted provided that the following conditions
  37  * are met:
  38  * 1. Redistributions of source code must retain the above copyright
  39  *    notice, this list of conditions and the following disclaimer.
  40  * 2. Redistributions in binary form must reproduce the above copyright
  41  *    notice, this list of conditions and the following disclaimer in the
  42  *    documentation and/or other materials provided with the distribution.
  43  * 3. Neither the name of the copyright holders nor the names of its
  44  *    contributors may be used to endorse or promote products derived from
  45  *    this software without specific prior written permission.
  46  *
  47  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  48  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  49  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  50  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  51  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  52  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  53  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  54  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  55  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  56  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  57  * THE POSSIBILITY OF SUCH DAMAGE.
  58  */
  59 package jdk.internal.org.objectweb.asm;
  60 
  61 /**
  62  * A visitor to visit a Java class. The methods of this class must be called in
  63  * the following order: <tt>visit</tt> [ <tt>visitSource</tt> ] [
  64  * <tt>visitModule</tt> ][ <tt>visitOuterClass</tt> ] ( <tt>visitAnnotation</tt> |
  65  * <tt>visitTypeAnnotation</tt> | <tt>visitAttribute</tt> )* (
  66  * <tt>visitInnerClass</tt> | <tt>visitField</tt> | <tt>visitMethod</tt> )*
  67  * <tt>visitEnd</tt>.
  68  *
  69  * @author Eric Bruneton
  70  */
  71 public abstract class ClassVisitor {
  72 
  73     /**
  74      * The ASM API version implemented by this visitor. The value of this field
  75      * must be one of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
  76      */
  77     protected final int api;
  78 
  79     /**
  80      * The class visitor to which this visitor must delegate method calls. May
  81      * be null.
  82      */
  83     protected ClassVisitor cv;
  84 
  85     /**
  86      * Constructs a new {@link ClassVisitor}.
  87      *
  88      * @param api
  89      *            the ASM API version implemented by this visitor. Must be one
  90      *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
  91      */
  92     public ClassVisitor(final int api) {
  93         this(api, null);
  94     }
  95 
  96     /**
  97      * Constructs a new {@link ClassVisitor}.
  98      *
  99      * @param api
 100      *            the ASM API version implemented by this visitor. Must be one
 101      *            of {@link Opcodes#ASM4}, {@link Opcodes#ASM5} or {@link Opcodes#ASM6}.
 102      * @param cv
 103      *            the class visitor to which this visitor must delegate method
 104      *            calls. May be null.
 105      */
 106     public ClassVisitor(final int api, final ClassVisitor cv) {
 107         if (api < Opcodes.ASM4 || api > Opcodes.ASM6) {
 108             throw new IllegalArgumentException();
 109         }
 110         this.api = api;
 111         this.cv = cv;
 112     }
 113 
 114     /**
 115      * Visits the header of the class.
 116      *
 117      * @param version
 118      *            the class version.
 119      * @param access
 120      *            the class's access flags (see {@link Opcodes}). This parameter
 121      *            also indicates if the class is deprecated.
 122      * @param name
 123      *            the internal name of the class (see
 124      *            {@link Type#getInternalName() getInternalName}).
 125      * @param signature
 126      *            the signature of this class. May be <tt>null</tt> if the class
 127      *            is not a generic one, and does not extend or implement generic
 128      *            classes or interfaces.
 129      * @param superName
 130      *            the internal of name of the super class (see
 131      *            {@link Type#getInternalName() getInternalName}). For
 132      *            interfaces, the super class is {@link Object}. May be
 133      *            <tt>null</tt>, but only for the {@link Object} class.
 134      * @param interfaces
 135      *            the internal names of the class's interfaces (see
 136      *            {@link Type#getInternalName() getInternalName}). May be
 137      *            <tt>null</tt>.
 138      */
 139     public void visit(int version, int access, String name, String signature,
 140             String superName, String[] interfaces) {
 141         if (cv != null) {
 142             cv.visit(version, access, name, signature, superName, interfaces);
 143         }
 144     }
 145 
 146     /**
 147      * Visits the source of the class.
 148      *
 149      * @param source
 150      *            the name of the source file from which the class was compiled.
 151      *            May be <tt>null</tt>.
 152      * @param debug
 153      *            additional debug information to compute the correspondance
 154      *            between source and compiled elements of the class. May be
 155      *            <tt>null</tt>.
 156      */
 157     public void visitSource(String source, String debug) {
 158         if (cv != null) {
 159             cv.visitSource(source, debug);
 160         }
 161     }
 162 
 163     /**
 164      * Visit the module corresponding to the class.
 165      * @param name
 166      *            module name
 167      * @param access
 168      *            module flags, among {@code ACC_OPEN}, {@code ACC_SYNTHETIC}
 169      *            and {@code ACC_MANDATED}.
 170      * @param version
 171      *            module version or null.
 172      * @return a visitor to visit the module values, or <tt>null</tt> if
 173      *         this visitor is not interested in visiting this module.
 174      */
 175     public ModuleVisitor visitModule(String name, int access, String version) {
 176         if (api < Opcodes.ASM6) {
 177             throw new RuntimeException();
 178         }
 179         if (cv != null) {
 180             return cv.visitModule(name, access, version);
 181         }
 182         return null;
 183     }
 184 
 185     /**
 186      * Visits the enclosing class of the class. This method must be called only
 187      * if the class has an enclosing class.
 188      *
 189      * @param owner
 190      *            internal name of the enclosing class of the class.
 191      * @param name
 192      *            the name of the method that contains the class, or
 193      *            <tt>null</tt> if the class is not enclosed in a method of its
 194      *            enclosing class.
 195      * @param desc
 196      *            the descriptor of the method that contains the class, or
 197      *            <tt>null</tt> if the class is not enclosed in a method of its
 198      *            enclosing class.
 199      */
 200     public void visitOuterClass(String owner, String name, String desc) {
 201         if (cv != null) {
 202             cv.visitOuterClass(owner, name, desc);
 203         }
 204     }
 205 
 206     /**
 207      * Visits an annotation of the class.
 208      *
 209      * @param desc
 210      *            the class descriptor of the annotation class.
 211      * @param visible
 212      *            <tt>true</tt> if the annotation is visible at runtime.
 213      * @return a visitor to visit the annotation values, or <tt>null</tt> if
 214      *         this visitor is not interested in visiting this annotation.
 215      */
 216     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
 217         if (cv != null) {
 218             return cv.visitAnnotation(desc, visible);
 219         }
 220         return null;
 221     }
 222 
 223     /**
 224      * Visits an annotation on a type in the class signature.
 225      *
 226      * @param typeRef
 227      *            a reference to the annotated type. The sort of this type
 228      *            reference must be {@link TypeReference#CLASS_TYPE_PARAMETER
 229      *            CLASS_TYPE_PARAMETER},
 230      *            {@link TypeReference#CLASS_TYPE_PARAMETER_BOUND
 231      *            CLASS_TYPE_PARAMETER_BOUND} or
 232      *            {@link TypeReference#CLASS_EXTENDS CLASS_EXTENDS}. See
 233      *            {@link TypeReference}.
 234      * @param typePath
 235      *            the path to the annotated type argument, wildcard bound, array
 236      *            element type, or static inner type within 'typeRef'. May be
 237      *            <tt>null</tt> if the annotation targets 'typeRef' as a whole.
 238      * @param desc
 239      *            the class descriptor of the annotation class.
 240      * @param visible
 241      *            <tt>true</tt> if the annotation is visible at runtime.
 242      * @return a visitor to visit the annotation values, or <tt>null</tt> if
 243      *         this visitor is not interested in visiting this annotation.
 244      */
 245     public AnnotationVisitor visitTypeAnnotation(int typeRef,
 246             TypePath typePath, String desc, boolean visible) {
 247         if (api < Opcodes.ASM5) {
 248             throw new RuntimeException();
 249         }
 250         if (cv != null) {
 251             return cv.visitTypeAnnotation(typeRef, typePath, desc, visible);
 252         }
 253         return null;
 254     }
 255 
 256     /**
 257      * Visits a non standard attribute of the class.
 258      *
 259      * @param attr
 260      *            an attribute.
 261      */
 262     public void visitAttribute(Attribute attr) {
 263         if (cv != null) {
 264             cv.visitAttribute(attr);
 265         }
 266     }
 267 
 268     /**
 269      * Visits information about an inner class. This inner class is not
 270      * necessarily a member of the class being visited.
 271      *
 272      * @param name
 273      *            the internal name of an inner class (see
 274      *            {@link Type#getInternalName() getInternalName}).
 275      * @param outerName
 276      *            the internal name of the class to which the inner class
 277      *            belongs (see {@link Type#getInternalName() getInternalName}).
 278      *            May be <tt>null</tt> for not member classes.
 279      * @param innerName
 280      *            the (simple) name of the inner class inside its enclosing
 281      *            class. May be <tt>null</tt> for anonymous inner classes.
 282      * @param access
 283      *            the access flags of the inner class as originally declared in
 284      *            the enclosing class.
 285      */
 286     public void visitInnerClass(String name, String outerName,
 287             String innerName, int access) {
 288         if (cv != null) {
 289             cv.visitInnerClass(name, outerName, innerName, access);
 290         }
 291     }
 292 
 293     /**
 294      * Visits a field of the class.
 295      *
 296      * @param access
 297      *            the field's access flags (see {@link Opcodes}). This parameter
 298      *            also indicates if the field is synthetic and/or deprecated.
 299      * @param name
 300      *            the field's name.
 301      * @param desc
 302      *            the field's descriptor (see {@link Type Type}).
 303      * @param signature
 304      *            the field's signature. May be <tt>null</tt> if the field's
 305      *            type does not use generic types.
 306      * @param value
 307      *            the field's initial value. This parameter, which may be
 308      *            <tt>null</tt> if the field does not have an initial value,
 309      *            must be an {@link Integer}, a {@link Float}, a {@link Long}, a
 310      *            {@link Double} or a {@link String} (for <tt>int</tt>,
 311      *            <tt>float</tt>, <tt>long</tt> or <tt>String</tt> fields
 312      *            respectively). <i>This parameter is only used for static
 313      *            fields</i>. Its value is ignored for non static fields, which
 314      *            must be initialized through bytecode instructions in
 315      *            constructors or methods.
 316      * @return a visitor to visit field annotations and attributes, or
 317      *         <tt>null</tt> if this class visitor is not interested in visiting
 318      *         these annotations and attributes.
 319      */
 320     public FieldVisitor visitField(int access, String name, String desc,
 321             String signature, Object value) {
 322         if (cv != null) {
 323             return cv.visitField(access, name, desc, signature, value);
 324         }
 325         return null;
 326     }
 327 
 328     /**
 329      * Visits a method of the class. This method <i>must</i> return a new
 330      * {@link MethodVisitor} instance (or <tt>null</tt>) each time it is called,
 331      * i.e., it should not return a previously returned visitor.
 332      *
 333      * @param access
 334      *            the method's access flags (see {@link Opcodes}). This
 335      *            parameter also indicates if the method is synthetic and/or
 336      *            deprecated.
 337      * @param name
 338      *            the method's name.
 339      * @param desc
 340      *            the method's descriptor (see {@link Type Type}).
 341      * @param signature
 342      *            the method's signature. May be <tt>null</tt> if the method
 343      *            parameters, return type and exceptions do not use generic
 344      *            types.
 345      * @param exceptions
 346      *            the internal names of the method's exception classes (see
 347      *            {@link Type#getInternalName() getInternalName}). May be
 348      *            <tt>null</tt>.
 349      * @return an object to visit the byte code of the method, or <tt>null</tt>
 350      *         if this class visitor is not interested in visiting the code of
 351      *         this method.
 352      */
 353     public MethodVisitor visitMethod(int access, String name, String desc,
 354             String signature, String[] exceptions) {
 355         if (cv != null) {
 356             return cv.visitMethod(access, name, desc, signature, exceptions);
 357         }
 358         return null;
 359     }
 360 
 361     /**
 362      * Visits the end of the class. This method, which is the last one to be
 363      * called, is used to inform the visitor that all the fields and methods of
 364      * the class have been visited.
 365      */
 366     public void visitEnd() {
 367         if (cv != null) {
 368             cv.visitEnd();
 369         }
 370     }
 371 }