public abstract class CFAbstractStore<V extends CFAbstractValue<V>,S extends CFAbstractStore<V,S>> extends Object implements Store<S>
Store.FlowRule, Store.Kind
Modifier and Type | Field and Description |
---|---|
protected CFAbstractAnalysis<V,S,?> |
analysis
The analysis class this store belongs to.
|
protected Map<FlowExpressions.ArrayAccess,V> |
arrayValues
Information collected about arrays, using the internal representation
FlowExpressions.ArrayAccess . |
protected Map<FlowExpressions.ClassName,V> |
classValues |
protected Map<FlowExpressions.FieldAccess,V> |
fieldValues
Information collected about fields, using the internal representation
FlowExpressions.FieldAccess . |
protected Map<FlowExpressions.LocalVariable,V> |
localVariableValues
Information collected about local variables, which are identified by the
corresponding element.
|
protected Map<FlowExpressions.PureMethodCall,V> |
methodValues
Information collected about pure method calls, using the internal
representation
FlowExpressions.PureMethodCall . |
protected boolean |
sequentialSemantics
Should the analysis use sequential Java semantics (i.e., assume that only
one thread is running at all times)?
|
protected V |
thisValue
Information collected about the current object.
|
Modifier | Constructor and Description |
---|---|
|
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
a and b be aliases? Returns a
conservative answer (i.e., returns true if not enough information
is available to determine aliasing). |
static boolean |
canInsertReceiver(FlowExpressions.Receiver r)
Returns true if the receiver
r can 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 expression
r ). |
S |
copy() |
boolean |
equals(Object o) |
protected String |
escapeDoubleQuotes(String str) |
V |
getValue(ArrayAccessNode n) |
V |
getValue(FieldAccessNode n) |
V |
getValue(FlowExpressions.Receiver expr) |
V |
getValue(LocalVariableNode n) |
V |
getValue(MethodInvocationNode n) |
V |
getValue(ThisLiteralNode n) |
boolean |
hasDOToutput() |
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 |
insertThisValue(AnnotationMirror a,
TypeMirror underlyingType) |
void |
insertValue(FlowExpressions.Receiver r,
AnnotationMirror a)
Add the annotation
a for the expression r (correctly
deciding where to store the information depending on the type of the
expression r ). |
void |
insertValue(FlowExpressions.Receiver r,
V value)
Add the abstract value
value for the expression r
(correctly deciding where to store the information depending on the type
of the expression r ). |
protected void |
internalDotOutput(StringBuilder result)
Adds a DOT representation of the internal information of this store to
result . |
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
arrayAccess has been assigned a new value (with the abstract
value val ). |
protected void |
removeConflicting(FlowExpressions.FieldAccess fieldAccess,
V val)
Remove any information in this store that might not be true any more
after
fieldAccess has been assigned a new value (with the
abstract value val ). |
protected void |
removeConflicting(FlowExpressions.LocalVariable var)
Remove any information in this store that might not be true any more
after
localVar has been assigned a new value. |
void |
replaceValue(FlowExpressions.Receiver r,
V value)
Completely replaces the abstract value
value for the expression
r (correctly deciding where to store the information depending on
the type of the expression r ). |
protected boolean |
supersetOf(CFAbstractStore<V,S> other)
Returns true iff this
CFAbstractStore contains a superset of the
map entries of the argument CFAbstractStore . |
String |
toDOToutput() |
String |
toString() |
protected String |
toStringEscapeDoubleQuotes(Object obj) |
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 value
val . |
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.
|
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.PureMethodCall,V extends CFAbstractValue<V>> methodValues
FlowExpressions.PureMethodCall
.protected Map<FlowExpressions.ClassName,V extends CFAbstractValue<V>> classValues
protected final boolean sequentialSemantics
public 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 a
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.
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.public V getValue(FieldAccessNode n)
null
if no
information is available.public V getValue(MethodInvocationNode n)
null
if no
information is available.public V getValue(ArrayAccessNode n)
null
if no
information is available.public 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.
n
might alias any expression in the receiver b.
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.public V getValue(ThisLiteralNode n)
null
if no
information is available.public S copy()
public S leastUpperBound(S other)
Store
Important: 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>>
protected 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()
@Pure public boolean hasDOToutput()
hasDOToutput
in interface Store<S extends CFAbstractStore<V,S>>
public String toDOToutput()
toDOToutput
in interface Store<S extends CFAbstractStore<V,S>>
protected void internalDotOutput(StringBuilder result)
result
.