use of org.checkerframework.dataflow.expression.LocalVariable 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;
}
}
use of org.checkerframework.dataflow.expression.LocalVariable in project checker-framework by typetools.
the class LockStore method updateForMethodCall.
@Override
public void updateForMethodCall(MethodInvocationNode n, AnnotatedTypeFactory atypeFactory, CFValue val) {
super.updateForMethodCall(n, atypeFactory, val);
ExecutableElement method = n.getTarget().getMethod();
// cannot use that logic.
if (!isSideEffectFree(atypeFactory, method)) {
// to @LockPossiblyHeld, but the annotation in the GuardedBy hierarchy should not be changed.
for (FieldAccess field : new ArrayList<>(fieldValues.keySet())) {
CFValue newValue = changeLockAnnoToTop(field, fieldValues.get(field));
if (newValue != null) {
fieldValues.put(field, newValue);
} else {
fieldValues.remove(field);
}
}
// Local variables could also be unlocked via an alias
for (LocalVariable var : new ArrayList<>(localVariableValues.keySet())) {
CFValue newValue = changeLockAnnoToTop(var, localVariableValues.get(var));
if (newValue != null) {
localVariableValues.put(var, newValue);
}
}
if (thisValue != null) {
thisValue = changeLockAnnoToTop(null, thisValue);
}
}
}
Aggregations