/*
* FindBugs - Find Bugs in Java programs
* Copyright (C) 2003-2008, University of Maryland
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.umd.cs.findbugs.ba.jsr305;
import edu.umd.cs.findbugs.SystemProperties;
import edu.umd.cs.findbugs.classfile.MethodDescriptor;
import edu.umd.cs.findbugs.util.DualKeyHashMap;
import java.util.HashMap;
import java.util.Map;
/**
* Store computed type qualifiers for method parameters
* and return values. This allows interprocedural checking
* of type qualifiers.
*
* @author David Hovemeyer
*/
public class TypeQualifierDatabase {
/**
* If true, populate and use interprocedural database.
*/
public static final boolean USE_DATABASE = SystemProperties.getBoolean("ctq.usedatabase", true);
public static final boolean DEBUG = SystemProperties.getBoolean("ctq.db.debug");
private Map<MethodDescriptor, Map<TypeQualifierValue, TypeQualifierAnnotation>> returnValueMap;
private DualKeyHashMap<MethodDescriptor, Integer, Map<TypeQualifierValue, TypeQualifierAnnotation>> parameterMap;
/**
* Constructor.
*/
public TypeQualifierDatabase() {
this.returnValueMap = new HashMap<MethodDescriptor, Map<TypeQualifierValue, TypeQualifierAnnotation>>();
this.parameterMap = new DualKeyHashMap<MethodDescriptor, Integer, Map<TypeQualifierValue, TypeQualifierAnnotation>>();
}
/**
* Set a TypeQualifierAnnotation on a method return value.
*
* @param methodDesc the method
* @param tqv the type qualifier
* @param tqa the type qualifier annotation
*/
public void setReturnValue(MethodDescriptor methodDesc, TypeQualifierValue tqv, TypeQualifierAnnotation tqa) {
Map<TypeQualifierValue, TypeQualifierAnnotation> map = returnValueMap.get(methodDesc);
if (map == null) {
map = new HashMap<TypeQualifierValue, TypeQualifierAnnotation>();
returnValueMap.put(methodDesc, map);
}
map.put(tqv, tqa);
if(DEBUG) {
System.out.println("tqdb: " + methodDesc + " for " + tqv + " ==> " + tqa);
}
}
/**
* Get the TypeQualifierAnnotation on a method return value.
*
* @param methodDesc the method
* @param tqv the type qualifier
* @return the type qualifier annotation on the method return value,
* or null if no (interesting) type qualifier annotation
* was computed for this method
*/
public TypeQualifierAnnotation getReturnValue(MethodDescriptor methodDesc, TypeQualifierValue tqv) {
//
// TODO: handling of overridden methods?
//
Map<TypeQualifierValue, TypeQualifierAnnotation> map = returnValueMap.get(methodDesc);
if (map == null) {
return null;
}
return map.get(tqv);
}
/**
* Set a TypeQualifierAnnotation on a method parameter.
*
* @param methodDesc the method
* @param param the parameter (0 == first parameter)
* @param tqv the type qualifier
* @param tqa the type qualifier annotation
*/
public void setParameter(MethodDescriptor methodDesc, int param, TypeQualifierValue tqv, TypeQualifierAnnotation tqa) {
Map<TypeQualifierValue, TypeQualifierAnnotation> map = parameterMap.get(methodDesc, param);
if (map == null) {
map = new HashMap<TypeQualifierValue, TypeQualifierAnnotation>();
parameterMap.put(methodDesc, param, map);
}
map.put(tqv, tqa);
if(DEBUG) {
System.out.println("tqdb: " + methodDesc + " parameter " + param + " for " + tqv + " ==> " + tqa);
}
}
/**
* Get the TypeQualifierAnnotation on a parameter.
*
* @param methodDesc the method
* @param param the parameter (0 == first parameter)
* @param tqv the type qualifier
* @return the type qualifier annotation on the method return value,
* or null if no (interesting) type qualifier annotation
* was computed for this method
*/
public TypeQualifierAnnotation getParameter(MethodDescriptor methodDesc, int param, TypeQualifierValue tqv) {
//
// TODO: handling of overridden methods?
//
Map<TypeQualifierValue, TypeQualifierAnnotation> map = parameterMap.get(methodDesc, param);
if (map == null) {
return null;
}
return map.get(tqv);
}
}