use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName in project checker-framework by typetools.
the class CFAbstractTransfer method addFieldValues.
private void addFieldValues(S info, AnnotatedTypeFactory factory, ClassTree classTree, MethodTree methodTree) {
// Add knowledge about final fields, or values of non-final fields
// if we are inside a constructor (information about initializers)
TypeMirror classType = TreeUtils.typeOf(classTree);
List<Pair<VariableElement, V>> fieldValues = analysis.getFieldValues();
for (Pair<VariableElement, V> p : fieldValues) {
VariableElement element = p.first;
V value = p.second;
if (ElementUtils.isFinal(element) || TreeUtils.isConstructor(methodTree)) {
Receiver receiver;
if (ElementUtils.isStatic(element)) {
receiver = new ClassName(classType);
} else {
receiver = new ThisReference(classType);
}
TypeMirror fieldType = ElementUtils.getType(element);
Receiver field = new FieldAccess(receiver, fieldType, element);
info.insertValue(field, value);
}
}
// add properties about fields (static information from type)
boolean isNotFullyInitializedReceiver = isNotFullyInitializedReceiver(methodTree);
if (isNotFullyInitializedReceiver && !TreeUtils.isConstructor(methodTree)) {
// and the method isn't a constructor
return;
}
for (Tree member : classTree.getMembers()) {
if (member instanceof VariableTree) {
VariableTree vt = (VariableTree) member;
final VariableElement element = TreeUtils.elementFromDeclaration(vt);
AnnotatedTypeMirror type = ((GenericAnnotatedTypeFactory<?, ?, ?, ?>) factory).getAnnotatedTypeLhs(vt);
TypeMirror fieldType = ElementUtils.getType(element);
Receiver receiver;
if (ElementUtils.isStatic(element)) {
receiver = new ClassName(classType);
} else {
receiver = new ThisReference(classType);
}
V value = analysis.createAbstractValue(type);
if (value == null)
continue;
if (TreeUtils.isConstructor(methodTree)) {
// if we are in a constructor,
// then we can still use the static type, but only
// if there is also an initializer that already does
// some initialization.
boolean found = false;
for (Pair<VariableElement, V> fieldValue : fieldValues) {
if (fieldValue.first.equals(element)) {
value = value.leastUpperBound(fieldValue.second);
found = true;
break;
}
}
if (!found) {
// no initializer found, cannot use static type
continue;
}
}
Receiver field = new FieldAccess(receiver, fieldType, element);
info.insertValue(field, value);
}
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName in project checker-framework by typetools.
the class FlowExpressionParseUtil method getReceiverField.
private static Receiver getReceiverField(String s, FlowExpressionContext context, boolean originalReceiver, VariableElement fieldElem) throws FlowExpressionParseException {
TypeMirror receiverType = context.receiver.getType();
TypeMirror fieldType = ElementUtils.getType(fieldElem);
if (ElementUtils.isStatic(fieldElem)) {
Element classElem = fieldElem.getEnclosingElement();
Receiver staticClassReceiver = new ClassName(ElementUtils.getType(classElem));
return new FieldAccess(staticClassReceiver, fieldType, fieldElem);
}
Receiver locationOfField;
if (originalReceiver) {
locationOfField = context.receiver;
} else {
locationOfField = FlowExpressions.internalReprOf(context.checkerContext.getAnnotationProvider(), new ImplicitThisLiteralNode(receiverType));
}
if (locationOfField instanceof ClassName) {
throw constructParserException(s, "a non-static field cannot have a class name as a receiver.");
}
return new FieldAccess(locationOfField, fieldType, fieldElem);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName in project checker-framework by typetools.
the class FlowExpressionParseUtil method parse.
/**
* Parse a string and return its representation as a {@link Receiver}, or throw an {@link
* FlowExpressionParseException}.
*
* @param expression flow expression to parse
* @param context information about any receiver and arguments
* @param localScope path to local scope to use
* @param useLocalScope whether {@code localScope} should be used to resolve identifiers
*/
public static FlowExpressions.Receiver parse(String expression, FlowExpressionContext context, TreePath localScope, boolean useLocalScope) throws FlowExpressionParseException {
context.useLocalScope = useLocalScope;
FlowExpressions.Receiver result = parseHelper(expression, context, localScope);
if (result instanceof ClassName && !expression.endsWith("class")) {
throw constructParserException(expression, "a class name cannot terminate a flow expression string");
}
return result;
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName in project checker-framework by typetools.
the class InitializationStore method insertValue.
/**
* {@inheritDoc}
*
* <p>If the receiver is a field, and has an invariant annotation, then it can be considered
* initialized.
*/
@Override
public void insertValue(Receiver r, V value) {
if (value == null) {
// top and top is also the default value.
return;
}
InitializationAnnotatedTypeFactory<?, ?, ?, ?> atypeFactory = (InitializationAnnotatedTypeFactory<?, ?, ?, ?>) analysis.getTypeFactory();
QualifierHierarchy qualifierHierarchy = atypeFactory.getQualifierHierarchy();
AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
// Remember fields that have the 'invariant' annotation in the store.
if (r instanceof FieldAccess) {
FieldAccess fieldAccess = (FieldAccess) r;
if (!fieldValues.containsKey(r)) {
Set<AnnotationMirror> declaredAnnos = atypeFactory.getAnnotatedType(fieldAccess.getField()).getAnnotations();
if (AnnotationUtils.containsSame(declaredAnnos, invariantAnno)) {
if (!invariantFields.containsKey(fieldAccess)) {
invariantFields.put(fieldAccess, analysis.createSingleAnnotationValue(invariantAnno, r.getType()));
}
}
}
}
super.insertValue(r, value);
for (AnnotationMirror a : value.getAnnotations()) {
if (qualifierHierarchy.isSubtype(a, invariantAnno)) {
if (r instanceof FieldAccess) {
FieldAccess fa = (FieldAccess) r;
if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
addInitializedField(fa.getField());
}
}
}
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.ClassName in project checker-framework by typetools.
the class InitializationVisitor method checkContract.
@Override
protected boolean checkContract(Receiver expr, AnnotationMirror necessaryAnnotation, AnnotationMirror inferredAnnotation, CFAbstractStore<?, ?> store) {
// also use the information about initialized fields to check contracts
final AnnotationMirror invariantAnno = atypeFactory.getFieldInvariantAnnotation();
if (atypeFactory.getQualifierHierarchy().isSubtype(invariantAnno, necessaryAnnotation)) {
if (expr instanceof FieldAccess) {
FieldAccess fa = (FieldAccess) expr;
if (fa.getReceiver() instanceof ThisReference || fa.getReceiver() instanceof ClassName) {
@SuppressWarnings("unchecked") Store s = (Store) store;
if (s.isFieldInitialized(fa.getField())) {
AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
// is this an invariant-field?
if (AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
return true;
}
}
} else {
Set<AnnotationMirror> recvAnnoSet;
@SuppressWarnings("unchecked") Value value = (Value) store.getValue(fa.getReceiver());
if (value != null) {
recvAnnoSet = value.getAnnotations();
} else if (fa.getReceiver() instanceof LocalVariable) {
Element elem = ((LocalVariable) fa.getReceiver()).getElement();
AnnotatedTypeMirror recvType = atypeFactory.getAnnotatedType(elem);
recvAnnoSet = recvType.getAnnotations();
} else {
// Is there anything better we could do?
return false;
}
boolean isRecvCommitted = false;
for (AnnotationMirror anno : recvAnnoSet) {
if (atypeFactory.isCommitted(anno)) {
isRecvCommitted = true;
}
}
AnnotatedTypeMirror fieldType = atypeFactory.getAnnotatedType(fa.getField());
// has the invariant type.
if (isRecvCommitted && AnnotationUtils.containsSame(fieldType.getAnnotations(), invariantAnno)) {
return true;
}
}
}
}
return super.checkContract(expr, necessaryAnnotation, inferredAnnotation, store);
}
Aggregations