[Fb-contrib-commit] fb-contrib/src/com/mebigfatguy/fbcontrib/detect ParallelLists.java,NONE,1.1
Brought to you by:
dbrosius
From: Dave B. <dbr...@us...> - 2005-09-25 03:37:32
|
Update of /cvsroot/fb-contrib/fb-contrib/src/com/mebigfatguy/fbcontrib/detect In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13034/src/com/mebigfatguy/fbcontrib/detect Added Files: ParallelLists.java Log Message: Initial Checkin: PL detector --- NEW FILE: ParallelLists.java --- package com.mebigfatguy.fbcontrib.detect; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.apache.bcel.classfile.Code; import org.apache.bcel.classfile.Field; import org.apache.bcel.classfile.JavaClass; import edu.umd.cs.findbugs.BugInstance; import edu.umd.cs.findbugs.BugReporter; import edu.umd.cs.findbugs.BytecodeScanningDetector; import edu.umd.cs.findbugs.FieldAnnotation; import edu.umd.cs.findbugs.OpcodeStack; import edu.umd.cs.findbugs.StatelessDetector; import edu.umd.cs.findbugs.ba.ClassContext; public class ParallelLists extends BytecodeScanningDetector implements StatelessDetector { private BugReporter bugReporter; private OpcodeStack stack = new OpcodeStack(); private Set<String> listFields = new HashSet<String>(); private Map<Integer, String> indexToFieldMap = new HashMap<Integer, String>(); public ParallelLists(BugReporter bugReporter) { this.bugReporter = bugReporter; } public Object clone() throws CloneNotSupportedException { return super.clone(); } public void visitClassContext(ClassContext classContext) { JavaClass cls = classContext.getJavaClass(); listFields.clear(); Field[] flds = cls.getFields(); for (Field f : flds) { String sig = f.getSignature(); if (sig.charAt(0) == 'L') { sig = sig.substring(1, sig.length() - 1); if (sig.startsWith("java/util/") && sig.endsWith("List")) { listFields.add(f.getName()); } } else if (sig.charAt(0) == '[') listFields.add(f.getName()); } if (listFields.size() > 0) super.visitClassContext(classContext); } public void visitCode(Code obj) { stack.resetForMethodEntry(this); indexToFieldMap.clear(); super.visitCode(obj); } public void sawOpcode(int seen) { try { if (seen == INVOKEINTERFACE) { String className = getClassConstantOperand(); String methodName = getNameConstantOperand(); String methodSig = getSigConstantOperand(); if ("java/util/List".equals(className) && "get".equals(methodName) && "(I)Ljava/lang/Object;".equals(methodSig)) { if (stack.getStackDepth() > 2) { OpcodeStack.Item index = stack.getStackItem(0); OpcodeStack.Item list =stack.getStackItem(1); int indexReg = index.getRegisterNumber(); FieldAnnotation fa = list.getField(); if ((indexReg >= 0) && (fa != null)) { if (listFields.contains(fa.getFieldName())) { String f = indexToFieldMap.get(new Integer(indexReg)); if (f != null) { bugReporter.reportBug( new BugInstance( this, "PL_PARALLEL_LISTS", NORMAL_PRIORITY) .addClass(this) .addMethod(this) .addSourceLine(this, getPC())); } listFields.remove(fa.getFieldName()); indexToFieldMap.clear(); } else indexToFieldMap.put(new Integer(indexReg), fa.getFieldName()); } } } } else if ((seen >= IFEQ) && (seen <= RETURN)) { indexToFieldMap.clear(); } } finally { stack.sawOpcode(this, seen); } } } |