KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > classfile > ProgramClass


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.classfile;
22
23 import proguard.classfile.util.*;
24 import proguard.classfile.visitor.*;
25 import proguard.classfile.attribute.*;
26 import proguard.classfile.attribute.visitor.AttributeVisitor;
27 import proguard.classfile.constant.*;
28 import proguard.classfile.constant.visitor.ConstantVisitor;
29
30 /**
31  * This Clazz is a complete representation of the data in a Java class.
32  *
33  * @author Eric Lafortune
34  */

35 public class ProgramClass implements Clazz
36 {
37     public int u4magic;
38     public int u4version;
39     public int u2constantPoolCount;
40     public Constant[] constantPool;
41     public int u2accessFlags;
42     public int u2thisClass;
43     public int u2superClass;
44     public int u2interfacesCount;
45     public int[] u2interfaces;
46     public int u2fieldsCount;
47     public ProgramField[] fields;
48     public int u2methodsCount;
49     public ProgramMethod[] methods;
50     public int u2attributesCount;
51     public Attribute[] attributes;
52
53     /**
54      * An extra field pointing to the subclasses of this class.
55      * This field is filled out by the {@link ClassSubHierarchyInitializer}.
56      */

57     public Clazz[] subClasses;
58
59     /**
60      * An extra field in which visitors can store information.
61      */

62     public Object JavaDoc visitorInfo;
63
64
65     /**
66      * Creates an uninitialized ProgramClass.
67      */

68     public ProgramClass() {}
69
70
71     /**
72      * Returns the Constant at the given index in the constant pool.
73      */

74     public Constant getConstant(int constantIndex)
75     {
76         return constantPool[constantIndex];
77     }
78
79
80     // Implementations for Clazz.
81

82     public int getAccessFlags()
83     {
84         return u2accessFlags;
85     }
86
87     public String JavaDoc getName()
88     {
89         return getClassName(u2thisClass);
90     }
91
92     public String JavaDoc getSuperName()
93     {
94         return u2superClass == 0 ? null : getClassName(u2superClass);
95     }
96
97     public int getInterfaceCount()
98     {
99         return u2interfacesCount;
100     }
101
102     public String JavaDoc getInterfaceName(int index)
103     {
104         return getClassName(u2interfaces[index]);
105     }
106
107     public int getTag(int constantIndex)
108     {
109         return constantPool[constantIndex].getTag();
110     }
111
112     public String JavaDoc getString(int constantIndex)
113     {
114         try
115         {
116             return ((Utf8Constant)constantPool[constantIndex]).getString();
117         }
118         catch (ClassCastException JavaDoc ex)
119         {
120             new ClassPrinter().visitProgramClass(this);
121             throw new ClassCastException JavaDoc("Expected Utf8Constant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
122         }
123     }
124
125     public String JavaDoc getStringString(int constantIndex)
126     {
127         try
128         {
129             return ((StringConstant)constantPool[constantIndex]).getString(this);
130         }
131         catch (ClassCastException JavaDoc ex)
132         {
133             throw new ClassCastException JavaDoc("Expected StringConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
134         }
135     }
136
137     public String JavaDoc getClassName(int constantIndex)
138     {
139         try
140         {
141             return ((ClassConstant)constantPool[constantIndex]).getName(this);
142         }
143         catch (ClassCastException JavaDoc ex)
144         {
145             throw new ClassCastException JavaDoc("Expected ClassConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
146         }
147     }
148
149     public String JavaDoc getName(int constantIndex)
150     {
151         try
152         {
153             return ((NameAndTypeConstant)constantPool[constantIndex]).getName(this);
154         }
155         catch (ClassCastException JavaDoc ex)
156         {
157             throw new ClassCastException JavaDoc("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
158         }
159     }
160
161     public String JavaDoc getType(int constantIndex)
162     {
163         try
164         {
165             return ((NameAndTypeConstant)constantPool[constantIndex]).getType(this);
166         }
167         catch (ClassCastException JavaDoc ex)
168         {
169             throw new ClassCastException JavaDoc("Expected NameAndTypeConstant at index ["+constantIndex+"] in class ["+getName()+"], found ["+ex.getMessage()+"]");
170         }
171     }
172
173
174     public void addSubClass(Clazz clazz)
175     {
176         if (subClasses == null)
177         {
178             subClasses = new Clazz[1];
179         }
180         else
181         {
182             // Copy the old elements into new larger array.
183
Clazz[] temp = new Clazz[subClasses.length+1];
184             System.arraycopy(subClasses, 0, temp, 0, subClasses.length);
185             subClasses = temp;
186         }
187
188         subClasses[subClasses.length-1] = clazz;
189     }
190
191
192     public Clazz getSuperClass()
193     {
194         return u2superClass != 0 ?
195             ((ClassConstant)constantPool[u2superClass]).referencedClass :
196             null;
197     }
198
199
200     public Clazz getInterface(int index)
201     {
202         return ((ClassConstant)constantPool[u2interfaces[index]]).referencedClass;
203     }
204
205
206     public boolean extends_(Clazz clazz)
207     {
208         if (this.equals(clazz))
209         {
210             return true;
211         }
212
213         Clazz superClass = getSuperClass();
214         return superClass != null &&
215                superClass.extends_(clazz);
216     }
217
218
219     public boolean extendsOrImplements(Clazz clazz)
220     {
221         if (this.equals(clazz))
222         {
223             return true;
224         }
225
226         Clazz superClass = getSuperClass();
227         if (superClass != null &&
228             superClass.extendsOrImplements(clazz))
229         {
230             return true;
231         }
232
233         for (int index = 0; index < u2interfacesCount; index++)
234         {
235             Clazz interfaceClass = getInterface(index);
236             if (interfaceClass != null &&
237                 interfaceClass.extendsOrImplements(clazz))
238             {
239                 return true;
240             }
241         }
242
243         return false;
244     }
245
246
247     public Field findField(String JavaDoc name, String JavaDoc descriptor)
248     {
249         for (int index = 0; index < u2fieldsCount; index++)
250         {
251             Field field = fields[index];
252             if ((name == null || field.getName(this).equals(name)) &&
253                 (descriptor == null || field.getDescriptor(this).equals(descriptor)))
254             {
255                 return field;
256             }
257         }
258
259         return null;
260     }
261
262
263     public Method findMethod(String JavaDoc name, String JavaDoc descriptor)
264     {
265         for (int index = 0; index < u2methodsCount; index++)
266         {
267             Method method = methods[index];
268             if ((name == null || method.getName(this).equals(name)) &&
269                 (descriptor == null || method.getDescriptor(this).equals(descriptor)))
270             {
271                 return method;
272             }
273         }
274
275         return null;
276     }
277
278
279     public void accept(ClassVisitor classVisitor)
280     {
281         classVisitor.visitProgramClass(this);
282     }
283
284
285     public void hierarchyAccept(boolean visitThisClass,
286                                 boolean visitSuperClass,
287                                 boolean visitInterfaces,
288                                 boolean visitSubclasses,
289                                 ClassVisitor classVisitor)
290     {
291         // First visit the current classfile.
292
if (visitThisClass)
293         {
294             accept(classVisitor);
295         }
296
297         // Then visit its superclass, recursively.
298
if (visitSuperClass)
299         {
300             Clazz superClass = getSuperClass();
301             if (superClass != null)
302             {
303                 superClass.hierarchyAccept(true,
304                                            true,
305                                            visitInterfaces,
306                                            false,
307                                            classVisitor);
308             }
309         }
310
311         // Then visit its interfaces, recursively.
312
if (visitInterfaces)
313         {
314             for (int index = 0; index < u2interfacesCount; index++)
315             {
316                 Clazz interfaceClass = getInterface(index);
317                 if (interfaceClass != null)
318                 {
319                     interfaceClass.hierarchyAccept(true,
320                                                    true,
321                                                    true,
322                                                    false,
323                                                    classVisitor);
324                 }
325             }
326         }
327
328         // Then visit its subclasses, recursively.
329
if (visitSubclasses)
330         {
331             if (subClasses != null)
332             {
333                 for (int index = 0; index < subClasses.length; index++)
334                 {
335                     Clazz subClass = subClasses[index];
336                     subClass.hierarchyAccept(true,
337                                              false,
338                                              false,
339                                              true,
340                                              classVisitor);
341                 }
342             }
343         }
344     }
345
346
347     public void constantPoolEntriesAccept(ConstantVisitor constantVisitor)
348     {
349         for (int index = 1; index < u2constantPoolCount; index++)
350         {
351             if (constantPool[index] != null)
352             {
353                 constantPool[index].accept(this, constantVisitor);
354             }
355         }
356     }
357
358
359     public void constantPoolEntryAccept(int index, ConstantVisitor constantVisitor)
360     {
361         constantPool[index].accept(this, constantVisitor);
362     }
363
364
365     public void fieldsAccept(MemberVisitor memberVisitor)
366     {
367         for (int index = 0; index < u2fieldsCount; index++)
368         {
369             fields[index].accept(this, memberVisitor);
370         }
371     }
372
373
374     public void fieldAccept(String JavaDoc name, String JavaDoc descriptor, MemberVisitor memberVisitor)
375     {
376         Field field = findField(name, descriptor);
377         if (field != null)
378         {
379             field.accept(this, memberVisitor);
380         }
381     }
382
383
384     public void methodsAccept(MemberVisitor memberVisitor)
385     {
386         for (int index = 0; index < u2methodsCount; index++)
387         {
388             methods[index].accept(this, memberVisitor);
389         }
390     }
391
392
393     public void methodAccept(String JavaDoc name, String JavaDoc descriptor, MemberVisitor memberVisitor)
394     {
395         Method method = findMethod(name, descriptor);
396         if (method != null)
397         {
398             method.accept(this, memberVisitor);
399         }
400     }
401
402
403     public boolean mayHaveImplementations(Method method)
404     {
405         return
406             (u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) == 0 &&
407             (method == null ||
408              ((method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE |
409                                           ClassConstants.INTERNAL_ACC_STATIC |
410                                           ClassConstants.INTERNAL_ACC_FINAL)) == 0 &&
411               !method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT)));
412     }
413
414
415     private boolean isSpecial(Method method)
416     {
417         return
418             (method.getAccessFlags() & (ClassConstants.INTERNAL_ACC_PRIVATE |
419                                         ClassConstants.INTERNAL_ACC_STATIC)) != 0 ||
420             method.getName(this).equals(ClassConstants.INTERNAL_METHOD_NAME_INIT);
421     }
422
423
424     public void methodImplementationsAccept(Method method,
425                                             boolean visitThisMethod,
426                                             MemberVisitor memberVisitor)
427     {
428         methodImplementationsAccept(method.getName(this),
429                                     method.getDescriptor(this),
430                                     method,
431                                     visitThisMethod,
432                                     true,
433                                     true,
434                                     true,
435                                     memberVisitor);
436     }
437
438
439     public void methodImplementationsAccept(String JavaDoc name,
440                                             String JavaDoc descriptor,
441                                             boolean visitThisMethod,
442                                             MemberVisitor memberVisitor)
443     {
444         methodImplementationsAccept(name,
445                                     descriptor,
446                                     visitThisMethod,
447                                     true,
448                                     true,
449                                     true,
450                                     memberVisitor);
451     }
452
453
454     public void methodImplementationsAccept(String JavaDoc name,
455                                             String JavaDoc descriptor,
456                                             boolean visitThisMethod,
457                                             boolean visitSpecialMethods,
458                                             boolean visitSuperMethods,
459                                             boolean visitOverridingMethods,
460                                             MemberVisitor memberVisitor)
461     {
462         methodImplementationsAccept(name,
463                                     descriptor,
464                                     findMethod(name, descriptor),
465                                     visitThisMethod,
466                                     visitSpecialMethods,
467                                     visitSuperMethods,
468                                     visitOverridingMethods,
469                                     memberVisitor);
470     }
471
472
473     public void methodImplementationsAccept(String JavaDoc name,
474                                             String JavaDoc descriptor,
475                                             Method method,
476                                             boolean visitThisMethod,
477                                             boolean visitSpecialMethods,
478                                             boolean visitSuperMethods,
479                                             boolean visitOverridingMethods,
480                                             MemberVisitor memberVisitor)
481     {
482         // Do we have the method in this class?
483
if (method != null)
484         {
485             // Is it a special method?
486
if (isSpecial(method))
487             {
488                 // Visit the special method in this class, if allowed.
489
if (visitSpecialMethods)
490                 {
491                     method.accept(this, memberVisitor);
492
493                     // The method can't have any other implementations.
494
return;
495                 }
496             }
497             else
498             {
499                 // Visit the method in this class, if allowed.
500
if (visitThisMethod)
501                 {
502                     method.accept(this, memberVisitor);
503                 }
504
505                 // We don't have to look in subclasses if there can't be
506
// any overriding implementations.
507
if (!mayHaveImplementations(method))
508                 {
509                     visitOverridingMethods = false;
510                 }
511
512                 // We don't have to look in superclasses if we have a concrete
513
// implementation here.
514
if ((method.getAccessFlags() & ClassConstants.INTERNAL_ACC_ABSTRACT) == 0)
515                 {
516                     visitSuperMethods = false;
517                 }
518             }
519         }
520
521         // Then visit the method in its subclasses, recursively.
522
if (visitOverridingMethods)
523         {
524             // Go looking for implementations in all of the subclasses.
525
if (subClasses != null)
526             {
527                 for (int index = 0; index < subClasses.length; index++)
528                 {
529                     Clazz subClass = subClasses[index];
530                     subClass.methodImplementationsAccept(name,
531                                                          descriptor,
532                                                          true,
533                                                          false,
534                                                          visitSuperMethods,
535                                                          true,
536                                                          memberVisitor);
537                 }
538             }
539
540             // We don't have to look in superclasses right away if we dont't
541
// have a concrete class here.
542
if ((u2accessFlags & (ClassConstants.INTERNAL_ACC_INTERFACE |
543                                   ClassConstants.INTERNAL_ACC_ABSTRACT)) != 0)
544             {
545                 visitSuperMethods = false;
546             }
547         }
548
549         // Then visit the method in its superclass, recursively.
550
if (visitSuperMethods)
551         {
552             Clazz superClass = getSuperClass();
553             if (superClass != null)
554             {
555                 superClass.methodImplementationsAccept(name,
556                                                        descriptor,
557                                                        true,
558                                                        false,
559                                                        true,
560                                                        false,
561                                                        memberVisitor);
562             }
563         }
564     }
565
566
567     public void attributesAccept(AttributeVisitor attributeVisitor)
568     {
569         for (int index = 0; index < u2attributesCount; index++)
570         {
571             attributes[index].accept(this, attributeVisitor);
572         }
573     }
574
575
576     // Implementations for VisitorAccepter.
577

578     public Object JavaDoc getVisitorInfo()
579     {
580         return visitorInfo;
581     }
582
583     public void setVisitorInfo(Object JavaDoc visitorInfo)
584     {
585         this.visitorInfo = visitorInfo;
586     }
587 }
588
Popular Tags