aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java')
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java140
1 files changed, 140 insertions, 0 deletions
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java
new file mode 100644
index 0000000000..85d17e7c06
--- /dev/null
+++ b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java
@@ -0,0 +1,140 @@
+package org.checkerframework.dataflow.cfg.node;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+
+import org.checkerframework.javacutil.TreeUtils;
+
+import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+
+/**
+ * An assignment context for a node, which represents the place to which the
+ * node with this context is 'assigned' to. An 'assignment' (as we use the term
+ * here) can occur for Java assignments, method calls (for all the actual
+ * parameters which get assigned to their formal parameters) or method return
+ * statements.
+ *
+ * <p>
+ * The main use of {@link AssignmentContext} is to be able to get the declared
+ * type of the left-hand side of the assignment for proper type-refinement.
+ *
+ * @author Stefan Heule
+ */
+public abstract class AssignmentContext {
+
+ /**
+ * An assignment context for an assignment 'lhs = rhs'.
+ */
+ public static class AssignmentLhsContext extends AssignmentContext {
+
+ protected final Node node;
+
+ public AssignmentLhsContext(Node node) {
+ this.node = node;
+ }
+
+ @Override
+ public Element getElementForType() {
+ Tree tree = node.getTree();
+ if (tree == null) {
+ return null;
+ } else if (tree instanceof ExpressionTree) {
+ return TreeUtils.elementFromUse((ExpressionTree) tree);
+ } else if (tree instanceof VariableTree) {
+ return TreeUtils.elementFromDeclaration((VariableTree) tree);
+ } else {
+ assert false : "unexpected tree";
+ return null;
+ }
+ }
+
+ @Override
+ public Tree getContextTree() {
+ return node.getTree();
+ }
+ }
+
+ /**
+ * An assignment context for a method parameter.
+ */
+ public static class MethodParameterContext extends AssignmentContext {
+
+ protected final ExecutableElement method;
+ protected final int paramNum;
+
+ public MethodParameterContext(ExecutableElement method, int paramNum) {
+ this.method = method;
+ this.paramNum = paramNum;
+ }
+
+ @Override
+ public Element getElementForType() {
+ return method.getParameters().get(paramNum);
+ }
+
+ @Override
+ public Tree getContextTree() {
+ // TODO: what is the right assignment context? We might not have
+ // a tree for the invoked method.
+ return null;
+ }
+ }
+
+ /**
+ * An assignment context for method return statements.
+ */
+ public static class MethodReturnContext extends AssignmentContext {
+
+ protected final ExecutableElement method;
+ protected final Tree ret;
+
+ public MethodReturnContext(MethodTree method) {
+ this.method = TreeUtils.elementFromDeclaration(method);
+ this.ret = method.getReturnType();
+ }
+
+ @Override
+ public Element getElementForType() {
+ return method;
+ }
+
+ @Override
+ public Tree getContextTree() {
+ return ret;
+ }
+ }
+
+ /**
+ * An assignment context for lambda return statements.
+ */
+ public static class LambdaReturnContext extends AssignmentContext {
+
+ protected final ExecutableElement method;
+
+ public LambdaReturnContext(ExecutableElement method) {
+ this.method = method;
+ }
+
+ @Override
+ public Element getElementForType() {
+ return method;
+ }
+
+ @Override
+ public Tree getContextTree() {
+ // TODO: what is the right assignment context? We might not have
+ // a tree for the invoked method.
+ return null;
+ }
+ }
+
+ /**
+ * Returns an {@link Element} that has the type of this assignment context.
+ */
+ public abstract Element getElementForType();
+
+ public abstract Tree getContextTree();
+}