Update of /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31704/src/com/mebigfatguy/fbcontrib/detect
Modified Files:
SluggishGui.java
Log Message:
parse non listener methods for expensive code, and then parse listener methods. If one of these aux methods is called, then report the listener as sluggish.
Index: SluggishGui.java
===================================================================
RCS file: /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect/SluggishGui.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- SluggishGui.java 2 Feb 2006 07:05:02 -0000 1.3
+++ SluggishGui.java 3 Feb 2006 03:45:20 -0000 1.4
@@ -19,12 +19,13 @@
package com.mebigfatguy.fbcontrib.detect;
import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
import java.util.Set;
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
-import org.apache.bcel.generic.Type;
import edu.umd.cs.findbugs.BugInstance;
import edu.umd.cs.findbugs.BugReporter;
@@ -68,7 +69,11 @@
}
private BugReporter bugReporter;
+ private Set<String> expensiveThisCalls = new HashSet<String>();
private Set<JavaClass> guiInterfaces = new HashSet<JavaClass>();
+ private Map<Code,Method> listenerCode = new LinkedHashMap<Code,Method>();
+ private String methodName;
+ private String methodSig;
private boolean isListenerMethod = false;
private boolean methodReported = false;
@@ -100,6 +105,8 @@
public void visitClassContext(ClassContext classContext) {
try {
guiInterfaces.clear();
+ listenerCode.clear();
+ expensiveThisCalls.clear();
JavaClass cls = classContext.getJavaClass();
JavaClass[] infs = cls.getAllInterfaces();
for (JavaClass inf : infs) {
@@ -119,50 +126,52 @@
}
/**
- * overrides the visitor to find methods that override listeners
+ * overrides the visitor to visit all of the collected listener methods
+ *
+ * @parm obj the context object of the currently parsed class
+ */
+ @Override
+ public void visitAfter(JavaClass obj) {
+ isListenerMethod = true;
+ for (Code l : listenerCode.keySet()) {
+ methodReported = false;
+ super.visitCode(l);
+ }
+ super.visitAfter(obj);
+ }
+ /**
+ * overrides the visitor collect method info
*
* @param obj the context object of the currently parsed method
*/
@Override
public void visitMethod(Method obj) {
- isListenerMethod = false;
- methodReported = false;
- if (!obj.isPublic())
- return;
-
- String methodSig = obj.getSignature();
- Type r = Type.getReturnType(methodSig);
- if (!r.equals(Type.VOID))
- return;
- Type[] args = Type.getArgumentTypes(methodSig);
- if (args.length != 1)
- return;
- if (args[0].getSignature().charAt(0) != 'L')
- return;
-
- String methodName = obj.getName();
+ methodName = obj.getName();
+ methodSig = obj.getSignature();
+ }
+
+ /**
+ * overrides the visitor to segregate method into two, those that implement
+ * listeners, and those that don't. The ones that don't are processed first.
+ *
+ * @param obj the context object of the currently parsed code block
+ */
+ @Override
+ public void visitCode(Code obj) {
for (JavaClass inf : guiInterfaces) {
Method[] methods = inf.getMethods();
for (Method m : methods) {
if (m.getName().equals(methodName)) {
if (m.getSignature().equals(methodSig)) {
- isListenerMethod = true;
+ listenerCode.put(obj, this.getMethod());
return;
}
}
}
}
- }
-
- /**
- * overrides the visitor to check whether to parse method if its a listener
- *
- * @param obj the context object of the currently parsed code block
- */
- @Override
- public void visitCode(Code obj) {
- if (isListenerMethod)
- super.visitCode(obj);
+ isListenerMethod = false;
+ methodReported = false;
+ super.visitCode(obj);
}
/**
@@ -180,12 +189,18 @@
|| (seen == INVOKESTATIC)) {
String clsName = getClassConstantOperand();
String methodName = getNameConstantOperand();
- String info = clsName + ":" + methodName;
- if (expensiveCalls.contains(info)) {
- bugReporter.reportBug(new BugInstance(this, "SG_SLUGGISH_GUI", NORMAL_PRIORITY)
- .addClass(this)
- .addMethod(this)
- .addSourceLine(this));
+ String methodInfo = clsName + ":" + methodName;
+ String methodSig = getSigConstantOperand();
+ String thisMethodInfo = (clsName.equals(getClassName())) ? (methodName + ":" + methodSig) : "0";
+
+ if (expensiveCalls.contains(methodInfo) || expensiveThisCalls.contains(thisMethodInfo)) {
+ if (isListenerMethod) {
+ bugReporter.reportBug(new BugInstance(this, "SG_SLUGGISH_GUI", NORMAL_PRIORITY)
+ .addClass(this)
+ .addMethod(this.getClassContext().getJavaClass(), listenerCode.get(this.getCode())));
+ } else {
+ expensiveThisCalls.add(getMethodName() + ":" + getMethodSig());
+ }
methodReported = true;
}
}
|