001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2005, University of Maryland
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package edu.umd.cs.findbugs.ba;
021:
022: import edu.umd.cs.findbugs.annotations.CheckForNull;
023: import edu.umd.cs.findbugs.log.Profiler;
024:
025: /**
026: * @author pugh
027: */
028: public class NullnessAnnotationDatabase extends
029: AnnotationDatabase<NullnessAnnotation> implements
030: INullnessAnnotationDatabase {
031:
032: public NullnessAnnotationDatabase() {
033: setAddClassOnly(true);
034: loadAuxiliaryAnnotations();
035: setAddClassOnly(false);
036: }
037:
038: @Override
039: public void loadAuxiliaryAnnotations() {
040: DefaultNullnessAnnotations.addDefaultNullnessAnnotations(this );
041: }
042:
043: /* (non-Javadoc)
044: * @see edu.umd.cs.findbugs.ba.INullnessAnnotationDatabase#parameterMustBeNonNull(edu.umd.cs.findbugs.ba.XMethod, int)
045: */
046: public boolean parameterMustBeNonNull(XMethod m, int param) {
047: if (!anyAnnotations(NullnessAnnotation.NONNULL))
048: return false;
049: XMethodParameter xmp = new XMethodParameter(m, param);
050: NullnessAnnotation resolvedAnnotation = getResolvedAnnotation(
051: xmp, true);
052: if (false) {
053: System.out.println("QQQ parameter " + param + " of " + m
054: + " is " + resolvedAnnotation);
055: System.out.println(m.getSignature());
056: }
057:
058: return resolvedAnnotation == NullnessAnnotation.NONNULL;
059: }
060:
061: /* (non-Javadoc)
062: * @see edu.umd.cs.findbugs.ba.INullnessAnnotationDatabase#getResolvedAnnotation(java.lang.Object, boolean)
063: */
064: @CheckForNull
065: @Override
066: public NullnessAnnotation getResolvedAnnotation(final Object o,
067: boolean getMinimal) {
068:
069: Profiler profiler = Profiler.getInstance();
070: profiler.start(this .getClass());
071: try {
072: if (o instanceof XMethodParameter) {
073: XMethodParameter mp = (XMethodParameter) o;
074: XMethod m = mp.getMethod();
075: if (m.getName().startsWith("access$"))
076: return null;
077: // TODO: Handle argument to equals specially: generate special bug code for it
078: if (mp.getParameterNumber() == 0
079: && m.getName().equals("equals")
080: && m.getSignature().equals(
081: "(Ljava/lang/Object;)Z")
082: && !m.isStatic())
083: return NullnessAnnotation.CHECK_FOR_NULL;
084: else if (mp.getParameterNumber() == 0
085: && m.getName().equals("compareTo")
086: && m.getSignature().endsWith(";)Z")
087: && !m.isStatic())
088: return NullnessAnnotation.NONNULL;
089: } else if (o instanceof XMethod) {
090: XMethod m = (XMethod) o;
091: if (m.getName().startsWith("access$"))
092: return null;
093: if (m.getName().equals("clone")
094: && m.getSignature().equals(
095: "()Ljava/lang/Object;"))
096: return NullnessAnnotation.NONNULL;
097: if (m.getName().equals("toString")
098: && m.getSignature().equals(
099: "()Ljava/lang/String;"))
100: return NullnessAnnotation.NONNULL;
101: } else if (o instanceof XField) {
102: XField f = (XField) o;
103: if (f.getName().startsWith("this$"))
104: return NullnessAnnotation.NONNULL;
105: }
106: NullnessAnnotation result = super .getResolvedAnnotation(o,
107: getMinimal);
108: return result;
109: } finally {
110: profiler.end(this .getClass());
111: }
112: }
113:
114: /* (non-Javadoc)
115: * @see edu.umd.cs.findbugs.ba.AnnotationDatabase#addDefaultMethodAnnotation(java.lang.String, edu.umd.cs.findbugs.ba.AnnotationEnumeration)
116: */
117: @Override
118: public void addDefaultMethodAnnotation(String name,
119: NullnessAnnotation annotation) {
120: super .addDefaultMethodAnnotation(name, annotation);
121: }
122:
123: /* (non-Javadoc)
124: * @see edu.umd.cs.findbugs.ba.AnnotationDatabase#addDefaultAnnotation(java.lang.String, java.lang.String, edu.umd.cs.findbugs.ba.AnnotationEnumeration)
125: */
126: @Override
127: public void addDefaultAnnotation(AnnotationDatabase.Target target,
128: String c, NullnessAnnotation n) {
129: super .addDefaultAnnotation(target, c, n);
130: }
131:
132: /* (non-Javadoc)
133: * @see edu.umd.cs.findbugs.ba.AnnotationDatabase#addFieldAnnotation(java.lang.String, java.lang.String, java.lang.String, boolean, edu.umd.cs.findbugs.ba.AnnotationEnumeration)
134: */
135: @Override
136: public void addFieldAnnotation(String name, String name2,
137: String sig, boolean isStatic, NullnessAnnotation annotation) {
138: super
139: .addFieldAnnotation(name, name2, sig, isStatic,
140: annotation);
141: }
142:
143: /* (non-Javadoc)
144: * @see edu.umd.cs.findbugs.ba.AnnotationDatabase#addMethodAnnotation(java.lang.String, java.lang.String, java.lang.String, boolean, edu.umd.cs.findbugs.ba.AnnotationEnumeration)
145: */
146: @Override
147: public void addMethodAnnotation(String name, String name2,
148: String sig, boolean isStatic, NullnessAnnotation annotation) {
149: super .addMethodAnnotation(name, name2, sig, isStatic,
150: annotation);
151: }
152:
153: /* (non-Javadoc)
154: * @see edu.umd.cs.findbugs.ba.AnnotationDatabase#addMethodParameterAnnotation(java.lang.String, java.lang.String, java.lang.String, boolean, int, edu.umd.cs.findbugs.ba.AnnotationEnumeration)
155: */
156: @Override
157: public void addMethodParameterAnnotation(String name, String name2,
158: String sig, boolean isStatic, int param,
159: NullnessAnnotation annotation) {
160: super.addMethodParameterAnnotation(name, name2, sig, isStatic,
161: param, annotation);
162: }
163: }
|