001// ***** This file is automatically generated from SequenceInitial.java.jpp 002 003package daikon.derive.unary; 004 005import org.checkerframework.checker.interning.qual.Interned; 006import org.checkerframework.dataflow.qual.Pure; 007import org.checkerframework.dataflow.qual.SideEffectFree; 008import daikon.*; 009import daikon.derive.*; 010import daikon.derive.binary.*; 011import org.plumelib.util.Intern; 012 013// originally from pass1. 014/** 015 * This represents a sequence element at a particular offset (such as first, second, penultimate, 016 * last). 017 */ 018public final class SequenceInitial extends UnaryDerivation { 019 static final long serialVersionUID = 20020122L; 020 021 // Variables starting with dkconfig_ should only be set via the 022 // daikon.config.Configuration interface. 023 /** Boolean. True iff SequenceInitial derived variables should be generated. */ 024 public static boolean dkconfig_enabled = false; 025 026 /** Typically 0, 1, -1, or -2. A negative number means counting from end. */ 027 public final int index; 028 029 /** Array length required for the subscript to be meaningful: (i.e., 1 or 2) */ 030 final int minLength; 031 032 SequenceInitial(VarInfo vi, int index) { 033 super(vi); 034 this.index = index; 035 if (index < 0) { 036 minLength = -index; 037 } else { 038 minLength = index + 1; 039 } 040 } 041 042 public VarInfo seqvar() { 043 return base; 044 } 045 046 public static boolean applicable(VarInfo vi) { 047 assert vi.rep_type == ProglangType.INT_ARRAY; 048 // For now, applicable if not a derived variable; a better test is if 049 // not a prefix subsequence (sequence slice) we have added. 050 if (vi.derived != null) { 051 assert (vi.derived instanceof SequenceScalarSubsequence) 052 || (vi.derived instanceof SequenceScalarIntersection) 053 || (vi.derived instanceof SequenceScalarUnion); 054 return false; 055 } 056 057 // If order doesn't matter 058 if (!vi.aux.hasOrder()) { 059 return false; 060 } 061 062 return true; 063 } 064 065 @Override 066 public ValueAndModified computeValueAndModifiedImpl(ValueTuple vt) { 067 int source_mod = base.getModified(vt); 068 if (source_mod == ValueTuple.MISSING_NONSENSICAL) { 069 return ValueAndModified.MISSING_NONSENSICAL; 070 } 071 Object val = base.getValue(vt); 072 if (val == null) { 073 return ValueAndModified.MISSING_NONSENSICAL; 074 } 075 if (base.rep_type == ProglangType.INT_ARRAY) { 076 long[] val_array = (long[]) val; 077 if (val_array.length < minLength) { 078 return ValueAndModified.MISSING_NONSENSICAL; 079 } 080 int real_index = (index < 0 ? val_array.length + index : index); 081 return new ValueAndModified(Intern.internedLong(val_array[real_index]), source_mod); 082 } else { 083 @Interned Object[] val_array = (@Interned Object[]) val; 084 if (val_array.length < minLength) { 085 return ValueAndModified.MISSING_NONSENSICAL; 086 } 087 int real_index = (index < 0 ? val_array.length + index : index); 088 return new ValueAndModified(val_array[real_index], source_mod); 089 } 090 } 091 092 @Override 093 protected VarInfo makeVarInfo() { 094 return VarInfo.make_subscript(base, null, index); 095 } 096 097 @Pure 098 @Override 099 public boolean isSameFormula(Derivation other) { 100 return (other instanceof SequenceInitial) 101 && (((SequenceInitial) other).index == this.index); 102 } 103 104 @SideEffectFree 105 @Override 106 public String esc_name(String index) { 107 return String.format("%s[0]", base.esc_name()); 108 } 109}