001: /***
002: * Retrotranslator: a Java bytecode transformer that translates Java classes
003: * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
004: *
005: * Copyright (c) 2005 - 2008 Taras Puchko
006: * All rights reserved.
007: *
008: * Redistribution and use in source and binary forms, with or without
009: * modification, are permitted provided that the following conditions
010: * are met:
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: * 2. Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: * 3. Neither the name of the copyright holders nor the names of its
017: * contributors may be used to endorse or promote products derived from
018: * this software without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
022: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
023: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
024: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
025: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
026: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
027: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
028: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
029: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
030: * THE POSSIBILITY OF SUCH DAMAGE.
031: */package net.sf.retrotranslator.transformer;
032:
033: import net.sf.retrotranslator.runtime.asm.*;
034:
035: /**
036: * @author Taras Puchko
037: */
038: abstract class GenericClassVisitor extends NameTranslator implements
039: ClassVisitor {
040:
041: private final ClassVisitor classVisitor;
042:
043: public GenericClassVisitor(ClassVisitor classVisitor) {
044: this .classVisitor = classVisitor;
045: }
046:
047: public void visit(int version, int access, String name,
048: String signature, String super Name, String[] interfaces) {
049: classVisitor.visit(version, access, typeName(name),
050: declarationSignature(signature), typeName(super Name),
051: typeNames(interfaces));
052: }
053:
054: public void visitSource(String source, String debug) {
055: classVisitor.visitSource(source, debug);
056: }
057:
058: public void visitOuterClass(String owner, String name, String desc) {
059: classVisitor.visitOuterClass(typeName(owner), identifier(name),
060: methodDescriptor(desc));
061: }
062:
063: public AnnotationVisitor visitAnnotation(String desc,
064: boolean visible) {
065: return wrap(classVisitor.visitAnnotation(typeDescriptor(desc),
066: visible));
067: }
068:
069: public void visitAttribute(Attribute attr) {
070: classVisitor.visitAttribute(attr);
071: }
072:
073: public void visitInnerClass(String name, String outerName,
074: String innerName, int access) {
075: classVisitor.visitInnerClass(typeName(name),
076: typeName(outerName), identifier(innerName), access);
077: }
078:
079: public FieldVisitor visitField(int access, String name,
080: String desc, String signature, Object value) {
081: FieldVisitor result = classVisitor.visitField(access,
082: identifier(name), typeDescriptor(desc),
083: typeSignature(signature), value);
084: return result == null ? null : new GenericFieldVisitor(result);
085: }
086:
087: public MethodVisitor visitMethod(int access, String name,
088: String desc, String signature, String[] exceptions) {
089: MethodVisitor result = classVisitor.visitMethod(access,
090: identifier(name), methodDescriptor(desc),
091: declarationSignature(signature), typeNames(exceptions));
092: return result == null ? null : new GenericMethodVisitor(result);
093: }
094:
095: protected void visitTypeInstruction(MethodVisitor visitor,
096: int opcode, String desc) {
097: visitor.visitTypeInsn(opcode, typeNameOrTypeDescriptor(desc));
098: }
099:
100: protected void visitFieldInstruction(MethodVisitor visitor,
101: int opcode, String owner, String name, String desc) {
102: visitor.visitFieldInsn(opcode, typeName(owner),
103: identifier(name), typeDescriptor(desc));
104: }
105:
106: protected void visitMethodInstruction(MethodVisitor visitor,
107: int opcode, String owner, String name, String desc) {
108: visitor.visitMethodInsn(opcode,
109: typeNameOrTypeDescriptor(owner), identifier(name),
110: methodDescriptor(desc));
111: }
112:
113: public void visitEnd() {
114: classVisitor.visitEnd();
115: }
116:
117: private AnnotationVisitor wrap(AnnotationVisitor av) {
118: return av == null ? null : new GenericAnnotationVisitor(av);
119: }
120:
121: private class GenericAnnotationVisitor implements AnnotationVisitor {
122:
123: private AnnotationVisitor annotationVisitor;
124:
125: public GenericAnnotationVisitor(
126: AnnotationVisitor annotationVisitor) {
127: this .annotationVisitor = annotationVisitor;
128: }
129:
130: public void visit(String name, Object value) {
131: annotationVisitor.visit(identifier(name),
132: typeOrValue(value));
133: }
134:
135: public void visitEnum(String name, String desc, String value) {
136: annotationVisitor.visitEnum(identifier(name),
137: typeDescriptor(desc), value);
138: }
139:
140: public AnnotationVisitor visitAnnotation(String name,
141: String desc) {
142: return wrap(annotationVisitor.visitAnnotation(
143: identifier(name), typeDescriptor(desc)));
144: }
145:
146: public AnnotationVisitor visitArray(String name) {
147: return wrap(annotationVisitor.visitArray(identifier(name)));
148: }
149:
150: public void visitEnd() {
151: annotationVisitor.visitEnd();
152: }
153: }
154:
155: private class GenericFieldVisitor implements FieldVisitor {
156:
157: private FieldVisitor fieldVisitor;
158:
159: public GenericFieldVisitor(FieldVisitor fieldVisitor) {
160: this .fieldVisitor = fieldVisitor;
161: }
162:
163: public AnnotationVisitor visitAnnotation(String desc,
164: boolean visible) {
165: return wrap(fieldVisitor.visitAnnotation(
166: typeDescriptor(desc), visible));
167: }
168:
169: public void visitAttribute(Attribute attr) {
170: fieldVisitor.visitAttribute(attr);
171: }
172:
173: public void visitEnd() {
174: fieldVisitor.visitEnd();
175: }
176: }
177:
178: private class GenericMethodVisitor extends AbstractMethodVisitor {
179:
180: private String deferredConstant;
181:
182: public GenericMethodVisitor(MethodVisitor visitor) {
183: super (visitor);
184: }
185:
186: protected void flush() {
187: if (deferredConstant != null) {
188: mv.visitLdcInsn(deferredConstant);
189: deferredConstant = null;
190: }
191: }
192:
193: public AnnotationVisitor visitAnnotationDefault() {
194: return wrap(super .visitAnnotationDefault());
195: }
196:
197: public AnnotationVisitor visitAnnotation(String desc,
198: boolean visible) {
199: return wrap(super .visitAnnotation(typeDescriptor(desc),
200: visible));
201: }
202:
203: public AnnotationVisitor visitParameterAnnotation(
204: int parameter, String desc, boolean visible) {
205: return wrap(super .visitParameterAnnotation(parameter,
206: typeDescriptor(desc), visible));
207: }
208:
209: public void visitTypeInsn(int opcode, String desc) {
210: flush();
211: visitTypeInstruction(mv, opcode, desc);
212: }
213:
214: public void visitFieldInsn(int opcode, String owner,
215: String name, String desc) {
216: flush();
217: visitFieldInstruction(mv, opcode, owner, name, desc);
218: }
219:
220: public void visitMethodInsn(int opcode, String owner,
221: String name, String desc) {
222: if (deferredConstant != null
223: && deferredConstant.indexOf('/') < 0
224: && opcode == Opcodes.INVOKESTATIC
225: && name.equals("class$")
226: && desc.equals(TransformerTools.descriptor(
227: Class.class, String.class))) {
228: deferredConstant = typeNameOrTypeDescriptor(
229: deferredConstant.replace('.', '/')).replace(
230: '/', '.');
231: }
232: flush();
233: visitMethodInstruction(mv, opcode, owner, name, desc);
234: }
235:
236: public void visitLdcInsn(Object cst) {
237: flush();
238: if (cst instanceof String) {
239: deferredConstant = (String) cst;
240: } else {
241: mv.visitLdcInsn(typeOrValue(cst));
242: }
243: }
244:
245: public void visitMultiANewArrayInsn(String desc, int dims) {
246: super .visitMultiANewArrayInsn(typeDescriptor(desc), dims);
247: }
248:
249: public void visitTryCatchBlock(Label start, Label end,
250: Label handler, String type) {
251: super .visitTryCatchBlock(start, end, handler,
252: typeName(type));
253: }
254:
255: public void visitLocalVariable(String name, String desc,
256: String signature, Label start, Label end, int index) {
257: super.visitLocalVariable(identifier(name),
258: typeDescriptor(desc), typeSignature(signature),
259: start, end, index);
260: }
261: }
262:
263: }
|