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}