use of org.checkerframework.dataflow.cfg.node.LocalVariableNode in project error-prone by google.
the class NullnessPropagationTransfer method handleEqualityComparison.
/**
* Refines the {@code Nullness} of {@code LocalVariableNode}s used in an equality comparison using
* the greatest lower bound.
*
* @param equalTo whether the comparison is == (false for !=)
* @param leftNode the left-hand side of the comparison
* @param rightNode the right-hand side of the comparison
* @param inputs access to nullness values of the left and right nodes
* @param thenUpdates the local variables whose nullness values should be updated if the
* comparison returns {@code true}
* @param elseUpdates the local variables whose nullness values should be updated if the
* comparison returns {@code false}
*/
private static void handleEqualityComparison(boolean equalTo, Node leftNode, Node rightNode, SubNodeValues inputs, LocalVariableUpdates thenUpdates, LocalVariableUpdates elseUpdates) {
Nullness leftVal = inputs.valueOfSubNode(leftNode);
Nullness rightVal = inputs.valueOfSubNode(rightNode);
Nullness equalBranchValue = leftVal.greatestLowerBound(rightVal);
LocalVariableUpdates equalBranchUpdates = equalTo ? thenUpdates : elseUpdates;
LocalVariableUpdates notEqualBranchUpdates = equalTo ? elseUpdates : thenUpdates;
if (leftNode instanceof LocalVariableNode) {
LocalVariableNode localVar = (LocalVariableNode) leftNode;
equalBranchUpdates.set(localVar, equalBranchValue);
notEqualBranchUpdates.set(localVar, leftVal.greatestLowerBound(rightVal.deducedValueWhenNotEqual()));
}
if (rightNode instanceof LocalVariableNode) {
LocalVariableNode localVar = (LocalVariableNode) rightNode;
equalBranchUpdates.set(localVar, equalBranchValue);
notEqualBranchUpdates.set(localVar, rightVal.greatestLowerBound(leftVal.deducedValueWhenNotEqual()));
}
}
use of org.checkerframework.dataflow.cfg.node.LocalVariableNode in project error-prone by google.
the class NullnessPropagationTransfer method visitAssignment.
@Override
Nullness visitAssignment(AssignmentNode node, SubNodeValues inputs, LocalVariableUpdates updates) {
Nullness value = inputs.valueOfSubNode(node.getExpression());
Node target = node.getTarget();
if (target instanceof LocalVariableNode) {
updates.set((LocalVariableNode) target, value);
}
if (target instanceof ArrayAccessNode) {
setNonnullIfLocalVariable(updates, ((ArrayAccessNode) target).getArray());
}
if (target instanceof FieldAccessNode) {
FieldAccessNode fieldAccess = (FieldAccessNode) target;
ClassAndField targetField = tryGetFieldSymbol(target.getTree());
setReceiverNonnull(updates, fieldAccess.getReceiver(), targetField);
}
/*
* We propagate the value of the target to the value of the assignment expressions as a whole.
* We do this regardless of whether the target is a local variable. For example:
*
* String s = object.field = "foo"; // Now |s| is non-null.
*
* It's not clear to me that this is technically correct, but it works in practice with the
* bytecode generated by both javac and ecj.
*
* http://stackoverflow.com/q/12850676/28465
*/
return value;
}
Aggregations