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 // We are Serializable, so we specify a version to allow changes to 018 // method signatures without breaking serialization. If you add or 019 // remove fields, you should change this number to the current date. 020 static final long serialVersionUID = 20041216L; 021 022 public PptTopLevel parent; 023 public transient Splitter splitter; 024 // indicates whether we're on the true side or the false side of the Splitter 025 public boolean splitter_inverse; 026 027 // This does not install the variable values. The reason is that it's 028 // more efficient to do that for two PptConditional objects at once. 029 030 public PptConditional(PptTopLevel parent, Splitter splitter, boolean splitter_inverse) { 031 032 super(ctor_name_helper(parent, splitter, splitter_inverse), ctor_vis_helper(parent)); 033 // assert splitter.instantiated() == false; 034 this.parent = parent; 035 @SuppressWarnings({"nullness"}) // won't be used until it's fully initialized 036 @Initialized PptConditional thisNonRaw = this; 037 this.splitter = splitter.instantiateSplitter(thisNonRaw); 038 this.splitter_inverse = splitter_inverse; 039 // assert splitter.instantiated() == false; 040 // assert this.splitter.instantiated() == true; 041 // jhp this.invflow_ppts = new PptTopLevel[0]; 042 // jhp this.invflow_transforms = new int[0][]; 043 } 044 045 private static String ctor_name_helper( 046 PptTopLevel parent, Splitter splitter, boolean splitter_inverse) { 047 if (splitter_inverse) { 048 return parent.name + ";condition=\"not(" + splitter.condition() + ")\""; 049 } else { 050 return parent.name + ";condition=\"" + splitter.condition() + "\""; 051 } 052 } 053 054 private static VarInfo[] ctor_vis_helper(PptTopLevel parent) { 055 return VarInfo.arrayclone_simple(parent.var_infos); 056 } 057 058 // This is tested after constructing a PptConditional but before 059 // installing it on any lists. It should perhaps be checked earlier, but 060 // it's convenient (for the Splitter writer) to do so after instantiating. 061 public boolean splitter_valid() { 062 return splitter.valid(); 063 } 064 065 public @Nullable DummyInvariant dummyInvariant() { 066 return splitter.getDummyInvariant(); 067 } 068}