KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2003-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 org.apache.bcel.classfile.Code;
25
26 public class WaitInLoop extends BytecodeScanningDetector implements StatelessDetector {
27
28     boolean sawWait = false;
29     boolean sawAwait = false;
30     boolean waitHasTimeout = false;
31     boolean sawNotify = false;
32     int notifyPC;
33     int earliestJump = 0;
34     int waitAt = 0;
35     private BugReporter bugReporter;
36
37     public WaitInLoop(BugReporter bugReporter) {
38         this.bugReporter = bugReporter;
39     }
40
41
42
43     @Override JavaDoc
44          public void visit(Code obj) {
45         sawWait = false;
46         sawAwait = false;
47         waitHasTimeout = false;
48         sawNotify = false;
49         earliestJump = 9999999;
50         super.visit(obj);
51         if ((sawWait || sawAwait) && waitAt < earliestJump) {
52             String JavaDoc bugType = sawWait ? "WA_NOT_IN_LOOP" : "WA_AWAIT_NOT_IN_LOOP";
53             bugReporter.reportBug(new BugInstance(this, bugType, waitHasTimeout ? LOW_PRIORITY : NORMAL_PRIORITY)
54                     .addClassAndMethod(this)
55                     .addSourceLine(this, waitAt));
56         }
57         if (sawNotify)
58             bugReporter.reportBug(new BugInstance(this, "NO_NOTIFY_NOT_NOTIFYALL", LOW_PRIORITY)
59                     .addClassAndMethod(this)
60                     .addSourceLine(this, notifyPC));
61     }
62
63     @Override JavaDoc
64          public void sawOpcode(int seen) {
65
66         if ((seen == INVOKEVIRTUAL || seen == INVOKEINTERFACE)
67                 && getNameConstantOperand().equals("notify")
68                 && getSigConstantOperand().equals("()V")) {
69             sawNotify = true;
70             notifyPC = getPC();
71         }
72         if (!(sawWait || sawAwait)
73                 && (seen == INVOKEVIRTUAL || seen == INVOKEINTERFACE)
74                 && (isMonitorWait() || isConditionAwait())) {
75
76             if (getNameConstantOperand().equals("wait")) {
77                 sawWait = true;
78             } else {
79                 sawAwait = true;
80             }
81             waitHasTimeout = !getSigConstantOperand().equals("()V");
82             waitAt = getPC();
83             earliestJump = getPC() + 1;
84             return;
85         }
86         if (seen >= IFEQ && seen <= GOTO
87                 || seen >= IFNULL && seen <= GOTO_W)
88             earliestJump = Math.min(earliestJump, getBranchTarget());
89     }
90
91     private boolean isConditionAwait() {
92         String JavaDoc className = getClassConstantOperand();
93         String JavaDoc name = getNameConstantOperand();
94         String JavaDoc sig = getSigConstantOperand();
95
96         if (!className.equals("java/util/concurrent/locks/Condition")) return false;
97         
98         if (!name.startsWith("await")) return false;
99         
100         if (
101                 name.equals("await") &&
102                 (sig.equals("()V") || sig.equals("(JLjava/util/concurrent/TimeUnit;)V")))
103             return true;
104         if (name.equals("awaitNanos") && sig.equals("(J)V"))
105             return true;
106         if (name.equals("awaitUninterruptibly") && sig.equals("()V"))
107             return true;
108         if (name.equals("awaitUntil") && sig.equals("(Ljava/util/Date;)V"))
109             return true;
110         
111         return false;
112     }
113
114     private boolean isMonitorWait() {
115         String JavaDoc name = getNameConstantOperand();
116         String JavaDoc sig = getSigConstantOperand();
117
118         return name.equals("wait")
119                 && (sig.equals("()V") || sig.equals("(J)V") || sig.equals("(JI)V"));
120     }
121
122
123 }
124
Popular Tags