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}