1 /*
   2  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.invoke.anon;
  27 
  28 /**
  29  * A visitor called by {@link ConstantPoolParser#parse(ConstantPoolVisitor)}
  30  * when a constant pool entry is parsed.
  31  * <p>
  32  * A visit* method is called when a constant pool entry is parsed.
  33  * The first argument is always the constant pool index.
  34  * The second argument is always the constant pool tag,
  35  * even for methods like {@link #visitUTF8(int, byte, String)} which only apply to one tag.
  36  * String arguments refer to Utf8 or NameAndType entries declared elsewhere,
  37  * and are always accompanied by the indexes of those entries.
  38  * <p>
  39  * The order of the calls to the visit* methods is not necessarily related
  40  * to the order of the entries in the constant pool.
  41  * If one entry has a reference to another entry, the latter (lower-level)
  42  * entry will be visited first.
  43  * <p>
  44  * The following table shows the relation between constant pool entry
  45  * types and the corresponding visit* methods:
  46  *
  47  * <table border=1 cellpadding=5 summary="constant pool visitor methods">
  48  * <tr><th>Tag(s)</th><th>Method</th></tr>
  49  * <tr>
  50  *   <td>{@link #CONSTANT_Utf8}</td>
  51  *   <td>{@link #visitUTF8(int, byte, String)}</td>
  52  * </tr><tr>
  53  *   <td>{@link #CONSTANT_Integer}, {@link #CONSTANT_Float},
  54  *       {@link #CONSTANT_Long}, {@link #CONSTANT_Double}</td>
  55  *   <td>{@link #visitConstantValue(int, byte, Object)}</td>
  56  * </tr><tr>
  57  *   <td>{@link #CONSTANT_String}, {@link #CONSTANT_Class}</td>
  58  *   <td>{@link #visitConstantString(int, byte, String, int)}</td>
  59  * </tr><tr>
  60  *   <td>{@link #CONSTANT_NameAndType}</td>
  61  *   <td>{@link #visitDescriptor(int, byte, String, String, int, int)}</td>
  62  * </tr><tr>
  63  *   <td>{@link #CONSTANT_Fieldref},
  64  *       {@link #CONSTANT_Methodref},
  65  *       {@link #CONSTANT_InterfaceMethodref}</td>
  66  *   <td>{@link #visitMemberRef(int, byte, String, String, String, int, int)}</td>
  67  * </tr>
  68  * </table>
  69  *
  70  * @see ConstantPoolPatch
  71  * @author Remi Forax
  72  * @author jrose
  73  */
  74 public class ConstantPoolVisitor {
  75   /** Called each time an UTF8 constant pool entry is found.
  76    * @param index the constant pool index
  77    * @param tag always {@link #CONSTANT_Utf8}
  78    * @param utf8 string encoded in modified UTF-8 format passed as a {@code String}
  79    *
  80    * @see ConstantPoolPatch#putUTF8(int, String)
  81    */
  82   public void visitUTF8(int index, byte tag, String utf8) {
  83     // do nothing
  84   }
  85 
  86   /** Called for each constant pool entry that encodes an integer,
  87    *  a float, a long, or a double.
  88    *  Constant strings and classes are not managed by this method but
  89    *  by {@link #visitConstantString(int, byte, String, int)}.
  90    *
  91    * @param index the constant pool index
  92    * @param tag one of {@link #CONSTANT_Integer},
  93    *            {@link #CONSTANT_Float},
  94    *            {@link #CONSTANT_Long},
  95    *            or {@link #CONSTANT_Double}
  96    * @param value encoded value
  97    *
  98    * @see ConstantPoolPatch#putConstantValue(int, Object)
  99    */
 100   public void visitConstantValue(int index, byte tag, Object value) {
 101     // do nothing
 102   }
 103 
 104   /** Called for each constant pool entry that encodes a string or a class.
 105    * @param index the constant pool index
 106    * @param tag one of {@link #CONSTANT_String},
 107    *            {@link #CONSTANT_Class},
 108    * @param name string body or class name (using dot separator)
 109    * @param nameIndex the index of the Utf8 string for the name
 110    *
 111    * @see ConstantPoolPatch#putConstantValue(int, byte, Object)
 112    */
 113   public void visitConstantString(int index, byte tag,
 114                                   String name, int nameIndex) {
 115     // do nothing
 116   }
 117 
 118   /** Called for each constant pool entry that encodes a name and type.
 119    * @param index the constant pool index
 120    * @param tag always {@link #CONSTANT_NameAndType}
 121    * @param memberName a field or method name
 122    * @param signature the member signature
 123    * @param memberNameIndex index of the Utf8 string for the member name
 124    * @param signatureIndex index of the Utf8 string for the signature
 125    *
 126    * @see ConstantPoolPatch#putDescriptor(int, String, String)
 127    */
 128   public void visitDescriptor(int index, byte tag,
 129                               String memberName, String signature,
 130                               int memberNameIndex, int signatureIndex) {
 131     // do nothing
 132   }
 133 
 134   /** Called for each constant pool entry that encodes a field or method.
 135    * @param index the constant pool index
 136    * @param tag one of {@link #CONSTANT_Fieldref},
 137    *            or {@link #CONSTANT_Methodref},
 138    *            or {@link #CONSTANT_InterfaceMethodref}
 139    * @param className the class name (using dot separator)
 140    * @param memberName name of the field or method
 141    * @param signature the field or method signature
 142    * @param classNameIndex index of the Utf8 string for the class name
 143    * @param descriptorIndex index of the NameAndType descriptor constant
 144    *
 145    * @see ConstantPoolPatch#putMemberRef(int, byte, String, String, String)
 146    */
 147   public void visitMemberRef(int index, byte tag,
 148                              String className, String memberName, String signature,
 149                              int classNameIndex, int descriptorIndex) {
 150     // do nothing
 151   }
 152 
 153     public static final byte
 154       CONSTANT_None = 0,
 155       CONSTANT_Utf8 = 1,
 156       //CONSTANT_Unicode = 2,               /* unused */
 157       CONSTANT_Integer = 3,
 158       CONSTANT_Float = 4,
 159       CONSTANT_Long = 5,
 160       CONSTANT_Double = 6,
 161       CONSTANT_Class = 7,
 162       CONSTANT_String = 8,
 163       CONSTANT_Fieldref = 9,
 164       CONSTANT_Methodref = 10,
 165       CONSTANT_InterfaceMethodref = 11,
 166       CONSTANT_NameAndType = 12;
 167 
 168     private static String[] TAG_NAMES = {
 169         "Empty",
 170         "Utf8",
 171         null, //"Unicode",
 172         "Integer",
 173         "Float",
 174         "Long",
 175         "Double",
 176         "Class",
 177         "String",
 178         "Fieldref",
 179         "Methodref",
 180         "InterfaceMethodref",
 181         "NameAndType"
 182     };
 183 
 184     public static String tagName(byte tag) {
 185         String name = null;
 186         if ((tag & 0xFF) < TAG_NAMES.length)
 187             name = TAG_NAMES[tag];
 188         if (name == null)
 189             name = "Unknown#"+(tag&0xFF);
 190         return name;
 191     }
 192 }