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.Type; 37 import org.objectweb.asm.util.attrs.ASMifiable; 38 39 /** 40 * An abstract ASMifier visitor. 41 * 42 * @author Eric Bruneton 43 */ 44 public class ASMifierAbstractVisitor extends AbstractVisitor { 45 46 /** 47 * The name of the variable for this visitor in the produced code. 48 */ 49 protected String name; 50 51 /** 52 * The label names. This map associates String values to Label keys. It is 53 * used only in ASMifierMethodVisitor. 54 */ 55 HashMap labelNames; 56 57 /** 58 * Constructs a new {@link ASMifierAbstractVisitor}. 59 * 60 * @param name the name of the variable for this visitor in the produced 61 * code. 62 */ ASMifierAbstractVisitor(final String name)63 protected ASMifierAbstractVisitor(final String name) { 64 this.name = name; 65 } 66 67 /** 68 * Prints the ASM code that generates the given annotation. 69 * 70 * @param desc the class descriptor of the annotation class. 71 * @param visible <tt>true</tt> if the annotation is visible at runtime. 72 * @return a visitor to visit the annotation values. 73 */ visitAnnotation( final String desc, final boolean visible)74 public AnnotationVisitor visitAnnotation( 75 final String desc, 76 final boolean visible) 77 { 78 buf.setLength(0); 79 buf.append("{\n") 80 .append("av0 = ") 81 .append(name) 82 .append(".visitAnnotation("); 83 appendConstant(desc); 84 buf.append(", ").append(visible).append(");\n"); 85 text.add(buf.toString()); 86 ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0); 87 text.add(av.getText()); 88 text.add("}\n"); 89 return av; 90 } 91 92 /** 93 * Prints the ASM code that generates the given attribute. 94 * 95 * @param attr an attribute. 96 */ visitAttribute(final Attribute attr)97 public void visitAttribute(final Attribute attr) { 98 buf.setLength(0); 99 if (attr instanceof ASMifiable) { 100 buf.append("{\n"); 101 buf.append("// ATTRIBUTE\n"); 102 ((ASMifiable) attr).asmify(buf, "attr", labelNames); 103 buf.append(name).append(".visitAttribute(attr);\n"); 104 buf.append("}\n"); 105 } else { 106 buf.append("// WARNING! skipped a non standard attribute of type \""); 107 buf.append(attr.type).append("\"\n"); 108 } 109 text.add(buf.toString()); 110 } 111 112 /** 113 * Prints the ASM code to end the visit. 114 */ visitEnd()115 public void visitEnd() { 116 buf.setLength(0); 117 buf.append(name).append(".visitEnd();\n"); 118 text.add(buf.toString()); 119 } 120 121 /** 122 * Appends a string representation of the given constant to the given 123 * buffer. 124 * 125 * @param cst an {@link Integer}, {@link Float}, {@link Long}, 126 * {@link Double} or {@link String} object. May be <tt>null</tt>. 127 */ appendConstant(final Object cst)128 void appendConstant(final Object cst) { 129 appendConstant(buf, cst); 130 } 131 132 /** 133 * Appends a string representation of the given constant to the given 134 * buffer. 135 * 136 * @param buf a string buffer. 137 * @param cst an {@link Integer}, {@link Float}, {@link Long}, 138 * {@link Double} or {@link String} object. May be <tt>null</tt>. 139 */ appendConstant(final StringBuffer buf, final Object cst)140 static void appendConstant(final StringBuffer buf, final Object cst) { 141 if (cst == null) { 142 buf.append("null"); 143 } else if (cst instanceof String) { 144 appendString(buf, (String) cst); 145 } else if (cst instanceof Type) { 146 buf.append("Type.getType(\""); 147 buf.append(((Type) cst).getDescriptor()); 148 buf.append("\")"); 149 } else if (cst instanceof Byte) { 150 buf.append("new Byte((byte)").append(cst).append(")"); 151 } else if (cst instanceof Boolean) { 152 buf.append("new Boolean(").append(cst).append(")"); 153 } else if (cst instanceof Short) { 154 buf.append("new Short((short)").append(cst).append(")"); 155 } else if (cst instanceof Character) { 156 int c = ((Character) cst).charValue(); 157 buf.append("new Character((char)").append(c).append(")"); 158 } else if (cst instanceof Integer) { 159 buf.append("new Integer(").append(cst).append(")"); 160 } else if (cst instanceof Float) { 161 buf.append("new Float(\"").append(cst).append("\")"); 162 } else if (cst instanceof Long) { 163 buf.append("new Long(").append(cst).append("L)"); 164 } else if (cst instanceof Double) { 165 buf.append("new Double(\"").append(cst).append("\")"); 166 } else if (cst instanceof byte[]) { 167 byte[] v = (byte[]) cst; 168 buf.append("new byte[] {"); 169 for (int i = 0; i < v.length; i++) { 170 buf.append(i == 0 ? "" : ",").append(v[i]); 171 } 172 buf.append("}"); 173 } else if (cst instanceof boolean[]) { 174 boolean[] v = (boolean[]) cst; 175 buf.append("new boolean[] {"); 176 for (int i = 0; i < v.length; i++) { 177 buf.append(i == 0 ? "" : ",").append(v[i]); 178 } 179 buf.append("}"); 180 } else if (cst instanceof short[]) { 181 short[] v = (short[]) cst; 182 buf.append("new short[] {"); 183 for (int i = 0; i < v.length; i++) { 184 buf.append(i == 0 ? "" : ",").append("(short)").append(v[i]); 185 } 186 buf.append("}"); 187 } else if (cst instanceof char[]) { 188 char[] v = (char[]) cst; 189 buf.append("new char[] {"); 190 for (int i = 0; i < v.length; i++) { 191 buf.append(i == 0 ? "" : ",") 192 .append("(char)") 193 .append((int) v[i]); 194 } 195 buf.append("}"); 196 } else if (cst instanceof int[]) { 197 int[] v = (int[]) cst; 198 buf.append("new int[] {"); 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 long[]) { 204 long[] v = (long[]) cst; 205 buf.append("new long[] {"); 206 for (int i = 0; i < v.length; i++) { 207 buf.append(i == 0 ? "" : ",").append(v[i]).append("L"); 208 } 209 buf.append("}"); 210 } else if (cst instanceof float[]) { 211 float[] v = (float[]) cst; 212 buf.append("new float[] {"); 213 for (int i = 0; i < v.length; i++) { 214 buf.append(i == 0 ? "" : ",").append(v[i]).append("f"); 215 } 216 buf.append("}"); 217 } else if (cst instanceof double[]) { 218 double[] v = (double[]) cst; 219 buf.append("new double[] {"); 220 for (int i = 0; i < v.length; i++) { 221 buf.append(i == 0 ? "" : ",").append(v[i]).append("d"); 222 } 223 buf.append("}"); 224 } 225 } 226 } 227