OSDN Git Service

プラットフォームごとのStigmataのホームディレクトリの場所を返す一連のクラスをリファクタリングした.
[stigmata/stigmata.git] / src / main / java / jp / sourceforge / stigmata / birthmarks / uc / UsedClassesBirthmarkExtractVisitor.java
1 package jp.sourceforge.stigmata.birthmarks.uc;
2
3 /*
4  * $Id$
5  */
6
7 import jp.sourceforge.stigmata.Birthmark;
8 import jp.sourceforge.stigmata.BirthmarkContext;
9 import jp.sourceforge.stigmata.BirthmarkElement;
10 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
11
12 import org.objectweb.asm.ClassVisitor;
13 import org.objectweb.asm.FieldVisitor;
14 import org.objectweb.asm.Label;
15 import org.objectweb.asm.MethodAdapter;
16 import org.objectweb.asm.MethodVisitor;
17 import org.objectweb.asm.Type;
18 import org.objectweb.asm.signature.SignatureReader;
19 import org.objectweb.asm.signature.SignatureWriter;
20
21 /**
22  *
23  * @author Haruaki TAMADA
24  * @version $Revision$ 
25  */
26 public class UsedClassesBirthmarkExtractVisitor extends BirthmarkExtractVisitor{
27     public UsedClassesBirthmarkExtractVisitor(ClassVisitor visitor, Birthmark birthmark,
28             BirthmarkContext context){
29         super(visitor, birthmark, context);
30     }
31
32     @Override
33     public void visit(int version, int access, String name, String signature,
34             String superName, String[] interfaces){
35         addSignatureClass(signature);
36
37         if(getEnvironment().getWellknownClassManager().isWellKnownClass(superName)){
38             add(superName);
39         }
40         for(String i: interfaces){
41             if(getEnvironment().getWellknownClassManager().isWellKnownClass(i)){
42                 add(i);
43             }
44         }
45     }
46
47     @Override
48     public FieldVisitor visitField(int access, String name, String desc,
49             String signature, Object value){
50         FieldVisitor visitor = super.visitField(access, name, desc, signature, value);
51
52         addDescriptor(desc);
53         addSignatureClass(signature);
54
55         return visitor;
56     }
57
58     @Override
59     public MethodVisitor visitMethod(int access, String name, String desc,
60                                      String signature, String[] exceptions){
61         if(exceptions != null){
62             for(String exception: exceptions){
63                 if(getEnvironment().getWellknownClassManager().isWellKnownClass(exception)){
64                     add(exception);
65                 }
66             }
67         }
68         addMethodDescriptor(desc);
69         addSignatureClass(signature);
70
71         MethodVisitor visitor = super.visitMethod(access, name, desc, signature, exceptions);
72
73         return new MethodAdapter(visitor){
74             @Override
75             public void visitTypeInsn(int opcode, String desc){
76                 Type type = Type.getType("L" + desc + ";");
77                 if(checkType(type)){
78                     add(desc);
79                 }
80                 super.visitTypeInsn(opcode, desc);
81             }
82
83             @Override
84             public void visitTryCatchBlock(Label start, Label end, Label handle, String desc){
85                 Type type = Type.getType("L" + desc + ";");
86                 if(checkType(type)){
87                     add(getType(type));
88                 }
89                 super.visitTryCatchBlock(start, end, handle, desc);
90             }
91
92             @Override
93             public void visitMultiANewArrayInsn(String desc, int dims){
94                 Type type = Type.getType(desc);
95                 if(checkType(type)){
96                     add(getType(type));
97                 }
98                 super.visitMultiANewArrayInsn(desc, dims);
99             }
100
101             @Override
102             public void visitLocalVariable(String name, String desc, String signature,
103                                            Label start, Label end, int index){
104                 if(checkType(Type.getType(desc))){
105                     add(desc);
106                 }
107                 addSignatureClass(signature);
108
109                 super.visitLocalVariable(name, desc, signature, start, end, index);
110             }
111
112             @Override
113             public void visitFieldInsn(int opcode, String owner, String name, String desc){
114                 if(getEnvironment().getWellknownClassManager().isWellKnownClass(owner)){
115                     add(owner);
116                 }
117                 addDescriptor(desc);
118                 super.visitFieldInsn(opcode, owner, name, desc);
119             }
120             @Override
121             public void visitMethodInsn(int opcode, String owner, String name, String desc){
122                 String className = normalize(owner);
123                 if(getEnvironment().getWellknownClassManager().isWellKnownClass(className)){
124                     add(className);
125                 }
126                 addMethodDescriptor(desc);
127                 super.visitMethodInsn(opcode, owner, name, desc);
128             }
129         };
130     }
131
132     private void addSignatureClass(String signature){
133         if(signature != null){
134             SignatureReader in = new SignatureReader(signature);
135             SignatureWriter writer = new SignatureWriter(){
136                 @Override
137                 public void visitClassType(String classType){
138                     if(getEnvironment().getWellknownClassManager().isWellKnownClass(classType)){
139                         add(classType);
140                     }
141                 }
142             };
143             in.accept(writer);
144         }
145     }
146
147     private void addMethodDescriptor(String desc){
148         Type returnType = Type.getReturnType(desc);
149         Type[] args = Type.getArgumentTypes(desc);
150         if(checkType(returnType)){
151             add(getType(returnType));
152         }
153         for(Type arg: args){
154             if(checkType(arg)){
155                 add(getType(arg));
156             }
157         }
158     }
159
160     private void addDescriptor(String desc){
161         Type type = Type.getType(desc);
162         if(checkType(type)){
163             add(desc);
164         }
165     }
166
167     private String getType(Type type){
168         if(type.getSort() == Type.ARRAY){
169             while(type.getSort() != Type.ARRAY){
170                 type = type.getElementType();
171             }
172         }
173
174         if(type.getSort() == Type.OBJECT){
175             return normalize(type.getClassName());
176         }
177
178         return null;
179     }
180
181     private boolean checkType(Type type){
182         if(type.getSort() == Type.ARRAY){
183             while(type.getSort() != Type.ARRAY){
184                 type = type.getElementType();
185             }
186         }
187
188         if(type.getSort() == Type.OBJECT){
189             String className = type.getClassName();
190             if(getEnvironment().getWellknownClassManager().isWellKnownClass(className)){
191                 return true;
192             }
193         }
194         return false;
195     }
196
197     private String normalize(String name){
198         if(name.startsWith("L") && name.endsWith(";")){
199             name = name.substring(1, name.length() - 1);
200         }
201         name = name.replace('/', '.');
202
203         return name;
204     }
205
206     private void add(String name){
207         addElement(new BirthmarkElement(normalize(name)));
208     }
209 }