use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver 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.Receiver in project checker-framework by typetools.
the class FlowExpressionParseUtil method parseArray.
private static Receiver parseArray(String s, FlowExpressionContext context, TreePath path) throws FlowExpressionParseException {
Pair<Pair<String, String>, String> array = parseArray(s);
if (array == null) {
return null;
}
String receiverStr = array.first.first;
String indexStr = array.first.second;
Receiver receiver = parseHelper(receiverStr, context, path);
FlowExpressionContext contextForIndex = context.copyAndUseOuterReceiver();
Receiver index = parseHelper(indexStr, contextForIndex, path);
TypeMirror receiverType = receiver.getType();
if (!(receiverType instanceof ArrayType)) {
throw constructParserException(s, String.format("receiver not an array: %s : %s", receiver, receiverType));
}
TypeMirror componentType = ((ArrayType) receiverType).getComponentType();
ArrayAccess result = new ArrayAccess(componentType, receiver, index);
return result;
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class SameLenTransfer method refineEq.
/**
* Handles refinement of equality comparisons (cases 2 and 3). After "a.length == b.length"
* evaluates to true, a and b have SameLen of each other in the store.
*/
private void refineEq(Node left, Node right, CFStore store) {
List<Receiver> receivers = new ArrayList<>();
List<AnnotationMirror> annos = new ArrayList<>();
for (Node internal : splitAssignments(left)) {
receivers.add(FlowExpressions.internalReprOf(analysis.getTypeFactory(), internal));
annos.add(getAnno(internal));
}
for (Node internal : splitAssignments(right)) {
receivers.add(FlowExpressions.internalReprOf(analysis.getTypeFactory(), internal));
annos.add(getAnno(internal));
}
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(receivers, annos);
propagateCombinedSameLen(combinedSameLen, left, store);
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class SameLenTransfer method visitAssignment.
/**
* Handles case 1
*/
@Override
public TransferResult<CFValue, CFStore> visitAssignment(AssignmentNode node, TransferInput<CFValue, CFStore> in) {
TransferResult<CFValue, CFStore> result = super.visitAssignment(node, in);
// Handle b = new T[a.length]
if (node.getExpression() instanceof ArrayCreationNode) {
ArrayCreationNode acNode = (ArrayCreationNode) node.getExpression();
if (acNode.getDimensions().size() == 1) {
Node lengthNode = acNode.getDimension(0);
Node lengthNodeReceiver = getLengthNodeReceiver(lengthNode);
if (lengthNodeReceiver != null) {
// "new T[a.length]" or "new T[s.length()]" is the right hand side of the
// assignment. lengthNode is known to be "lengthNodeReceiver.length" or
// "lengthNodeReceiver.length()"
// targetRec is the receiver for the left hand side of the assignment.
Receiver targetRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), node.getTarget());
Receiver otherRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), lengthNodeReceiver);
AnnotationMirror lengthNodeAnnotation = aTypeFactory.getAnnotatedType(lengthNodeReceiver.getTree()).getAnnotationInHierarchy(UNKNOWN);
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(targetRec, otherRec, UNKNOWN, lengthNodeAnnotation);
propagateCombinedSameLen(combinedSameLen, node, result.getRegularStore());
return result;
}
}
}
AnnotationMirror rightAnno = aTypeFactory.getAnnotatedType(node.getExpression().getTree()).getAnnotationInHierarchy(UNKNOWN);
// If the left side of the assignment is an array or a string, then have both the right and
// left side be SameLen of each other.
Receiver targetRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), node.getTarget());
Receiver exprRec = FlowExpressions.internalReprOf(analysis.getTypeFactory(), node.getExpression());
if (IndexUtil.isSequenceType(node.getTarget().getType()) || (rightAnno != null && AnnotationUtils.areSameByClass(rightAnno, SameLen.class))) {
AnnotationMirror rightAnnoOrUnknown = rightAnno == null ? UNKNOWN : rightAnno;
AnnotationMirror combinedSameLen = aTypeFactory.createCombinedSameLen(targetRec, exprRec, UNKNOWN, rightAnnoOrUnknown);
propagateCombinedSameLen(combinedSameLen, node, result.getRegularStore());
}
return result;
}
use of org.checkerframework.dataflow.analysis.FlowExpressions.Receiver in project checker-framework by typetools.
the class OffsetEquation method standardizeAndViewpointAdaptExpressions.
/**
* Standardizes and viewpoint-adapts string terms in the list based on the supplied context.
* Terms that evaluate to a integer constant are removed from the list, and the constants are
* added to or subtracted from the intValue field.
*/
private void standardizeAndViewpointAdaptExpressions(List<String> terms, boolean subtract, FlowExpressionContext context, TreePath scope, boolean useLocalScope) throws FlowExpressionParseException {
// Standardize all terms and remove constants
int length = terms.size(), j = 0;
for (int i = 0; i < length; ++i) {
String term = terms.get(i);
Receiver receiver = FlowExpressionParseUtil.parse(term, context, scope, useLocalScope);
Integer termConstant = evalConstantTerm(receiver);
if (termConstant == null) {
terms.set(j, receiver.toString());
++j;
} else if (subtract) {
intValue -= termConstant;
} else {
intValue += termConstant;
}
}
// Remove remaining elements from the end of the list
terms.subList(j, length).clear();
}
Aggregations