use of org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess in project checker-framework by typetools.
the class GenericAnnotatedTypeFactory method getAnnotationFromReceiver.
/**
* Returns the primary annotation on a receiver.
*
* @param receiver the receiver for which the annotation is returned
* @param tree current tree
* @param clazz the Class of the annotation
* @return the annotation on expression or null if one does not exist
* @throws FlowExpressionParseException thrown if the expression cannot be parsed
*/
public AnnotationMirror getAnnotationFromReceiver(FlowExpressions.Receiver receiver, Tree tree, Class<? extends Annotation> clazz) throws FlowExpressionParseException {
AnnotationMirror annotationMirror = null;
if (CFAbstractStore.canInsertReceiver(receiver)) {
Store store = getStoreBefore(tree);
if (store != null) {
Value value = store.getValue(receiver);
if (value != null) {
annotationMirror = AnnotationUtils.getAnnotationByClass(value.getAnnotations(), clazz);
}
}
}
if (annotationMirror == null) {
if (receiver instanceof LocalVariable) {
Element ele = ((LocalVariable) receiver).getElement();
annotationMirror = getAnnotatedType(ele).getAnnotation(clazz);
} else if (receiver instanceof FieldAccess) {
Element ele = ((FieldAccess) receiver).getField();
annotationMirror = getAnnotatedType(ele).getAnnotation(clazz);
}
}
return annotationMirror;
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess in project checker-framework by typetools.
the class UpperBoundTransfer method visitFieldAccess.
/**
* If n is an array length field access, then the type of a.length is the glb
* of @LTEqLengthOf("a") and the value of a.length in the store. This is case 19.
*/
@Override
public TransferResult<CFValue, CFStore> visitFieldAccess(FieldAccessNode n, TransferInput<CFValue, CFStore> in) {
if (NodeUtils.isArrayLengthFieldAccess(n)) {
FieldAccess arrayLength = FlowExpressions.internalReprOfFieldAccess(atypeFactory, n);
Receiver arrayRec = arrayLength.getReceiver();
Tree arrayTree = n.getReceiver().getTree();
TransferResult<CFValue, CFStore> result = visitLengthAccess(n, in, arrayRec, arrayTree);
if (result != null) {
return result;
}
}
return super.visitFieldAccess(n, in);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess in project checker-framework by typetools.
the class InitializationStore method updateForMethodCall.
/**
* {@inheritDoc}
*
* <p>Additionally, the {@link InitializationStore} keeps all field values for fields that have
* the 'invariant' annotation.
*/
@Override
public void updateForMethodCall(MethodInvocationNode n, AnnotatedTypeFactory atypeFactory, V val) {
// Remove invariant annotated fields to avoid performance issue reported in #1438.
for (FieldAccess invariantField : invariantFields.keySet()) {
fieldValues.remove(invariantField);
}
super.updateForMethodCall(n, atypeFactory, val);
// Add invariant annotation again.
fieldValues.putAll(invariantFields);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess in project checker-framework by typetools.
the class InitializationStore method leastUpperBound.
@Override
public S leastUpperBound(S other) {
// Remove invariant annotated fields to avoid performance issue reported in #1438.
Map<FlowExpressions.FieldAccess, V> removedFieldValues = new HashMap<>();
Map<FlowExpressions.FieldAccess, V> removedOtherFieldValues = new HashMap<>();
for (FieldAccess invariantField : invariantFields.keySet()) {
V v = fieldValues.remove(invariantField);
removedFieldValues.put(invariantField, v);
}
for (FieldAccess invariantField : other.invariantFields.keySet()) {
V v = other.fieldValues.remove(invariantField);
removedOtherFieldValues.put(invariantField, v);
}
S result = super.leastUpperBound(other);
// Restore removed values.
fieldValues.putAll(removedFieldValues);
other.fieldValues.putAll(removedOtherFieldValues);
// Set intersection for initializedFields.
result.initializedFields.addAll(other.initializedFields);
result.initializedFields.retainAll(initializedFields);
// Set intersection for invariantFields.
for (Entry<FieldAccess, V> e : invariantFields.entrySet()) {
if (other.invariantFields.containsKey(e.getKey())) {
result.invariantFields.put(e.getKey(), e.getValue());
}
}
// Add invariant annotation.
result.fieldValues.putAll(result.invariantFields);
return result;
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.FieldAccess 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(Receiver expr) {
if (expr instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) expr;
Receiver recv = fieldAccess.getReceiver();
// Don't call fieldAccess
return fieldAccess.isFinal() && isExpressionEffectivelyFinal(recv);
} else if (expr instanceof LocalVariable) {
return ElementUtils.isEffectivelyFinal(((LocalVariable) expr).getElement());
} else if (expr instanceof MethodCall) {
MethodCall methodCall = (MethodCall) expr;
for (Receiver param : methodCall.getParameters()) {
if (!isExpressionEffectivelyFinal(param)) {
return false;
}
}
return PurityUtils.isDeterministic(this, methodCall.getElement()) && isExpressionEffectivelyFinal(methodCall.getReceiver());
} else if (expr instanceof ThisReference || expr instanceof ClassName) {
// final too.
return true;
} else {
// type of 'expr' is not supported in @GuardedBy(...) lock expressions
return false;
}
}
Aggregations