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: */package com.uwyn.rife.asm.util;
030:
031: import java.util.HashMap;
032:
033: import com.uwyn.rife.asm.AnnotationVisitor;
034: import com.uwyn.rife.asm.Attribute;
035: import com.uwyn.rife.asm.Type;
036: import com.uwyn.rife.asm.util.attrs.ASMifiable;
037:
038: /**
039: * An abstract ASMifier visitor.
040: *
041: * @author Eric Bruneton
042: */
043: public class ASMifierAbstractVisitor extends AbstractVisitor {
044:
045: /**
046: * The name of the variable for this visitor in the produced code.
047: */
048: protected String name;
049:
050: /**
051: * The label names. This map associates String values to Label keys. It is
052: * used only in ASMifierMethodVisitor.
053: */
054: HashMap labelNames;
055:
056: /**
057: * Constructs a new {@link ASMifierAbstractVisitor}.
058: *
059: * @param name the name of the variable for this visitor in the produced
060: * code.
061: */
062: protected ASMifierAbstractVisitor(final String name) {
063: this .name = name;
064: }
065:
066: /**
067: * Prints the ASM code that generates the given annotation.
068: *
069: * @param desc the class descriptor of the annotation class.
070: * @param visible <tt>true</tt> if the annotation is visible at runtime.
071: * @return a visitor to visit the annotation values.
072: */
073: public AnnotationVisitor visitAnnotation(final String desc,
074: final boolean visible) {
075: buf.setLength(0);
076: buf.append("{\n").append("av0 = ").append(name).append(
077: ".visitAnnotation(");
078: appendConstant(desc);
079: buf.append(", ").append(visible).append(");\n");
080: text.add(buf.toString());
081: ASMifierAnnotationVisitor av = new ASMifierAnnotationVisitor(0);
082: text.add(av.getText());
083: text.add("}\n");
084: return av;
085: }
086:
087: /**
088: * Prints the ASM code that generates the given attribute.
089: *
090: * @param attr an attribute.
091: */
092: public void visitAttribute(final Attribute attr) {
093: buf.setLength(0);
094: if (attr instanceof ASMifiable) {
095: buf.append("{\n");
096: buf.append("// ATTRIBUTE\n");
097: ((ASMifiable) attr).asmify(buf, "attr", labelNames);
098: buf.append(name).append(".visitAttribute(attr);\n");
099: buf.append("}\n");
100: } else {
101: buf
102: .append("// WARNING! skipped a non standard attribute of type \"");
103: buf.append(attr.type).append("\"\n");
104: }
105: text.add(buf.toString());
106: }
107:
108: /**
109: * Prints the ASM code to end the visit.
110: */
111: public void visitEnd() {
112: buf.setLength(0);
113: buf.append(name).append(".visitEnd();\n");
114: text.add(buf.toString());
115: }
116:
117: /**
118: * Appends a string representation of the given constant to the given
119: * buffer.
120: *
121: * @param cst an {@link Integer}, {@link Float}, {@link Long},
122: * {@link Double} or {@link String} object. May be <tt>null</tt>.
123: */
124: void appendConstant(final Object cst) {
125: appendConstant(buf, cst);
126: }
127:
128: /**
129: * Appends a string representation of the given constant to the given
130: * buffer.
131: *
132: * @param buf a string buffer.
133: * @param cst an {@link Integer}, {@link Float}, {@link Long},
134: * {@link Double} or {@link String} object. May be <tt>null</tt>.
135: */
136: static void appendConstant(final StringBuffer buf, final Object cst) {
137: if (cst == null) {
138: buf.append("null");
139: } else if (cst instanceof String) {
140: appendString(buf, (String) cst);
141: } else if (cst instanceof Type) {
142: buf.append("Type.getType(\"");
143: buf.append(((Type) cst).getDescriptor());
144: buf.append("\")");
145: } else if (cst instanceof Byte) {
146: buf.append("new Byte((byte)").append(cst).append(")");
147: } else if (cst instanceof Boolean) {
148: buf.append("new Boolean(").append(cst).append(")");
149: } else if (cst instanceof Short) {
150: buf.append("new Short((short)").append(cst).append(")");
151: } else if (cst instanceof Character) {
152: int c = ((Character) cst).charValue();
153: buf.append("new Character((char)").append(c).append(")");
154: } else if (cst instanceof Integer) {
155: buf.append("new Integer(").append(cst).append(")");
156: } else if (cst instanceof Float) {
157: buf.append("new Float(\"").append(cst).append("\")");
158: } else if (cst instanceof Long) {
159: buf.append("new Long(").append(cst).append("L)");
160: } else if (cst instanceof Double) {
161: buf.append("new Double(\"").append(cst).append("\")");
162: } else if (cst instanceof byte[]) {
163: byte[] v = (byte[]) cst;
164: buf.append("new byte[] {");
165: for (int i = 0; i < v.length; i++) {
166: buf.append(i == 0 ? "" : ",").append(v[i]);
167: }
168: buf.append("}");
169: } else if (cst instanceof boolean[]) {
170: boolean[] v = (boolean[]) cst;
171: buf.append("new boolean[] {");
172: for (int i = 0; i < v.length; i++) {
173: buf.append(i == 0 ? "" : ",").append(v[i]);
174: }
175: buf.append("}");
176: } else if (cst instanceof short[]) {
177: short[] v = (short[]) cst;
178: buf.append("new short[] {");
179: for (int i = 0; i < v.length; i++) {
180: buf.append(i == 0 ? "" : ",").append("(short)").append(
181: v[i]);
182: }
183: buf.append("}");
184: } else if (cst instanceof char[]) {
185: char[] v = (char[]) cst;
186: buf.append("new char[] {");
187: for (int i = 0; i < v.length; i++) {
188: buf.append(i == 0 ? "" : ",").append("(char)").append(
189: (int) v[i]);
190: }
191: buf.append("}");
192: } else if (cst instanceof int[]) {
193: int[] v = (int[]) cst;
194: buf.append("new int[] {");
195: for (int i = 0; i < v.length; i++) {
196: buf.append(i == 0 ? "" : ",").append(v[i]);
197: }
198: buf.append("}");
199: } else if (cst instanceof long[]) {
200: long[] v = (long[]) cst;
201: buf.append("new long[] {");
202: for (int i = 0; i < v.length; i++) {
203: buf.append(i == 0 ? "" : ",").append(v[i]).append("L");
204: }
205: buf.append("}");
206: } else if (cst instanceof float[]) {
207: float[] v = (float[]) cst;
208: buf.append("new float[] {");
209: for (int i = 0; i < v.length; i++) {
210: buf.append(i == 0 ? "" : ",").append(v[i]).append("f");
211: }
212: buf.append("}");
213: } else if (cst instanceof double[]) {
214: double[] v = (double[]) cst;
215: buf.append("new double[] {");
216: for (int i = 0; i < v.length; i++) {
217: buf.append(i == 0 ? "" : ",").append(v[i]).append("d");
218: }
219: buf.append("}");
220: }
221: }
222: }
|