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

📄 buginstance.java

📁 A static analysis tool to find bugs in Java programs
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/* * FindBugs - Find bugs in Java programs * Copyright (C) 2003-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;import java.io.IOException;import java.io.Serializable;import java.math.BigInteger;import java.security.MessageDigest;import java.util.ArrayList;import java.util.Collection;import java.util.Collections;import java.util.HashSet;import java.util.Iterator;import java.util.NoSuchElementException;import java.util.Set;import java.util.StringTokenizer;import org.apache.bcel.Constants;import org.apache.bcel.classfile.JavaClass;import org.apache.bcel.classfile.Method;import org.apache.bcel.classfile.Field;import org.apache.bcel.generic.ConstantPoolGen;import org.apache.bcel.generic.InstructionHandle;import org.apache.bcel.generic.InvokeInstruction;import org.apache.bcel.generic.MethodGen;import org.objectweb.asm.tree.ClassNode;import edu.umd.cs.findbugs.annotations.NonNull;import edu.umd.cs.findbugs.annotations.Nullable;import edu.umd.cs.findbugs.annotations.CheckForNull;import edu.umd.cs.findbugs.ba.AnalysisContext;import edu.umd.cs.findbugs.ba.ClassContext;import edu.umd.cs.findbugs.ba.JavaClassAndMethod;import edu.umd.cs.findbugs.ba.Location;import edu.umd.cs.findbugs.ba.XFactory;import edu.umd.cs.findbugs.ba.XField;import edu.umd.cs.findbugs.ba.XMethod;import edu.umd.cs.findbugs.ba.bcp.FieldVariable;import edu.umd.cs.findbugs.classfile.ClassDescriptor;import edu.umd.cs.findbugs.classfile.FieldDescriptor;import edu.umd.cs.findbugs.classfile.MethodDescriptor;import edu.umd.cs.findbugs.util.ClassName;import edu.umd.cs.findbugs.visitclass.DismantleBytecode;import edu.umd.cs.findbugs.visitclass.PreorderVisitor;import edu.umd.cs.findbugs.xml.XMLAttributeList;import edu.umd.cs.findbugs.xml.XMLOutput;/** * An instance of a bug pattern. * A BugInstance consists of several parts: * <p/> * <ul> * <li> the type, which is a string indicating what kind of bug it is; * used as a key for the FindBugsMessages resource bundle * <li> the priority; how likely this instance is to actually be a bug * <li> a list of <em>annotations</em> * </ul> * <p/> * The annotations describe classes, methods, fields, source locations, * and other relevant context information about the bug instance. * Every BugInstance must have at least one ClassAnnotation, which * describes the class in which the instance was found.  This is the * "primary class annotation". * <p/> * <p> BugInstance objects are built up by calling a string of <code>add</code> * methods.  (These methods all "return this", so they can be chained). * Some of the add methods are specialized to get information automatically from * a BetterVisitor or DismantleBytecode object. * * @author David Hovemeyer * @see BugAnnotation */public class BugInstance implements Comparable<BugInstance>, XMLWriteableWithMessages, Serializable, Cloneable {	private static final long serialVersionUID = 1L;	private String type;	private int priority;	private ArrayList<BugAnnotation> annotationList;	private int cachedHashCode;	private @CheckForNull  BugDesignation userDesignation;	private BugProperty propertyListHead, propertyListTail;	private String uniqueId;	private String oldInstanceHash;	private String instanceHash;	private int instanceOccurrenceNum;	private int instanceOccurrenceMax;	/*	 * The following fields are used for tracking Bug instances across multiple versions of software.	 * They are meaningless in a BugCollection for just one version of software. 	 */	private long firstVersion = 0;	private long lastVersion = -1;	private boolean introducedByChangeOfExistingClass;	private boolean removedByChangeOfPersistingClass;	/**	 * This value is used to indicate that the cached hashcode	 * is invalid, and should be recomputed.	 */	private static final int INVALID_HASH_CODE = 0;	/**	 * This value is used to indicate whether BugInstances should be reprioritized very low,	 * when the BugPattern is marked as experimental	 */	private static boolean adjustExperimental = false;	private static Set<String> bugTypes = Collections.synchronizedSet(new HashSet<String>());		/**	 * Constructor.	 *	 * @param type     the bug type	 * @param priority the bug priority	 */	public BugInstance(String type, int priority) {		this.type = type;		this.priority = priority;		annotationList = new ArrayList<BugAnnotation>(4);		cachedHashCode = INVALID_HASH_CODE;		if (bugTypes.add(type)) {			BugPattern p = I18N.instance().lookupBugPattern(type);			if (p == null) {				String msg = "Can't find definition of bug type " + type;				AnalysisContext.logError(msg, new IllegalArgumentException(msg));			}		}		if (adjustExperimental && isExperimental())			this.priority = Detector.EXP_PRIORITY;		boundPriority();	}	private void boundPriority() {		priority = boundedPriority(priority);	}	@Override	public Object clone() {		BugInstance dup;		try {			dup = (BugInstance) super.clone();			// Do deep copying of mutable objects			for (int i = 0; i < dup.annotationList.size(); ++i) {				dup.annotationList.set(i, (BugAnnotation) dup.annotationList.get(i).clone());			}			 dup.propertyListHead = dup.propertyListTail = null;			for (Iterator<BugProperty> i = propertyIterator(); i.hasNext(); ) {				dup.addProperty((BugProperty) i.next().clone());			}			return dup;		} catch (CloneNotSupportedException e) {			throw new AssertionError(e);		}	}	/**	 * Create a new BugInstance.	 * This is the constructor that should be used by Detectors.	 * 	 * @param detector the Detector that is reporting the BugInstance	 * @param type     the bug type	 * @param priority the bug priority	 */	public BugInstance(Detector detector, String type, int priority) {		this(type, priority);		if (detector != null) {			// Adjust priority if required			DetectorFactory factory =				DetectorFactoryCollection.instance().getFactoryByClassName(detector.getClass().getName());			if (factory != null) {				this.priority += factory.getPriorityAdjustment();				boundPriority();			}		}	}	/**	 * Create a new BugInstance.	 * This is the constructor that should be used by Detectors.	 * 	 * @param detector the Detector2 that is reporting the BugInstance	 * @param type     the bug type	 * @param priority the bug priority	 */	public BugInstance(Detector2 detector, String type, int priority) {		this(type, priority);		if (detector != null) {			// Adjust priority if required			DetectorFactory factory =				DetectorFactoryCollection.instance().getFactoryByClassName(detector.getDetectorClassName());			if (factory != null) {				this.priority += factory.getPriorityAdjustment();				boundPriority();			}		}	}	public static void setAdjustExperimental(boolean adjust) {		adjustExperimental = adjust;	}	/* ----------------------------------------------------------------------	 * Accessors	 * ---------------------------------------------------------------------- */	/**	 * Get the bug type.	 */	public String getType() {		return type;	}	/**	 * Get the BugPattern.	 */	public @NonNull BugPattern getBugPattern() {		BugPattern result =  I18N.instance().lookupBugPattern(getType());		if (result != null) return result;		AnalysisContext.logError("Unable to find description of bug pattern " + getType());		result = I18N.instance().lookupBugPattern("UNKNOWN");		if (result != null) return result;		return BugPattern.REALLY_UNKNOWN;	}	/**	 * Get the bug priority.	 */	public int getPriority() {		return priority;	}	/**	 * Get a string describing the bug priority and type.	 * e.g. "High Priority Correctness"	 * @return a string describing the bug priority and type	 */	public String getPriorityTypeString()	{		String priorityString = getPriorityString();		BugPattern bugPattern = this.getBugPattern();		//then get the category and put everything together		String categoryString;		if (bugPattern == null) categoryString = "Unknown category for " + getType();		else categoryString = I18N.instance().getBugCategoryDescription(bugPattern.getCategory());		return priorityString + " Priority " + categoryString;		//TODO: internationalize the word "Priority"	}	public String getPriorityTypeAbbreviation()	{		String priorityString = getPriorityAbbreviation();		return priorityString + " " + getCategoryAbbrev();	}	public String getCategoryAbbrev() {	    BugPattern bugPattern = getBugPattern();	    if (bugPattern == null) return "?";		return bugPattern.getCategoryAbbrev();    }	public String getPriorityString() {		//first, get the priority		int value = this.getPriority();		String priorityString;		if (value == Detector.HIGH_PRIORITY)			priorityString = edu.umd.cs.findbugs.L10N.getLocalString("sort.priority_high", "High");		else if (value == Detector.NORMAL_PRIORITY)			priorityString = edu.umd.cs.findbugs.L10N.getLocalString("sort.priority_normal", "Medium");		else if (value == Detector.LOW_PRIORITY)			priorityString = edu.umd.cs.findbugs.L10N.getLocalString("sort.priority_low", "Low");		else if (value == Detector.EXP_PRIORITY)			priorityString = edu.umd.cs.findbugs.L10N.getLocalString("sort.priority_experimental", "Experimental");		else			priorityString = edu.umd.cs.findbugs.L10N.getLocalString("sort.priority_ignore", "Ignore"); // This probably shouldn't ever happen, but what the hell, let's be complete		return priorityString;	}	public String getPriorityAbbreviation() {		return getPriorityString().substring(0,1);	}	/**	 * Set the bug priority.	 */	public void setPriority(int p) {		priority = boundedPriority(p);	}	private int boundedPriority(int p) {		return Math.max(Detector.HIGH_PRIORITY, Math.min(Detector.IGNORE_PRIORITY, p));	}	public void raisePriority() {		priority = boundedPriority(priority-1);	}	public void lowerPriority() {		priority = boundedPriority(priority+1);	}	public void lowerPriorityALot() {		priority = boundedPriority(priority+2);	}	/**	 * Is this bug instance the result of an experimental detector?	 */	public boolean isExperimental() {		BugPattern pattern = getBugPattern();		return (pattern != null) && pattern.isExperimental();	}	/**	 * Get the primary class annotation, which indicates where the bug occurs.	 */	public ClassAnnotation getPrimaryClass() {		return (ClassAnnotation) findAnnotationOfType(ClassAnnotation.class);	}	/**	 * Get the primary method annotation, which indicates where the bug occurs.	 */	public MethodAnnotation getPrimaryMethod() {		return (MethodAnnotation) findAnnotationOfType(MethodAnnotation.class);	}	/**	 * Get the primary method annotation, which indicates where the bug occurs.	 */	public FieldAnnotation getPrimaryField() {		return (FieldAnnotation) findAnnotationOfType(FieldAnnotation.class);	}	public BugInstance lowerPriorityIfDeprecated() {		MethodAnnotation m = getPrimaryMethod();		if (m != null && AnalysisContext.currentXFactory().getDeprecated().contains(XFactory.createXMethod(m)))				lowerPriority();		FieldAnnotation f = getPrimaryField();		if (f != null && AnalysisContext.currentXFactory().getDeprecated().contains(XFactory.createXField(f)))			lowerPriority();		return this;	}	/**	 * Find the first BugAnnotation in the list of annotations	 * that is the same type or a subtype as the given Class parameter.	 * 	 * @param cls the Class parameter	 * @return the first matching BugAnnotation of the given type,	 *         or null if there is no such BugAnnotation	 */	private BugAnnotation findAnnotationOfType(Class<? extends BugAnnotation> cls) {		for (Iterator<BugAnnotation> i = annotationIterator(); i.hasNext();) {			BugAnnotation annotation = i.next();			if (cls.isAssignableFrom(annotation.getClass()))				return annotation;		}		return null;	}	public LocalVariableAnnotation getPrimaryLocalVariableAnnotation() {		for (BugAnnotation annotation : annotationList) 			if (annotation instanceof LocalVariableAnnotation)				return (LocalVariableAnnotation) annotation;		return null;	}	/**	 * Get the primary source line annotation.	 * There is guaranteed to be one (unless some Detector constructed	 * an invalid BugInstance).	 *	 * @return the source line annotation	 */	public SourceLineAnnotation getPrimarySourceLineAnnotation() {		// Highest priority: return the first top level source line annotation		for (BugAnnotation annotation : annotationList) {			if (annotation instanceof SourceLineAnnotation)				return (SourceLineAnnotation) annotation;		}		// Next: Try primary method, primary field, primary class		SourceLineAnnotation srcLine;		if ((srcLine = inspectPackageMemberSourceLines(getPrimaryMethod())) != null)			return srcLine;		if ((srcLine = inspectPackageMemberSourceLines(getPrimaryField())) != null)			return srcLine;		if ((srcLine = inspectPackageMemberSourceLines(getPrimaryClass())) != null)			return srcLine;		// Last resort: throw exception		throw new IllegalStateException("BugInstance must contain at least one class, method, or field annotation");	}	public String getInstanceKey() {		StringBuffer buf = new StringBuffer(type);		for (BugAnnotation annotation : annotationList) {			if (annotation instanceof SourceLineAnnotation || annotation instanceof MethodAnnotation && !annotation.isSignificant()) {				// do nothing			} else {				buf.append(":");				buf.append(annotation.format("hash", null));			}		}		return buf.toString();	}	/**	 * If given PackageMemberAnnotation is non-null, return its	 * SourceLineAnnotation.	 * 	 * @param packageMember	 *            a PackageMemberAnnotation	 * @return the PackageMemberAnnotation's SourceLineAnnotation, or null if	 *         there is no SourceLineAnnotation	 */	private SourceLineAnnotation inspectPackageMemberSourceLines(PackageMemberAnnotation packageMember) {		return (packageMember != null) ? packageMember.getSourceLines() : null;	}	/**	 * Get an Iterator over all bug annotations.	 */	public Iterator<BugAnnotation> annotationIterator() {		return annotationList.iterator();	}	/**	 * Get the abbreviation of this bug instance's BugPattern.	 * This is the same abbreviation used by the BugCode which	 * the BugPattern is a particular species of.	 */	public String getAbbrev() {		BugPattern pattern = getBugPattern();		return pattern != null ? pattern.getAbbrev() : "<unknown bug pattern>";	}	/** set the user designation object. This will clobber any	 *  existing annotationText (or any other BugDesignation field). */	public void setUserDesignation(BugDesignation bd) {		userDesignation = bd;	}	/** return the user designation object, which may be null.	 * 	 *  A previous calls to getSafeUserDesignation(), setAnnotationText(),	 *  or setUserDesignation() will ensure it will be non-null

⌨️ 快捷键说明

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