use of org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable 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.LocalVariable in project checker-framework by typetools.
the class CFAbstractTransfer method addFinalLocalValues.
private void addFinalLocalValues(S info, Element enclosingElement) {
// add information about effectively final variables (from outer scopes)
for (Entry<Element, V> e : analysis.atypeFactory.getFinalLocalValues().entrySet()) {
Element elem = e.getKey();
// TODO: There is a design flaw where the values of final local values leaks
// into other methods of the same class. For example, in
// class a { void b() {...} void c() {...} }
// final local values from b() would be visible in the store for c(),
// even though they should only be visible in b() and in classes
// defined inside the method body of b().
// This is partly because GenericAnnotatedTypeFactory.performFlowAnalysis
// does not call itself recursively to analyze inner classes, but instead
// pops classes off of a queue, and the information about known final local
// values is stored by GenericAnnotatedTypeFactory.analyze in
// GenericAnnotatedTypeFactory.flowResult, which is visible to all classes
// in the queue regardless of their level of recursion.
// We work around this here by ensuring that we only add a final
// local value to a method's store if that method is enclosed by
// the method where the local variables were declared.
// Find the enclosing method of the element
Element enclosingMethodOfVariableDeclaration = elem.getEnclosingElement();
if (enclosingMethodOfVariableDeclaration != null) {
// Now find all the enclosing methods of the code we are analyzing. If any one of
// them matches the above, then the final local variable value applies.
Element enclosingMethodOfCurrentMethod = enclosingElement;
while (enclosingMethodOfCurrentMethod != null) {
if (enclosingMethodOfVariableDeclaration.equals(enclosingMethodOfCurrentMethod)) {
LocalVariable l = new LocalVariable(elem);
info.insertValue(l, e.getValue());
break;
}
enclosingMethodOfCurrentMethod = enclosingMethodOfCurrentMethod.getEnclosingElement();
}
}
}
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable 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.LocalVariable 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");
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.LocalVariable in project checker-framework by typetools.
the class FlowExpressionParseUtil method internalReprOfVariable.
public static Receiver internalReprOfVariable(AnnotatedTypeFactory provider, VariableTree tree) throws FlowExpressionParseException {
Element elt = TreeUtils.elementFromDeclaration(tree);
if (elt.getKind() == ElementKind.LOCAL_VARIABLE || elt.getKind() == ElementKind.RESOURCE_VARIABLE || elt.getKind() == ElementKind.EXCEPTION_PARAMETER || elt.getKind() == ElementKind.PARAMETER) {
return new LocalVariable(elt);
}
Receiver receiverF = FlowExpressions.internalReprOfImplicitReceiver(elt);
FlowExpressionParseUtil.FlowExpressionContext context = new FlowExpressionParseUtil.FlowExpressionContext(receiverF, null, provider.getContext());
return FlowExpressionParseUtil.parse(tree.getName().toString(), context, provider.getPath(tree), false);
}
Aggregations