001: /*
002: * FindBugs - Find Bugs in Java programs
003: * Copyright (C) 2003-2007 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.jsr305;
021:
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.HashSet;
025:
026: import javax.annotation.meta.When;
027:
028: import edu.umd.cs.findbugs.SystemProperties;
029: import edu.umd.cs.findbugs.ba.AnalysisContext;
030: import edu.umd.cs.findbugs.ba.AnalysisException;
031: import edu.umd.cs.findbugs.ba.SignatureParser;
032: import edu.umd.cs.findbugs.ba.XFactory;
033: import edu.umd.cs.findbugs.ba.XMethod;
034: import edu.umd.cs.findbugs.ba.ch.InheritanceGraphVisitor;
035: import edu.umd.cs.findbugs.ba.ch.OverriddenMethodsVisitor;
036: import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
037: import edu.umd.cs.findbugs.classfile.Global;
038: import edu.umd.cs.findbugs.classfile.IAnalysisCache;
039: import edu.umd.cs.findbugs.classfile.MethodDescriptor;
040:
041: /**
042: * @author pugh
043: */
044: public class Analysis {
045: private static final boolean DEBUG = SystemProperties
046: .getBoolean("ctq.debug.analysis");
047:
048: public static Collection<TypeQualifierValue> getRelevantTypeQualifiers(
049: MethodDescriptor methodDescriptor)
050: throws CheckedAnalysisException {
051:
052: final IAnalysisCache analysisCache = Global.getAnalysisCache();
053: final HashSet<TypeQualifierValue> result = new HashSet<TypeQualifierValue>();
054:
055: XMethod xmethod = XFactory.createXMethod(methodDescriptor);
056:
057: if (methodDescriptor.isStatic()) {
058: getDirectlyRelevantTypeQualifiers(xmethod, analysisCache,
059: result);
060: } else {
061:
062: // Instance method - must consider type qualifiers inherited from superclasses
063:
064: InheritanceGraphVisitor visitor = new OverriddenMethodsVisitor(
065: xmethod) {
066: /* (non-Javadoc)
067: * @see edu.umd.cs.findbugs.ba.ch.OverriddenMethodsVisitor#visitOverriddenMethod(edu.umd.cs.findbugs.ba.XMethod)
068: */
069: @Override
070: protected boolean visitOverriddenMethod(XMethod xmethod) {
071: getDirectlyRelevantTypeQualifiers(xmethod,
072: analysisCache, result);
073: return true;
074: }
075: };
076:
077: try {
078: AnalysisContext.currentAnalysisContext().getSubtypes2()
079: .traverseSupertypes(
080: xmethod.getClassDescriptor(), visitor);
081: } catch (ClassNotFoundException e) {
082: AnalysisContext.currentAnalysisContext()
083: .getLookupFailureCallback().reportMissingClass(
084: e);
085: return (Collection<TypeQualifierValue>) Collections.EMPTY_SET;
086: } catch (AnalysisException e) {
087: AnalysisContext.currentAnalysisContext()
088: .getLookupFailureCallback().logError(
089: "Error getting relevant type qualifiers for "
090: + xmethod.toString(), e);
091: return (Collection<TypeQualifierValue>) Collections.EMPTY_SET;
092: }
093: }
094:
095: return result;
096:
097: }
098:
099: private static void getDirectlyRelevantTypeQualifiers(
100: XMethod xmethod, IAnalysisCache analysisCache,
101: HashSet<TypeQualifierValue> result) {
102: result.addAll(AnalysisContext.currentAnalysisContext()
103: .getDirectlyRelevantTypeQualifiersDatabase()
104: .getDirectlyRelevantTypeQualifiers(
105: xmethod.getMethodDescriptor()));
106:
107: }
108:
109: /**
110: * @param result
111: * @param m
112: */
113: public static void addKnownTypeQualifiersForParameters(
114: HashSet<TypeQualifierValue> result, XMethod m) {
115: int numParameters = new SignatureParser(m.getSignature())
116: .getNumParameters();
117: for (int p = 0; p < numParameters; p++)
118: addKnownTypeQualifiers(result, TypeQualifierApplications
119: .getApplicableApplications(m, p));
120: }
121:
122: /**
123: * @param result
124: * @param applicableApplications
125: */
126: public static void addKnownTypeQualifiers(
127: HashSet<TypeQualifierValue> result,
128: Collection<TypeQualifierAnnotation> applicableApplications) {
129: for (TypeQualifierAnnotation t : applicableApplications)
130: if (t.when != When.UNKNOWN)
131: result.add(t.typeQualifier);
132: }
133:
134: }
|