001: /*
002: * ASM: a very small and fast Java bytecode manipulation framework
003: * Copyright (c) 2000-2005 INRIA, France Telecom
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: * 2. Redistributions in binary form must reproduce the above copyright
012: * notice, this list of conditions and the following disclaimer in the
013: * documentation and/or other materials provided with the distribution.
014: * 3. Neither the name of the copyright holders nor the names of its
015: * contributors may be used to endorse or promote products derived from
016: * this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
022: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
023: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
024: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
025: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
026: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
027: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
028: * THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.objectweb.asm.util;
031:
032: import java.util.HashMap;
033:
034: import org.objectweb.asm.AnnotationVisitor;
035: import org.objectweb.asm.Attribute;
036: import org.objectweb.asm.Type;
037:
038: /**
039: * An abstract ASMifier visitor.
040: *
041: * @author Eric Bruneton
042: */
043: @SuppressWarnings("unchecked")
044: public class ASMifierAbstractVisitor extends AbstractVisitor {
045:
046: /**
047: * The name of the variable for this visitor in the produced code.
048: */
049: protected String name;
050:
051: /**
052: * The label names. This map associates String values to Label keys. It is
053: * used only in ASMifierMethodVisitor.
054: */
055: HashMap labelNames;
056:
057: /**
058: * Constructs a new {@link ASMifierAbstractVisitor}.
059: *
060: * @param name the name of the variable for this visitor in the produced
061: * code.
062: */
063: protected ASMifierAbstractVisitor(final String name) {
064: this .name = name;
065: }
066:
067: /**
068: * Prints the ASM code that generates the given annotation.
069: *
070: * @param desc the class descriptor of the annotation class.
071: * @param visible <tt>true</tt> if the annotation is visible at runtime.
072: * @return a visitor to visit the annotation values.
073: */
074: public AnnotationVisitor visitAnnotation(final String desc,
075: final boolean visible) {
076: buf.setLength(0);
077: buf.append("{\n").append("av0 = ").append(name).append(
078: ".visitAnnotation(");
079: appendConstant(desc);
080: buf.append(", ").append(visible).append(");\n");
081: text.add(buf.toString());
082: ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
083: text.add(av.getText());
084: text.add("}\n");
085: return av;
086: }
087:
088: /**
089: * Prints the ASM code that generates the given attribute.
090: *
091: * @param attr an attribute.
092: */
093: public void visitAttribute(final Attribute attr) {
094: buf.setLength(0);
095: buf.append("// ATTRIBUTE ").append(attr.type).append("\n");
096: if (attr instanceof ASMifiable) {
097: buf.append("{\n");
098: ((ASMifiable) attr).asmify(buf, "attr", labelNames);
099: buf.append(name).append(".visitAttribute(attr);\n");
100: buf.append("}\n");
101: }
102: text.add(buf.toString());
103: }
104:
105: /**
106: * Prints the ASM code to end the visit.
107: */
108: public void visitEnd() {
109: buf.setLength(0);
110: buf.append(name).append(".visitEnd();\n");
111: text.add(buf.toString());
112: }
113:
114: /**
115: * Appends a string representation of the given constant to the given
116: * buffer.
117: *
118: * @param cst an {@link Integer}, {@link Float}, {@link Long},
119: * {@link Double} or {@link String} object. May be <tt>null</tt>.
120: */
121: void appendConstant(final Object cst) {
122: appendConstant(buf, cst);
123: }
124:
125: /**
126: * Appends a string representation of the given constant to the given
127: * buffer.
128: *
129: * @param buf a string buffer.
130: * @param cst an {@link Integer}, {@link Float}, {@link Long},
131: * {@link Double} or {@link String} object. May be <tt>null</tt>.
132: */
133: static void appendConstant(final StringBuffer buf, final Object cst) {
134: if (cst == null) {
135: buf.append("null");
136: } else if (cst instanceof String) {
137: appendString(buf, (String) cst);
138: } else if (cst instanceof Type) {
139: buf.append("Type.getType(\"");
140: buf.append(((Type) cst).getDescriptor());
141: buf.append("\")");
142: } else if (cst instanceof Byte) {
143: buf.append("new Byte((byte)").append(cst).append(")");
144: } else if (cst instanceof Boolean) {
145: buf.append("new Boolean(").append(cst).append(")");
146: } else if (cst instanceof Short) {
147: buf.append("new Short((short)").append(cst).append(")");
148: } else if (cst instanceof Character) {
149: int c = ((Character) cst).charValue();
150: buf.append("new Character((char)").append(c).append(")");
151: } else if (cst instanceof Integer) {
152: buf.append("new Integer(").append(cst).append(")");
153: } else if (cst instanceof Float) {
154: buf.append("new Float(\"").append(cst).append("\")");
155: } else if (cst instanceof Long) {
156: buf.append("new Long(").append(cst).append("L)");
157: } else if (cst instanceof Double) {
158: buf.append("new Double(\"").append(cst).append("\")");
159: } else if (cst instanceof byte[]) {
160: byte[] v = (byte[]) cst;
161: buf.append("new byte[] {");
162: for (int i = 0; i < v.length; i++) {
163: buf.append(i == 0 ? "" : ",").append(v[i]);
164: }
165: buf.append("}");
166: } else if (cst instanceof boolean[]) {
167: boolean[] v = (boolean[]) cst;
168: buf.append("new boolean[] {");
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 short[]) {
174: short[] v = (short[]) cst;
175: buf.append("new short[] {");
176: for (int i = 0; i < v.length; i++) {
177: buf.append(i == 0 ? "" : ",").append("(short)").append(
178: v[i]);
179: }
180: buf.append("}");
181: } else if (cst instanceof char[]) {
182: char[] v = (char[]) cst;
183: buf.append("new char[] {");
184: for (int i = 0; i < v.length; i++) {
185: buf.append(i == 0 ? "" : ",").append("(char)").append(
186: (int) v[i]);
187: }
188: buf.append("}");
189: } else if (cst instanceof int[]) {
190: int[] v = (int[]) cst;
191: buf.append("new int[] {");
192: for (int i = 0; i < v.length; i++) {
193: buf.append(i == 0 ? "" : ",").append(v[i]);
194: }
195: buf.append("}");
196: } else if (cst instanceof long[]) {
197: long[] v = (long[]) cst;
198: buf.append("new long[] {");
199: for (int i = 0; i < v.length; i++) {
200: buf.append(i == 0 ? "" : ",").append(v[i]).append("L");
201: }
202: buf.append("}");
203: } else if (cst instanceof float[]) {
204: float[] v = (float[]) cst;
205: buf.append("new float[] {");
206: for (int i = 0; i < v.length; i++) {
207: buf.append(i == 0 ? "" : ",").append(v[i]).append("f");
208: }
209: buf.append("}");
210: } else if (cst instanceof double[]) {
211: double[] v = (double[]) cst;
212: buf.append("new double[] {");
213: for (int i = 0; i < v.length; i++) {
214: buf.append(i == 0 ? "" : ",").append(v[i]).append("d");
215: }
216: buf.append("}");
217: }
218: }
219: }
|