use of org.checkerframework.dataflow.expression.MethodCall in project checker-framework by typetools.
the class CFAbstractStore method supersetOf.
/**
* Returns true iff this {@link CFAbstractStore} contains a superset of the map entries of the
* argument {@link 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.
*/
protected boolean supersetOf(CFAbstractStore<V, S> other) {
for (Map.Entry<LocalVariable, V> e : other.localVariableValues.entrySet()) {
LocalVariable key = e.getKey();
V value = localVariableValues.get(key);
if (value == null || !value.equals(e.getValue())) {
return false;
}
}
if (!Objects.equals(thisValue, other.thisValue)) {
return false;
}
for (Map.Entry<FieldAccess, V> e : other.fieldValues.entrySet()) {
FieldAccess key = e.getKey();
V value = fieldValues.get(key);
if (value == null || !value.equals(e.getValue())) {
return false;
}
}
for (Map.Entry<ArrayAccess, V> e : other.arrayValues.entrySet()) {
ArrayAccess key = e.getKey();
V value = arrayValues.get(key);
if (value == null || !value.equals(e.getValue())) {
return false;
}
}
for (Map.Entry<MethodCall, V> e : other.methodValues.entrySet()) {
MethodCall key = e.getKey();
V value = methodValues.get(key);
if (value == null || !value.equals(e.getValue())) {
return false;
}
}
for (Map.Entry<ClassName, V> e : other.classValues.entrySet()) {
ClassName key = e.getKey();
V value = classValues.get(key);
if (value == null || !value.equals(e.getValue())) {
return false;
}
}
return true;
}
use of org.checkerframework.dataflow.expression.MethodCall in project checker-framework by typetools.
the class CFAbstractStore method upperBound.
private S upperBound(S other, boolean shouldWiden) {
S newStore = analysis.createEmptyStore(sequentialSemantics);
for (Map.Entry<LocalVariable, V> e : other.localVariableValues.entrySet()) {
// local variables that are only part of one store, but not the other are discarded, as one of
// store implicitly contains 'top' for that variable.
LocalVariable localVar = e.getKey();
V thisVal = localVariableValues.get(localVar);
if (thisVal != null) {
V otherVal = e.getValue();
V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
if (mergedVal != null) {
newStore.localVariableValues.put(localVar, mergedVal);
}
}
}
// information about the current object
{
V otherVal = other.thisValue;
V myVal = thisValue;
V mergedVal = myVal == null ? null : upperBoundOfValues(otherVal, myVal, shouldWiden);
if (mergedVal != null) {
newStore.thisValue = mergedVal;
}
}
for (Map.Entry<FieldAccess, V> e : other.fieldValues.entrySet()) {
// information about fields that are only part of one store, but not the other are discarded,
// as one store implicitly contains 'top' for that field.
FieldAccess el = e.getKey();
V thisVal = fieldValues.get(el);
if (thisVal != null) {
V otherVal = e.getValue();
V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
if (mergedVal != null) {
newStore.fieldValues.put(el, mergedVal);
}
}
}
for (Map.Entry<ArrayAccess, V> e : other.arrayValues.entrySet()) {
// information about arrays that are only part of one store, but not the other are discarded,
// as one store implicitly contains 'top' for that array access.
ArrayAccess el = e.getKey();
V thisVal = arrayValues.get(el);
if (thisVal != null) {
V otherVal = e.getValue();
V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
if (mergedVal != null) {
newStore.arrayValues.put(el, mergedVal);
}
}
}
for (Map.Entry<MethodCall, V> e : other.methodValues.entrySet()) {
// information about methods that are only part of one store, but not the other are discarded,
// as one store implicitly contains 'top' for that field.
MethodCall el = e.getKey();
V thisVal = methodValues.get(el);
if (thisVal != null) {
V otherVal = e.getValue();
V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
if (mergedVal != null) {
newStore.methodValues.put(el, mergedVal);
}
}
}
for (Map.Entry<ClassName, V> e : other.classValues.entrySet()) {
ClassName el = e.getKey();
V thisVal = classValues.get(el);
if (thisVal != null) {
V otherVal = e.getValue();
V mergedVal = upperBoundOfValues(otherVal, thisVal, shouldWiden);
if (mergedVal != null) {
newStore.classValues.put(el, mergedVal);
}
}
}
return newStore;
}
use of org.checkerframework.dataflow.expression.MethodCall in project checker-framework by typetools.
the class CFAbstractStore method removeConflicting.
/**
* Remove any information in this store that might not be true any more after {@code localVar} has
* been assigned a new value. This includes the following steps:
*
* <ol>
* <li value="1">Remove any abstract values for field accesses <em>b.g</em> where {@code
* localVar} might alias any expression in the receiver <em>b</em>.
* <li value="2">Remove any abstract values for array accesses <em>a[i]</em> where {@code
* localVar} might alias the receiver <em>a</em>.
* <li value="3">Remove any information about method calls where the receiver or any of the
* parameters contains {@code localVar}.
* </ol>
*/
protected void removeConflicting(LocalVariable var) {
final Iterator<Map.Entry<FieldAccess, V>> fieldValuesIterator = fieldValues.entrySet().iterator();
while (fieldValuesIterator.hasNext()) {
Map.Entry<FieldAccess, V> entry = fieldValuesIterator.next();
FieldAccess otherFieldAccess = entry.getKey();
// case 1:
if (otherFieldAccess.containsSyntacticEqualJavaExpression(var)) {
fieldValuesIterator.remove();
}
}
final Iterator<Map.Entry<ArrayAccess, V>> arrayValuesIterator = arrayValues.entrySet().iterator();
while (arrayValuesIterator.hasNext()) {
Map.Entry<ArrayAccess, V> entry = arrayValuesIterator.next();
ArrayAccess otherArrayAccess = entry.getKey();
// case 2:
if (otherArrayAccess.containsSyntacticEqualJavaExpression(var)) {
arrayValuesIterator.remove();
}
}
final Iterator<Map.Entry<MethodCall, V>> methodValuesIterator = methodValues.entrySet().iterator();
while (methodValuesIterator.hasNext()) {
Map.Entry<MethodCall, V> entry = methodValuesIterator.next();
MethodCall otherMethodAccess = entry.getKey();
// case 3:
if (otherMethodAccess.containsSyntacticEqualJavaExpression(var)) {
methodValuesIterator.remove();
}
}
}
use of org.checkerframework.dataflow.expression.MethodCall in project checker-framework by typetools.
the class CFAbstractStore method clearValue.
/**
* Remove any knowledge about the expression {@code expr} (correctly deciding where to remove the
* information depending on the type of the expression {@code expr}).
*/
public void clearValue(JavaExpression expr) {
if (expr.containsUnknown()) {
// Expressions containing unknown expressions are not stored.
return;
}
if (expr instanceof LocalVariable) {
LocalVariable localVar = (LocalVariable) expr;
localVariableValues.remove(localVar);
} else if (expr instanceof FieldAccess) {
FieldAccess fieldAcc = (FieldAccess) expr;
fieldValues.remove(fieldAcc);
} else if (expr instanceof MethodCall) {
MethodCall method = (MethodCall) expr;
methodValues.remove(method);
} else if (expr instanceof ArrayAccess) {
ArrayAccess a = (ArrayAccess) expr;
arrayValues.remove(a);
} else if (expr instanceof ClassName) {
ClassName c = (ClassName) expr;
classValues.remove(c);
} else {
// thisValue ...
// No other types of expressions are stored.
}
}
use of org.checkerframework.dataflow.expression.MethodCall in project checker-framework by typetools.
the class LockAnnotatedTypeFactory method isExpressionEffectivelyFinal.
/**
* Returns whether or not the expression is effectively final.
*
* <p>This method returns true in the following cases when expr is:
*
* <p>1. a field access and the field is final and the field access expression is effectively
* final as specified by this method.
*
* <p>2. an effectively final local variable.
*
* <p>3. a deterministic method call whose arguments and receiver expression are effectively final
* as specified by this method.
*
* <p>4. a this reference or a class literal
*
* @param expr expression
* @return whether or not the expression is effectively final
*/
boolean isExpressionEffectivelyFinal(JavaExpression expr) {
if (expr instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) expr;
JavaExpression receiver = fieldAccess.getReceiver();
// Don't call fieldAccess
return fieldAccess.isFinal() && isExpressionEffectivelyFinal(receiver);
} else if (expr instanceof LocalVariable) {
return ElementUtils.isEffectivelyFinal(((LocalVariable) expr).getElement());
} else if (expr instanceof MethodCall) {
MethodCall methodCall = (MethodCall) expr;
for (JavaExpression arg : methodCall.getArguments()) {
if (!isExpressionEffectivelyFinal(arg)) {
return false;
}
}
return PurityUtils.isDeterministic(this, methodCall.getElement()) && isExpressionEffectivelyFinal(methodCall.getReceiver());
} else if (expr instanceof ThisReference || expr instanceof ClassName) {
// too.
return true;
} else {
// type of 'expr' is not supported in @GuardedBy(...) lock expressions
return false;
}
}
Aggregations