KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tonicsystems > jarjar > DepKillTransformer


1 /*
2   Jar Jar Links - A utility to repackage and embed Java libraries
3   Copyright (C) 2004 Tonic Systems, Inc.
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; see the file COPYING. if not, write to
17   the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18   Boston, MA 02111-1307 USA
19 */

20
21 package com.tonicsystems.jarjar;
22
23 import com.tonicsystems.jarjar.util.*;
24 import java.util.*;
25 import org.objectweb.asm.Attribute;
26 import org.objectweb.asm.ClassAdapter;
27 import org.objectweb.asm.ClassVisitor;
28 import org.objectweb.asm.FieldVisitor;
29 import org.objectweb.asm.Label;
30 import org.objectweb.asm.MethodAdapter;
31 import org.objectweb.asm.MethodVisitor;
32 import org.objectweb.asm.Opcodes;
33 import org.objectweb.asm.Type;
34
35 // TODO: annotations
36
class DepKillTransformer extends ClassAdapter implements ClassTransformer
37 {
38     private static final Type TYPE_OBJECT = Type.getType(Object JavaDoc.class);
39     private Wildcard[] wildcards;
40
41     public DepKillTransformer(List patterns) {
42         super(null);
43         wildcards = PatternElement.createWildcards(patterns);
44     }
45
46     public void setTarget(ClassVisitor target) {
47         cv = target;
48     }
49
50     private boolean checkDesc(String JavaDoc desc) {
51         for (int i = 0; i < wildcards.length; i++) {
52             if (wildcards[i].matches(desc, Wildcard.STYLE_DESC))
53                 return true;
54         }
55         return false;
56     }
57
58     private String JavaDoc fixMethodDesc(String JavaDoc methodDesc) {
59         if (wildcards.length == 0)
60             return methodDesc;
61         Type[] args = Type.getArgumentTypes(methodDesc);
62         for (int i = 0; i < args.length; i++)
63             args[i] = eraseType(args[i]);
64         return Type.getMethodDescriptor(eraseType(Type.getReturnType(methodDesc)), args);
65     }
66
67     private Type eraseType(Type type) {
68         return checkDesc(type.getDescriptor()) ? TYPE_OBJECT : type;
69     }
70
71     private boolean checkName(String JavaDoc name) {
72         if (wildcards.length == 0)
73             return false;
74         return checkDesc("L" + name + ";");
75     }
76
77     private static void replace(MethodVisitor mv, String JavaDoc desc) {
78         switch (desc.charAt(0)) {
79         case 'V':
80             break;
81         case 'D':
82             mv.visitInsn(Opcodes.DCONST_0);
83             break;
84         case 'F':
85             mv.visitInsn(Opcodes.FCONST_0);
86             break;
87         case 'J':
88             mv.visitInsn(Opcodes.LCONST_0);
89             break;
90         case 'C':
91         case 'S':
92         case 'B':
93         case 'I':
94         case 'Z':
95             mv.visitInsn(Opcodes.ICONST_0);
96             break;
97         case 'L':
98         case '[':
99             mv.visitInsn(Opcodes.ACONST_NULL);
100             break;
101         }
102     }
103
104     private static void pop(MethodVisitor mv, String JavaDoc desc) {
105         switch (desc.charAt(0)) {
106         case 'D':
107         case 'J':
108             mv.visitInsn(Opcodes.POP2);
109         default:
110             mv.visitInsn(Opcodes.POP);
111         }
112     }
113                 
114     public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
115         if (exceptions != null && wildcards.length > 0) {
116             List exceptionList = new ArrayList(exceptions.length);
117             for (int i = 0; i < exceptions.length; i++) {
118                 if (!checkName(exceptions[i]))
119                     exceptionList.add(exceptions[i]);
120             }
121             exceptions = (String JavaDoc[])exceptionList.toArray(new String JavaDoc[exceptionList.size()]);
122         }
123         return new DepKillMethodVisitor(cv.visitMethod(access, name, fixMethodDesc(desc), signature, exceptions));
124     }
125
126     public FieldVisitor visitField(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, Object JavaDoc value) {
127         if (checkDesc(desc)) {
128             // System.err.println("visitField " + desc);
129
desc = TYPE_OBJECT.getDescriptor();
130         }
131         return super.visitField(access, name, desc, signature, value);
132     }
133
134     private class DepKillMethodVisitor extends MethodAdapter
135     {
136         public DepKillMethodVisitor(MethodVisitor mv) {
137             super(mv);
138         }
139
140         public void visitTypeInsn(int opcode, String JavaDoc desc) {
141             if ((desc.charAt(0) == '[') ? checkDesc(desc) : checkName(desc)) {
142                 // System.err.println("visitTypeInsn " + desc);
143
switch (opcode) {
144                 case Opcodes.NEW:
145                 case Opcodes.ANEWARRAY:
146                     mv.visitInsn(Opcodes.ACONST_NULL);
147                     break;
148                 case Opcodes.CHECKCAST:
149                 case Opcodes.INSTANCEOF:
150                     mv.visitInsn(Opcodes.ICONST_0);
151                     break;
152                 }
153             } else {
154                 mv.visitTypeInsn(opcode, desc);
155             }
156         }
157
158         public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
159             if (checkName(owner) || checkDesc(desc)) {
160                 // System.err.println("visitFieldInsn " + owner + ", " + desc);
161
switch (opcode) {
162                 case Opcodes.GETFIELD:
163                     mv.visitInsn(Opcodes.POP);
164                     replace(mv, desc);
165                     break;
166                 case Opcodes.PUTFIELD:
167                     pop(mv, desc);
168                     mv.visitInsn(Opcodes.POP);
169                     break;
170                 case Opcodes.GETSTATIC:
171                     replace(mv, desc);
172                     break;
173                 case Opcodes.PUTSTATIC:
174                     pop(mv, desc);
175                     break;
176                 }
177             } else {
178                 mv.visitFieldInsn(opcode, owner, name, desc);
179             }
180         }
181
182         public void visitMethodInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
183             if (checkName(owner)) {
184                 // System.err.println("visitMethodInsn " + owner + ", " + desc + " (" + name + ")");
185
switch (opcode) {
186                 case Opcodes.INVOKEINTERFACE:
187                 case Opcodes.INVOKEVIRTUAL:
188                     mv.visitInsn(Opcodes.POP);
189                     break;
190                 case Opcodes.INVOKESPECIAL:
191                     throw new IllegalStateException JavaDoc("Cannot remove invocation of " + owner + "." + desc);
192                 case Opcodes.INVOKESTATIC:
193                 }
194
195                 Type[] args = Type.getArgumentTypes(desc);
196                 for (int i = 0; i < args.length; i++)
197                     mv.visitInsn((args[i].getSize() == 2) ? Opcodes.POP2 : Opcodes.POP);
198                 replace(mv, Type.getReturnType(desc).getDescriptor());
199
200             } else {
201                 mv.visitMethodInsn(opcode, owner, name, fixMethodDesc(desc));
202             }
203         }
204
205         public void visitMultiANewArrayInsn(String JavaDoc desc, int dims) {
206             if (checkDesc(desc)) {
207                 // System.err.println("visitMultiANewArrayInsn " + desc);
208
mv.visitInsn(Opcodes.ACONST_NULL);
209             } else {
210                 mv.visitMultiANewArrayInsn(desc, dims);
211             }
212         }
213
214         public void visitTryCatchBlock(Label start, Label end, Label handler, String JavaDoc type) {
215             if (!checkName(type))
216                 mv.visitTryCatchBlock(start, end, handler, type);
217         }
218
219         public void visitLocalVariable(String JavaDoc name, String JavaDoc desc, String JavaDoc signature, Label start, Label end, int index) {
220             if (checkDesc(desc)) {
221                 // System.err.println("visitLocalVariable " + desc);
222
desc = TYPE_OBJECT.getDescriptor();
223             }
224             mv.visitLocalVariable(name, desc, signature, start, end, index);
225         }
226
227         public void visitAttribute(Attribute attr) {
228             mv.visitAttribute(attr);
229         }
230     }
231 }
232
Popular Tags