use of org.checkerframework.dataflow.cfg.node.SuperNode in project bazel by bazelbuild.
the class FlowExpressions method internalReprOf.
/**
* We ignore operations such as widening and
* narrowing when computing the internal representation.
*
* @return The internal representation (as {@link Receiver}) of any
* {@link Node}. Might contain {@link Unknown}.
*/
public static Receiver internalReprOf(AnnotationProvider provider, Node receiverNode, boolean allowNonDeterminitic) {
Receiver receiver = null;
if (receiverNode instanceof FieldAccessNode) {
FieldAccessNode fan = (FieldAccessNode) receiverNode;
if (fan.getFieldName().equals("this")) {
// For some reason, "className.this" is considered a field access.
// We right this wrong here.
receiver = new ThisReference(fan.getReceiver().getType());
} else {
receiver = internalReprOfFieldAccess(provider, fan);
}
} else if (receiverNode instanceof ExplicitThisLiteralNode) {
receiver = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof ThisLiteralNode) {
receiver = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof SuperNode) {
receiver = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof LocalVariableNode) {
LocalVariableNode lv = (LocalVariableNode) receiverNode;
receiver = new LocalVariable(lv);
} else if (receiverNode instanceof ArrayAccessNode) {
ArrayAccessNode a = (ArrayAccessNode) receiverNode;
receiver = internalReprOfArrayAccess(provider, a);
} else if (receiverNode instanceof StringConversionNode) {
// ignore string conversion
return internalReprOf(provider, ((StringConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof WideningConversionNode) {
// ignore widening
return internalReprOf(provider, ((WideningConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof NarrowingConversionNode) {
// ignore narrowing
return internalReprOf(provider, ((NarrowingConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof ClassNameNode) {
ClassNameNode cn = (ClassNameNode) receiverNode;
receiver = new ClassName(cn.getType());
} else if (receiverNode instanceof ValueLiteralNode) {
ValueLiteralNode vn = (ValueLiteralNode) receiverNode;
receiver = new ValueLiteral(vn.getType(), vn);
} else if (receiverNode instanceof MethodInvocationNode) {
MethodInvocationNode mn = (MethodInvocationNode) receiverNode;
ExecutableElement invokedMethod = TreeUtils.elementFromUse(mn.getTree());
// check if this represents a boxing operation of a constant, in which
// case we treat the method call as deterministic, because there is no way
// to behave differently in two executions where two constants are being used.
boolean considerDeterministic = false;
if (invokedMethod.toString().equals("valueOf(long)") && mn.getTarget().getReceiver().toString().equals("Long")) {
Node arg = mn.getArgument(0);
if (arg instanceof ValueLiteralNode) {
considerDeterministic = true;
}
}
if (PurityUtils.isDeterministic(provider, invokedMethod) || allowNonDeterminitic || considerDeterministic) {
List<Receiver> parameters = new ArrayList<>();
for (Node p : mn.getArguments()) {
parameters.add(internalReprOf(provider, p));
}
Receiver methodReceiver;
if (ElementUtils.isStatic(invokedMethod)) {
methodReceiver = new ClassName(mn.getTarget().getReceiver().getType());
} else {
methodReceiver = internalReprOf(provider, mn.getTarget().getReceiver());
}
receiver = new PureMethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
}
}
if (receiver == null) {
receiver = new Unknown(receiverNode.getType());
}
return receiver;
}
use of org.checkerframework.dataflow.cfg.node.SuperNode in project checker-framework by typetools.
the class FlowExpressions method internalReprOf.
/**
* We ignore operations such as widening and narrowing when computing the internal
* representation.
*
* @return the internal representation (as {@link Receiver}) of any {@link Node}. Might contain
* {@link Unknown}.
*/
public static Receiver internalReprOf(AnnotationProvider provider, Node receiverNode, boolean allowNonDeterministic) {
Receiver receiver = null;
if (receiverNode instanceof FieldAccessNode) {
FieldAccessNode fan = (FieldAccessNode) receiverNode;
if (fan.getFieldName().equals("this")) {
// For some reason, "className.this" is considered a field access.
// We right this wrong here.
receiver = new ThisReference(fan.getReceiver().getType());
} else if (fan.getFieldName().equals("class")) {
// "className.class" is considered a field access. This makes sense,
// since .class is similar to a field access which is the equivalent
// of a call to getClass(). However for the purposes of dataflow
// analysis, and value stores, this is the equivalent of a ClassNameNode.
receiver = new ClassName(fan.getReceiver().getType());
} else {
receiver = internalReprOfFieldAccess(provider, fan);
}
} else if (receiverNode instanceof ExplicitThisLiteralNode) {
receiver = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof ThisLiteralNode) {
receiver = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof SuperNode) {
receiver = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof LocalVariableNode) {
LocalVariableNode lv = (LocalVariableNode) receiverNode;
receiver = new LocalVariable(lv);
} else if (receiverNode instanceof ArrayAccessNode) {
ArrayAccessNode a = (ArrayAccessNode) receiverNode;
receiver = internalReprOfArrayAccess(provider, a);
} else if (receiverNode instanceof StringConversionNode) {
// ignore string conversion
return internalReprOf(provider, ((StringConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof WideningConversionNode) {
// ignore widening
return internalReprOf(provider, ((WideningConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof NarrowingConversionNode) {
// ignore narrowing
return internalReprOf(provider, ((NarrowingConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof ClassNameNode) {
ClassNameNode cn = (ClassNameNode) receiverNode;
receiver = new ClassName(cn.getType());
} else if (receiverNode instanceof ValueLiteralNode) {
ValueLiteralNode vn = (ValueLiteralNode) receiverNode;
receiver = new ValueLiteral(vn.getType(), vn);
} else if (receiverNode instanceof ArrayCreationNode) {
ArrayCreationNode an = (ArrayCreationNode) receiverNode;
List<Receiver> dimensions = new ArrayList<>();
for (Node dimension : an.getDimensions()) {
dimensions.add(internalReprOf(provider, dimension, allowNonDeterministic));
}
List<Receiver> initializers = new ArrayList<>();
for (Node initializer : an.getInitializers()) {
initializers.add(internalReprOf(provider, initializer, allowNonDeterministic));
}
receiver = new ArrayCreation(an.getType(), dimensions, initializers);
} else if (receiverNode instanceof MethodInvocationNode) {
MethodInvocationNode mn = (MethodInvocationNode) receiverNode;
ExecutableElement invokedMethod = TreeUtils.elementFromUse(mn.getTree());
// check if this represents a boxing operation of a constant, in which
// case we treat the method call as deterministic, because there is no way
// to behave differently in two executions where two constants are being used.
boolean considerDeterministic = false;
if (isLongValueOf(mn, invokedMethod)) {
Node arg = mn.getArgument(0);
if (arg instanceof ValueLiteralNode) {
considerDeterministic = true;
}
}
if (PurityUtils.isDeterministic(provider, invokedMethod) || allowNonDeterministic || considerDeterministic) {
List<Receiver> parameters = new ArrayList<>();
for (Node p : mn.getArguments()) {
parameters.add(internalReprOf(provider, p));
}
Receiver methodReceiver;
if (ElementUtils.isStatic(invokedMethod)) {
methodReceiver = new ClassName(mn.getTarget().getReceiver().getType());
} else {
methodReceiver = internalReprOf(provider, mn.getTarget().getReceiver());
}
receiver = new MethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
}
}
if (receiver == null) {
receiver = new Unknown(receiverNode.getType());
}
return receiver;
}
use of org.checkerframework.dataflow.cfg.node.SuperNode in project checker-framework by typetools.
the class JavaExpression method fromNode.
/**
* We ignore operations such as widening and narrowing when computing the internal representation.
*
* @param receiverNode a node to convert to a JavaExpression
* @return the internal representation of the given node. Might contain {@link Unknown}.
*/
public static JavaExpression fromNode(Node receiverNode) {
JavaExpression result = null;
if (receiverNode instanceof FieldAccessNode) {
result = fromNodeFieldAccess((FieldAccessNode) receiverNode);
} else if (receiverNode instanceof ExplicitThisNode) {
result = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof ThisNode) {
result = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof SuperNode) {
result = new ThisReference(receiverNode.getType());
} else if (receiverNode instanceof LocalVariableNode) {
LocalVariableNode lv = (LocalVariableNode) receiverNode;
result = new LocalVariable(lv);
} else if (receiverNode instanceof ArrayAccessNode) {
ArrayAccessNode a = (ArrayAccessNode) receiverNode;
result = fromArrayAccess(a);
} else if (receiverNode instanceof StringConversionNode) {
// ignore string conversion
return fromNode(((StringConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof WideningConversionNode) {
// ignore widening
return fromNode(((WideningConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof NarrowingConversionNode) {
// ignore narrowing
return fromNode(((NarrowingConversionNode) receiverNode).getOperand());
} else if (receiverNode instanceof UnaryOperationNode) {
UnaryOperationNode uopn = (UnaryOperationNode) receiverNode;
return new UnaryOperation(uopn, fromNode(uopn.getOperand()));
} else if (receiverNode instanceof BinaryOperationNode) {
BinaryOperationNode bopn = (BinaryOperationNode) receiverNode;
return new BinaryOperation(bopn, fromNode(bopn.getLeftOperand()), fromNode(bopn.getRightOperand()));
} else if (receiverNode instanceof ClassNameNode) {
ClassNameNode cn = (ClassNameNode) receiverNode;
result = new ClassName(cn.getType());
} else if (receiverNode instanceof ValueLiteralNode) {
ValueLiteralNode vn = (ValueLiteralNode) receiverNode;
result = new ValueLiteral(vn.getType(), vn);
} else if (receiverNode instanceof ArrayCreationNode) {
ArrayCreationNode an = (ArrayCreationNode) receiverNode;
List<@Nullable JavaExpression> dimensions = CollectionsPlume.mapList(JavaExpression::fromNode, an.getDimensions());
List<JavaExpression> initializers = CollectionsPlume.mapList(JavaExpression::fromNode, an.getInitializers());
result = new ArrayCreation(an.getType(), dimensions, initializers);
} else if (receiverNode instanceof MethodInvocationNode) {
MethodInvocationNode mn = (MethodInvocationNode) receiverNode;
MethodInvocationTree t = mn.getTree();
if (t == null) {
throw new BugInCF("Unexpected null tree for node: " + mn);
}
assert TreeUtils.isUseOfElement(t) : "@AssumeAssertion(nullness): tree kind";
ExecutableElement invokedMethod = TreeUtils.elementFromUse(t);
// Note that the method might be nondeterministic.
List<JavaExpression> parameters = CollectionsPlume.mapList(JavaExpression::fromNode, mn.getArguments());
JavaExpression methodReceiver;
if (ElementUtils.isStatic(invokedMethod)) {
methodReceiver = new ClassName(mn.getTarget().getReceiver().getType());
} else {
methodReceiver = fromNode(mn.getTarget().getReceiver());
}
result = new MethodCall(mn.getType(), invokedMethod, methodReceiver, parameters);
}
if (result == null) {
result = new Unknown(receiverNode);
}
return result;
}
use of org.checkerframework.dataflow.cfg.node.SuperNode in project checker-framework by typetools.
the class CFGTranslationPhaseOne method visitIdentifier.
@Override
public Node visitIdentifier(IdentifierTree tree, Void p) {
Node node;
if (TreeUtils.isFieldAccess(tree)) {
Node receiver = getReceiver(tree);
node = new FieldAccessNode(tree, receiver);
} else {
Element element = TreeUtils.elementFromUse(tree);
switch(element.getKind()) {
case FIELD:
// Note that "this"/"super" is a field, but not a field access.
if (element.getSimpleName().contentEquals("this")) {
node = new ExplicitThisNode(tree);
} else {
node = new SuperNode(tree);
}
break;
case EXCEPTION_PARAMETER:
case LOCAL_VARIABLE:
case RESOURCE_VARIABLE:
case PARAMETER:
node = new LocalVariableNode(tree);
break;
case PACKAGE:
node = new PackageNameNode(tree);
break;
default:
if (ElementUtils.isTypeDeclaration(element)) {
node = new ClassNameNode(tree);
break;
} else if (ElementUtils.isBindingVariable(element)) {
// Note: BINDING_VARIABLE should be added as a direct case above when instanceof pattern
// matching and Java15 are supported.
node = new LocalVariableNode(tree);
break;
}
throw new BugInCF("bad element kind " + element.getKind());
}
}
if (node instanceof ClassNameNode) {
extendWithClassNameNode((ClassNameNode) node);
} else {
extendWithNode(node);
}
return node;
}
Aggregations