⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 annotationdatabase.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
字号:
/* * FindBugs - Find Bugs in Java programs * Copyright (C) 2005, 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;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;import java.util.TreeSet;import org.apache.bcel.Repository;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import edu.umd.cs.findbugs.SystemProperties;import edu.umd.cs.findbugs.annotations.CheckForNull;import edu.umd.cs.findbugs.ba.ch.Subtypes;import edu.umd.cs.findbugs.util.MapCache;/** * @author William Pugh */public class AnnotationDatabase<AnnotationEnum extends AnnotationEnumeration<AnnotationEnum>> {	static final boolean DEBUG = SystemProperties.getBoolean("annotations.debug");	public static final boolean IGNORE_BUILTIN_ANNOTATIONS = SystemProperties.getBoolean("findbugs.ignoreBuiltinAnnotations");	/**	 * 	 */	public static final String FIELD = "Field";	/**	 * 	 */	public static final String METHOD = "Method";	/**	 * 	 */	public static final String PARAMETER = "Parameter";	/**	 * 	 */	public static final String ANY = "Any";	private static final String DEFAULT_ANNOTATION_ANNOTATION_CLASS = "DefaultAnnotation";	private Map<Object, AnnotationEnum> directAnnotations = new HashMap<Object, AnnotationEnum>();	private Set<Object> syntheticElements = new HashSet<Object>();	private final Map<String, Map<String, AnnotationEnum>> defaultAnnotation = new HashMap<String, Map<String, AnnotationEnum>>();	private Subtypes subtypes;	public AnnotationDatabase() {		defaultAnnotation.put(ANY,				new HashMap<String, AnnotationEnum>());		defaultAnnotation.put(PARAMETER,				new HashMap<String, AnnotationEnum>());		defaultAnnotation.put(METHOD,				new HashMap<String, AnnotationEnum>());		defaultAnnotation.put(FIELD,				new HashMap<String, AnnotationEnum>());		subtypes = AnalysisContext.currentAnalysisContext().getSubtypes();	}	public void loadAuxiliaryAnnotations() {	}	private final Set<AnnotationEnum> seen = new HashSet<AnnotationEnum>();	public void addSyntheticElement(Object o) {		syntheticElements.add(o);		if (DEBUG)			System.out.println("Synthetic element: " + o);	}	public void addDirectAnnotation(Object o, AnnotationEnum n) {		directAnnotations.put(o, n);		seen.add(n);	}	public void addDefaultAnnotation(String target, String c,			AnnotationEnum n) {		if (!defaultAnnotation.containsKey(target))			return;		if (DEBUG)			System.out.println("Default annotation " + target + " " + c + " " + n);		defaultAnnotation.get(target).put(c, n);		seen.add(n);	}	public boolean anyAnnotations(AnnotationEnum n) {		return seen.contains(n);	}	// TODO: Parameterize these values?	Map<Object, AnnotationEnum> cachedMinimal = new MapCache<Object, AnnotationEnum>(20000);	Map<Object, AnnotationEnum> cachedMaximal= new MapCache<Object, AnnotationEnum>(20000);	@CheckForNull	public AnnotationEnum getResolvedAnnotation(Object o, boolean getMinimal) {		Map<Object, AnnotationEnum> cache;		if (getMinimal) cache = cachedMinimal;		else cache = cachedMaximal;		if (cache.containsKey(o)) {			return cache.get(o);		}		AnnotationEnum n = getUncachedResolvedAnnotation(o, getMinimal);		if (DEBUG) System.out.println("TTT: " + o + " " + n);		cache.put(o,n);		return n;	}	public boolean annotationIsDirect(Object o) {		return directAnnotations.containsKey(o);	}	@CheckForNull	public AnnotationEnum getUncachedResolvedAnnotation(final Object o, boolean getMinimal) {		AnnotationEnum n = directAnnotations.get(o);		if (n != null)			return n;		try {			String className;			String kind;			boolean isParameterToInitMethodofAnonymousInnerClass = false;			boolean isSyntheticMethod = false;			if (o instanceof XMethod || o instanceof XMethodParameter) {				XMethod m;				if (o instanceof XMethod) {					m = (XMethod) o;					isSyntheticMethod = syntheticElements.contains(m);					kind = METHOD;					className = m.getClassName();				} else if (o instanceof XMethodParameter) {					m = ((XMethodParameter) o).getMethod();					// Don't 					isSyntheticMethod = syntheticElements.contains(m);					className = m.getClassName();					kind = PARAMETER;					if (m.getName().equals("<init>")) {						int i = className.lastIndexOf("$");						if (i+1 < className.length()								&& Character.isDigit(className.charAt(i+1)))								isParameterToInitMethodofAnonymousInnerClass = true;					}				} else					throw new IllegalStateException("impossible");				if (!m.isStatic() && !m.getName().equals("<init>")) {					JavaClass c = Repository.lookupClass(className);					// get inherited annotation					TreeSet<AnnotationEnum> inheritedAnnotations = new TreeSet<AnnotationEnum>();					if (c.getSuperclassNameIndex() > 0) {						n = lookInOverriddenMethod(o, c.getSuperclassName(), m, getMinimal);						if (n != null)							inheritedAnnotations.add(n);					}					for(String implementedInterface : c.getInterfaceNames()) {						n = lookInOverriddenMethod(o, implementedInterface, m, getMinimal);						if (n != null)							inheritedAnnotations.add(n);					}					if (DEBUG) System.out.println("# of inherited annotations : " + inheritedAnnotations.size());					if (!inheritedAnnotations.isEmpty()) {						if (inheritedAnnotations.size() == 1) 							return inheritedAnnotations.first();						if (!getMinimal) 							return inheritedAnnotations.last();						AnnotationEnum min = inheritedAnnotations.first();						if (min.getIndex() == 0) {							inheritedAnnotations.remove(min);							min = inheritedAnnotations.first();						}						return min;					}					// check to see if method is defined in this class;					// if not, on't consider default annotations					if (! classDefinesMethod(c, m) ) return null;					if (DEBUG) System.out.println("looking for default annotations: " + c.getClassName() + " defines " + m);				} // if not static				} // associated with method			 else if (o instanceof XField) {				className = ((XField) o).getClassName();				kind = FIELD;			} else if (o instanceof String) {				className = (String) o;				kind = "CLASS";			} else throw new IllegalArgumentException("Can't look up annotation for " + o.getClass().getName());			// <init> method parameters for inner classes don't inherit default annotations			// since some of them are synthetic			if (isParameterToInitMethodofAnonymousInnerClass) return null;			if (isSyntheticMethod) return null;			// synthetic elements should not inherit default annotations			if (syntheticElements.contains(o)) return null;			if (syntheticElements.contains(className)) return null;			// look for default annotation			n = defaultAnnotation.get(kind).get(className);			if (DEBUG) 				System.out.println("Default annotation for " + kind + " is " + n);			if (n != null)				return n;			n = defaultAnnotation.get(ANY).get(className);			if (DEBUG) 				System.out.println("Default annotation for any is " + n);			if (n != null)				return n;			int p = className.lastIndexOf('.');			className = className.substring(0,p+1) + "package-info";			n = defaultAnnotation.get(kind).get(className);			if (DEBUG) 				System.out.println("Default annotation for " + kind + " is " + n);			if (n != null)				return n;			n = defaultAnnotation.get(ANY).get(className);			if (DEBUG) 				System.out.println("Default annotation for any is " + n);			if (n != null)				return n;			return n;		} catch (ClassNotFoundException e) {			AnalysisContext.reportMissingClass(e);			return null;		}	}	private boolean classDefinesMethod(JavaClass c, XMethod m) {		for(Method definedMethod : c.getMethods()) 			if (definedMethod.getName().equals(m.getName())					&& definedMethod.getSignature().equals(m.getSignature())					&& definedMethod.isStatic() == m.isStatic())				return true;		return false;	}	private AnnotationEnum lookInOverriddenMethod(final Object originalQuery, 			String classToLookIn, XMethod originalMethod, boolean getMinimal) {		try {		AnnotationEnum n;		// Look in supermethod		XMethod superMethod = XFactory.createXMethod(classToLookIn, originalMethod.getName(),				originalMethod.getSignature(), originalMethod.isStatic());		if (!superMethod.isResolved()) return null;		if (DEBUG)			System.out.println("Looking for overridden method " + superMethod);		Object probe;		if (originalQuery instanceof XMethod)			probe = superMethod;		else if (originalQuery instanceof XMethodParameter)			probe = new XMethodParameter(superMethod,					((XMethodParameter) originalQuery).getParameterNumber());		else			throw new IllegalStateException("impossible");		n = getResolvedAnnotation(probe, getMinimal);		return n;		} catch (RuntimeException e) {			e.printStackTrace();			throw e;		}	}	boolean addClassOnly = false;	public boolean setAddClassOnly(boolean newValue) {		boolean oldValue = addClassOnly;		addClassOnly = newValue;		return oldValue;	}	protected void addDefaultMethodAnnotation(String cName, AnnotationEnum annotation) {		subtypes.addNamedClass(cName);		if (addClassOnly) return;			addDefaultAnnotation(AnnotationDatabase.METHOD, cName, annotation);	}	protected void addFieldAnnotation(String cName, String mName, String mSig, boolean isStatic, AnnotationEnum annotation) {		subtypes.addNamedClass(cName);		if (addClassOnly) return;		XField m = XFactory.createXField(cName, mName, mSig, isStatic);		addDirectAnnotation(m, annotation);	}	protected void addMethodAnnotation(String cName, String mName, String mSig, boolean isStatic, AnnotationEnum annotation) {		subtypes.addNamedClass(cName);		if (addClassOnly) return;		XMethod m = XFactory.createXMethod(cName, mName, mSig, isStatic);		addDirectAnnotation(m, annotation);	}	private boolean onlyAppliesToReferenceParameters(AnnotationEnum annotation) {		// return annotation instanceof NullnessAnnotation; work around JDK bug		return true;	}	protected void addMethodParameterAnnotation(String cName, String mName, String mSig, boolean isStatic, int param, AnnotationEnum annotation) {		subtypes.addNamedClass(cName);		if (addClassOnly) return;		SignatureParser parser = new SignatureParser(mSig);		if (param < 0 || param >= parser.getNumParameters())			throw new IllegalArgumentException("can't annotation parameter #" + param + " of " + cName +"." + mName + mSig);		String signature = parser.getParameter(param);		char firstChar = signature.charAt(0);		boolean isReference = firstChar == 'L' || firstChar == '[';		if (onlyAppliesToReferenceParameters(annotation) && !isReference) {			AnalysisContext.logError("Can't apply " + 					annotation + " to parameter " + param + " with signature " + signature + 					" of " + cName +"." + mName +" : " + mSig);			return;		}		XMethod m = XFactory.createXMethod(cName, mName, mSig, isStatic);		addDirectAnnotation(new XMethodParameter(m, param), annotation);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -