KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2004,2005 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
23 import edu.umd.cs.findbugs.*;
24 import edu.umd.cs.findbugs.ba.*;
25 import edu.umd.cs.findbugs.ba.type.*;
26 import java.util.*;
27 import org.apache.bcel.Constants;
28 import org.apache.bcel.classfile.*;
29 import org.apache.bcel.generic.*;
30
31 /**
32  * Find places where ordinary (balanced) synchronization is performed
33  * on JSR166 Lock objects. Suggested by Doug Lea.
34  *
35  * @author David Hovemeyer
36  */

37 public final class FindJSR166LockMonitorenter implements Detector, StatelessDetector {
38     private BugReporter bugReporter;
39
40     private static final ObjectType LOCK_TYPE = ObjectTypeFactory.getInstance("java.util.concurrent.locks.Lock");
41
42     public FindJSR166LockMonitorenter(BugReporter bugReporter) {
43         this.bugReporter = bugReporter;
44     }
45
46     @Override JavaDoc
47     public Object JavaDoc clone() {
48         try {
49             return super.clone();
50         } catch (CloneNotSupportedException JavaDoc e) {
51             throw new AssertionError JavaDoc(e);
52         }
53     }
54
55     public void visitClassContext(ClassContext classContext) {
56         JavaClass jclass = classContext.getJavaClass();
57         Method[] methodList = jclass.getMethods();
58
59         for (Method method : methodList) {
60             if (method.getCode() == null)
61                 continue;
62
63             // We can ignore methods that don't contain a monitorenter
64
BitSet bytecodeSet = classContext.getBytecodeSet(method);
65             if (bytecodeSet == null) continue;
66             if (!bytecodeSet.get(Constants.MONITORENTER))
67                 continue;
68
69             try {
70                 analyzeMethod(classContext, method);
71             } catch (CFGBuilderException e) {
72                 bugReporter.logError("FindJSR166LockMonitorEnter caught exception", e);
73             } catch (DataflowAnalysisException e) {
74                 bugReporter.logError("FindJSR166LockMonitorEnter caught exception", e);
75             }
76         }
77     }
78
79     private void analyzeMethod(ClassContext classContext, Method method)
80             throws CFGBuilderException, DataflowAnalysisException {
81         ConstantPoolGen cpg = classContext.getConstantPoolGen();
82         CFG cfg = classContext.getCFG(method);
83         TypeDataflow typeDataflow = classContext.getTypeDataflow(method);
84
85         for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {
86             Location location = i.next();
87             
88             InstructionHandle handle = location.getHandle();
89             Instruction ins = handle.getInstruction();
90             
91             if (ins.getOpcode() != Constants.MONITORENTER)
92                 continue;
93             
94             TypeFrame frame = typeDataflow.getFactAtLocation(location);
95             if (!frame.isValid())
96                 continue;
97             Type type = frame.getInstance(ins, cpg);
98             
99             if (!(type instanceof ReferenceType)) {
100                 // Something is deeply wrong if a non-reference type
101
// is used for a monitorenter. But, that's really a
102
// verification problem.
103
return;
104             }
105             
106             boolean isSubtype;
107             try {
108                 isSubtype = Hierarchy.isSubtype((ReferenceType) type, LOCK_TYPE);
109             } catch (ClassNotFoundException JavaDoc e) {
110                 bugReporter.reportMissingClass(e);
111                 return;
112             }
113             
114             if (isSubtype) {
115                 MethodGen mg = classContext.getMethodGen(method);
116                 String JavaDoc sourceFile = classContext.getJavaClass().getSourceFileName();
117                 
118                 bugReporter.reportBug(new BugInstance(this, "JLM_JSR166_LOCK_MONITORENTER", NORMAL_PRIORITY)
119                         .addClassAndMethod(mg, sourceFile)
120                         .addSourceLine(classContext, mg, sourceFile, handle));
121             }
122         }
123     }
124
125     public void report() {
126     }
127 }
128
129 // vim:ts=4
130
Popular Tags