edu.umd.cs.findbugs.ba.vna.ValueNumberFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spotbugs Show documentation
Show all versions of spotbugs Show documentation
SpotBugs: Because it's easy!
The newest version!
/*
* Bytecode Analysis Framework
* Copyright (C) 2003,2004 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.vna;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.CheckForNull;
import edu.umd.cs.findbugs.internalAnnotations.DottedClassName;
import edu.umd.cs.findbugs.util.ClassName;
/**
* Factory for ValueNumbers. A single Factory must be used to create all of the
* ValueNumbers for a method.
*
* @author David Hovemeyer
* @see ValueNumber
*/
public class ValueNumberFactory {
/**
* Store all allocated value numbers.
*/
private ArrayList allocatedValueList = new ArrayList<>();
private final HashMap classObjectValueMap = new HashMap<>();
/**
* Create a fresh (unique) value number.
*/
public ValueNumber createFreshValue() {
ValueNumber result = ValueNumber.createValueNumber(getNumValuesAllocated());
allocatedValueList.add(result);
return result;
}
public ValueNumber createFreshValue(int flags) {
ValueNumber result = ValueNumber.createValueNumber(getNumValuesAllocated(), flags);
allocatedValueList.add(result);
return result;
}
/**
* Return a previously allocated value.
*/
public ValueNumber forNumber(int number) {
if (number >= getNumValuesAllocated()) {
throw new IllegalArgumentException("Value " + number + " has not been allocated");
}
return allocatedValueList.get(number);
}
/**
* Get the number of values which have been created.
*/
public int getNumValuesAllocated() {
return allocatedValueList.size();
}
/**
* Compact the value numbers produced by this factory.
*
* @param map
* array mapping old numbers to new numbers
* @param numValuesAllocated
* the number of values allocated in the new numbering
*/
@Deprecated
public void compact(int[] map, int numValuesAllocated) {
throw new UnsupportedOperationException();
}
/**
* Get the ValueNumber for given class's Class object.
*
* @param className
* the class
*/
public ValueNumber getClassObjectValue(@DottedClassName String className) {
// assert className.indexOf('.') == -1;
// TODO: Check to see if we need to do this
className = ClassName.toDottedClassName(className);
ValueNumber value = classObjectValueMap.get(className);
if (value == null) {
value = createFreshValue(ValueNumber.CONSTANT_CLASS_OBJECT);
classObjectValueMap.put(className, value);
}
return value;
}
public @CheckForNull @DottedClassName String getClassName(ValueNumber v) {
if (!v.hasFlag(ValueNumber.CONSTANT_CLASS_OBJECT)) {
throw new IllegalArgumentException("Not a value number for a constant class");
}
for (Map.Entry e : classObjectValueMap.entrySet()) {
if (e.getValue().equals(v)) {
return e.getKey();
}
}
return null;
}
}