1 20 21 package edu.umd.cs.findbugs.detect; 22 23 24 import edu.umd.cs.findbugs.*; 25 import java.util.*; 26 import org.apache.bcel.Repository; 27 import org.apache.bcel.classfile.*; 28 29 30 public class InstantiateStaticClass extends BytecodeScanningDetector { 31 private BugReporter bugReporter; 32 33 Map<String ,Boolean > isStaticClass = new HashMap<String ,Boolean >(); 34 35 public InstantiateStaticClass(BugReporter bugReporter) { 36 this.bugReporter = bugReporter; 37 } 38 39 @Override 40 public void sawOpcode(int seen) { 41 try { 42 if ((seen == INVOKESPECIAL) 43 && getNameConstantOperand().equals("<init>") 44 && getSigConstantOperand().equals("()V")) { 45 String clsName = getClassConstantOperand(); 46 if (clsName.equals("java/lang/Object")) 47 return; 48 49 if (getMethodName().equals("<init>") && (getPC() == 1)) 51 return; 52 53 if (getMethodName().equals("<clinit>") && (getClassName().equals(clsName))) 55 return; 56 57 Boolean b = isStaticClass.get(clsName); 58 if (b == null) { 59 b = Boolean.valueOf(isStaticOnlyClass(clsName)); 60 isStaticClass.put(clsName, b); 61 } 62 if (b) 63 64 bugReporter.reportBug(new BugInstance(this, "ISC_INSTANTIATE_STATIC_CLASS", LOW_PRIORITY) 65 .addClassAndMethod(this) 66 .addSourceLine(this)); 67 } 68 } catch (ClassNotFoundException cnfe) { 69 bugReporter.reportMissingClass(cnfe); 70 } 71 } 72 73 private boolean isStaticOnlyClass(String clsName) throws ClassNotFoundException { 74 clsName = clsName.replace('/', '.'); 75 JavaClass cls = Repository.lookupClass(clsName); 76 if (cls.getInterfaceNames().length > 0) 77 return false; 78 String superClassName = cls.getSuperclassName(); 79 if (!superClassName.equals("java.lang.Object")) 80 return false; 81 82 Method[] methods = cls.getMethods(); 83 int staticCount = 0; 84 for (Method m : methods) { 85 if (m.isStatic()) { 86 staticCount++; 87 continue; 88 } 89 90 if (m.getName().equals("<init>")) { 91 if (!m.getSignature().equals("()V")) 92 return false; 93 94 Code c = m.getCode(); 95 96 if (c.getCode().length > 5) 97 return false; 98 } else { 99 return false; 100 } 101 } 102 103 Field[] fields = cls.getFields(); 104 for (Field f : fields) { 105 if (f.isStatic()) { 106 staticCount++; 107 continue; 108 } 109 110 if (!f.isPrivate()) 111 return false; 112 } 113 114 if (staticCount == 0) return false; 115 return true; 116 } 117 118 } 119 | Popular Tags |