KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > AssignedFieldMap


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003,2004 University of Maryland
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  */

19
20 package edu.umd.cs.findbugs.ba;
21
22 import java.util.HashSet JavaDoc;
23 import java.util.IdentityHashMap JavaDoc;
24 import java.util.Map JavaDoc;
25 import java.util.Set JavaDoc;
26
27 import org.apache.bcel.Constants;
28 import org.apache.bcel.classfile.Field;
29 import org.apache.bcel.classfile.JavaClass;
30 import org.apache.bcel.classfile.Method;
31 import org.apache.bcel.generic.ConstantPoolGen;
32 import org.apache.bcel.generic.Instruction;
33 import org.apache.bcel.generic.InstructionHandle;
34 import org.apache.bcel.generic.InstructionList;
35 import org.apache.bcel.generic.MethodGen;
36 import org.apache.bcel.generic.PUTFIELD;
37
38 public class AssignedFieldMap implements Constants {
39     private final ClassContext classContext;
40     private final Map JavaDoc<Method, Set JavaDoc<XField>> assignedFieldSetForMethodMap;
41
42     public AssignedFieldMap(ClassContext classContext) {
43         this.classContext = classContext;
44         this.assignedFieldSetForMethodMap = new IdentityHashMap JavaDoc<Method, Set JavaDoc<XField>>();
45     }
46
47     public void build() throws ClassNotFoundException JavaDoc {
48         JavaClass jclass = classContext.getJavaClass();
49
50         // Build a set of all fields that could be assigned
51
// by methods in this class
52
Set JavaDoc<XField> assignableFieldSet = new HashSet JavaDoc<XField>();
53         scanFields(jclass, assignableFieldSet);
54         JavaClass[] superClassList = jclass.getSuperClasses();
55         if (superClassList != null) {
56             for (JavaClass aSuperClassList : superClassList) {
57                 scanFields(aSuperClassList, assignableFieldSet);
58             }
59         }
60
61         Method[] methodList = jclass.getMethods();
62         for (Method method : methodList) {
63             MethodGen methodGen = classContext.getMethodGen(method);
64             if (methodGen == null)
65                 continue;
66
67             scanMethod(method, assignableFieldSet);
68         }
69     }
70
71     public Set JavaDoc<XField> getAssignedFieldSetForMethod(Method method) {
72         Set JavaDoc<XField> set = assignedFieldSetForMethodMap.get(method);
73         if (set == null) {
74             set = new HashSet JavaDoc<XField>();
75             assignedFieldSetForMethodMap.put(method, set);
76         }
77         return set;
78     }
79
80     private void scanFields(JavaClass jclass, Set JavaDoc<XField> assignableFieldSet) {
81         JavaClass myClass = classContext.getJavaClass();
82         String JavaDoc myClassName = myClass.getClassName();
83         String JavaDoc myPackageName = myClass.getPackageName();
84
85         String JavaDoc superClassName = jclass.getClassName();
86         String JavaDoc superPackageName = jclass.getPackageName();
87
88         Field[] fieldList = jclass.getFields();
89         for (Field field : fieldList) {
90             if (field.isStatic())
91                 continue;
92             boolean assignable;
93             if (field.isPublic() || field.isProtected())
94                 assignable = true;
95             else if (field.isPrivate())
96                 assignable = myClassName.equals(superClassName);
97             else // package protected
98
assignable = myPackageName.equals(superPackageName);
99
100             if (assignable) {
101                 assignableFieldSet.add(new InstanceField(superClassName, field.getName(), field.getSignature(),
102                         field.getAccessFlags()));
103             }
104         }
105     }
106
107     private void scanMethod(Method method, Set JavaDoc<XField> assignableFieldSet) throws ClassNotFoundException JavaDoc {
108         MethodGen methodGen = classContext.getMethodGen(method);
109         if (methodGen == null) return;
110         InstructionList il = methodGen.getInstructionList();
111         InstructionHandle handle = il.getStart();
112
113         ConstantPoolGen cpg = methodGen.getConstantPool();
114
115         while (handle != null) {
116             Instruction ins = handle.getInstruction();
117             short opcode = ins.getOpcode();
118             if (opcode == Constants.PUTFIELD) {
119                 PUTFIELD putfield = (PUTFIELD) ins;
120
121                 XField instanceField = Hierarchy.findXField(putfield, cpg);
122                 if (instanceField != null && assignableFieldSet.contains(instanceField)) {
123                     Set JavaDoc<XField> assignedFieldSetForMethod = getAssignedFieldSetForMethod(method);
124                     assignedFieldSetForMethod.add(instanceField);
125                 }
126             }
127
128             handle = handle.getNext();
129         }
130     }
131 }
132
133 // vim:ts=4
134
Popular Tags