KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > AssertionMethods


1 /*
2  * Bytecode Analysis Framework
3  * Copyright (C) 2003,2004 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.ba;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.BitSet JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.StringTokenizer JavaDoc;
26
27 import org.apache.bcel.Constants;
28 import org.apache.bcel.classfile.ClassFormatException;
29 import org.apache.bcel.classfile.Constant;
30 import org.apache.bcel.classfile.ConstantMethodref;
31 import org.apache.bcel.classfile.ConstantNameAndType;
32 import org.apache.bcel.classfile.ConstantPool;
33 import org.apache.bcel.classfile.ConstantUtf8;
34 import org.apache.bcel.classfile.JavaClass;
35 import org.apache.bcel.generic.InvokeInstruction;
36
37 import edu.umd.cs.findbugs.SystemProperties;
38
39 /**
40  * Mark methodref constant pool entries of methods
41  * that are likely to implement assertions.
42  * This is useful for pruning likely false paths.
43  *
44  * @author David Hovemeyer
45  */

46 public class AssertionMethods implements Constants {
47     
48     private static final boolean DEBUG = SystemProperties.getBoolean("assertionmethods.debug");
49     
50     /**
51      * Bitset of methodref constant pool indexes referring to likely assertion methods.
52      */

53     private BitSet JavaDoc assertionMethodRefSet;
54
55     private static class UserAssertionMethod {
56         private String JavaDoc className;
57         private String JavaDoc methodName;
58
59         public UserAssertionMethod(String JavaDoc className, String JavaDoc methodName) {
60             this.className = className;
61             this.methodName = methodName;
62         }
63
64         public String JavaDoc getClassName() {
65             return className;
66         }
67
68         public String JavaDoc getMethodName() {
69             return methodName;
70         }
71     }
72
73     private static final List JavaDoc<UserAssertionMethod> userAssertionMethodList = new ArrayList JavaDoc<UserAssertionMethod>();
74
75     static {
76         String JavaDoc userProperty = SystemProperties.getProperty("findbugs.assertionmethods");
77         if (userProperty != null) {
78             StringTokenizer JavaDoc tok = new StringTokenizer JavaDoc(userProperty, ",");
79             while (tok.hasMoreTokens()) {
80                 String JavaDoc fullyQualifiedName = tok.nextToken();
81                 int lastDot = fullyQualifiedName.lastIndexOf('.');
82                 if (lastDot < 0)
83                     continue;
84                 String JavaDoc className = fullyQualifiedName.substring(0, lastDot);
85                 String JavaDoc methodName = fullyQualifiedName.substring(lastDot + 1);
86                 userAssertionMethodList.add(new UserAssertionMethod(className, methodName));
87             }
88         }
89     }
90
91     /**
92      * Constructor.
93      *
94      * @param jclass the JavaClass containing the methodrefs
95      */

96     public AssertionMethods(JavaClass jclass) {
97         this.assertionMethodRefSet = new BitSet JavaDoc();
98         init(jclass);
99     }
100
101     private void init(JavaClass jclass) {
102         ConstantPool cp = jclass.getConstantPool();
103         int numConstants = cp.getLength();
104         for (int i = 0; i < numConstants; ++i) {
105             try {
106                 Constant c = cp.getConstant(i);
107                 if (c instanceof ConstantMethodref) {
108                     ConstantMethodref cmr = (ConstantMethodref) c;
109                     ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex(), CONSTANT_NameAndType);
110                     String JavaDoc methodName = ((ConstantUtf8) cp.getConstant(cnat.getNameIndex(), CONSTANT_Utf8)).getBytes();
111                     String JavaDoc className = cp.getConstantString(cmr.getClassIndex(), CONSTANT_Class).replace('/', '.');
112                     String JavaDoc methodSig = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex(), CONSTANT_Utf8)).getBytes();
113                     
114                     String JavaDoc classNameLC = className.toLowerCase();
115                     String JavaDoc methodNameLC = methodName.toLowerCase();
116                     boolean voidReturnType = methodSig.endsWith(")V");
117                     
118                     if (DEBUG) {
119                         System.out.print("Is " + className + "." + methodName + " assertion method: " + voidReturnType);
120                     }
121
122                     if (isUserAssertionMethod(className, methodName)
123                             || className.endsWith("Assert")
124                             && methodName.startsWith("is")
125                             || voidReturnType
126                             && (classNameLC.indexOf("assert") >= 0
127                                     || methodNameLC.startsWith("throw")
128                                     || methodName.startsWith("affirm")
129                                     || methodName.startsWith("panic")
130                                     || methodNameLC.equals("insist")
131                                     || methodNameLC.equals("usage")
132                                     || methodNameLC.startsWith("fail")
133                                     || methodNameLC.startsWith("fatal")
134                                     || methodNameLC.indexOf("assert") >= 0
135                                     || methodNameLC.indexOf("legal") >= 0
136                                     || methodNameLC.indexOf("error") >= 0
137                                     || methodNameLC.indexOf("abort") >= 0
138                                     || methodNameLC.indexOf("check") >= 0 || methodNameLC.indexOf("failed") >= 0)) {
139                         assertionMethodRefSet.set(i);
140                         if (DEBUG) {
141                             System.out.println("==> YES");
142                         }
143                     } else {
144                         if (DEBUG) {
145                             System.out.println("==> NO");
146                         }
147                     }
148                 }
149             } catch (ClassFormatException e) {
150                 // FIXME: should report
151
}
152         }
153     }
154
155     private static boolean isUserAssertionMethod(String JavaDoc className, String JavaDoc methodName) {
156         for (UserAssertionMethod uam : userAssertionMethodList) {
157             if (className.equals(uam.getClassName()) && methodName.equals(uam.getMethodName()))
158                 return true;
159         }
160         return false;
161     }
162
163     /**
164      * Does the given InvokeInstruction refer to a likely assertion method?
165      *
166      * @param inv the InvokeInstruction
167      * @return true if the instruction likely refers to an assertion, false if not
168      */

169     public boolean isAssertionCall(InvokeInstruction inv) {
170 // if (DEBUG) {
171
// System.out.print("Checking if " + inv + " is an assertion method: ");
172
// }
173
boolean isAssertionMethod = assertionMethodRefSet.get(inv.getIndex());
174 // if (DEBUG) {
175
// System.out.println("==> " + isAssertionMethod);
176
// }
177
return isAssertionMethod;
178     }
179 }
180
181 // vim:ts=4
182
Popular Tags