<commit_before>/*
 * 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.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 <NAME>
 * @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;

	/**
	 * 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 (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) {<commit_msg>first time we see a bug instance with a type we can't lookup, log an error<commit_after>/*
 * 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 <NAME>
 * @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) {
{'fraction_non_alphanumeric': 0.09076578445200364, 'fraction_numerical': 0.005143947564921596, 'mean_word_length': 4.4815825375170535, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7387452', 'n_tokens_mistral': 3770, 'n_tokens_neox': 3502, 'n_words': 1173}