public abstract class CFAbstractStore<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>> extends Object implements Store<S>
When adding a new field to track values for a code construct (similar to localVariableValues and thisValue), it is important to review all constructors and
 methods in this class for locations where the new field must be handled (such as the copy
 constructor and clearValue), as well as all constructors/methods in subclasses of {code
 CFAbstractStore}. Note that this includes not only overridden methods in the subclasses, but new
 methods in the subclasses as well. Also check if
 BaseTypeVisitor#getFlowExpressionContextFromNode(Node) needs to be updated. Failing to do so may
 result in silent failures that are time consuming to debug.
Store.FlowRule, Store.Kind| Modifier and Type | Field and Description | 
|---|---|
| protected CFAbstractAnalysis<V,S,?> | analysisThe analysis class this store belongs to. | 
| protected Map<FlowExpressions.ArrayAccess,V> | arrayValuesInformation collected about arrays, using the internal representation  FlowExpressions.ArrayAccess. | 
| protected Map<FlowExpressions.ClassName,V> | classValuesInformation collected about classname.class values, using the internal representation
  FlowExpressions.ClassName. | 
| protected Map<FlowExpressions.FieldAccess,V> | fieldValuesInformation collected about fields, using the internal representation  FlowExpressions.FieldAccess. | 
| protected Map<FlowExpressions.LocalVariable,V> | localVariableValuesInformation collected about local variables (including method arguments). | 
| protected Map<FlowExpressions.MethodCall,V> | methodValuesInformation collected about method calls, using the internal representation  FlowExpressions.MethodCall. | 
| protected boolean | sequentialSemanticsShould the analysis use sequential Java semantics (i.e., assume that only one thread is
 running at all times)? | 
| protected V | thisValueInformation collected about the current object. | 
| Modifier | Constructor and Description | 
|---|---|
| protected  | CFAbstractStore(CFAbstractAnalysis<V,S,?> analysis,
               boolean sequentialSemantics) | 
| protected  | CFAbstractStore(CFAbstractStore<V,S> other)Copy constructor. | 
| Modifier and Type | Method and Description | 
|---|---|
| boolean | canAlias(FlowExpressions.Receiver a,
        FlowExpressions.Receiver b)Can the objects  aandbbe aliases? Returns a conservative answer (i.e.,
 returnstrueif not enough information is available to determine aliasing). | 
| static boolean | canInsertReceiver(FlowExpressions.Receiver r)Returns true if the receiver  rcan be stored in this store. | 
| void | clearValue(FlowExpressions.Receiver r)Remove any knowledge about the expression  r(correctly deciding where to remove the
 information depending on the type of the expressionr). | 
| S | copy()Returns an exact copy of this store. | 
| boolean | equals(@Nullable Object o) | 
| V | getValue(ArrayAccessNode n)Returns current abstract value of a field access, or  nullif no information is
 available. | 
| V | getValue(FieldAccessNode n)Returns current abstract value of a field access, or  nullif no information is
 available. | 
| V | getValue(FlowExpressions.Receiver expr)Returns current abstract value of a flow expression, or  nullif no information is
 available. | 
| V | getValue(LocalVariableNode n)Returns current abstract value of a local variable, or  nullif no information is
 available. | 
| V | getValue(MethodInvocationNode n)Returns current abstract value of a method call, or  nullif no information is
 available. | 
| V | getValue(ThisLiteralNode n)Returns current abstract value of the current object, or  nullif no information is
 available. | 
| int | hashCode() | 
| void | initializeMethodParameter(LocalVariableNode p,
                         V value)Set the abstract value of a method parameter (only adds the information to the store, does
 not remove any other knowledge). | 
| void | initializeThisValue(AnnotationMirror a,
                   TypeMirror underlyingType)Set the value of the current object. | 
| void | insertOrRefine(FlowExpressions.Receiver r,
              AnnotationMirror newAnno)Add the annotation  newAnnofor the expressionr(correctly deciding where to
 store the information depending on the type of the expressionr). | 
| void | insertThisValue(AnnotationMirror a,
               TypeMirror underlyingType) | 
| void | insertValue(FlowExpressions.Receiver r,
           AnnotationMirror a)Add the annotation  afor the expressionr(correctly deciding where to store
 the information depending on the type of the expressionr). | 
| void | insertValue(FlowExpressions.Receiver r,
           V value)Add the abstract value  valuefor the expressionr(correctly deciding where
 to store the information depending on the type of the expressionr). | 
| protected String | internalVisualize(CFGVisualizer<V,S,?> viz)Adds a representation of the internal information of this Store to visualizer  viz. | 
| protected boolean | isMonotonicUpdate(FlowExpressions.FieldAccess fieldAcc,
                 V value)Return true if fieldAcc is an update of a monotonic qualifier to its target qualifier. | 
| protected boolean | isSideEffectFree(AnnotatedTypeFactory atypeFactory,
                ExecutableElement method) | 
| S | leastUpperBound(S other)Compute the least upper bound of two stores. | 
| protected void | removeConflicting(FlowExpressions.ArrayAccess arrayAccess,
                 V val)Remove any information in the store that might not be true any more after  arrayAccesshas been assigned a new value (with the abstract valueval). | 
| protected void | removeConflicting(FlowExpressions.FieldAccess fieldAccess,
                 V val)Remove any information in this store that might not be true any more after  fieldAccesshas been assigned a new value (with the abstract valueval). | 
| protected void | removeConflicting(FlowExpressions.LocalVariable var)Remove any information in this store that might not be true any more after  localVarhas been assigned a new value. | 
| void | replaceValue(FlowExpressions.Receiver r,
            V value)Completely replaces the abstract value  valuefor the expressionr(correctly
 deciding where to store the information depending on the type of the expressionr). | 
| protected boolean | supersetOf(CFAbstractStore<V,S> other)Returns true iff this  CFAbstractStorecontains a superset of the map entries of the
 argumentCFAbstractStore. | 
| String | toString() | 
| protected void | updateForArrayAssignment(FlowExpressions.ArrayAccess arrayAccess,
                        V val)Update the information in the store by considering an assignment with target  n, where
 the target is an array access. | 
| void | updateForAssignment(Node n,
                   V val)Update the information in the store by considering an assignment with target  n. | 
| protected void | updateForFieldAccessAssignment(FlowExpressions.FieldAccess fieldAccess,
                              V val)Update the information in the store by considering a field assignment with target  n,
 where the right hand side has the abstract valueval. | 
| protected void | updateForLocalVariableAssignment(FlowExpressions.LocalVariable receiver,
                                V val)Set the abstract value of a local variable in the store. | 
| void | updateForMethodCall(MethodInvocationNode n,
                   AnnotatedTypeFactory atypeFactory,
                   V val)Remove any information that might not be valid any more after a method call, and add
 information guaranteed by the method. | 
| String | visualize(CFGVisualizer<?,S,?> viz)Delegate visualization responsibility to a visualizer. | 
| S | widenedUpperBound(S previous)Compute an upper bound of two stores that is wider than the least upper bound of the two
 stores. | 
protected final CFAbstractAnalysis<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>,?> analysis
protected final Map<FlowExpressions.LocalVariable,V extends CFAbstractValue<V>> localVariableValues
protected V extends CFAbstractValue<V> thisValue
protected Map<FlowExpressions.FieldAccess,V extends CFAbstractValue<V>> fieldValues
FlowExpressions.FieldAccess.protected Map<FlowExpressions.ArrayAccess,V extends CFAbstractValue<V>> arrayValues
FlowExpressions.ArrayAccess.protected Map<FlowExpressions.MethodCall,V extends CFAbstractValue<V>> methodValues
FlowExpressions.MethodCall.protected Map<FlowExpressions.ClassName,V extends CFAbstractValue<V>> classValues
FlowExpressions.ClassName.protected final boolean sequentialSemantics
protected CFAbstractStore(CFAbstractAnalysis<V,S,?> analysis, boolean sequentialSemantics)
protected CFAbstractStore(CFAbstractStore<V,S> other)
public void initializeMethodParameter(LocalVariableNode p, V value)
public void initializeThisValue(AnnotationMirror a, TypeMirror underlyingType)
protected boolean isSideEffectFree(AnnotatedTypeFactory atypeFactory, ExecutableElement method)
public void updateForMethodCall(MethodInvocationNode n, AnnotatedTypeFactory atypeFactory, V val)
SideEffectFree or Pure), then no information needs to be removed.
   a.f needs to be removed, except
       if the method n cannot modify a.f (e.g., if a is a local
       variable or this, and f is final).
   val in the store.public void insertValue(FlowExpressions.Receiver r, AnnotationMirror a)
a for the expression r (correctly deciding where to store
 the information depending on the type of the expression r).
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
If there is already a value v present for r, then the stronger of the new
 and old value are taken (according to the lattice). Note that this happens per hierarchy, and
 if the store already contains information about a hierarchy other than as hierarchy,
 that information is preserved.
public void insertOrRefine(FlowExpressions.Receiver r, AnnotationMirror newAnno)
newAnno for the expression r (correctly deciding where to
 store the information depending on the type of the expression r).
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
If there is already a value v present for r, then the greatest lower bound
 of the new and old value is inserted into the store unless it's bottom. Some checkers do not
 override QualifierHierarchy.greatestLowerBound(AnnotationMirror, AnnotationMirror)
 and the default implementation will return the bottom qualifier incorrectly. So this method
 conservatively does not insert the glb if it is bottom.
 
Note that this happens per hierarchy, and if the store already contains information about
 a hierarchy other than newAnno's hierarchy, that information is preserved.
public static boolean canInsertReceiver(FlowExpressions.Receiver r)
r can be stored in this store.public void insertValue(FlowExpressions.Receiver r, V value)
value for the expression r (correctly deciding where
 to store the information depending on the type of the expression r).
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
If there is already a value v present for r, then the stronger of the new
 and old value are taken (according to the lattice). Note that this happens per hierarchy, and
 if the store already contains information about a hierarchy for which value does not
 contain information, then that information is preserved.
protected boolean isMonotonicUpdate(FlowExpressions.FieldAccess fieldAcc, V value)
sequentialSemantics is
 true.public void insertThisValue(AnnotationMirror a, TypeMirror underlyingType)
public void replaceValue(FlowExpressions.Receiver r, V value)
value for the expression r (correctly
 deciding where to store the information depending on the type of the expression r).
 Any previous information is discarded.
 This method does not take care of removing other information that might be influenced by changes to certain parts of the state.
public void clearValue(FlowExpressions.Receiver r)
r (correctly deciding where to remove the
 information depending on the type of the expression r).public V getValue(FlowExpressions.Receiver expr)
null if no information is
 available.null if no information is
     availablepublic V getValue(FieldAccessNode n)
null if no information is
 available.null if no information is
     availablepublic V getValue(MethodInvocationNode n)
null if no information is
 available.null if no information is
     availablepublic V getValue(ArrayAccessNode n)
null if no information is
 available.null if no information is
     availablepublic void updateForAssignment(Node n, V val)
n.protected void updateForFieldAccessAssignment(FlowExpressions.FieldAccess fieldAccess, V val)
n,
 where the right hand side has the abstract value val.val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void updateForArrayAssignment(FlowExpressions.ArrayAccess arrayAccess, V val)
n, where
 the target is an array access.
 See removeConflicting(FlowExpressions.ArrayAccess,CFAbstractValue), as it is
 called first by this method.
protected void updateForLocalVariableAssignment(FlowExpressions.LocalVariable receiver, V val)
val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void removeConflicting(FlowExpressions.FieldAccess fieldAccess, V val)
fieldAccess has been assigned a new value (with the abstract value val). This
 includes the following steps (assume that fieldAccess is of the form a.f for
 some a.
 fieldAccess, a. This update will raise the abstract value
       for such field accesses to at least val (or the old value, if that was less
       precise). However, this is only necessary if the field g is not final.
   fieldAccess might alias any expression in the receiver b.
   fieldAccess might alias any expression in the receiver a or index i.
 val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void removeConflicting(FlowExpressions.ArrayAccess arrayAccess, V val)
arrayAccess
 has been assigned a new value (with the abstract value val). This includes the
 following steps (assume that arrayAccess is of the form a[i] for some
 a.
 val - the abstract value of the value assigned to n (or null if the
     abstract value is not known).protected void removeConflicting(FlowExpressions.LocalVariable var)
localVar
 has been assigned a new value. This includes the following steps:
 localVar might alias any expression in the receiver b.
   localVar might alias the receiver a.
   localVar.
 public boolean canAlias(FlowExpressions.Receiver a, FlowExpressions.Receiver b)
a and b be aliases? Returns a conservative answer (i.e.,
 returns true if not enough information is available to determine aliasing).public V getValue(LocalVariableNode n)
null if no information is
 available.null if no information is
     availablepublic V getValue(ThisLiteralNode n)
null if no information is
 available.null if no information is
     availablepublic S leastUpperBound(S other)
StoreImportant: This method must fulfill the following contract:
this.
   other.
   this, even if the signature is
       more permissive.
   leastUpperBound in interface Store<S extends CFAbstractStore<V,S>>public S widenedUpperBound(S previous)
StoreAnalysis. previous must be the previous store.
 A particular analysis might not require widening and should implement this method by calling leastUpperBound.
Important: This method must fulfill the following contract:
this.
   previous.
   this, even if the signature is
       more permissive.
   widenedUpperBound in interface Store<S extends CFAbstractStore<V,S>>previous - must be the previous storeprotected boolean supersetOf(CFAbstractStore<V,S> other)
CFAbstractStore contains a superset of the map entries of the
 argument CFAbstractStore. Note that we test the entry keys and values by Java
 equality, not by any subtype relationship. This method is used primarily to simplify the
 equals predicate.@SideEffectFree public String toString()
public String visualize(CFGVisualizer<?,S,?> viz)
Storeprotected String internalVisualize(CFGVisualizer<V,S,?> viz)
viz.Store