001package daikon;
002
003import daikon.inv.DummyInvariant;
004import daikon.split.Splitter;
005import org.checkerframework.checker.initialization.qual.Initialized;
006import org.checkerframework.checker.nullness.qual.Nullable;
007
008// Information about a disjunctive program point that represents just part
009// of the data.
010// This doesn't do any direct computation, instead deferring that to its
011// views that are slices.
012
013// This perhaps shouldn't extend PptTopLevel; fix that in the future.
014// For now, it's convenient to take advantage of its functionality.
015// And they're so similar that maybe this is the right thing after all.
016public final class PptConditional extends PptTopLevel {
017  static final long serialVersionUID = 20041216L;
018
019  public PptTopLevel parent;
020  public transient Splitter splitter;
021  // indicates whether we're on the true side or the false side of the Splitter
022  public boolean splitter_inverse;
023
024  // This does not install the variable values.  The reason is that it's
025  // more efficient to do that for two PptConditional objects at once.
026
027  public PptConditional(PptTopLevel parent, Splitter splitter, boolean splitter_inverse) {
028
029    super(ctor_name_helper(parent, splitter, splitter_inverse), ctor_vis_helper(parent));
030    // assert splitter.instantiated() == false;
031    this.parent = parent;
032    @SuppressWarnings({"nullness"}) // won't be used until it's fully initialized
033    @Initialized PptConditional thisNonRaw = this;
034    this.splitter = splitter.instantiateSplitter(thisNonRaw);
035    this.splitter_inverse = splitter_inverse;
036    // assert splitter.instantiated() == false;
037    // assert this.splitter.instantiated() == true;
038    // jhp this.invflow_ppts = new PptTopLevel[0];
039    // jhp this.invflow_transforms = new int[0][];
040  }
041
042  private static String ctor_name_helper(
043      PptTopLevel parent, Splitter splitter, boolean splitter_inverse) {
044    if (splitter_inverse) {
045      return parent.name + ";condition=\"not(" + splitter.condition() + ")\"";
046    } else {
047      return parent.name + ";condition=\"" + splitter.condition() + "\"";
048    }
049  }
050
051  private static VarInfo[] ctor_vis_helper(PptTopLevel parent) {
052    return VarInfo.arrayclone_simple(parent.var_infos);
053  }
054
055  // This is tested after constructing a PptConditional but before
056  // installing it on any lists.  It should perhaps be checked earlier, but
057  // it's convenient (for the Splitter writer) to do so after instantiating.
058  public boolean splitter_valid() {
059    return splitter.valid();
060  }
061
062  public @Nullable DummyInvariant dummyInvariant() {
063    return splitter.getDummyInvariant();
064  }
065}