KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > ba > npe > NonNullContractCollector


1 /*
2  * Bytecode analysis framework
3  * Copyright (C) 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.ba.npe;
21
22 import java.util.BitSet JavaDoc;
23 import java.util.LinkedList JavaDoc;
24 import java.util.List JavaDoc;
25
26 import org.apache.bcel.generic.ConstantPoolGen;
27 import org.apache.bcel.generic.InvokeInstruction;
28
29 import edu.umd.cs.findbugs.SystemProperties;
30 import edu.umd.cs.findbugs.ba.Hierarchy;
31 import edu.umd.cs.findbugs.ba.JavaClassAndMethod;
32 import edu.umd.cs.findbugs.ba.JavaClassAndMethodChooser;
33 import edu.umd.cs.findbugs.ba.XFactory;
34 import edu.umd.cs.findbugs.ba.XMethod;
35
36 /**
37  * Find the contract specified by @NonNull and @CheckForNull parameter
38  * annotations in the class hierarchy. Also, check null argument sets
39  * for violations.
40  *
41  * <p>TODO: this code could be generalized for other kinds of parameter annotations</p>
42  *
43  * @author David Hovemeyer
44  */

45 public class NonNullContractCollector implements JavaClassAndMethodChooser {
46     private static final boolean DEBUG_NULLARG = SystemProperties.getBoolean("fnd.debug.nullarg");
47
48     private final ParameterNullnessPropertyDatabase nonNullParamDatabase;
49     private final ParameterNullnessPropertyDatabase possiblyNullParamDatabase;
50     private final List JavaDoc<NonNullSpecification> specificationList;
51
52     public NonNullContractCollector(ParameterNullnessPropertyDatabase nonNullParamDatabase, ParameterNullnessPropertyDatabase possiblyNullParamDatabase) {
53         super();
54         this.nonNullParamDatabase = nonNullParamDatabase;
55         this.possiblyNullParamDatabase = possiblyNullParamDatabase;
56         this.specificationList = new LinkedList JavaDoc<NonNullSpecification>();
57     }
58
59     public boolean choose(JavaClassAndMethod classAndMethod) {
60         XMethod xmethod = XFactory.createXMethod(
61                 classAndMethod.getJavaClass(), classAndMethod.getMethod());
62
63         NonNullSpecification specification = new NonNullSpecification(
64                 classAndMethod,
65                 wrapProperty(nonNullParamDatabase.getProperty(xmethod)),
66                 wrapProperty(possiblyNullParamDatabase.getProperty(xmethod)));
67         if (DEBUG_NULLARG) {
68             System.out.println("Found specification: " + specification);
69         }
70         specificationList.add(specification);
71         
72         return false;
73     }
74     
75     public void findContractForCallSite(InvokeInstruction invokeInstruction, ConstantPoolGen cpg) throws ClassNotFoundException JavaDoc {
76         Hierarchy.findInvocationLeastUpperBound(invokeInstruction, cpg, this);
77     }
78     
79     public void findContractForMethod(JavaClassAndMethod classAndMethod) throws ClassNotFoundException JavaDoc {
80         String JavaDoc methodName = classAndMethod.getMethod().getName();
81         String JavaDoc signature = classAndMethod.getMethod().getSignature();
82         Hierarchy.findMethod(classAndMethod.getJavaClass(), methodName, signature, this);
83         Hierarchy.visitSuperClassMethods(classAndMethod, this);
84         Hierarchy.visitSuperInterfaceMethods(classAndMethod, this);
85     }
86     
87     public interface SpecificationBuilder {
88         public boolean checkParam(int param);
89         public void setNonNullParam(int param, NonNullSpecification specification);
90         public void setCheckForNullParam(int param, NonNullSpecification specification);
91     }
92     
93     public void checkSpecifications(int numParams, SpecificationBuilder builder) {
94         BitSet JavaDoc checkedParams = new BitSet JavaDoc();
95         for (NonNullSpecification specification : specificationList) {
96             if (DEBUG_NULLARG) {
97                 System.out.println("Check specification: " + specification);
98             }
99             
100         paramLoop:
101             for (int i = 0; i < numParams; ++i) {
102                 if (DEBUG_NULLARG) {
103                     System.out.print("\tParam " + i);
104                 }
105                 
106                 if (checkedParams.get(i)) {
107                     if (DEBUG_NULLARG) System.out.println(" ==> already checked");
108                     continue paramLoop;
109                 }
110                 
111                 if (!builder.checkParam(i))
112                     continue paramLoop;
113                 
114                 // Param should be checked, and we haven't seen a specification for the parameter yet.
115
// See if this method defines a specification.
116
if (specification.getCheckForNullProperty().isNonNull(i)) {
117                     // Parameter declared @CheckForNull.
118
builder.setCheckForNullParam(i, specification);
119                     checkedParams.set(i);
120                 } else if (specification.getNonNullProperty().isNonNull(i)) {
121                     // Parameter declated @NonNull.
122
builder.setNonNullParam(i, specification);
123                     checkedParams.set(i);
124                 } else {
125                     if (DEBUG_NULLARG) System.out.println(" ==> no constraint");
126                 }
127             }
128         }
129     }
130     
131     public void getViolationList(
132             int numParams,
133             final BitSet JavaDoc nullArgSet,
134             final List JavaDoc<NonNullParamViolation> violationList,
135             final BitSet JavaDoc violatedParamSet) {
136         
137         SpecificationBuilder builder = new SpecificationBuilder() {
138             public boolean checkParam(int param) {
139                 if (!argIsNull(param)) {
140                     if (DEBUG_NULLARG) System.out.println(" ==> not null");
141                     return false;
142                 }
143                 return true;
144             }
145             
146             public void setNonNullParam(int param, NonNullSpecification specification) {
147                 if (DEBUG_NULLARG) System.out.println(" ==> @NonNull violation!");
148                 violationList.add(new NonNullParamViolation(specification.getClassAndMethod(), param));
149                 violatedParamSet.set(param);
150             }
151             
152             public void setCheckForNullParam(int param, NonNullSpecification specification) {
153                 if (DEBUG_NULLARG) System.out.println(" ==> @CheckForNull");
154             }
155             
156             private boolean argIsNull(int param) {
157                 return nullArgSet.get(param);
158             }
159         };
160         checkSpecifications(numParams, builder);
161     }
162     
163     public void getAnnotationSets(int numParams, final BitSet JavaDoc nonNullParamSet, final BitSet JavaDoc possiblyNullParamSet) {
164         SpecificationBuilder builder = new SpecificationBuilder() {
165             public boolean checkParam(int param) {
166                 return true;
167             }
168             
169             public void setNonNullParam(int param, NonNullSpecification specification) {
170                 nonNullParamSet.set(param);
171             }
172             
173             public void setCheckForNullParam(int param, NonNullSpecification specification) {
174                 possiblyNullParamSet.set(param);
175             }
176         };
177         checkSpecifications(numParams, builder);
178     }
179     
180     static ParameterNullnessProperty wrapProperty(ParameterNullnessProperty property) {
181         return property != null ? property : new ParameterNullnessProperty();
182     }
183 }
184
Popular Tags