KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2006 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.detect;
21
22 import java.util.HashSet JavaDoc;
23 import java.util.Set JavaDoc;
24
25 import org.apache.bcel.classfile.Attribute;
26 import org.apache.bcel.classfile.Code;
27 import org.apache.bcel.classfile.JavaClass;
28 import org.apache.bcel.classfile.Method;
29
30 import edu.umd.cs.findbugs.BugInstance;
31 import edu.umd.cs.findbugs.BugReporter;
32 import edu.umd.cs.findbugs.BytecodeScanningDetector;
33 import edu.umd.cs.findbugs.ba.AnalysisContext;
34 import edu.umd.cs.findbugs.ba.XFactory;
35 import edu.umd.cs.findbugs.ba.XMethod;
36 import edu.umd.cs.findbugs.util.ClassName;
37
38 public class UncallableMethodOfAnonymousClass extends BytecodeScanningDetector {
39
40     BugReporter bugReporter;
41
42     public UncallableMethodOfAnonymousClass(BugReporter bugReporter) {
43         this.bugReporter = bugReporter;
44     }
45
46     boolean isInnerClass = false;
47
48     @Override JavaDoc
49     public void visit(JavaClass obj) {
50         isInnerClass = ClassName.isAnonymous(getClassName());
51     }
52
53     boolean definedInThisClassOrSuper(JavaClass clazz, String JavaDoc method)
54             throws ClassNotFoundException JavaDoc {
55         if (clazz == null)
56             return false;
57         // System.out.println("Checking to see if " + method + " is defined in "
58
// + clazz.getClassName());
59
for (Method m : clazz.getMethods())
60             if (method.equals(m.getName() + ":" + m.getSignature()))
61                 return true;
62
63         return definedInSuperClassOrInterface(clazz, method);
64
65     }
66
67     boolean definedInSuperClassOrInterface(JavaClass clazz, String JavaDoc method)
68             throws ClassNotFoundException JavaDoc {
69         if (clazz == null)
70             return false;
71         JavaClass superClass = clazz.getSuperClass();
72         if (definedInThisClassOrSuper(superClass, method))
73             return true;
74         for (JavaClass i : clazz.getInterfaces())
75             if (definedInThisClassOrSuper(i, method))
76                 return true;
77         return false;
78     }
79
80     Set JavaDoc<String JavaDoc> definedInClass(JavaClass clazz) {
81         HashSet JavaDoc<String JavaDoc> result = new HashSet JavaDoc<String JavaDoc>();
82         for(Method m : clazz.getMethods()) {
83             if (!skip(m))
84                 result.add(m.getName()+m.getSignature());
85         }
86         return result;
87     }
88     
89     static private boolean skip(Method obj) {
90         if (obj.getName().equals("<init>"))
91             return true;
92         if (obj.getName().startsWith("access$"))
93             return true;
94         if (obj.isSynthetic())
95             return true;
96         if (obj.isPrivate())
97             return true;
98         if (obj.isAbstract()) return true;
99         return false;
100     }
101     @Override JavaDoc
102     public void visit(Method obj) {
103         try {
104             if (!isInnerClass)
105                 return;
106             if (skip(obj)) return;
107
108             JavaClass clazz = getThisClass();
109             XMethod xmethod = XFactory.createXMethod(clazz, obj);
110             XFactory factory = AnalysisContext.currentXFactory();
111             if (!factory.isCalled(xmethod)
112                     && !definedInSuperClassOrInterface(clazz, obj.getName()
113                             + ":" + obj.getSignature())) {
114                 int priority = NORMAL_PRIORITY;
115                 JavaClass superClass = clazz.getSuperClass();
116                 String JavaDoc superClassName = superClass.getClassName();
117                 if (superClass.isInterface() || superClassName.equals("java.lang.Object"))
118                         priority = HIGH_PRIORITY;
119                 else if (definedInClass(superClass).containsAll(definedInClass(clazz)))
120                         priority = NORMAL_PRIORITY;
121                 else
122                     priority = HIGH_PRIORITY;
123                 Code code = null;
124                 for(Attribute a : obj.getAttributes())
125                     if (a instanceof Code) {
126                         code = (Code) a;
127                         break;
128                     }
129                 if (code != null && code.getLength() == 1) priority++; // TODO: why didn't FindBugs give a warning here before the null check was added?
130
bugReporter.reportBug(new BugInstance("UMAC_UNCALLABLE_METHOD_OF_ANONYMOUS_CLASS",
131                         priority).addClassAndMethod(this));
132             
133             }
134
135         } catch (ClassNotFoundException JavaDoc e) {
136             bugReporter.reportMissingClass(e);
137         }
138
139     }
140
141 }
142
Popular Tags