001package daikon.chicory; 002 003import java.util.EnumSet; 004import org.checkerframework.dataflow.qual.Pure; 005 006/** 007 * The ParameterInfo class is a subtype of DaikonVariableInfo used for variable types which are 008 * arguments to procedures. 009 * 010 * <p>This class takes "precedence" over when a seeming conflict could arise. For instance, 011 * consider: public static sort(int array[]). Is the "array" parameter represented as an 012 * ParameterInfo object or an ArrayInfo object? Because ParameterInfo takes precedence, it is the 013 * former. This makes sense because the arrays are really treated as hash codes at the first level, 014 * so such a parameter needs no array-specific processing (at this level of the tree at least). 015 */ 016public class ParameterInfo extends DaikonVariableInfo { 017 /** 018 * The argument number for this parameter. For instance, consider the method void x(int a, double 019 * b, Object c). Then a, b, and c have argument numbers 0, 1 and 2 respectively. 020 */ 021 private final int argNum; 022 023 /** 024 * Offset of this parameter in the local table. This is similar to the argument number except that 025 * doubles and longs take up two slots each. 026 */ 027 private final int param_offset; 028 029 /** Argument type. */ 030 private final Class<?> argType; 031 032 /** True if this parameter is of a primitive type. */ 033 boolean isPrimitive; 034 035 /** 036 * Constructs an ParameterInfo object with the specified name. 037 * 038 * @param theName the variable name (used in the declaration) 039 */ 040 public ParameterInfo(String theName, int theArgNum, Class<?> argType, int param_offset) { 041 super( 042 theName, 043 stdClassName(argType) + DaikonVariableInfo.isParamString, 044 getRepName(argType, false)); 045 046 argNum = theArgNum; 047 this.param_offset = param_offset; 048 this.argType = argType; 049 this.isPrimitive = argType.isPrimitive(); 050 } 051 052 /** 053 * Constructs a PamterInfo object with the name/type specified for this the specified argument 054 * number in mi. 055 */ 056 public ParameterInfo(MethodInfo mi, int theArgNum, int param_offset) { 057 this(mi.arg_names[theArgNum], theArgNum, mi.arg_types[theArgNum], param_offset); 058 } 059 060 /** Returns the argument number for this parameter. */ 061 public int getArgNum() { 062 return argNum; 063 } 064 065 /** Returns the offset in the local table for this parameter. */ 066 public int get_param_offset() { 067 return param_offset; 068 } 069 070 @Override 071 public Object getMyValFromParentVal(Object value) { 072 // a parameter has no parent value 073 throw new RuntimeException("Parameters have no parent value"); 074 } 075 076 public Class<?> getType() { 077 return argType; 078 } 079 080 /** Returns whether or not this parameter is a primitive type. */ 081 @Pure 082 public boolean isPrimitive() { 083 return isPrimitive; 084 } 085 086 /** Parameters are not enclosed in other variable, so they are of kind VARIABLE. */ 087 @Override 088 public VarKind get_var_kind() { 089 return VarKind.VARIABLE; 090 } 091 092 /** Add IS_PARM to list of variable flags. */ 093 @Override 094 public EnumSet<VarFlags> get_var_flags() { 095 // System.out.printf("%s is a parameter%n", this); 096 EnumSet<VarFlags> var_flags = super.get_var_flags(); 097 var_flags.add(VarFlags.IS_PARAM); 098 return var_flags; 099 } 100}