001package daikon.derive.unary;
002
003import daikon.ValueTuple;
004import daikon.VarInfo;
005import daikon.derive.Derivation;
006import daikon.derive.ValueAndModified;
007import org.checkerframework.checker.lock.qual.GuardSatisfied;
008import org.checkerframework.dataflow.qual.Pure;
009import org.checkerframework.dataflow.qual.SideEffectFree;
010import org.plumelib.util.ArraysPlume;
011
012public abstract class UnaryDerivation extends Derivation {
013  static final long serialVersionUID = 20020122L;
014
015  public VarInfo base;
016
017  protected UnaryDerivation(VarInfo vi) {
018    base = vi;
019  }
020
021  @SideEffectFree
022  @Override
023  public UnaryDerivation clone(@GuardSatisfied UnaryDerivation this) {
024    try {
025      return (UnaryDerivation) super.clone();
026    } catch (CloneNotSupportedException e) {
027      throw new Error("This can't happen", e);
028    }
029  }
030
031  @Override
032  public Derivation switchVars(VarInfo[] old_vars, VarInfo[] new_vars) {
033    UnaryDerivation result = this.clone();
034    result.base = new_vars[ArraysPlume.indexOf(old_vars, result.base)];
035    return result;
036  }
037
038  @Override
039  public ValueAndModified computeValueAndModified(ValueTuple vt) {
040    int source_mod = base.getModified(vt);
041    if (source_mod == ValueTuple.MISSING_NONSENSICAL) {
042      return ValueAndModified.MISSING_NONSENSICAL;
043    }
044    if (source_mod == ValueTuple.MISSING_FLOW) {
045      return ValueAndModified.MISSING_FLOW;
046    }
047
048    return computeValueAndModifiedImpl(vt);
049  }
050
051  /** Actual implementation once mods are handled. */
052  protected abstract ValueAndModified computeValueAndModifiedImpl(ValueTuple vt);
053
054  public VarInfo base() {
055    return base;
056  }
057
058  @SideEffectFree
059  @Override
060  public VarInfo[] getBases() {
061    return new VarInfo[] {base()};
062  }
063
064  @Pure
065  @Override
066  public VarInfo getBase(int i) {
067    switch (i) {
068      case 0:
069        return base;
070      default:
071        throw new Error("bad base: " + i);
072    }
073  }
074
075  @Pure
076  @Override
077  protected boolean isParam() {
078    return base.isParam();
079  }
080
081  @Pure
082  @Override
083  public boolean isDerivedFromNonCanonical() {
084    return !base.isCanonical();
085  }
086
087  @Override
088  public int derivedDepth() {
089    return 1 + base.derivedDepth();
090  }
091
092  @Override
093  public boolean canBeMissing() {
094    return base.canBeMissing;
095  }
096}