@Test void assignment_order_should_not_lead_to_different_state() throws Exception { SymbolicValue sv = new SymbolicValue(); Symbol var1 = variable("var1"); Symbol var2 = variable("var2"); ProgramState ps1 = ProgramState.EMPTY_STATE; ps1 = ps1.put(var1, sv); ps1 = ps1.put(var2, sv); ProgramState ps2 = ProgramState.EMPTY_STATE; ps2 = ps2.put(var2, sv); ps2 = ps2.put(var1, sv); assertThat(ps1) .isEqualTo(ps2) .hasSameHashCodeAs(ps2); }
@VisibleForTesting public ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown() || isVolatileField(symbol)) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue); } return this; }
ProgramState { @VisibleForTesting public ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown() || isVolatileField(symbol)) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue); } return this; } }
ProgramState { @VisibleForTesting public ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown() || isVolatileField(symbol)) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue); } return this; } private  ProgramState(PMap<Symbol, SymbolicValue> values,PMap<Integer, SymbolicValue> valuesByIndex, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(PMap<Symbol, SymbolicValue> values, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(ProgramState ps, PStack<SymbolicValueSymbol> newStack); private  ProgramState(ProgramState ps, PMap<SymbolicValue, ConstraintsByDomain> newConstraints); }
ProgramState { @VisibleForTesting public ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown() || isVolatileField(symbol)) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue); } return this; } private  ProgramState(PMap<Symbol, SymbolicValue> values,PMap<Integer, SymbolicValue> valuesByIndex, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(PMap<Symbol, SymbolicValue> values, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(ProgramState ps, PStack<SymbolicValueSymbol> newStack); private  ProgramState(ProgramState ps, PMap<SymbolicValue, ConstraintsByDomain> newConstraints); ProgramState stackValue(SymbolicValue sv); ProgramState stackValue(SymbolicValue sv, @Nullable Symbol symbol); Pop unstackValue(int nbElements); @CheckForNull SymbolicValue peekValue(); SymbolicValueSymbol peekValueSymbol(); SymbolicValue peekValue(int i); List<SymbolicValue> peekValues(int n); List<SymbolicValueSymbol> peekValuesAndSymbols(int n); int numberOfTimeVisited(ProgramPoint programPoint); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString(); ProgramState addConstraintTransitively(SymbolicValue symbolicValue, Constraint constraint); Set<RelationalSymbolicValue> knownRelations(); ProgramState addConstraint(SymbolicValue symbolicValue, Constraint constraint); ProgramState addConstraints(SymbolicValue symbolicValue, ConstraintsByDomain constraintsForSV); ProgramState removeConstraintsOnDomain(SymbolicValue sv, Class<? extends Constraint> domain); @VisibleForTesting ProgramState put(Symbol symbol, SymbolicValue value); ProgramState cleanupDeadSymbols(Set<Symbol> liveVariables, Collection<SymbolicValue> protectedSymbolicValues); ProgramState cleanupConstraints(Collection<SymbolicValue> protectedSymbolicValues); static boolean isField(Symbol symbol); boolean canReach(SymbolicValue symbolicValue); ProgramState visitedPoint(ProgramPoint programPoint, int nbOfVisit); @Nullable ConstraintsByDomain getConstraints(SymbolicValue sv); @CheckForNull T getConstraint(SymbolicValue sv, Class<T> domain); int constraintsSize(); @CheckForNull SymbolicValue getValue(int index); @CheckForNull SymbolicValue getValue(Symbol symbol); List<SymbolicValue> getValuesWithConstraints(final Constraint constraint); void storeExitValue(); @CheckForNull SymbolicValue exitValue(); boolean exitingOnRuntimeException(); }
ProgramState { @VisibleForTesting public ProgramState put(Symbol symbol, SymbolicValue value) { if (symbol.isUnknown() || isVolatileField(symbol)) { return this; } SymbolicValue oldValue = values.get(symbol); if (oldValue == null || oldValue != value) { PMap<SymbolicValue, Integer> newReferences = references; if (oldValue != null) { newReferences = decreaseReference(newReferences, oldValue); } newReferences = increaseReference(newReferences, value); PMap<Symbol, SymbolicValue> newValues = values.put(symbol, value); return new ProgramState(newValues, newReferences, constraints, visitedPoints, stack, exitSymbolicValue); } return this; } private  ProgramState(PMap<Symbol, SymbolicValue> values,PMap<Integer, SymbolicValue> valuesByIndex, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(PMap<Symbol, SymbolicValue> values, PMap<SymbolicValue, Integer> references,
                       PMap<SymbolicValue, ConstraintsByDomain> constraints, PMap<ProgramPoint, Integer> visitedPoints,
                       PStack<SymbolicValueSymbol> stack, SymbolicValue exitSymbolicValue); private  ProgramState(ProgramState ps, PStack<SymbolicValueSymbol> newStack); private  ProgramState(ProgramState ps, PMap<SymbolicValue, ConstraintsByDomain> newConstraints); ProgramState stackValue(SymbolicValue sv); ProgramState stackValue(SymbolicValue sv, @Nullable Symbol symbol); Pop unstackValue(int nbElements); @CheckForNull SymbolicValue peekValue(); SymbolicValueSymbol peekValueSymbol(); SymbolicValue peekValue(int i); List<SymbolicValue> peekValues(int n); List<SymbolicValueSymbol> peekValuesAndSymbols(int n); int numberOfTimeVisited(ProgramPoint programPoint); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString(); ProgramState addConstraintTransitively(SymbolicValue symbolicValue, Constraint constraint); Set<RelationalSymbolicValue> knownRelations(); ProgramState addConstraint(SymbolicValue symbolicValue, Constraint constraint); ProgramState addConstraints(SymbolicValue symbolicValue, ConstraintsByDomain constraintsForSV); ProgramState removeConstraintsOnDomain(SymbolicValue sv, Class<? extends Constraint> domain); @VisibleForTesting ProgramState put(Symbol symbol, SymbolicValue value); ProgramState cleanupDeadSymbols(Set<Symbol> liveVariables, Collection<SymbolicValue> protectedSymbolicValues); ProgramState cleanupConstraints(Collection<SymbolicValue> protectedSymbolicValues); static boolean isField(Symbol symbol); boolean canReach(SymbolicValue symbolicValue); ProgramState visitedPoint(ProgramPoint programPoint, int nbOfVisit); @Nullable ConstraintsByDomain getConstraints(SymbolicValue sv); @CheckForNull T getConstraint(SymbolicValue sv, Class<T> domain); int constraintsSize(); @CheckForNull SymbolicValue getValue(int index); @CheckForNull SymbolicValue getValue(Symbol symbol); List<SymbolicValue> getValuesWithConstraints(final Constraint constraint); void storeExitValue(); @CheckForNull SymbolicValue exitValue(); boolean exitingOnRuntimeException(); static final ProgramState EMPTY_STATE; }