KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > detect > ResolveAllReferences


1 package edu.umd.cs.findbugs.detect;
2
3
4 import edu.umd.cs.findbugs.*;
5 import edu.umd.cs.findbugs.ba.*;
6 import edu.umd.cs.findbugs.ba.ch.Subtypes;
7 import edu.umd.cs.findbugs.visitclass.PreorderVisitor;
8 import java.util.*;
9 import org.apache.bcel.Repository;
10 import org.apache.bcel.classfile.*;
11
12 public class ResolveAllReferences extends PreorderVisitor implements Detector {
13
14     private BugReporter bugReporter;
15
16     public ResolveAllReferences(BugReporter bugReporter) {
17         this.bugReporter = bugReporter;
18
19     }
20
21     Set<String JavaDoc> defined;
22
23     private void compute() {
24         if (defined == null) {
25             // System.out.println("Computing");
26
defined = new HashSet<String JavaDoc>();
27             Subtypes subtypes = AnalysisContext.currentAnalysisContext()
28                     .getSubtypes();
29             Set<JavaClass> allClasses;
30             allClasses = subtypes.getAllClasses();
31             for (JavaClass c : allClasses)
32                 addAllDefinitions(c);
33             // System.out.println("Done Computing: " + defined.contains("edu.umd.cs.findbugs.ba.IsNullValueAnalysis.UNKNOWN_VALUES_ARE_NSP : Z"));
34
}
35     }
36
37     public void visitClassContext(ClassContext classContext) {
38         classContext.getJavaClass().accept(this);
39
40     }
41
42     public void report() {
43     }
44
45     public void addAllDefinitions(JavaClass obj) {
46         String JavaDoc className2 = obj.getClassName();
47         
48         defined.add(className2);
49         for (Method m : obj.getMethods())
50             if (!m.isPrivate()) {
51                 String JavaDoc name = getMemberName(obj, className2, m.getNameIndex(),
52                         m.getSignatureIndex());
53                 defined.add(name);
54             }
55         for (Field f : obj.getFields())
56             if (!f.isPrivate()) {
57                 String JavaDoc name = getMemberName(obj, className2, f.getNameIndex(), f
58                         .getSignatureIndex());
59                 defined.add(name);
60             }
61     }
62
63     private String JavaDoc getClassName(JavaClass c, int classIndex) {
64         String JavaDoc name = c.getConstantPool().getConstantString(classIndex,
65                 CONSTANT_Class);
66         return Subtypes.extractClassName(name).replace('/','.');
67     }
68
69     private String JavaDoc getMemberName(JavaClass c, String JavaDoc className,
70             int memberNameIndex, int signatureIndex) {
71         return className
72                 + "."
73                 + ((ConstantUtf8) c.getConstantPool().getConstant(
74                         memberNameIndex, CONSTANT_Utf8)).getBytes()
75                         + " : "
76                         + ((ConstantUtf8) c.getConstantPool().getConstant(
77                         signatureIndex, CONSTANT_Utf8)).getBytes();
78     }
79     private String JavaDoc getMemberName(String JavaDoc className,
80             String JavaDoc memberName, String JavaDoc signature) {
81         return className.replace('/','.')
82                 + "."
83                 + memberName
84                         + " : "
85                         + signature;
86     }
87     private boolean find(JavaClass target, String JavaDoc name, String JavaDoc signature) throws ClassNotFoundException JavaDoc {
88         if (target == null) return false;
89         String JavaDoc ref = getMemberName(target.getClassName(), name,
90                 signature);
91         if (defined.contains(ref)) return true;
92         if (find(target.getSuperClass(), name, signature)) return true;
93         for(JavaClass i : target.getInterfaces())
94             if (find(i, name, signature)) return true;
95         return false;
96     }
97     @Override JavaDoc
98          public void visit(JavaClass obj) {
99         compute();
100         ConstantPool cp = obj.getConstantPool();
101         Constant[] constants = cp.getConstantPool();
102         checkConstant: for (int i = 0; i < constants.length; i++) {
103             Constant co = constants[i];
104             if (co instanceof ConstantDouble || co instanceof ConstantLong)
105                 i++;
106             if (co instanceof ConstantClass) {
107                 String JavaDoc ref = getClassName(obj, i);
108                 if ((ref.startsWith("java") || ref.startsWith("org.w3c.dom")) && !defined.contains(ref))
109                     bugReporter.reportBug(new BugInstance(this, "VR_UNRESOLVABLE_REFERENCE", NORMAL_PRIORITY)
110                             .addClass(obj).addString(ref));
111                     
112
113             } else if (co instanceof ConstantFieldref) {
114                 // do nothing until we handle static fields defined in interfaces
115
} else if (co instanceof ConstantCP) {
116                 ConstantCP co2 = (ConstantCP) co;
117                 String JavaDoc className = getClassName(obj, co2.getClassIndex());
118
119                 // System.out.println("checking " + ref);
120
if (className.equals(obj.getClassName())
121                         || !defined.contains(className)) {
122                     // System.out.println("Skipping check of " + ref);
123
continue checkConstant;
124                 }
125                 ConstantNameAndType nt = (ConstantNameAndType) cp
126                 .getConstant(co2.getNameAndTypeIndex());
127                 String JavaDoc name = ((ConstantUtf8) obj.getConstantPool().getConstant(
128                         nt.getNameIndex(), CONSTANT_Utf8)).getBytes();
129                 String JavaDoc signature = ((ConstantUtf8) obj.getConstantPool().getConstant(
130                         nt.getSignatureIndex(), CONSTANT_Utf8)).getBytes();
131
132                 
133                 try {
134                     JavaClass target = Repository.lookupClass(className);
135                     if (! find(target, name, signature))
136                         bugReporter.reportBug(new BugInstance(this, "VR_UNRESOLVABLE_REFERENCE", NORMAL_PRIORITY)
137                             .addClass(obj).addString(getMemberName(target.getClassName(), name,
138                                     signature)));
139                     
140                 } catch (ClassNotFoundException JavaDoc e) {
141                     bugReporter.reportMissingClass(e);
142                 }
143             }
144
145         }
146     }
147
148 }
149
Popular Tags