KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > optimize > peephole > ClassFinalizer


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2003 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program 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 program 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 General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.optimize.peephole;
22
23 import proguard.classfile.*;
24 import proguard.classfile.util.*;
25 import proguard.classfile.visitor.*;
26 import proguard.optimize.KeepMarker;
27
28 /**
29  * This <code>ClassVisitor</code> and <code>MemberVisitor</code>
30  * makes the classes it visits, and their methods, final, if possible.
31  *
32  * @author Eric Lafortune
33  */

34 public class ClassFinalizer
35 extends SimplifiedVisitor
36 implements ClassVisitor,
37              MemberVisitor
38 {
39     private ClassVisitor extraClassVisitor;
40     private MemberVisitor extraMemberVisitor;
41
42     private MemberFinder memberFinder = new MemberFinder();
43
44
45     /**
46      * Creates a new ClassFinalizer.
47      */

48     public ClassFinalizer()
49     {
50         this(null, null);
51     }
52
53
54     /**
55      * Creates a new ClassFinalizer.
56      * @param extraClassVisitor an optional extra visitor for all finalized
57      * classes.
58      * @param extraMemberVisitor an optional extra visitor for all finalized
59      * methods.
60      */

61     public ClassFinalizer(ClassVisitor extraClassVisitor,
62                           MemberVisitor extraMemberVisitor)
63     {
64         this.extraClassVisitor = extraClassVisitor;
65         this.extraMemberVisitor = extraMemberVisitor;
66     }
67
68
69     // Implementations for ClassVisitor.
70

71     public void visitProgramClass(ProgramClass programClass)
72     {
73         // If the class is not final/interface/abstract,
74
// and it is not being kept,
75
// and it doesn't have any subclasses,
76
// then make it final.
77
if ((programClass.u2accessFlags & (ClassConstants.INTERNAL_ACC_FINAL |
78                                            ClassConstants.INTERNAL_ACC_INTERFACE |
79                                            ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
80             !KeepMarker.isKept(programClass) &&
81             programClass.subClasses == null)
82         {
83             programClass.u2accessFlags |= ClassConstants.INTERNAL_ACC_FINAL;
84
85             // Visit the class, if required.
86
if (extraClassVisitor != null)
87             {
88                 extraClassVisitor.visitProgramClass(programClass);
89             }
90         }
91
92         // Check all methods.
93
programClass.methodsAccept(this);
94     }
95
96
97     // Implementations for MemberVisitor.
98

99     public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
100     {
101         String JavaDoc name = programMethod.getName(programClass);
102
103         // If the method is not already private/static/final/abstract,
104
// and it is not a constructor,
105
// and its class is final,
106
// or it is not being kept and it is not overridden,
107
// then make it final.
108
if ((programMethod.u2accessFlags & (ClassConstants.INTERNAL_ACC_PRIVATE |
109                                             ClassConstants.INTERNAL_ACC_STATIC |
110                                             ClassConstants.INTERNAL_ACC_FINAL |
111                                             ClassConstants.INTERNAL_ACC_ABSTRACT)) == 0 &&
112             !name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) &&
113             ((programClass.u2accessFlags & ClassConstants.INTERNAL_ACC_FINAL) != 0 ||
114              (!KeepMarker.isKept(programMethod) &&
115               (programClass.subClasses == null ||
116                !memberFinder.isOverriden(programClass, programMethod)))))
117         {
118             programMethod.u2accessFlags |= ClassConstants.INTERNAL_ACC_FINAL;
119
120             // Visit the method, if required.
121
if (extraMemberVisitor != null)
122             {
123                 extraMemberVisitor.visitProgramMethod(programClass, programMethod);
124             }
125         }
126     }
127 }
128
Popular Tags