1 /*** 2 * ASM: a very small and fast Java bytecode manipulation framework 3 * Copyright (c) 2000-2005 INRIA, France Telecom 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of the copyright holders nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 package org.objectweb.asm.util; 31 32 import java.util.HashMap; 33 34 import org.objectweb.asm.AnnotationVisitor; 35 import org.objectweb.asm.Attribute; 36 import org.objectweb.asm.TypeAnnotationVisitor; 37 import org.objectweb.asm.Type; 38 import org.objectweb.asm.util.attrs.ASMifiable; 39 40 /** 41 * An abstract ASMifier visitor. 42 * 43 * @author Eric Bruneton 44 */ 45 public class ASMifierAbstractVisitor extends AbstractVisitor { 46 47 /** 48 * The name of the variable for this visitor in the produced code. 49 */ 50 protected String name; 51 52 /** 53 * The label names. This map associates String values to Label keys. It is 54 * used only in ASMifierMethodVisitor. 55 */ 56 HashMap labelNames; 57 58 /** 59 * Constructs a new {@link ASMifierAbstractVisitor}. 60 * 61 * @param name the name of the variable for this visitor in the produced 62 * code. 63 */ 64 protected ASMifierAbstractVisitor(final String name) { 65 this.name = name; 66 } 67 68 /** 69 * Prints the ASM code that generates the given annotation. 70 * 71 * @param desc the class descriptor of the annotation class. 72 * @param visible <tt>true</tt> if the annotation is visible at runtime. 73 * @return a visitor to visit the annotation values. 74 */ 75 public AnnotationVisitor visitAnnotation( 76 final String desc, 77 final boolean visible) 78 { 79 buf.setLength(0); 80 buf.append("{\n") 81 .append("av0 = ") 82 .append(name) 83 .append(".visitAnnotation("); 84 appendConstant(desc); 85 buf.append(", ").append(visible).append(");\n"); 86 text.add(buf.toString()); 87 ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); 88 text.add(av.getText()); 89 text.add("}\n"); 90 return av; 91 } 92 93 /** 94 * Prints the ASM code that generates the given extended annotation. 95 * 96 * @param desc the class descriptor of the annotation class. 97 * @param visible <tt>true</tt> if the annotation is visible at runtime. 98 * @return a visitor to visit the annotation values. 99 */ 100 public TypeAnnotationVisitor visitTypeAnnotation( 101 final String desc, 102 final boolean visible, 103 final boolean inCode) 104 { 105 buf.setLength(0); 106 buf.append("{\n") 107 .append("xav0 = ") 108 .append(name) 109 .append(".visitTypeAnnotation("); 110 appendConstant(desc); 111 buf.append(", ").append(visible); 112 buf.append(", ").append(inCode).append(");\n"); 113 text.add(buf.toString()); 114 ASMifierTypeAnnotationVisitor xav = 115 new ASMifierTypeAnnotationVisitor(0); 116 text.add(xav.getText()); 117 text.add("}\n"); 118 return xav; 119 } 120 121 122 /** 123 * Prints the ASM code that generates the given attribute. 124 * 125 * @param attr an attribute. 126 */ 127 public void visitAttribute(final Attribute attr) { 128 buf.setLength(0); 129 if (attr instanceof ASMifiable) { 130 buf.append("{\n"); 131 buf.append("// ATTRIBUTE\n"); 132 ((ASMifiable) attr).asmify(buf, "attr", labelNames); 133 buf.append(name).append(".visitAttribute(attr);\n"); 134 buf.append("}\n"); 135 } else { 136 buf.append("// WARNING! skipped a non standard attribute of type \""); 137 buf.append(attr.type).append("\"\n"); 138 } 139 text.add(buf.toString()); 140 } 141 142 /** 143 * Prints the ASM code to end the visit. 144 */ 145 public void visitEnd() { 146 buf.setLength(0); 147 buf.append(name).append(".visitEnd();\n"); 148 text.add(buf.toString()); 149 } 150 151 /** 152 * Appends a string representation of the given constant to the given 153 * buffer. 154 * 155 * @param cst an {@link Integer}, {@link Float}, {@link Long}, 156 * {@link Double} or {@link String} object. May be <tt>null</tt>. 157 */ 158 void appendConstant(final Object cst) { 159 appendConstant(buf, cst); 160 } 161 162 /** 163 * Appends a string representation of the given constant to the given 164 * buffer. 165 * 166 * @param buf a string buffer. 167 * @param cst an {@link Integer}, {@link Float}, {@link Long}, 168 * {@link Double} or {@link String} object. May be <tt>null</tt>. 169 */ 170 static void appendConstant(final StringBuffer buf, final Object cst) { 171 if (cst == null) { 172 buf.append("null"); 173 } else if (cst instanceof String) { 174 appendString(buf, (String) cst); 175 } else if (cst instanceof Type) { 176 buf.append("Type.getType(\""); 177 buf.append(((Type) cst).getDescriptor()); 178 buf.append("\")"); 179 } else if (cst instanceof Byte) { 180 buf.append("new Byte((byte)").append(cst).append(")"); 181 } else if (cst instanceof Boolean) { 182 buf.append("new Boolean(").append(cst).append(")"); 183 } else if (cst instanceof Short) { 184 buf.append("new Short((short)").append(cst).append(")"); 185 } else if (cst instanceof Character) { 186 int c = ((Character) cst).charValue(); 187 buf.append("new Character((char)").append(c).append(")"); 188 } else if (cst instanceof Integer) { 189 buf.append("new Integer(").append(cst).append(")"); 190 } else if (cst instanceof Float) { 191 buf.append("new Float(\"").append(cst).append("\")"); 192 } else if (cst instanceof Long) { 193 buf.append("new Long(").append(cst).append("L)"); 194 } else if (cst instanceof Double) { 195 buf.append("new Double(\"").append(cst).append("\")"); 196 } else if (cst instanceof byte[]) { 197 byte[] v = (byte[]) cst; 198 buf.append("new byte[] {"); 199 for (int i = 0; i < v.length; i++) { 200 buf.append(i == 0 ? "" : ",").append(v[i]); 201 } 202 buf.append("}"); 203 } else if (cst instanceof boolean[]) { 204 boolean[] v = (boolean[]) cst; 205 buf.append("new boolean[] {"); 206 for (int i = 0; i < v.length; i++) { 207 buf.append(i == 0 ? "" : ",").append(v[i]); 208 } 209 buf.append("}"); 210 } else if (cst instanceof short[]) { 211 short[] v = (short[]) cst; 212 buf.append("new short[] {"); 213 for (int i = 0; i < v.length; i++) { 214 buf.append(i == 0 ? "" : ",").append("(short)").append(v[i]); 215 } 216 buf.append("}"); 217 } else if (cst instanceof char[]) { 218 char[] v = (char[]) cst; 219 buf.append("new char[] {"); 220 for (int i = 0; i < v.length; i++) { 221 buf.append(i == 0 ? "" : ",") 222 .append("(char)") 223 .append((int) v[i]); 224 } 225 buf.append("}"); 226 } else if (cst instanceof int[]) { 227 int[] v = (int[]) cst; 228 buf.append("new int[] {"); 229 for (int i = 0; i < v.length; i++) { 230 buf.append(i == 0 ? "" : ",").append(v[i]); 231 } 232 buf.append("}"); 233 } else if (cst instanceof long[]) { 234 long[] v = (long[]) cst; 235 buf.append("new long[] {"); 236 for (int i = 0; i < v.length; i++) { 237 buf.append(i == 0 ? "" : ",").append(v[i]).append("L"); 238 } 239 buf.append("}"); 240 } else if (cst instanceof float[]) { 241 float[] v = (float[]) cst; 242 buf.append("new float[] {"); 243 for (int i = 0; i < v.length; i++) { 244 buf.append(i == 0 ? "" : ",").append(v[i]).append("f"); 245 } 246 buf.append("}"); 247 } else if (cst instanceof double[]) { 248 double[] v = (double[]) cst; 249 buf.append("new double[] {"); 250 for (int i = 0; i < v.length; i++) { 251 buf.append(i == 0 ? "" : ",").append(v[i]).append("d"); 252 } 253 buf.append("}"); 254 } 255 } 256 } 257