aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/checker_framework_dataflow
diff options
context:
space:
mode:
authorGravatar Liam Miller-Cushon <cushon@google.com>2018-03-28 11:42:55 -0700
committerGravatar Vladimir Moskva <vladmos@google.com>2018-04-04 14:13:01 +0200
commit88a007244f51ed66a62d442e28de483e13a68576 (patch)
tree7d1f05429efd1553bc18fb54648c7b51922c38a3 /third_party/checker_framework_dataflow
parent83d8ef1c4a67c23c103741cca23bafafdc811c79 (diff)
Update to version 2.4.0 of Checker Framework dataflow and javacutil
Change-Id: I29e007625d0a25279d8b2967f89b1014b4825bd6
Diffstat (limited to 'third_party/checker_framework_dataflow')
-rw-r--r--third_party/checker_framework_dataflow/BUILD17
-rw-r--r--third_party/checker_framework_dataflow/dataflow-2.4.0-sources.jarbin0 -> 162105 bytes
-rw-r--r--third_party/checker_framework_dataflow/dataflow-2.4.0.jarbin0 -> 308674 bytes
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AbstractValue.java25
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Analysis.java767
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java220
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/ConditionalTransferResult.java126
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/FlowExpressions.java1143
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/RegularTransferResult.java116
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Store.java91
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferFunction.java41
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferInput.java250
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferResult.java104
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGBuilder.java4491
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGVisualizer.java167
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/ControlFlowGraph.java246
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/DOTCFGVisualizer.java511
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/JavaSource2CFGDOT.java269
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/UnderlyingAST.java125
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/Block.java31
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/BlockImpl.java57
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlock.java30
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlockImpl.java81
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlock.java27
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlockImpl.java66
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlock.java27
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlockImpl.java59
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlock.java24
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlockImpl.java45
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlock.java31
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlockImpl.java22
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java374
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayAccessNode.java81
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayCreationNode.java136
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayTypeNode.java60
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssertionErrorNode.java80
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java126
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentNode.java93
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BinaryOperationNode.java52
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseAndNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseComplementNode.java47
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseOrNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseXorNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BooleanLiteralNode.java49
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CaseNode.java81
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CharacterLiteralNode.java51
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java120
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalAndNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalNotNode.java47
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalOrNode.java47
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/DoubleLiteralNode.java50
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/EqualToNode.java47
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ExplicitThisLiteralNode.java41
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java106
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatLiteralNode.java50
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingDivisionNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingRemainderNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FunctionalInterfaceNode.java90
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanOrEqualNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ImplicitThisLiteralNode.java31
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/InstanceOfNode.java87
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerDivisionNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerLiteralNode.java51
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerRemainderNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LeftShiftNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanNode.java51
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanOrEqualNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LocalVariableNode.java101
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LongLiteralNode.java50
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MarkerNode.java82
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodAccessNode.java78
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodInvocationNode.java126
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NarrowingConversionNode.java76
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/Node.java144
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java160
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NotEqualNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullChkNode.java69
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullLiteralNode.java49
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalAdditionNode.java47
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMinusNode.java47
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMultiplicationNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalPlusNode.java47
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalSubtractionNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ObjectCreationNode.java101
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PackageNameNode.java101
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ParameterizedTypeNode.java67
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java60
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ReturnNode.java100
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ShortLiteralNode.java54
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SignedRightShiftNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateAssignmentNode.java57
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConversionNode.java76
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringLiteralNode.java53
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SuperNode.java66
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SynchronizedNode.java89
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TernaryExpressionNode.java94
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThisLiteralNode.java45
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThrowNode.java69
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TypeCastNode.java72
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnaryOperationNode.java45
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnsignedRightShiftNode.java48
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ValueLiteralNode.java72
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/VariableDeclarationNode.java71
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/WideningConversionNode.java76
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/playground/ConstantPropagationPlayground.java27
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/Constant.java102
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationStore.java163
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationTransfer.java85
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Deterministic.java87
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Pure.java30
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/SideEffectFree.java54
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/TerminatesExecution.java34
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/HashCodeUtils.java102
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java151
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/NodeUtils.java56
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityChecker.java491
-rw-r--r--third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityUtils.java91
119 files changed, 5 insertions, 16033 deletions
diff --git a/third_party/checker_framework_dataflow/BUILD b/third_party/checker_framework_dataflow/BUILD
index b174255011..8361cdc1bb 100644
--- a/third_party/checker_framework_dataflow/BUILD
+++ b/third_party/checker_framework_dataflow/BUILD
@@ -7,20 +7,13 @@ filegroup(
srcs = glob(["**"]),
)
-java_library(
+java_import(
name = "checker_framework_dataflow",
- srcs = glob(["java/**"]),
- javacopts = ["-Xep:MissingCasesInEnumSwitch:OFF"],
- deps = [
- "//third_party/checker_framework_javacutil",
- "@local_jdk//:langtools-neverlink",
- ],
+ jars = ["dataflow-2.4.0.jar"],
+ srcjar = "dataflow-2.4.0-sources.jar",
)
-load("//tools/build_rules:java_rules_skylark.bzl", "bootstrap_java_library")
-
-bootstrap_java_library(
+filegroup(
name = "bootstrap",
- srcs = glob(["java/**"]),
- deps = ["//third_party/checker_framework_javacutil:bootstrap"],
+ srcs = ["dataflow-2.4.0.jar"],
)
diff --git a/third_party/checker_framework_dataflow/dataflow-2.4.0-sources.jar b/third_party/checker_framework_dataflow/dataflow-2.4.0-sources.jar
new file mode 100644
index 0000000000..d95f203b8e
--- /dev/null
+++ b/third_party/checker_framework_dataflow/dataflow-2.4.0-sources.jar
Binary files differ
diff --git a/third_party/checker_framework_dataflow/dataflow-2.4.0.jar b/third_party/checker_framework_dataflow/dataflow-2.4.0.jar
new file mode 100644
index 0000000000..2ee9edecdd
--- /dev/null
+++ b/third_party/checker_framework_dataflow/dataflow-2.4.0.jar
Binary files differ
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AbstractValue.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AbstractValue.java
deleted file mode 100644
index 25b78075da..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AbstractValue.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-/**
- * An abstract value used in the org.checkerframework.dataflow analysis.
- *
- * @author Stefan Heule
- */
-public interface AbstractValue<V extends AbstractValue<V>> {
-
- /**
- * Compute the least upper bound of two stores.
- *
- * <p><em>Important</em>: This method must fulfill the following contract:
- *
- * <ul>
- * <li>Does not change {@code this}.
- * <li>Does not change {@code other}.
- * <li>Returns a fresh object which is not aliased yet.
- * <li>Returns an object of the same (dynamic) type as {@code this}, even if the signature is
- * more permissive.
- * <li>Is commutative.
- * </ul>
- */
- V leastUpperBound(V other);
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Analysis.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Analysis.java
deleted file mode 100644
index 2e81b4af4a..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Analysis.java
+++ /dev/null
@@ -1,767 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.LambdaExpressionTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.PriorityQueue;
-import java.util.Set;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.cfg.ControlFlowGraph;
-import org.checkerframework.dataflow.cfg.UnderlyingAST;
-import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGLambda;
-import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod;
-import org.checkerframework.dataflow.cfg.UnderlyingAST.Kind;
-import org.checkerframework.dataflow.cfg.block.Block;
-import org.checkerframework.dataflow.cfg.block.ConditionalBlock;
-import org.checkerframework.dataflow.cfg.block.ExceptionBlock;
-import org.checkerframework.dataflow.cfg.block.RegularBlock;
-import org.checkerframework.dataflow.cfg.block.SpecialBlock;
-import org.checkerframework.dataflow.cfg.node.AssignmentNode;
-import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.dataflow.cfg.node.ReturnNode;
-import org.checkerframework.javacutil.ElementUtils;
-import org.checkerframework.javacutil.Pair;
-
-/**
- * An implementation of an iterative algorithm to solve a org.checkerframework.dataflow problem,
- * given a control flow graph and a transfer function.
- *
- * @author Stefan Heule
- * @param <A> the abstract value type to be tracked by the analysis
- * @param <S> the store type used in the analysis
- * @param <T> the transfer function type that is used to approximated runtime behavior
- */
-public class Analysis<
- A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>> {
-
- /** Is the analysis currently running? */
- protected boolean isRunning = false;
-
- /** The transfer function for regular nodes. */
- protected T transferFunction;
-
- /** The control flow graph to perform the analysis on. */
- protected ControlFlowGraph cfg;
-
- /** The associated processing environment */
- protected final ProcessingEnvironment env;
-
- /** Instance of the types utility. */
- protected final Types types;
-
- /** Then stores before every basic block (assumed to be 'no information' if not present). */
- protected IdentityHashMap<Block, S> thenStores;
-
- /** Else stores before every basic block (assumed to be 'no information' if not present). */
- protected IdentityHashMap<Block, S> elseStores;
-
- /**
- * Number of times every block has been analyzed since the last time widening was applied. Null,
- * if maxCountBeforeWidening is -1 which implies widening isn't used for this analysis.
- */
- protected IdentityHashMap<Block, Integer> blockCount;
-
- /**
- * Number of times a block can be analyzed before widening. -1 implies that widening shouldn't
- * be used.
- */
- protected final int maxCountBeforeWidening;
-
- /**
- * The transfer inputs before every basic block (assumed to be 'no information' if not present).
- */
- protected IdentityHashMap<Block, TransferInput<A, S>> inputs;
-
- /** The stores after every return statement. */
- protected IdentityHashMap<ReturnNode, TransferResult<A, S>> storesAtReturnStatements;
-
- /** The worklist used for the fix-point iteration. */
- protected Worklist worklist;
-
- /** Abstract values of nodes. */
- protected IdentityHashMap<Node, A> nodeValues;
-
- /** Map from (effectively final) local variable elements to their abstract value. */
- public HashMap<Element, A> finalLocalValues;
-
- /**
- * The node that is currently handled in the analysis (if it is running). The following
- * invariant holds:
- *
- * <pre>
- * !isRunning &rArr; (currentNode == null)
- * </pre>
- */
- protected Node currentNode;
-
- /**
- * The tree that is currently being looked at. The transfer function can set this tree to make
- * sure that calls to {@code getValue} will not return information for this given tree.
- */
- protected Tree currentTree;
-
- /** The current transfer input when the analysis is running. */
- protected TransferInput<A, S> currentInput;
-
- public Tree getCurrentTree() {
- return currentTree;
- }
-
- public void setCurrentTree(Tree currentTree) {
- this.currentTree = currentTree;
- }
-
- /**
- * Construct an object that can perform a org.checkerframework.dataflow analysis over a control
- * flow graph. The transfer function is set later using {@code setTransferFunction}.
- */
- public Analysis(ProcessingEnvironment env) {
- this(env, null, -1);
- }
-
- /**
- * Construct an object that can perform a org.checkerframework.dataflow analysis over a control
- * flow graph, given a transfer function.
- */
- public Analysis(ProcessingEnvironment env, T transfer) {
- this(env, transfer, -1);
- }
-
- /**
- * Construct an object that can perform a org.checkerframework.dataflow analysis over a control
- * flow graph, given a transfer function.
- */
- public Analysis(ProcessingEnvironment env, T transfer, int maxCountBeforeWidening) {
- this.env = env;
- types = env.getTypeUtils();
- this.transferFunction = transfer;
- this.maxCountBeforeWidening = maxCountBeforeWidening;
- this.transferFunction = transfer;
- }
-
- public void setTransferFunction(T transfer) {
- this.transferFunction = transfer;
- }
-
- public T getTransferFunction() {
- return transferFunction;
- }
-
- public Types getTypes() {
- return types;
- }
-
- public ProcessingEnvironment getEnv() {
- return env;
- }
-
- /**
- * Perform the actual analysis. Should only be called once after the object has been created.
- */
- public void performAnalysis(ControlFlowGraph cfg) {
- assert isRunning == false;
- isRunning = true;
-
- init(cfg);
-
- while (!worklist.isEmpty()) {
- Block b = worklist.poll();
-
- switch (b.getType()) {
- case REGULAR_BLOCK:
- {
- RegularBlock rb = (RegularBlock) b;
-
- // apply transfer function to contents
- TransferInput<A, S> inputBefore = getInputBefore(rb);
- currentInput = inputBefore.copy();
- TransferResult<A, S> transferResult = null;
- Node lastNode = null;
- boolean addToWorklistAgain = false;
- for (Node n : rb.getContents()) {
- transferResult = callTransferFunction(n, currentInput);
- addToWorklistAgain |= updateNodeValues(n, transferResult);
- currentInput = new TransferInput<>(n, this, transferResult);
- lastNode = n;
- }
- // loop will run at least one, making transferResult non-null
-
- // propagate store to successors
- Block succ = rb.getSuccessor();
- assert succ != null
- : "regular basic block without non-exceptional successor unexpected";
- propagateStoresTo(
- succ, lastNode, currentInput, rb.getFlowRule(), addToWorklistAgain);
- break;
- }
-
- case EXCEPTION_BLOCK:
- {
- ExceptionBlock eb = (ExceptionBlock) b;
-
- // apply transfer function to content
- TransferInput<A, S> inputBefore = getInputBefore(eb);
- currentInput = inputBefore.copy();
- Node node = eb.getNode();
- TransferResult<A, S> transferResult =
- callTransferFunction(node, currentInput);
- boolean addToWorklistAgain = updateNodeValues(node, transferResult);
-
- // propagate store to successor
- Block succ = eb.getSuccessor();
- if (succ != null) {
- currentInput = new TransferInput<>(node, this, transferResult);
- // TODO? Variable wasn't used.
- // Store.FlowRule storeFlow = eb.getFlowRule();
- propagateStoresTo(
- succ, node, currentInput, eb.getFlowRule(), addToWorklistAgain);
- }
-
- // propagate store to exceptional successors
- for (Entry<TypeMirror, Set<Block>> e :
- eb.getExceptionalSuccessors().entrySet()) {
- TypeMirror cause = e.getKey();
- S exceptionalStore = transferResult.getExceptionalStore(cause);
- if (exceptionalStore != null) {
- for (Block exceptionSucc : e.getValue()) {
- addStoreBefore(
- exceptionSucc,
- node,
- exceptionalStore,
- Store.Kind.BOTH,
- addToWorklistAgain);
- }
- } else {
- for (Block exceptionSucc : e.getValue()) {
- addStoreBefore(
- exceptionSucc,
- node,
- inputBefore.copy().getRegularStore(),
- Store.Kind.BOTH,
- addToWorklistAgain);
- }
- }
- }
- break;
- }
-
- case CONDITIONAL_BLOCK:
- {
- ConditionalBlock cb = (ConditionalBlock) b;
-
- // get store before
- TransferInput<A, S> inputBefore = getInputBefore(cb);
- TransferInput<A, S> input = inputBefore.copy();
-
- // propagate store to successor
- Block thenSucc = cb.getThenSuccessor();
- Block elseSucc = cb.getElseSuccessor();
-
- propagateStoresTo(thenSucc, null, input, cb.getThenFlowRule(), false);
- propagateStoresTo(elseSucc, null, input, cb.getElseFlowRule(), false);
- break;
- }
-
- case SPECIAL_BLOCK:
- {
- // special basic blocks are empty and cannot throw exceptions,
- // thus there is no need to perform any analysis.
- SpecialBlock sb = (SpecialBlock) b;
- Block succ = sb.getSuccessor();
- if (succ != null) {
- propagateStoresTo(
- succ, null, getInputBefore(b), sb.getFlowRule(), false);
- }
- break;
- }
-
- default:
- assert false;
- break;
- }
- }
-
- assert isRunning == true;
- isRunning = false;
- }
-
- /**
- * Propagate the stores in currentInput to the successor block, succ, according to the flowRule.
- */
- protected void propagateStoresTo(
- Block succ,
- Node node,
- TransferInput<A, S> currentInput,
- Store.FlowRule flowRule,
- boolean addToWorklistAgain) {
- switch (flowRule) {
- case EACH_TO_EACH:
- if (currentInput.containsTwoStores()) {
- addStoreBefore(
- succ,
- node,
- currentInput.getThenStore(),
- Store.Kind.THEN,
- addToWorklistAgain);
- addStoreBefore(
- succ,
- node,
- currentInput.getElseStore(),
- Store.Kind.ELSE,
- addToWorklistAgain);
- } else {
- addStoreBefore(
- succ,
- node,
- currentInput.getRegularStore(),
- Store.Kind.BOTH,
- addToWorklistAgain);
- }
- break;
- case THEN_TO_BOTH:
- addStoreBefore(
- succ,
- node,
- currentInput.getThenStore(),
- Store.Kind.BOTH,
- addToWorklistAgain);
- break;
- case ELSE_TO_BOTH:
- addStoreBefore(
- succ,
- node,
- currentInput.getElseStore(),
- Store.Kind.BOTH,
- addToWorklistAgain);
- break;
- case THEN_TO_THEN:
- addStoreBefore(
- succ,
- node,
- currentInput.getThenStore(),
- Store.Kind.THEN,
- addToWorklistAgain);
- break;
- case ELSE_TO_ELSE:
- addStoreBefore(
- succ,
- node,
- currentInput.getElseStore(),
- Store.Kind.ELSE,
- addToWorklistAgain);
- break;
- }
- }
-
- /**
- * Updates the value of node {@code node} to the value of the {@code transferResult}. Returns
- * true if the node's value changed, or a store was updated.
- */
- protected boolean updateNodeValues(Node node, TransferResult<A, S> transferResult) {
- A newVal = transferResult.getResultValue();
- boolean nodeValueChanged = false;
-
- if (newVal != null) {
- A oldVal = nodeValues.get(node);
- nodeValues.put(node, newVal);
- nodeValueChanged = !Objects.equals(oldVal, newVal);
- }
-
- return nodeValueChanged || transferResult.storeChanged();
- }
-
- /**
- * Call the transfer function for node {@code node}, and set that node as current node first.
- */
- protected TransferResult<A, S> callTransferFunction(Node node, TransferInput<A, S> store) {
-
- if (node.isLValue()) {
- // TODO: should the default behavior be to return either a regular
- // transfer result or a conditional transfer result (depending on
- // store.hasTwoStores()), or is the following correct?
- return new RegularTransferResult<A, S>(null, store.getRegularStore());
- }
- store.node = node;
- currentNode = node;
- TransferResult<A, S> transferResult = node.accept(transferFunction, store);
- currentNode = null;
- if (node instanceof ReturnNode) {
- // save a copy of the store to later check if some property held at
- // a given return statement
- storesAtReturnStatements.put((ReturnNode) node, transferResult);
- }
- if (node instanceof AssignmentNode) {
- // store the flow-refined value for effectively final local variables
- AssignmentNode assignment = (AssignmentNode) node;
- Node lhst = assignment.getTarget();
- if (lhst instanceof LocalVariableNode) {
- LocalVariableNode lhs = (LocalVariableNode) lhst;
- Element elem = lhs.getElement();
- if (ElementUtils.isEffectivelyFinal(elem)) {
- finalLocalValues.put(elem, transferResult.getResultValue());
- }
- }
- }
- return transferResult;
- }
-
- /** Initialize the analysis with a new control flow graph. */
- protected void init(ControlFlowGraph cfg) {
- this.cfg = cfg;
- thenStores = new IdentityHashMap<>();
- elseStores = new IdentityHashMap<>();
- blockCount = maxCountBeforeWidening == -1 ? null : new IdentityHashMap<Block, Integer>();
- inputs = new IdentityHashMap<>();
- storesAtReturnStatements = new IdentityHashMap<>();
- worklist = new Worklist(cfg);
- nodeValues = new IdentityHashMap<>();
- finalLocalValues = new HashMap<>();
- worklist.add(cfg.getEntryBlock());
-
- List<LocalVariableNode> parameters = null;
- UnderlyingAST underlyingAST = cfg.getUnderlyingAST();
- if (underlyingAST.getKind() == Kind.METHOD) {
- MethodTree tree = ((CFGMethod) underlyingAST).getMethod();
- parameters = new ArrayList<>();
- for (VariableTree p : tree.getParameters()) {
- LocalVariableNode var = new LocalVariableNode(p);
- parameters.add(var);
- // TODO: document that LocalVariableNode has no block that it
- // belongs to
- }
- } else if (underlyingAST.getKind() == Kind.LAMBDA) {
- LambdaExpressionTree lambda = ((CFGLambda) underlyingAST).getLambdaTree();
- parameters = new ArrayList<>();
- for (VariableTree p : lambda.getParameters()) {
- LocalVariableNode var = new LocalVariableNode(p);
- parameters.add(var);
- // TODO: document that LocalVariableNode has no block that it
- // belongs to
- }
-
- } else {
- // nothing to do
- }
- S initialStore = transferFunction.initialStore(underlyingAST, parameters);
- Block entry = cfg.getEntryBlock();
- thenStores.put(entry, initialStore);
- elseStores.put(entry, initialStore);
- inputs.put(entry, new TransferInput<>(null, this, initialStore));
- }
-
- /**
- * Add a basic block to the worklist. If {@code b} is already present, the method does nothing.
- */
- protected void addToWorklist(Block b) {
- // TODO: use a more efficient way to check if b is already present
- if (!worklist.contains(b)) {
- worklist.add(b);
- }
- }
-
- /**
- * Add a store before the basic block {@code b} by merging with the existing stores for that
- * location.
- */
- protected void addStoreBefore(
- Block b, Node node, S s, Store.Kind kind, boolean addBlockToWorklist) {
- S thenStore = getStoreBefore(b, Store.Kind.THEN);
- S elseStore = getStoreBefore(b, Store.Kind.ELSE);
- boolean shouldWiden = false;
- if (blockCount != null) {
- Integer count = blockCount.get(b);
- if (count == null) {
- count = 0;
- }
- shouldWiden = count >= maxCountBeforeWidening;
- if (shouldWiden) {
- blockCount.put(b, 0);
- } else {
- blockCount.put(b, count + 1);
- }
- }
-
- switch (kind) {
- case THEN:
- {
- // Update the then store
- S newThenStore = mergeStores(s, thenStore, shouldWiden);
- if (!newThenStore.equals(thenStore)) {
- thenStores.put(b, newThenStore);
- if (elseStore != null) {
- inputs.put(b, new TransferInput<>(node, this, newThenStore, elseStore));
- addBlockToWorklist = true;
- }
- }
- break;
- }
- case ELSE:
- {
- // Update the else store
- S newElseStore = mergeStores(s, elseStore, shouldWiden);
- if (!newElseStore.equals(elseStore)) {
- elseStores.put(b, newElseStore);
- if (thenStore != null) {
- inputs.put(b, new TransferInput<>(node, this, thenStore, newElseStore));
- addBlockToWorklist = true;
- }
- }
- break;
- }
- case BOTH:
- if (thenStore == elseStore) {
- // Currently there is only one regular store
- S newStore = mergeStores(s, thenStore, shouldWiden);
- if (!newStore.equals(thenStore)) {
- thenStores.put(b, newStore);
- elseStores.put(b, newStore);
- inputs.put(b, new TransferInput<>(node, this, newStore));
- addBlockToWorklist = true;
- }
- } else {
- boolean storeChanged = false;
-
- S newThenStore = mergeStores(s, thenStore, shouldWiden);
- if (!newThenStore.equals(thenStore)) {
- thenStores.put(b, newThenStore);
- storeChanged = true;
- }
-
- S newElseStore = mergeStores(s, elseStore, shouldWiden);
- if (!newElseStore.equals(elseStore)) {
- elseStores.put(b, newElseStore);
- storeChanged = true;
- }
-
- if (storeChanged) {
- inputs.put(b, new TransferInput<>(node, this, newThenStore, newElseStore));
- addBlockToWorklist = true;
- }
- }
- }
-
- if (addBlockToWorklist) {
- addToWorklist(b);
- }
- }
-
- private S mergeStores(S newStore, S previousStore, boolean shouldWiden) {
- if (previousStore == null) {
- return newStore;
- } else if (shouldWiden) {
- return newStore.widenedUpperBound(previousStore);
- } else {
- return newStore.leastUpperBound(previousStore);
- }
- }
-
- /**
- * A worklist is a priority queue of blocks in which the order is given by depth-first ordering
- * to place non-loop predecessors ahead of successors.
- */
- protected static class Worklist {
-
- /** Map all blocks in the CFG to their depth-first order. */
- protected IdentityHashMap<Block, Integer> depthFirstOrder;
-
- /** Comparator to allow priority queue to order blocks by their depth-first order. */
- public class DFOComparator implements Comparator<Block> {
- @Override
- public int compare(Block b1, Block b2) {
- return depthFirstOrder.get(b1) - depthFirstOrder.get(b2);
- }
- }
-
- /** The backing priority queue. */
- protected PriorityQueue<Block> queue;
-
- public Worklist(ControlFlowGraph cfg) {
- depthFirstOrder = new IdentityHashMap<>();
- int count = 1;
- for (Block b : cfg.getDepthFirstOrderedBlocks()) {
- depthFirstOrder.put(b, count++);
- }
-
- queue = new PriorityQueue<Block>(11, new DFOComparator());
- }
-
- public boolean isEmpty() {
- return queue.isEmpty();
- }
-
- public boolean contains(Block block) {
- return queue.contains(block);
- }
-
- public void add(Block block) {
- queue.add(block);
- }
-
- public Block poll() {
- return queue.poll();
- }
-
- @Override
- public String toString() {
- return "Worklist(" + queue + ")";
- }
- }
-
- /**
- * Read the {@link TransferInput} for a particular basic block (or {@code null} if none exists
- * yet).
- */
- public /*@Nullable*/ TransferInput<A, S> getInput(Block b) {
- return getInputBefore(b);
- }
-
- /**
- * @return the transfer input corresponding to the location right before the basic block {@code
- * b}.
- */
- protected /*@Nullable*/ TransferInput<A, S> getInputBefore(Block b) {
- return inputs.get(b);
- }
-
- /** @return the store corresponding to the location right before the basic block {@code b}. */
- protected /*@Nullable*/ S getStoreBefore(Block b, Store.Kind kind) {
- switch (kind) {
- case THEN:
- return readFromStore(thenStores, b);
- case ELSE:
- return readFromStore(elseStores, b);
- default:
- assert false;
- return null;
- }
- }
-
- /**
- * Read the {@link Store} for a particular basic block from a map of stores (or {@code null} if
- * none exists yet).
- */
- protected static <S> /*@Nullable*/ S readFromStore(Map<Block, S> stores, Block b) {
- return stores.get(b);
- }
-
- /** Is the analysis currently running? */
- public boolean isRunning() {
- return isRunning;
- }
-
- /**
- * @return the abstract value for {@link Node} {@code n}, or {@code null} if no information is
- * available. Note that if the analysis has not finished yet, this value might not represent
- * the final value for this node.
- */
- public /*@Nullable*/ A getValue(Node n) {
- if (isRunning) {
- // we do not yet have a org.checkerframework.dataflow fact about the current node
- if (currentNode == null
- || currentNode == n
- || (currentTree != null && currentTree == n.getTree())) {
- return null;
- }
- // check that 'n' is a subnode of 'node'. Check immediate operands
- // first for efficiency.
- assert !n.isLValue() : "Did not expect an lvalue, but got " + n;
- if (!(currentNode != n
- && (currentNode.getOperands().contains(n)
- || currentNode.getTransitiveOperands().contains(n)))) {
- return null;
- }
- return nodeValues.get(n);
- }
- return nodeValues.get(n);
- }
-
- /**
- * @return the abstract value for {@link Tree} {@code t}, or {@code null} if no information is
- * available. Note that if the analysis has not finished yet, this value might not represent
- * the final value for this node.
- */
- public /*@Nullable*/ A getValue(Tree t) {
- // we do not yet have a org.checkerframework.dataflow fact about the current node
- if (t == currentTree) {
- return null;
- }
- Node nodeCorrespondingToTree = getNodeForTree(t);
- if (nodeCorrespondingToTree == null || nodeCorrespondingToTree.isLValue()) {
- return null;
- }
- return getValue(nodeCorrespondingToTree);
- }
-
- /** Get the {@link Node} for a given {@link Tree}. */
- public Node getNodeForTree(Tree t) {
- return cfg.getNodeCorrespondingToTree(t);
- }
-
- /**
- * Get the {@link MethodTree} of the current CFG if the argument {@link Tree} maps to a {@link
- * Node} in the CFG or null otherwise.
- */
- public /*@Nullable*/ MethodTree getContainingMethod(Tree t) {
- return cfg.getContainingMethod(t);
- }
-
- /**
- * Get the {@link ClassTree} of the current CFG if the argument {@link Tree} maps to a {@link
- * Node} in the CFG or null otherwise.
- */
- public /*@Nullable*/ ClassTree getContainingClass(Tree t) {
- return cfg.getContainingClass(t);
- }
-
- public List<Pair<ReturnNode, TransferResult<A, S>>> getReturnStatementStores() {
- List<Pair<ReturnNode, TransferResult<A, S>>> result = new ArrayList<>();
- for (ReturnNode returnNode : cfg.getReturnNodes()) {
- TransferResult<A, S> store = storesAtReturnStatements.get(returnNode);
- result.add(Pair.of(returnNode, store));
- }
- return result;
- }
-
- public AnalysisResult<A, S> getResult() {
- assert !isRunning;
- IdentityHashMap<Tree, Node> treeLookup = cfg.getTreeLookup();
- return new AnalysisResult<>(nodeValues, inputs, treeLookup, finalLocalValues);
- }
-
- /**
- * @return the regular exit store, or {@code null}, if there is no such store (because the
- * method cannot exit through the regular exit block).
- */
- public /*@Nullable*/ S getRegularExitStore() {
- SpecialBlock regularExitBlock = cfg.getRegularExitBlock();
- if (inputs.containsKey(regularExitBlock)) {
- S regularExitStore = inputs.get(regularExitBlock).getRegularStore();
- return regularExitStore;
- } else {
- return null;
- }
- }
-
- public S getExceptionalExitStore() {
- S exceptionalExitStore = inputs.get(cfg.getExceptionalExitBlock()).getRegularStore();
- return exceptionalExitStore;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java
deleted file mode 100644
index 48f376dbea..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/AnalysisResult.java
+++ /dev/null
@@ -1,220 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.Tree;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.lang.model.element.Element;
-import org.checkerframework.dataflow.cfg.block.Block;
-import org.checkerframework.dataflow.cfg.block.ExceptionBlock;
-import org.checkerframework.dataflow.cfg.block.RegularBlock;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-/**
- * An {@link AnalysisResult} represents the result of a org.checkerframework.dataflow analysis by
- * providing the abstract values given a node or a tree. Note that it does not keep track of custom
- * results computed by some analysis.
- *
- * @author Stefan Heule
- * @param <A> type of the abstract value that is tracked
- */
-public class AnalysisResult<A extends AbstractValue<A>, S extends Store<S>> {
-
- /** Abstract values of nodes. */
- protected final IdentityHashMap<Node, A> nodeValues;
-
- /** Map from AST {@link Tree}s to {@link Node}s. */
- protected final IdentityHashMap<Tree, Node> treeLookup;
-
- /** Map from (effectively final) local variable elements to their abstract value. */
- protected final HashMap<Element, A> finalLocalValues;
-
- /** The stores before every method call. */
- protected final IdentityHashMap<Block, TransferInput<A, S>> stores;
-
- /** Initialize with a given node-value mapping. */
- public AnalysisResult(
- Map<Node, A> nodeValues,
- IdentityHashMap<Block, TransferInput<A, S>> stores,
- IdentityHashMap<Tree, Node> treeLookup,
- HashMap<Element, A> finalLocalValues) {
- this.nodeValues = new IdentityHashMap<>(nodeValues);
- this.treeLookup = new IdentityHashMap<>(treeLookup);
- this.stores = stores;
- this.finalLocalValues = finalLocalValues;
- }
-
- /** Initialize empty result. */
- public AnalysisResult() {
- nodeValues = new IdentityHashMap<>();
- treeLookup = new IdentityHashMap<>();
- stores = new IdentityHashMap<>();
- finalLocalValues = new HashMap<>();
- }
-
- /** Combine with another analysis result. */
- public void combine(AnalysisResult<A, S> other) {
- for (Entry<Node, A> e : other.nodeValues.entrySet()) {
- nodeValues.put(e.getKey(), e.getValue());
- }
- for (Entry<Tree, Node> e : other.treeLookup.entrySet()) {
- treeLookup.put(e.getKey(), e.getValue());
- }
- for (Entry<Block, TransferInput<A, S>> e : other.stores.entrySet()) {
- stores.put(e.getKey(), e.getValue());
- }
- for (Entry<Element, A> e : other.finalLocalValues.entrySet()) {
- finalLocalValues.put(e.getKey(), e.getValue());
- }
- }
-
- /** @return the value of effectively final local variables */
- public HashMap<Element, A> getFinalLocalValues() {
- return finalLocalValues;
- }
-
- /**
- * @return the abstract value for {@link Node} {@code n}, or {@code null} if no information is
- * available.
- */
- public /*@Nullable*/ A getValue(Node n) {
- return nodeValues.get(n);
- }
-
- /**
- * @return the abstract value for {@link Tree} {@code t}, or {@code null} if no information is
- * available.
- */
- public /*@Nullable*/ A getValue(Tree t) {
- A val = getValue(treeLookup.get(t));
- return val;
- }
-
- /** @return the {@link Node} for a given {@link Tree}. */
- public /*@Nullable*/ Node getNodeForTree(Tree tree) {
- return treeLookup.get(tree);
- }
-
- /** @return the store immediately before a given {@link Tree}. */
- public S getStoreBefore(Tree tree) {
- Node node = getNodeForTree(tree);
- if (node == null) {
- return null;
- }
- return getStoreBefore(node);
- }
-
- /** @return the store immediately before a given {@link Node}. */
- public S getStoreBefore(Node node) {
- return runAnalysisFor(node, true);
- }
-
- /** @return the store immediately after a given {@link Tree}. */
- public S getStoreAfter(Tree tree) {
- Node node = getNodeForTree(tree);
- if (node == null) {
- return null;
- }
- return getStoreAfter(node);
- }
-
- /** @return the store immediately after a given {@link Node}. */
- public S getStoreAfter(Node node) {
- return runAnalysisFor(node, false);
- }
-
- /**
- * Runs the analysis again within the block of {@code node} and returns the store at the
- * location of {@code node}. If {@code before} is true, then the store immediately before the
- * {@link Node} {@code node} is returned. Otherwise, the store after {@code node} is returned.
- *
- * <p>If the given {@link Node} cannot be reached (in the control flow graph), then {@code null}
- * is returned.
- */
- protected S runAnalysisFor(Node node, boolean before) {
- Block block = node.getBlock();
- TransferInput<A, S> transferInput = stores.get(block);
- if (transferInput == null) {
- return null;
- }
- return runAnalysisFor(node, before, transferInput);
- }
-
- /**
- * Runs the analysis again within the block of {@code node} and returns the store at the
- * location of {@code node}. If {@code before} is true, then the store immediately before the
- * {@link Node} {@code node} is returned. Otherwise, the store after {@code node} is returned.
- */
- public static <A extends AbstractValue<A>, S extends Store<S>> S runAnalysisFor(
- Node node, boolean before, TransferInput<A, S> transferInput) {
- assert node != null;
- Block block = node.getBlock();
- assert transferInput != null;
- Analysis<A, S, ?> analysis = transferInput.analysis;
- Node oldCurrentNode = analysis.currentNode;
-
- if (analysis.isRunning) {
- return analysis.currentInput.getRegularStore();
- }
- analysis.isRunning = true;
- try {
- switch (block.getType()) {
- case REGULAR_BLOCK:
- {
- RegularBlock rb = (RegularBlock) block;
-
- // Apply transfer function to contents until we found the node
- // we
- // are looking for.
- TransferInput<A, S> store = transferInput;
- TransferResult<A, S> transferResult = null;
- for (Node n : rb.getContents()) {
- analysis.currentNode = n;
- if (n == node && before) {
- return store.getRegularStore();
- }
- transferResult = analysis.callTransferFunction(n, store);
- if (n == node) {
- return transferResult.getRegularStore();
- }
- store = new TransferInput<>(n, analysis, transferResult);
- }
- // This point should never be reached. If the block of 'node' is
- // 'block', then 'node' must be part of the contents of 'block'.
- assert false;
- return null;
- }
-
- case EXCEPTION_BLOCK:
- {
- ExceptionBlock eb = (ExceptionBlock) block;
-
- // apply transfer function to content
- assert eb.getNode() == node;
- if (before) {
- return transferInput.getRegularStore();
- }
- analysis.currentNode = node;
- TransferResult<A, S> transferResult =
- analysis.callTransferFunction(node, transferInput);
- return transferResult.getRegularStore();
- }
-
- default:
- // Only regular blocks and exceptional blocks can hold nodes.
- assert false;
- break;
- }
-
- return null;
- } finally {
- analysis.currentNode = oldCurrentNode;
- analysis.isRunning = false;
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/ConditionalTransferResult.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/ConditionalTransferResult.java
deleted file mode 100644
index 99a8a525ec..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/ConditionalTransferResult.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-import java.util.Map;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Implementation of a {@link TransferResult} with two non-exceptional store; one for the 'then'
- * edge and one for 'else'. The result of {@code getRegularStore} will be the least upper bound of
- * the two underlying stores.
- *
- * @author Stefan Heule
- * @param <S> the {@link Store} used to keep track of intermediate results
- */
-public class ConditionalTransferResult<A extends AbstractValue<A>, S extends Store<S>>
- extends TransferResult<A, S> {
-
- private final boolean storeChanged;
-
- /** The 'then' result store. */
- protected S thenStore;
-
- /** The 'else' result store. */
- protected S elseStore;
-
- /**
- * Create a {@code ConditionalTransferResult} with {@code thenStore} as the resulting store if
- * the corresponding {@link org.checkerframework.dataflow.cfg.node.Node} evaluates to {@code
- * true} and {@code elseStore} otherwise.
- *
- * <p>For the meaning of storeChanged, see {@link
- * org.checkerframework.dataflow.analysis.TransferResult#storeChanged}.
- *
- * <p><em>Exceptions</em>: If the corresponding {@link
- * org.checkerframework.dataflow.cfg.node.Node} throws an exception, then it is assumed that no
- * special handling is necessary and the store before the corresponding {@link
- * org.checkerframework.dataflow.cfg.node.Node} will be passed along any exceptional edge.
- *
- * <p><em>Aliasing</em>: {@code thenStore} and {@code elseStore} are not allowed to be used
- * anywhere outside of this class (including use through aliases). Complete control over the
- * objects is transfered to this class.
- */
- public ConditionalTransferResult(A value, S thenStore, S elseStore, boolean storeChanged) {
- super(value);
- this.thenStore = thenStore;
- this.elseStore = elseStore;
- this.storeChanged = storeChanged;
- }
-
- public ConditionalTransferResult(A value, S thenStore, S elseStore) {
- this(value, thenStore, elseStore, false);
- }
-
- /**
- * Create a {@code ConditionalTransferResult} with {@code thenStore} as the resulting store if
- * the corresponding {@link org.checkerframework.dataflow.cfg.node.Node} evaluates to {@code
- * true} and {@code elseStore} otherwise.
- *
- * <p><em>Exceptions</em>: If the corresponding {@link
- * org.checkerframework.dataflow.cfg.node.Node} throws an exception, then the corresponding
- * store in {@code exceptionalStores} is used. If no exception is found in {@code
- * exceptionalStores}, then it is assumed that no special handling is necessary and the store
- * before the corresponding {@link org.checkerframework.dataflow.cfg.node.Node} will be passed
- * along any exceptional edge.
- *
- * <p><em>Aliasing</em>: {@code thenStore}, {@code elseStore}, and any store in {@code
- * exceptionalStores} are not allowed to be used anywhere outside of this class (including use
- * through aliases). Complete control over the objects is transfered to this class.
- */
- public ConditionalTransferResult(
- A value,
- S thenStore,
- S elseStore,
- Map<TypeMirror, S> exceptionalStores,
- boolean storeChanged) {
- super(value);
- this.exceptionalStores = exceptionalStores;
- this.thenStore = thenStore;
- this.elseStore = elseStore;
- this.storeChanged = storeChanged;
- }
-
- public ConditionalTransferResult(
- A value, S thenStore, S elseStore, Map<TypeMirror, S> exceptionalStores) {
- this(value, thenStore, elseStore, exceptionalStores, false);
- }
-
- @Override
- public S getRegularStore() {
- return thenStore.leastUpperBound(elseStore);
- }
-
- @Override
- public S getThenStore() {
- return thenStore;
- }
-
- @Override
- public S getElseStore() {
- return elseStore;
- }
-
- @Override
- public boolean containsTwoStores() {
- return true;
- }
-
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder();
- result.append("RegularTransferResult(");
- result.append(System.getProperty("line.separator"));
- result.append("resultValue = " + resultValue);
- result.append(System.getProperty("line.separator"));
- result.append("thenStore = " + thenStore);
- result.append("elseStore = " + elseStore);
- result.append(System.getProperty("line.separator"));
- result.append(")");
- return result.toString();
- }
-
- /** @see org.checkerframework.dataflow.analysis.TransferResult#storeChanged() */
- @Override
- public boolean storeChanged() {
- return storeChanged;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/FlowExpressions.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/FlowExpressions.java
deleted file mode 100644
index 85ad7b4b00..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/FlowExpressions.java
+++ /dev/null
@@ -1,1143 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.TreePath;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.cfg.node.ArrayAccessNode;
-import org.checkerframework.dataflow.cfg.node.ArrayCreationNode;
-import org.checkerframework.dataflow.cfg.node.ClassNameNode;
-import org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode;
-import org.checkerframework.dataflow.cfg.node.FieldAccessNode;
-import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
-import org.checkerframework.dataflow.cfg.node.MethodInvocationNode;
-import org.checkerframework.dataflow.cfg.node.NarrowingConversionNode;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.dataflow.cfg.node.StringConversionNode;
-import org.checkerframework.dataflow.cfg.node.SuperNode;
-import org.checkerframework.dataflow.cfg.node.ThisLiteralNode;
-import org.checkerframework.dataflow.cfg.node.ValueLiteralNode;
-import org.checkerframework.dataflow.cfg.node.WideningConversionNode;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.dataflow.util.PurityUtils;
-import org.checkerframework.javacutil.AnnotationProvider;
-import org.checkerframework.javacutil.ElementUtils;
-import org.checkerframework.javacutil.ErrorReporter;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.TreeUtils;
-import org.checkerframework.javacutil.TypeAnnotationUtils;
-import org.checkerframework.javacutil.TypesUtils;
-
-/**
- * Collection of classes and helper functions to represent Java expressions about which the
- * org.checkerframework.dataflow analysis can possibly infer facts. Expressions include:
- *
- * <ul>
- * <li>Field accesses (e.g., <em>o.f</em>)
- * <li>Local variables (e.g., <em>l</em>)
- * <li>This reference (e.g., <em>this</em>)
- * <li>Pure method calls (e.g., <em>o.m()</em>)
- * <li>Unknown other expressions to mark that something else was present.
- * </ul>
- *
- * @author Stefan Heule
- */
-public class FlowExpressions {
-
- /**
- * @return the internal representation (as {@link FieldAccess}) of a {@link FieldAccessNode}.
- * Can contain {@link Unknown} as receiver.
- */
- public static FieldAccess internalReprOfFieldAccess(
- AnnotationProvider provider, FieldAccessNode node) {
- Receiver receiver;
- Node receiverNode = node.getReceiver();
- if (node.isStatic()) {
- receiver = new ClassName(receiverNode.getType());
- } else {
- receiver = internalReprOf(provider, receiverNode);
- }
- return new FieldAccess(receiver, node);
- }
-
- /**
- * @return the internal representation (as {@link FieldAccess}) of a {@link FieldAccessNode}.
- * Can contain {@link Unknown} as receiver.
- */
- public static ArrayAccess internalReprOfArrayAccess(
- AnnotationProvider provider, ArrayAccessNode node) {
- Receiver receiver = internalReprOf(provider, node.getArray());
- Receiver index = internalReprOf(provider, node.getIndex());
- return new ArrayAccess(node.getType(), receiver, index);
- }
-
- /**
- * 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) {
- return internalReprOf(provider, receiverNode, false);
- }
-
- /**
- * 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;
- receiver = new ArrayCreation(an.getType(), an.getDimensions(), an.getInitializers());
- } 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)
- || 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;
- }
-
- /**
- * @return the internal representation (as {@link Receiver}) of any {@link ExpressionTree}.
- * Might contain {@link Unknown}.
- */
- public static Receiver internalReprOf(
- AnnotationProvider provider, ExpressionTree receiverTree) {
- return internalReprOf(provider, receiverTree, true);
- }
- /**
- * We ignore operations such as widening and narrowing when computing the internal
- * representation.
- *
- * @return the internal representation (as {@link Receiver}) of any {@link ExpressionTree}.
- * Might contain {@link Unknown}.
- */
- public static Receiver internalReprOf(
- AnnotationProvider provider,
- ExpressionTree receiverTree,
- boolean allowNonDeterministic) {
- Receiver receiver;
- switch (receiverTree.getKind()) {
- case ARRAY_ACCESS:
- ArrayAccessTree a = (ArrayAccessTree) receiverTree;
- Receiver arrayAccessExpression = internalReprOf(provider, a.getExpression());
- Receiver index = internalReprOf(provider, a.getIndex());
- receiver = new ArrayAccess(InternalUtils.typeOf(a), arrayAccessExpression, index);
- break;
- case BOOLEAN_LITERAL:
- case CHAR_LITERAL:
- case DOUBLE_LITERAL:
- case FLOAT_LITERAL:
- case INT_LITERAL:
- case LONG_LITERAL:
- case NULL_LITERAL:
- case STRING_LITERAL:
- LiteralTree vn = (LiteralTree) receiverTree;
- receiver = new ValueLiteral(InternalUtils.typeOf(receiverTree), vn.getValue());
- break;
- case NEW_ARRAY:
- receiver =
- new ArrayCreation(
- InternalUtils.typeOf(receiverTree),
- Collections.<Node>emptyList(),
- Collections.<Node>emptyList());
- break;
- case METHOD_INVOCATION:
- MethodInvocationTree mn = (MethodInvocationTree) receiverTree;
- ExecutableElement invokedMethod = TreeUtils.elementFromUse(mn);
- if (PurityUtils.isDeterministic(provider, invokedMethod) || allowNonDeterministic) {
- List<Receiver> parameters = new ArrayList<>();
- for (ExpressionTree p : mn.getArguments()) {
- parameters.add(internalReprOf(provider, p));
- }
- Receiver methodReceiver;
- if (ElementUtils.isStatic(invokedMethod)) {
- methodReceiver = new ClassName(InternalUtils.typeOf(mn.getMethodSelect()));
- } else {
- methodReceiver = internalReprOf(provider, mn.getMethodSelect());
- }
- TypeMirror type = InternalUtils.typeOf(mn);
- receiver = new MethodCall(type, invokedMethod, methodReceiver, parameters);
- } else {
- receiver = null;
- }
- break;
- case MEMBER_SELECT:
- receiver = internalRepOfMemberSelect(provider, (MemberSelectTree) receiverTree);
- break;
- case IDENTIFIER:
- IdentifierTree identifierTree = (IdentifierTree) receiverTree;
- TypeMirror typeOfId = InternalUtils.typeOf(identifierTree);
- if (identifierTree.getName().contentEquals("this")
- || identifierTree.getName().contentEquals("super")) {
- receiver = new ThisReference(typeOfId);
- break;
- }
- Element ele = TreeUtils.elementFromUse(identifierTree);
- switch (ele.getKind()) {
- case LOCAL_VARIABLE:
- case RESOURCE_VARIABLE:
- case EXCEPTION_PARAMETER:
- case PARAMETER:
- receiver = new LocalVariable(ele);
- break;
- case FIELD:
- // Implicit access expression, such as "this" or a class name
- Receiver fieldAccessExpression;
- TypeMirror enclosingType = ElementUtils.enclosingClass(ele).asType();
- if (ElementUtils.isStatic(ele)) {
- fieldAccessExpression = new ClassName(enclosingType);
- } else {
- fieldAccessExpression = new ThisReference(enclosingType);
- }
- receiver =
- new FieldAccess(
- fieldAccessExpression, typeOfId, (VariableElement) ele);
- break;
- case CLASS:
- case ENUM:
- case ANNOTATION_TYPE:
- case INTERFACE:
- receiver = new ClassName(ele.asType());
- break;
- default:
- receiver = null;
- }
- break;
- default:
- receiver = null;
- }
-
- if (receiver == null) {
- receiver = new Unknown(InternalUtils.typeOf(receiverTree));
- }
- return receiver;
- }
-
- /**
- * Returns the implicit receiver of ele.
- *
- * <p>Returns either a new ClassName or a new ThisReference depending on whether ele is static
- * or not. The passed element must be a field, method, or class.
- *
- * @param ele field, method, or class
- * @return either a new ClassName or a new ThisReference depending on whether ele is static or
- * not
- */
- public static Receiver internalRepOfImplicitReceiver(Element ele) {
- TypeMirror enclosingType = ElementUtils.enclosingClass(ele).asType();
- if (ElementUtils.isStatic(ele)) {
- return new ClassName(enclosingType);
- } else {
- return new ThisReference(enclosingType);
- }
- }
-
- /**
- * Returns either a new ClassName or ThisReference Receiver object for the enclosingType
- *
- * <p>The Tree should be an expression or a statement that does not have a receiver or an
- * implicit receiver. For example, a local variable declaration.
- *
- * @param path TreePath to tree
- * @param enclosingType type of the enclosing type
- * @return a new ClassName or ThisReference that is a Receiver object for the enclosingType
- */
- public static Receiver internalRepOfPseudoReceiver(TreePath path, TypeMirror enclosingType) {
- if (TreeUtils.isTreeInStaticScope(path)) {
- return new ClassName(enclosingType);
- } else {
- return new ThisReference(enclosingType);
- }
- }
-
- private static Receiver internalRepOfMemberSelect(
- AnnotationProvider provider, MemberSelectTree memberSelectTree) {
- TypeMirror expressionType = InternalUtils.typeOf(memberSelectTree.getExpression());
- if (TreeUtils.isClassLiteral(memberSelectTree)) {
- return new ClassName(expressionType);
- }
- Element ele = TreeUtils.elementFromUse(memberSelectTree);
- switch (ele.getKind()) {
- case METHOD:
- case CONSTRUCTOR:
- return internalReprOf(provider, memberSelectTree.getExpression());
- case CLASS: // o instanceof MyClass.InnerClass
- case ENUM:
- case INTERFACE: // o instanceof MyClass.InnerInterface
- case ANNOTATION_TYPE:
- return new ClassName(expressionType);
- case ENUM_CONSTANT:
- case FIELD:
- Receiver r = internalReprOf(provider, memberSelectTree.getExpression());
- return new FieldAccess(r, ElementUtils.getType(ele), (VariableElement) ele);
- default:
- ErrorReporter.errorAbort(
- "Unexpected element kind: %s element: %s", ele.getKind(), ele);
- return null;
- }
- }
-
- /**
- * Returns Receiver objects for the formal parameters of the method in which path is enclosed.
- *
- * @param annotationProvider annotationProvider
- * @param path TreePath that is enclosed by the method
- * @return list of Receiver objects for the formal parameters of the method in which path is
- * enclosed
- */
- public static List<Receiver> getParametersOfEnclosingMethod(
- AnnotationProvider annotationProvider, TreePath path) {
- MethodTree methodTree = TreeUtils.enclosingMethod(path);
- if (methodTree == null) {
- return null;
- }
- List<Receiver> internalArguments = new ArrayList<>();
- for (VariableTree arg : methodTree.getParameters()) {
- internalArguments.add(internalReprOf(annotationProvider, new LocalVariableNode(arg)));
- }
- return internalArguments;
- }
-
- public abstract static class Receiver {
- protected final TypeMirror type;
-
- public Receiver(TypeMirror type) {
- assert type != null;
- this.type = type;
- }
-
- public TypeMirror getType() {
- return type;
- }
-
- public abstract boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz);
-
- public boolean containsUnknown() {
- return containsOfClass(Unknown.class);
- }
-
- /**
- * Returns true if and only if the value this expression stands for cannot be changed by a
- * method call. This is the case for local variables, the self reference as well as final
- * field accesses for whose receiver {@link #isUnmodifiableByOtherCode} is true.
- */
- public abstract boolean isUnmodifiableByOtherCode();
-
- /** @return true if and only if the two receiver are syntactically identical */
- public boolean syntacticEquals(Receiver other) {
- return other == this;
- }
-
- /**
- * @return true if and only if this receiver contains a receiver that is syntactically equal
- * to {@code other}.
- */
- public boolean containsSyntacticEqualReceiver(Receiver other) {
- return syntacticEquals(other);
- }
-
- /**
- * Returns true if and only if {@code other} appears anywhere in this receiver or an
- * expression appears in this receiver such that {@code other} might alias this expression,
- * and that expression is modifiable.
- *
- * <p>This is always true, except for cases where the Java type information prevents
- * aliasing and none of the subexpressions can alias 'other'.
- */
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- return this.equals(other) || store.canAlias(this, other);
- }
- }
-
- public static class FieldAccess extends Receiver {
- protected Receiver receiver;
- protected VariableElement field;
-
- public Receiver getReceiver() {
- return receiver;
- }
-
- public VariableElement getField() {
- return field;
- }
-
- public FieldAccess(Receiver receiver, FieldAccessNode node) {
- super(node.getType());
- this.receiver = receiver;
- this.field = node.getElement();
- }
-
- public FieldAccess(Receiver receiver, TypeMirror type, VariableElement fieldElement) {
- super(type);
- this.receiver = receiver;
- this.field = fieldElement;
- }
-
- public boolean isFinal() {
- return ElementUtils.isFinal(field);
- }
-
- public boolean isStatic() {
- return ElementUtils.isStatic(field);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof FieldAccess)) {
- return false;
- }
- FieldAccess fa = (FieldAccess) obj;
- return fa.getField().equals(getField()) && fa.getReceiver().equals(getReceiver());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getField(), getReceiver());
- }
-
- @Override
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- return super.containsModifiableAliasOf(store, other)
- || receiver.containsModifiableAliasOf(store, other);
- }
-
- @Override
- public boolean containsSyntacticEqualReceiver(Receiver other) {
- return syntacticEquals(other) || receiver.containsSyntacticEqualReceiver(other);
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- if (!(other instanceof FieldAccess)) {
- return false;
- }
- FieldAccess fa = (FieldAccess) other;
- return super.syntacticEquals(other)
- || (fa.getField().equals(getField())
- && fa.getReceiver().syntacticEquals(getReceiver()));
- }
-
- @Override
- public String toString() {
- if (receiver instanceof ClassName) {
- return receiver.getType() + "." + field;
- } else {
- return receiver + "." + field;
- }
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- return getClass().equals(clazz) || receiver.containsOfClass(clazz);
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return isFinal() && getReceiver().isUnmodifiableByOtherCode();
- }
- }
-
- public static class ThisReference extends Receiver {
- public ThisReference(TypeMirror type) {
- super(type);
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj != null && obj instanceof ThisReference;
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(0);
- }
-
- @Override
- public String toString() {
- return "this";
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- return getClass().equals(clazz);
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- return other instanceof ThisReference;
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return true;
- }
-
- @Override
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- return false; // 'this' is not modifiable
- }
- }
-
- /**
- * A ClassName represents the occurrence of a class as part of a static field access or method
- * invocation.
- */
- public static class ClassName extends Receiver {
- public ClassName(TypeMirror type) {
- super(type);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ClassName)) {
- return false;
- }
- ClassName other = (ClassName) obj;
- return getType().toString().equals(other.getType().toString());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getType().toString());
- }
-
- @Override
- public String toString() {
- return getType().toString() + ".class";
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- return getClass().equals(clazz);
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- return this.equals(other);
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return true;
- }
-
- @Override
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- return false; // not modifiable
- }
- }
-
- public static class Unknown extends Receiver {
- public Unknown(TypeMirror type) {
- super(type);
- }
-
- @Override
- public boolean equals(Object obj) {
- return obj == this;
- }
-
- @Override
- public int hashCode() {
- return System.identityHashCode(this);
- }
-
- @Override
- public String toString() {
- return "?";
- }
-
- @Override
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- return true;
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- return getClass().equals(clazz);
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return false;
- }
- }
-
- public static class LocalVariable extends Receiver {
- protected Element element;
-
- public LocalVariable(LocalVariableNode localVar) {
- super(localVar.getType());
- this.element = localVar.getElement();
- }
-
- public LocalVariable(Element elem) {
- super(ElementUtils.getType(elem));
- this.element = elem;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof LocalVariable)) {
- return false;
- }
- LocalVariable other = (LocalVariable) obj;
- VarSymbol vs = (VarSymbol) element;
- VarSymbol vsother = (VarSymbol) other.element;
- // Use TypeAnnotationUtils.unannotatedType(type).toString().equals(...) instead of Types.isSameType(...)
- // because Types requires a processing environment, and FlowExpressions is
- // designed to be independent of processing environment. See also
- // calls to getType().toString() in FlowExpressions.
- return vsother.name.contentEquals(vs.name)
- && TypeAnnotationUtils.unannotatedType(vsother.type)
- .toString()
- .equals(TypeAnnotationUtils.unannotatedType(vs.type).toString())
- && vsother.owner.toString().equals(vs.owner.toString());
- }
-
- public Element getElement() {
- return element;
- }
-
- @Override
- public int hashCode() {
- VarSymbol vs = (VarSymbol) element;
- return HashCodeUtils.hash(
- vs.name.toString(),
- TypeAnnotationUtils.unannotatedType(vs.type).toString(),
- vs.owner.toString());
- }
-
- @Override
- public String toString() {
- return element.toString();
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- return getClass().equals(clazz);
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- if (!(other instanceof LocalVariable)) {
- return false;
- }
- LocalVariable l = (LocalVariable) other;
- return l.equals(this);
- }
-
- @Override
- public boolean containsSyntacticEqualReceiver(Receiver other) {
- return syntacticEquals(other);
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return true;
- }
- }
-
- public static class ValueLiteral extends Receiver {
-
- protected final Object value;
-
- public ValueLiteral(TypeMirror type, ValueLiteralNode node) {
- super(type);
- value = node.getValue();
- }
-
- public ValueLiteral(TypeMirror type, Object value) {
- super(type);
- this.value = value;
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- return getClass().equals(clazz);
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return true;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ValueLiteral)) {
- return false;
- }
- ValueLiteral other = (ValueLiteral) obj;
- if (value == null) {
- return type.toString().equals(other.type.toString()) && other.value == null;
- }
- return type.toString().equals(other.type.toString()) && value.equals(other.value);
- }
-
- @Override
- public String toString() {
- if (TypesUtils.isString(type)) {
- return "\"" + value + "\"";
- } else if (type.getKind() == TypeKind.LONG) {
- return value.toString() + "L";
- }
- return value == null ? "null" : value.toString();
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(value, type.toString());
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- return this.equals(other);
- }
-
- @Override
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- return false; // not modifiable
- }
-
- public Object getValue() {
- return value;
- }
- }
-
- /** A method call. */
- public static class MethodCall extends Receiver {
-
- protected final Receiver receiver;
- protected final List<Receiver> parameters;
- protected final ExecutableElement method;
-
- public MethodCall(
- TypeMirror type,
- ExecutableElement method,
- Receiver receiver,
- List<Receiver> parameters) {
- super(type);
- this.receiver = receiver;
- this.parameters = parameters;
- this.method = method;
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- if (getClass().equals(clazz)) {
- return true;
- }
- if (receiver.containsOfClass(clazz)) {
- return true;
- }
- for (Receiver p : parameters) {
- if (p.containsOfClass(clazz)) {
- return true;
- }
- }
- return false;
- }
-
- /** @return the method call receiver (for inspection only - do not modify) */
- public Receiver getReceiver() {
- return receiver;
- }
-
- /**
- * @return the method call parameters (for inspection only - do not modify any of the
- * parameters)
- */
- public List<Receiver> getParameters() {
- return Collections.unmodifiableList(parameters);
- }
-
- /** @return the ExecutableElement for the method call */
- public ExecutableElement getElement() {
- return method;
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return false;
- }
-
- @Override
- public boolean containsSyntacticEqualReceiver(Receiver other) {
- return syntacticEquals(other) || receiver.syntacticEquals(other);
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- if (!(other instanceof MethodCall)) {
- return false;
- }
- MethodCall otherMethod = (MethodCall) other;
- if (!receiver.syntacticEquals(otherMethod.receiver)) {
- return false;
- }
- if (parameters.size() != otherMethod.parameters.size()) {
- return false;
- }
- int i = 0;
- for (Receiver p : parameters) {
- if (!p.syntacticEquals(otherMethod.parameters.get(i))) {
- return false;
- }
- i++;
- }
- return method.equals(otherMethod.method);
- }
-
- public boolean containsSyntacticEqualParameter(LocalVariable var) {
- for (Receiver p : parameters) {
- if (p.containsSyntacticEqualReceiver(var)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- if (receiver.containsModifiableAliasOf(store, other)) {
- return true;
- }
- for (Receiver p : parameters) {
- if (p.containsModifiableAliasOf(store, other)) {
- return true;
- }
- }
- return false; // the method call itself is not modifiable
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof MethodCall)) {
- return false;
- }
- MethodCall other = (MethodCall) obj;
- int i = 0;
- for (Receiver p : parameters) {
- if (!p.equals(other.parameters.get(i))) {
- return false;
- }
- i++;
- }
- return receiver.equals(other.receiver) && method.equals(other.method);
- }
-
- @Override
- public int hashCode() {
- int hash = HashCodeUtils.hash(method, receiver);
- for (Receiver p : parameters) {
- hash = HashCodeUtils.hash(hash, p);
- }
- return hash;
- }
-
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder();
- if (receiver instanceof ClassName) {
- result.append(receiver.getType());
- } else {
- result.append(receiver);
- }
- result.append(".");
- String methodName = method.getSimpleName().toString();
- result.append(methodName);
- result.append("(");
- boolean first = true;
- for (Receiver p : parameters) {
- if (!first) {
- result.append(", ");
- }
- result.append(p.toString());
- first = false;
- }
- result.append(")");
- return result.toString();
- }
- }
-
- /** A deterministic method call. */
- public static class ArrayAccess extends Receiver {
-
- protected final Receiver receiver;
- protected final Receiver index;
-
- public ArrayAccess(TypeMirror type, Receiver receiver, Receiver index) {
- super(type);
- this.receiver = receiver;
- this.index = index;
- }
-
- @Override
- public boolean containsOfClass(Class<? extends FlowExpressions.Receiver> clazz) {
- if (getClass().equals(clazz)) {
- return true;
- }
- if (receiver.containsOfClass(clazz)) {
- return true;
- }
- return index.containsOfClass(clazz);
- }
-
- public Receiver getReceiver() {
- return receiver;
- }
-
- public Receiver getIndex() {
- return index;
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return false;
- }
-
- @Override
- public boolean containsSyntacticEqualReceiver(Receiver other) {
- return syntacticEquals(other)
- || receiver.syntacticEquals(other)
- || index.syntacticEquals(other);
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- if (!(other instanceof ArrayAccess)) {
- return false;
- }
- ArrayAccess otherArrayAccess = (ArrayAccess) other;
- if (!receiver.syntacticEquals(otherArrayAccess.receiver)) {
- return false;
- }
- return index.syntacticEquals(otherArrayAccess.index);
- }
-
- @Override
- public boolean containsModifiableAliasOf(Store<?> store, Receiver other) {
- if (receiver.containsModifiableAliasOf(store, other)) {
- return true;
- }
- return index.containsModifiableAliasOf(store, other);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ArrayAccess)) {
- return false;
- }
- ArrayAccess other = (ArrayAccess) obj;
- return receiver.equals(other.receiver) && index.equals(other.index);
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(receiver, index);
- }
-
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder();
- result.append(receiver.toString());
- result.append("[");
- result.append(index.toString());
- result.append("]");
- return result.toString();
- }
- }
-
- public static class ArrayCreation extends Receiver {
-
- protected List<Node> dimensions;
- protected List<Node> initializers;
-
- public ArrayCreation(TypeMirror type, List<Node> dimensions, List<Node> initializers) {
- super(type);
- this.dimensions = dimensions;
- this.initializers = initializers;
- }
-
- public List<Node> getDimensions() {
- return dimensions;
- }
-
- public List<Node> getInitializers() {
- return initializers;
- }
-
- @Override
- public boolean containsOfClass(Class<? extends Receiver> clazz) {
- for (Node n : dimensions) {
- if (n.getClass().equals(clazz)) return true;
- }
- for (Node n : initializers) {
- if (n.getClass().equals(clazz)) return true;
- }
- return false;
- }
-
- @Override
- public boolean isUnmodifiableByOtherCode() {
- return false;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((dimensions == null) ? 0 : dimensions.hashCode());
- result = prime * result + ((initializers == null) ? 0 : initializers.hashCode());
- result = prime * result + HashCodeUtils.hash(getType().toString());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ArrayCreation)) {
- return false;
- }
- ArrayCreation other = (ArrayCreation) obj;
- return this.dimensions.equals(other.getDimensions())
- && this.initializers.equals(other.getInitializers())
- && getType().toString().equals(other.getType().toString());
- }
-
- @Override
- public boolean syntacticEquals(Receiver other) {
- return this.equals(other);
- }
-
- @Override
- public boolean containsSyntacticEqualReceiver(Receiver other) {
- return syntacticEquals(other);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("new " + type);
- if (!dimensions.isEmpty()) {
- boolean needComma = false;
- sb.append(" (");
- for (Node dim : dimensions) {
- if (needComma) {
- sb.append(", ");
- }
- sb.append(dim);
- needComma = true;
- }
- sb.append(")");
- }
- if (!initializers.isEmpty()) {
- boolean needComma = false;
- sb.append(" = {");
- for (Node init : initializers) {
- if (needComma) {
- sb.append(", ");
- }
- sb.append(init);
- needComma = true;
- }
- sb.append("}");
- }
- return sb.toString();
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/RegularTransferResult.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/RegularTransferResult.java
deleted file mode 100644
index b4044fae83..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/RegularTransferResult.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-import java.util.Map;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * Implementation of a {@link TransferResult} with just one non-exceptional store. The result of
- * {@code getThenStore} and {@code getElseStore} is equal to the only underlying store.
- *
- * @author Stefan Heule
- * @param <S> the {@link Store} used to keep track of intermediate results
- */
-public class RegularTransferResult<A extends AbstractValue<A>, S extends Store<S>>
- extends TransferResult<A, S> {
-
- /** The regular result store. */
- protected S store;
-
- private final boolean storeChanged;
-
- /**
- * Create a {@code TransferResult} with {@code resultStore} as the resulting store. If the
- * corresponding {@link org.checkerframework.dataflow.cfg.node.Node} is a boolean node, then
- * {@code resultStore} is used for both the 'then' and 'else' edge.
- *
- * <p><em>Exceptions</em>: If the corresponding {@link
- * org.checkerframework.dataflow.cfg.node.Node} throws an exception, then it is assumed that no
- * special handling is necessary and the store before the corresponding {@link
- * org.checkerframework.dataflow.cfg.node.Node} will be passed along any exceptional edge.
- *
- * <p><em>Aliasing</em>: {@code resultStore} is not allowed to be used anywhere outside of this
- * class (including use through aliases). Complete control over the object is transfered to this
- * class.
- */
- public RegularTransferResult(A value, S resultStore, boolean storeChanged) {
- super(value);
- this.store = resultStore;
- this.storeChanged = storeChanged;
- }
-
- public RegularTransferResult(A value, S resultStore) {
- this(value, resultStore, false);
- }
-
- /**
- * Create a {@code TransferResult} with {@code resultStore} as the resulting store. If the
- * corresponding {@link org.checkerframework.dataflow.cfg.node.Node} is a boolean node, then
- * {@code resultStore} is used for both the 'then' and 'else' edge.
- *
- * <p>For the meaning of storeChanged, see {@link
- * org.checkerframework.dataflow.analysis.TransferResult#storeChanged}.
- *
- * <p><em>Exceptions</em>: If the corresponding {@link
- * org.checkerframework.dataflow.cfg.node.Node} throws an exception, then the corresponding
- * store in {@code exceptionalStores} is used. If no exception is found in {@code
- * exceptionalStores}, then it is assumed that no special handling is necessary and the store
- * before the corresponding {@link org.checkerframework.dataflow.cfg.node.Node} will be passed
- * along any exceptional edge.
- *
- * <p><em>Aliasing</em>: {@code resultStore} and any store in {@code exceptionalStores} are not
- * allowed to be used anywhere outside of this class (including use through aliases). Complete
- * control over the objects is transfered to this class.
- */
- public RegularTransferResult(
- A value, S resultStore, Map<TypeMirror, S> exceptionalStores, boolean storeChanged) {
- super(value);
- this.store = resultStore;
- this.storeChanged = storeChanged;
- this.exceptionalStores = exceptionalStores;
- }
-
- public RegularTransferResult(A value, S resultStore, Map<TypeMirror, S> exceptionalStores) {
- this(value, resultStore, exceptionalStores, false);
- }
-
- @Override
- public S getRegularStore() {
- return store;
- }
-
- @Override
- public S getThenStore() {
- return store;
- }
-
- @Override
- public S getElseStore() {
- // copy the store such that it is the same as the result of getThenStore
- // (that is, identical according to equals), but two different objects.
- return store.copy();
- }
-
- @Override
- public boolean containsTwoStores() {
- return false;
- }
-
- @Override
- public String toString() {
- StringBuilder result = new StringBuilder();
- result.append("RegularTransferResult(");
- result.append(System.getProperty("line.separator"));
- result.append("resultValue = " + resultValue);
- result.append(System.getProperty("line.separator"));
- result.append("store = " + store);
- result.append(System.getProperty("line.separator"));
- result.append(")");
- return result.toString();
- }
-
- /** @see org.checkerframework.dataflow.analysis.TransferResult#storeChanged() */
- @Override
- public boolean storeChanged() {
- return storeChanged;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Store.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Store.java
deleted file mode 100644
index 5d714da889..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/Store.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-import org.checkerframework.dataflow.cfg.CFGVisualizer;
-
-/**
- * A store is used to keep track of the information that the org.checkerframework.dataflow analysis
- * has accumulated at any given point in time.
- *
- * @author Stefan Heule
- * @param <S> the type of the store returned by {@code copy} and that is used in {@code
- * leastUpperBound}. Usually it is the implementing class itself, e.g. in {@code T extends
- * Store<T>}.
- */
-public interface Store<S extends Store<S>> {
-
- // We maintain a then store and an else store before each basic block.
- // When they are identical (by reference equality), they can be treated
- // as a regular unconditional store.
- // Once we have some information for both the then and else store, we
- // create a TransferInput for the block and allow it to be analyzed.
- public static enum Kind {
- THEN,
- ELSE,
- BOTH
- }
-
- /** A flow rule describes how stores flow along one edge between basic blocks. */
- public static enum FlowRule {
- EACH_TO_EACH, // The normal case, then store flows to the then store
- // and else store flows to the else store.
- THEN_TO_BOTH, // Then store flows to both then and else of successor.
- ELSE_TO_BOTH, // Else store flows to both then and else of successor.
- THEN_TO_THEN, // Then store flows to the then of successor. Else store is ignored.
- ELSE_TO_ELSE, // Else store flows to the else of successor. Then store is ignored.
- }
-
- /** @return an exact copy of this store. */
- S copy();
-
- /**
- * Compute the least upper bound of two stores.
- *
- * <p><em>Important</em>: This method must fulfill the following contract:
- *
- * <ul>
- * <li>Does not change {@code this}.
- * <li>Does not change {@code other}.
- * <li>Returns a fresh object which is not aliased yet.
- * <li>Returns an object of the same (dynamic) type as {@code this}, even if the signature is
- * more permissive.
- * <li>Is commutative.
- * </ul>
- */
- S leastUpperBound(S other);
-
- /**
- * Compute an upper bound of two stores that is wider than the least upper bound of the two
- * stores. Used to jump to a higher abstraction to allow faster termination of the fixed point
- * computations in {@link Analysis}. {@code previous} must be the previous store.
- *
- * <p>A particular analysis might not require widening and should implement this method by
- * calling leastUpperBound.
- *
- * <p><em>Important</em>: This method must fulfill the following contract:
- *
- * <ul>
- * <li>Does not change {@code this}.
- * <li>Does not change {@code previous}.
- * <li>Returns a fresh object which is not aliased yet.
- * <li>Returns an object of the same (dynamic) type as {@code this}, even if the signature is
- * more permissive.
- * <li>Is commutative.
- * </ul>
- *
- * @param previous must be the previous store
- */
- S widenedUpperBound(S previous);
-
- /**
- * Can the objects {@code a} and {@code b} be aliases? Returns a conservative answer (i.e.,
- * returns {@code true} if not enough information is available to determine aliasing).
- */
- boolean canAlias(FlowExpressions.Receiver a, FlowExpressions.Receiver b);
-
- /**
- * Delegate visualization responsibility to a visualizer.
- *
- * @param viz the visualizer to visualize this store
- */
- void visualize(CFGVisualizer<?, S, ?> viz);
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferFunction.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferFunction.java
deleted file mode 100644
index a10a766b33..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferFunction.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import java.util.List;
-import org.checkerframework.dataflow.cfg.UnderlyingAST;
-import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.dataflow.cfg.node.NodeVisitor;
-
-/**
- * Interface of a transfer function for the abstract interpretation used for the flow analysis.
- *
- * <p>A transfer function consists of the following components:
- *
- * <ul>
- * <li>A method {@code initialStore} that determines which initial store should be used in the
- * org.checkerframework.dataflow analysis.
- * <li>A function for every {@link Node} type that determines the behavior of the
- * org.checkerframework.dataflow analysis in that case. This method takes a {@link Node} and
- * an incoming store, and produces a {@link RegularTransferResult}.
- * </ul>
- *
- * <p><em>Important</em>: The individual transfer functions ( {@code visit*}) are allowed to use
- * (and modify) the stores contained in the argument passed; the ownership is transfered from the
- * caller to that function.
- *
- * @author Stefan Heule
- * @param <S> the {@link Store} used to keep track of intermediate results
- */
-public interface TransferFunction<A extends AbstractValue<A>, S extends Store<S>>
- extends NodeVisitor<TransferResult<A, S>, TransferInput<A, S>> {
-
- /**
- * @return the initial store to be used by the org.checkerframework.dataflow analysis. {@code
- * parameters} is only set if the underlying AST is a method.
- */
- S initialStore(UnderlyingAST underlyingAST, /*@Nullable*/ List<LocalVariableNode> parameters);
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferInput.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferInput.java
deleted file mode 100644
index f827ad302d..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferInput.java
+++ /dev/null
@@ -1,250 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * {@code TransferInput} is used as the input type of the individual transfer functions of a {@link
- * TransferFunction}. It also contains a reference to the node for which the transfer function will
- * be applied.
- *
- * <p>A {@code TransferInput} contains one or two stores. If two stores are present, one belongs to
- * 'then', and the other to 'else'.
- *
- * @author Stefan Heule
- * @param <S> the {@link Store} used to keep track of intermediate results
- */
-public class TransferInput<A extends AbstractValue<A>, S extends Store<S>> {
-
- /** The corresponding node. */
- protected Node node;
-
- /**
- * The regular result store (or {@code null} if none is present). The following invariant is
- * maintained:
- *
- * <pre>{@code
- * store == null &hArr; thenStore != null &amp;&amp; elseStore != null
- * }</pre>
- */
- protected final /*@Nullable*/ S store;
-
- /**
- * The 'then' result store (or {@code null} if none is present). The following invariant is
- * maintained:
- *
- * <pre>{@code
- * store == null &hArr; thenStore != null &amp;&amp; elseStore != null
- * }</pre>
- */
- protected final /*@Nullable*/ S thenStore;
-
- /**
- * The 'else' result store (or {@code null} if none is present). The following invariant is
- * maintained:
- *
- * <pre>{@code
- * store == null &hArr; thenStore != null &amp;&amp; elseStore != null
- * }</pre>
- */
- protected final /*@Nullable*/ S elseStore;
-
- /** The corresponding analysis class to get intermediate flow results. */
- protected final Analysis<A, S, ?> analysis;
-
- /**
- * Create a {@link TransferInput}, given a {@link TransferResult} and a node-value mapping.
- *
- * <p><em>Aliasing</em>: The stores returned by any methods of {@code to} will be stored
- * internally and are not allowed to be used elsewhere. Full control of them is transfered to
- * this object.
- *
- * <p>The node-value mapping {@code nodeValues} is provided by the analysis and is only read
- * from within this {@link TransferInput}.
- */
- public TransferInput(Node n, Analysis<A, S, ?> analysis, TransferResult<A, S> to) {
- node = n;
- this.analysis = analysis;
- if (to.containsTwoStores()) {
- thenStore = to.getThenStore();
- elseStore = to.getElseStore();
- store = null;
- } else {
- store = to.getRegularStore();
- thenStore = elseStore = null;
- }
- }
-
- /**
- * Create a {@link TransferInput}, given a store and a node-value mapping.
- *
- * <p><em>Aliasing</em>: The store {@code s} will be stored internally and is not allowed to be
- * used elsewhere. Full control over {@code s} is transfered to this object.
- *
- * <p>The node-value mapping {@code nodeValues} is provided by the analysis and is only read
- * from within this {@link TransferInput}.
- */
- public TransferInput(Node n, Analysis<A, S, ?> analysis, S s) {
- node = n;
- this.analysis = analysis;
- store = s;
- thenStore = elseStore = null;
- }
-
- /**
- * Create a {@link TransferInput}, given two stores and a node-value mapping.
- *
- * <p><em>Aliasing</em>: The two stores {@code s1} and {@code s2} will be stored internally and
- * are not allowed to be used elsewhere. Full control of them is transfered to this object.
- */
- public TransferInput(Node n, Analysis<A, S, ?> analysis, S s1, S s2) {
- node = n;
- this.analysis = analysis;
- thenStore = s1;
- elseStore = s2;
- store = null;
- }
-
- /** Copy constructor. */
- protected TransferInput(TransferInput<A, S> from) {
- this.node = from.node;
- this.analysis = from.analysis;
- if (from.store == null) {
- thenStore = from.thenStore.copy();
- elseStore = from.elseStore.copy();
- store = null;
- } else {
- store = from.store.copy();
- thenStore = elseStore = null;
- }
- }
-
- /** @return the {@link Node} for this {@link TransferInput}. */
- public Node getNode() {
- return node;
- }
-
- /**
- * @return the abstract value of {@link Node} {@code n}, which is required to be a 'sub-node'
- * (that is, a direct or indirect child) of the node this transfer input is associated with.
- * Furthermore, {@code n} cannot be a l-value node. Returns {@code null} if no value if
- * available.
- */
- public /*@Nullable*/ A getValueOfSubNode(Node n) {
- return analysis.getValue(n);
- }
-
- /**
- * @return the regular result store produced if no exception is thrown by the {@link Node}
- * corresponding to this transfer function result
- */
- public S getRegularStore() {
- if (store == null) {
- return thenStore.leastUpperBound(elseStore);
- } else {
- return store;
- }
- }
-
- /**
- * @return the result store produced if the {@link Node} this result belongs to evaluates to
- * {@code true}.
- */
- public S getThenStore() {
- if (store == null) {
- return thenStore;
- }
- return store;
- }
-
- /**
- * @return the result store produced if the {@link Node} this result belongs to evaluates to
- * {@code false}.
- */
- public S getElseStore() {
- if (store == null) {
- return elseStore;
- }
- // copy the store such that it is the same as the result of getThenStore
- // (that is, identical according to equals), but two different objects.
- return store.copy();
- }
-
- /**
- * @return {@code true} if and only if this transfer input contains two stores that are
- * potentially not equal. Note that the result {@code true} does not imply that {@code
- * getRegularStore} cannot be called (or vice versa for {@code false}). Rather, it indicates
- * that {@code getThenStore} or {@code getElseStore} can be used to give more precise
- * results. Otherwise, if the result is {@code false}, then all three methods {@code
- * getRegularStore}, {@code getThenStore}, and {@code getElseStore} return equivalent
- * stores.
- */
- public boolean containsTwoStores() {
- return (thenStore != null && elseStore != null);
- }
-
- /** @return an exact copy of this store. */
- public TransferInput<A, S> copy() {
- return new TransferInput<>(this);
- }
-
- /**
- * Compute the least upper bound of two stores.
- *
- * <p><em>Important</em>: This method must fulfill the same contract as {@code leastUpperBound}
- * of {@link Store}.
- */
- public TransferInput<A, S> leastUpperBound(TransferInput<A, S> other) {
- if (store == null) {
- S newThenStore = thenStore.leastUpperBound(other.getThenStore());
- S newElseStore = elseStore.leastUpperBound(other.getElseStore());
- return new TransferInput<>(node, analysis, newThenStore, newElseStore);
- } else {
- if (other.store == null) {
- // make sure we do not lose precision and keep two stores if at
- // least one of the two TransferInput's has two stores.
- return other.leastUpperBound(this);
- }
- return new TransferInput<>(
- node, analysis, store.leastUpperBound(other.getRegularStore()));
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (o != null && o instanceof TransferInput) {
- @SuppressWarnings("unchecked")
- TransferInput<A, S> other = (TransferInput<A, S>) o;
- if (containsTwoStores()) {
- if (other.containsTwoStores()) {
- return getThenStore().equals(other.getThenStore())
- && getElseStore().equals(other.getElseStore());
- }
- } else {
- if (!other.containsTwoStores()) {
- return getRegularStore().equals(other.getRegularStore());
- }
- }
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(
- this.analysis, this.node, this.store, this.thenStore, this.elseStore);
- }
-
- @Override
- public String toString() {
- if (store == null) {
- return "[then=" + thenStore + ", else=" + elseStore + "]";
- } else {
- return "[" + store + "]";
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferResult.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferResult.java
deleted file mode 100644
index 7c178a13fc..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/analysis/TransferResult.java
+++ /dev/null
@@ -1,104 +0,0 @@
-package org.checkerframework.dataflow.analysis;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import java.util.Map;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * {@code TransferResult} is used as the result type of the individual transfer functions of a
- * {@link TransferFunction}. It always belongs to the result of the individual transfer function for
- * a particular {@link org.checkerframework.dataflow.cfg.node.Node}, even though that {@code
- * org.checkerframework.dataflow.cfg.node.Node} is not explicitly store in {@code TransferResult}.
- *
- * <p>A {@code TransferResult} contains one or two stores (for 'then' and 'else'), and zero or more
- * stores with a cause ({@link TypeMirror}).
- *
- * @author Stefan Heule
- * @param <S> the {@link Store} used to keep track of intermediate results
- */
-public abstract class TransferResult<A extends AbstractValue<A>, S extends Store<S>> {
-
- /**
- * The stores in case the basic block throws an exception (or {@code null} if the corresponding
- * {@link org.checkerframework.dataflow.cfg.node.Node} does not throw any exceptions). Does not
- * necessarily contain a store for every exception, in which case the in-store will be used.
- */
- protected /*@Nullable*/ Map<TypeMirror, S> exceptionalStores;
-
- /**
- * The abstract value of the {@link org.checkerframework.dataflow.cfg.node.Node} associated with
- * this {@link TransferResult}, or {@code null} if no value has been produced.
- */
- protected /*@Nullable*/ A resultValue;
-
- public TransferResult(/*@Nullable*/ A resultValue) {
- this.resultValue = resultValue;
- }
-
- /** @return the abstract value produced by the transfer function */
- public A getResultValue() {
- return resultValue;
- }
-
- public void setResultValue(A resultValue) {
- this.resultValue = resultValue;
- }
-
- /**
- * @return the regular result store produced if no exception is thrown by the {@link
- * org.checkerframework.dataflow.cfg.node.Node} corresponding to this transfer function
- * result.
- */
- public abstract S getRegularStore();
-
- /**
- * @return the result store produced if the {@link org.checkerframework.dataflow.cfg.node.Node}
- * this result belongs to evaluates to {@code true}.
- */
- public abstract S getThenStore();
-
- /**
- * @return the result store produced if the {@link org.checkerframework.dataflow.cfg.node.Node}
- * this result belongs to evaluates to {@code false}.
- */
- public abstract S getElseStore();
-
- /**
- * @return the store that flows along the outgoing exceptional edge labeled with {@code
- * exception} (or {@code null} if no special handling is required for exceptional edges).
- */
- public /*@Nullable*/ S getExceptionalStore(TypeMirror exception) {
- if (exceptionalStores == null) {
- return null;
- }
- return exceptionalStores.get(exception);
- }
-
- /**
- * @return a Map of {@link TypeMirror} to {@link Store}
- * @see TransferResult#getExceptionalStore(TypeMirror)
- */
- public Map<TypeMirror, S> getExceptionalStores() {
- return exceptionalStores;
- }
-
- /**
- * @return {@code true} if and only if this transfer result contains two stores that are
- * potentially not equal. Note that the result {@code true} does not imply that {@code
- * getRegularStore} cannot be called (or vice versa for {@code false}). Rather, it indicates
- * that {@code getThenStore} or {@code getElseStore} can be used to give more precise
- * results. Otherwise, if the result is {@code false}, then all three methods {@code
- * getRegularStore}, {@code getThenStore}, and {@code getElseStore} return equivalent
- * stores.
- */
- public abstract boolean containsTwoStores();
-
- /**
- * @return {@code true} if and only if the transfer function returning this transfer result
- * changed the regularStore, elseStore, or thenStore.
- */
- public abstract boolean storeChanged();
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGBuilder.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGBuilder.java
deleted file mode 100644
index 55daff24ff..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGBuilder.java
+++ /dev/null
@@ -1,4491 +0,0 @@
-package org.checkerframework.dataflow.cfg;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.AnnotatedTypeTree;
-import com.sun.source.tree.AnnotationTree;
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.ArrayTypeTree;
-import com.sun.source.tree.AssertTree;
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.BlockTree;
-import com.sun.source.tree.BreakTree;
-import com.sun.source.tree.CaseTree;
-import com.sun.source.tree.CatchTree;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.CompoundAssignmentTree;
-import com.sun.source.tree.ConditionalExpressionTree;
-import com.sun.source.tree.ContinueTree;
-import com.sun.source.tree.DoWhileLoopTree;
-import com.sun.source.tree.EmptyStatementTree;
-import com.sun.source.tree.EnhancedForLoopTree;
-import com.sun.source.tree.ErroneousTree;
-import com.sun.source.tree.ExpressionStatementTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.ForLoopTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.IfTree;
-import com.sun.source.tree.ImportTree;
-import com.sun.source.tree.InstanceOfTree;
-import com.sun.source.tree.LabeledStatementTree;
-import com.sun.source.tree.LambdaExpressionTree;
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.ModifiersTree;
-import com.sun.source.tree.NewArrayTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.tree.ParameterizedTypeTree;
-import com.sun.source.tree.ParenthesizedTree;
-import com.sun.source.tree.PrimitiveTypeTree;
-import com.sun.source.tree.ReturnTree;
-import com.sun.source.tree.StatementTree;
-import com.sun.source.tree.SwitchTree;
-import com.sun.source.tree.SynchronizedTree;
-import com.sun.source.tree.ThrowTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.tree.TryTree;
-import com.sun.source.tree.TypeCastTree;
-import com.sun.source.tree.TypeParameterTree;
-import com.sun.source.tree.UnaryTree;
-import com.sun.source.tree.UnionTypeTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.tree.WhileLoopTree;
-import com.sun.source.tree.WildcardTree;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.util.Context;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.PrimitiveType;
-import javax.lang.model.type.ReferenceType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.UnionType;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.analysis.Store;
-import org.checkerframework.dataflow.cfg.CFGBuilder.ExtendedNode.ExtendedNodeType;
-import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod;
-import org.checkerframework.dataflow.cfg.block.Block;
-import org.checkerframework.dataflow.cfg.block.Block.BlockType;
-import org.checkerframework.dataflow.cfg.block.BlockImpl;
-import org.checkerframework.dataflow.cfg.block.ConditionalBlockImpl;
-import org.checkerframework.dataflow.cfg.block.ExceptionBlockImpl;
-import org.checkerframework.dataflow.cfg.block.RegularBlockImpl;
-import org.checkerframework.dataflow.cfg.block.SingleSuccessorBlockImpl;
-import org.checkerframework.dataflow.cfg.block.SpecialBlock.SpecialBlockType;
-import org.checkerframework.dataflow.cfg.block.SpecialBlockImpl;
-import org.checkerframework.dataflow.cfg.node.ArrayAccessNode;
-import org.checkerframework.dataflow.cfg.node.ArrayCreationNode;
-import org.checkerframework.dataflow.cfg.node.ArrayTypeNode;
-import org.checkerframework.dataflow.cfg.node.AssertionErrorNode;
-import org.checkerframework.dataflow.cfg.node.AssignmentNode;
-import org.checkerframework.dataflow.cfg.node.BitwiseAndNode;
-import org.checkerframework.dataflow.cfg.node.BitwiseComplementNode;
-import org.checkerframework.dataflow.cfg.node.BitwiseOrNode;
-import org.checkerframework.dataflow.cfg.node.BitwiseXorNode;
-import org.checkerframework.dataflow.cfg.node.BooleanLiteralNode;
-import org.checkerframework.dataflow.cfg.node.CaseNode;
-import org.checkerframework.dataflow.cfg.node.CharacterLiteralNode;
-import org.checkerframework.dataflow.cfg.node.ClassNameNode;
-import org.checkerframework.dataflow.cfg.node.ConditionalAndNode;
-import org.checkerframework.dataflow.cfg.node.ConditionalNotNode;
-import org.checkerframework.dataflow.cfg.node.ConditionalOrNode;
-import org.checkerframework.dataflow.cfg.node.DoubleLiteralNode;
-import org.checkerframework.dataflow.cfg.node.EqualToNode;
-import org.checkerframework.dataflow.cfg.node.ExplicitThisLiteralNode;
-import org.checkerframework.dataflow.cfg.node.FieldAccessNode;
-import org.checkerframework.dataflow.cfg.node.FloatLiteralNode;
-import org.checkerframework.dataflow.cfg.node.FloatingDivisionNode;
-import org.checkerframework.dataflow.cfg.node.FloatingRemainderNode;
-import org.checkerframework.dataflow.cfg.node.FunctionalInterfaceNode;
-import org.checkerframework.dataflow.cfg.node.GreaterThanNode;
-import org.checkerframework.dataflow.cfg.node.GreaterThanOrEqualNode;
-import org.checkerframework.dataflow.cfg.node.ImplicitThisLiteralNode;
-import org.checkerframework.dataflow.cfg.node.InstanceOfNode;
-import org.checkerframework.dataflow.cfg.node.IntegerDivisionNode;
-import org.checkerframework.dataflow.cfg.node.IntegerLiteralNode;
-import org.checkerframework.dataflow.cfg.node.IntegerRemainderNode;
-import org.checkerframework.dataflow.cfg.node.LeftShiftNode;
-import org.checkerframework.dataflow.cfg.node.LessThanNode;
-import org.checkerframework.dataflow.cfg.node.LessThanOrEqualNode;
-import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
-import org.checkerframework.dataflow.cfg.node.LongLiteralNode;
-import org.checkerframework.dataflow.cfg.node.MarkerNode;
-import org.checkerframework.dataflow.cfg.node.MethodAccessNode;
-import org.checkerframework.dataflow.cfg.node.MethodInvocationNode;
-import org.checkerframework.dataflow.cfg.node.NarrowingConversionNode;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.dataflow.cfg.node.NotEqualNode;
-import org.checkerframework.dataflow.cfg.node.NullChkNode;
-import org.checkerframework.dataflow.cfg.node.NullLiteralNode;
-import org.checkerframework.dataflow.cfg.node.NumericalAdditionNode;
-import org.checkerframework.dataflow.cfg.node.NumericalMinusNode;
-import org.checkerframework.dataflow.cfg.node.NumericalMultiplicationNode;
-import org.checkerframework.dataflow.cfg.node.NumericalPlusNode;
-import org.checkerframework.dataflow.cfg.node.NumericalSubtractionNode;
-import org.checkerframework.dataflow.cfg.node.ObjectCreationNode;
-import org.checkerframework.dataflow.cfg.node.PackageNameNode;
-import org.checkerframework.dataflow.cfg.node.ParameterizedTypeNode;
-import org.checkerframework.dataflow.cfg.node.PrimitiveTypeNode;
-import org.checkerframework.dataflow.cfg.node.ReturnNode;
-import org.checkerframework.dataflow.cfg.node.SignedRightShiftNode;
-import org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode;
-import org.checkerframework.dataflow.cfg.node.StringConcatenateNode;
-import org.checkerframework.dataflow.cfg.node.StringConversionNode;
-import org.checkerframework.dataflow.cfg.node.StringLiteralNode;
-import org.checkerframework.dataflow.cfg.node.SuperNode;
-import org.checkerframework.dataflow.cfg.node.SynchronizedNode;
-import org.checkerframework.dataflow.cfg.node.TernaryExpressionNode;
-import org.checkerframework.dataflow.cfg.node.ThisLiteralNode;
-import org.checkerframework.dataflow.cfg.node.ThrowNode;
-import org.checkerframework.dataflow.cfg.node.TypeCastNode;
-import org.checkerframework.dataflow.cfg.node.UnsignedRightShiftNode;
-import org.checkerframework.dataflow.cfg.node.ValueLiteralNode;
-import org.checkerframework.dataflow.cfg.node.VariableDeclarationNode;
-import org.checkerframework.dataflow.cfg.node.WideningConversionNode;
-import org.checkerframework.dataflow.qual.TerminatesExecution;
-import org.checkerframework.dataflow.util.MostlySingleton;
-import org.checkerframework.javacutil.AnnotationProvider;
-import org.checkerframework.javacutil.BasicAnnotationProvider;
-import org.checkerframework.javacutil.ElementUtils;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.Pair;
-import org.checkerframework.javacutil.TreeUtils;
-import org.checkerframework.javacutil.TypesUtils;
-import org.checkerframework.javacutil.trees.TreeBuilder;
-
-/**
- * Builds the control flow graph of some Java code (either a method, or an arbitrary statement).
- *
- * <p>The translation of the AST to the CFG is split into three phases:
- *
- * <ol>
- * <li><em>Phase one.</em> In the first phase, the AST is translated into a sequence of {@link
- * org.checkerframework.dataflow.cfg.CFGBuilder.ExtendedNode}s. An extended node can either be
- * a {@link Node}, or one of several meta elements such as a conditional or unconditional jump
- * or a node with additional information about exceptions. Some of the extended nodes contain
- * labels (e.g., for the jump target), and phase one additionally creates a mapping from
- * labels to extended nodes. Finally, the list of leaders is computed: A leader is an extended
- * node which will give rise to a basic block in phase two.
- * <li><em>Phase two.</em> In this phase, the sequence of extended nodes is translated to a graph
- * of control flow blocks that contain nodes. The meta elements from phase one are translated
- * into the correct edges.
- * <li><em>Phase three.</em> The control flow graph generated in phase two can contain degenerate
- * basic blocks such as empty regular basic blocks or conditional basic blocks that have the
- * same block as both 'then' and 'else' successor. This phase removes these cases while
- * preserving the control flow structure.
- * </ol>
- *
- * @author Stefan Heule
- */
-public class CFGBuilder {
-
- /** Can assertions be assumed to be disabled? */
- protected final boolean assumeAssertionsDisabled;
-
- /** Can assertions be assumed to be enabled? */
- protected final boolean assumeAssertionsEnabled;
-
- public CFGBuilder(boolean assumeAssertionsEnabled, boolean assumeAssertionsDisabled) {
- assert !(assumeAssertionsDisabled && assumeAssertionsEnabled);
- this.assumeAssertionsEnabled = assumeAssertionsEnabled;
- this.assumeAssertionsDisabled = assumeAssertionsDisabled;
- }
-
- /**
- * Class declarations that have been encountered when building the control-flow graph for a
- * method.
- */
- protected final List<ClassTree> declaredClasses = new LinkedList<>();
-
- public List<ClassTree> getDeclaredClasses() {
- return declaredClasses;
- }
-
- /**
- * Lambdas encountered when building the control-flow graph for a method, variable initializer,
- * or initializer.
- */
- protected final List<LambdaExpressionTree> declaredLambdas = new LinkedList<>();
-
- public List<LambdaExpressionTree> getDeclaredLambdas() {
- return declaredLambdas;
- }
-
- /** Build the control flow graph of some code. */
- public static ControlFlowGraph build(
- CompilationUnitTree root,
- ProcessingEnvironment env,
- UnderlyingAST underlyingAST,
- boolean assumeAssertionsEnabled,
- boolean assumeAssertionsDisabled) {
- return new CFGBuilder(assumeAssertionsEnabled, assumeAssertionsDisabled)
- .run(root, env, underlyingAST);
- }
-
- /**
- * Build the control flow graph of some code (method, initializer block, ...). bodyPath is the
- * TreePath to the body of that code.
- */
- public static ControlFlowGraph build(
- TreePath bodyPath,
- ProcessingEnvironment env,
- UnderlyingAST underlyingAST,
- boolean assumeAssertionsEnabled,
- boolean assumeAssertionsDisabled) {
- return new CFGBuilder(assumeAssertionsEnabled, assumeAssertionsDisabled)
- .run(bodyPath, env, underlyingAST);
- }
-
- /** Build the control flow graph of a method. */
- public static ControlFlowGraph build(
- CompilationUnitTree root,
- ProcessingEnvironment env,
- MethodTree tree,
- ClassTree classTree,
- boolean assumeAssertionsEnabled,
- boolean assumeAssertionsDisabled) {
- return new CFGBuilder(assumeAssertionsEnabled, assumeAssertionsDisabled)
- .run(root, env, tree, classTree);
- }
-
- /** Build the control flow graph of some code. */
- public static ControlFlowGraph build(
- CompilationUnitTree root, ProcessingEnvironment env, UnderlyingAST underlyingAST) {
- return new CFGBuilder(false, false).run(root, env, underlyingAST);
- }
-
- /** Build the control flow graph of a method. */
- public static ControlFlowGraph build(
- CompilationUnitTree root,
- ProcessingEnvironment env,
- MethodTree tree,
- ClassTree classTree) {
- return new CFGBuilder(false, false).run(root, env, tree, classTree);
- }
-
- /** Build the control flow graph of some code. */
- public ControlFlowGraph run(
- CompilationUnitTree root, ProcessingEnvironment env, UnderlyingAST underlyingAST) {
- declaredClasses.clear();
- declaredLambdas.clear();
-
- TreeBuilder builder = new TreeBuilder(env);
- AnnotationProvider annotationProvider = new BasicAnnotationProvider();
- PhaseOneResult phase1result =
- new CFGTranslationPhaseOne()
- .process(
- root,
- env,
- underlyingAST,
- exceptionalExitLabel,
- builder,
- annotationProvider);
- ControlFlowGraph phase2result = new CFGTranslationPhaseTwo().process(phase1result);
- ControlFlowGraph phase3result = CFGTranslationPhaseThree.process(phase2result);
- return phase3result;
- }
-
- /**
- * Build the control flow graph of some code (method, initializer block, ...). bodyPath is the
- * TreePath to the body of that code.
- */
- public ControlFlowGraph run(
- TreePath bodyPath, ProcessingEnvironment env, UnderlyingAST underlyingAST) {
- declaredClasses.clear();
- TreeBuilder builder = new TreeBuilder(env);
- AnnotationProvider annotationProvider = new BasicAnnotationProvider();
- PhaseOneResult phase1result =
- new CFGTranslationPhaseOne()
- .process(
- bodyPath,
- env,
- underlyingAST,
- exceptionalExitLabel,
- builder,
- annotationProvider);
- ControlFlowGraph phase2result = new CFGTranslationPhaseTwo().process(phase1result);
- ControlFlowGraph phase3result = CFGTranslationPhaseThree.process(phase2result);
- return phase3result;
- }
-
- /** Build the control flow graph of a method. */
- public ControlFlowGraph run(
- CompilationUnitTree root,
- ProcessingEnvironment env,
- MethodTree tree,
- ClassTree classTree) {
- UnderlyingAST underlyingAST = new CFGMethod(tree, classTree);
- return run(root, env, underlyingAST);
- }
-
- /* --------------------------------------------------------- */
- /* Extended Node Types and Labels */
- /* --------------------------------------------------------- */
-
- /** Special label to identify the exceptional exit. */
- protected final Label exceptionalExitLabel = new Label();
-
- /** Special label to identify the regular exit. */
- protected final Label regularExitLabel = new Label();
-
- /**
- * An extended node can be one of several things (depending on its {@code type}):
- *
- * <ul>
- * <li><em>NODE</em>. An extended node of this type is just a wrapper for a {@link Node} (that
- * cannot throw exceptions).
- * <li><em>EXCEPTION_NODE</em>. A wrapper for a {@link Node} which can throw exceptions. It
- * contains a label for every possible exception type the node might throw.
- * <li><em>UNCONDITIONAL_JUMP</em>. An unconditional jump to a label.
- * <li><em>TWO_TARGET_CONDITIONAL_JUMP</em>. A conditional jump with two targets for both the
- * 'then' and 'else' branch.
- * </ul>
- */
- protected abstract static class ExtendedNode {
-
- /** The basic block this extended node belongs to (as determined in phase two). */
- protected BlockImpl block;
-
- /** Type of this node. */
- protected ExtendedNodeType type;
-
- /** Does this node terminate the execution? (e.g., "System.exit()") */
- protected boolean terminatesExecution = false;
-
- public ExtendedNode(ExtendedNodeType type) {
- this.type = type;
- }
-
- /** Extended node types (description see above). */
- public enum ExtendedNodeType {
- NODE,
- EXCEPTION_NODE,
- UNCONDITIONAL_JUMP,
- CONDITIONAL_JUMP
- }
-
- public ExtendedNodeType getType() {
- return type;
- }
-
- public boolean getTerminatesExecution() {
- return terminatesExecution;
- }
-
- public void setTerminatesExecution(boolean terminatesExecution) {
- this.terminatesExecution = terminatesExecution;
- }
-
- /**
- * @return the node contained in this extended node (only applicable if the type is {@code
- * NODE} or {@code EXCEPTION_NODE}).
- */
- public Node getNode() {
- assert false;
- return null;
- }
-
- /**
- * @return the label associated with this extended node (only applicable if type is {@link
- * ExtendedNodeType#CONDITIONAL_JUMP} or {@link ExtendedNodeType#UNCONDITIONAL_JUMP}).
- */
- public Label getLabel() {
- assert false;
- return null;
- }
-
- public BlockImpl getBlock() {
- return block;
- }
-
- public void setBlock(BlockImpl b) {
- this.block = b;
- }
-
- @Override
- public String toString() {
- return "ExtendedNode(" + type + ")";
- }
- }
-
- /** An extended node of type {@code NODE}. */
- protected static class NodeHolder extends ExtendedNode {
-
- protected Node node;
-
- public NodeHolder(Node node) {
- super(ExtendedNodeType.NODE);
- this.node = node;
- }
-
- @Override
- public Node getNode() {
- return node;
- }
-
- @Override
- public String toString() {
- return "NodeHolder(" + node + ")";
- }
- }
-
- /** An extended node of type {@code EXCEPTION_NODE}. */
- protected static class NodeWithExceptionsHolder extends ExtendedNode {
-
- protected Node node;
- /**
- * Map from exception type to labels of successors that may be reached as a result of that
- * exception.
- */
- protected Map<TypeMirror, Set<Label>> exceptions;
-
- public NodeWithExceptionsHolder(Node node, Map<TypeMirror, Set<Label>> exceptions) {
- super(ExtendedNodeType.EXCEPTION_NODE);
- this.node = node;
- this.exceptions = exceptions;
- }
-
- public Map<TypeMirror, Set<Label>> getExceptions() {
- return exceptions;
- }
-
- @Override
- public Node getNode() {
- return node;
- }
-
- @Override
- public String toString() {
- return "NodeWithExceptionsHolder(" + node + ")";
- }
- }
-
- /**
- * An extended node of type {@link ExtendedNodeType#CONDITIONAL_JUMP}.
- *
- * <p><em>Important:</em> In the list of extended nodes, there should not be any labels that
- * point to a conditional jump. Furthermore, the node directly ahead of any conditional jump has
- * to be a {@link NodeWithExceptionsHolder} or {@link NodeHolder}, and the node held by that
- * extended node is required to be of boolean type.
- */
- protected static class ConditionalJump extends ExtendedNode {
-
- protected Label trueSucc;
- protected Label falseSucc;
-
- protected Store.FlowRule trueFlowRule;
- protected Store.FlowRule falseFlowRule;
-
- public ConditionalJump(Label trueSucc, Label falseSucc) {
- super(ExtendedNodeType.CONDITIONAL_JUMP);
- this.trueSucc = trueSucc;
- this.falseSucc = falseSucc;
- }
-
- public Label getThenLabel() {
- return trueSucc;
- }
-
- public Label getElseLabel() {
- return falseSucc;
- }
-
- public Store.FlowRule getTrueFlowRule() {
- return trueFlowRule;
- }
-
- public Store.FlowRule getFalseFlowRule() {
- return falseFlowRule;
- }
-
- public void setTrueFlowRule(Store.FlowRule rule) {
- trueFlowRule = rule;
- }
-
- public void setFalseFlowRule(Store.FlowRule rule) {
- falseFlowRule = rule;
- }
-
- @Override
- public String toString() {
- return "TwoTargetConditionalJump(" + getThenLabel() + "," + getElseLabel() + ")";
- }
- }
-
- /** An extended node of type {@link ExtendedNodeType#UNCONDITIONAL_JUMP}. */
- protected static class UnconditionalJump extends ExtendedNode {
-
- protected Label jumpTarget;
-
- public UnconditionalJump(Label jumpTarget) {
- super(ExtendedNodeType.UNCONDITIONAL_JUMP);
- this.jumpTarget = jumpTarget;
- }
-
- @Override
- public Label getLabel() {
- return jumpTarget;
- }
-
- @Override
- public String toString() {
- return "JumpMarker(" + getLabel() + ")";
- }
- }
-
- /**
- * A label is used to refer to other extended nodes using a mapping from labels to extended
- * nodes. Labels get their names either from labeled statements in the source code or from
- * internally generated unique names.
- */
- protected static class Label {
- private static int uid = 0;
-
- protected String name;
-
- public Label(String name) {
- this.name = name;
- }
-
- public Label() {
- this.name = uniqueName();
- }
-
- @Override
- public String toString() {
- return name;
- }
-
- /**
- * Return a new unique label name that cannot be confused with a Java source code label.
- *
- * @return a new unique label name
- */
- private static String uniqueName() {
- return "%L" + uid++;
- }
- }
-
- /**
- * A TryFrame takes a thrown exception type and maps it to a set of possible control-flow
- * successors.
- */
- protected static interface TryFrame {
- /**
- * Given a type of thrown exception, add the set of possible control flow successor {@link
- * Label}s to the argument set. Return true if the exception is known to be caught by one of
- * those labels and false if it may propagate still further.
- */
- public boolean possibleLabels(TypeMirror thrown, Set<Label> labels);
- }
-
- /**
- * A TryCatchFrame contains an ordered list of catch labels that apply to exceptions with
- * specific types.
- */
- protected static class TryCatchFrame implements TryFrame {
- protected Types types;
-
- /** An ordered list of pairs because catch blocks are ordered. */
- protected List<Pair<TypeMirror, Label>> catchLabels;
-
- public TryCatchFrame(Types types, List<Pair<TypeMirror, Label>> catchLabels) {
- this.types = types;
- this.catchLabels = catchLabels;
- }
-
- /**
- * Given a type of thrown exception, add the set of possible control flow successor {@link
- * Label}s to the argument set. Return true if the exception is known to be caught by one of
- * those labels and false if it may propagate still further.
- */
- @Override
- public boolean possibleLabels(TypeMirror thrown, Set<Label> labels) {
- // A conservative approach would be to say that every catch block
- // might execute for any thrown exception, but we try to do better.
- //
- // We rely on several assumptions that seem to hold as of Java 7.
- // 1) An exception parameter in a catch block must be either
- // a declared type or a union composed of declared types,
- // all of which are subtypes of Throwable.
- // 2) A thrown type must either be a declared type or a variable
- // that extends a declared type, which is a subtype of Throwable.
- //
- // Under those assumptions, if the thrown type (or its bound) is
- // a subtype of the caught type (or one of its alternatives), then
- // the catch block must apply and none of the later ones can apply.
- // Otherwise, if the thrown type (or its bound) is a supertype
- // of the caught type (or one of its alternatives), then the catch
- // block may apply, but so may later ones.
- // Otherwise, the thrown type and the caught type are unrelated
- // declared types, so they do not overlap on any non-null value.
-
- while (!(thrown instanceof DeclaredType)) {
- assert thrown instanceof TypeVariable
- : "thrown type must be a variable or a declared type";
- thrown = ((TypeVariable) thrown).getUpperBound();
- }
- DeclaredType declaredThrown = (DeclaredType) thrown;
- assert thrown != null : "thrown type must be bounded by a declared type";
-
- for (Pair<TypeMirror, Label> pair : catchLabels) {
- TypeMirror caught = pair.first;
- boolean canApply = false;
-
- if (caught instanceof DeclaredType) {
- DeclaredType declaredCaught = (DeclaredType) caught;
- if (types.isSubtype(declaredThrown, declaredCaught)) {
- // No later catch blocks can apply.
- labels.add(pair.second);
- return true;
- } else if (types.isSubtype(declaredCaught, declaredThrown)) {
- canApply = true;
- }
- } else {
- assert caught instanceof UnionType
- : "caught type must be a union or a declared type";
- UnionType caughtUnion = (UnionType) caught;
- for (TypeMirror alternative : caughtUnion.getAlternatives()) {
- assert alternative instanceof DeclaredType
- : "alternatives of an caught union type must be declared types";
- DeclaredType declaredAlt = (DeclaredType) alternative;
- if (types.isSubtype(declaredThrown, declaredAlt)) {
- // No later catch blocks can apply.
- labels.add(pair.second);
- return true;
- } else if (types.isSubtype(declaredAlt, declaredThrown)) {
- canApply = true;
- }
- }
- }
-
- if (canApply) {
- labels.add(pair.second);
- }
- }
-
- return false;
- }
- }
-
- /** A TryFinallyFrame applies to exceptions of any type */
- protected static class TryFinallyFrame implements TryFrame {
- protected Label finallyLabel;
-
- public TryFinallyFrame(Label finallyLabel) {
- this.finallyLabel = finallyLabel;
- }
-
- @Override
- public boolean possibleLabels(TypeMirror thrown, Set<Label> labels) {
- labels.add(finallyLabel);
- return true;
- }
- }
-
- /**
- * An exception stack represents the set of all try-catch blocks in effect at a given point in a
- * program. It maps an exception type to a set of Labels and it maps a block exit (via return or
- * fall-through) to a single Label.
- */
- protected static class TryStack {
- protected Label exitLabel;
- protected LinkedList<TryFrame> frames;
-
- public TryStack(Label exitLabel) {
- this.exitLabel = exitLabel;
- this.frames = new LinkedList<>();
- }
-
- public void pushFrame(TryFrame frame) {
- frames.addFirst(frame);
- }
-
- public void popFrame() {
- frames.removeFirst();
- }
-
- /**
- * Returns the set of possible {@link Label}s where control may transfer when an exception
- * of the given type is thrown.
- */
- public Set<Label> possibleLabels(TypeMirror thrown) {
- // Work up from the innermost frame until the exception is known to
- // be caught.
- Set<Label> labels = new MostlySingleton<>();
- for (TryFrame frame : frames) {
- if (frame.possibleLabels(thrown, labels)) {
- return labels;
- }
- }
- labels.add(exitLabel);
- return labels;
- }
- }
-
- /* --------------------------------------------------------- */
- /* Phase Three */
- /* --------------------------------------------------------- */
-
- /**
- * Class that performs phase three of the translation process. In particular, the following
- * degenerate cases of basic blocks are removed:
- *
- * <ol>
- * <li>Empty regular basic blocks: These blocks will be removed and their predecessors linked
- * directly to the successor.
- * <li>Conditional basic blocks that have the same basic block as the 'then' and 'else'
- * successor: The conditional basic block will be removed in this case.
- * <li>Two consecutive, non-empty, regular basic blocks where the second block has exactly one
- * predecessor (namely the other of the two blocks): In this case, the two blocks are
- * merged.
- * <li>Some basic blocks might not be reachable from the entryBlock. These basic blocks are
- * removed, and the list of predecessors (in the doubly-linked structure of basic blocks)
- * are adapted correctly.
- * </ol>
- *
- * Eliminating the second type of degenerate cases might introduce cases of the third problem.
- * These are also removed.
- */
- public static class CFGTranslationPhaseThree {
-
- /**
- * A simple wrapper object that holds a basic block and allows to set one of its successors.
- */
- protected interface PredecessorHolder {
- void setSuccessor(BlockImpl b);
-
- BlockImpl getBlock();
- }
-
- /**
- * Perform phase three on the control flow graph {@code cfg}.
- *
- * @param cfg the control flow graph. Ownership is transfered to this method and the caller
- * is not allowed to read or modify {@code cfg} after the call to {@code process} any
- * more.
- * @return the resulting control flow graph
- */
- public static ControlFlowGraph process(ControlFlowGraph cfg) {
- Set<Block> worklist = cfg.getAllBlocks();
- Set<Block> dontVisit = new HashSet<>();
-
- // note: this method has to be careful when relinking basic blocks
- // to not forget to adjust the predecessors, too
-
- // fix predecessor lists by removing any unreachable predecessors
- for (Block c : worklist) {
- BlockImpl cur = (BlockImpl) c;
- for (BlockImpl pred : new HashSet<>(cur.getPredecessors())) {
- if (!worklist.contains(pred)) {
- cur.removePredecessor(pred);
- }
- }
- }
-
- // remove empty blocks
- for (Block cur : worklist) {
- if (dontVisit.contains(cur)) {
- continue;
- }
-
- if (cur.getType() == BlockType.REGULAR_BLOCK) {
- RegularBlockImpl b = (RegularBlockImpl) cur;
- if (b.isEmpty()) {
- Set<RegularBlockImpl> empty = new HashSet<>();
- Set<PredecessorHolder> predecessors = new HashSet<>();
- BlockImpl succ = computeNeighborhoodOfEmptyBlock(b, empty, predecessors);
- for (RegularBlockImpl e : empty) {
- succ.removePredecessor(e);
- dontVisit.add(e);
- }
- for (PredecessorHolder p : predecessors) {
- BlockImpl block = p.getBlock();
- dontVisit.add(block);
- succ.removePredecessor(block);
- p.setSuccessor(succ);
- }
- }
- }
- }
-
- // remove useless conditional blocks
- worklist = cfg.getAllBlocks();
- for (Block c : worklist) {
- BlockImpl cur = (BlockImpl) c;
-
- if (cur.getType() == BlockType.CONDITIONAL_BLOCK) {
- ConditionalBlockImpl cb = (ConditionalBlockImpl) cur;
- assert cb.getPredecessors().size() == 1;
- if (cb.getThenSuccessor() == cb.getElseSuccessor()) {
- BlockImpl pred = cb.getPredecessors().iterator().next();
- PredecessorHolder predecessorHolder = getPredecessorHolder(pred, cb);
- BlockImpl succ = (BlockImpl) cb.getThenSuccessor();
- succ.removePredecessor(cb);
- predecessorHolder.setSuccessor(succ);
- }
- }
- }
-
- // merge consecutive basic blocks if possible
- worklist = cfg.getAllBlocks();
- for (Block cur : worklist) {
- if (cur.getType() == BlockType.REGULAR_BLOCK) {
- RegularBlockImpl b = (RegularBlockImpl) cur;
- Block succ = b.getRegularSuccessor();
- if (succ.getType() == BlockType.REGULAR_BLOCK) {
- RegularBlockImpl rs = (RegularBlockImpl) succ;
- if (rs.getPredecessors().size() == 1) {
- b.setSuccessor(rs.getRegularSuccessor());
- b.addNodes(rs.getContents());
- rs.getRegularSuccessor().removePredecessor(rs);
- }
- }
- }
- }
-
- return cfg;
- }
-
- /**
- * Compute the set of empty regular basic blocks {@code empty}, starting at {@code start}
- * and going both forward and backwards. Furthermore, compute the predecessors of these
- * empty blocks ({@code predecessors} ), and their single successor (return value).
- *
- * @param start the starting point of the search (an empty, regular basic block)
- * @param empty an empty set to be filled by this method with all empty basic blocks found
- * (including {@code start}).
- * @param predecessors an empty set to be filled by this method with all predecessors
- * @return the single successor of the set of the empty basic blocks
- */
- protected static BlockImpl computeNeighborhoodOfEmptyBlock(
- RegularBlockImpl start,
- Set<RegularBlockImpl> empty,
- Set<PredecessorHolder> predecessors) {
-
- // get empty neighborhood that come before 'start'
- computeNeighborhoodOfEmptyBlockBackwards(start, empty, predecessors);
-
- // go forward
- BlockImpl succ = (BlockImpl) start.getSuccessor();
- while (succ.getType() == BlockType.REGULAR_BLOCK) {
- RegularBlockImpl cur = (RegularBlockImpl) succ;
- if (cur.isEmpty()) {
- computeNeighborhoodOfEmptyBlockBackwards(cur, empty, predecessors);
- assert empty.contains(cur) : "cur ought to be in empty";
- succ = (BlockImpl) cur.getSuccessor();
- if (succ == cur) {
- // An infinite loop, making exit block unreachable
- break;
- }
- } else {
- break;
- }
- }
- return succ;
- }
-
- /**
- * Compute the set of empty regular basic blocks {@code empty}, starting at {@code start}
- * and looking only backwards in the control flow graph. Furthermore, compute the
- * predecessors of these empty blocks ( {@code predecessors}).
- *
- * @param start the starting point of the search (an empty, regular basic block)
- * @param empty a set to be filled by this method with all empty basic blocks found
- * (including {@code start}).
- * @param predecessors a set to be filled by this method with all predecessors
- */
- protected static void computeNeighborhoodOfEmptyBlockBackwards(
- RegularBlockImpl start,
- Set<RegularBlockImpl> empty,
- Set<PredecessorHolder> predecessors) {
-
- RegularBlockImpl cur = start;
- empty.add(cur);
- for (final BlockImpl pred : cur.getPredecessors()) {
- switch (pred.getType()) {
- case SPECIAL_BLOCK:
- // add pred correctly to predecessor list
- predecessors.add(getPredecessorHolder(pred, cur));
- break;
- case CONDITIONAL_BLOCK:
- // add pred correctly to predecessor list
- predecessors.add(getPredecessorHolder(pred, cur));
- break;
- case EXCEPTION_BLOCK:
- // add pred correctly to predecessor list
- predecessors.add(getPredecessorHolder(pred, cur));
- break;
- case REGULAR_BLOCK:
- RegularBlockImpl r = (RegularBlockImpl) pred;
- if (r.isEmpty()) {
- // recursively look backwards
- if (!empty.contains(r)) {
- computeNeighborhoodOfEmptyBlockBackwards(r, empty, predecessors);
- }
- } else {
- // add pred correctly to predecessor list
- predecessors.add(getPredecessorHolder(pred, cur));
- }
- break;
- }
- }
- }
-
- /**
- * Return a predecessor holder that can be used to set the successor of {@code pred} in the
- * place where previously the edge pointed to {@code cur}. Additionally, the predecessor
- * holder also takes care of unlinking (i.e., removing the {@code pred} from {@code cur's}
- * predecessors).
- */
- protected static PredecessorHolder getPredecessorHolder(
- final BlockImpl pred, final BlockImpl cur) {
- switch (pred.getType()) {
- case SPECIAL_BLOCK:
- SingleSuccessorBlockImpl s = (SingleSuccessorBlockImpl) pred;
- return singleSuccessorHolder(s, cur);
- case CONDITIONAL_BLOCK:
- // add pred correctly to predecessor list
- final ConditionalBlockImpl c = (ConditionalBlockImpl) pred;
- if (c.getThenSuccessor() == cur) {
- return new PredecessorHolder() {
- @Override
- public void setSuccessor(BlockImpl b) {
- c.setThenSuccessor(b);
- cur.removePredecessor(pred);
- }
-
- @Override
- public BlockImpl getBlock() {
- return c;
- }
- };
- } else {
- assert c.getElseSuccessor() == cur;
- return new PredecessorHolder() {
- @Override
- public void setSuccessor(BlockImpl b) {
- c.setElseSuccessor(b);
- cur.removePredecessor(pred);
- }
-
- @Override
- public BlockImpl getBlock() {
- return c;
- }
- };
- }
- case EXCEPTION_BLOCK:
- // add pred correctly to predecessor list
- final ExceptionBlockImpl e = (ExceptionBlockImpl) pred;
- if (e.getSuccessor() == cur) {
- return singleSuccessorHolder(e, cur);
- } else {
- Set<Entry<TypeMirror, Set<Block>>> entrySet =
- e.getExceptionalSuccessors().entrySet();
- for (final Entry<TypeMirror, Set<Block>> entry : entrySet) {
- if (entry.getValue().contains(cur)) {
- return new PredecessorHolder() {
- @Override
- public void setSuccessor(BlockImpl b) {
- e.addExceptionalSuccessor(b, entry.getKey());
- cur.removePredecessor(pred);
- }
-
- @Override
- public BlockImpl getBlock() {
- return e;
- }
- };
- }
- }
- }
- assert false;
- break;
- case REGULAR_BLOCK:
- RegularBlockImpl r = (RegularBlockImpl) pred;
- return singleSuccessorHolder(r, cur);
- }
- return null;
- }
-
- /**
- * @return a {@link PredecessorHolder} that sets the successor of a single successor block
- * {@code s}.
- */
- protected static PredecessorHolder singleSuccessorHolder(
- final SingleSuccessorBlockImpl s, final BlockImpl old) {
- return new PredecessorHolder() {
- @Override
- public void setSuccessor(BlockImpl b) {
- s.setSuccessor(b);
- old.removePredecessor(s);
- }
-
- @Override
- public BlockImpl getBlock() {
- return s;
- }
- };
- }
- }
-
- /* --------------------------------------------------------- */
- /* Phase Two */
- /* --------------------------------------------------------- */
-
- /** Tuple class with up to three members. */
- protected static class Tuple<A, B, C> {
- public A a;
- public B b;
- public C c;
-
- public Tuple(A a, B b) {
- this.a = a;
- this.b = b;
- }
-
- public Tuple(A a, B b, C c) {
- this.a = a;
- this.b = b;
- this.c = c;
- }
- }
-
- /** Class that performs phase two of the translation process. */
- public class CFGTranslationPhaseTwo {
-
- public CFGTranslationPhaseTwo() {}
-
- /**
- * Perform phase two of the translation.
- *
- * @param in the result of phase one
- * @return a control flow graph that might still contain degenerate basic block (such as
- * empty regular basic blocks or conditional blocks with the same block as 'then' and
- * 'else' sucessor)
- */
- public ControlFlowGraph process(PhaseOneResult in) {
-
- Map<Label, Integer> bindings = in.bindings;
- ArrayList<ExtendedNode> nodeList = in.nodeList;
- Set<Integer> leaders = in.leaders;
-
- assert in.nodeList.size() > 0;
-
- // exit blocks
- SpecialBlockImpl regularExitBlock = new SpecialBlockImpl(SpecialBlockType.EXIT);
- SpecialBlockImpl exceptionalExitBlock =
- new SpecialBlockImpl(SpecialBlockType.EXCEPTIONAL_EXIT);
-
- // record missing edges that will be added later
- Set<Tuple<? extends SingleSuccessorBlockImpl, Integer, ?>> missingEdges =
- new MostlySingleton<>();
-
- // missing exceptional edges
- Set<Tuple<ExceptionBlockImpl, Integer, TypeMirror>> missingExceptionalEdges =
- new HashSet<>();
-
- // create start block
- SpecialBlockImpl startBlock = new SpecialBlockImpl(SpecialBlockType.ENTRY);
- missingEdges.add(new Tuple<>(startBlock, 0));
-
- // loop through all 'leaders' (while dynamically detecting the
- // leaders)
- RegularBlockImpl block = new RegularBlockImpl();
- int i = 0;
- for (ExtendedNode node : nodeList) {
- switch (node.getType()) {
- case NODE:
- if (leaders.contains(i)) {
- RegularBlockImpl b = new RegularBlockImpl();
- block.setSuccessor(b);
- block = b;
- }
- block.addNode(node.getNode());
- node.setBlock(block);
-
- // does this node end the execution (modeled as an edge to
- // the exceptional exit block)
- boolean terminatesExecution = node.getTerminatesExecution();
- if (terminatesExecution) {
- block.setSuccessor(exceptionalExitBlock);
- block = new RegularBlockImpl();
- }
- break;
- case CONDITIONAL_JUMP:
- {
- ConditionalJump cj = (ConditionalJump) node;
- // Exception nodes may fall through to conditional jumps,
- // so we set the block which is required for the insertion
- // of missing edges.
- node.setBlock(block);
- assert block != null;
- final ConditionalBlockImpl cb = new ConditionalBlockImpl();
- if (cj.getTrueFlowRule() != null) {
- cb.setThenFlowRule(cj.getTrueFlowRule());
- }
- if (cj.getFalseFlowRule() != null) {
- cb.setElseFlowRule(cj.getFalseFlowRule());
- }
- block.setSuccessor(cb);
- block = new RegularBlockImpl();
- // use two anonymous SingleSuccessorBlockImpl that set the
- // 'then' and 'else' successor of the conditional block
- final Label thenLabel = cj.getThenLabel();
- final Label elseLabel = cj.getElseLabel();
- missingEdges.add(
- new Tuple<>(
- new SingleSuccessorBlockImpl() {
- @Override
- public void setSuccessor(BlockImpl successor) {
- cb.setThenSuccessor(successor);
- }
- },
- bindings.get(thenLabel)));
- missingEdges.add(
- new Tuple<>(
- new SingleSuccessorBlockImpl() {
- @Override
- public void setSuccessor(BlockImpl successor) {
- cb.setElseSuccessor(successor);
- }
- },
- bindings.get(elseLabel)));
- break;
- }
- case UNCONDITIONAL_JUMP:
- if (leaders.contains(i)) {
- RegularBlockImpl b = new RegularBlockImpl();
- block.setSuccessor(b);
- block = b;
- }
- node.setBlock(block);
- if (node.getLabel() == regularExitLabel) {
- block.setSuccessor(regularExitBlock);
- } else if (node.getLabel() == exceptionalExitLabel) {
- block.setSuccessor(exceptionalExitBlock);
- } else {
- missingEdges.add(new Tuple<>(block, bindings.get(node.getLabel())));
- }
- block = new RegularBlockImpl();
- break;
- case EXCEPTION_NODE:
- NodeWithExceptionsHolder en = (NodeWithExceptionsHolder) node;
- // create new exception block and link with previous block
- ExceptionBlockImpl e = new ExceptionBlockImpl();
- Node nn = en.getNode();
- e.setNode(nn);
- node.setBlock(e);
- block.setSuccessor(e);
- block = new RegularBlockImpl();
-
- // ensure linking between e and next block (normal edge)
- // Note: do not link to the next block for throw statements
- // (these throw exceptions for sure)
- if (!node.getTerminatesExecution()) {
- missingEdges.add(new Tuple<>(e, i + 1));
- }
-
- // exceptional edges
- for (Entry<TypeMirror, Set<Label>> entry : en.getExceptions().entrySet()) {
- TypeMirror cause = entry.getKey();
- for (Label label : entry.getValue()) {
- Integer target = bindings.get(label);
- missingExceptionalEdges.add(
- new Tuple<ExceptionBlockImpl, Integer, TypeMirror>(
- e, target, cause));
- }
- }
- break;
- }
- i++;
- }
-
- // add missing edges
- for (Tuple<? extends SingleSuccessorBlockImpl, Integer, ?> p : missingEdges) {
- Integer index = p.b;
- ExtendedNode extendedNode = nodeList.get(index);
- BlockImpl target = extendedNode.getBlock();
- SingleSuccessorBlockImpl source = p.a;
- source.setSuccessor(target);
- }
-
- // add missing exceptional edges
- for (Tuple<ExceptionBlockImpl, Integer, ?> p : missingExceptionalEdges) {
- Integer index = p.b;
- TypeMirror cause = (TypeMirror) p.c;
- ExceptionBlockImpl source = p.a;
- if (index == null) {
- // edge to exceptional exit
- source.addExceptionalSuccessor(exceptionalExitBlock, cause);
- } else {
- // edge to specific target
- ExtendedNode extendedNode = nodeList.get(index);
- BlockImpl target = extendedNode.getBlock();
- source.addExceptionalSuccessor(target, cause);
- }
- }
-
- return new ControlFlowGraph(
- startBlock,
- regularExitBlock,
- exceptionalExitBlock,
- in.underlyingAST,
- in.treeLookupMap,
- in.convertedTreeLookupMap,
- in.returnNodes);
- }
- }
-
- /* --------------------------------------------------------- */
- /* Phase One */
- /* --------------------------------------------------------- */
-
- /**
- * A wrapper object to pass around the result of phase one. For a documentation of the fields
- * see {@link CFGTranslationPhaseOne}.
- */
- protected static class PhaseOneResult {
-
- private final IdentityHashMap<Tree, Node> treeLookupMap;
- private final IdentityHashMap<Tree, Node> convertedTreeLookupMap;
- private final UnderlyingAST underlyingAST;
- private final Map<Label, Integer> bindings;
- private final ArrayList<ExtendedNode> nodeList;
- private final Set<Integer> leaders;
- private final List<ReturnNode> returnNodes;
-
- public PhaseOneResult(
- UnderlyingAST underlyingAST,
- IdentityHashMap<Tree, Node> treeLookupMap,
- IdentityHashMap<Tree, Node> convertedTreeLookupMap,
- ArrayList<ExtendedNode> nodeList,
- Map<Label, Integer> bindings,
- Set<Integer> leaders,
- List<ReturnNode> returnNodes) {
- this.underlyingAST = underlyingAST;
- this.treeLookupMap = treeLookupMap;
- this.convertedTreeLookupMap = convertedTreeLookupMap;
- this.nodeList = nodeList;
- this.bindings = bindings;
- this.leaders = leaders;
- this.returnNodes = returnNodes;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (ExtendedNode n : nodeList) {
- sb.append(nodeToString(n));
- sb.append("\n");
- }
- return sb.toString();
- }
-
- protected String nodeToString(ExtendedNode n) {
- if (n.getType() == ExtendedNodeType.CONDITIONAL_JUMP) {
- ConditionalJump t = (ConditionalJump) n;
- return "TwoTargetConditionalJump("
- + resolveLabel(t.getThenLabel())
- + ","
- + resolveLabel(t.getElseLabel())
- + ")";
- } else if (n.getType() == ExtendedNodeType.UNCONDITIONAL_JUMP) {
- return "UnconditionalJump(" + resolveLabel(n.getLabel()) + ")";
- } else {
- return n.toString();
- }
- }
-
- private String resolveLabel(Label label) {
- Integer index = bindings.get(label);
- if (index == null) {
- return "null";
- }
- return nodeToString(nodeList.get(index));
- }
- }
-
- /**
- * Class that performs phase one of the translation process. It generates the following
- * information:
- *
- * <ul>
- * <li>A sequence of extended nodes.
- * <li>A set of bindings from {@link Label}s to positions in the node sequence.
- * <li>A set of leader nodes that give rise to basic blocks in phase two.
- * <li>A lookup map that gives the mapping from AST tree nodes to {@link Node}s.
- * </ul>
- *
- * <p>The return type of this scanner is {@link Node}. For expressions, the corresponding node
- * is returned to allow linking between different nodes.
- *
- * <p>However, for statements there is usually no single {@link Node} that is created, and thus
- * no node is returned (rather, null is returned).
- *
- * <p>Every {@code visit*} method is assumed to add at least one extended node to the list of
- * nodes (which might only be a jump).
- */
- public class CFGTranslationPhaseOne extends TreePathScanner<Node, Void> {
-
- public CFGTranslationPhaseOne() {}
-
- /** Annotation processing environment and its associated type and tree utilities. */
- protected ProcessingEnvironment env;
-
- protected Elements elements;
- protected Types types;
- protected Trees trees;
- protected TreeBuilder treeBuilder;
- protected AnnotationProvider annotationProvider;
-
- /**
- * Current {@link Label} to which a break statement with no label should jump, or null if
- * there is no valid destination.
- */
- protected /*@Nullable*/ Label breakTargetL;
-
- /**
- * Map from AST label Names to CFG {@link Label}s for breaks. Each labeled statement creates
- * two CFG {@link Label}s, one for break and one for continue.
- */
- protected Map<Name, Label> breakLabels;
-
- /**
- * Current {@link Label} to which a continue statement with no label should jump, or null if
- * there is no valid destination.
- */
- protected /*@Nullable*/ Label continueTargetL;
-
- /**
- * Map from AST label Names to CFG {@link Label}s for continues. Each labeled statement
- * creates two CFG {@link Label}s, one for break and one for continue.
- */
- protected Map<Name, Label> continueLabels;
-
- /**
- * Maps from AST {@link Tree}s to {@link Node}s. Every Tree that produces a value will have
- * at least one corresponding Node. Trees that undergo conversions, such as boxing or
- * unboxing, can map to two distinct Nodes. The Node for the pre-conversion value is stored
- * in the treeLookupMap, while the Node for the post-conversion value is stored in the
- * convertedTreeLookupMap.
- */
- protected IdentityHashMap<Tree, Node> treeLookupMap;
-
- /** Map from AST {@link Tree}s to post-conversion {@link Node}s. */
- protected IdentityHashMap<Tree, Node> convertedTreeLookupMap;
-
- /** The list of extended nodes. */
- protected ArrayList<ExtendedNode> nodeList;
-
- /** The bindings of labels to positions (i.e., indices) in the {@code nodeList}. */
- protected Map<Label, Integer> bindings;
-
- /** The set of leaders (represented as indices into {@code nodeList}). */
- protected Set<Integer> leaders;
-
- /**
- * All return nodes (if any) encountered. Only includes return statements that actually
- * return something
- */
- private List<ReturnNode> returnNodes;
-
- /** Nested scopes of try-catch blocks in force at the current program point. */
- private TryStack tryStack;
-
- /**
- * Performs the actual work of phase one.
- *
- * @param bodyPath path to the body of the underlying AST's method
- * @param env annotation processing environment containing type utilities
- * @param underlyingAST the AST for which the CFG is to be built
- * @param exceptionalExitLabel the label for exceptional exits from the CFG
- * @param treeBuilder builder for new AST nodes
- * @param annotationProvider extracts annotations from AST nodes
- * @return the result of phase one
- */
- public PhaseOneResult process(
- TreePath bodyPath,
- ProcessingEnvironment env,
- UnderlyingAST underlyingAST,
- Label exceptionalExitLabel,
- TreeBuilder treeBuilder,
- AnnotationProvider annotationProvider) {
- this.env = env;
- this.tryStack = new TryStack(exceptionalExitLabel);
- this.treeBuilder = treeBuilder;
- this.annotationProvider = annotationProvider;
- elements = env.getElementUtils();
- types = env.getTypeUtils();
-
- // initialize lists and maps
- treeLookupMap = new IdentityHashMap<>();
- convertedTreeLookupMap = new IdentityHashMap<>();
- nodeList = new ArrayList<>();
- bindings = new HashMap<>();
- leaders = new HashSet<>();
- breakLabels = new HashMap<>();
- continueLabels = new HashMap<>();
- returnNodes = new ArrayList<>();
-
- // traverse AST of the method body
- scan(bodyPath, null);
-
- // add marker to indicate that the next block will be the exit block
- // Note: if there is a return statement earlier in the method (which
- // is always the case for non-void methods), then this is not
- // strictly necessary. However, it is also not a problem, as it will
- // just generate a degenerated control graph case that will be
- // removed in a later phase.
- nodeList.add(new UnconditionalJump(regularExitLabel));
-
- return new PhaseOneResult(
- underlyingAST,
- treeLookupMap,
- convertedTreeLookupMap,
- nodeList,
- bindings,
- leaders,
- returnNodes);
- }
-
- public PhaseOneResult process(
- CompilationUnitTree root,
- ProcessingEnvironment env,
- UnderlyingAST underlyingAST,
- Label exceptionalExitLabel,
- TreeBuilder treeBuilder,
- AnnotationProvider annotationProvider) {
- trees = Trees.instance(env);
- TreePath bodyPath = trees.getPath(root, underlyingAST.getCode());
- return process(
- bodyPath,
- env,
- underlyingAST,
- exceptionalExitLabel,
- treeBuilder,
- annotationProvider);
- }
-
- /**
- * Perform any actions required when CFG translation creates a new Tree that is not part of
- * the original AST.
- *
- * @param tree the newly created Tree
- */
- public void handleArtificialTree(Tree tree) {}
-
- /* --------------------------------------------------------- */
- /* Nodes and Labels Management */
- /* --------------------------------------------------------- */
-
- /**
- * Add a node to the lookup map if it not already present.
- *
- * @param node the node to add to the lookup map
- */
- protected void addToLookupMap(Node node) {
- Tree tree = node.getTree();
- if (tree == null) {
- return;
- }
- if (!treeLookupMap.containsKey(tree)) {
- treeLookupMap.put(tree, node);
- }
-
- Tree enclosingParens = parenMapping.get(tree);
- while (enclosingParens != null) {
- treeLookupMap.put(enclosingParens, node);
- enclosingParens = parenMapping.get(enclosingParens);
- }
- }
-
- /**
- * Add a node in the post-conversion lookup map. The node should refer to a Tree and that
- * Tree should already be in the pre-conversion lookup map. This method is used to update
- * the Tree-Node mapping with conversion nodes.
- *
- * @param node the node to add to the lookup map
- */
- protected void addToConvertedLookupMap(Node node) {
- Tree tree = node.getTree();
- addToConvertedLookupMap(tree, node);
- }
-
- /**
- * Add a node in the post-conversion lookup map. The tree argument should already be in the
- * pre-conversion lookup map. This method is used to update the Tree-Node mapping with
- * conversion nodes.
- *
- * @param tree the tree used as a key in the map
- * @param node the node to add to the lookup map
- */
- protected void addToConvertedLookupMap(Tree tree, Node node) {
- assert tree != null;
- assert treeLookupMap.containsKey(tree);
- convertedTreeLookupMap.put(tree, node);
- }
-
- /**
- * Extend the list of extended nodes with a node.
- *
- * @param node the node to add
- * @return the same node (for convenience)
- */
- protected <T extends Node> T extendWithNode(T node) {
- addToLookupMap(node);
- extendWithExtendedNode(new NodeHolder(node));
- return node;
- }
-
- /**
- * Extend the list of extended nodes with a node, where {@code node} might throw the
- * exception {@code cause}.
- *
- * @param node the node to add
- * @param cause an exception that the node might throw
- * @return the node holder
- */
- protected NodeWithExceptionsHolder extendWithNodeWithException(
- Node node, TypeMirror cause) {
- addToLookupMap(node);
- return extendWithNodeWithExceptions(node, Collections.singleton(cause));
- }
-
- /**
- * Extend the list of extended nodes with a node, where {@code node} might throw any of the
- * exception in {@code causes}.
- *
- * @param node the node to add
- * @param causes set of exceptions that the node might throw
- * @return the node holder
- */
- protected NodeWithExceptionsHolder extendWithNodeWithExceptions(
- Node node, Set<TypeMirror> causes) {
- addToLookupMap(node);
- Map<TypeMirror, Set<Label>> exceptions = new HashMap<>();
- for (TypeMirror cause : causes) {
- exceptions.put(cause, tryStack.possibleLabels(cause));
- }
- NodeWithExceptionsHolder exNode = new NodeWithExceptionsHolder(node, exceptions);
- extendWithExtendedNode(exNode);
- return exNode;
- }
-
- /**
- * Insert {@code node} after {@code pred} in the list of extended nodes, or append to the
- * list if {@code pred} is not present.
- *
- * @param node the node to add
- * @param pred the desired predecessor of node
- * @return the node holder
- */
- protected <T extends Node> T insertNodeAfter(T node, Node pred) {
- addToLookupMap(node);
- insertExtendedNodeAfter(new NodeHolder(node), pred);
- return node;
- }
-
- /**
- * Insert a {@code node} that might throw the exception {@code cause} after {@code pred} in
- * the list of extended nodes, or append to the list if {@code pred} is not present.
- *
- * @param node the node to add
- * @param causes set of exceptions that the node might throw
- * @param pred the desired predecessor of node
- * @return the node holder
- */
- protected NodeWithExceptionsHolder insertNodeWithExceptionsAfter(
- Node node, Set<TypeMirror> causes, Node pred) {
- addToLookupMap(node);
- Map<TypeMirror, Set<Label>> exceptions = new HashMap<>();
- for (TypeMirror cause : causes) {
- exceptions.put(cause, tryStack.possibleLabels(cause));
- }
- NodeWithExceptionsHolder exNode = new NodeWithExceptionsHolder(node, exceptions);
- insertExtendedNodeAfter(exNode, pred);
- return exNode;
- }
-
- /**
- * Extend the list of extended nodes with an extended node.
- *
- * @param n the extended node
- */
- protected void extendWithExtendedNode(ExtendedNode n) {
- nodeList.add(n);
- }
-
- /**
- * Insert {@code n} after the node {@code pred} in the list of extended nodes, or append
- * {@code n} if {@code pred} is not present.
- *
- * @param n the extended node
- * @param pred the desired predecessor
- */
- protected void insertExtendedNodeAfter(ExtendedNode n, Node pred) {
- int index = -1;
- for (int i = 0; i < nodeList.size(); i++) {
- ExtendedNode inList = nodeList.get(i);
- if (inList instanceof NodeHolder || inList instanceof NodeWithExceptionsHolder) {
- if (inList.getNode() == pred) {
- index = i;
- break;
- }
- }
- }
- if (index != -1) {
- nodeList.add(index + 1, n);
- // update bindings
- for (Entry<Label, Integer> e : bindings.entrySet()) {
- if (e.getValue() >= index + 1) {
- bindings.put(e.getKey(), e.getValue() + 1);
- }
- }
- // update leaders
- Set<Integer> newLeaders = new HashSet<>();
- for (Integer l : leaders) {
- if (l >= index + 1) {
- newLeaders.add(l + 1);
- } else {
- newLeaders.add(l);
- }
- }
- leaders = newLeaders;
- } else {
- nodeList.add(n);
- }
- }
-
- /**
- * Add the label {@code l} to the extended node that will be placed next in the sequence.
- */
- protected void addLabelForNextNode(Label l) {
- leaders.add(nodeList.size());
- bindings.put(l, nodeList.size());
- }
-
- /* --------------------------------------------------------- */
- /* Utility Methods */
- /* --------------------------------------------------------- */
-
- protected long uid = 0;
-
- protected String uniqueName(String prefix) {
- return prefix + "#num" + uid++;
- }
-
- /**
- * If the input node is an unboxed primitive type, insert a call to the appropriate valueOf
- * method, otherwise leave it alone.
- *
- * @param node in input node
- * @return a Node representing the boxed version of the input, which may simply be the input
- * node
- */
- protected Node box(Node node) {
- // For boxing conversion, see JLS 5.1.7
- if (TypesUtils.isPrimitive(node.getType())) {
- PrimitiveType primitive = types.getPrimitiveType(node.getType().getKind());
- TypeMirror boxedType = types.getDeclaredType(types.boxedClass(primitive));
-
- TypeElement boxedElement = (TypeElement) ((DeclaredType) boxedType).asElement();
- IdentifierTree classTree = treeBuilder.buildClassUse(boxedElement);
- handleArtificialTree(classTree);
- ClassNameNode className = new ClassNameNode(classTree);
- className.setInSource(false);
- insertNodeAfter(className, node);
-
- MemberSelectTree valueOfSelect = treeBuilder.buildValueOfMethodAccess(classTree);
- handleArtificialTree(valueOfSelect);
- MethodAccessNode valueOfAccess = new MethodAccessNode(valueOfSelect, className);
- valueOfAccess.setInSource(false);
- insertNodeAfter(valueOfAccess, className);
-
- MethodInvocationTree valueOfCall =
- treeBuilder.buildMethodInvocation(
- valueOfSelect, (ExpressionTree) node.getTree());
- handleArtificialTree(valueOfCall);
- Node boxed =
- new MethodInvocationNode(
- valueOfCall,
- valueOfAccess,
- Collections.singletonList(node),
- getCurrentPath());
- boxed.setInSource(false);
- // Add Throwable to account for unchecked exceptions
- TypeElement throwableElement = elements.getTypeElement("java.lang.Throwable");
- addToConvertedLookupMap(node.getTree(), boxed);
- insertNodeWithExceptionsAfter(
- boxed, Collections.singleton(throwableElement.asType()), valueOfAccess);
- return boxed;
- } else {
- return node;
- }
- }
-
- /**
- * If the input node is a boxed type, unbox it, otherwise leave it alone.
- *
- * @param node in input node
- * @return a Node representing the unboxed version of the input, which may simply be the
- * input node
- */
- protected Node unbox(Node node) {
- if (TypesUtils.isBoxedPrimitive(node.getType())) {
-
- MemberSelectTree primValueSelect =
- treeBuilder.buildPrimValueMethodAccess(node.getTree());
- handleArtificialTree(primValueSelect);
- MethodAccessNode primValueAccess = new MethodAccessNode(primValueSelect, node);
- primValueAccess.setInSource(false);
- // Method access may throw NullPointerException
- TypeElement npeElement = elements.getTypeElement("java.lang.NullPointerException");
- insertNodeWithExceptionsAfter(
- primValueAccess, Collections.singleton(npeElement.asType()), node);
-
- MethodInvocationTree primValueCall =
- treeBuilder.buildMethodInvocation(primValueSelect);
- handleArtificialTree(primValueCall);
- Node unboxed =
- new MethodInvocationNode(
- primValueCall,
- primValueAccess,
- Collections.<Node>emptyList(),
- getCurrentPath());
- unboxed.setInSource(false);
-
- // Add Throwable to account for unchecked exceptions
- TypeElement throwableElement = elements.getTypeElement("java.lang.Throwable");
- addToConvertedLookupMap(node.getTree(), unboxed);
- insertNodeWithExceptionsAfter(
- unboxed, Collections.singleton(throwableElement.asType()), primValueAccess);
- return unboxed;
- } else {
- return node;
- }
- }
-
- private TreeInfo getTreeInfo(Tree tree) {
- final TypeMirror type = InternalUtils.typeOf(tree);
- final boolean boxed = TypesUtils.isBoxedPrimitive(type);
- final TypeMirror unboxedType = boxed ? types.unboxedType(type) : type;
-
- final boolean bool = TypesUtils.isBooleanType(type);
- final boolean numeric = TypesUtils.isNumeric(unboxedType);
-
- return new TreeInfo() {
- @Override
- public boolean isNumeric() {
- return numeric;
- }
-
- @Override
- public boolean isBoxed() {
- return boxed;
- }
-
- @Override
- public boolean isBoolean() {
- return bool;
- }
-
- @Override
- public TypeMirror unboxedType() {
- return unboxedType;
- }
- };
- }
-
- /** @return the unboxed tree if necessary, as described in JLS 5.1.8 */
- private Node unboxAsNeeded(Node node, boolean boxed) {
- return boxed ? unbox(node) : node;
- }
-
- /**
- * Convert the input node to String type, if it isn't already.
- *
- * @param node an input node
- * @return a Node with the value promoted to String, which may be the input node
- */
- protected Node stringConversion(Node node) {
- // For string conversion, see JLS 5.1.11
- TypeElement stringElement = elements.getTypeElement("java.lang.String");
- if (!TypesUtils.isString(node.getType())) {
- Node converted =
- new StringConversionNode(node.getTree(), node, stringElement.asType());
- addToConvertedLookupMap(converted);
- insertNodeAfter(converted, node);
- return converted;
- } else {
- return node;
- }
- }
-
- /**
- * Perform unary numeric promotion on the input node.
- *
- * @param node a node producing a value of numeric primitive or boxed type
- * @return a Node with the value promoted to the int, long float or double, which may be the
- * input node
- */
- protected Node unaryNumericPromotion(Node node) {
- // For unary numeric promotion, see JLS 5.6.1
- node = unbox(node);
-
- switch (node.getType().getKind()) {
- case BYTE:
- case CHAR:
- case SHORT:
- {
- TypeMirror intType = types.getPrimitiveType(TypeKind.INT);
- Node widened = new WideningConversionNode(node.getTree(), node, intType);
- addToConvertedLookupMap(widened);
- insertNodeAfter(widened, node);
- return widened;
- }
- default:
- // Nothing to do.
- break;
- }
-
- return node;
- }
-
- /**
- * Returns true if the argument type is a numeric primitive or a boxed numeric primitive and
- * false otherwise.
- */
- protected boolean isNumericOrBoxed(TypeMirror type) {
- if (TypesUtils.isBoxedPrimitive(type)) {
- type = types.unboxedType(type);
- }
- return TypesUtils.isNumeric(type);
- }
-
- /**
- * Compute the type to which two numeric types must be promoted before performing a binary
- * numeric operation on them. The input types must both be numeric and the output type is
- * primitive.
- *
- * @param left the type of the left operand
- * @param right the type of the right operand
- * @return a TypeMirror representing the binary numeric promoted type
- */
- protected TypeMirror binaryPromotedType(TypeMirror left, TypeMirror right) {
- if (TypesUtils.isBoxedPrimitive(left)) {
- left = types.unboxedType(left);
- }
- if (TypesUtils.isBoxedPrimitive(right)) {
- right = types.unboxedType(right);
- }
- TypeKind promotedTypeKind = TypesUtils.widenedNumericType(left, right);
- return types.getPrimitiveType(promotedTypeKind);
- }
-
- /**
- * Perform binary numeric promotion on the input node to make it match the expression type.
- *
- * @param node a node producing a value of numeric primitive or boxed type
- * @param exprType the type to promote the value to
- * @return a Node with the value promoted to the exprType, which may be the input node
- */
- protected Node binaryNumericPromotion(Node node, TypeMirror exprType) {
- // For binary numeric promotion, see JLS 5.6.2
- node = unbox(node);
-
- if (!types.isSameType(node.getType(), exprType)) {
- Node widened = new WideningConversionNode(node.getTree(), node, exprType);
- addToConvertedLookupMap(widened);
- insertNodeAfter(widened, node);
- return widened;
- } else {
- return node;
- }
- }
-
- /**
- * Perform widening primitive conversion on the input node to make it match the destination
- * type.
- *
- * @param node a node producing a value of numeric primitive type
- * @param destType the type to widen the value to
- * @return a Node with the value widened to the exprType, which may be the input node
- */
- protected Node widen(Node node, TypeMirror destType) {
- // For widening conversion, see JLS 5.1.2
- assert TypesUtils.isPrimitive(node.getType()) && TypesUtils.isPrimitive(destType)
- : "widening must be applied to primitive types";
- if (types.isSubtype(node.getType(), destType)
- && !types.isSameType(node.getType(), destType)) {
- Node widened = new WideningConversionNode(node.getTree(), node, destType);
- addToConvertedLookupMap(widened);
- insertNodeAfter(widened, node);
- return widened;
- } else {
- return node;
- }
- }
-
- /**
- * Perform narrowing conversion on the input node to make it match the destination type.
- *
- * @param node a node producing a value of numeric primitive type
- * @param destType the type to narrow the value to
- * @return a Node with the value narrowed to the exprType, which may be the input node
- */
- protected Node narrow(Node node, TypeMirror destType) {
- // For narrowing conversion, see JLS 5.1.3
- assert TypesUtils.isPrimitive(node.getType()) && TypesUtils.isPrimitive(destType)
- : "narrowing must be applied to primitive types";
- if (types.isSubtype(destType, node.getType())
- && !types.isSameType(destType, node.getType())) {
- Node narrowed = new NarrowingConversionNode(node.getTree(), node, destType);
- addToConvertedLookupMap(narrowed);
- insertNodeAfter(narrowed, node);
- return narrowed;
- } else {
- return node;
- }
- }
-
- /**
- * Perform narrowing conversion and optionally boxing conversion on the input node to make
- * it match the destination type.
- *
- * @param node a node producing a value of numeric primitive type
- * @param destType the type to narrow the value to (possibly boxed)
- * @return a Node with the value narrowed and boxed to the destType, which may be the input
- * node
- */
- protected Node narrowAndBox(Node node, TypeMirror destType) {
- if (TypesUtils.isBoxedPrimitive(destType)) {
- return box(narrow(node, types.unboxedType(destType)));
- } else {
- return narrow(node, destType);
- }
- }
-
- /**
- * Return whether a conversion from the type of the node to varType requires narrowing.
- *
- * @param varType the type of a variable (or general LHS) to be converted to
- * @param node a node whose value is being converted
- * @return whether this conversion requires narrowing to succeed
- */
- protected boolean conversionRequiresNarrowing(TypeMirror varType, Node node) {
- // Narrowing is restricted to cases where the left hand side
- // is byte, char, short or Byte, Char, Short and the right
- // hand side is a constant.
- TypeMirror unboxedVarType =
- TypesUtils.isBoxedPrimitive(varType) ? types.unboxedType(varType) : varType;
- TypeKind unboxedVarKind = unboxedVarType.getKind();
- boolean isLeftNarrowableTo =
- unboxedVarKind == TypeKind.BYTE
- || unboxedVarKind == TypeKind.SHORT
- || unboxedVarKind == TypeKind.CHAR;
- boolean isRightConstant = node instanceof ValueLiteralNode;
- return isLeftNarrowableTo && isRightConstant;
- }
-
- /**
- * Assignment conversion and method invocation conversion are almost identical, except that
- * assignment conversion allows narrowing. We factor out the common logic here.
- *
- * @param node a Node producing a value
- * @param varType the type of a variable
- * @param contextAllowsNarrowing whether to allow narrowing (for assignment conversion) or
- * not (for method invocation conversion)
- * @return a Node with the value converted to the type of the variable, which may be the
- * input node itself
- */
- protected Node commonConvert(
- Node node, TypeMirror varType, boolean contextAllowsNarrowing) {
- // For assignment conversion, see JLS 5.2
- // For method invocation conversion, see JLS 5.3
-
- // Check for identical types or "identity conversion"
- TypeMirror nodeType = node.getType();
- boolean isSameType = types.isSameType(nodeType, varType);
- if (isSameType) {
- return node;
- }
-
- boolean isRightNumeric = TypesUtils.isNumeric(nodeType);
- boolean isRightPrimitive = TypesUtils.isPrimitive(nodeType);
- boolean isRightBoxed = TypesUtils.isBoxedPrimitive(nodeType);
- boolean isRightReference = nodeType instanceof ReferenceType;
- boolean isLeftNumeric = TypesUtils.isNumeric(varType);
- boolean isLeftPrimitive = TypesUtils.isPrimitive(varType);
- // boolean isLeftBoxed = TypesUtils.isBoxedPrimitive(varType);
- boolean isLeftReference = varType instanceof ReferenceType;
- boolean isSubtype = types.isSubtype(nodeType, varType);
-
- if (isRightNumeric && isLeftNumeric && isSubtype) {
- node = widen(node, varType);
- nodeType = node.getType();
- } else if (isRightReference && isLeftReference && isSubtype) {
- // widening reference conversion is a no-op, but if it
- // applies, then later conversions do not.
- } else if (isRightPrimitive && isLeftReference) {
- if (contextAllowsNarrowing && conversionRequiresNarrowing(varType, node)) {
- node = narrowAndBox(node, varType);
- nodeType = node.getType();
- } else {
- node = box(node);
- nodeType = node.getType();
- }
- } else if (isRightBoxed && isLeftPrimitive) {
- node = unbox(node);
- nodeType = node.getType();
-
- if (types.isSubtype(nodeType, varType) && !types.isSameType(nodeType, varType)) {
- node = widen(node, varType);
- nodeType = node.getType();
- }
- } else if (isRightPrimitive && isLeftPrimitive) {
- if (contextAllowsNarrowing && conversionRequiresNarrowing(varType, node)) {
- node = narrow(node, varType);
- nodeType = node.getType();
- }
- }
-
- // TODO: if checkers need to know about null references of
- // a particular type, add logic for them here.
-
- return node;
- }
-
- /**
- * Perform assignment conversion so that it can be assigned to a variable of the given type.
- *
- * @param node a Node producing a value
- * @param varType the type of a variable
- * @return a Node with the value converted to the type of the variable, which may be the
- * input node itself
- */
- protected Node assignConvert(Node node, TypeMirror varType) {
- return commonConvert(node, varType, true);
- }
-
- /**
- * Perform method invocation conversion so that the node can be passed as a formal parameter
- * of the given type.
- *
- * @param node a Node producing a value
- * @param formalType the type of a formal parameter
- * @return a Node with the value converted to the type of the formal, which may be the input
- * node itself
- */
- protected Node methodInvocationConvert(Node node, TypeMirror formalType) {
- return commonConvert(node, formalType, false);
- }
-
- /**
- * Given a method element and as list of argument expressions, return a list of {@link
- * Node}s representing the arguments converted for a call of the method. This method applies
- * to both method invocations and constructor calls.
- *
- * @param method an ExecutableElement representing a method to be called
- * @param actualExprs a List of argument expressions to a call
- * @return a List of {@link Node}s representing arguments after conversions required by a
- * call to this method
- */
- protected List<Node> convertCallArguments(
- ExecutableElement method, List<? extends ExpressionTree> actualExprs) {
- // NOTE: It is important to convert one method argument before
- // generating CFG nodes for the next argument, since label binding
- // expects nodes to be generated in execution order. Therefore,
- // this method first determines which conversions need to be applied
- // and then iterates over the actual arguments.
- List<? extends VariableElement> formals = method.getParameters();
-
- ArrayList<Node> convertedNodes = new ArrayList<Node>();
-
- int numFormals = formals.size();
- int numActuals = actualExprs.size();
- if (method.isVarArgs()) {
- // Create a new array argument if the actuals outnumber
- // the formals, or if the last actual is not assignable
- // to the last formal.
- int lastArgIndex = numFormals - 1;
- TypeMirror lastParamType = formals.get(lastArgIndex).asType();
- List<Node> dimensions = new ArrayList<>();
- List<Node> initializers = new ArrayList<>();
-
- if (numActuals == numFormals - 1) {
- // Apply method invocation conversion to all actual
- // arguments, then create and append an empty array
- for (int i = 0; i < numActuals; i++) {
- Node actualVal = scan(actualExprs.get(i), null);
- convertedNodes.add(
- methodInvocationConvert(actualVal, formals.get(i).asType()));
- }
-
- Node lastArgument =
- new ArrayCreationNode(null, lastParamType, dimensions, initializers);
- extendWithNode(lastArgument);
-
- convertedNodes.add(lastArgument);
- } else {
- TypeMirror actualType = InternalUtils.typeOf(actualExprs.get(lastArgIndex));
- if (numActuals == numFormals && types.isAssignable(actualType, lastParamType)) {
- // Normal call with no array creation, apply method
- // invocation conversion to all arguments.
- for (int i = 0; i < numActuals; i++) {
- Node actualVal = scan(actualExprs.get(i), null);
- convertedNodes.add(
- methodInvocationConvert(actualVal, formals.get(i).asType()));
- }
- } else {
- assert lastParamType instanceof ArrayType
- : "variable argument formal must be an array";
- // Apply method invocation conversion to lastArgIndex
- // arguments and use the remaining ones to initialize
- // an array.
- for (int i = 0; i < lastArgIndex; i++) {
- Node actualVal = scan(actualExprs.get(i), null);
- convertedNodes.add(
- methodInvocationConvert(actualVal, formals.get(i).asType()));
- }
-
- TypeMirror elemType = ((ArrayType) lastParamType).getComponentType();
- for (int i = lastArgIndex; i < numActuals; i++) {
- Node actualVal = scan(actualExprs.get(i), null);
- initializers.add(assignConvert(actualVal, elemType));
- }
-
- Node lastArgument =
- new ArrayCreationNode(
- null, lastParamType, dimensions, initializers);
- extendWithNode(lastArgument);
- convertedNodes.add(lastArgument);
- }
- }
- } else {
- for (int i = 0; i < numActuals; i++) {
- Node actualVal = scan(actualExprs.get(i), null);
- convertedNodes.add(methodInvocationConvert(actualVal, formals.get(i).asType()));
- }
- }
-
- return convertedNodes;
- }
-
- /**
- * Convert an operand of a conditional expression to the type of the whole expression.
- *
- * @param node a node occurring as the second or third operand of a conditional expression
- * @param destType the type to promote the value to
- * @return a Node with the value promoted to the destType, which may be the input node
- */
- protected Node conditionalExprPromotion(Node node, TypeMirror destType) {
- // For rules on converting operands of conditional expressions,
- // JLS 15.25
- TypeMirror nodeType = node.getType();
-
- // If the operand is already the same type as the whole
- // expression, then do nothing.
- if (types.isSameType(nodeType, destType)) {
- return node;
- }
-
- // If the operand is a primitive and the whole expression is
- // boxed, then apply boxing.
- if (TypesUtils.isPrimitive(nodeType) && TypesUtils.isBoxedPrimitive(destType)) {
- return box(node);
- }
-
- // If the operand is byte or Byte and the whole expression is
- // short, then convert to short.
- boolean isBoxedPrimitive = TypesUtils.isBoxedPrimitive(nodeType);
- TypeMirror unboxedNodeType = isBoxedPrimitive ? types.unboxedType(nodeType) : nodeType;
- TypeMirror unboxedDestType =
- TypesUtils.isBoxedPrimitive(destType) ? types.unboxedType(destType) : destType;
- if (TypesUtils.isNumeric(unboxedNodeType) && TypesUtils.isNumeric(unboxedDestType)) {
- if (unboxedNodeType.getKind() == TypeKind.BYTE
- && destType.getKind() == TypeKind.SHORT) {
- if (isBoxedPrimitive) {
- node = unbox(node);
- }
- return widen(node, destType);
- }
-
- // If the operand is Byte, Short or Character and the whole expression
- // is the unboxed version of it, then apply unboxing.
- TypeKind destKind = destType.getKind();
- if (destKind == TypeKind.BYTE
- || destKind == TypeKind.CHAR
- || destKind == TypeKind.SHORT) {
- if (isBoxedPrimitive) {
- return unbox(node);
- } else if (nodeType.getKind() == TypeKind.INT) {
- return narrow(node, destType);
- }
- }
-
- return binaryNumericPromotion(node, destType);
- }
-
- // For the final case in JLS 15.25, apply boxing but not lub.
- if (TypesUtils.isPrimitive(nodeType)
- && (destType.getKind() == TypeKind.DECLARED
- || destType.getKind() == TypeKind.UNION
- || destType.getKind() == TypeKind.INTERSECTION)) {
- return box(node);
- }
-
- return node;
- }
-
- /**
- * Returns the label {@link Name} of the leaf in the argument path, or null if the leaf is
- * not a labeled statement.
- */
- protected /*@Nullable*/ Name getLabel(TreePath path) {
- if (path.getParentPath() != null) {
- Tree parent = path.getParentPath().getLeaf();
- if (parent.getKind() == Tree.Kind.LABELED_STATEMENT) {
- return ((LabeledStatementTree) parent).getLabel();
- }
- }
- return null;
- }
-
- /* --------------------------------------------------------- */
- /* Visitor Methods */
- /* --------------------------------------------------------- */
-
- @Override
- public Node visitAnnotatedType(AnnotatedTypeTree tree, Void p) {
- return scan(tree.getUnderlyingType(), p);
- }
-
- @Override
- public Node visitAnnotation(AnnotationTree tree, Void p) {
- assert false : "AnnotationTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public MethodInvocationNode visitMethodInvocation(MethodInvocationTree tree, Void p) {
-
- // see JLS 15.12.4
-
- // First, compute the receiver, if any (15.12.4.1)
- // Second, evaluate the actual arguments, left to right and
- // possibly some arguments are stored into an array for variable
- // arguments calls (15.12.4.2)
- // Third, test the receiver, if any, for nullness (15.12.4.4)
- // Fourth, convert the arguments to the type of the formal
- // parameters (15.12.4.5)
- // Fifth, if the method is synchronized, lock the receiving
- // object or class (15.12.4.5)
- ExecutableElement method = TreeUtils.elementFromUse(tree);
- if (method == null) {
- // The method wasn't found, e.g. because of a compilation error.
- return null;
- }
-
- // TODO? Variable wasn't used.
- // boolean isBooleanMethod = TypesUtils.isBooleanType(method.getReturnType());
-
- ExpressionTree methodSelect = tree.getMethodSelect();
- assert TreeUtils.isMethodAccess(methodSelect)
- : "Expected a method access, but got: " + methodSelect;
-
- List<? extends ExpressionTree> actualExprs = tree.getArguments();
-
- // Look up method to invoke and possibly throw NullPointerException
- Node receiver = getReceiver(methodSelect, TreeUtils.enclosingClass(getCurrentPath()));
-
- MethodAccessNode target = new MethodAccessNode(methodSelect, receiver);
-
- ExecutableElement element = TreeUtils.elementFromUse(tree);
- if (ElementUtils.isStatic(element) || receiver instanceof ThisLiteralNode) {
- // No NullPointerException can be thrown, use normal node
- extendWithNode(target);
- } else {
- TypeElement npeElement = elements.getTypeElement("java.lang.NullPointerException");
- extendWithNodeWithException(target, npeElement.asType());
- }
-
- List<Node> arguments = new ArrayList<>();
-
- // Don't convert arguments for enum super calls. The AST contains
- // no actual arguments, while the method element expects two arguments,
- // leading to an exception in convertCallArguments. Since no actual
- // arguments are present in the AST that is being checked, it shouldn't
- // cause any harm to omit the conversions.
- // See also BaseTypeVisitor.visitMethodInvocation and
- // QualifierPolymorphism.annotate
- if (!TreeUtils.isEnumSuper(tree)) {
- arguments = convertCallArguments(method, actualExprs);
- }
-
- // TODO: lock the receiver for synchronized methods
-
- MethodInvocationNode node =
- new MethodInvocationNode(tree, target, arguments, getCurrentPath());
-
- Set<TypeMirror> thrownSet = new HashSet<>();
- // Add exceptions explicitly mentioned in the throws clause.
- List<? extends TypeMirror> thrownTypes = element.getThrownTypes();
- thrownSet.addAll(thrownTypes);
- // Add Throwable to account for unchecked exceptions
- TypeElement throwableElement = elements.getTypeElement("java.lang.Throwable");
- thrownSet.add(throwableElement.asType());
-
- ExtendedNode extendedNode = extendWithNodeWithExceptions(node, thrownSet);
-
- /* Check for the TerminatesExecution annotation. */
- Element methodElement = InternalUtils.symbol(tree);
- boolean terminatesExecution =
- annotationProvider.getDeclAnnotation(methodElement, TerminatesExecution.class)
- != null;
- if (terminatesExecution) {
- extendedNode.setTerminatesExecution(true);
- }
-
- return node;
- }
-
- @Override
- public Node visitAssert(AssertTree tree, Void p) {
-
- // see JLS 14.10
-
- // If assertions are enabled, then we can just translate the
- // assertion.
- if (assumeAssertionsEnabled || assumeAssertionsEnabledFor(tree)) {
- translateAssertWithAssertionsEnabled(tree);
- return null;
- }
-
- // If assertions are disabled, then nothing is executed.
- if (assumeAssertionsDisabled) {
- return null;
- }
-
- // Otherwise, we don't know if assertions are enabled, so we use a
- // variable "ea" and case-split on it. One branch does execute the
- // assertion, while the other assumes assertions are disabled.
- VariableTree ea = getAssertionsEnabledVariable();
-
- // all necessary labels
- Label assertionEnabled = new Label();
- Label assertionDisabled = new Label();
-
- extendWithNode(new LocalVariableNode(ea));
- extendWithExtendedNode(new ConditionalJump(assertionEnabled, assertionDisabled));
-
- // 'then' branch (i.e. check the assertion)
- addLabelForNextNode(assertionEnabled);
-
- translateAssertWithAssertionsEnabled(tree);
-
- // 'else' branch
- addLabelForNextNode(assertionDisabled);
-
- return null;
- }
-
- /**
- * Should assertions be assumed to be executed for a given {@link AssertTree}? False by
- * default.
- */
- protected boolean assumeAssertionsEnabledFor(AssertTree tree) {
- return false;
- }
-
- /** The {@link VariableTree} that indicates whether assertions are enabled or not. */
- protected VariableTree ea = null;
-
- /**
- * Get a synthetic {@link VariableTree} that indicates whether assertions are enabled or
- * not.
- */
- protected VariableTree getAssertionsEnabledVariable() {
- if (ea == null) {
- String name = uniqueName("assertionsEnabled");
- MethodTree enclosingMethod = TreeUtils.enclosingMethod(getCurrentPath());
- Element owner;
- if (enclosingMethod != null) {
- owner = TreeUtils.elementFromDeclaration(enclosingMethod);
- } else {
- ClassTree enclosingClass = TreeUtils.enclosingClass(getCurrentPath());
- owner = TreeUtils.elementFromDeclaration(enclosingClass);
- }
- ExpressionTree initializer = null;
- ea =
- treeBuilder.buildVariableDecl(
- types.getPrimitiveType(TypeKind.BOOLEAN), name, owner, initializer);
- }
- return ea;
- }
-
- /**
- * Translates an assertion statement to the correct CFG nodes. The translation assumes that
- * assertions are enabled.
- */
- protected void translateAssertWithAssertionsEnabled(AssertTree tree) {
-
- // all necessary labels
- Label assertEnd = new Label();
- Label elseEntry = new Label();
-
- // basic block for the condition
- Node condition = unbox(scan(tree.getCondition(), null));
- ConditionalJump cjump = new ConditionalJump(assertEnd, elseEntry);
- extendWithExtendedNode(cjump);
-
- // else branch
- Node detail = null;
- addLabelForNextNode(elseEntry);
- if (tree.getDetail() != null) {
- detail = scan(tree.getDetail(), null);
- }
- TypeElement assertException = elements.getTypeElement("java.lang.AssertionError");
- AssertionErrorNode assertNode =
- new AssertionErrorNode(tree, condition, detail, assertException.asType());
- extendWithNode(assertNode);
- NodeWithExceptionsHolder exNode =
- extendWithNodeWithException(
- new ThrowNode(null, assertNode, env.getTypeUtils()),
- assertException.asType());
- exNode.setTerminatesExecution(true);
-
- // then branch (nothing happens)
- addLabelForNextNode(assertEnd);
- }
-
- @Override
- public Node visitAssignment(AssignmentTree tree, Void p) {
-
- // see JLS 15.26.1
-
- AssignmentNode assignmentNode;
- ExpressionTree variable = tree.getVariable();
- TypeMirror varType = InternalUtils.typeOf(variable);
-
- // case 1: field access
- if (TreeUtils.isFieldAccess(variable)) {
- // visit receiver
- Node receiver = getReceiver(variable, TreeUtils.enclosingClass(getCurrentPath()));
-
- // visit expression
- Node expression = scan(tree.getExpression(), p);
- expression = assignConvert(expression, varType);
-
- // visit field access (throws null-pointer exception)
- FieldAccessNode target = new FieldAccessNode(variable, receiver);
- target.setLValue();
-
- Element element = TreeUtils.elementFromUse(variable);
- if (ElementUtils.isStatic(element) || receiver instanceof ThisLiteralNode) {
- // No NullPointerException can be thrown, use normal node
- extendWithNode(target);
- } else {
- TypeElement npeElement =
- elements.getTypeElement("java.lang.NullPointerException");
- extendWithNodeWithException(target, npeElement.asType());
- }
-
- // add assignment node
- assignmentNode = new AssignmentNode(tree, target, expression);
- extendWithNode(assignmentNode);
- }
-
- // case 2: other cases
- else {
- Node target = scan(variable, p);
- target.setLValue();
-
- assignmentNode = translateAssignment(tree, target, tree.getExpression());
- }
-
- return assignmentNode;
- }
-
- /** Translate an assignment. */
- protected AssignmentNode translateAssignment(Tree tree, Node target, ExpressionTree rhs) {
- Node expression = scan(rhs, null);
- return translateAssignment(tree, target, expression);
- }
-
- /** Translate an assignment where the RHS has already been scanned. */
- protected AssignmentNode translateAssignment(Tree tree, Node target, Node expression) {
- assert tree instanceof AssignmentTree || tree instanceof VariableTree;
- target.setLValue();
- expression = assignConvert(expression, target.getType());
- AssignmentNode assignmentNode = new AssignmentNode(tree, target, expression);
- extendWithNode(assignmentNode);
- return assignmentNode;
- }
-
- /**
- * Note 1: Requires {@code tree} to be a field or method access tree.
- *
- * <p>Note 2: Visits the receiver and adds all necessary blocks to the CFG.
- *
- * @param tree the field access tree containing the receiver
- * @param classTree the ClassTree enclosing the field access
- * @return the receiver of the field access
- */
- private Node getReceiver(ExpressionTree tree, ClassTree classTree) {
- assert TreeUtils.isFieldAccess(tree) || TreeUtils.isMethodAccess(tree);
- if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
- MemberSelectTree mtree = (MemberSelectTree) tree;
- return scan(mtree.getExpression(), null);
- } else {
- Element ele = TreeUtils.elementFromUse(tree);
- TypeElement declaringClass = ElementUtils.enclosingClass(ele);
- TypeMirror type = ElementUtils.getType(declaringClass);
- if (ElementUtils.isStatic(ele)) {
- Node node = new ClassNameNode(type, declaringClass);
- extendWithNode(node);
- return node;
- } else {
- Node node = new ImplicitThisLiteralNode(type);
- extendWithNode(node);
- return node;
- }
- }
- }
-
- /**
- * Map an operation with assignment to the corresponding operation without assignment.
- *
- * @param kind a Tree.Kind representing an operation with assignment
- * @return the Tree.Kind for the same operation without assignment
- */
- protected Tree.Kind withoutAssignment(Tree.Kind kind) {
- switch (kind) {
- case DIVIDE_ASSIGNMENT:
- return Tree.Kind.DIVIDE;
- case MULTIPLY_ASSIGNMENT:
- return Tree.Kind.MULTIPLY;
- case REMAINDER_ASSIGNMENT:
- return Tree.Kind.REMAINDER;
- case MINUS_ASSIGNMENT:
- return Tree.Kind.MINUS;
- case PLUS_ASSIGNMENT:
- return Tree.Kind.PLUS;
- case LEFT_SHIFT_ASSIGNMENT:
- return Tree.Kind.LEFT_SHIFT;
- case RIGHT_SHIFT_ASSIGNMENT:
- return Tree.Kind.RIGHT_SHIFT;
- case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
- return Tree.Kind.UNSIGNED_RIGHT_SHIFT;
- case AND_ASSIGNMENT:
- return Tree.Kind.AND;
- case OR_ASSIGNMENT:
- return Tree.Kind.OR;
- case XOR_ASSIGNMENT:
- return Tree.Kind.XOR;
- default:
- return Tree.Kind.ERRONEOUS;
- }
- }
-
- @Override
- public Node visitCompoundAssignment(CompoundAssignmentTree tree, Void p) {
- // According the JLS 15.26.2, E1 op= E2 is equivalent to
- // E1 = (T) ((E1) op (E2)), where T is the type of E1,
- // except that E1 is evaluated only once.
- //
-
- Tree.Kind kind = tree.getKind();
- switch (kind) {
- case DIVIDE_ASSIGNMENT:
- case MULTIPLY_ASSIGNMENT:
- case REMAINDER_ASSIGNMENT:
- {
- // see JLS 15.17 and 15.26.2
- Node targetLHS = scan(tree.getVariable(), p);
- Node value = scan(tree.getExpression(), p);
-
- TypeMirror exprType = InternalUtils.typeOf(tree);
- TypeMirror leftType = InternalUtils.typeOf(tree.getVariable());
- TypeMirror rightType = InternalUtils.typeOf(tree.getExpression());
- TypeMirror promotedType = binaryPromotedType(leftType, rightType);
- Node targetRHS = binaryNumericPromotion(targetLHS, promotedType);
- value = binaryNumericPromotion(value, promotedType);
-
- BinaryTree operTree =
- treeBuilder.buildBinary(
- promotedType,
- withoutAssignment(kind),
- tree.getVariable(),
- tree.getExpression());
- handleArtificialTree(operTree);
- Node operNode;
- if (kind == Tree.Kind.MULTIPLY_ASSIGNMENT) {
- operNode = new NumericalMultiplicationNode(operTree, targetRHS, value);
- } else if (kind == Tree.Kind.DIVIDE_ASSIGNMENT) {
- if (TypesUtils.isIntegral(exprType)) {
- operNode = new IntegerDivisionNode(operTree, targetRHS, value);
- } else {
- operNode = new FloatingDivisionNode(operTree, targetRHS, value);
- }
- } else {
- assert kind == Kind.REMAINDER_ASSIGNMENT;
- if (TypesUtils.isIntegral(exprType)) {
- operNode = new IntegerRemainderNode(operTree, targetRHS, value);
- } else {
- operNode = new FloatingRemainderNode(operTree, targetRHS, value);
- }
- }
- extendWithNode(operNode);
-
- TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
- handleArtificialTree(castTree);
- TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType);
- castNode.setInSource(false);
- extendWithNode(castNode);
-
- AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
- extendWithNode(assignNode);
- return assignNode;
- }
-
- case MINUS_ASSIGNMENT:
- case PLUS_ASSIGNMENT:
- {
- // see JLS 15.18 and 15.26.2
-
- Node targetLHS = scan(tree.getVariable(), p);
- Node value = scan(tree.getExpression(), p);
-
- TypeMirror leftType = InternalUtils.typeOf(tree.getVariable());
- TypeMirror rightType = InternalUtils.typeOf(tree.getExpression());
-
- if (TypesUtils.isString(leftType) || TypesUtils.isString(rightType)) {
- assert (kind == Tree.Kind.PLUS_ASSIGNMENT);
- Node targetRHS = stringConversion(targetLHS);
- value = stringConversion(value);
- Node r = new StringConcatenateAssignmentNode(tree, targetRHS, value);
- extendWithNode(r);
- return r;
- } else {
- TypeMirror promotedType = binaryPromotedType(leftType, rightType);
- Node targetRHS = binaryNumericPromotion(targetLHS, promotedType);
- value = binaryNumericPromotion(value, promotedType);
-
- BinaryTree operTree =
- treeBuilder.buildBinary(
- promotedType,
- withoutAssignment(kind),
- tree.getVariable(),
- tree.getExpression());
- handleArtificialTree(operTree);
- Node operNode;
- if (kind == Tree.Kind.PLUS_ASSIGNMENT) {
- operNode = new NumericalAdditionNode(operTree, targetRHS, value);
- } else {
- assert kind == Kind.MINUS_ASSIGNMENT;
- operNode = new NumericalSubtractionNode(operTree, targetRHS, value);
- }
- extendWithNode(operNode);
-
- TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
- handleArtificialTree(castTree);
- TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType);
- castNode.setInSource(false);
- extendWithNode(castNode);
-
- // Map the compound assignment tree to an assignment node, which
- // will have the correct type.
- AssignmentNode assignNode =
- new AssignmentNode(tree, targetLHS, castNode);
- extendWithNode(assignNode);
- return assignNode;
- }
- }
-
- case LEFT_SHIFT_ASSIGNMENT:
- case RIGHT_SHIFT_ASSIGNMENT:
- case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
- {
- // see JLS 15.19 and 15.26.2
- Node targetLHS = scan(tree.getVariable(), p);
- Node value = scan(tree.getExpression(), p);
-
- TypeMirror leftType = InternalUtils.typeOf(tree.getVariable());
-
- Node targetRHS = unaryNumericPromotion(targetLHS);
- value = unaryNumericPromotion(value);
-
- BinaryTree operTree =
- treeBuilder.buildBinary(
- leftType,
- withoutAssignment(kind),
- tree.getVariable(),
- tree.getExpression());
- handleArtificialTree(operTree);
- Node operNode;
- if (kind == Tree.Kind.LEFT_SHIFT_ASSIGNMENT) {
- operNode = new LeftShiftNode(operTree, targetRHS, value);
- } else if (kind == Tree.Kind.RIGHT_SHIFT_ASSIGNMENT) {
- operNode = new SignedRightShiftNode(operTree, targetRHS, value);
- } else {
- assert kind == Kind.UNSIGNED_RIGHT_SHIFT_ASSIGNMENT;
- operNode = new UnsignedRightShiftNode(operTree, targetRHS, value);
- }
- extendWithNode(operNode);
-
- TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
- handleArtificialTree(castTree);
- TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType);
- castNode.setInSource(false);
- extendWithNode(castNode);
-
- AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
- extendWithNode(assignNode);
- return assignNode;
- }
-
- case AND_ASSIGNMENT:
- case OR_ASSIGNMENT:
- case XOR_ASSIGNMENT:
- // see JLS 15.22
- Node targetLHS = scan(tree.getVariable(), p);
- Node value = scan(tree.getExpression(), p);
-
- TypeMirror leftType = InternalUtils.typeOf(tree.getVariable());
- TypeMirror rightType = InternalUtils.typeOf(tree.getExpression());
-
- Node targetRHS = null;
- if (isNumericOrBoxed(leftType) && isNumericOrBoxed(rightType)) {
- TypeMirror promotedType = binaryPromotedType(leftType, rightType);
- targetRHS = binaryNumericPromotion(targetLHS, promotedType);
- value = binaryNumericPromotion(value, promotedType);
- } else if (TypesUtils.isBooleanType(leftType)
- && TypesUtils.isBooleanType(rightType)) {
- targetRHS = unbox(targetLHS);
- value = unbox(value);
- } else {
- assert false
- : "Both argument to logical operation must be numeric or boolean";
- }
-
- BinaryTree operTree =
- treeBuilder.buildBinary(
- leftType,
- withoutAssignment(kind),
- tree.getVariable(),
- tree.getExpression());
- handleArtificialTree(operTree);
- Node operNode;
- if (kind == Tree.Kind.AND_ASSIGNMENT) {
- operNode = new BitwiseAndNode(operTree, targetRHS, value);
- } else if (kind == Tree.Kind.OR_ASSIGNMENT) {
- operNode = new BitwiseOrNode(operTree, targetRHS, value);
- } else {
- assert kind == Kind.XOR_ASSIGNMENT;
- operNode = new BitwiseXorNode(operTree, targetRHS, value);
- }
- extendWithNode(operNode);
-
- TypeCastTree castTree = treeBuilder.buildTypeCast(leftType, operTree);
- handleArtificialTree(castTree);
- TypeCastNode castNode = new TypeCastNode(castTree, operNode, leftType);
- castNode.setInSource(false);
- extendWithNode(castNode);
-
- AssignmentNode assignNode = new AssignmentNode(tree, targetLHS, castNode);
- extendWithNode(assignNode);
- return assignNode;
- default:
- assert false : "unexpected compound assignment type";
- break;
- }
- assert false : "unexpected compound assignment type";
- return null;
- }
-
- @Override
- public Node visitBinary(BinaryTree tree, Void p) {
- // Note that for binary operations it is important to perform any required
- // promotion on the left operand before generating any Nodes for the right
- // operand, because labels must be inserted AFTER ALL preceding Nodes and
- // BEFORE ALL following Nodes.
- Node r = null;
- Tree leftTree = tree.getLeftOperand();
- Tree rightTree = tree.getRightOperand();
-
- Tree.Kind kind = tree.getKind();
- switch (kind) {
- case DIVIDE:
- case MULTIPLY:
- case REMAINDER:
- {
- // see JLS 15.17
-
- TypeMirror exprType = InternalUtils.typeOf(tree);
- TypeMirror leftType = InternalUtils.typeOf(leftTree);
- TypeMirror rightType = InternalUtils.typeOf(rightTree);
- TypeMirror promotedType = binaryPromotedType(leftType, rightType);
-
- Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
- Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
-
- if (kind == Tree.Kind.MULTIPLY) {
- r = new NumericalMultiplicationNode(tree, left, right);
- } else if (kind == Tree.Kind.DIVIDE) {
- if (TypesUtils.isIntegral(exprType)) {
- r = new IntegerDivisionNode(tree, left, right);
- } else {
- r = new FloatingDivisionNode(tree, left, right);
- }
- } else {
- assert kind == Kind.REMAINDER;
- if (TypesUtils.isIntegral(exprType)) {
- r = new IntegerRemainderNode(tree, left, right);
- } else {
- r = new FloatingRemainderNode(tree, left, right);
- }
- }
- break;
- }
-
- case MINUS:
- case PLUS:
- {
- // see JLS 15.18
-
- // TypeMirror exprType = InternalUtils.typeOf(tree);
- TypeMirror leftType = InternalUtils.typeOf(leftTree);
- TypeMirror rightType = InternalUtils.typeOf(rightTree);
-
- if (TypesUtils.isString(leftType) || TypesUtils.isString(rightType)) {
- assert (kind == Tree.Kind.PLUS);
- Node left = stringConversion(scan(leftTree, p));
- Node right = stringConversion(scan(rightTree, p));
- r = new StringConcatenateNode(tree, left, right);
- } else {
- TypeMirror promotedType = binaryPromotedType(leftType, rightType);
- Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
- Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
-
- // TODO: Decide whether to deal with floating-point value
- // set conversion.
- if (kind == Tree.Kind.PLUS) {
- r = new NumericalAdditionNode(tree, left, right);
- } else {
- assert kind == Kind.MINUS;
- r = new NumericalSubtractionNode(tree, left, right);
- }
- }
- break;
- }
-
- case LEFT_SHIFT:
- case RIGHT_SHIFT:
- case UNSIGNED_RIGHT_SHIFT:
- {
- // see JLS 15.19
-
- Node left = unaryNumericPromotion(scan(leftTree, p));
- Node right = unaryNumericPromotion(scan(rightTree, p));
-
- if (kind == Tree.Kind.LEFT_SHIFT) {
- r = new LeftShiftNode(tree, left, right);
- } else if (kind == Tree.Kind.RIGHT_SHIFT) {
- r = new SignedRightShiftNode(tree, left, right);
- } else {
- assert kind == Kind.UNSIGNED_RIGHT_SHIFT;
- r = new UnsignedRightShiftNode(tree, left, right);
- }
- break;
- }
-
- case GREATER_THAN:
- case GREATER_THAN_EQUAL:
- case LESS_THAN:
- case LESS_THAN_EQUAL:
- {
- // see JLS 15.20.1
- TypeMirror leftType = InternalUtils.typeOf(leftTree);
- if (TypesUtils.isBoxedPrimitive(leftType)) {
- leftType = types.unboxedType(leftType);
- }
-
- TypeMirror rightType = InternalUtils.typeOf(rightTree);
- if (TypesUtils.isBoxedPrimitive(rightType)) {
- rightType = types.unboxedType(rightType);
- }
-
- TypeMirror promotedType = binaryPromotedType(leftType, rightType);
- Node left = binaryNumericPromotion(scan(leftTree, p), promotedType);
- Node right = binaryNumericPromotion(scan(rightTree, p), promotedType);
-
- Node node;
- if (kind == Tree.Kind.GREATER_THAN) {
- node = new GreaterThanNode(tree, left, right);
- } else if (kind == Tree.Kind.GREATER_THAN_EQUAL) {
- node = new GreaterThanOrEqualNode(tree, left, right);
- } else if (kind == Tree.Kind.LESS_THAN) {
- node = new LessThanNode(tree, left, right);
- } else {
- assert kind == Tree.Kind.LESS_THAN_EQUAL;
- node = new LessThanOrEqualNode(tree, left, right);
- }
-
- extendWithNode(node);
-
- return node;
- }
-
- case EQUAL_TO:
- case NOT_EQUAL_TO:
- {
- // see JLS 15.21
- TreeInfo leftInfo = getTreeInfo(leftTree);
- TreeInfo rightInfo = getTreeInfo(rightTree);
- Node left = scan(leftTree, p);
- Node right = scan(rightTree, p);
-
- if (leftInfo.isNumeric()
- && rightInfo.isNumeric()
- && !(leftInfo.isBoxed() && rightInfo.isBoxed())) {
- // JLS 15.21.1 numerical equality
- TypeMirror promotedType =
- binaryPromotedType(
- leftInfo.unboxedType(), rightInfo.unboxedType());
- left = binaryNumericPromotion(left, promotedType);
- right = binaryNumericPromotion(right, promotedType);
- } else if (leftInfo.isBoolean()
- && rightInfo.isBoolean()
- && !(leftInfo.isBoxed() && rightInfo.isBoxed())) {
- // JSL 15.21.2 boolean equality
- left = unboxAsNeeded(left, leftInfo.isBoxed());
- right = unboxAsNeeded(right, rightInfo.isBoxed());
- }
-
- Node node;
- if (kind == Tree.Kind.EQUAL_TO) {
- node = new EqualToNode(tree, left, right);
- } else {
- assert kind == Kind.NOT_EQUAL_TO;
- node = new NotEqualNode(tree, left, right);
- }
- extendWithNode(node);
-
- return node;
- }
-
- case AND:
- case OR:
- case XOR:
- {
- // see JLS 15.22
- TypeMirror leftType = InternalUtils.typeOf(leftTree);
- TypeMirror rightType = InternalUtils.typeOf(rightTree);
- boolean isBooleanOp =
- TypesUtils.isBooleanType(leftType)
- && TypesUtils.isBooleanType(rightType);
-
- Node left;
- Node right;
-
- if (isBooleanOp) {
- left = unbox(scan(leftTree, p));
- right = unbox(scan(rightTree, p));
- } else if (isNumericOrBoxed(leftType) && isNumericOrBoxed(rightType)) {
- TypeMirror promotedType = binaryPromotedType(leftType, rightType);
- left = binaryNumericPromotion(scan(leftTree, p), promotedType);
- right = binaryNumericPromotion(scan(rightTree, p), promotedType);
- } else {
- left = unbox(scan(leftTree, p));
- right = unbox(scan(rightTree, p));
- }
-
- Node node;
- if (kind == Tree.Kind.AND) {
- node = new BitwiseAndNode(tree, left, right);
- } else if (kind == Tree.Kind.OR) {
- node = new BitwiseOrNode(tree, left, right);
- } else {
- assert kind == Kind.XOR;
- node = new BitwiseXorNode(tree, left, right);
- }
-
- extendWithNode(node);
-
- return node;
- }
-
- case CONDITIONAL_AND:
- case CONDITIONAL_OR:
- {
- // see JLS 15.23 and 15.24
-
- // all necessary labels
- Label rightStartL = new Label();
- Label shortCircuitL = new Label();
-
- // left-hand side
- Node left = scan(leftTree, p);
-
- ConditionalJump cjump;
- if (kind == Tree.Kind.CONDITIONAL_AND) {
- cjump = new ConditionalJump(rightStartL, shortCircuitL);
- cjump.setFalseFlowRule(Store.FlowRule.ELSE_TO_ELSE);
- } else {
- cjump = new ConditionalJump(shortCircuitL, rightStartL);
- cjump.setTrueFlowRule(Store.FlowRule.THEN_TO_THEN);
- }
- extendWithExtendedNode(cjump);
-
- // right-hand side
- addLabelForNextNode(rightStartL);
- Node right = scan(rightTree, p);
-
- // conditional expression itself
- addLabelForNextNode(shortCircuitL);
- Node node;
- if (kind == Tree.Kind.CONDITIONAL_AND) {
- node = new ConditionalAndNode(tree, left, right);
- } else {
- node = new ConditionalOrNode(tree, left, right);
- }
- extendWithNode(node);
- return node;
- }
- default:
- assert false : "unexpected binary tree: " + kind;
- break;
- }
- assert r != null : "unexpected binary tree";
- return extendWithNode(r);
- }
-
- @Override
- public Node visitBlock(BlockTree tree, Void p) {
- for (StatementTree n : tree.getStatements()) {
- scan(n, null);
- }
- return null;
- }
-
- @Override
- public Node visitBreak(BreakTree tree, Void p) {
- Name label = tree.getLabel();
- if (label == null) {
- assert breakTargetL != null : "no target for break statement";
-
- extendWithExtendedNode(new UnconditionalJump(breakTargetL));
- } else {
- assert breakLabels.containsKey(label);
-
- extendWithExtendedNode(new UnconditionalJump(breakLabels.get(label)));
- }
-
- return null;
- }
-
- @Override
- public Node visitSwitch(SwitchTree tree, Void p) {
- SwitchBuilder builder = new SwitchBuilder(tree, p);
- builder.build();
- return null;
- }
-
- private class SwitchBuilder {
- private final SwitchTree switchTree;
- private final Label[] caseBodyLabels;
- private final Void p;
- private Node switchExpr;
-
- private SwitchBuilder(SwitchTree tree, Void p) {
- this.switchTree = tree;
- this.caseBodyLabels = new Label[switchTree.getCases().size() + 1];
- this.p = p;
- }
-
- public void build() {
- Label oldBreakTargetL = breakTargetL;
- breakTargetL = new Label();
- int cases = caseBodyLabels.length - 1;
- for (int i = 0; i < cases; ++i) {
- caseBodyLabels[i] = new Label();
- }
- caseBodyLabels[cases] = breakTargetL;
-
- switchExpr = unbox(scan(switchTree.getExpression(), p));
- extendWithNode(
- new MarkerNode(
- switchTree, "start of switch statement", env.getTypeUtils()));
-
- Integer defaultIndex = null;
- for (int i = 0; i < cases; ++i) {
- CaseTree caseTree = switchTree.getCases().get(i);
- if (caseTree.getExpression() == null) {
- defaultIndex = i;
- } else {
- buildCase(caseTree, i);
- }
- }
- if (defaultIndex != null) {
- // the checks of all cases must happen before the default case,
- // therefore we build the default case last.
- // fallthrough is still handled correctly with the caseBodyLabels.
- buildCase(switchTree.getCases().get(defaultIndex), defaultIndex);
- }
-
- addLabelForNextNode(breakTargetL);
- breakTargetL = oldBreakTargetL;
- }
-
- private void buildCase(CaseTree tree, int index) {
- final Label thisBodyL = caseBodyLabels[index];
- final Label nextBodyL = caseBodyLabels[index + 1];
- final Label nextCaseL = new Label();
-
- ExpressionTree exprTree = tree.getExpression();
- if (exprTree != null) {
- Node expr = scan(exprTree, p);
- CaseNode test = new CaseNode(tree, switchExpr, expr, env.getTypeUtils());
- extendWithNode(test);
- extendWithExtendedNode(new ConditionalJump(thisBodyL, nextCaseL));
- }
- addLabelForNextNode(thisBodyL);
- for (StatementTree stmt : tree.getStatements()) {
- scan(stmt, p);
- }
- extendWithExtendedNode(new UnconditionalJump(nextBodyL));
- addLabelForNextNode(nextCaseL);
- }
- }
-
- @Override
- public Node visitCase(CaseTree tree, Void p) {
- throw new AssertionError("case visitor is implemented in SwitchBuilder");
- }
-
- @Override
- public Node visitCatch(CatchTree tree, Void p) {
- scan(tree.getParameter(), p);
- scan(tree.getBlock(), p);
- return null;
- }
-
- @Override
- public Node visitClass(ClassTree tree, Void p) {
- declaredClasses.add(tree);
- return null;
- }
-
- @Override
- public Node visitConditionalExpression(ConditionalExpressionTree tree, Void p) {
- // see JLS 15.25
- TypeMirror exprType = InternalUtils.typeOf(tree);
-
- Label trueStart = new Label();
- Label falseStart = new Label();
- Label merge = new Label();
-
- Node condition = unbox(scan(tree.getCondition(), p));
- ConditionalJump cjump = new ConditionalJump(trueStart, falseStart);
- extendWithExtendedNode(cjump);
-
- addLabelForNextNode(trueStart);
- Node trueExpr = scan(tree.getTrueExpression(), p);
- trueExpr = conditionalExprPromotion(trueExpr, exprType);
- extendWithExtendedNode(new UnconditionalJump(merge));
-
- addLabelForNextNode(falseStart);
- Node falseExpr = scan(tree.getFalseExpression(), p);
- falseExpr = conditionalExprPromotion(falseExpr, exprType);
-
- addLabelForNextNode(merge);
- Node node = new TernaryExpressionNode(tree, condition, trueExpr, falseExpr);
- extendWithNode(node);
-
- return node;
- }
-
- @Override
- public Node visitContinue(ContinueTree tree, Void p) {
- Name label = tree.getLabel();
- if (label == null) {
- assert continueTargetL != null : "no target for continue statement";
-
- extendWithExtendedNode(new UnconditionalJump(continueTargetL));
- } else {
- assert continueLabels.containsKey(label);
-
- extendWithExtendedNode(new UnconditionalJump(continueLabels.get(label)));
- }
-
- return null;
- }
-
- @Override
- public Node visitDoWhileLoop(DoWhileLoopTree tree, Void p) {
- Name parentLabel = getLabel(getCurrentPath());
-
- Label loopEntry = new Label();
- Label loopExit = new Label();
-
- // If the loop is a labeled statement, then its continue
- // target is identical for continues with no label and
- // continues with the loop's label.
- Label conditionStart;
- if (parentLabel != null) {
- conditionStart = continueLabels.get(parentLabel);
- } else {
- conditionStart = new Label();
- }
-
- Label oldBreakTargetL = breakTargetL;
- breakTargetL = loopExit;
-
- Label oldContinueTargetL = continueTargetL;
- continueTargetL = conditionStart;
-
- // Loop body
- addLabelForNextNode(loopEntry);
- if (tree.getStatement() != null) {
- scan(tree.getStatement(), p);
- }
-
- // Condition
- addLabelForNextNode(conditionStart);
- if (tree.getCondition() != null) {
- unbox(scan(tree.getCondition(), p));
- ConditionalJump cjump = new ConditionalJump(loopEntry, loopExit);
- extendWithExtendedNode(cjump);
- }
-
- // Loop exit
- addLabelForNextNode(loopExit);
-
- breakTargetL = oldBreakTargetL;
- continueTargetL = oldContinueTargetL;
-
- return null;
- }
-
- @Override
- public Node visitErroneous(ErroneousTree tree, Void p) {
- assert false : "ErroneousTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitExpressionStatement(ExpressionStatementTree tree, Void p) {
- return scan(tree.getExpression(), p);
- }
-
- @Override
- public Node visitEnhancedForLoop(EnhancedForLoopTree tree, Void p) {
- // see JLS 14.14.2
- Name parentLabel = getLabel(getCurrentPath());
-
- Label conditionStart = new Label();
- Label loopEntry = new Label();
- Label loopExit = new Label();
-
- // If the loop is a labeled statement, then its continue
- // target is identical for continues with no label and
- // continues with the loop's label.
- Label updateStart;
- if (parentLabel != null) {
- updateStart = continueLabels.get(parentLabel);
- } else {
- updateStart = new Label();
- }
-
- Label oldBreakTargetL = breakTargetL;
- breakTargetL = loopExit;
-
- Label oldContinueTargetL = continueTargetL;
- continueTargetL = updateStart;
-
- // Distinguish loops over Iterables from loops over arrays.
-
- TypeElement iterableElement = elements.getTypeElement("java.lang.Iterable");
- TypeMirror iterableType = types.erasure(iterableElement.asType());
-
- VariableTree variable = tree.getVariable();
- VariableElement variableElement = TreeUtils.elementFromDeclaration(variable);
- ExpressionTree expression = tree.getExpression();
- StatementTree statement = tree.getStatement();
-
- TypeMirror exprType = InternalUtils.typeOf(expression);
-
- if (types.isSubtype(exprType, iterableType)) {
- // Take the upper bound of a type variable or wildcard
- exprType = TypesUtils.upperBound(exprType);
-
- assert (exprType instanceof DeclaredType) : "an Iterable must be a DeclaredType";
- DeclaredType declaredExprType = (DeclaredType) exprType;
- declaredExprType.getTypeArguments();
-
- MemberSelectTree iteratorSelect = treeBuilder.buildIteratorMethodAccess(expression);
- handleArtificialTree(iteratorSelect);
-
- MethodInvocationTree iteratorCall =
- treeBuilder.buildMethodInvocation(iteratorSelect);
- handleArtificialTree(iteratorCall);
-
- VariableTree iteratorVariable =
- createEnhancedForLoopIteratorVariable(iteratorCall, variableElement);
- handleArtificialTree(iteratorVariable);
-
- VariableDeclarationNode iteratorVariableDecl =
- new VariableDeclarationNode(iteratorVariable);
- iteratorVariableDecl.setInSource(false);
-
- extendWithNode(iteratorVariableDecl);
-
- Node expressionNode = scan(expression, p);
-
- MethodAccessNode iteratorAccessNode =
- new MethodAccessNode(iteratorSelect, expressionNode);
- iteratorAccessNode.setInSource(false);
- extendWithNode(iteratorAccessNode);
- MethodInvocationNode iteratorCallNode =
- new MethodInvocationNode(
- iteratorCall,
- iteratorAccessNode,
- Collections.<Node>emptyList(),
- getCurrentPath());
- iteratorCallNode.setInSource(false);
- extendWithNode(iteratorCallNode);
-
- translateAssignment(
- iteratorVariable,
- new LocalVariableNode(iteratorVariable),
- iteratorCallNode);
-
- // Test the loop ending condition
- addLabelForNextNode(conditionStart);
- IdentifierTree iteratorUse1 = treeBuilder.buildVariableUse(iteratorVariable);
- handleArtificialTree(iteratorUse1);
-
- LocalVariableNode iteratorReceiverNode = new LocalVariableNode(iteratorUse1);
- iteratorReceiverNode.setInSource(false);
- extendWithNode(iteratorReceiverNode);
-
- MemberSelectTree hasNextSelect = treeBuilder.buildHasNextMethodAccess(iteratorUse1);
- handleArtificialTree(hasNextSelect);
-
- MethodAccessNode hasNextAccessNode =
- new MethodAccessNode(hasNextSelect, iteratorReceiverNode);
- hasNextAccessNode.setInSource(false);
- extendWithNode(hasNextAccessNode);
-
- MethodInvocationTree hasNextCall = treeBuilder.buildMethodInvocation(hasNextSelect);
- handleArtificialTree(hasNextCall);
-
- MethodInvocationNode hasNextCallNode =
- new MethodInvocationNode(
- hasNextCall,
- hasNextAccessNode,
- Collections.<Node>emptyList(),
- getCurrentPath());
- hasNextCallNode.setInSource(false);
- extendWithNode(hasNextCallNode);
- extendWithExtendedNode(new ConditionalJump(loopEntry, loopExit));
-
- // Loop body, starting with declaration of the loop iteration variable
- addLabelForNextNode(loopEntry);
- extendWithNode(new VariableDeclarationNode(variable));
-
- IdentifierTree iteratorUse2 = treeBuilder.buildVariableUse(iteratorVariable);
- handleArtificialTree(iteratorUse2);
-
- LocalVariableNode iteratorReceiverNode2 = new LocalVariableNode(iteratorUse2);
- iteratorReceiverNode2.setInSource(false);
- extendWithNode(iteratorReceiverNode2);
-
- MemberSelectTree nextSelect = treeBuilder.buildNextMethodAccess(iteratorUse2);
- handleArtificialTree(nextSelect);
-
- MethodAccessNode nextAccessNode =
- new MethodAccessNode(nextSelect, iteratorReceiverNode2);
- nextAccessNode.setInSource(false);
- extendWithNode(nextAccessNode);
-
- MethodInvocationTree nextCall = treeBuilder.buildMethodInvocation(nextSelect);
- handleArtificialTree(nextCall);
-
- MethodInvocationNode nextCallNode =
- new MethodInvocationNode(
- nextCall,
- nextAccessNode,
- Collections.<Node>emptyList(),
- getCurrentPath());
- nextCallNode.setInSource(false);
- extendWithNode(nextCallNode);
-
- translateAssignment(variable, new LocalVariableNode(variable), nextCall);
-
- if (statement != null) {
- scan(statement, p);
- }
-
- // Loop back edge
- addLabelForNextNode(updateStart);
- extendWithExtendedNode(new UnconditionalJump(conditionStart));
-
- } else {
- // TODO: Shift any labels after the initialization of the
- // temporary array variable.
-
- VariableTree arrayVariable =
- createEnhancedForLoopArrayVariable(expression, variableElement);
- handleArtificialTree(arrayVariable);
-
- VariableDeclarationNode arrayVariableNode =
- new VariableDeclarationNode(arrayVariable);
- arrayVariableNode.setInSource(false);
- extendWithNode(arrayVariableNode);
- Node expressionNode = scan(expression, p);
-
- translateAssignment(
- arrayVariable, new LocalVariableNode(arrayVariable), expressionNode);
-
- // Declare and initialize the loop index variable
- TypeMirror intType = types.getPrimitiveType(TypeKind.INT);
-
- LiteralTree zero = treeBuilder.buildLiteral(Integer.valueOf(0));
- handleArtificialTree(zero);
-
- VariableTree indexVariable =
- treeBuilder.buildVariableDecl(
- intType,
- uniqueName("index"),
- variableElement.getEnclosingElement(),
- zero);
- handleArtificialTree(indexVariable);
- VariableDeclarationNode indexVariableNode =
- new VariableDeclarationNode(indexVariable);
- indexVariableNode.setInSource(false);
- extendWithNode(indexVariableNode);
- IntegerLiteralNode zeroNode = extendWithNode(new IntegerLiteralNode(zero));
-
- translateAssignment(indexVariable, new LocalVariableNode(indexVariable), zeroNode);
-
- // Compare index to array length
- addLabelForNextNode(conditionStart);
- IdentifierTree indexUse1 = treeBuilder.buildVariableUse(indexVariable);
- handleArtificialTree(indexUse1);
- LocalVariableNode indexNode1 = new LocalVariableNode(indexUse1);
- indexNode1.setInSource(false);
- extendWithNode(indexNode1);
-
- IdentifierTree arrayUse1 = treeBuilder.buildVariableUse(arrayVariable);
- handleArtificialTree(arrayUse1);
- LocalVariableNode arrayNode1 = extendWithNode(new LocalVariableNode(arrayUse1));
-
- MemberSelectTree lengthSelect = treeBuilder.buildArrayLengthAccess(arrayUse1);
- handleArtificialTree(lengthSelect);
- FieldAccessNode lengthAccessNode = new FieldAccessNode(lengthSelect, arrayNode1);
- lengthAccessNode.setInSource(false);
- extendWithNode(lengthAccessNode);
-
- BinaryTree lessThan = treeBuilder.buildLessThan(indexUse1, lengthSelect);
- handleArtificialTree(lessThan);
-
- LessThanNode lessThanNode =
- new LessThanNode(lessThan, indexNode1, lengthAccessNode);
- lessThanNode.setInSource(false);
- extendWithNode(lessThanNode);
- extendWithExtendedNode(new ConditionalJump(loopEntry, loopExit));
-
- // Loop body, starting with declaration of the loop iteration variable
- addLabelForNextNode(loopEntry);
- extendWithNode(new VariableDeclarationNode(variable));
-
- IdentifierTree arrayUse2 = treeBuilder.buildVariableUse(arrayVariable);
- handleArtificialTree(arrayUse2);
- LocalVariableNode arrayNode2 = new LocalVariableNode(arrayUse2);
- arrayNode2.setInSource(false);
- extendWithNode(arrayNode2);
-
- IdentifierTree indexUse2 = treeBuilder.buildVariableUse(indexVariable);
- handleArtificialTree(indexUse2);
- LocalVariableNode indexNode2 = new LocalVariableNode(indexUse2);
- indexNode2.setInSource(false);
- extendWithNode(indexNode2);
-
- ArrayAccessTree arrayAccess = treeBuilder.buildArrayAccess(arrayUse2, indexUse2);
- handleArtificialTree(arrayAccess);
- ArrayAccessNode arrayAccessNode =
- new ArrayAccessNode(arrayAccess, arrayNode2, indexNode2);
- arrayAccessNode.setInSource(false);
- extendWithNode(arrayAccessNode);
- translateAssignment(variable, new LocalVariableNode(variable), arrayAccessNode);
-
- if (statement != null) {
- scan(statement, p);
- }
-
- // Loop back edge
- addLabelForNextNode(updateStart);
-
- IdentifierTree indexUse3 = treeBuilder.buildVariableUse(indexVariable);
- handleArtificialTree(indexUse3);
- LocalVariableNode indexNode3 = new LocalVariableNode(indexUse3);
- indexNode3.setInSource(false);
- extendWithNode(indexNode3);
-
- LiteralTree oneTree = treeBuilder.buildLiteral(Integer.valueOf(1));
- handleArtificialTree(oneTree);
- Node one = new IntegerLiteralNode(oneTree);
- one.setInSource(false);
- extendWithNode(one);
-
- BinaryTree addOneTree =
- treeBuilder.buildBinary(intType, Tree.Kind.PLUS, indexUse3, oneTree);
- handleArtificialTree(addOneTree);
- Node addOneNode = new NumericalAdditionNode(addOneTree, indexNode3, one);
- addOneNode.setInSource(false);
- extendWithNode(addOneNode);
-
- AssignmentTree assignTree = treeBuilder.buildAssignment(indexUse3, addOneTree);
- handleArtificialTree(assignTree);
- Node assignNode = new AssignmentNode(assignTree, indexNode3, addOneNode);
- assignNode.setInSource(false);
- extendWithNode(assignNode);
-
- extendWithExtendedNode(new UnconditionalJump(conditionStart));
- }
-
- // Loop exit
- addLabelForNextNode(loopExit);
-
- breakTargetL = oldBreakTargetL;
- continueTargetL = oldContinueTargetL;
-
- return null;
- }
-
- protected VariableTree createEnhancedForLoopIteratorVariable(
- MethodInvocationTree iteratorCall, VariableElement variableElement) {
- TypeMirror iteratorType = InternalUtils.typeOf(iteratorCall);
-
- // Declare and initialize a new, unique iterator variable
- VariableTree iteratorVariable =
- treeBuilder.buildVariableDecl(
- iteratorType, // annotatedIteratorTypeTree,
- uniqueName("iter"),
- variableElement.getEnclosingElement(),
- iteratorCall);
- return iteratorVariable;
- }
-
- protected VariableTree createEnhancedForLoopArrayVariable(
- ExpressionTree expression, VariableElement variableElement) {
- TypeMirror arrayType = InternalUtils.typeOf(expression);
-
- // Declare and initialize a temporary array variable
- VariableTree arrayVariable =
- treeBuilder.buildVariableDecl(
- arrayType,
- uniqueName("array"),
- variableElement.getEnclosingElement(),
- expression);
- return arrayVariable;
- }
-
- @Override
- public Node visitForLoop(ForLoopTree tree, Void p) {
- Name parentLabel = getLabel(getCurrentPath());
-
- Label conditionStart = new Label();
- Label loopEntry = new Label();
- Label loopExit = new Label();
-
- // If the loop is a labeled statement, then its continue
- // target is identical for continues with no label and
- // continues with the loop's label.
- Label updateStart;
- if (parentLabel != null) {
- updateStart = continueLabels.get(parentLabel);
- } else {
- updateStart = new Label();
- }
-
- Label oldBreakTargetL = breakTargetL;
- breakTargetL = loopExit;
-
- Label oldContinueTargetL = continueTargetL;
- continueTargetL = updateStart;
-
- // Initializer
- for (StatementTree init : tree.getInitializer()) {
- scan(init, p);
- }
-
- // Condition
- addLabelForNextNode(conditionStart);
- if (tree.getCondition() != null) {
- unbox(scan(tree.getCondition(), p));
- ConditionalJump cjump = new ConditionalJump(loopEntry, loopExit);
- extendWithExtendedNode(cjump);
- }
-
- // Loop body
- addLabelForNextNode(loopEntry);
- if (tree.getStatement() != null) {
- scan(tree.getStatement(), p);
- }
-
- // Update
- addLabelForNextNode(updateStart);
- for (ExpressionStatementTree update : tree.getUpdate()) {
- scan(update, p);
- }
-
- extendWithExtendedNode(new UnconditionalJump(conditionStart));
-
- // Loop exit
- addLabelForNextNode(loopExit);
-
- breakTargetL = oldBreakTargetL;
- continueTargetL = oldContinueTargetL;
-
- return null;
- }
-
- @Override
- public Node visitIdentifier(IdentifierTree tree, Void p) {
- Node node;
- if (TreeUtils.isFieldAccess(tree)) {
- Node receiver = getReceiver(tree, TreeUtils.enclosingClass(getCurrentPath()));
- node = new FieldAccessNode(tree, receiver);
- } else {
- Element element = TreeUtils.elementFromUse(tree);
- switch (element.getKind()) {
- case ANNOTATION_TYPE:
- case CLASS:
- case ENUM:
- case INTERFACE:
- case TYPE_PARAMETER:
- node = new ClassNameNode(tree);
- break;
- case FIELD:
- // Note that "this"/"super" is a field, but not a field access.
- if (element.getSimpleName().contentEquals("this")) {
- node = new ExplicitThisLiteralNode(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:
- throw new IllegalArgumentException(
- "unexpected element kind : " + element.getKind());
- }
- }
- extendWithNode(node);
- return node;
- }
-
- @Override
- public Node visitIf(IfTree tree, Void p) {
- // all necessary labels
- Label thenEntry = new Label();
- Label elseEntry = new Label();
- Label endIf = new Label();
-
- // basic block for the condition
- unbox(scan(tree.getCondition(), p));
-
- ConditionalJump cjump = new ConditionalJump(thenEntry, elseEntry);
- extendWithExtendedNode(cjump);
-
- // then branch
- addLabelForNextNode(thenEntry);
- StatementTree thenStatement = tree.getThenStatement();
- scan(thenStatement, p);
- extendWithExtendedNode(new UnconditionalJump(endIf));
-
- // else branch
- addLabelForNextNode(elseEntry);
- StatementTree elseStatement = tree.getElseStatement();
- if (elseStatement != null) {
- scan(elseStatement, p);
- }
-
- // label the end of the if statement
- addLabelForNextNode(endIf);
-
- return null;
- }
-
- @Override
- public Node visitImport(ImportTree tree, Void p) {
- assert false : "ImportTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitArrayAccess(ArrayAccessTree tree, Void p) {
- Node array = scan(tree.getExpression(), p);
- Node index = unaryNumericPromotion(scan(tree.getIndex(), p));
- return extendWithNode(new ArrayAccessNode(tree, array, index));
- }
-
- @Override
- public Node visitLabeledStatement(LabeledStatementTree tree, Void p) {
- // This method can set the break target after generating all Nodes
- // in the contained statement, but it can't set the continue target,
- // which may be in the middle of a sequence of nodes. Labeled loops
- // must look up and use the continue Labels.
- Name labelName = tree.getLabel();
-
- Label breakL = new Label(labelName + "_break");
- Label continueL = new Label(labelName + "_continue");
-
- breakLabels.put(labelName, breakL);
- continueLabels.put(labelName, continueL);
-
- scan(tree.getStatement(), p);
-
- addLabelForNextNode(breakL);
-
- breakLabels.remove(labelName);
- continueLabels.remove(labelName);
-
- return null;
- }
-
- @Override
- public Node visitLiteral(LiteralTree tree, Void p) {
- Node r = null;
- switch (tree.getKind()) {
- case BOOLEAN_LITERAL:
- r = new BooleanLiteralNode(tree);
- break;
- case CHAR_LITERAL:
- r = new CharacterLiteralNode(tree);
- break;
- case DOUBLE_LITERAL:
- r = new DoubleLiteralNode(tree);
- break;
- case FLOAT_LITERAL:
- r = new FloatLiteralNode(tree);
- break;
- case INT_LITERAL:
- r = new IntegerLiteralNode(tree);
- break;
- case LONG_LITERAL:
- r = new LongLiteralNode(tree);
- break;
- case NULL_LITERAL:
- r = new NullLiteralNode(tree);
- break;
- case STRING_LITERAL:
- r = new StringLiteralNode(tree);
- break;
- default:
- assert false : "unexpected literal tree";
- break;
- }
- assert r != null : "unexpected literal tree";
- Node result = extendWithNode(r);
- return result;
- }
-
- @Override
- public Node visitMethod(MethodTree tree, Void p) {
- assert false : "MethodTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitModifiers(ModifiersTree tree, Void p) {
- assert false : "ModifiersTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitNewArray(NewArrayTree tree, Void p) {
- // see JLS 15.10
-
- ArrayType type = (ArrayType) InternalUtils.typeOf(tree);
- TypeMirror elemType = type.getComponentType();
-
- List<? extends ExpressionTree> dimensions = tree.getDimensions();
- List<? extends ExpressionTree> initializers = tree.getInitializers();
-
- List<Node> dimensionNodes = new ArrayList<Node>();
- if (dimensions != null) {
- for (ExpressionTree dim : dimensions) {
- dimensionNodes.add(unaryNumericPromotion(scan(dim, p)));
- }
- }
-
- List<Node> initializerNodes = new ArrayList<Node>();
- if (initializers != null) {
- for (ExpressionTree init : initializers) {
- initializerNodes.add(assignConvert(scan(init, p), elemType));
- }
- }
-
- Node node = new ArrayCreationNode(tree, type, dimensionNodes, initializerNodes);
- return extendWithNode(node);
- }
-
- @Override
- public Node visitNewClass(NewClassTree tree, Void p) {
- // see JLS 15.9
-
- Tree enclosingExpr = tree.getEnclosingExpression();
- if (enclosingExpr != null) {
- scan(enclosingExpr, p);
- }
-
- // We ignore any class body because its methods should
- // be visited separately.
- // TODO: For anonymous classes we want to propagate the current store
- // to the anonymous class.
- // See Issues 266, 811.
-
- // Convert constructor arguments
- ExecutableElement constructor = TreeUtils.elementFromUse(tree);
-
- List<? extends ExpressionTree> actualExprs = tree.getArguments();
-
- List<Node> arguments = convertCallArguments(constructor, actualExprs);
-
- // TODO: for anonymous classes, don't use the identifier alone.
- // See Issue 890.
- Node constructorNode = scan(tree.getIdentifier(), p);
-
- Node node = new ObjectCreationNode(tree, constructorNode, arguments);
-
- Set<TypeMirror> thrownSet = new HashSet<>();
- // Add exceptions explicitly mentioned in the throws clause.
- List<? extends TypeMirror> thrownTypes = constructor.getThrownTypes();
- thrownSet.addAll(thrownTypes);
- // Add Throwable to account for unchecked exceptions
- TypeElement throwableElement = elements.getTypeElement("java.lang.Throwable");
- thrownSet.add(throwableElement.asType());
-
- extendWithNodeWithExceptions(node, thrownSet);
-
- return node;
- }
-
- /**
- * Maps a {@code Tree} its directly enclosing {@code ParenthesizedTree} if one exists.
- *
- * <p>This map is used by {@link CFGTranslationPhaseOne#addToLookupMap(Node)} to associate a
- * {@code ParenthesizedTree} with the dataflow {@code Node} that was used during inference.
- * This map is necessary because dataflow does not create a {@code Node} for a {@code
- * ParenthesizedTree.}
- */
- private final Map<Tree, ParenthesizedTree> parenMapping = new HashMap<>();
-
- @Override
- public Node visitParenthesized(ParenthesizedTree tree, Void p) {
- parenMapping.put(tree.getExpression(), tree);
- return scan(tree.getExpression(), p);
- }
-
- @Override
- public Node visitReturn(ReturnTree tree, Void p) {
- ExpressionTree ret = tree.getExpression();
- // TODO: also have a return-node if nothing is returned
- ReturnNode result = null;
- if (ret != null) {
- Node node = scan(ret, p);
- Tree enclosing =
- TreeUtils.enclosingOfKind(
- getCurrentPath(),
- new HashSet<Kind>(
- Arrays.asList(Kind.METHOD, Kind.LAMBDA_EXPRESSION)));
- if (enclosing.getKind() == Kind.LAMBDA_EXPRESSION) {
- LambdaExpressionTree lambdaTree = (LambdaExpressionTree) enclosing;
- TreePath lambdaTreePath =
- TreePath.getPath(getCurrentPath().getCompilationUnit(), lambdaTree);
- Context ctx = ((JavacProcessingEnvironment) env).getContext();
- Element overriddenElement =
- com.sun.tools.javac.code.Types.instance(ctx)
- .findDescriptorSymbol(
- ((Type) trees.getTypeMirror(lambdaTreePath)).tsym);
-
- result =
- new ReturnNode(
- tree,
- node,
- env.getTypeUtils(),
- lambdaTree,
- (MethodSymbol) overriddenElement);
- } else {
- result = new ReturnNode(tree, node, env.getTypeUtils(), (MethodTree) enclosing);
- }
- returnNodes.add(result);
- extendWithNode(result);
- }
- extendWithExtendedNode(new UnconditionalJump(regularExitLabel));
- // TODO: return statements should also flow to an enclosing finally block
- return result;
- }
-
- @Override
- public Node visitMemberSelect(MemberSelectTree tree, Void p) {
- Node expr = scan(tree.getExpression(), p);
- if (!TreeUtils.isFieldAccess(tree)) {
- // Could be a selector of a class or package
- Node result = null;
- Element element = TreeUtils.elementFromUse(tree);
- switch (element.getKind()) {
- case ANNOTATION_TYPE:
- case CLASS:
- case ENUM:
- case INTERFACE:
- result = extendWithNode(new ClassNameNode(tree, expr));
- break;
- case PACKAGE:
- result = extendWithNode(new PackageNameNode(tree, (PackageNameNode) expr));
- break;
- default:
- assert false : "Unexpected element kind: " + element.getKind();
- return null;
- }
- return result;
- }
-
- Node node = new FieldAccessNode(tree, expr);
-
- Element element = TreeUtils.elementFromUse(tree);
- if (ElementUtils.isStatic(element)
- || expr instanceof ImplicitThisLiteralNode
- || expr instanceof ExplicitThisLiteralNode) {
- // No NullPointerException can be thrown, use normal node
- extendWithNode(node);
- } else {
- TypeElement npeElement = elements.getTypeElement("java.lang.NullPointerException");
- extendWithNodeWithException(node, npeElement.asType());
- }
-
- return node;
- }
-
- @Override
- public Node visitEmptyStatement(EmptyStatementTree tree, Void p) {
- return null;
- }
-
- @Override
- public Node visitSynchronized(SynchronizedTree tree, Void p) {
- // see JLS 14.19
-
- Node synchronizedExpr = scan(tree.getExpression(), p);
- SynchronizedNode synchronizedStartNode =
- new SynchronizedNode(tree, synchronizedExpr, true, env.getTypeUtils());
- extendWithNode(synchronizedStartNode);
- scan(tree.getBlock(), p);
- SynchronizedNode synchronizedEndNode =
- new SynchronizedNode(tree, synchronizedExpr, false, env.getTypeUtils());
- extendWithNode(synchronizedEndNode);
-
- return null;
- }
-
- @Override
- public Node visitThrow(ThrowTree tree, Void p) {
- Node expression = scan(tree.getExpression(), p);
- TypeMirror exception = expression.getType();
- ThrowNode throwsNode = new ThrowNode(tree, expression, env.getTypeUtils());
- NodeWithExceptionsHolder exNode = extendWithNodeWithException(throwsNode, exception);
- exNode.setTerminatesExecution(true);
- return throwsNode;
- }
-
- @Override
- public Node visitCompilationUnit(CompilationUnitTree tree, Void p) {
- assert false : "CompilationUnitTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitTry(TryTree tree, Void p) {
- List<? extends CatchTree> catches = tree.getCatches();
- BlockTree finallyBlock = tree.getFinallyBlock();
-
- extendWithNode(new MarkerNode(tree, "start of try statement", env.getTypeUtils()));
-
- // TODO: Should we handle try-with-resources blocks by also generating code
- // for automatically closing the resources?
- List<? extends Tree> resources = tree.getResources();
- for (Tree resource : resources) {
- scan(resource, p);
- }
-
- List<Pair<TypeMirror, Label>> catchLabels = new ArrayList<>();
- for (CatchTree c : catches) {
- TypeMirror type = InternalUtils.typeOf(c.getParameter().getType());
- assert type != null : "exception parameters must have a type";
- catchLabels.add(Pair.of(type, new Label()));
- }
-
- Label finallyLabel = null;
- if (finallyBlock != null) {
- finallyLabel = new Label();
- tryStack.pushFrame(new TryFinallyFrame(finallyLabel));
- }
-
- Label doneLabel = new Label();
-
- tryStack.pushFrame(new TryCatchFrame(types, catchLabels));
-
- scan(tree.getBlock(), p);
- extendWithExtendedNode(new UnconditionalJump(firstNonNull(finallyLabel, doneLabel)));
-
- tryStack.popFrame();
-
- int catchIndex = 0;
- for (CatchTree c : catches) {
- addLabelForNextNode(catchLabels.get(catchIndex).second);
- scan(c, p);
- catchIndex++;
- extendWithExtendedNode(
- new UnconditionalJump(firstNonNull(finallyLabel, doneLabel)));
- }
-
- if (finallyLabel != null) {
- tryStack.popFrame();
- addLabelForNextNode(finallyLabel);
- scan(finallyBlock, p);
-
- TypeMirror throwableType = elements.getTypeElement("java.lang.Throwable").asType();
- extendWithNodeWithException(
- new MarkerNode(tree, "end of finally block", env.getTypeUtils()),
- throwableType);
- }
-
- addLabelForNextNode(doneLabel);
-
- return null;
- }
-
- @Override
- public Node visitParameterizedType(ParameterizedTypeTree tree, Void p) {
- return extendWithNode(new ParameterizedTypeNode(tree));
- }
-
- @Override
- public Node visitUnionType(UnionTypeTree tree, Void p) {
- assert false : "UnionTypeTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitArrayType(ArrayTypeTree tree, Void p) {
- return extendWithNode(new ArrayTypeNode(tree));
- }
-
- @Override
- public Node visitTypeCast(TypeCastTree tree, Void p) {
- final Node operand = scan(tree.getExpression(), p);
- final TypeMirror type = InternalUtils.typeOf(tree.getType());
- final Node node = new TypeCastNode(tree, operand, type);
- final TypeElement cceElement = elements.getTypeElement("java.lang.ClassCastException");
-
- extendWithNodeWithException(node, cceElement.asType());
- return node;
- }
-
- @Override
- public Node visitPrimitiveType(PrimitiveTypeTree tree, Void p) {
- return extendWithNode(new PrimitiveTypeNode(tree));
- }
-
- @Override
- public Node visitTypeParameter(TypeParameterTree tree, Void p) {
- assert false : "TypeParameterTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitInstanceOf(InstanceOfTree tree, Void p) {
- Node operand = scan(tree.getExpression(), p);
- TypeMirror refType = InternalUtils.typeOf(tree.getType());
- InstanceOfNode node = new InstanceOfNode(tree, operand, refType, types);
- extendWithNode(node);
- return node;
- }
-
- @Override
- public Node visitUnary(UnaryTree tree, Void p) {
- Node result = null;
- Tree.Kind kind = tree.getKind();
- switch (kind) {
- case BITWISE_COMPLEMENT:
- case UNARY_MINUS:
- case UNARY_PLUS:
- {
- // see JLS 15.14 and 15.15
- Node expr = scan(tree.getExpression(), p);
- expr = unaryNumericPromotion(expr);
-
- // TypeMirror exprType = InternalUtils.typeOf(tree);
-
- switch (kind) {
- case BITWISE_COMPLEMENT:
- result = extendWithNode(new BitwiseComplementNode(tree, expr));
- break;
- case UNARY_MINUS:
- result = extendWithNode(new NumericalMinusNode(tree, expr));
- break;
- case UNARY_PLUS:
- result = extendWithNode(new NumericalPlusNode(tree, expr));
- break;
- default:
- assert false;
- break;
- }
- break;
- }
-
- case LOGICAL_COMPLEMENT:
- {
- // see JLS 15.15.6
- Node expr = scan(tree.getExpression(), p);
- result = extendWithNode(new ConditionalNotNode(tree, unbox(expr)));
- break;
- }
-
- case POSTFIX_DECREMENT:
- case POSTFIX_INCREMENT:
- {
- ExpressionTree exprTree = tree.getExpression();
- TypeMirror exprType = InternalUtils.typeOf(exprTree);
- TypeMirror oneType = types.getPrimitiveType(TypeKind.INT);
- Node expr = scan(exprTree, p);
-
- TypeMirror promotedType = binaryPromotedType(exprType, oneType);
-
- LiteralTree oneTree = treeBuilder.buildLiteral(Integer.valueOf(1));
- handleArtificialTree(oneTree);
-
- Node exprRHS = binaryNumericPromotion(expr, promotedType);
- Node one = new IntegerLiteralNode(oneTree);
- one.setInSource(false);
- extendWithNode(one);
- one = binaryNumericPromotion(one, promotedType);
-
- BinaryTree operTree =
- treeBuilder.buildBinary(
- promotedType,
- (kind == Tree.Kind.POSTFIX_INCREMENT
- ? Tree.Kind.PLUS
- : Tree.Kind.MINUS),
- exprTree,
- oneTree);
- handleArtificialTree(operTree);
- Node operNode;
- if (kind == Tree.Kind.POSTFIX_INCREMENT) {
- operNode = new NumericalAdditionNode(operTree, exprRHS, one);
- } else {
- assert kind == Tree.Kind.POSTFIX_DECREMENT;
- operNode = new NumericalSubtractionNode(operTree, exprRHS, one);
- }
- extendWithNode(operNode);
-
- Node narrowed = narrowAndBox(operNode, exprType);
- // TODO: By using the assignment as the result of the expression, we
- // act like a pre-increment/decrement. Fix this by saving the initial
- // value of the expression in a temporary.
- AssignmentNode assignNode = new AssignmentNode(tree, expr, narrowed);
- extendWithNode(assignNode);
- result = assignNode;
- break;
- }
- case PREFIX_DECREMENT:
- case PREFIX_INCREMENT:
- {
- ExpressionTree exprTree = tree.getExpression();
- TypeMirror exprType = InternalUtils.typeOf(exprTree);
- TypeMirror oneType = types.getPrimitiveType(TypeKind.INT);
- Node expr = scan(exprTree, p);
-
- TypeMirror promotedType = binaryPromotedType(exprType, oneType);
-
- LiteralTree oneTree = treeBuilder.buildLiteral(Integer.valueOf(1));
- handleArtificialTree(oneTree);
-
- Node exprRHS = binaryNumericPromotion(expr, promotedType);
- Node one = new IntegerLiteralNode(oneTree);
- one.setInSource(false);
- extendWithNode(one);
- one = binaryNumericPromotion(one, promotedType);
-
- BinaryTree operTree =
- treeBuilder.buildBinary(
- promotedType,
- (kind == Tree.Kind.PREFIX_INCREMENT
- ? Tree.Kind.PLUS
- : Tree.Kind.MINUS),
- exprTree,
- oneTree);
- handleArtificialTree(operTree);
- Node operNode;
- if (kind == Tree.Kind.PREFIX_INCREMENT) {
- operNode = new NumericalAdditionNode(operTree, exprRHS, one);
- } else {
- assert kind == Tree.Kind.PREFIX_DECREMENT;
- operNode = new NumericalSubtractionNode(operTree, exprRHS, one);
- }
- extendWithNode(operNode);
-
- Node narrowed = narrowAndBox(operNode, exprType);
- AssignmentNode assignNode = new AssignmentNode(tree, expr, narrowed);
- extendWithNode(assignNode);
- result = assignNode;
- break;
- }
-
- case OTHER:
- default:
- // special node NLLCHK
- if (tree.toString().startsWith("<*nullchk*>")) {
- Node expr = scan(tree.getExpression(), p);
- result = extendWithNode(new NullChkNode(tree, expr));
- break;
- }
-
- assert false : "Unknown kind (" + kind + ") of unary expression: " + tree;
- }
-
- return result;
- }
-
- @Override
- public Node visitVariable(VariableTree tree, Void p) {
-
- // see JLS 14.4
-
- boolean isField =
- getCurrentPath().getParentPath() != null
- && getCurrentPath().getParentPath().getLeaf().getKind() == Kind.CLASS;
- Node node = null;
-
- ClassTree enclosingClass = TreeUtils.enclosingClass(getCurrentPath());
- TypeElement classElem = TreeUtils.elementFromDeclaration(enclosingClass);
- Node receiver = new ImplicitThisLiteralNode(classElem.asType());
-
- if (isField) {
- ExpressionTree initializer = tree.getInitializer();
- assert initializer != null;
- node =
- translateAssignment(
- tree,
- new FieldAccessNode(
- tree, TreeUtils.elementFromDeclaration(tree), receiver),
- initializer);
- } else {
- // local variable definition
- VariableDeclarationNode decl = new VariableDeclarationNode(tree);
- extendWithNode(decl);
-
- // initializer
-
- ExpressionTree initializer = tree.getInitializer();
- if (initializer != null) {
- node =
- translateAssignment(
- tree, new LocalVariableNode(tree, receiver), initializer);
- }
- }
-
- return node;
- }
-
- @Override
- public Node visitWhileLoop(WhileLoopTree tree, Void p) {
- Name parentLabel = getLabel(getCurrentPath());
-
- Label loopEntry = new Label();
- Label loopExit = new Label();
-
- // If the loop is a labeled statement, then its continue
- // target is identical for continues with no label and
- // continues with the loop's label.
- Label conditionStart;
- if (parentLabel != null) {
- conditionStart = continueLabels.get(parentLabel);
- } else {
- conditionStart = new Label();
- }
-
- Label oldBreakTargetL = breakTargetL;
- breakTargetL = loopExit;
-
- Label oldContinueTargetL = continueTargetL;
- continueTargetL = conditionStart;
-
- // Condition
- addLabelForNextNode(conditionStart);
- if (tree.getCondition() != null) {
- unbox(scan(tree.getCondition(), p));
- ConditionalJump cjump = new ConditionalJump(loopEntry, loopExit);
- extendWithExtendedNode(cjump);
- }
-
- // Loop body
- addLabelForNextNode(loopEntry);
- if (tree.getStatement() != null) {
- scan(tree.getStatement(), p);
- }
- extendWithExtendedNode(new UnconditionalJump(conditionStart));
-
- // Loop exit
- addLabelForNextNode(loopExit);
-
- breakTargetL = oldBreakTargetL;
- continueTargetL = oldContinueTargetL;
-
- return null;
- }
-
- @Override
- public Node visitLambdaExpression(LambdaExpressionTree tree, Void p) {
- declaredLambdas.add(tree);
- Node node = new FunctionalInterfaceNode(tree);
- extendWithNode(node);
- return node;
- }
-
- @Override
- public Node visitMemberReference(MemberReferenceTree tree, Void p) {
- Tree enclosingExpr = tree.getQualifierExpression();
- if (enclosingExpr != null) {
- scan(enclosingExpr, p);
- }
-
- Node node = new FunctionalInterfaceNode(tree);
- extendWithNode(node);
-
- return node;
- }
-
- @Override
- public Node visitWildcard(WildcardTree tree, Void p) {
- assert false : "WildcardTree is unexpected in AST to CFG translation";
- return null;
- }
-
- @Override
- public Node visitOther(Tree tree, Void p) {
- assert false : "Unknown AST element encountered in AST to CFG translation.";
- return null;
- }
- }
-
- /** A tuple with 4 named elements. */
- private interface TreeInfo {
- boolean isBoxed();
-
- boolean isNumeric();
-
- boolean isBoolean();
-
- TypeMirror unboxedType();
- }
-
- private static <A> A firstNonNull(A first, A second) {
- if (first != null) {
- return first;
- } else if (second != null) {
- return second;
- } else {
- throw new NullPointerException();
- }
- }
-
- /* --------------------------------------------------------- */
- /* Utility routines for debugging CFG building */
- /* --------------------------------------------------------- */
-
- /**
- * Print a set of {@link Block}s and the edges between them. This is useful for examining the
- * results of phase two.
- */
- protected static void printBlocks(Set<Block> blocks) {
- for (Block b : blocks) {
- System.out.print(b.hashCode() + ": " + b);
- switch (b.getType()) {
- case REGULAR_BLOCK:
- case SPECIAL_BLOCK:
- {
- Block succ = ((SingleSuccessorBlockImpl) b).getSuccessor();
- System.out.println(" -> " + (succ != null ? succ.hashCode() : "||"));
- break;
- }
- case EXCEPTION_BLOCK:
- {
- Block succ = ((SingleSuccessorBlockImpl) b).getSuccessor();
- System.out.print(" -> " + (succ != null ? succ.hashCode() : "||") + " {");
- for (Map.Entry<TypeMirror, Set<Block>> entry :
- ((ExceptionBlockImpl) b).getExceptionalSuccessors().entrySet()) {
- System.out.print(entry.getKey() + " : " + entry.getValue() + ", ");
- }
- System.out.println("}");
- break;
- }
- case CONDITIONAL_BLOCK:
- {
- Block tSucc = ((ConditionalBlockImpl) b).getThenSuccessor();
- Block eSucc = ((ConditionalBlockImpl) b).getElseSuccessor();
- System.out.println(
- " -> T "
- + (tSucc != null ? tSucc.hashCode() : "||")
- + " F "
- + (eSucc != null ? eSucc.hashCode() : "||"));
- break;
- }
- }
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGVisualizer.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGVisualizer.java
deleted file mode 100644
index 9378d83726..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/CFGVisualizer.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package org.checkerframework.dataflow.cfg;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import java.util.Map;
-import org.checkerframework.dataflow.analysis.AbstractValue;
-import org.checkerframework.dataflow.analysis.Analysis;
-import org.checkerframework.dataflow.analysis.FlowExpressions;
-import org.checkerframework.dataflow.analysis.Store;
-import org.checkerframework.dataflow.analysis.TransferFunction;
-import org.checkerframework.dataflow.cfg.block.Block;
-import org.checkerframework.dataflow.cfg.block.SpecialBlock;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-/**
- * Perform some visualization on a control flow graph. The particular operations depend on the
- * implementation.
- */
-public interface CFGVisualizer<
- A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>> {
- /**
- * Initialization method guaranteed to be called once before the first invocation of {@link
- * visualize}.
- *
- * @param args implementation-dependent options
- */
- void init(Map<String, Object> args);
-
- /**
- * Output a visualization representing the control flow graph starting at {@code entry}. The
- * concrete actions are implementation dependent.
- *
- * <p>An invocation {@code visualize(cfg, entry, null);} does not output stores at the beginning
- * of basic blocks.
- *
- * @param cfg the CFG to visualize
- * @param entry the entry node of the control flow graph to be represented
- * @param analysis an analysis containing information about the program represented by the CFG.
- * The information includes {@link Store}s that are valid at the beginning of basic blocks
- * reachable from {@code entry} and per-node information for value producing {@link Node}s.
- * Can also be {@code null} to indicate that this information should not be output.
- * @return possible analysis results, e.g. generated file names.
- */
- /*@Nullable*/ Map<String, Object> visualize(
- ControlFlowGraph cfg, Block entry, /*@Nullable*/ Analysis<A, S, T> analysis);
-
- /**
- * Delegate the visualization responsibility to the passed {@link Store} instance, which will
- * call back to this visualizer instance for sub-components.
- *
- * @param store the store to visualize
- */
- void visualizeStore(S store);
-
- /**
- * Called by a {@code CFAbstractStore} to visualize the class name before calling the {@code
- * CFAbstractStore#internalVisualize()} method.
- *
- * @param classCanonicalName the canonical name of the class
- */
- void visualizeStoreHeader(String classCanonicalName);
-
- /**
- * Called by {@code CFAbstractStore#internalVisualize()} to visualize a local variable.
- *
- * @param localVar the local variable
- * @param value the value of the local variable
- */
- void visualizeStoreLocalVar(FlowExpressions.LocalVariable localVar, A value);
-
- /**
- * Called by {@code CFAbstractStore#internalVisualize()} to visualize the value of the current
- * object {@code this} in this Store.
- *
- * @param value the value of the current object this
- */
- void visualizeStoreThisVal(A value);
-
- /**
- * Called by {@code CFAbstractStore#internalVisualize()} to visualize the value of fields
- * collected by this Store.
- *
- * @param fieldAccess the field
- * @param value the value of the field
- */
- void visualizeStoreFieldVals(FlowExpressions.FieldAccess fieldAccess, A value);
-
- /**
- * Called by {@code CFAbstractStore#internalVisualize()} to visualize the value of arrays
- * collected by this Store.
- *
- * @param arrayValue the array
- * @param value the value of the array
- */
- void visualizeStoreArrayVal(FlowExpressions.ArrayAccess arrayValue, A value);
-
- /**
- * Called by {@code CFAbstractStore#internalVisualize()} to visualize the value of pure method
- * calls collected by this Store.
- *
- * @param methodCall the pure method call
- * @param value the value of the pure method call
- */
- void visualizeStoreMethodVals(FlowExpressions.MethodCall methodCall, A value);
-
- /**
- * Called by {@code CFAbstractStore#internalVisualize()} to visualize the value of class names
- * collected by this Store.
- *
- * @param className the class name
- * @param value the value of the class name
- */
- void visualizeStoreClassVals(FlowExpressions.ClassName className, A value);
-
- /**
- * Called by {@code CFAbstractStore#internalVisualize()} to visualize the specific information
- * collected according to the specific kind of Store. Currently, these Stores call this method:
- * {@code LockStore}, {@code NullnessStore}, and {@code InitializationStore} to visualize
- * additional information.
- *
- * @param keyName the name of the specific information to be visualized
- * @param value the value of the specific information to be visualized
- */
- void visualizeStoreKeyVal(String keyName, Object value);
-
- /**
- * Called by {@code CFAbstractStore} to visualize any information after the invocation of {@code
- * CFAbstractStore#internalVisualize()}.
- */
- void visualizeStoreFooter();
-
- /**
- * Visualize a block based on the analysis.
- *
- * @param bb the block
- * @param analysis the current analysis
- */
- void visualizeBlock(Block bb, /*@Nullable*/ Analysis<A, S, T> analysis);
-
- /**
- * Visualize a SpecialBlock.
- *
- * @param sbb the special block
- */
- void visualizeSpecialBlock(SpecialBlock sbb);
-
- /**
- * Visualize the transferInput of a Block based on the analysis.
- *
- * @param bb the block
- * @param analysis the current analysis
- */
- void visualizeBlockTransferInput(Block bb, Analysis<A, S, T> analysis);
-
- /**
- * Visualize a Node based on the analysis.
- *
- * @param t the node
- * @param analysis the current analysis
- */
- void visualizeBlockNode(Node t, /*@Nullable*/ Analysis<A, S, T> analysis);
-
- /** Shutdown method called once from the shutdown hook of the {@code BaseTypeChecker}. */
- void shutdown();
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/ControlFlowGraph.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/ControlFlowGraph.java
deleted file mode 100644
index 0a2687aec2..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/ControlFlowGraph.java
+++ /dev/null
@@ -1,246 +0,0 @@
-package org.checkerframework.dataflow.cfg;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import org.checkerframework.dataflow.cfg.block.Block;
-import org.checkerframework.dataflow.cfg.block.Block.BlockType;
-import org.checkerframework.dataflow.cfg.block.ConditionalBlock;
-import org.checkerframework.dataflow.cfg.block.ExceptionBlock;
-import org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock;
-import org.checkerframework.dataflow.cfg.block.SpecialBlock;
-import org.checkerframework.dataflow.cfg.block.SpecialBlockImpl;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.dataflow.cfg.node.ReturnNode;
-
-/**
- * A control flow graph (CFG for short) of a single method.
- *
- * @author Stefan Heule
- */
-public class ControlFlowGraph {
-
- /** The entry block of the control flow graph. */
- protected final SpecialBlock entryBlock;
-
- /** The regular exit block of the control flow graph. */
- protected final SpecialBlock regularExitBlock;
-
- /** The exceptional exit block of the control flow graph. */
- protected final SpecialBlock exceptionalExitBlock;
-
- /** The AST this CFG corresponds to. */
- protected UnderlyingAST underlyingAST;
-
- /**
- * Maps from AST {@link Tree}s to {@link Node}s. Every Tree that produces a value will have at
- * least one corresponding Node. Trees that undergo conversions, such as boxing or unboxing, can
- * map to two distinct Nodes. The Node for the pre-conversion value is stored in treeLookup,
- * while the Node for the post-conversion value is stored in convertedTreeLookup.
- */
- protected IdentityHashMap<Tree, Node> treeLookup;
-
- /** Map from AST {@link Tree}s to post-conversion {@link Node}s. */
- protected IdentityHashMap<Tree, Node> convertedTreeLookup;
-
- /**
- * All return nodes (if any) encountered. Only includes return statements that actually return
- * something
- */
- protected final List<ReturnNode> returnNodes;
-
- public ControlFlowGraph(
- SpecialBlock entryBlock,
- SpecialBlockImpl regularExitBlock,
- SpecialBlockImpl exceptionalExitBlock,
- UnderlyingAST underlyingAST,
- IdentityHashMap<Tree, Node> treeLookup,
- IdentityHashMap<Tree, Node> convertedTreeLookup,
- List<ReturnNode> returnNodes) {
- super();
- this.entryBlock = entryBlock;
- this.underlyingAST = underlyingAST;
- this.treeLookup = treeLookup;
- this.convertedTreeLookup = convertedTreeLookup;
- this.regularExitBlock = regularExitBlock;
- this.exceptionalExitBlock = exceptionalExitBlock;
- this.returnNodes = returnNodes;
- }
-
- /** @return the {@link Node} to which the {@link Tree} {@code t} corresponds. */
- public Node getNodeCorrespondingToTree(Tree t) {
- if (convertedTreeLookup.containsKey(t)) {
- return convertedTreeLookup.get(t);
- } else {
- return treeLookup.get(t);
- }
- }
-
- /** @return the entry block of the control flow graph. */
- public SpecialBlock getEntryBlock() {
- return entryBlock;
- }
-
- public List<ReturnNode> getReturnNodes() {
- return returnNodes;
- }
-
- public SpecialBlock getRegularExitBlock() {
- return regularExitBlock;
- }
-
- public SpecialBlock getExceptionalExitBlock() {
- return exceptionalExitBlock;
- }
-
- /** @return the AST this CFG corresponds to. */
- public UnderlyingAST getUnderlyingAST() {
- return underlyingAST;
- }
-
- /** @return the set of all basic block in this control flow graph */
- public Set<Block> getAllBlocks() {
- Set<Block> visited = new HashSet<>();
- Queue<Block> worklist = new LinkedList<>();
- Block cur = entryBlock;
- visited.add(entryBlock);
-
- // traverse the whole control flow graph
- while (true) {
- if (cur == null) {
- break;
- }
-
- Queue<Block> succs = new LinkedList<>();
- if (cur.getType() == BlockType.CONDITIONAL_BLOCK) {
- ConditionalBlock ccur = ((ConditionalBlock) cur);
- succs.add(ccur.getThenSuccessor());
- succs.add(ccur.getElseSuccessor());
- } else {
- assert cur instanceof SingleSuccessorBlock;
- Block b = ((SingleSuccessorBlock) cur).getSuccessor();
- if (b != null) {
- succs.add(b);
- }
- }
-
- if (cur.getType() == BlockType.EXCEPTION_BLOCK) {
- ExceptionBlock ecur = (ExceptionBlock) cur;
- for (Set<Block> exceptionSuccSet : ecur.getExceptionalSuccessors().values()) {
- succs.addAll(exceptionSuccSet);
- }
- }
-
- for (Block b : succs) {
- if (!visited.contains(b)) {
- visited.add(b);
- worklist.add(b);
- }
- }
-
- cur = worklist.poll();
- }
-
- return visited;
- }
-
- /**
- * @return the list of all basic block in this control flow graph in reversed depth-first
- * postorder sequence.
- * <p>Blocks may appear more than once in the sequence.
- */
- public List<Block> getDepthFirstOrderedBlocks() {
- List<Block> dfsOrderResult = new LinkedList<>();
- Set<Block> visited = new HashSet<>();
- Deque<Block> worklist = new LinkedList<>();
- worklist.add(entryBlock);
- while (!worklist.isEmpty()) {
- Block cur = worklist.getLast();
- if (visited.contains(cur)) {
- dfsOrderResult.add(cur);
- worklist.removeLast();
- } else {
- visited.add(cur);
- Deque<Block> successors = getSuccessors(cur);
- successors.removeAll(visited);
- worklist.addAll(successors);
- }
- }
-
- Collections.reverse(dfsOrderResult);
- return dfsOrderResult;
- }
-
- /**
- * Get a list of all successor Blocks for cur
- *
- * @return a Deque of successor Blocks
- */
- private Deque<Block> getSuccessors(Block cur) {
- Deque<Block> succs = new LinkedList<>();
- if (cur.getType() == BlockType.CONDITIONAL_BLOCK) {
- ConditionalBlock ccur = ((ConditionalBlock) cur);
- succs.add(ccur.getThenSuccessor());
- succs.add(ccur.getElseSuccessor());
- } else {
- assert cur instanceof SingleSuccessorBlock;
- Block b = ((SingleSuccessorBlock) cur).getSuccessor();
- if (b != null) {
- succs.add(b);
- }
- }
-
- if (cur.getType() == BlockType.EXCEPTION_BLOCK) {
- ExceptionBlock ecur = (ExceptionBlock) cur;
- for (Set<Block> exceptionSuccSet : ecur.getExceptionalSuccessors().values()) {
- succs.addAll(exceptionSuccSet);
- }
- }
- return succs;
- }
-
- /** @return the tree-lookup map */
- public IdentityHashMap<Tree, Node> getTreeLookup() {
- return new IdentityHashMap<>(treeLookup);
- }
-
- /**
- * Get the {@link MethodTree} of the CFG if the argument {@link Tree} maps to a {@link Node} in
- * the CFG or null otherwise.
- */
- public /*@Nullable*/ MethodTree getContainingMethod(Tree t) {
- if (treeLookup.containsKey(t)) {
- if (underlyingAST.getKind() == UnderlyingAST.Kind.METHOD) {
- UnderlyingAST.CFGMethod cfgMethod = (UnderlyingAST.CFGMethod) underlyingAST;
- return cfgMethod.getMethod();
- }
- }
- return null;
- }
-
- /**
- * Get the {@link ClassTree} of the CFG if the argument {@link Tree} maps to a {@link Node} in
- * the CFG or null otherwise.
- */
- public /*@Nullable*/ ClassTree getContainingClass(Tree t) {
- if (treeLookup.containsKey(t)) {
- if (underlyingAST.getKind() == UnderlyingAST.Kind.METHOD) {
- UnderlyingAST.CFGMethod cfgMethod = (UnderlyingAST.CFGMethod) underlyingAST;
- return cfgMethod.getClassTree();
- }
- }
- return null;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/DOTCFGVisualizer.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/DOTCFGVisualizer.java
deleted file mode 100644
index 1eb1cb87a2..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/DOTCFGVisualizer.java
+++ /dev/null
@@ -1,511 +0,0 @@
-package org.checkerframework.dataflow.cfg;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.tools.javac.tree.JCTree;
-import java.io.BufferedWriter;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Queue;
-import java.util.Set;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.analysis.AbstractValue;
-import org.checkerframework.dataflow.analysis.Analysis;
-import org.checkerframework.dataflow.analysis.FlowExpressions;
-import org.checkerframework.dataflow.analysis.Store;
-import org.checkerframework.dataflow.analysis.TransferFunction;
-import org.checkerframework.dataflow.analysis.TransferInput;
-import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod;
-import org.checkerframework.dataflow.cfg.UnderlyingAST.CFGStatement;
-import org.checkerframework.dataflow.cfg.block.Block;
-import org.checkerframework.dataflow.cfg.block.Block.BlockType;
-import org.checkerframework.dataflow.cfg.block.ConditionalBlock;
-import org.checkerframework.dataflow.cfg.block.ExceptionBlock;
-import org.checkerframework.dataflow.cfg.block.RegularBlock;
-import org.checkerframework.dataflow.cfg.block.SingleSuccessorBlock;
-import org.checkerframework.dataflow.cfg.block.SpecialBlock;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.javacutil.ErrorReporter;
-
-/**
- * Generate a graph description in the DOT language of a control graph.
- *
- * @author Stefan Heule
- */
-public class DOTCFGVisualizer<
- A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>>
- implements CFGVisualizer<A, S, T> {
-
- protected String outdir;
- protected boolean verbose;
- protected String checkerName;
-
- protected StringBuilder sbDigraph;
- protected StringBuilder sbStore;
- protected StringBuilder sbBlock;
-
- /** Mapping from class/method representation to generated dot file. */
- protected Map<String, String> generated;
-
- @Override
- public void init(Map<String, Object> args) {
- this.outdir = (String) args.get("outdir");
- {
- Object verb = args.get("verbose");
- this.verbose =
- verb == null
- ? false
- : verb instanceof String
- ? Boolean.getBoolean((String) verb)
- : (boolean) verb;
- }
- this.checkerName = (String) args.get("checkerName");
-
- this.generated = new HashMap<>();
-
- this.sbDigraph = new StringBuilder();
-
- this.sbStore = new StringBuilder();
-
- this.sbBlock = new StringBuilder();
- }
-
- /** {@inheritDoc} */
- @Override
- public /*@Nullable*/ Map<String, Object> visualize(
- ControlFlowGraph cfg, Block entry, /*@Nullable*/ Analysis<A, S, T> analysis) {
-
- String dotgraph = generateDotGraph(cfg, entry, analysis);
-
- String dotfilename = dotOutputFileName(cfg.underlyingAST);
- // System.err.println("Output to DOT file: " + dotfilename);
-
- try {
- FileWriter fstream = new FileWriter(dotfilename);
- BufferedWriter out = new BufferedWriter(fstream);
- out.write(dotgraph);
- out.close();
- } catch (IOException e) {
- ErrorReporter.errorAbort(
- "Error creating dot file: " + dotfilename + "; ensure the path is valid", e);
- }
-
- Map<String, Object> res = new HashMap<>();
- res.put("dotFileName", dotfilename);
-
- return res;
- }
-
- /** Generate the dot representation as String. */
- protected String generateDotGraph(
- ControlFlowGraph cfg, Block entry, /*@Nullable*/ Analysis<A, S, T> analysis) {
- this.sbDigraph.setLength(0);
- Set<Block> visited = new HashSet<>();
-
- // header
- this.sbDigraph.append("digraph {\n");
-
- Block cur = entry;
- Queue<Block> worklist = new LinkedList<>();
- visited.add(entry);
- // traverse control flow graph and define all arrows
- while (true) {
- if (cur == null) {
- break;
- }
-
- if (cur.getType() == BlockType.CONDITIONAL_BLOCK) {
- ConditionalBlock ccur = ((ConditionalBlock) cur);
- Block thenSuccessor = ccur.getThenSuccessor();
- addDotEdge(ccur.getId(), thenSuccessor.getId(), "then\\n" + ccur.getThenFlowRule());
- if (!visited.contains(thenSuccessor)) {
- visited.add(thenSuccessor);
- worklist.add(thenSuccessor);
- }
- Block elseSuccessor = ccur.getElseSuccessor();
- addDotEdge(ccur.getId(), elseSuccessor.getId(), "else\\n" + ccur.getElseFlowRule());
- if (!visited.contains(elseSuccessor)) {
- visited.add(elseSuccessor);
- worklist.add(elseSuccessor);
- }
- } else {
- assert cur instanceof SingleSuccessorBlock;
- Block b = ((SingleSuccessorBlock) cur).getSuccessor();
- if (b != null) {
- addDotEdge(
- cur.getId(),
- b.getId(),
- ((SingleSuccessorBlock) cur).getFlowRule().name());
- if (!visited.contains(b)) {
- visited.add(b);
- worklist.add(b);
- }
- }
- }
-
- // exceptional edges
- if (cur.getType() == BlockType.EXCEPTION_BLOCK) {
- ExceptionBlock ecur = (ExceptionBlock) cur;
- for (Entry<TypeMirror, Set<Block>> e : ecur.getExceptionalSuccessors().entrySet()) {
- Set<Block> blocks = e.getValue();
- TypeMirror cause = e.getKey();
- String exception = cause.toString();
- if (exception.startsWith("java.lang.")) {
- exception = exception.replace("java.lang.", "");
- }
-
- for (Block b : blocks) {
- addDotEdge(cur.getId(), b.getId(), exception);
- if (!visited.contains(b)) {
- visited.add(b);
- worklist.add(b);
- }
- }
- }
- }
-
- cur = worklist.poll();
- }
-
- generateDotNodes(visited, cfg, analysis);
-
- // footer
- this.sbDigraph.append("}\n");
-
- return this.sbDigraph.toString();
- }
-
- protected void generateDotNodes(
- Set<Block> visited, ControlFlowGraph cfg, /*@Nullable*/ Analysis<A, S, T> analysis) {
- IdentityHashMap<Block, List<Integer>> processOrder = getProcessOrder(cfg);
- this.sbDigraph.append(" node [shape=rectangle];\n\n");
- // definition of all nodes including their labels
- for (Block v : visited) {
- this.sbDigraph.append(" " + v.getId() + " [");
- if (v.getType() == BlockType.CONDITIONAL_BLOCK) {
- this.sbDigraph.append("shape=polygon sides=8 ");
- } else if (v.getType() == BlockType.SPECIAL_BLOCK) {
- this.sbDigraph.append("shape=oval ");
- }
- this.sbDigraph.append("label=\"");
- if (verbose) {
- this.sbDigraph.append(
- "Process order: "
- + processOrder.get(v).toString().replaceAll("[\\[\\]]", "")
- + "\\n");
- }
- visualizeBlock(v, analysis);
- }
-
- this.sbDigraph.append("\n");
- }
-
- /** @return the file name used for DOT output. */
- protected String dotOutputFileName(UnderlyingAST ast) {
- StringBuilder srcloc = new StringBuilder();
-
- StringBuilder outfile = new StringBuilder(outdir);
- outfile.append('/');
- if (ast.getKind() == UnderlyingAST.Kind.ARBITRARY_CODE) {
- CFGStatement cfgs = (CFGStatement) ast;
- String clsname = cfgs.getClassTree().getSimpleName().toString();
- outfile.append(clsname);
- outfile.append("-initializer-");
- outfile.append(ast.hashCode());
-
- srcloc.append('<');
- srcloc.append(clsname);
- srcloc.append("::initializer::");
- srcloc.append(((JCTree) cfgs.getCode()).pos);
- srcloc.append('>');
- } else if (ast.getKind() == UnderlyingAST.Kind.METHOD) {
- CFGMethod cfgm = (CFGMethod) ast;
- String clsname = cfgm.getClassTree().getSimpleName().toString();
- String methname = cfgm.getMethod().getName().toString();
- outfile.append(clsname);
- outfile.append('-');
- outfile.append(methname);
-
- srcloc.append('<');
- srcloc.append(clsname);
- srcloc.append("::");
- srcloc.append(methname);
- srcloc.append('(');
- srcloc.append(cfgm.getMethod().getParameters());
- srcloc.append(")::");
- srcloc.append(((JCTree) cfgm.getMethod()).pos);
- srcloc.append('>');
- } else {
- ErrorReporter.errorAbort(
- "Unexpected AST kind: " + ast.getKind() + " value: " + ast.toString());
- return null;
- }
- outfile.append('-');
- outfile.append(checkerName);
- outfile.append(".dot");
-
- // make path safe for Windows
- String out = outfile.toString().replace("<", "_").replace(">", "");
-
- generated.put(srcloc.toString(), out);
-
- return out;
- }
-
- protected IdentityHashMap<Block, List<Integer>> getProcessOrder(ControlFlowGraph cfg) {
- IdentityHashMap<Block, List<Integer>> depthFirstOrder = new IdentityHashMap<>();
- int count = 1;
- for (Block b : cfg.getDepthFirstOrderedBlocks()) {
- if (depthFirstOrder.get(b) == null) {
- depthFirstOrder.put(b, new ArrayList<Integer>());
- }
- depthFirstOrder.get(b).add(count++);
- }
- return depthFirstOrder;
- }
-
- /**
- * Produce a representation of the contests of a basic block.
- *
- * @param bb basic block to visualize
- */
- @Override
- public void visualizeBlock(Block bb, /*@Nullable*/ Analysis<A, S, T> analysis) {
-
- this.sbBlock.setLength(0);
-
- // loop over contents
- List<Node> contents = new LinkedList<>();
- switch (bb.getType()) {
- case REGULAR_BLOCK:
- contents.addAll(((RegularBlock) bb).getContents());
- break;
- case EXCEPTION_BLOCK:
- contents.add(((ExceptionBlock) bb).getNode());
- break;
- case CONDITIONAL_BLOCK:
- break;
- case SPECIAL_BLOCK:
- break;
- default:
- assert false : "All types of basic blocks covered";
- }
- boolean notFirst = false;
- for (Node t : contents) {
- if (notFirst) {
- this.sbBlock.append("\\n");
- }
- notFirst = true;
- visualizeBlockNode(t, analysis);
- }
-
- // handle case where no contents are present
- boolean centered = false;
- if (this.sbBlock.length() == 0) {
- centered = true;
- if (bb.getType() == BlockType.SPECIAL_BLOCK) {
- visualizeSpecialBlock((SpecialBlock) bb);
- } else if (bb.getType() == BlockType.CONDITIONAL_BLOCK) {
- this.sbDigraph.append(" \",];\n");
- return;
- } else {
- this.sbDigraph.append("?? empty ?? \",];\n");
- return;
- }
- }
-
- // visualize transfer input if necessary
- if (analysis != null) {
- visualizeBlockTransferInput(bb, analysis);
- }
-
- this.sbDigraph.append(
- (this.sbBlock.toString() + (centered ? "" : "\\n")).replace("\\n", "\\l")
- + " \",];\n");
- }
-
- @Override
- public void visualizeSpecialBlock(SpecialBlock sbb) {
- switch (sbb.getSpecialType()) {
- case ENTRY:
- this.sbBlock.append("<entry>");
- break;
- case EXIT:
- this.sbBlock.append("<exit>");
- break;
- case EXCEPTIONAL_EXIT:
- this.sbBlock.append("<exceptional-exit>");
- break;
- }
- }
-
- @Override
- public void visualizeBlockTransferInput(Block bb, Analysis<A, S, T> analysis) {
- assert analysis != null
- : "analysis should be non-null when visualizing the transfer input of a block.";
-
- TransferInput<A, S> input = analysis.getInput(bb);
- this.sbStore.setLength(0);
-
- // split input representation to two lines
- this.sbStore.append("Before:");
- S thenStore = input.getThenStore();
- if (!input.containsTwoStores()) {
- S regularStore = input.getRegularStore();
- this.sbStore.append('[');
- visualizeStore(regularStore);
- this.sbStore.append(']');
- } else {
- S elseStore = input.getElseStore();
- this.sbStore.append("[then=");
- visualizeStore(thenStore);
- this.sbStore.append(", else=");
- visualizeStore(elseStore);
- this.sbStore.append("]");
- }
- // separator
- this.sbStore.append("\\n~~~~~~~~~\\n");
-
- // the transfer input before this block is added before the block content
- this.sbBlock.insert(0, this.sbStore);
-
- if (verbose) {
- Node lastNode;
- switch (bb.getType()) {
- case REGULAR_BLOCK:
- List<Node> blockContents = ((RegularBlock) bb).getContents();
- lastNode = blockContents.get(blockContents.size() - 1);
- break;
- case EXCEPTION_BLOCK:
- lastNode = ((ExceptionBlock) bb).getNode();
- break;
- default:
- lastNode = null;
- }
- if (lastNode != null) {
- this.sbStore.setLength(0);
- this.sbStore.append("\\n~~~~~~~~~\\n");
- this.sbStore.append("After:");
- visualizeStore(analysis.getResult().getStoreAfter(lastNode));
- this.sbBlock.append(this.sbStore);
- }
- }
- }
-
- @Override
- public void visualizeBlockNode(Node t, /*@Nullable*/ Analysis<A, S, T> analysis) {
- this.sbBlock.append(prepareString(t.toString()) + " [ " + prepareNodeType(t) + " ]");
- if (analysis != null) {
- A value = analysis.getValue(t);
- if (value != null) {
- this.sbBlock.append(" > " + prepareString(value.toString()));
- }
- }
- }
-
- protected String prepareNodeType(Node t) {
- String name = t.getClass().getSimpleName();
- return name.replace("Node", "");
- }
-
- protected String prepareString(String s) {
- return s.replace("\"", "\\\"");
- }
-
- protected void addDotEdge(long sId, long eId, String labelContent) {
- this.sbDigraph.append(" " + sId + " -> " + eId + " [label=\"" + labelContent + "\"];\n");
- }
-
- @Override
- public void visualizeStore(S store) {
- store.visualize(this);
- }
-
- @Override
- public void visualizeStoreThisVal(A value) {
- this.sbStore.append(" this > " + value + "\\n");
- }
-
- @Override
- public void visualizeStoreLocalVar(FlowExpressions.LocalVariable localVar, A value) {
- this.sbStore.append(" " + localVar + " > " + toStringEscapeDoubleQuotes(value) + "\\n");
- }
-
- @Override
- public void visualizeStoreFieldVals(FlowExpressions.FieldAccess fieldAccess, A value) {
- this.sbStore.append(" " + fieldAccess + " > " + toStringEscapeDoubleQuotes(value) + "\\n");
- }
-
- @Override
- public void visualizeStoreArrayVal(FlowExpressions.ArrayAccess arrayValue, A value) {
- this.sbStore.append(" " + arrayValue + " > " + toStringEscapeDoubleQuotes(value) + "\\n");
- }
-
- @Override
- public void visualizeStoreMethodVals(FlowExpressions.MethodCall methodCall, A value) {
- this.sbStore.append(
- " " + methodCall.toString().replace("\"", "\\\"") + " > " + value + "\\n");
- }
-
- @Override
- public void visualizeStoreClassVals(FlowExpressions.ClassName className, A value) {
- this.sbStore.append(" " + className + " > " + toStringEscapeDoubleQuotes(value) + "\\n");
- }
-
- @Override
- public void visualizeStoreKeyVal(String keyName, Object value) {
- this.sbStore.append(" " + keyName + " = " + value + "\\n");
- }
-
- protected String escapeDoubleQuotes(final String str) {
- return str.replace("\"", "\\\"");
- }
-
- protected String toStringEscapeDoubleQuotes(final Object obj) {
- return escapeDoubleQuotes(String.valueOf(obj));
- }
-
- @Override
- public void visualizeStoreHeader(String classCanonicalName) {
- this.sbStore.append(classCanonicalName + " (\\n");
- }
-
- @Override
- public void visualizeStoreFooter() {
- this.sbStore.append(")");
- }
-
- /**
- * Write a file {@code methods.txt} that contains a mapping from source code location to
- * generated dot file.
- */
- @Override
- public void shutdown() {
- try {
- // Open for append, in case of multiple sub-checkers.
- FileWriter fstream = new FileWriter(outdir + "/methods.txt", true);
- BufferedWriter out = new BufferedWriter(fstream);
- for (Map.Entry<String, String> kv : generated.entrySet()) {
- out.write(kv.getKey());
- out.append('\t');
- out.write(kv.getValue());
- out.append('\n');
- }
- out.close();
- } catch (IOException e) {
- ErrorReporter.errorAbort(
- "Error creating methods.txt file in: " + outdir + "; ensure the path is valid",
- e);
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/JavaSource2CFGDOT.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/JavaSource2CFGDOT.java
deleted file mode 100644
index fa6ff55dc5..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/JavaSource2CFGDOT.java
+++ /dev/null
@@ -1,269 +0,0 @@
-package org.checkerframework.dataflow.cfg;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.util.TreePathScanner;
-import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Options;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import javax.lang.model.element.ExecutableElement;
-import javax.tools.JavaFileManager;
-import javax.tools.JavaFileObject;
-import javax.xml.ws.Holder;
-import org.checkerframework.dataflow.analysis.AbstractValue;
-import org.checkerframework.dataflow.analysis.Analysis;
-import org.checkerframework.dataflow.analysis.Store;
-import org.checkerframework.dataflow.analysis.TransferFunction;
-import org.checkerframework.javacutil.BasicTypeProcessor;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * Class to generate the DOT representation of the control flow graph of a given method.
- *
- * @author Stefan Heule
- */
-public class JavaSource2CFGDOT {
-
- /** Main method. */
- public static void main(String[] args) {
- if (args.length < 2) {
- printUsage();
- System.exit(1);
- }
- String input = args[0];
- String output = args[1];
- File file = new File(input);
- if (!file.canRead()) {
- printError("Cannot read input file: " + file.getAbsolutePath());
- printUsage();
- System.exit(1);
- }
-
- String method = "test";
- String clas = "Test";
- boolean pdf = false;
- boolean error = false;
-
- for (int i = 2; i < args.length; i++) {
- if (args[i].equals("-pdf")) {
- pdf = true;
- } else if (args[i].equals("-method")) {
- if (i >= args.length - 1) {
- printError("Did not find <name> after -method.");
- continue;
- }
- i++;
- method = args[i];
- } else if (args[i].equals("-class")) {
- if (i >= args.length - 1) {
- printError("Did not find <name> after -class.");
- continue;
- }
- i++;
- clas = args[i];
- } else {
- printError("Unknown command-line argument: " + args[i]);
- error = true;
- }
- }
-
- if (error) {
- System.exit(1);
- }
-
- generateDOTofCFG(input, output, method, clas, pdf);
- }
-
- /** Print an error message. */
- protected static void printError(String string) {
- System.err.println("ERROR: " + string);
- }
-
- /** Print usage information. */
- protected static void printUsage() {
- System.out.println(
- "Generate the control flow graph of a Java method, represented as a DOT graph.");
- System.out.println(
- "Parameters: <inputfile> <outputdir> [-method <name>] [-class <name>] [-pdf]");
- System.out.println(" -pdf: Also generate the PDF by invoking 'dot'.");
- System.out.println(" -method: The method to generate the CFG for (defaults to 'test').");
- System.out.println(
- " -class: The class in which to find the method (defaults to 'Test').");
- }
-
- /** Just like method above but without analysis. */
- public static void generateDOTofCFG(
- String inputFile, String outputDir, String method, String clas, boolean pdf) {
- generateDOTofCFG(inputFile, outputDir, method, clas, pdf, null);
- }
-
- /**
- * Generate the DOT representation of the CFG for a method.
- *
- * @param inputFile java source input file
- * @param outputDir source output directory
- * @param method method name to generate the CFG for
- * @param pdf also generate a PDF?
- * @param analysis analysis to perform befor the visualization (or {@code null} if no analysis
- * is to be performed).
- */
- public static <A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>>
- void generateDOTofCFG(
- String inputFile,
- String outputDir,
- String method,
- String clas,
- boolean pdf,
- /*@Nullable*/ Analysis<A, S, T> analysis) {
- Entry<MethodTree, CompilationUnitTree> m =
- getMethodTreeAndCompilationUnit(inputFile, method, clas);
- generateDOTofCFG(
- inputFile, outputDir, method, clas, pdf, analysis, m.getKey(), m.getValue());
- }
-
- public static <A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>>
- void generateDOTofCFG(
- String inputFile,
- String outputDir,
- String method,
- String clas,
- boolean pdf,
- /*@Nullable*/ Analysis<A, S, T> analysis,
- MethodTree m,
- CompilationUnitTree r) {
- String fileName = (new File(inputFile)).getName();
- System.out.println("Working on " + fileName + "...");
-
- if (m == null) {
- printError("Method not found.");
- System.exit(1);
- }
-
- ControlFlowGraph cfg = CFGBuilder.build(r, null, m, null);
- if (analysis != null) {
- analysis.performAnalysis(cfg);
- }
-
- Map<String, Object> args = new HashMap<>();
- args.put("outdir", outputDir);
- args.put("checkerName", "");
-
- CFGVisualizer<A, S, T> viz = new DOTCFGVisualizer<A, S, T>();
- viz.init(args);
- Map<String, Object> res = viz.visualize(cfg, cfg.getEntryBlock(), analysis);
- viz.shutdown();
-
- if (pdf) {
- producePDF((String) res.get("dotFileName"));
- }
- }
-
- /** Invoke DOT to generate a PDF. */
- protected static void producePDF(String file) {
- try {
- String command = "dot -Tpdf \"" + file + ".txt\" -o \"" + file + ".pdf\"";
- Process child = Runtime.getRuntime().exec(command);
- child.waitFor();
- } catch (InterruptedException | IOException e) {
- e.printStackTrace();
- System.exit(1);
- }
- }
-
- /**
- * @return the AST of a specific method in a specific class in a specific file (or null if no
- * such method exists)
- */
- public static /*@Nullable*/ MethodTree getMethodTree(
- String file, final String method, String clas) {
- return getMethodTreeAndCompilationUnit(file, method, clas).getKey();
- }
-
- /**
- * @return the AST of a specific method in a specific class as well as the {@link
- * CompilationUnitTree} in a specific file (or null they do not exist).
- */
- public static Entry</*@Nullable*/ MethodTree, /*@Nullable*/ CompilationUnitTree>
- getMethodTreeAndCompilationUnit(String file, final String method, String clas) {
- final Holder<MethodTree> m = new Holder<>();
- final Holder<CompilationUnitTree> c = new Holder<>();
- BasicTypeProcessor typeProcessor =
- new BasicTypeProcessor() {
- @Override
- protected TreePathScanner<?, ?> createTreePathScanner(
- CompilationUnitTree root) {
- c.value = root;
- return new TreePathScanner<Void, Void>() {
- @Override
- public Void visitMethod(MethodTree node, Void p) {
- ExecutableElement el = TreeUtils.elementFromDeclaration(node);
- if (el.getSimpleName().contentEquals(method)) {
- m.value = node;
- // stop execution by throwing an exception. this
- // makes sure that compilation does not proceed, and
- // thus the AST is not modified by further phases of
- // the compilation (and we save the work to do the
- // compilation).
- throw new RuntimeException();
- }
- return null;
- }
- };
- }
- };
-
- Context context = new Context();
- Options.instance(context).put("compilePolicy", "ATTR_ONLY");
- JavaCompiler javac = new JavaCompiler(context);
- JavacFileManager fileManager = (JavacFileManager) context.get(JavaFileManager.class);
-
- JavaFileObject l =
- fileManager.getJavaFileObjectsFromStrings(List.of(file)).iterator().next();
-
- PrintStream err = System.err;
- try {
- // redirect syserr to nothing (and prevent the compiler from issuing
- // warnings about our exception.
- System.setErr(
- new PrintStream(
- new OutputStream() {
- @Override
- public void write(int b) throws IOException {}
- }));
- javac.compile(List.of(l), List.of(clas), List.of(typeProcessor));
- } catch (Throwable e) {
- // ok
- } finally {
- System.setErr(err);
- }
- return new Entry<MethodTree, CompilationUnitTree>() {
- @Override
- public CompilationUnitTree setValue(CompilationUnitTree value) {
- return null;
- }
-
- @Override
- public CompilationUnitTree getValue() {
- return c.value;
- }
-
- @Override
- public MethodTree getKey() {
- return m.value;
- }
- };
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/UnderlyingAST.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/UnderlyingAST.java
deleted file mode 100644
index dd646f110d..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/UnderlyingAST.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package org.checkerframework.dataflow.cfg;
-
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.LambdaExpressionTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-
-/**
- * Represents an abstract syntax tree of type {@link Tree} that underlies a given control flow
- * graph.
- *
- * @author Stefan Heule
- */
-public abstract class UnderlyingAST {
- public enum Kind {
- /** The underlying code is a whole method */
- METHOD,
- /** The underlying code is a lambda expression */
- LAMBDA,
-
- /** The underlying code is an arbitrary Java statement or expression */
- ARBITRARY_CODE,
- }
-
- protected final Kind kind;
-
- public UnderlyingAST(Kind kind) {
- this.kind = kind;
- }
-
- /** @return the code that corresponds to the CFG */
- public abstract Tree getCode();
-
- public Kind getKind() {
- return kind;
- }
-
- /** If the underlying AST is a method. */
- public static class CFGMethod extends UnderlyingAST {
-
- /** The method declaration */
- protected final MethodTree method;
-
- /** The class tree this method belongs to. */
- protected final ClassTree classTree;
-
- public CFGMethod(MethodTree method, ClassTree classTree) {
- super(Kind.METHOD);
- this.method = method;
- this.classTree = classTree;
- }
-
- @Override
- public Tree getCode() {
- return method.getBody();
- }
-
- public MethodTree getMethod() {
- return method;
- }
-
- public ClassTree getClassTree() {
- return classTree;
- }
-
- @Override
- public String toString() {
- return "CFGMethod(\n" + method + "\n)";
- }
- }
-
- /** If the underlying AST is a lambda. */
- public static class CFGLambda extends UnderlyingAST {
-
- private final LambdaExpressionTree lambda;
-
- public CFGLambda(LambdaExpressionTree lambda) {
- super(Kind.LAMBDA);
- this.lambda = lambda;
- }
-
- @Override
- public Tree getCode() {
- return lambda.getBody();
- }
-
- public LambdaExpressionTree getLambdaTree() {
- return lambda;
- }
-
- @Override
- public String toString() {
- return "CFGLambda(\n" + lambda + "\n)";
- }
- }
-
- /** If the underlying AST is a statement or expression. */
- public static class CFGStatement extends UnderlyingAST {
-
- protected final Tree code;
-
- /** The class tree this method belongs to. */
- protected final ClassTree classTree;
-
- public CFGStatement(Tree code, ClassTree classTree) {
- super(Kind.ARBITRARY_CODE);
- this.code = code;
- this.classTree = classTree;
- }
-
- @Override
- public Tree getCode() {
- return code;
- }
-
- public ClassTree getClassTree() {
- return classTree;
- }
-
- @Override
- public String toString() {
- return "CFGStatement(\n" + code + "\n)";
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/Block.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/Block.java
deleted file mode 100644
index 2d58550568..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/Block.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-/**
- * Represents a basic block in a control flow graph.
- *
- * @author Stefan Heule
- */
-public interface Block {
-
- /** The types of basic blocks */
- public static enum BlockType {
-
- /** A regular basic block. */
- REGULAR_BLOCK,
-
- /** A conditional basic block. */
- CONDITIONAL_BLOCK,
-
- /** A special basic block. */
- SPECIAL_BLOCK,
-
- /** A basic block that can throw an exception. */
- EXCEPTION_BLOCK,
- }
-
- /** @return the type of this basic block */
- BlockType getType();
-
- /** @return the unique identifier of this block */
- long getId();
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/BlockImpl.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/BlockImpl.java
deleted file mode 100644
index 0421a1e3f5..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/BlockImpl.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Base class of the {@link Block} implementation hierarchy.
- *
- * @author Stefan Heule
- */
-public abstract class BlockImpl implements Block {
-
- /** A unique ID for this node. */
- protected long id = BlockImpl.uniqueID();
-
- /** The last ID that has already been used. */
- protected static long lastId = 0;
-
- /** The type of this basic block. */
- protected BlockType type;
-
- /** The set of predecessors. */
- protected Set<BlockImpl> predecessors;
-
- /** @return a fresh identifier */
- private static long uniqueID() {
- return lastId++;
- }
-
- public BlockImpl() {
- predecessors = new HashSet<>();
- }
-
- @Override
- public long getId() {
- return id;
- }
-
- @Override
- public BlockType getType() {
- return type;
- }
-
- /** @return the list of predecessors of this basic block */
- public Set<BlockImpl> getPredecessors() {
- return Collections.unmodifiableSet(predecessors);
- }
-
- public void addPredecessor(BlockImpl pred) {
- predecessors.add(pred);
- }
-
- public void removePredecessor(BlockImpl pred) {
- predecessors.remove(pred);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlock.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlock.java
deleted file mode 100644
index dce04abdfe..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlock.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-import org.checkerframework.dataflow.analysis.Store;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-/**
- * Represents a conditional basic block that contains exactly one boolean {@link Node}.
- *
- * @author Stefan Heule
- */
-public interface ConditionalBlock extends Block {
-
- /** @return the entry block of the then branch */
- Block getThenSuccessor();
-
- /** @return the entry block of the else branch */
- Block getElseSuccessor();
-
- /** @return the flow rule for information flowing from this block to its then successor */
- Store.FlowRule getThenFlowRule();
-
- /** @return the flow rule for information flowing from this block to its else successor */
- Store.FlowRule getElseFlowRule();
-
- /** Set the flow rule for information flowing from this block to its then successor. */
- void setThenFlowRule(Store.FlowRule rule);
-
- /** Set the flow rule for information flowing from this block to its else successor. */
- void setElseFlowRule(Store.FlowRule rule);
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlockImpl.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlockImpl.java
deleted file mode 100644
index bd12522983..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ConditionalBlockImpl.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-import org.checkerframework.dataflow.analysis.Store;
-
-/**
- * Implementation of a conditional basic block.
- *
- * @author Stefan Heule
- */
-public class ConditionalBlockImpl extends BlockImpl implements ConditionalBlock {
-
- /** Successor of the then branch. */
- protected BlockImpl thenSuccessor;
-
- /** Successor of the else branch. */
- protected BlockImpl elseSuccessor;
-
- /**
- * The rules below say that the THEN store before a conditional block flows to BOTH of the
- * stores of the then successor, while the ELSE store before a conditional block flows to BOTH
- * of the stores of the else successor.
- */
- protected Store.FlowRule thenFlowRule = Store.FlowRule.THEN_TO_BOTH;
-
- protected Store.FlowRule elseFlowRule = Store.FlowRule.ELSE_TO_BOTH;
-
- /**
- * Initialize an empty conditional basic block to be filled with contents and linked to other
- * basic blocks later.
- */
- public ConditionalBlockImpl() {
- type = BlockType.CONDITIONAL_BLOCK;
- }
-
- /** Set the then branch successor. */
- public void setThenSuccessor(BlockImpl b) {
- thenSuccessor = b;
- b.addPredecessor(this);
- }
-
- /** Set the else branch successor. */
- public void setElseSuccessor(BlockImpl b) {
- elseSuccessor = b;
- b.addPredecessor(this);
- }
-
- @Override
- public Block getThenSuccessor() {
- return thenSuccessor;
- }
-
- @Override
- public Block getElseSuccessor() {
- return elseSuccessor;
- }
-
- @Override
- public Store.FlowRule getThenFlowRule() {
- return thenFlowRule;
- }
-
- @Override
- public Store.FlowRule getElseFlowRule() {
- return elseFlowRule;
- }
-
- @Override
- public void setThenFlowRule(Store.FlowRule rule) {
- thenFlowRule = rule;
- }
-
- @Override
- public void setElseFlowRule(Store.FlowRule rule) {
- elseFlowRule = rule;
- }
-
- @Override
- public String toString() {
- return "ConditionalBlock()";
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlock.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlock.java
deleted file mode 100644
index a549c5f03f..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlock.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-import java.util.Map;
-import java.util.Set;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-/**
- * Represents a basic block that contains exactly one {@link Node} which can throw an exception.
- * This block has exactly one non-exceptional successor, and one or more exceptional successors.
- *
- * <p>The following invariant holds.
- *
- * <pre>
- * getNode().getBlock() == this
- * </pre>
- *
- * @author Stefan Heule
- */
-public interface ExceptionBlock extends SingleSuccessorBlock {
-
- /** @return the node of this block */
- Node getNode();
-
- /** @return the list of exceptional successor blocks as an unmodifiable map */
- Map<TypeMirror, Set<Block>> getExceptionalSuccessors();
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlockImpl.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlockImpl.java
deleted file mode 100644
index 2a6c3b4914..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/ExceptionBlockImpl.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-/**
- * Base class of the {@link Block} implementation hierarchy.
- *
- * @author Stefan Heule
- */
-public class ExceptionBlockImpl extends SingleSuccessorBlockImpl implements ExceptionBlock {
-
- /** Set of exceptional successors. */
- protected Map<TypeMirror, Set<Block>> exceptionalSuccessors;
-
- public ExceptionBlockImpl() {
- type = BlockType.EXCEPTION_BLOCK;
- exceptionalSuccessors = new HashMap<>();
- }
-
- /** The node of this block. */
- protected Node node;
-
- /** Set the node. */
- public void setNode(Node c) {
- node = c;
- c.setBlock(this);
- }
-
- @Override
- public Node getNode() {
- return node;
- }
-
- /** Add an exceptional successor. */
- public void addExceptionalSuccessor(BlockImpl b, TypeMirror cause) {
- if (exceptionalSuccessors == null) {
- exceptionalSuccessors = new HashMap<>();
- }
- Set<Block> blocks = exceptionalSuccessors.get(cause);
- if (blocks == null) {
- blocks = new HashSet<Block>();
- exceptionalSuccessors.put(cause, blocks);
- }
- blocks.add(b);
- b.addPredecessor(this);
- }
-
- @Override
- public Map<TypeMirror, Set<Block>> getExceptionalSuccessors() {
- if (exceptionalSuccessors == null) {
- return Collections.emptyMap();
- }
- return Collections.unmodifiableMap(exceptionalSuccessors);
- }
-
- @Override
- public String toString() {
- return "ExceptionBlock(" + node + ")";
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlock.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlock.java
deleted file mode 100644
index 566449257b..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlock.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-import java.util.List;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-/**
- * A regular basic block that contains a sequence of {@link Node}s.
- *
- * <p>The following invariant holds.
- *
- * <pre>
- * forall n in getContents() :: n.getBlock() == this
- * </pre>
- *
- * @author Stefan Heule
- */
-public interface RegularBlock extends SingleSuccessorBlock {
-
- /** @return the unmodifiable sequence of {@link Node}s. */
- List<Node> getContents();
-
- /** @return the regular successor block */
- Block getRegularSuccessor();
-
- /** Is this block empty (i.e., does it not contain any contents). */
- boolean isEmpty();
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlockImpl.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlockImpl.java
deleted file mode 100644
index b302710d70..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/RegularBlockImpl.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-/**
- * Implementation of a regular basic block.
- *
- * @author Stefan Heule
- */
-public class RegularBlockImpl extends SingleSuccessorBlockImpl implements RegularBlock {
-
- /** Internal representation of the contents. */
- protected List<Node> contents;
-
- /**
- * Initialize an empty basic block to be filled with contents and linked to other basic blocks
- * later.
- */
- public RegularBlockImpl() {
- contents = new LinkedList<>();
- type = BlockType.REGULAR_BLOCK;
- }
-
- /** Add a node to the contents of this basic block. */
- public void addNode(Node t) {
- contents.add(t);
- t.setBlock(this);
- }
-
- /** Add multiple nodes to the contents of this basic block. */
- public void addNodes(List<? extends Node> ts) {
- for (Node t : ts) {
- addNode(t);
- }
- }
-
- @Override
- public List<Node> getContents() {
- return Collections.unmodifiableList(contents);
- }
-
- @Override
- public BlockImpl getRegularSuccessor() {
- return successor;
- }
-
- @Override
- public String toString() {
- return "RegularBlock(" + contents + ")";
- }
-
- @Override
- public boolean isEmpty() {
- return contents.isEmpty();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlock.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlock.java
deleted file mode 100644
index 038a69d3e4..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlock.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import org.checkerframework.dataflow.analysis.Store;
-
-/**
- * A basic block that has at exactly one non-exceptional successor.
- *
- * @author Stefan Heule
- */
-public interface SingleSuccessorBlock extends Block {
-
- /** @return the non-exceptional successor block, or {@code null} if there is no successor. */
- /*@Nullable*/ Block getSuccessor();
-
- /** @return the flow rule for information flowing from this block to its successor */
- Store.FlowRule getFlowRule();
-
- /** Set the flow rule for information flowing from this block to its successor. */
- void setFlowRule(Store.FlowRule rule);
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlockImpl.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlockImpl.java
deleted file mode 100644
index 9e8872e850..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SingleSuccessorBlockImpl.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import org.checkerframework.dataflow.analysis.Store;
-
-/**
- * Implementation of a non-special basic block.
- *
- * @author Stefan Heule
- */
-public abstract class SingleSuccessorBlockImpl extends BlockImpl implements SingleSuccessorBlock {
-
- /** Internal representation of the successor. */
- protected /*@Nullable*/ BlockImpl successor;
-
- /**
- * The rule below say that EACH store at the end of a single successor block flow to the
- * corresponding store of the successor.
- */
- protected Store.FlowRule flowRule = Store.FlowRule.EACH_TO_EACH;
-
- @Override
- public /*@Nullable*/ Block getSuccessor() {
- return successor;
- }
-
- /** Set a basic block as the successor of this block. */
- public void setSuccessor(BlockImpl successor) {
- this.successor = successor;
- successor.addPredecessor(this);
- }
-
- @Override
- public Store.FlowRule getFlowRule() {
- return flowRule;
- }
-
- @Override
- public void setFlowRule(Store.FlowRule rule) {
- flowRule = rule;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlock.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlock.java
deleted file mode 100644
index dac9b4b8c2..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlock.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-/**
- * Represents a special basic block; i.e., one of the following:
- *
- * <ul>
- * <li>Entry block of a method.
- * <li>Regular exit block of a method.
- * <li>Exceptional exit block of a method.
- * </ul>
- *
- * @author Stefan Heule
- */
-public interface SpecialBlock extends SingleSuccessorBlock {
-
- /** The types of special basic blocks */
- public static enum SpecialBlockType {
-
- /** The entry block of a method */
- ENTRY,
-
- /** The exit block of a method */
- EXIT,
-
- /** A special exit block of a method for exceptional termination */
- EXCEPTIONAL_EXIT,
- }
-
- /** @return the type of this special basic block */
- SpecialBlockType getSpecialType();
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlockImpl.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlockImpl.java
deleted file mode 100644
index e6f25e8b1b..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/block/SpecialBlockImpl.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.checkerframework.dataflow.cfg.block;
-
-public class SpecialBlockImpl extends SingleSuccessorBlockImpl implements SpecialBlock {
-
- /** The type of this special basic block. */
- protected SpecialBlockType specialType;
-
- public SpecialBlockImpl(SpecialBlockType type) {
- this.specialType = type;
- this.type = BlockType.SPECIAL_BLOCK;
- }
-
- @Override
- public SpecialBlockType getSpecialType() {
- return specialType;
- }
-
- @Override
- public String toString() {
- return "SpecialBlock(" + specialType + ")";
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java
deleted file mode 100644
index 39f1f84074..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AbstractNodeVisitor.java
+++ /dev/null
@@ -1,374 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/**
- * A default implementation of the node visitor interface. The class introduces several 'summary'
- * methods, that can be overridden to change the behavior of several related visit methods at once.
- * An example is the {@code visitValueLiteral} method, that is called for every {@link
- * ValueLiteralNode}.
- *
- * <p>This is useful to implement a visitor that performs the same operation (e.g., nothing) for
- * most {@link Node}s and only has special behavior for a few.
- *
- * @author Stefan Heule
- * @param <R> return type of the visitor
- * @param <P> parameter type of the visitor
- */
-public abstract class AbstractNodeVisitor<R, P> implements NodeVisitor<R, P> {
-
- public abstract R visitNode(Node n, P p);
-
- public R visitValueLiteral(ValueLiteralNode n, P p) {
- return visitNode(n, p);
- }
-
- // Literals
- @Override
- public R visitShortLiteral(ShortLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitIntegerLiteral(IntegerLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitLongLiteral(LongLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitFloatLiteral(FloatLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitDoubleLiteral(DoubleLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitBooleanLiteral(BooleanLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitCharacterLiteral(CharacterLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitStringLiteral(StringLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- @Override
- public R visitNullLiteral(NullLiteralNode n, P p) {
- return visitValueLiteral(n, p);
- }
-
- // Unary operations
- @Override
- public R visitNumericalMinus(NumericalMinusNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitNumericalPlus(NumericalPlusNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitBitwiseComplement(BitwiseComplementNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitNullChk(NullChkNode n, P p) {
- return visitNode(n, p);
- }
-
- // Binary operations
- @Override
- public R visitStringConcatenate(StringConcatenateNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitNumericalAddition(NumericalAdditionNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitNumericalSubtraction(NumericalSubtractionNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitNumericalMultiplication(NumericalMultiplicationNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitIntegerDivision(IntegerDivisionNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitFloatingDivision(FloatingDivisionNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitIntegerRemainder(IntegerRemainderNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitFloatingRemainder(FloatingRemainderNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitLeftShift(LeftShiftNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitSignedRightShift(SignedRightShiftNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitUnsignedRightShift(UnsignedRightShiftNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitBitwiseAnd(BitwiseAndNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitBitwiseOr(BitwiseOrNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitBitwiseXor(BitwiseXorNode n, P p) {
- return visitNode(n, p);
- }
-
- // Compound assignments
- @Override
- public R visitStringConcatenateAssignment(StringConcatenateAssignmentNode n, P p) {
- return visitNode(n, p);
- }
-
- // Comparison operations
- @Override
- public R visitLessThan(LessThanNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitLessThanOrEqual(LessThanOrEqualNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitGreaterThan(GreaterThanNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitGreaterThanOrEqual(GreaterThanOrEqualNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitEqualTo(EqualToNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitNotEqual(NotEqualNode n, P p) {
- return visitNode(n, p);
- }
-
- // Conditional operations
- @Override
- public R visitConditionalAnd(ConditionalAndNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitConditionalOr(ConditionalOrNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitConditionalNot(ConditionalNotNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitTernaryExpression(TernaryExpressionNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitAssignment(AssignmentNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitLocalVariable(LocalVariableNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitVariableDeclaration(VariableDeclarationNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitFieldAccess(FieldAccessNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitMethodAccess(MethodAccessNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitArrayAccess(ArrayAccessNode n, P p) {
- return visitNode(n, p);
- }
-
- public R visitThisLiteral(ThisLiteralNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitImplicitThisLiteral(ImplicitThisLiteralNode n, P p) {
- return visitThisLiteral(n, p);
- }
-
- @Override
- public R visitExplicitThisLiteral(ExplicitThisLiteralNode n, P p) {
- return visitThisLiteral(n, p);
- }
-
- @Override
- public R visitSuper(SuperNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitReturn(ReturnNode n, P p) {
- return visitNode(n, p);
- };
-
- @Override
- public R visitStringConversion(StringConversionNode n, P p) {
- return visitNode(n, p);
- };
-
- @Override
- public R visitNarrowingConversion(NarrowingConversionNode n, P p) {
- return visitNode(n, p);
- };
-
- @Override
- public R visitWideningConversion(WideningConversionNode n, P p) {
- return visitNode(n, p);
- };
-
- @Override
- public R visitInstanceOf(InstanceOfNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitTypeCast(TypeCastNode n, P p) {
- return visitNode(n, p);
- }
-
- // Statements
- @Override
- public R visitAssertionError(AssertionErrorNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitSynchronized(SynchronizedNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitThrow(ThrowNode n, P p) {
- return visitNode(n, p);
- }
-
- // Cases
- @Override
- public R visitCase(CaseNode n, P p) {
- return visitNode(n, p);
- }
-
- // Method and constructor invocations
- @Override
- public R visitMethodInvocation(MethodInvocationNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitObjectCreation(ObjectCreationNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitMemberReference(FunctionalInterfaceNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitArrayCreation(ArrayCreationNode n, P p) {
- return visitNode(n, p);
- }
-
- // Type, package and class names
- @Override
- public R visitArrayType(ArrayTypeNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitPrimitiveType(PrimitiveTypeNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitClassName(ClassNameNode n, P p) {
- return visitNode(n, p);
- }
-
- @Override
- public R visitPackageName(PackageNameNode n, P p) {
- return visitNode(n, p);
- }
-
- // Parameterized types
- @Override
- public R visitParameterizedType(ParameterizedTypeNode n, P p) {
- return visitNode(n, p);
- }
-
- // Marker nodes
- @Override
- public R visitMarker(MarkerNode n, P p) {
- return visitNode(n, p);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayAccessNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayAccessNode.java
deleted file mode 100644
index 24ef689ee9..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayAccessNode.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for an array access:
- *
- * <pre>
- * <em>arrayref</em> [ <em>index</em> ]
- * </pre>
- *
- * We allow array accesses without corresponding AST {@link Tree}s.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ArrayAccessNode extends Node {
-
- protected Tree tree;
- protected Node array;
- protected Node index;
-
- public ArrayAccessNode(Tree t, Node array, Node index) {
- super(InternalUtils.typeOf(t));
- assert t instanceof ArrayAccessTree;
- this.tree = t;
- this.array = array;
- this.index = index;
- }
-
- public Node getArray() {
- return array;
- }
-
- public Node getIndex() {
- return index;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitArrayAccess(this, p);
- }
-
- @Override
- public String toString() {
- String base = getArray().toString() + "[" + getIndex().toString() + "]";
- return base;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ArrayAccessNode)) {
- return false;
- }
- ArrayAccessNode other = (ArrayAccessNode) obj;
- return getArray().equals(other.getArray()) && getIndex().equals(other.getIndex());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getArray(), getIndex());
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(getArray());
- list.add(getIndex());
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayCreationNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayCreationNode.java
deleted file mode 100644
index 5f277f2a0b..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayCreationNode.java
+++ /dev/null
@@ -1,136 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.NewArrayTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for new array creation
- *
- * <pre>
- * <em>new type [1][2]</em>
- * <em>new type [] = { expr1, expr2, ... }</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ArrayCreationNode extends Node {
-
- /** The tree is null when an array is created for variable arity method calls. */
- protected /*@Nullable*/ NewArrayTree tree;
- /**
- * The length of this list is the number of dimensions in the array. Each element is the size of
- * the given dimension.
- */
- protected List<Node> dimensions;
-
- protected List<Node> initializers;
-
- public ArrayCreationNode(
- /*@Nullable*/ NewArrayTree tree,
- TypeMirror type,
- List<Node> dimensions,
- List<Node> initializers) {
- super(type);
- this.tree = tree;
- this.dimensions = dimensions;
- this.initializers = initializers;
- }
-
- public List<Node> getDimensions() {
- return dimensions;
- }
-
- public Node getDimension(int i) {
- return dimensions.get(i);
- }
-
- public List<Node> getInitializers() {
- return initializers;
- }
-
- public Node getInitializer(int i) {
- return initializers.get(i);
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitArrayCreation(this, p);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("new " + type);
- if (!dimensions.isEmpty()) {
- boolean needComma = false;
- sb.append(" (");
- for (Node dim : dimensions) {
- if (needComma) {
- sb.append(", ");
- }
- sb.append(dim);
- needComma = true;
- }
- sb.append(")");
- }
- if (!initializers.isEmpty()) {
- boolean needComma = false;
- sb.append(" = {");
- for (Node init : initializers) {
- if (needComma) {
- sb.append(", ");
- }
- sb.append(init);
- needComma = true;
- }
- sb.append("}");
- }
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ArrayCreationNode)) {
- return false;
- }
- ArrayCreationNode other = (ArrayCreationNode) obj;
-
- return getDimensions().equals(other.getDimensions())
- && getInitializers().equals(other.getInitializers());
- }
-
- @Override
- public int hashCode() {
- int hash = 0;
- for (Node dim : dimensions) {
- hash = HashCodeUtils.hash(hash, dim.hashCode());
- }
- for (Node init : initializers) {
- hash = HashCodeUtils.hash(hash, init.hashCode());
- }
- return hash;
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.addAll(dimensions);
- list.addAll(initializers);
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayTypeNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayTypeNode.java
deleted file mode 100644
index dfde575b5e..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ArrayTypeNode.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.ArrayTypeTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node representing a array type used in an expression such as a field access
- *
- * <p><em>type</em> .class
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ArrayTypeNode extends Node {
-
- protected final ArrayTypeTree tree;
-
- public ArrayTypeNode(ArrayTypeTree tree) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitArrayType(this, p);
- }
-
- @Override
- public String toString() {
- return tree.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ArrayTypeNode)) {
- return false;
- }
- ArrayTypeNode other = (ArrayTypeNode) obj;
- return getType().equals(other.getType());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getType());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssertionErrorNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssertionErrorNode.java
deleted file mode 100644
index 0b4d747331..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssertionErrorNode.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.Tree.Kind;
-import java.util.Collection;
-import java.util.LinkedList;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the {@link AssertionError} when an assertion fails.
- *
- * <pre>
- * assert <em>condition</em> : <em>detail</em> ;
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class AssertionErrorNode extends Node {
-
- protected Tree tree;
- protected Node condition;
- protected Node detail;
-
- public AssertionErrorNode(Tree tree, Node condition, Node detail, TypeMirror type) {
- // TODO: Find out the correct "type" for statements.
- // Is it TypeKind.NONE?
- super(type);
- assert tree.getKind() == Kind.ASSERT;
- this.tree = tree;
- this.condition = condition;
- this.detail = detail;
- }
-
- public Node getCondition() {
- return condition;
- }
-
- public Node getDetail() {
- return detail;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitAssertionError(this, p);
- }
-
- @Override
- public String toString() {
- return "AssertionError(" + getDetail() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof AssertionErrorNode)) {
- return false;
- }
- AssertionErrorNode other = (AssertionErrorNode) obj;
- return getCondition().equals(other.getCondition()) && getDetail().equals(other.getDetail());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getCondition(), getDetail());
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(getCondition());
- list.add(getDetail());
- return list;
- }
-}
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
deleted file mode 100644
index 5e6a1606de..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentContext.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * 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();
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentNode.java
deleted file mode 100644
index 32723dd8e4..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/AssignmentNode.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.CompoundAssignmentTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.UnaryTree;
-import com.sun.source.tree.VariableTree;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.checkerframework.dataflow.cfg.node.AssignmentContext.AssignmentLhsContext;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for an assignment:
- *
- * <pre>
- * <em>variable</em> = <em>expression</em>
- * <em>expression</em> . <em>field</em> = <em>expression</em>
- * <em>expression</em> [ <em>index</em> ] = <em>expression</em>
- * </pre>
- *
- * We allow assignments without corresponding AST {@link Tree}s.
- *
- * @author Stefan Heule
- */
-public class AssignmentNode extends Node {
-
- protected Tree tree;
- protected Node lhs;
- protected Node rhs;
-
- public AssignmentNode(Tree tree, Node target, Node expression) {
- super(InternalUtils.typeOf(tree));
- assert tree instanceof AssignmentTree
- || tree instanceof VariableTree
- || tree instanceof CompoundAssignmentTree
- || tree instanceof UnaryTree;
- assert target instanceof FieldAccessNode
- || target instanceof LocalVariableNode
- || target instanceof ArrayAccessNode;
- this.tree = tree;
- this.lhs = target;
- this.rhs = expression;
- rhs.setAssignmentContext(new AssignmentLhsContext(lhs));
- }
-
- public Node getTarget() {
- return lhs;
- }
-
- public Node getExpression() {
- return rhs;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitAssignment(this, p);
- }
-
- @Override
- public String toString() {
- return getTarget() + " = " + getExpression();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof AssignmentNode)) {
- return false;
- }
- AssignmentNode other = (AssignmentNode) obj;
- return getTarget().equals(other.getTarget())
- && getExpression().equals(other.getExpression());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getTarget(), getExpression());
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(getTarget());
- list.add(getExpression());
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BinaryOperationNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BinaryOperationNode.java
deleted file mode 100644
index 424747b4ac..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BinaryOperationNode.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for a binary expression.
- *
- * <p>For example:
- *
- * <pre>
- * <em>lefOperandNode</em> <em>operator</em> <em>rightOperandNode</em>
- * </pre>
- *
- * @author charleszhuochen
- */
-public abstract class BinaryOperationNode extends Node {
-
- protected final BinaryTree tree;
- protected final Node left;
- protected final Node right;
-
- public BinaryOperationNode(BinaryTree tree, Node left, Node right) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- this.left = left;
- this.right = right;
- }
-
- public Node getLeftOperand() {
- return left;
- }
-
- public Node getRightOperand() {
- return right;
- }
-
- @Override
- public BinaryTree getTree() {
- return tree;
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(getLeftOperand());
- list.add(getRightOperand());
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseAndNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseAndNode.java
deleted file mode 100644
index 18d7163f22..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseAndNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the bitwise or logical (single bit) and operation:
- *
- * <pre>
- * <em>expression</em> &amp; <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class BitwiseAndNode extends BinaryOperationNode {
-
- public BitwiseAndNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.AND;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitBitwiseAnd(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " & " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof BitwiseAndNode)) {
- return false;
- }
- BitwiseAndNode other = (BitwiseAndNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseComplementNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseComplementNode.java
deleted file mode 100644
index a1c2111b8c..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseComplementNode.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.tree.UnaryTree;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the bitwise complement operation:
- *
- * <pre>
- * ~ <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class BitwiseComplementNode extends UnaryOperationNode {
-
- public BitwiseComplementNode(UnaryTree tree, Node operand) {
- super(tree, operand);
- assert tree.getKind() == Kind.BITWISE_COMPLEMENT;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitBitwiseComplement(this, p);
- }
-
- @Override
- public String toString() {
- return "(~ " + getOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof BitwiseComplementNode)) {
- return false;
- }
- BitwiseComplementNode other = (BitwiseComplementNode) obj;
- return getOperand().equals(other.getOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseOrNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseOrNode.java
deleted file mode 100644
index 66089133f2..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseOrNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the bitwise or logical (single bit) or operation:
- *
- * <pre>
- * <em>expression</em> | <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class BitwiseOrNode extends BinaryOperationNode {
-
- public BitwiseOrNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.OR;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitBitwiseOr(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " | " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof BitwiseOrNode)) {
- return false;
- }
- BitwiseOrNode other = (BitwiseOrNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseXorNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseXorNode.java
deleted file mode 100644
index cdbe0ed93d..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BitwiseXorNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the bitwise or logical (single bit) xor operation:
- *
- * <pre>
- * <em>expression</em> ^ <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class BitwiseXorNode extends BinaryOperationNode {
-
- public BitwiseXorNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.XOR;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitBitwiseXor(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " ^ " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof BitwiseXorNode)) {
- return false;
- }
- BitwiseXorNode other = (BitwiseXorNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BooleanLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BooleanLiteralNode.java
deleted file mode 100644
index 7f5a7a1eda..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/BooleanLiteralNode.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for a boolean literal:
- *
- * <pre>
- * <em>true</em>
- * <em>false</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class BooleanLiteralNode extends ValueLiteralNode {
-
- public BooleanLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.BOOLEAN_LITERAL);
- }
-
- @Override
- public Boolean getValue() {
- return (Boolean) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitBooleanLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a BooleanLiteralNode
- if (!(obj instanceof BooleanLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CaseNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CaseNode.java
deleted file mode 100644
index a694dfb975..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CaseNode.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.CaseTree;
-import com.sun.source.tree.Tree.Kind;
-import java.util.Collection;
-import java.util.LinkedList;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for a case in a switch statement. Although a case has no abstract value, it can imply
- * facts about the abstract values of its operands.
- *
- * <pre>
- * case <em>constant</em>:
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class CaseNode extends Node {
-
- protected CaseTree tree;
- protected Node switchExpr;
- protected Node caseExpr;
-
- public CaseNode(CaseTree tree, Node switchExpr, Node caseExpr, Types types) {
- super(types.getNoType(TypeKind.NONE));
- assert tree.getKind().equals(Kind.CASE);
- this.tree = tree;
- this.switchExpr = switchExpr;
- this.caseExpr = caseExpr;
- }
-
- public Node getSwitchOperand() {
- return switchExpr;
- }
-
- public Node getCaseOperand() {
- return caseExpr;
- }
-
- @Override
- public CaseTree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitCase(this, p);
- }
-
- @Override
- public String toString() {
- return "case " + getCaseOperand() + ":";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof CaseNode)) {
- return false;
- }
- CaseNode other = (CaseNode) obj;
- return getSwitchOperand().equals(other.getSwitchOperand())
- && getCaseOperand().equals(other.getCaseOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getSwitchOperand(), getCaseOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(getSwitchOperand());
- list.add(getCaseOperand());
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CharacterLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CharacterLiteralNode.java
deleted file mode 100644
index c1d51c7523..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/CharacterLiteralNode.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for a character literal. For example:
- *
- * <pre>
- * <em>'a'</em>
- * <em>'\t'</em>
- * <em>'\u03a9'</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class CharacterLiteralNode extends ValueLiteralNode {
-
- public CharacterLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.CHAR_LITERAL);
- }
-
- @Override
- public Character getValue() {
- return (Character) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitCharacterLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a CharacterLiteralNode
- if (obj == null || !(obj instanceof CharacterLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java
deleted file mode 100644
index c3e2471309..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ClassNameNode.java
+++ /dev/null
@@ -1,120 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.element.Element;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * A node representing a class name used in an expression such as a static method invocation.
- *
- * <p>parent.<em>class</em> .forName(...)
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ClassNameNode extends Node {
-
- protected final Tree tree;
- /** The class named by this node */
- protected final Element element;
-
- /** The parent name, if any. */
- protected final /*@Nullable*/ Node parent;
-
- public ClassNameNode(IdentifierTree tree) {
- super(InternalUtils.typeOf(tree));
- assert tree.getKind() == Tree.Kind.IDENTIFIER;
- this.tree = tree;
- this.element = TreeUtils.elementFromUse(tree);
- this.parent = null;
- }
-
- public ClassNameNode(ClassTree tree) {
- super(InternalUtils.typeOf(tree));
- assert tree.getKind() == Tree.Kind.CLASS
- || tree.getKind() == Tree.Kind.ENUM
- || tree.getKind() == Tree.Kind.INTERFACE
- || tree.getKind() == Tree.Kind.ANNOTATION_TYPE;
- this.tree = tree;
- this.element = TreeUtils.elementFromDeclaration(tree);
- this.parent = null;
- }
-
- public ClassNameNode(MemberSelectTree tree, Node parent) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- this.element = TreeUtils.elementFromUse(tree);
- this.parent = parent;
- }
-
- public ClassNameNode(TypeMirror type, Element element) {
- super(type);
- this.tree = null;
- this.element = element;
- this.parent = null;
- }
-
- public Element getElement() {
- return element;
- }
-
- public Node getParent() {
- return parent;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitClassName(this, p);
- }
-
- @Override
- public String toString() {
- return getElement().getSimpleName().toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ClassNameNode)) {
- return false;
- }
- ClassNameNode other = (ClassNameNode) obj;
- if (getParent() == null) {
- return other.getParent() == null && getElement().equals(other.getElement());
- } else {
- return getParent().equals(other.getParent()) && getElement().equals(other.getElement());
- }
- }
-
- @Override
- public int hashCode() {
- if (parent == null) {
- return HashCodeUtils.hash(getElement());
- }
- return HashCodeUtils.hash(getElement(), getParent());
- }
-
- @Override
- public Collection<Node> getOperands() {
- if (parent == null) {
- return Collections.emptyList();
- }
- return Collections.singleton(parent);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalAndNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalAndNode.java
deleted file mode 100644
index fb5145ab89..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalAndNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for a conditional and expression:
- *
- * <pre>
- * <em>expression</em> &amp;&amp; <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ConditionalAndNode extends BinaryOperationNode {
-
- public ConditionalAndNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind().equals(Kind.CONDITIONAL_AND);
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitConditionalAnd(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " && " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ConditionalAndNode)) {
- return false;
- }
- ConditionalAndNode other = (ConditionalAndNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalNotNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalNotNode.java
deleted file mode 100644
index 6a28c67a16..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalNotNode.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.tree.UnaryTree;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for a conditional not expression:
- *
- * <pre>
- * ! <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ConditionalNotNode extends UnaryOperationNode {
-
- public ConditionalNotNode(UnaryTree tree, Node operand) {
- super(tree, operand);
- assert tree.getKind().equals(Kind.LOGICAL_COMPLEMENT);
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitConditionalNot(this, p);
- }
-
- @Override
- public String toString() {
- return "(!" + getOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ConditionalNotNode)) {
- return false;
- }
- ConditionalNotNode other = (ConditionalNotNode) obj;
- return getOperand().equals(other.getOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalOrNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalOrNode.java
deleted file mode 100644
index e5cb0bfc13..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ConditionalOrNode.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for a conditional or expression:
- *
- * <pre>
- * <em>expression</em> || <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class ConditionalOrNode extends BinaryOperationNode {
-
- public ConditionalOrNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind().equals(Kind.CONDITIONAL_OR);
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitConditionalOr(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " || " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ConditionalOrNode)) {
- return false;
- }
- ConditionalOrNode other = (ConditionalOrNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/DoubleLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/DoubleLiteralNode.java
deleted file mode 100644
index 60c25749a4..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/DoubleLiteralNode.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for a double literal. For example:
- *
- * <pre>
- * <em>-9.</em>
- * <em>3.14159D</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class DoubleLiteralNode extends ValueLiteralNode {
-
- public DoubleLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.DOUBLE_LITERAL);
- }
-
- @Override
- public Double getValue() {
- return (Double) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitDoubleLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a DoubleLiteralNode
- if (obj == null || !(obj instanceof DoubleLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/EqualToNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/EqualToNode.java
deleted file mode 100644
index b1fb5d8f68..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/EqualToNode.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for an equality check:
- *
- * <pre>
- * <em>expression</em> == <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class EqualToNode extends BinaryOperationNode {
-
- public EqualToNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind().equals(Kind.EQUAL_TO);
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitEqualTo(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " == " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof EqualToNode)) {
- return false;
- }
- EqualToNode other = (EqualToNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ExplicitThisLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ExplicitThisLiteralNode.java
deleted file mode 100644
index abb3b5447e..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ExplicitThisLiteralNode.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.Tree;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for a reference to 'this'.
- *
- * <pre>
- * <em>this</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ExplicitThisLiteralNode extends ThisLiteralNode {
-
- protected Tree tree;
-
- public ExplicitThisLiteralNode(Tree t) {
- super(InternalUtils.typeOf(t));
- assert t instanceof IdentifierTree && ((IdentifierTree) t).getName().contentEquals("this");
- tree = t;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitExplicitThisLiteral(this, p);
- }
-
- @Override
- public String toString() {
- return getName();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java
deleted file mode 100644
index 1b8e856a17..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FieldAccessNode.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.element.VariableElement;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.ElementUtils;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * A node for a field access, including a method accesses:
- *
- * <pre>
- * <em>expression</em> . <em>field</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class FieldAccessNode extends Node {
-
- protected Tree tree;
- protected VariableElement element;
- protected String field;
- protected Node receiver;
-
- // TODO: add method to get modifiers (static, access level, ..)
-
- public FieldAccessNode(Tree tree, Node receiver) {
- super(InternalUtils.typeOf(tree));
- assert TreeUtils.isFieldAccess(tree);
- this.tree = tree;
- this.receiver = receiver;
- this.field = TreeUtils.getFieldName(tree);
-
- if (tree instanceof MemberSelectTree) {
- this.element = (VariableElement) TreeUtils.elementFromUse((MemberSelectTree) tree);
- } else {
- assert tree instanceof IdentifierTree;
- this.element = (VariableElement) TreeUtils.elementFromUse((IdentifierTree) tree);
- }
- }
-
- public FieldAccessNode(Tree tree, VariableElement element, Node receiver) {
- super(element.asType());
- this.tree = tree;
- this.element = element;
- this.receiver = receiver;
- this.field = element.getSimpleName().toString();
- }
-
- public VariableElement getElement() {
- return element;
- }
-
- public Node getReceiver() {
- return receiver;
- }
-
- public String getFieldName() {
- return field;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitFieldAccess(this, p);
- }
-
- @Override
- public String toString() {
- return getReceiver() + "." + field;
- }
-
- /** Is this a static field? */
- public boolean isStatic() {
- return ElementUtils.isStatic(getElement());
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof FieldAccessNode)) {
- return false;
- }
- FieldAccessNode other = (FieldAccessNode) obj;
- return getReceiver().equals(other.getReceiver())
- && getFieldName().equals(other.getFieldName());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getReceiver(), getFieldName());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(receiver);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatLiteralNode.java
deleted file mode 100644
index ee8b5103ed..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatLiteralNode.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for a float literal. For example:
- *
- * <pre>
- * <em>8.0f</em>
- * <em>6.022137e+23F</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class FloatLiteralNode extends ValueLiteralNode {
-
- public FloatLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.FLOAT_LITERAL);
- }
-
- @Override
- public Float getValue() {
- return (Float) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitFloatLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a FloatLiteralNode
- if (obj == null || !(obj instanceof FloatLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingDivisionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingDivisionNode.java
deleted file mode 100644
index 6eb6c41ac4..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingDivisionNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the floating-point division:
- *
- * <pre>
- * <em>expression</em> / <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class FloatingDivisionNode extends BinaryOperationNode {
-
- public FloatingDivisionNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.DIVIDE;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitFloatingDivision(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " / " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof FloatingDivisionNode)) {
- return false;
- }
- FloatingDivisionNode other = (FloatingDivisionNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingRemainderNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingRemainderNode.java
deleted file mode 100644
index d3a7918ff1..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FloatingRemainderNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the floating-point remainder:
- *
- * <pre>
- * <em>expression</em> % <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class FloatingRemainderNode extends BinaryOperationNode {
-
- public FloatingRemainderNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.REMAINDER;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitFloatingRemainder(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " % " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof FloatingRemainderNode)) {
- return false;
- }
- FloatingRemainderNode other = (FloatingRemainderNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FunctionalInterfaceNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FunctionalInterfaceNode.java
deleted file mode 100644
index a0ddbaf10c..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/FunctionalInterfaceNode.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LambdaExpressionTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.checkerframework.javacutil.ErrorReporter;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for member references and lambdas.
- *
- * <p>The {@link Node#type} of a FunctionalInterfaceNode is determined by the assignment context the
- * member reference or lambda is used in.
- *
- * <pre>
- * <em>FunctionalInterface func = param1, param2, ... &rarr; statement</em>
- * </pre>
- *
- * <pre>
- * <em>FunctionalInterface func = param1, param2, ... &rarr; { ... }</em>
- * </pre>
- *
- * <pre>
- * <em>FunctionalInterface func = member reference</em>
- * </pre>
- *
- * @author David
- */
-public class FunctionalInterfaceNode extends Node {
-
- protected Tree tree;
-
- public FunctionalInterfaceNode(MemberReferenceTree tree) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- }
-
- public FunctionalInterfaceNode(LambdaExpressionTree tree) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitMemberReference(this, p);
- }
-
- @Override
- public String toString() {
- if (tree instanceof LambdaExpressionTree) {
- return "FunctionalInterfaceNode:" + ((LambdaExpressionTree) tree).getBodyKind();
- } else if (tree instanceof MemberReferenceTree) {
- return "FunctionalInterfaceNode:" + ((MemberReferenceTree) tree).getName();
- } else {
- // This should never happen.
- ErrorReporter.errorAbort("Invalid tree in FunctionalInterfaceNode");
- return null; // Dead code
- }
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
-
- FunctionalInterfaceNode that = (FunctionalInterfaceNode) o;
-
- if (tree != null ? !tree.equals(that.tree) : that.tree != null) return false;
-
- return true;
- }
-
- @Override
- public int hashCode() {
- return tree != null ? tree.hashCode() : 0;
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanNode.java
deleted file mode 100644
index f1713a9241..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the greater than comparison:
- *
- * <pre>
- * <em>expression</em> &gt; <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class GreaterThanNode extends BinaryOperationNode {
-
- public GreaterThanNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.GREATER_THAN;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitGreaterThan(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " > " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof GreaterThanNode)) {
- return false;
- }
- GreaterThanNode other = (GreaterThanNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanOrEqualNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanOrEqualNode.java
deleted file mode 100644
index 058ae7be84..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/GreaterThanOrEqualNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the greater than or equal comparison:
- *
- * <pre>
- * <em>expression</em> &gt;= <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class GreaterThanOrEqualNode extends BinaryOperationNode {
-
- public GreaterThanOrEqualNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.GREATER_THAN_EQUAL;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitGreaterThanOrEqual(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " >= " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof GreaterThanOrEqualNode)) {
- return false;
- }
- GreaterThanOrEqualNode other = (GreaterThanOrEqualNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ImplicitThisLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ImplicitThisLiteralNode.java
deleted file mode 100644
index 25a63617ad..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ImplicitThisLiteralNode.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import javax.lang.model.type.TypeMirror;
-
-/**
- * A node to model the implicit {@code this}, e.g., in a field access.
- *
- * @author Stefan Heule
- */
-public class ImplicitThisLiteralNode extends ThisLiteralNode {
-
- public ImplicitThisLiteralNode(TypeMirror type) {
- super(type);
- }
-
- @Override
- public Tree getTree() {
- return null;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitImplicitThisLiteral(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getName() + ")";
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/InstanceOfNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/InstanceOfNode.java
deleted file mode 100644
index 78b4e06916..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/InstanceOfNode.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.InstanceOfTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the instanceof operator:
- *
- * <p><em>x</em> instanceof <em>Point</em>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class InstanceOfNode extends Node {
-
- /** The value being tested. */
- protected Node operand;
-
- /** The reference type being tested against. */
- protected TypeMirror refType;
-
- /** The tree associated with this node. */
- protected final InstanceOfTree tree;
-
- public InstanceOfNode(Tree tree, Node operand, TypeMirror refType, Types types) {
- super(types.getPrimitiveType(TypeKind.BOOLEAN));
- assert tree.getKind() == Tree.Kind.INSTANCE_OF;
- this.tree = (InstanceOfTree) tree;
- this.operand = operand;
- this.refType = refType;
- }
-
- public Node getOperand() {
- return operand;
- }
-
- @Override
- public TypeMirror getType() {
- return type;
- }
-
- public TypeMirror getRefType() {
- return refType;
- }
-
- @Override
- public InstanceOfTree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitInstanceOf(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getOperand() + " instanceof " + getRefType() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof InstanceOfNode)) {
- return false;
- }
- InstanceOfNode other = (InstanceOfNode) obj;
- // TODO: TypeMirror.equals may be too restrictive.
- // Check whether Types.isSameType is the better comparison.
- return getOperand().equals(other.getOperand()) && getRefType().equals(other.getRefType());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerDivisionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerDivisionNode.java
deleted file mode 100644
index e69947bea5..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerDivisionNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the integer division:
- *
- * <pre>
- * <em>expression</em> / <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class IntegerDivisionNode extends BinaryOperationNode {
-
- public IntegerDivisionNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.DIVIDE;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitIntegerDivision(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " / " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof IntegerDivisionNode)) {
- return false;
- }
- IntegerDivisionNode other = (IntegerDivisionNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerLiteralNode.java
deleted file mode 100644
index 5bea779369..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerLiteralNode.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for an integer literal. For example:
- *
- * <pre>
- * <em>42</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class IntegerLiteralNode extends ValueLiteralNode {
-
- int value;
-
- public IntegerLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.INT_LITERAL);
- value = (Integer) tree.getValue();
- }
-
- @Override
- public Integer getValue() {
- return value;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitIntegerLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a IntegerLiteralNode
- if (!(obj instanceof IntegerLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerRemainderNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerRemainderNode.java
deleted file mode 100644
index d5399183a7..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/IntegerRemainderNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the integer remainder:
- *
- * <pre>
- * <em>expression</em> % <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class IntegerRemainderNode extends BinaryOperationNode {
-
- public IntegerRemainderNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.REMAINDER;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitIntegerRemainder(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " % " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof IntegerRemainderNode)) {
- return false;
- }
- IntegerRemainderNode other = (IntegerRemainderNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LeftShiftNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LeftShiftNode.java
deleted file mode 100644
index 65a1e13d3c..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LeftShiftNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for bitwise left shift operations:
- *
- * <pre>
- * <em>expression</em> &lt;&lt; <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class LeftShiftNode extends BinaryOperationNode {
-
- public LeftShiftNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.LEFT_SHIFT;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitLeftShift(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " << " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof LeftShiftNode)) {
- return false;
- }
- LeftShiftNode other = (LeftShiftNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanNode.java
deleted file mode 100644
index fcc901150a..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanNode.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the less than comparison:
- *
- * <pre>
- * <em>expression</em> &lt; <em>expression</em>
- * </pre>
- *
- * We allow less than nodes without corresponding AST {@link Tree}s.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class LessThanNode extends BinaryOperationNode {
-
- public LessThanNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.LESS_THAN;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitLessThan(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " < " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof LessThanNode)) {
- return false;
- }
- LessThanNode other = (LessThanNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanOrEqualNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanOrEqualNode.java
deleted file mode 100644
index 0dfb65ec41..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LessThanOrEqualNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the less than or equal comparison:
- *
- * <pre>
- * <em>expression</em> &lt;= <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class LessThanOrEqualNode extends BinaryOperationNode {
-
- public LessThanOrEqualNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.LESS_THAN_EQUAL;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitLessThanOrEqual(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " <= " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof LessThanOrEqualNode)) {
- return false;
- }
- LessThanOrEqualNode other = (LessThanOrEqualNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LocalVariableNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LocalVariableNode.java
deleted file mode 100644
index 724d63a46b..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LocalVariableNode.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.VariableTree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.element.Element;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * A node for a local variable or a parameter:
- *
- * <pre>
- * <em>identifier</em>
- * </pre>
- *
- * We allow local variable uses introduced by the {@link
- * org.checkerframework.dataflow.cfg.CFGBuilder} without corresponding AST {@link Tree}s.
- *
- * @author Stefan Heule
- */
-// TODO: don't use for parameters, as they don't have a tree
-public class LocalVariableNode extends Node {
-
- protected Tree tree;
- protected Node receiver;
-
- public LocalVariableNode(Tree t) {
- super(InternalUtils.typeOf(t));
- // IdentifierTree for normal uses of the local variable or parameter,
- // and VariableTree for the translation of an initializer block
- assert t != null;
- assert t instanceof IdentifierTree || t instanceof VariableTree;
- tree = t;
- this.receiver = null;
- }
-
- public LocalVariableNode(Tree t, Node receiver) {
- this(t);
- this.receiver = receiver;
- }
-
- public Element getElement() {
- Element el;
- if (tree instanceof IdentifierTree) {
- el = TreeUtils.elementFromUse((IdentifierTree) tree);
- } else {
- assert tree instanceof VariableTree;
- el = TreeUtils.elementFromDeclaration((VariableTree) tree);
- }
- return el;
- }
-
- public Node getReceiver() {
- return receiver;
- }
-
- public String getName() {
- if (tree instanceof IdentifierTree) {
- return ((IdentifierTree) tree).getName().toString();
- }
- return ((VariableTree) tree).getName().toString();
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitLocalVariable(this, p);
- }
-
- @Override
- public String toString() {
- return getName().toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof LocalVariableNode)) {
- return false;
- }
- LocalVariableNode other = (LocalVariableNode) obj;
- return getName().equals(other.getName());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getName());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LongLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LongLiteralNode.java
deleted file mode 100644
index b92575ef90..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/LongLiteralNode.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for a long literal. For example:
- *
- * <pre>
- * <em>-3l</em>
- * <em>0x80808080L</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class LongLiteralNode extends ValueLiteralNode {
-
- public LongLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.LONG_LITERAL);
- }
-
- @Override
- public Long getValue() {
- return (Long) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitLongLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a LongLiteralNode
- if (obj == null || !(obj instanceof LongLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MarkerNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MarkerNode.java
deleted file mode 100644
index a7a892f3be..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MarkerNode.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * MarkerNodes are no-op Nodes used for debugging information. They can hold a Tree and a message,
- * which will be part of the String representation of the MarkerNode.
- *
- * <p>An example use case for MarkerNodes is representing switch statements.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class MarkerNode extends Node {
-
- protected /*@Nullable*/ Tree tree;
- protected String message;
-
- public MarkerNode(/*@Nullable*/ Tree tree, String message, Types types) {
- super(types.getNoType(TypeKind.NONE));
- this.tree = tree;
- this.message = message;
- }
-
- public String getMessage() {
- return message;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitMarker(this, p);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("marker ");
- sb.append("(" + message + ")");
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof MarkerNode)) {
- return false;
- }
- MarkerNode other = (MarkerNode) obj;
- if (tree == null && other.getTree() != null) {
- return false;
- }
-
- return getTree().equals(other.getTree()) && getMessage().equals(other.getMessage());
- }
-
- @Override
- public int hashCode() {
- int hash = 0;
- if (tree != null) {
- hash = HashCodeUtils.hash(tree);
- }
- return HashCodeUtils.hash(hash, getMessage());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodAccessNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodAccessNode.java
deleted file mode 100644
index 060f17b62d..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodAccessNode.java
+++ /dev/null
@@ -1,78 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.element.ExecutableElement;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * A node for a method access, including a method accesses:
- *
- * <pre>
- * <em>expression</em> . <em>method</em> ()
- * </pre>
- *
- * @author Stefan Heule
- */
-public class MethodAccessNode extends Node {
-
- protected ExpressionTree tree;
- protected ExecutableElement method;
- protected Node receiver;
-
- // TODO: add method to get modifiers (static, access level, ..)
-
- public MethodAccessNode(ExpressionTree tree, Node receiver) {
- super(InternalUtils.typeOf(tree));
- assert TreeUtils.isMethodAccess(tree);
- this.tree = tree;
- this.method = (ExecutableElement) TreeUtils.elementFromUse(tree);
- this.receiver = receiver;
- }
-
- public ExecutableElement getMethod() {
- return method;
- }
-
- public Node getReceiver() {
- return receiver;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitMethodAccess(this, p);
- }
-
- @Override
- public String toString() {
- return getReceiver() + "." + method.getSimpleName();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof MethodAccessNode)) {
- return false;
- }
- MethodAccessNode other = (MethodAccessNode) obj;
- return getReceiver().equals(other.getReceiver()) && getMethod().equals(other.getMethod());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getReceiver(), getMethod());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(receiver);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodInvocationNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodInvocationNode.java
deleted file mode 100644
index 9456f37808..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/MethodInvocationNode.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.util.TreePath;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import org.checkerframework.dataflow.cfg.node.AssignmentContext.MethodParameterContext;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for method invocation
- *
- * <pre>
- * <em>target(arg1, arg2, ...)</em>
- * </pre>
- *
- * CFGs may contain {@link MethodInvocationNode}s that correspond to no AST {@link Tree}, in which
- * case, the tree field will be null.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class MethodInvocationNode extends Node {
-
- protected MethodInvocationTree tree;
- protected MethodAccessNode target;
- protected List<Node> arguments;
- protected TreePath treePath;
-
- public MethodInvocationNode(
- MethodInvocationTree tree,
- MethodAccessNode target,
- List<Node> arguments,
- TreePath treePath) {
- super(tree != null ? InternalUtils.typeOf(tree) : target.getMethod().getReturnType());
- this.tree = tree;
- this.target = target;
- this.arguments = arguments;
- this.treePath = treePath;
-
- // set assignment contexts for parameters
- int i = 0;
- for (Node arg : arguments) {
- AssignmentContext ctx = new MethodParameterContext(target.getMethod(), i++);
- arg.setAssignmentContext(ctx);
- }
- }
-
- public MethodInvocationNode(MethodAccessNode target, List<Node> arguments, TreePath treePath) {
- this(null, target, arguments, treePath);
- }
-
- public MethodAccessNode getTarget() {
- return target;
- }
-
- public List<Node> getArguments() {
- return arguments;
- }
-
- public Node getArgument(int i) {
- return arguments.get(i);
- }
-
- public TreePath getTreePath() {
- return treePath;
- }
-
- @Override
- public MethodInvocationTree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitMethodInvocation(this, p);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append(target);
- sb.append("(");
- boolean needComma = false;
- for (Node arg : arguments) {
- if (needComma) {
- sb.append(", ");
- }
- sb.append(arg);
- needComma = true;
- }
- sb.append(")");
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof MethodInvocationNode)) {
- return false;
- }
- MethodInvocationNode other = (MethodInvocationNode) obj;
-
- return getTarget().equals(other.getTarget()) && getArguments().equals(other.getArguments());
- }
-
- @Override
- public int hashCode() {
- int hash = 0;
- hash = HashCodeUtils.hash(target);
- for (Node arg : arguments) {
- hash = HashCodeUtils.hash(hash, arg.hashCode());
- }
- return hash;
- }
-
- @Override
- public Collection<Node> getOperands() {
- List<Node> list = new LinkedList<Node>();
- list.add(target);
- list.addAll(arguments);
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NarrowingConversionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NarrowingConversionNode.java
deleted file mode 100644
index 79a47283eb..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NarrowingConversionNode.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.TypesUtils;
-
-/**
- * A node for the narrowing primitive conversion operation. See JLS 5.1.3 for the definition of
- * narrowing primitive conversion.
- *
- * <p>A {@link NarrowingConversionNode} does not correspond to any tree node in the parsed AST. It
- * is introduced when a value of some primitive type appears in a context that requires a different
- * primitive with more bits of precision.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NarrowingConversionNode extends Node {
-
- protected Tree tree;
- protected Node operand;
-
- public NarrowingConversionNode(Tree tree, Node operand, TypeMirror type) {
- super(type);
- assert TypesUtils.isPrimitive(type) : "non-primitive type in narrowing conversion";
- this.tree = tree;
- this.operand = operand;
- }
-
- public Node getOperand() {
- return operand;
- }
-
- @Override
- public TypeMirror getType() {
- return type;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNarrowingConversion(this, p);
- }
-
- @Override
- public String toString() {
- return "NarrowingConversion(" + getOperand() + ", " + type + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NarrowingConversionNode)) {
- return false;
- }
- NarrowingConversionNode other = (NarrowingConversionNode) obj;
- return getOperand().equals(other.getOperand())
- && TypesUtils.areSamePrimitiveTypes(getType(), other.getType());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/Node.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/Node.java
deleted file mode 100644
index fb5bf5335d..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/Node.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.LinkedList;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.cfg.CFGBuilder;
-import org.checkerframework.dataflow.cfg.block.Block;
-
-/**
- * A node in the abstract representation used for Java code inside a basic block.
- *
- * <p>The following invariants hold:
- *
- * <pre>
- * block == null || block instanceof RegularBlock || block instanceof ExceptionBlock
- * block instanceof RegularBlock &rArr; block.getContents().contains(this)
- * block instanceof ExceptionBlock &rArr; block.getNode() == this
- * block == null &hArr; "This object represents a parameter of the method."
- * </pre>
- *
- * <pre>
- * type != null
- * tree != null &rArr; node.getType() == InternalUtils.typeOf(node.getTree())
- * </pre>
- *
- * @author Stefan Heule
- */
-public abstract class Node {
-
- /** The basic block this node belongs to (see invariant about this field above). */
- protected /*@Nullable*/ Block block;
-
- /** Is this node an l-value? */
- protected boolean lvalue = false;
-
- /** The assignment context of this node. See {@link AssignmentContext}. */
- protected /*@Nullable*/ AssignmentContext assignmentContext;
-
- /**
- * Does this node represent a tree that appears in the source code (true) or one that the CFG
- * builder added while desugaring (false).
- */
- protected boolean inSource = true;
-
- /**
- * The type of this node. For {@link Node}s with {@link Tree}s, this type is the type of the
- * {@link Tree}. Otherwise, it is the type is set by the {@link CFGBuilder}.
- */
- protected final TypeMirror type;
-
- public Node(TypeMirror type) {
- assert type != null;
- this.type = type;
- }
-
- /**
- * @return the basic block this node belongs to (or {@code null} if it represents the parameter
- * of a method).
- */
- public /*@Nullable*/ Block getBlock() {
- return block;
- }
-
- /** Set the basic block this node belongs to. */
- public void setBlock(Block b) {
- block = b;
- }
-
- /**
- * Returns the {@link Tree} in the abstract syntax tree, or {@code null} if no corresponding
- * tree exists. For instance, this is the case for an {@link ImplicitThisLiteralNode}.
- *
- * @return the corresponding {@link Tree} or {@code null}.
- */
- public abstract /*@Nullable*/ Tree getTree();
-
- /**
- * Returns a {@link TypeMirror} representing the type of a {@link Node} A {@link Node} will
- * always have a type even when it has no {@link Tree}.
- *
- * @return a {@link TypeMirror} representing the type of this {@link Node}
- */
- public TypeMirror getType() {
- return type;
- }
-
- /**
- * Accept method of the visitor pattern
- *
- * @param <R> result type of the operation
- * @param <P> parameter type
- * @param visitor the visitor to be applied to this node
- * @param p the parameter for this operation
- */
- public abstract <R, P> R accept(NodeVisitor<R, P> visitor, P p);
-
- public boolean isLValue() {
- return lvalue;
- }
-
- /** Make this node an l-value. */
- public void setLValue() {
- lvalue = true;
- }
-
- public boolean getInSource() {
- return inSource;
- }
-
- public void setInSource(boolean inSrc) {
- inSource = inSrc;
- }
-
- public AssignmentContext getAssignmentContext() {
- return assignmentContext;
- }
-
- public void setAssignmentContext(AssignmentContext assignmentContext) {
- this.assignmentContext = assignmentContext;
- }
-
- /** @return a collection containing all of the operand {@link Node}s of this {@link Node}. */
- public abstract Collection<Node> getOperands();
-
- /**
- * @return a collection containing all of the operand {@link Node}s of this {@link Node}, as
- * well as (transitively) the operands of its operands
- */
- public Collection<Node> getTransitiveOperands() {
- LinkedList<Node> operands = new LinkedList<>(getOperands());
- LinkedList<Node> transitiveOperands = new LinkedList<>();
- while (!operands.isEmpty()) {
- Node next = operands.removeFirst();
- operands.addAll(next.getOperands());
- transitiveOperands.add(next);
- }
- return transitiveOperands;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java
deleted file mode 100644
index 8a2f513924..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NodeVisitor.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/**
- * A visitor for a {@link Node} tree.
- *
- * @author Stefan Heule
- * @param <R> return type of the visitor. Use {@link Void} if the visitor does not have a return
- * value.
- * @param <P> parameter type of the visitor. Use {@link Void} if the visitor does not have a
- * parameter.
- */
-public interface NodeVisitor<R, P> {
- // Literals
- R visitShortLiteral(ShortLiteralNode n, P p);
-
- R visitIntegerLiteral(IntegerLiteralNode n, P p);
-
- R visitLongLiteral(LongLiteralNode n, P p);
-
- R visitFloatLiteral(FloatLiteralNode n, P p);
-
- R visitDoubleLiteral(DoubleLiteralNode n, P p);
-
- R visitBooleanLiteral(BooleanLiteralNode n, P p);
-
- R visitCharacterLiteral(CharacterLiteralNode n, P p);
-
- R visitStringLiteral(StringLiteralNode n, P p);
-
- R visitNullLiteral(NullLiteralNode n, P p);
-
- // Unary operations
- R visitNumericalMinus(NumericalMinusNode n, P p);
-
- R visitNumericalPlus(NumericalPlusNode n, P p);
-
- R visitBitwiseComplement(BitwiseComplementNode n, P p);
-
- R visitNullChk(NullChkNode n, P p);
-
- // Binary operations
- R visitStringConcatenate(StringConcatenateNode n, P p);
-
- R visitNumericalAddition(NumericalAdditionNode n, P p);
-
- R visitNumericalSubtraction(NumericalSubtractionNode n, P p);
-
- R visitNumericalMultiplication(NumericalMultiplicationNode n, P p);
-
- R visitIntegerDivision(IntegerDivisionNode n, P p);
-
- R visitFloatingDivision(FloatingDivisionNode n, P p);
-
- R visitIntegerRemainder(IntegerRemainderNode n, P p);
-
- R visitFloatingRemainder(FloatingRemainderNode n, P p);
-
- R visitLeftShift(LeftShiftNode n, P p);
-
- R visitSignedRightShift(SignedRightShiftNode n, P p);
-
- R visitUnsignedRightShift(UnsignedRightShiftNode n, P p);
-
- R visitBitwiseAnd(BitwiseAndNode n, P p);
-
- R visitBitwiseOr(BitwiseOrNode n, P p);
-
- R visitBitwiseXor(BitwiseXorNode n, P p);
-
- // Compound assignments
- R visitStringConcatenateAssignment(StringConcatenateAssignmentNode n, P p);
-
- // Comparison operations
- R visitLessThan(LessThanNode n, P p);
-
- R visitLessThanOrEqual(LessThanOrEqualNode n, P p);
-
- R visitGreaterThan(GreaterThanNode n, P p);
-
- R visitGreaterThanOrEqual(GreaterThanOrEqualNode n, P p);
-
- R visitEqualTo(EqualToNode n, P p);
-
- R visitNotEqual(NotEqualNode n, P p);
-
- // Conditional operations
- R visitConditionalAnd(ConditionalAndNode n, P p);
-
- R visitConditionalOr(ConditionalOrNode n, P p);
-
- R visitConditionalNot(ConditionalNotNode n, P p);
-
- R visitTernaryExpression(TernaryExpressionNode n, P p);
-
- R visitAssignment(AssignmentNode n, P p);
-
- R visitLocalVariable(LocalVariableNode n, P p);
-
- R visitVariableDeclaration(VariableDeclarationNode n, P p);
-
- R visitFieldAccess(FieldAccessNode n, P p);
-
- R visitMethodAccess(MethodAccessNode n, P p);
-
- R visitArrayAccess(ArrayAccessNode n, P p);
-
- R visitImplicitThisLiteral(ImplicitThisLiteralNode n, P p);
-
- R visitExplicitThisLiteral(ExplicitThisLiteralNode n, P p);
-
- R visitSuper(SuperNode n, P p);
-
- R visitReturn(ReturnNode n, P p);
-
- R visitStringConversion(StringConversionNode n, P p);
-
- R visitNarrowingConversion(NarrowingConversionNode n, P p);
-
- R visitWideningConversion(WideningConversionNode n, P p);
-
- R visitInstanceOf(InstanceOfNode n, P p);
-
- R visitTypeCast(TypeCastNode n, P p);
-
- // Blocks
-
- R visitSynchronized(SynchronizedNode n, P p);
-
- // Statements
- R visitAssertionError(AssertionErrorNode n, P p);
-
- R visitThrow(ThrowNode n, P p);
-
- // Cases
- R visitCase(CaseNode n, P p);
-
- // Method and constructor invocations
- R visitMethodInvocation(MethodInvocationNode n, P p);
-
- R visitObjectCreation(ObjectCreationNode n, P p);
-
- R visitMemberReference(FunctionalInterfaceNode n, P p);
-
- R visitArrayCreation(ArrayCreationNode n, P p);
-
- // Type, package and class names
- R visitArrayType(ArrayTypeNode n, P p);
-
- R visitPrimitiveType(PrimitiveTypeNode n, P p);
-
- R visitClassName(ClassNameNode n, P p);
-
- R visitPackageName(PackageNameNode n, P p);
-
- // Parameterized types
- R visitParameterizedType(ParameterizedTypeNode n, P p);
-
- // Marker nodes
- R visitMarker(MarkerNode n, P p);
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NotEqualNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NotEqualNode.java
deleted file mode 100644
index debd7cbaf0..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NotEqualNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the not equal comparison:
- *
- * <pre>
- * <em>expression</em> != <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NotEqualNode extends BinaryOperationNode {
-
- public NotEqualNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.NOT_EQUAL_TO;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNotEqual(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " != " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NotEqualNode)) {
- return false;
- }
- NotEqualNode other = (NotEqualNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullChkNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullChkNode.java
deleted file mode 100644
index 6609a29b59..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullChkNode.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.Tree.Kind;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for the unary 'nullchk' operation (generated by the Java compiler):
- *
- * <pre>
- * &lt;*nullchk*&gt;<em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NullChkNode extends Node {
-
- protected Tree tree;
- protected Node operand;
-
- public NullChkNode(Tree tree, Node operand) {
- super(InternalUtils.typeOf(tree));
- assert tree.getKind() == Kind.OTHER;
- this.tree = tree;
- this.operand = operand;
- }
-
- public Node getOperand() {
- return operand;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNullChk(this, p);
- }
-
- @Override
- public String toString() {
- return "(+ " + getOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NumericalPlusNode)) {
- return false;
- }
- NumericalPlusNode other = (NumericalPlusNode) obj;
- return getOperand().equals(other.getOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullLiteralNode.java
deleted file mode 100644
index 1fcdeb4825..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NullLiteralNode.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for the null literal.
- *
- * <pre>
- * <em>null</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NullLiteralNode extends ValueLiteralNode {
-
- public NullLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.NULL_LITERAL);
- }
-
- @Override
- public Void getValue() {
- return (Void) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNullLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a NullLiteralNode
- if (obj == null || !(obj instanceof NullLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalAdditionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalAdditionNode.java
deleted file mode 100644
index 4692856dd8..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalAdditionNode.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the numerical addition:
- *
- * <pre>
- * <em>expression</em> + <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class NumericalAdditionNode extends BinaryOperationNode {
-
- public NumericalAdditionNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.PLUS || tree.getKind() == Kind.PLUS_ASSIGNMENT;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNumericalAddition(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " + " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NumericalAdditionNode)) {
- return false;
- }
- NumericalAdditionNode other = (NumericalAdditionNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMinusNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMinusNode.java
deleted file mode 100644
index 141ab580e0..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMinusNode.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.tree.UnaryTree;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the unary minus operation:
- *
- * <pre>
- * - <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NumericalMinusNode extends UnaryOperationNode {
-
- public NumericalMinusNode(UnaryTree tree, Node operand) {
- super(tree, operand);
- assert tree.getKind() == Kind.UNARY_MINUS;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNumericalMinus(this, p);
- }
-
- @Override
- public String toString() {
- return "(- " + getOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NumericalMinusNode)) {
- return false;
- }
- NumericalMinusNode other = (NumericalMinusNode) obj;
- return getOperand().equals(other.getOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMultiplicationNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMultiplicationNode.java
deleted file mode 100644
index 85561a1a02..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalMultiplicationNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the numerical multiplication:
- *
- * <pre>
- * <em>expression</em> * <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NumericalMultiplicationNode extends BinaryOperationNode {
-
- public NumericalMultiplicationNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.MULTIPLY;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNumericalMultiplication(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " * " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NumericalMultiplicationNode)) {
- return false;
- }
- NumericalMultiplicationNode other = (NumericalMultiplicationNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalPlusNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalPlusNode.java
deleted file mode 100644
index 21b5b584d2..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalPlusNode.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.tree.UnaryTree;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the unary plus operation:
- *
- * <pre>
- * + <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NumericalPlusNode extends UnaryOperationNode {
-
- public NumericalPlusNode(UnaryTree tree, Node operand) {
- super(tree, operand);
- assert tree.getKind() == Kind.UNARY_PLUS;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNumericalPlus(this, p);
- }
-
- @Override
- public String toString() {
- return "(+ " + getOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NumericalPlusNode)) {
- return false;
- }
- NumericalPlusNode other = (NumericalPlusNode) obj;
- return getOperand().equals(other.getOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalSubtractionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalSubtractionNode.java
deleted file mode 100644
index a962eadd78..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/NumericalSubtractionNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the numerical subtraction:
- *
- * <pre>
- * <em>expression</em> - <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class NumericalSubtractionNode extends BinaryOperationNode {
-
- public NumericalSubtractionNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.MINUS;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitNumericalSubtraction(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " - " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof NumericalSubtractionNode)) {
- return false;
- }
- NumericalSubtractionNode other = (NumericalSubtractionNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ObjectCreationNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ObjectCreationNode.java
deleted file mode 100644
index 8ab862a2ef..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ObjectCreationNode.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.NewClassTree;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for new object creation
- *
- * <pre>
- * <em>new constructor(arg1, arg2, ...)</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ObjectCreationNode extends Node {
-
- protected NewClassTree tree;
- protected Node constructor;
- protected List<Node> arguments;
-
- public ObjectCreationNode(NewClassTree tree, Node constructor, List<Node> arguments) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- this.constructor = constructor;
- this.arguments = arguments;
- }
-
- public Node getConstructor() {
- return constructor;
- }
-
- public List<Node> getArguments() {
- return arguments;
- }
-
- public Node getArgument(int i) {
- return arguments.get(i);
- }
-
- @Override
- public NewClassTree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitObjectCreation(this, p);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("new " + constructor + "(");
- boolean needComma = false;
- for (Node arg : arguments) {
- if (needComma) {
- sb.append(", ");
- }
- sb.append(arg);
- needComma = true;
- }
- sb.append(")");
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ObjectCreationNode)) {
- return false;
- }
- ObjectCreationNode other = (ObjectCreationNode) obj;
- if (constructor == null && other.getConstructor() != null) {
- return false;
- }
-
- return getConstructor().equals(other.getConstructor())
- && getArguments().equals(other.getArguments());
- }
-
- @Override
- public int hashCode() {
- int hash = HashCodeUtils.hash(constructor);
- for (Node arg : arguments) {
- hash = HashCodeUtils.hash(hash, arg.hashCode());
- }
- return hash;
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(constructor);
- list.addAll(arguments);
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PackageNameNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PackageNameNode.java
deleted file mode 100644
index 3c69b8252b..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PackageNameNode.java
+++ /dev/null
@@ -1,101 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.element.Element;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * A node representing a package name used in an expression such as a constructor invocation
- *
- * <p><em>package</em>.class.object(...)
- *
- * <p>parent.<em>package</em>.class.object(...)
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class PackageNameNode extends Node {
-
- protected final Tree tree;
- /** The package named by this node */
- protected final Element element;
-
- /** The parent name, if any. */
- protected final /*@Nullable*/ PackageNameNode parent;
-
- public PackageNameNode(IdentifierTree tree) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- this.element = TreeUtils.elementFromUse(tree);
- this.parent = null;
- }
-
- public PackageNameNode(MemberSelectTree tree, PackageNameNode parent) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- this.element = TreeUtils.elementFromUse(tree);
- this.parent = parent;
- }
-
- public Element getElement() {
- return element;
- }
-
- public PackageNameNode getParent() {
- return parent;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitPackageName(this, p);
- }
-
- @Override
- public String toString() {
- return getElement().getSimpleName().toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof PackageNameNode)) {
- return false;
- }
- PackageNameNode other = (PackageNameNode) obj;
- if (getParent() == null) {
- return other.getParent() == null && getElement().equals(other.getElement());
- } else {
- return getParent().equals(other.getParent()) && getElement().equals(other.getElement());
- }
- }
-
- @Override
- public int hashCode() {
- if (parent == null) {
- return HashCodeUtils.hash(getElement());
- }
- return HashCodeUtils.hash(getElement(), getParent());
- }
-
- @Override
- public Collection<Node> getOperands() {
- if (parent == null) {
- return Collections.emptyList();
- }
- return Collections.singleton((Node) parent);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ParameterizedTypeNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ParameterizedTypeNode.java
deleted file mode 100644
index 774ac8b7c5..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ParameterizedTypeNode.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.ParameterizedTypeTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for a parameterized type occurring in an expression:
- *
- * <pre>
- * <em>type&lt;arg1, arg2&gt;</em>
- * </pre>
- *
- * Parameterized types don't represent any computation to be done at runtime, so we might choose to
- * represent them differently by modifying the {@link Node}s in which parameterized types can occur,
- * such as {@link ObjectCreationNode}s.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ParameterizedTypeNode extends Node {
-
- protected Tree tree;
-
- public ParameterizedTypeNode(Tree t) {
- super(InternalUtils.typeOf(t));
- assert t instanceof ParameterizedTypeTree;
- tree = t;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitParameterizedType(this, p);
- }
-
- @Override
- public String toString() {
- return getTree().toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ParameterizedTypeNode)) {
- return false;
- }
- ParameterizedTypeNode other = (ParameterizedTypeNode) obj;
- return getTree().equals(other.getTree());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getTree());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java
deleted file mode 100644
index 379bb92024..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/PrimitiveTypeNode.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.PrimitiveTypeTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node representing a primitive type used in an expression such as a field access
- *
- * <p><em>type</em> .class
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class PrimitiveTypeNode extends Node {
-
- protected final PrimitiveTypeTree tree;
-
- public PrimitiveTypeNode(PrimitiveTypeTree tree) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitPrimitiveType(this, p);
- }
-
- @Override
- public String toString() {
- return tree.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof PrimitiveTypeNode)) {
- return false;
- }
- PrimitiveTypeNode other = (PrimitiveTypeNode) obj;
- return getType().equals(other.getType());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getType());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ReturnNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ReturnNode.java
deleted file mode 100644
index b7222dfa18..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ReturnNode.java
+++ /dev/null
@@ -1,100 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import com.sun.source.tree.LambdaExpressionTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.ReturnTree;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.cfg.node.AssignmentContext.LambdaReturnContext;
-import org.checkerframework.dataflow.cfg.node.AssignmentContext.MethodReturnContext;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for a return statement:
- *
- * <pre>
- * return
- * return <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class ReturnNode extends Node {
-
- protected ReturnTree tree;
- protected /*@Nullable*/ Node result;
-
- public ReturnNode(ReturnTree t, /*@Nullable*/ Node result, Types types, MethodTree methodTree) {
- super(types.getNoType(TypeKind.NONE));
- this.result = result;
- tree = t;
- result.setAssignmentContext(new MethodReturnContext(methodTree));
- }
-
- public ReturnNode(
- ReturnTree t,
- /*@Nullable*/ Node result,
- Types types,
- LambdaExpressionTree lambda,
- MethodSymbol methodSymbol) {
- super(types.getNoType(TypeKind.NONE));
- this.result = result;
- tree = t;
- result.setAssignmentContext(new LambdaReturnContext(methodSymbol));
- }
-
- public Node getResult() {
- return result;
- }
-
- @Override
- public ReturnTree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitReturn(this, p);
- }
-
- @Override
- public String toString() {
- if (result != null) {
- return "return " + result;
- }
- return "return";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ReturnNode)) {
- return false;
- }
- ReturnNode other = (ReturnNode) obj;
- if ((result == null) != (other.result == null)) {
- return false;
- }
- return (result == null || result.equals(other.result));
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(result);
- }
-
- @Override
- public Collection<Node> getOperands() {
- if (result == null) {
- return Collections.emptyList();
- } else {
- return Collections.singletonList(result);
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ShortLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ShortLiteralNode.java
deleted file mode 100644
index cd1db1e560..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ShortLiteralNode.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for a short literal. For example:
- *
- * <pre>
- * <em>5</em>
- * <em>0x8fff</em>
- * </pre>
- *
- * Java source and the AST representation do not have "short" literals. They have integer literals
- * that may be narrowed to shorts depending on context. If we use explicit NarrowingConversionNodes,
- * do we need ShortLiteralNodes too? TODO: Decide this question.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ShortLiteralNode extends ValueLiteralNode {
-
- public ShortLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.INT_LITERAL);
- }
-
- @Override
- public Short getValue() {
- return (Short) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitShortLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a ShortLiteralNode
- if (obj == null || !(obj instanceof ShortLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SignedRightShiftNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SignedRightShiftNode.java
deleted file mode 100644
index ac4aa58783..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SignedRightShiftNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for bitwise right shift operations with sign extension:
- *
- * <pre>
- * <em>expression</em> &gt;&gt; <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class SignedRightShiftNode extends BinaryOperationNode {
-
- public SignedRightShiftNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.RIGHT_SHIFT;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitSignedRightShift(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " >> " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof SignedRightShiftNode)) {
- return false;
- }
- SignedRightShiftNode other = (SignedRightShiftNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateAssignmentNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateAssignmentNode.java
deleted file mode 100644
index 0e6f006d7e..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateAssignmentNode.java
+++ /dev/null
@@ -1,57 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.Tree.Kind;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for the string concatenation compound assignment:
- *
- * <pre>
- * <em>variable</em> += <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class StringConcatenateAssignmentNode extends Node {
- protected Tree tree;
- protected Node left;
- protected Node right;
-
- public StringConcatenateAssignmentNode(Tree tree, Node left, Node right) {
- super(InternalUtils.typeOf(tree));
- assert tree.getKind() == Kind.PLUS_ASSIGNMENT;
- this.tree = tree;
- this.left = left;
- this.right = right;
- }
-
- public Node getLeftOperand() {
- return left;
- }
-
- public Node getRightOperand() {
- return right;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitStringConcatenateAssignment(this, p);
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(getLeftOperand());
- list.add(getRightOperand());
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateNode.java
deleted file mode 100644
index c69beea694..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConcatenateNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for string concatenation:
- *
- * <pre>
- * <em>expression</em> + <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class StringConcatenateNode extends BinaryOperationNode {
-
- public StringConcatenateNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.PLUS;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitStringConcatenate(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " + " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof StringConcatenateNode)) {
- return false;
- }
- StringConcatenateNode other = (StringConcatenateNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConversionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConversionNode.java
deleted file mode 100644
index 8ba8c6ff60..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringConversionNode.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the string conversion operation. See JLS 5.1.11 for the definition of string
- * conversion.
- *
- * <p>A {@link StringConversionNode} does not correspond to any tree node in the parsed AST. It is
- * introduced when a value of non-string type appears in a context that requires a {@link String},
- * such as in a string concatenation. A {@link StringConversionNode} should be treated as a
- * potential call to the toString method of its operand, but does not necessarily call any method
- * because null is converted to the string "null".
- *
- * <p>Conversion of primitive types to Strings requires first boxing and then string conversion.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class StringConversionNode extends Node {
-
- protected Tree tree;
- protected Node operand;
-
- // TODO: The type of a string conversion should be a final
- // TypeMirror representing java.lang.String. Currently we require
- // the caller to pass in a TypeMirror instead of creating one
- // through the javax.lang.model.type.Types interface.
- public StringConversionNode(Tree tree, Node operand, TypeMirror type) {
- super(type);
- this.tree = tree;
- this.operand = operand;
- }
-
- public Node getOperand() {
- return operand;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitStringConversion(this, p);
- }
-
- @Override
- public String toString() {
- return "StringConversion(" + getOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof StringConversionNode)) {
- return false;
- }
- StringConversionNode other = (StringConversionNode) obj;
- return getOperand().equals(other.getOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringLiteralNode.java
deleted file mode 100644
index c6ec1c90b8..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/StringLiteralNode.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-
-/**
- * A node for an string literal. For example:
- *
- * <pre>
- * <em>"abc"</em>
- * </pre>
- *
- * @author Stefan Heule
- */
-public class StringLiteralNode extends ValueLiteralNode {
-
- public StringLiteralNode(LiteralTree t) {
- super(t);
- assert t.getKind().equals(Tree.Kind.STRING_LITERAL);
- }
-
- @Override
- public String getValue() {
- return (String) tree.getValue();
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitStringLiteral(this, p);
- }
-
- @Override
- public boolean equals(Object obj) {
- // test that obj is a StringLiteralNode
- if (!(obj instanceof StringLiteralNode)) {
- return false;
- }
- // super method compares values
- return super.equals(obj);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-
- @Override
- public String toString() {
- return "\"" + super.toString() + "\"";
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SuperNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SuperNode.java
deleted file mode 100644
index 797eae8e7a..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SuperNode.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for a reference to 'super'.
- *
- * <pre>
- * <em>super</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class SuperNode extends Node {
-
- protected Tree tree;
-
- public SuperNode(Tree t) {
- super(InternalUtils.typeOf(t));
- assert t instanceof IdentifierTree && ((IdentifierTree) t).getName().contentEquals("super");
- tree = t;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitSuper(this, p);
- }
-
- public String getName() {
- return "super";
- }
-
- @Override
- public String toString() {
- return getName();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof SuperNode)) {
- return false;
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getName());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SynchronizedNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SynchronizedNode.java
deleted file mode 100644
index a17e2fa2e8..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/SynchronizedNode.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-/*
- * This represents the start and end of synchronized code block.
- * If startOfBlock == true it is the node preceding a synchronized code block.
- * Otherwise it is the node immediately after a synchronized code block.
- */
-
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-public class SynchronizedNode extends Node {
-
- protected /*@Nullable*/ Tree tree;
- protected Node expression;
- protected boolean startOfBlock;
-
- public SynchronizedNode(
- /*@Nullable*/ Tree tree, Node expression, boolean startOfBlock, Types types) {
- super(types.getNoType(TypeKind.NONE));
- this.tree = tree;
- this.expression = expression;
- this.startOfBlock = startOfBlock;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- public Node getExpression() {
- return expression;
- }
-
- public boolean getIsStartOfBlock() {
- return startOfBlock;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitSynchronized(this, p);
- }
-
- @Override
- public String toString() {
- StringBuffer sb = new StringBuffer();
- sb.append("synchronized ");
- sb.append("(" + expression + ")");
- return sb.toString();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof SynchronizedNode)) {
- return false;
- }
- SynchronizedNode other = (SynchronizedNode) obj;
- if (tree == null && other.getTree() != null) {
- return false;
- }
-
- return getTree().equals(other.getTree())
- && getExpression().equals(other.getExpression())
- && startOfBlock == other.startOfBlock;
- }
-
- @Override
- public int hashCode() {
- int hash = 0;
- if (tree != null) {
- hash = HashCodeUtils.hash(tree);
- }
- hash = HashCodeUtils.hash(startOfBlock);
- return HashCodeUtils.hash(hash, getExpression());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TernaryExpressionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TernaryExpressionNode.java
deleted file mode 100644
index 9a149a3325..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TernaryExpressionNode.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.ConditionalExpressionTree;
-import com.sun.source.tree.Tree.Kind;
-import java.util.Collection;
-import java.util.LinkedList;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for a conditional expression:
- *
- * <pre>
- * <em>expression</em> ? <em>expression</em> : <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class TernaryExpressionNode extends Node {
-
- protected ConditionalExpressionTree tree;
- protected Node condition;
- protected Node thenOperand;
- protected Node elseOperand;
-
- public TernaryExpressionNode(
- ConditionalExpressionTree tree, Node condition, Node thenOperand, Node elseOperand) {
- super(InternalUtils.typeOf(tree));
- assert tree.getKind().equals(Kind.CONDITIONAL_EXPRESSION);
- this.tree = tree;
- this.condition = condition;
- this.thenOperand = thenOperand;
- this.elseOperand = elseOperand;
- }
-
- public Node getConditionOperand() {
- return condition;
- }
-
- public Node getThenOperand() {
- return thenOperand;
- }
-
- public Node getElseOperand() {
- return elseOperand;
- }
-
- @Override
- public ConditionalExpressionTree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitTernaryExpression(this, p);
- }
-
- @Override
- public String toString() {
- return "("
- + getConditionOperand()
- + " ? "
- + getThenOperand()
- + " : "
- + getElseOperand()
- + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof TernaryExpressionNode)) {
- return false;
- }
- TernaryExpressionNode other = (TernaryExpressionNode) obj;
- return getConditionOperand().equals(other.getConditionOperand())
- && getThenOperand().equals(other.getThenOperand())
- && getElseOperand().equals(other.getElseOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getConditionOperand(), getThenOperand(), getElseOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- LinkedList<Node> list = new LinkedList<Node>();
- list.add(getConditionOperand());
- list.add(getThenOperand());
- list.add(getElseOperand());
- return list;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThisLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThisLiteralNode.java
deleted file mode 100644
index 3bb4c186e6..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThisLiteralNode.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for a reference to 'this', either implicit or explicit.
- *
- * <pre>
- * <em>this</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public abstract class ThisLiteralNode extends Node {
-
- public ThisLiteralNode(TypeMirror type) {
- super(type);
- }
-
- public String getName() {
- return "this";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ThisLiteralNode)) {
- return false;
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getName());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThrowNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThrowNode.java
deleted file mode 100644
index bb36e10a4a..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ThrowNode.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.ThrowTree;
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.util.Types;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for exception throws:
- *
- * <pre>
- * <em>throw</em> expr
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class ThrowNode extends Node {
-
- protected ThrowTree tree;
- protected Node expression;
-
- public ThrowNode(ThrowTree tree, Node expression, Types types) {
- super(types.getNoType(TypeKind.NONE));
- this.tree = tree;
- this.expression = expression;
- }
-
- public Node getExpression() {
- return expression;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitThrow(this, p);
- }
-
- @Override
- public String toString() {
- return "throw " + expression;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ThrowNode)) {
- return false;
- }
- ThrowNode other = (ThrowNode) obj;
- return getExpression().equals(other.getExpression());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(expression);
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(expression);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TypeCastNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TypeCastNode.java
deleted file mode 100644
index f6e71bf6aa..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/TypeCastNode.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for the cast operator:
- *
- * <p>(<em>Point</em>) <em>x</em>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class TypeCastNode extends Node {
-
- protected Tree tree;
- protected Node operand;
-
- public TypeCastNode(Tree tree, Node operand, TypeMirror type) {
- super(type);
- this.tree = tree;
- this.operand = operand;
- }
-
- public Node getOperand() {
- return operand;
- }
-
- @Override
- public TypeMirror getType() {
- return type;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitTypeCast(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getType() + ")" + getOperand();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof TypeCastNode)) {
- return false;
- }
- TypeCastNode other = (TypeCastNode) obj;
- // TODO: TypeMirror.equals may be too restrictive.
- // Check whether Types.isSameType is the better comparison.
- return getOperand().equals(other.getOperand()) && getType().equals(other.getType());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnaryOperationNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnaryOperationNode.java
deleted file mode 100644
index cb33e6a3f1..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnaryOperationNode.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.UnaryTree;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for a postfix or an unary expression.
- *
- * <p>For example:
- *
- * <pre>
- * <em>operator</em> <em>expressionNode</em>
- *
- * <em>expressionNode</em> <em>operator</em>
- * </pre>
- *
- * @author charleszhuochen
- */
-public abstract class UnaryOperationNode extends Node {
-
- protected final UnaryTree tree;
- protected final Node operand;
-
- public UnaryOperationNode(UnaryTree tree, Node operand) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- this.operand = operand;
- }
-
- public Node getOperand() {
- return this.operand;
- }
-
- @Override
- public UnaryTree getTree() {
- return tree;
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnsignedRightShiftNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnsignedRightShiftNode.java
deleted file mode 100644
index 2609a7d7ae..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/UnsignedRightShiftNode.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.Tree.Kind;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-
-/**
- * A node for bitwise right shift operations with zero extension:
- *
- * <pre>
- * <em>expression</em> &gt;&gt;&gt; <em>expression</em>
- * </pre>
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class UnsignedRightShiftNode extends BinaryOperationNode {
-
- public UnsignedRightShiftNode(BinaryTree tree, Node left, Node right) {
- super(tree, left, right);
- assert tree.getKind() == Kind.UNSIGNED_RIGHT_SHIFT;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitUnsignedRightShift(this, p);
- }
-
- @Override
- public String toString() {
- return "(" + getLeftOperand() + " >>> " + getRightOperand() + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof UnsignedRightShiftNode)) {
- return false;
- }
- UnsignedRightShiftNode other = (UnsignedRightShiftNode) obj;
- return getLeftOperand().equals(other.getLeftOperand())
- && getRightOperand().equals(other.getRightOperand());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getLeftOperand(), getRightOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ValueLiteralNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ValueLiteralNode.java
deleted file mode 100644
index 4c9c18f0af..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/ValueLiteralNode.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.LiteralTree;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-/**
- * A node for a literals that have some form of value:
- *
- * <ul>
- * <li>integer literal
- * <li>long literal
- * <li>char literal
- * <li>string literal
- * <li>float literal
- * <li>double literal
- * <li>boolean literal
- * <li>null literal
- * </ul>
- *
- * @author Stefan Heule
- */
-public abstract class ValueLiteralNode extends Node {
-
- protected final LiteralTree tree;
-
- /** @return the value of the literal */
- public abstract /*@Nullable*/ Object getValue();
-
- public ValueLiteralNode(LiteralTree tree) {
- super(InternalUtils.typeOf(tree));
- this.tree = tree;
- }
-
- @Override
- public LiteralTree getTree() {
- return tree;
- }
-
- @Override
- public String toString() {
- return String.valueOf(getValue());
- }
-
- /** Compare the value of this nodes. */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof ValueLiteralNode)) {
- return false;
- }
- ValueLiteralNode other = (ValueLiteralNode) obj;
- Object val = getValue();
- Object otherVal = other.getValue();
- return ((val == null || otherVal == null) && val == otherVal) || val.equals(otherVal);
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getValue());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/VariableDeclarationNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/VariableDeclarationNode.java
deleted file mode 100644
index 867cdf1ad9..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/VariableDeclarationNode.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.VariableTree;
-import java.util.Collection;
-import java.util.Collections;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * A node for a local variable declaration:
- *
- * <pre>
- * <em>modifier</em> <em>type</em> <em>identifier</em>;
- * </pre>
- *
- * Note: Does not have an initializer block, as that will be translated to a separate {@link
- * AssignmentNode}.
- *
- * @author Stefan Heule
- */
-public class VariableDeclarationNode extends Node {
-
- protected VariableTree tree;
- protected String name;
-
- // TODO: make modifier accessible
-
- public VariableDeclarationNode(VariableTree t) {
- super(InternalUtils.typeOf(t));
- tree = t;
- name = tree.getName().toString();
- }
-
- public String getName() {
- return name;
- }
-
- @Override
- public VariableTree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitVariableDeclaration(this, p);
- }
-
- @Override
- public String toString() {
- return name;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof VariableDeclarationNode)) {
- return false;
- }
- VariableDeclarationNode other = (VariableDeclarationNode) obj;
- return getName().equals(other.getName());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getName());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.emptyList();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/WideningConversionNode.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/WideningConversionNode.java
deleted file mode 100644
index 9b949ea546..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/node/WideningConversionNode.java
+++ /dev/null
@@ -1,76 +0,0 @@
-package org.checkerframework.dataflow.cfg.node;
-
-import com.sun.source.tree.Tree;
-import java.util.Collection;
-import java.util.Collections;
-import javax.lang.model.type.TypeMirror;
-import org.checkerframework.dataflow.util.HashCodeUtils;
-import org.checkerframework.javacutil.TypesUtils;
-
-/**
- * A node for the widening primitive conversion operation. See JLS 5.1.2 for the definition of
- * widening primitive conversion.
- *
- * <p>A {@link WideningConversionNode} does not correspond to any tree node in the parsed AST. It is
- * introduced when a value of some primitive type appears in a context that requires a different
- * primitive with more bits of precision.
- *
- * @author Stefan Heule
- * @author Charlie Garrett
- */
-public class WideningConversionNode extends Node {
-
- protected Tree tree;
- protected Node operand;
-
- public WideningConversionNode(Tree tree, Node operand, TypeMirror type) {
- super(type);
- assert TypesUtils.isPrimitive(type) : "non-primitive type in widening conversion";
- this.tree = tree;
- this.operand = operand;
- }
-
- public Node getOperand() {
- return operand;
- }
-
- @Override
- public TypeMirror getType() {
- return type;
- }
-
- @Override
- public Tree getTree() {
- return tree;
- }
-
- @Override
- public <R, P> R accept(NodeVisitor<R, P> visitor, P p) {
- return visitor.visitWideningConversion(this, p);
- }
-
- @Override
- public String toString() {
- return "WideningConversion(" + getOperand() + ", " + type + ")";
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof WideningConversionNode)) {
- return false;
- }
- WideningConversionNode other = (WideningConversionNode) obj;
- return getOperand().equals(other.getOperand())
- && TypesUtils.areSamePrimitiveTypes(getType(), other.getType());
- }
-
- @Override
- public int hashCode() {
- return HashCodeUtils.hash(getOperand());
- }
-
- @Override
- public Collection<Node> getOperands() {
- return Collections.singletonList(getOperand());
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/playground/ConstantPropagationPlayground.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/playground/ConstantPropagationPlayground.java
deleted file mode 100644
index 79088386a9..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/cfg/playground/ConstantPropagationPlayground.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.checkerframework.dataflow.cfg.playground;
-
-import org.checkerframework.dataflow.analysis.Analysis;
-import org.checkerframework.dataflow.cfg.JavaSource2CFGDOT;
-import org.checkerframework.dataflow.constantpropagation.Constant;
-import org.checkerframework.dataflow.constantpropagation.ConstantPropagationStore;
-import org.checkerframework.dataflow.constantpropagation.ConstantPropagationTransfer;
-
-public class ConstantPropagationPlayground {
-
- /** Run constant propagation for a specific file and create a PDF of the CFG in the end. */
- public static void main(String[] args) {
-
- /* Configuration: change as appropriate */
- String inputFile = "cfg-input.java"; // input file name and path
- String outputDir = "cfg"; // output directory
- String method = "test"; // name of the method to analyze
- String clazz = "Test"; // name of the class to consider
-
- // run the analysis and create a PDF file
- ConstantPropagationTransfer transfer = new ConstantPropagationTransfer();
- // TODO: correct processing environment
- Analysis<Constant, ConstantPropagationStore, ConstantPropagationTransfer> analysis =
- new Analysis<>(null, transfer);
- JavaSource2CFGDOT.generateDOTofCFG(inputFile, outputDir, method, clazz, true, analysis);
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/Constant.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/Constant.java
deleted file mode 100644
index a95af7fa43..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/Constant.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.checkerframework.dataflow.constantpropagation;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import java.util.Objects;
-import org.checkerframework.dataflow.analysis.AbstractValue;
-
-public class Constant implements AbstractValue<Constant> {
-
- /** What kind of abstract value is this? */
- protected Type type;
-
- /** The value of this abstract value (or null) */
- protected /*@Nullable*/ Integer value;
-
- public enum Type {
- CONSTANT,
- TOP,
- BOTTOM,
- }
-
- public Constant(Type type) {
- assert !type.equals(Type.CONSTANT);
- this.type = type;
- }
-
- public Constant(Integer value) {
- this.type = Type.CONSTANT;
- this.value = value;
- }
-
- public boolean isTop() {
- return type.equals(Type.TOP);
- }
-
- public boolean isBottom() {
- return type.equals(Type.BOTTOM);
- }
-
- public boolean isConstant() {
- return type.equals(Type.CONSTANT);
- }
-
- public Integer getValue() {
- assert isConstant();
- return value;
- }
-
- public Constant copy() {
- if (isConstant()) {
- return new Constant(value);
- }
- return new Constant(type);
- }
-
- @Override
- public Constant leastUpperBound(Constant other) {
- if (other.isBottom()) {
- return this.copy();
- }
- if (this.isBottom()) {
- return other.copy();
- }
- if (other.isTop() || this.isTop()) {
- return new Constant(Type.TOP);
- }
- if (other.getValue().equals(getValue())) {
- return this.copy();
- }
- return new Constant(Type.TOP);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof Constant)) {
- return false;
- }
- Constant other = (Constant) obj;
- return type == other.type && Objects.equals(value, other.value);
- }
-
- @Override
- public int hashCode() {
- return type.hashCode() + (value != null ? value.hashCode() : 0);
- }
-
- @Override
- public String toString() {
- switch (type) {
- case TOP:
- return "T";
- case BOTTOM:
- return "-";
- case CONSTANT:
- return value.toString();
- }
- assert false;
- return "???";
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationStore.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationStore.java
deleted file mode 100644
index e7a718ee5b..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationStore.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.checkerframework.dataflow.constantpropagation;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-import org.checkerframework.dataflow.analysis.FlowExpressions;
-import org.checkerframework.dataflow.analysis.Store;
-import org.checkerframework.dataflow.cfg.CFGVisualizer;
-import org.checkerframework.dataflow.cfg.node.IntegerLiteralNode;
-import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.dataflow.constantpropagation.Constant.Type;
-
-public class ConstantPropagationStore implements Store<ConstantPropagationStore> {
-
- /** Information about variables gathered so far. */
- Map<Node, Constant> contents;
-
- public ConstantPropagationStore() {
- contents = new HashMap<>();
- }
-
- protected ConstantPropagationStore(Map<Node, Constant> contents) {
- this.contents = contents;
- }
-
- public Constant getInformation(Node n) {
- if (contents.containsKey(n)) {
- return contents.get(n);
- }
- return new Constant(Type.TOP);
- }
-
- public void mergeInformation(Node n, Constant val) {
- Constant value;
- if (contents.containsKey(n)) {
- value = val.leastUpperBound(contents.get(n));
- } else {
- value = val;
- }
- // TODO: remove (only two nodes supported atm)
- assert n instanceof IntegerLiteralNode || n instanceof LocalVariableNode;
- contents.put(n, value);
- }
-
- public void setInformation(Node n, Constant val) {
- // TODO: remove (only two nodes supported atm)
- assert n instanceof IntegerLiteralNode || n instanceof LocalVariableNode;
- contents.put(n, val);
- }
-
- @Override
- public ConstantPropagationStore copy() {
- return new ConstantPropagationStore(new HashMap<>(contents));
- }
-
- @Override
- public ConstantPropagationStore leastUpperBound(ConstantPropagationStore other) {
- Map<Node, Constant> newContents = new HashMap<>();
-
- // go through all of the information of the other class
- for (Entry<Node, Constant> e : other.contents.entrySet()) {
- Node n = e.getKey();
- Constant otherVal = e.getValue();
- if (contents.containsKey(n)) {
- // merge if both contain information about a variable
- newContents.put(n, otherVal.leastUpperBound(contents.get(n)));
- } else {
- // add new information
- newContents.put(n, otherVal);
- }
- }
-
- for (Entry<Node, Constant> e : contents.entrySet()) {
- Node n = e.getKey();
- Constant thisVal = e.getValue();
- if (!other.contents.containsKey(n)) {
- // add new information
- newContents.put(n, thisVal);
- }
- }
-
- return new ConstantPropagationStore(newContents);
- }
-
- @Override
- public ConstantPropagationStore widenedUpperBound(ConstantPropagationStore previous) {
- return leastUpperBound(previous);
- }
-
- @Override
- public boolean equals(Object o) {
- if (o == null) {
- return false;
- }
- if (!(o instanceof ConstantPropagationStore)) {
- return false;
- }
- ConstantPropagationStore other = (ConstantPropagationStore) o;
- // go through all of the information of the other object
- for (Entry<Node, Constant> e : other.contents.entrySet()) {
- Node n = e.getKey();
- Constant otherVal = e.getValue();
- if (otherVal.isBottom()) {
- continue; // no information
- }
- if (contents.containsKey(n)) {
- if (!otherVal.equals(contents.get(n))) {
- return false;
- }
- } else {
- return false;
- }
- }
- // go through all of the information of the this object
- for (Entry<Node, Constant> e : contents.entrySet()) {
- Node n = e.getKey();
- Constant thisVal = e.getValue();
- if (thisVal.isBottom()) {
- continue; // no information
- }
- if (other.contents.containsKey(n)) {
- continue;
- } else {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public int hashCode() {
- int s = 0;
- for (Entry<Node, Constant> e : contents.entrySet()) {
- if (!e.getValue().isBottom()) {
- s += e.hashCode();
- }
- }
- return s;
- }
-
- @Override
- public String toString() {
- // only output local variable information
- Map<Node, Constant> smallerContents = new HashMap<>();
- for (Entry<Node, Constant> e : contents.entrySet()) {
- if (e.getKey() instanceof LocalVariableNode) {
- smallerContents.put(e.getKey(), e.getValue());
- }
- }
- return smallerContents.toString();
- }
-
- @Override
- public boolean canAlias(FlowExpressions.Receiver a, FlowExpressions.Receiver b) {
- return true;
- }
-
- @Override
- public void visualize(CFGVisualizer<?, ConstantPropagationStore, ?> viz) {
- // Do nothing since ConstantPropagationStore doesn't support visualize
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationTransfer.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationTransfer.java
deleted file mode 100644
index d5da13a518..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/constantpropagation/ConstantPropagationTransfer.java
+++ /dev/null
@@ -1,85 +0,0 @@
-package org.checkerframework.dataflow.constantpropagation;
-
-import java.util.List;
-import org.checkerframework.dataflow.analysis.ConditionalTransferResult;
-import org.checkerframework.dataflow.analysis.RegularTransferResult;
-import org.checkerframework.dataflow.analysis.TransferFunction;
-import org.checkerframework.dataflow.analysis.TransferInput;
-import org.checkerframework.dataflow.analysis.TransferResult;
-import org.checkerframework.dataflow.cfg.UnderlyingAST;
-import org.checkerframework.dataflow.cfg.node.AbstractNodeVisitor;
-import org.checkerframework.dataflow.cfg.node.AssignmentNode;
-import org.checkerframework.dataflow.cfg.node.EqualToNode;
-import org.checkerframework.dataflow.cfg.node.IntegerLiteralNode;
-import org.checkerframework.dataflow.cfg.node.LocalVariableNode;
-import org.checkerframework.dataflow.cfg.node.Node;
-
-public class ConstantPropagationTransfer
- extends AbstractNodeVisitor<
- TransferResult<Constant, ConstantPropagationStore>,
- TransferInput<Constant, ConstantPropagationStore>>
- implements TransferFunction<Constant, ConstantPropagationStore> {
-
- @Override
- public ConstantPropagationStore initialStore(
- UnderlyingAST underlyingAST, List<LocalVariableNode> parameters) {
- ConstantPropagationStore store = new ConstantPropagationStore();
- return store;
- }
-
- @Override
- public TransferResult<Constant, ConstantPropagationStore> visitLocalVariable(
- LocalVariableNode node, TransferInput<Constant, ConstantPropagationStore> before) {
- ConstantPropagationStore store = before.getRegularStore();
- Constant value = store.getInformation(node);
- return new RegularTransferResult<>(value, store);
- }
-
- @Override
- public TransferResult<Constant, ConstantPropagationStore> visitNode(
- Node n, TransferInput<Constant, ConstantPropagationStore> p) {
- return new RegularTransferResult<>(null, p.getRegularStore());
- }
-
- @Override
- public TransferResult<Constant, ConstantPropagationStore> visitAssignment(
- AssignmentNode n, TransferInput<Constant, ConstantPropagationStore> pi) {
- ConstantPropagationStore p = pi.getRegularStore();
- Node target = n.getTarget();
- Constant info = null;
- if (target instanceof LocalVariableNode) {
- LocalVariableNode t = (LocalVariableNode) target;
- info = p.getInformation(n.getExpression());
- p.setInformation(t, info);
- }
- return new RegularTransferResult<>(info, p);
- }
-
- @Override
- public TransferResult<Constant, ConstantPropagationStore> visitIntegerLiteral(
- IntegerLiteralNode n, TransferInput<Constant, ConstantPropagationStore> pi) {
- ConstantPropagationStore p = pi.getRegularStore();
- Constant c = new Constant(n.getValue());
- p.setInformation(n, c);
- return new RegularTransferResult<>(c, p);
- }
-
- @Override
- public TransferResult<Constant, ConstantPropagationStore> visitEqualTo(
- EqualToNode n, TransferInput<Constant, ConstantPropagationStore> pi) {
- ConstantPropagationStore p = pi.getRegularStore();
- ConstantPropagationStore old = p.copy();
- Node left = n.getLeftOperand();
- Node right = n.getRightOperand();
- process(p, left, right);
- process(p, right, left);
- return new ConditionalTransferResult<>(null, p, old);
- }
-
- protected void process(ConstantPropagationStore p, Node a, Node b) {
- Constant val = p.getInformation(a);
- if (b instanceof LocalVariableNode && val.isConstant()) {
- p.setInformation(b, val);
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Deterministic.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Deterministic.java
deleted file mode 100644
index 7e7d8b9cdc..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Deterministic.java
+++ /dev/null
@@ -1,87 +0,0 @@
-package org.checkerframework.dataflow.qual;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * A method is called <em>deterministic</em> if it returns the same value (according to {@code ==})
- * every time it is called with the same parameters and in the same environment. The parameters
- * include the receiver, and the environment includes all of the Java heap (that is, all fields of
- * all objects and all static variables).
- *
- * <p>Determinism refers to the return value during a non-exceptional execution. If a method throws
- * an exception, the Throwable does not have to be exactly the same object on each invocation (and
- * generally should not be, to capture the correct stack trace).
- *
- * <p>This annotation is important to pluggable type-checking because, after a call to a
- * {@code @Deterministic} method, flow-sensitive type refinement can assume that anything learned
- * about the first invocation is true about subsequent invocations (so long as no
- * non-{@code @}{@link SideEffectFree} method call intervenes). For example, the following code
- * never suffers a null pointer exception, so the Nullness Checker need not issue a warning:
- *
- * <pre>{@code
- * if (x.myDeterministicMethod() != null) {
- * x.myDeterministicMethod().hashCode();
- * }
- * }</pre>
- *
- * <p>Note that {@code @Deterministic} guarantees that the result is identical according to {@code
- * ==}, <b>not</b> just equal according to {@code equals()}. This means that writing <code>
- * {@literal @}Deterministic</code> on a method that returns a reference (including a String) is
- * often erroneous unless the returned value is cached or interned.
- *
- * <p>Also see {@link Pure}, which means both deterministic and {@link SideEffectFree}.
- *
- * <p><b>Analysis:</b> The Checker Framework performs a conservative analysis to verify a
- * {@code @Deterministic} annotation. The Checker Framework issues a warning if the method uses any
- * of the following Java constructs:
- *
- * <ol>
- * <li>Assignment to any expression, except for local variables (and method parameters).
- * <li>A method invocation of a method that is not {@link Deterministic}.
- * <li>Construction of a new object.
- * <li>Catching any exceptions. This is to prevent a method to get a hold of newly created objects
- * and using these objects (or some property thereof) to change their return value. For
- * instance, the following method must be forbidden.
- * <pre>
- * {@code @Deterministic
- * int f() {
- * try {
- * int b = 0;
- * int a = 1/b;
- * } catch (Throwable t) {
- * return t.hashCode();
- * }
- * return 0;
- * }
- * }</pre>
- * </ol>
- *
- * A constructor can be {@code @Pure}, but a constructor <em>invocation</em> is not deterministic
- * since it returns a different new object each time. TODO: Side-effect-free constructors could be
- * allowed to set their own fields.
- *
- * <p>Note that the rules for checking currently imply that every {@code Deterministic} method is
- * also {@link SideEffectFree}. This might change in the future; in general, a deterministic method
- * does not need to be side-effect-free.
- *
- * <p>These rules are conservative: any code that passes the checks is deterministic, but the
- * Checker Framework may issue false positive warnings, for code that uses one of the forbidden
- * constructs but is deterministic nonetheless.
- *
- * <p>In fact, the rules are so conservative that checking is currently disabled by default, but can
- * be enabled via the {@code -AcheckPurityAnnotations} command-line option.
- *
- * <p>
- *
- * @checker_framework.manual #type-refinement-purity Side effects, determinism, purity, and
- * flow-sensitive analysis
- * @author Stefan Heule
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
-public @interface Deterministic {}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Pure.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Pure.java
deleted file mode 100644
index 5a00db7a1b..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/Pure.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package org.checkerframework.dataflow.qual;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * {@code Pure} is a method annotation that means both {@link SideEffectFree} and {@link
- * Deterministic}. The more important of these, when performing pluggable type-checking, is usually
- * {@link SideEffectFree}.
- *
- * @checker_framework.manual #type-refinement-purity Side effects, determinism, purity, and
- * flow-sensitive analysis
- * @author Stefan Heule
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
-public @interface Pure {
- /** The type of purity. */
- public static enum Kind {
- /** The method has no visible side-effects. */
- SIDE_EFFECT_FREE,
-
- /** The method returns exactly the same value when called in the same environment. */
- DETERMINISTIC
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/SideEffectFree.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/SideEffectFree.java
deleted file mode 100644
index 6a969c4364..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/SideEffectFree.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.checkerframework.dataflow.qual;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * A method is called <em>side-effect-free</em> if it has no visible side-effects, such as setting a
- * field of an object that existed before the method was called.
- *
- * <p>Only the visible side-effects are important. The method is allowed to cache the answer to a
- * computationally expensive query, for instance. It is also allowed to modify newly-created
- * objects, and a constructor is side-effect-free if it does not modify any objects that existed
- * before it was called.
- *
- * <p>This annotation is important to pluggable type-checking because if some fact about an object
- * is known before a call to such a method, then the fact is still known afterwards, even if the
- * fact is about some non-final field. When any non-{@code @SideEffectFree} method is called, then a
- * pluggable type-checker must assume that any field of any accessible object might have been
- * modified, which annuls the effect of flow-sensitive type refinement and prevents the pluggable
- * type-checker from making conclusions that are obvious to a programmer.
- *
- * <p>Also see {@link Pure}, which means both side-effect-free and {@link Deterministic}.
- *
- * <p><b>Analysis:</b> The Checker Framework performs a conservative analysis to verify a
- * {@code @SideEffectFree} annotation. The Checker Framework issues a warning if the method uses any
- * of the following Java constructs:
- *
- * <ol>
- * <li>Assignment to any expression, except for local variables and method parameters.
- * <li>A method invocation of a method that is not {@code @SideEffectFree}.
- * <li>Construction of a new object where the constructor is not {@code @SideEffectFree}.
- * </ol>
- *
- * These rules are conservative: any code that passes the checks is side-effect-free, but the
- * Checker Framework may issue false positive warnings, for code that uses one of the forbidden
- * constructs but is side-effect-free nonetheless. In particular, a method that caches its result
- * will be rejected.
- *
- * <p>In fact, the rules are so conservative that checking is currently disabled by default, but can
- * be enabled via the {@code -AcheckPurityAnnotations} command-line option.
- *
- * <p>
- *
- * @checker_framework.manual #type-refinement-purity Side effects, determinism, purity, and
- * flow-sensitive analysis
- * @author Stefan Heule
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
-public @interface SideEffectFree {}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/TerminatesExecution.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/TerminatesExecution.java
deleted file mode 100644
index 4e83dcdb64..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/qual/TerminatesExecution.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.checkerframework.dataflow.qual;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * {@code TerminatesExecution} is a method annotation that indicates that a method terminates the
- * execution of the program. This can be used to annotate methods such as {@code System.exit()}.
- *
- * <p>The annotation enables flow-sensitive type refinement to be more precise. For example, after
- *
- * <pre>
- * if (x == null) {
- * System.err.println("Bad value supplied");
- * System.exit(1);
- * }
- * </pre>
- *
- * the Nullness Checker can determine that {@code x} is non-null.
- *
- * <p>The annotation is a <em>trusted</em> annotation, meaning that it is not checked whether the
- * annotated method really does terminate the program.
- *
- * @checker_framework.manual #type-refinement Automatic type refinement (flow-sensitive type
- * qualifier inference)
- * @author Stefan Heule
- */
-@Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
-public @interface TerminatesExecution {}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/HashCodeUtils.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/HashCodeUtils.java
deleted file mode 100644
index f898e3c9b4..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/HashCodeUtils.java
+++ /dev/null
@@ -1,102 +0,0 @@
-package org.checkerframework.dataflow.util;
-
-/**
- * Utility class to implement the {@code hashCode} method.
- *
- * @author Stefan Heule
- */
-public class HashCodeUtils {
-
- /** Odd prime number. */
- private static int prime = 31;
-
- /** Seed. */
- private static int seed = 17;
-
- /** Add a boolean value to a given hash. */
- public static int hash(int hash, boolean item) {
- return hash * prime + (item ? 1 : 0);
- }
-
- /** Add a char value to a given hash. */
- public static int hash(int hash, char item) {
- return hash * prime + item;
- }
-
- /** Add an int value to a given hash. */
- public static int hash(int hash, int item) {
- return hash * prime + item;
- }
-
- /** Add a long value to a given hash. */
- public static int hash(int hash, long item) {
- return hash * prime + (int) (item ^ (item >>> 32));
- }
-
- /** Add a float value to a given hash. */
- public static int hash(int hash, float item) {
- return hash * prime + Float.floatToIntBits(item);
- }
-
- /** Add a double value to a given hash. */
- public static int hash(int hash, double item) {
- long l = Double.doubleToLongBits(item);
- return seed * prime + (int) (l ^ (l >>> 32));
- }
-
- /** Add an object to a given hash. */
- public static int hash(int hash, Object item) {
- if (item == null) {
- return hash * prime;
- }
- return hash * prime + item.hashCode();
- }
-
- /** Hash a boolean value. */
- public static int hash(boolean item) {
- return (item ? 1 : 0);
- }
-
- /** Hash a char value. */
- public static int hash(char item) {
- return item;
- }
-
- /** Hash an int value. */
- public static int hash(int item) {
- return item;
- }
-
- /** Hash a long value. */
- public static int hash(long item) {
- return (int) (item ^ (item >>> 32));
- }
-
- /** Hash a float value. */
- public static int hash(float item) {
- return Float.floatToIntBits(item);
- }
-
- /** Hash a double value. */
- public static int hash(double item) {
- long l = Double.doubleToLongBits(item);
- return (int) (l ^ (l >>> 32));
- }
-
- /** Hash an object. */
- public static int hash(Object item) {
- if (item == null) {
- return 0;
- }
- return item.hashCode();
- }
-
- /** Hash multiple objects. */
- public static int hash(Object... items) {
- int result = seed;
- for (Object item : items) {
- result = result * prime + (item == null ? 0 : item.hashCode());
- }
- return result;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java
deleted file mode 100644
index 7e9172da91..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/MostlySingleton.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package org.checkerframework.dataflow.util;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Objects;
-import java.util.Set;
-
-/** A set that is more efficient than HashSet for 0 and 1 elements. */
-public final class MostlySingleton<T> implements Set<T> {
- private enum State {
- EMPTY,
- SINGLETON,
- ANY
- }
-
- private State state = State.EMPTY;
- private T value;
- private HashSet<T> set;
-
- @Override
- public int size() {
- switch (state) {
- case EMPTY:
- return 0;
- case SINGLETON:
- return 1;
- case ANY:
- return set.size();
- default:
- throw new AssertionError();
- }
- }
-
- @Override
- public boolean isEmpty() {
- return size() == 0;
- }
-
- @Override
- public boolean contains(Object o) {
- switch (state) {
- case EMPTY:
- return false;
- case SINGLETON:
- return Objects.equals(o, value);
- case ANY:
- return set.contains(o);
- default:
- throw new AssertionError();
- }
- }
-
- @Override
- @SuppressWarnings("fallthrough")
- public boolean add(T e) {
- switch (state) {
- case EMPTY:
- state = State.SINGLETON;
- value = e;
- return true;
- case SINGLETON:
- state = State.ANY;
- set = new HashSet<T>();
- set.add(value);
- value = null;
- // fallthrough
- case ANY:
- return set.add(e);
- default:
- throw new AssertionError();
- }
- }
-
- @Override
- public Iterator<T> iterator() {
- switch (state) {
- case EMPTY:
- return Collections.emptyIterator();
- case SINGLETON:
- return new Iterator<T>() {
- private boolean hasNext = true;
-
- @Override
- public boolean hasNext() {
- return hasNext;
- }
-
- @Override
- public T next() {
- if (hasNext) {
- hasNext = false;
- return value;
- }
- throw new NoSuchElementException();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
- case ANY:
- return set.iterator();
- default:
- throw new AssertionError();
- }
- }
-
- @Override
- public Object[] toArray() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <S> S[] toArray(S[] a) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean remove(Object o) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean containsAll(Collection<?> c) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean addAll(Collection<? extends T> c) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean retainAll(Collection<?> c) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean removeAll(Collection<?> c) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void clear() {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/NodeUtils.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/NodeUtils.java
deleted file mode 100644
index cf7a090024..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/NodeUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package org.checkerframework.dataflow.util;
-
-import com.sun.source.tree.Tree;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.tree.JCTree;
-import javax.lang.model.type.TypeKind;
-import org.checkerframework.dataflow.cfg.node.ConditionalOrNode;
-import org.checkerframework.dataflow.cfg.node.FieldAccessNode;
-import org.checkerframework.dataflow.cfg.node.Node;
-import org.checkerframework.javacutil.TypesUtils;
-
-/**
- * A utility class to operate on a given {@link Node}.
- *
- * @author Stefan Heule
- */
-public class NodeUtils {
-
- /**
- * @return true iff {@code node} corresponds to a boolean typed expression (either the primitive
- * type {@code boolean}, or class type {@link java.lang.Boolean})
- */
- public static boolean isBooleanTypeNode(Node node) {
-
- if (node instanceof ConditionalOrNode) {
- return true;
- }
-
- // not all nodes have an associated tree, but those are all not of a
- // boolean type.
- Tree tree = node.getTree();
- if (tree == null) {
- return false;
- }
-
- Type type = ((JCTree) tree).type;
- if (TypesUtils.isBooleanType(type)) {
- return true;
- }
-
- return false;
- }
-
- /**
- * @return true iff {@code node} is a {@link FieldAccessNode} that is an access to an array's
- * length
- */
- public static boolean isArrayLengthFieldAccess(Node node) {
- if (!(node instanceof FieldAccessNode)) {
- return false;
- }
- FieldAccessNode fieldAccess = (FieldAccessNode) node;
- return fieldAccess.getFieldName().equals("length")
- && fieldAccess.getReceiver().getType().getKind() == TypeKind.ARRAY;
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityChecker.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityChecker.java
deleted file mode 100644
index 0b298f1955..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityChecker.java
+++ /dev/null
@@ -1,491 +0,0 @@
-package org.checkerframework.dataflow.util;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-import org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey;
-*/
-
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.AssertTree;
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.BlockTree;
-import com.sun.source.tree.BreakTree;
-import com.sun.source.tree.CaseTree;
-import com.sun.source.tree.CatchTree;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompoundAssignmentTree;
-import com.sun.source.tree.ConditionalExpressionTree;
-import com.sun.source.tree.ContinueTree;
-import com.sun.source.tree.DoWhileLoopTree;
-import com.sun.source.tree.EmptyStatementTree;
-import com.sun.source.tree.EnhancedForLoopTree;
-import com.sun.source.tree.ExpressionStatementTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.ForLoopTree;
-import com.sun.source.tree.IdentifierTree;
-import com.sun.source.tree.IfTree;
-import com.sun.source.tree.InstanceOfTree;
-import com.sun.source.tree.LabeledStatementTree;
-import com.sun.source.tree.LambdaExpressionTree;
-import com.sun.source.tree.LiteralTree;
-import com.sun.source.tree.MemberReferenceTree;
-import com.sun.source.tree.MemberSelectTree;
-import com.sun.source.tree.MethodInvocationTree;
-import com.sun.source.tree.NewArrayTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.tree.ParenthesizedTree;
-import com.sun.source.tree.ReturnTree;
-import com.sun.source.tree.SwitchTree;
-import com.sun.source.tree.SynchronizedTree;
-import com.sun.source.tree.ThrowTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.TryTree;
-import com.sun.source.tree.TypeCastTree;
-import com.sun.source.tree.UnaryTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.tree.WhileLoopTree;
-import com.sun.source.util.SimpleTreeVisitor;
-import com.sun.tools.javac.tree.TreeScanner;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.List;
-import javax.lang.model.element.Element;
-import org.checkerframework.dataflow.qual.Deterministic;
-import org.checkerframework.dataflow.qual.Pure;
-import org.checkerframework.dataflow.qual.Pure.Kind;
-import org.checkerframework.dataflow.qual.SideEffectFree;
-import org.checkerframework.javacutil.AnnotationProvider;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.Pair;
-import org.checkerframework.javacutil.TreeUtils;
-
-/**
- * A visitor that determines the purity (as defined by {@link
- * org.checkerframework.dataflow.qual.SideEffectFree}, {@link
- * org.checkerframework.dataflow.qual.Deterministic}, and {@link
- * org.checkerframework.dataflow.qual.Pure}) of a statement or expression. The entry point is method
- * {@link #checkPurity}.
- *
- * @see SideEffectFree
- * @see Deterministic
- * @see Pure
- * @author Stefan Heule
- */
-public class PurityChecker {
-
- /**
- * Compute whether the given statement is side-effect-free, deterministic, or both. Returns a
- * result that can be queried.
- */
- public static PurityResult checkPurity(
- Tree statement, AnnotationProvider annoProvider, boolean assumeSideEffectFree) {
- PurityCheckerHelper helper = new PurityCheckerHelper(annoProvider, assumeSideEffectFree);
- PurityResult res = helper.scan(statement, new PurityResult());
- return res;
- }
-
- /**
- * Result of the {@link PurityChecker}. Can be queried regarding whether a given tree was
- * side-effect-free, deterministic, or both; also gives reasons if the answer is "no".
- */
- public static class PurityResult {
-
- protected final List<Pair<Tree, String>> notSeFreeReasons;
- protected final List<Pair<Tree, String>> notDetReasons;
- protected final List<Pair<Tree, String>> notBothReasons;
- protected EnumSet<Pure.Kind> types;
-
- public PurityResult() {
- notSeFreeReasons = new ArrayList<>();
- notDetReasons = new ArrayList<>();
- notBothReasons = new ArrayList<>();
- types = EnumSet.allOf(Pure.Kind.class);
- }
-
- public EnumSet<Pure.Kind> getTypes() {
- return types;
- }
-
- /** Is the method pure w.r.t. a given set of types? */
- public boolean isPure(Collection<Kind> kinds) {
- return types.containsAll(kinds);
- }
-
- /** Get the {@code reason}s why the method is not side-effect-free. */
- public List<Pair<Tree, String>> getNotSeFreeReasons() {
- return notSeFreeReasons;
- }
-
- /** Add {@code reason} as a reason why the method is not side-effect free. */
- public void addNotSeFreeReason(Tree t, String msgId) {
- notSeFreeReasons.add(Pair.of(t, msgId));
- types.remove(Kind.SIDE_EFFECT_FREE);
- }
-
- /** Get the {@code reason}s why the method is not deterministic. */
- public List<Pair<Tree, String>> getNotDetReasons() {
- return notDetReasons;
- }
-
- /** Add {@code reason} as a reason why the method is not deterministic. */
- public void addNotDetReason(Tree t, String msgId) {
- notDetReasons.add(Pair.of(t, msgId));
- types.remove(Kind.DETERMINISTIC);
- }
-
- /**
- * Get the {@code reason}s why the method is not both side-effect-free and deterministic.
- */
- public List<Pair<Tree, String>> getNotBothReasons() {
- return notBothReasons;
- }
-
- /**
- * Add {@code reason} as a reason why the method is not both side-effect free and
- * deterministic.
- */
- public void addNotBothReason(Tree t, String msgId) {
- notBothReasons.add(Pair.of(t, msgId));
- types.remove(Kind.DETERMINISTIC);
- types.remove(Kind.SIDE_EFFECT_FREE);
- }
- }
-
- /**
- * Helper class to keep {@link PurityChecker}'s interface clean. The implementation is heavily
- * based on {@link TreeScanner}, but some parts of the AST are skipped (such as types or
- * modifiers). Furthermore, scanning works differently in that the input parameter (usually
- * named {@code p}) gets "threaded through", instead of using {@code reduce}.
- */
- protected static class PurityCheckerHelper
- extends SimpleTreeVisitor<PurityResult, PurityResult> {
-
- protected final AnnotationProvider annoProvider;
- /**
- * True if all methods should be assumed to be @SideEffectFree, for the purposes of
- * org.checkerframework.dataflow analysis.
- */
- private final boolean assumeSideEffectFree;
-
- protected /*@Nullable*/ List<Element> methodParameter;
-
- public PurityCheckerHelper(AnnotationProvider annoProvider, boolean assumeSideEffectFree) {
- this.annoProvider = annoProvider;
- this.assumeSideEffectFree = assumeSideEffectFree;
- }
-
- /** Scan a single node. */
- public PurityResult scan(Tree node, PurityResult p) {
- return node == null ? p : node.accept(this, p);
- }
-
- /** Scan a list of nodes. */
- public PurityResult scan(Iterable<? extends Tree> nodes, PurityResult p) {
- PurityResult r = p;
- if (nodes != null) {
- for (Tree node : nodes) {
- r = scan(node, r);
- }
- }
- return r;
- }
-
- @Override
- protected PurityResult defaultAction(Tree node, PurityResult p) {
- assert false : "this type of tree is unexpected here";
- return null;
- }
-
- @Override
- public PurityResult visitClass(ClassTree node, PurityResult p) {
- return p;
- }
-
- @Override
- public PurityResult visitVariable(VariableTree node, PurityResult p) {
- return scan(node.getInitializer(), p);
- }
-
- @Override
- public PurityResult visitEmptyStatement(EmptyStatementTree node, PurityResult p) {
- return p;
- }
-
- @Override
- public PurityResult visitBlock(BlockTree node, PurityResult p) {
- return scan(node.getStatements(), p);
- }
-
- @Override
- public PurityResult visitDoWhileLoop(DoWhileLoopTree node, PurityResult p) {
- PurityResult r = scan(node.getStatement(), p);
- r = scan(node.getCondition(), r);
- return r;
- }
-
- @Override
- public PurityResult visitWhileLoop(WhileLoopTree node, PurityResult p) {
- PurityResult r = scan(node.getCondition(), p);
- r = scan(node.getStatement(), r);
- return r;
- }
-
- @Override
- public PurityResult visitForLoop(ForLoopTree node, PurityResult p) {
- PurityResult r = scan(node.getInitializer(), p);
- r = scan(node.getCondition(), r);
- r = scan(node.getUpdate(), r);
- r = scan(node.getStatement(), r);
- return r;
- }
-
- @Override
- public PurityResult visitEnhancedForLoop(EnhancedForLoopTree node, PurityResult p) {
- PurityResult r = scan(node.getVariable(), p);
- r = scan(node.getExpression(), r);
- r = scan(node.getStatement(), r);
- return r;
- }
-
- @Override
- public PurityResult visitLabeledStatement(LabeledStatementTree node, PurityResult p) {
- return scan(node.getStatement(), p);
- }
-
- @Override
- public PurityResult visitSwitch(SwitchTree node, PurityResult p) {
- PurityResult r = scan(node.getExpression(), p);
- r = scan(node.getCases(), r);
- return r;
- }
-
- @Override
- public PurityResult visitCase(CaseTree node, PurityResult p) {
- PurityResult r = scan(node.getExpression(), p);
- r = scan(node.getStatements(), r);
- return r;
- }
-
- @Override
- public PurityResult visitSynchronized(SynchronizedTree node, PurityResult p) {
- PurityResult r = scan(node.getExpression(), p);
- r = scan(node.getBlock(), r);
- return r;
- }
-
- @Override
- public PurityResult visitTry(TryTree node, PurityResult p) {
- PurityResult r = scan(node.getResources(), p);
- r = scan(node.getBlock(), r);
- r = scan(node.getCatches(), r);
- r = scan(node.getFinallyBlock(), r);
- return r;
- }
-
- @Override
- public PurityResult visitCatch(CatchTree node, PurityResult p) {
- p.addNotDetReason(node, "catch");
- PurityResult r = scan(node.getParameter(), p);
- r = scan(node.getBlock(), r);
- return r;
- }
-
- @Override
- public PurityResult visitConditionalExpression(
- ConditionalExpressionTree node, PurityResult p) {
- PurityResult r = scan(node.getCondition(), p);
- r = scan(node.getTrueExpression(), r);
- r = scan(node.getFalseExpression(), r);
- return r;
- }
-
- @Override
- public PurityResult visitIf(IfTree node, PurityResult p) {
- PurityResult r = scan(node.getCondition(), p);
- r = scan(node.getThenStatement(), r);
- r = scan(node.getElseStatement(), r);
- return r;
- }
-
- @Override
- public PurityResult visitExpressionStatement(ExpressionStatementTree node, PurityResult p) {
- return scan(node.getExpression(), p);
- }
-
- @Override
- public PurityResult visitBreak(BreakTree node, PurityResult p) {
- return p;
- }
-
- @Override
- public PurityResult visitContinue(ContinueTree node, PurityResult p) {
- return p;
- }
-
- @Override
- public PurityResult visitReturn(ReturnTree node, PurityResult p) {
- return scan(node.getExpression(), p);
- }
-
- @Override
- public PurityResult visitThrow(ThrowTree node, PurityResult p) {
- return scan(node.getExpression(), p);
- }
-
- @Override
- public PurityResult visitAssert(AssertTree node, PurityResult p) {
- PurityResult r = scan(node.getCondition(), p);
- r = scan(node.getDetail(), r);
- return r;
- }
-
- @Override
- public PurityResult visitMethodInvocation(MethodInvocationTree node, PurityResult p) {
- Element elt = TreeUtils.elementFromUse(node);
- String reason = "call";
- if (!PurityUtils.hasPurityAnnotation(annoProvider, elt)) {
- p.addNotBothReason(node, reason);
- } else {
- boolean det = PurityUtils.isDeterministic(annoProvider, elt);
- boolean seFree =
- (assumeSideEffectFree || PurityUtils.isSideEffectFree(annoProvider, elt));
- if (!det && !seFree) {
- p.addNotBothReason(node, reason);
- } else if (!det) {
- p.addNotDetReason(node, reason);
- } else if (!seFree) {
- p.addNotSeFreeReason(node, reason);
- }
- }
- PurityResult r = scan(node.getMethodSelect(), p);
- r = scan(node.getArguments(), r);
- return r;
- }
-
- @Override
- public PurityResult visitNewClass(NewClassTree node, PurityResult p) {
- Element methodElement = InternalUtils.symbol(node);
- boolean sideEffectFree =
- (assumeSideEffectFree
- || PurityUtils.isSideEffectFree(annoProvider, methodElement));
- if (sideEffectFree) {
- p.addNotDetReason(node, "object.creation");
- } else {
- p.addNotBothReason(node, "object.creation");
- }
- PurityResult r = scan(node.getEnclosingExpression(), p);
- r = scan(node.getArguments(), r);
- r = scan(node.getClassBody(), r);
- return r;
- }
-
- @Override
- public PurityResult visitNewArray(NewArrayTree node, PurityResult p) {
- PurityResult r = scan(node.getDimensions(), p);
- r = scan(node.getInitializers(), r);
- return r;
- }
-
- @Override
- public PurityResult visitLambdaExpression(LambdaExpressionTree node, PurityResult p) {
- PurityResult r = scan(node.getParameters(), p);
- r = scan(node.getBody(), r);
- return r;
- }
-
- @Override
- public PurityResult visitParenthesized(ParenthesizedTree node, PurityResult p) {
- return scan(node.getExpression(), p);
- }
-
- @Override
- public PurityResult visitAssignment(AssignmentTree node, PurityResult p) {
- ExpressionTree variable = node.getVariable();
- p = assignmentCheck(p, variable);
- PurityResult r = scan(variable, p);
- r = scan(node.getExpression(), r);
- return r;
- }
-
- protected PurityResult assignmentCheck(PurityResult p, ExpressionTree variable) {
- if (TreeUtils.isFieldAccess(variable)) {
- // rhs is a field access
- p.addNotBothReason(variable, "assign.field");
- } else if (variable instanceof ArrayAccessTree) {
- // rhs is array access
- p.addNotBothReason(variable, "assign.array");
- } else {
- // rhs is a local variable
- assert isLocalVariable(variable);
- }
- return p;
- }
-
- protected boolean isLocalVariable(ExpressionTree variable) {
- return variable instanceof IdentifierTree && !TreeUtils.isFieldAccess(variable);
- }
-
- @Override
- public PurityResult visitCompoundAssignment(CompoundAssignmentTree node, PurityResult p) {
- ExpressionTree variable = node.getVariable();
- p = assignmentCheck(p, variable);
- PurityResult r = scan(variable, p);
- r = scan(node.getExpression(), r);
- return r;
- }
-
- @Override
- public PurityResult visitUnary(UnaryTree node, PurityResult p) {
- return scan(node.getExpression(), p);
- }
-
- @Override
- public PurityResult visitBinary(BinaryTree node, PurityResult p) {
- PurityResult r = scan(node.getLeftOperand(), p);
- r = scan(node.getRightOperand(), r);
- return r;
- }
-
- @Override
- public PurityResult visitTypeCast(TypeCastTree node, PurityResult p) {
- PurityResult r = scan(node.getExpression(), p);
- return r;
- }
-
- @Override
- public PurityResult visitInstanceOf(InstanceOfTree node, PurityResult p) {
- PurityResult r = scan(node.getExpression(), p);
- return r;
- }
-
- @Override
- public PurityResult visitArrayAccess(ArrayAccessTree node, PurityResult p) {
- PurityResult r = scan(node.getExpression(), p);
- r = scan(node.getIndex(), r);
- return r;
- }
-
- @Override
- public PurityResult visitMemberSelect(MemberSelectTree node, PurityResult p) {
- return scan(node.getExpression(), p);
- }
-
- @Override
- public PurityResult visitMemberReference(MemberReferenceTree node, PurityResult p) {
- assert false : "this type of tree is unexpected here";
- return null;
- }
-
- @Override
- public PurityResult visitIdentifier(IdentifierTree node, PurityResult p) {
- return p;
- }
-
- @Override
- public PurityResult visitLiteral(LiteralTree node, PurityResult p) {
- return p;
- }
- }
-}
diff --git a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityUtils.java b/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityUtils.java
deleted file mode 100644
index c175877a24..0000000000
--- a/third_party/checker_framework_dataflow/java/org/checkerframework/dataflow/util/PurityUtils.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package org.checkerframework.dataflow.util;
-
-import com.sun.source.tree.MethodTree;
-import java.util.ArrayList;
-import java.util.List;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import org.checkerframework.dataflow.qual.Deterministic;
-import org.checkerframework.dataflow.qual.Pure;
-import org.checkerframework.dataflow.qual.Pure.Kind;
-import org.checkerframework.dataflow.qual.SideEffectFree;
-import org.checkerframework.javacutil.AnnotationProvider;
-import org.checkerframework.javacutil.InternalUtils;
-
-/**
- * An utility class for working with the {@link SideEffectFree}, {@link Deterministic}, and {@link
- * Pure} annotations.
- *
- * @see SideEffectFree
- * @see Deterministic
- * @see Pure
- * @author Stefan Heule
- */
-public class PurityUtils {
-
- /** Does the method {@code tree} have any purity annotation? */
- public static boolean hasPurityAnnotation(AnnotationProvider provider, MethodTree tree) {
- return !getPurityKinds(provider, tree).isEmpty();
- }
-
- /** Does the method {@code methodElement} have any purity annotation? */
- public static boolean hasPurityAnnotation(AnnotationProvider provider, Element methodElement) {
- return !getPurityKinds(provider, methodElement).isEmpty();
- }
-
- /** Is the method {@code tree} deterministic? */
- public static boolean isDeterministic(AnnotationProvider provider, MethodTree tree) {
- Element methodElement = InternalUtils.symbol(tree);
- return isDeterministic(provider, methodElement);
- }
-
- /** Is the method {@code methodElement} deterministic? */
- public static boolean isDeterministic(AnnotationProvider provider, Element methodElement) {
- List<Kind> kinds = getPurityKinds(provider, methodElement);
- return kinds.contains(Kind.DETERMINISTIC);
- }
-
- /** Is the method {@code tree} side-effect-free? */
- public static boolean isSideEffectFree(AnnotationProvider provider, MethodTree tree) {
- Element methodElement = InternalUtils.symbol(tree);
- return isSideEffectFree(provider, methodElement);
- }
-
- /** Is the method {@code methodElement} side-effect-free? */
- public static boolean isSideEffectFree(AnnotationProvider provider, Element methodElement) {
- List<Kind> kinds = getPurityKinds(provider, methodElement);
- return kinds.contains(Kind.SIDE_EFFECT_FREE);
- }
-
- /** @return the types of purity of the method {@code tree}. */
- public static List<Pure.Kind> getPurityKinds(AnnotationProvider provider, MethodTree tree) {
- Element methodElement = InternalUtils.symbol(tree);
- return getPurityKinds(provider, methodElement);
- }
-
- /**
- * @return the types of purity of the method {@code methodElement}. TODO: should the return type
- * be an EnumSet?
- */
- public static List<Pure.Kind> getPurityKinds(
- AnnotationProvider provider, Element methodElement) {
- AnnotationMirror pureAnnotation = provider.getDeclAnnotation(methodElement, Pure.class);
- AnnotationMirror sefAnnotation =
- provider.getDeclAnnotation(methodElement, SideEffectFree.class);
- AnnotationMirror detAnnotation =
- provider.getDeclAnnotation(methodElement, Deterministic.class);
-
- List<Pure.Kind> kinds = new ArrayList<>();
- if (pureAnnotation != null) {
- kinds.add(Kind.DETERMINISTIC);
- kinds.add(Kind.SIDE_EFFECT_FREE);
- }
- if (sefAnnotation != null) {
- kinds.add(Kind.SIDE_EFFECT_FREE);
- }
- if (detAnnotation != null) {
- kinds.add(Kind.DETERMINISTIC);
- }
- return kinds;
- }
-}