use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference 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.ThisReference 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.ThisReference 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);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference in project checker-framework by typetools.
the class FlowExpressionParseUtil method parseSuper.
private static Receiver parseSuper(String s, Types types, FlowExpressionContext context) throws FlowExpressionParseException {
// super literal
List<? extends TypeMirror> superTypes = types.directSupertypes(context.receiver.getType());
// find class supertype
TypeMirror superType = null;
for (TypeMirror t : superTypes) {
// ignore interface types
if (!(t instanceof ClassType)) {
continue;
}
ClassType tt = (ClassType) t;
if (!tt.isInterface()) {
superType = t;
break;
}
}
if (superType == null) {
throw constructParserException(s, "super class not found");
}
return new ThisReference(superType);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.ThisReference in project checker-framework by typetools.
the class FlowExpressionParseUtil method parseIdentifier.
private static Receiver parseIdentifier(String s, ProcessingEnvironment env, TreePath path, FlowExpressionContext context) throws FlowExpressionParseException {
Resolver resolver = new Resolver(env);
if (!context.parsingMember && context.useLocalScope) {
// Attempt to match a local variable within the scope of the
// given path before attempting to match a field.
VariableElement varElem = resolver.findLocalVariableOrParameterOrField(s, path);
if (varElem != null) {
if (varElem.getKind() == ElementKind.FIELD) {
boolean isOriginalReceiver = context.receiver instanceof ThisReference;
return getReceiverField(s, context, isOriginalReceiver, varElem);
} else {
return new LocalVariable(varElem);
}
}
}
// field access
TypeMirror receiverType = context.receiver.getType();
boolean originalReceiver = true;
VariableElement fieldElem = null;
if (receiverType.getKind() == TypeKind.ARRAY && s.equals("length")) {
fieldElem = resolver.findField(s, receiverType, path);
}
// Search for field in each enclosing class.
while (receiverType.getKind() == TypeKind.DECLARED) {
fieldElem = resolver.findField(s, receiverType, path);
if (fieldElem != null) {
break;
}
receiverType = getTypeOfEnclosingClass((DeclaredType) receiverType);
originalReceiver = false;
}
if (fieldElem != null && fieldElem.getKind() == ElementKind.FIELD) {
return getReceiverField(s, context, originalReceiver, fieldElem);
}
// Class name
Element classElem = resolver.findClass(s, path);
TypeMirror classType = ElementUtils.getType(classElem);
if (classType != null) {
return new ClassName(classType);
}
throw constructParserException(s, "identifier not found");
}
Aggregations