aboutsummaryrefslogtreecommitdiffhomepage
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
parent83d8ef1c4a67c23c103741cca23bafafdc811c79 (diff)
Update to version 2.4.0 of Checker Framework dataflow and javacutil
Change-Id: I29e007625d0a25279d8b2967f89b1014b4825bd6
-rw-r--r--third_party/BUILD1
-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
-rw-r--r--third_party/checker_framework_javacutil/BUILD13
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AbstractTypeProcessor.java196
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationProvider.java28
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationUtils.java650
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicAnnotationProvider.java29
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicTypeProcessor.java37
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/CollectionUtils.java26
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ElementUtils.java492
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorHandler.java17
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorReporter.java54
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/InternalUtils.java483
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Pair.java69
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Resolver.java397
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TreeUtils.java1020
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypeAnnotationUtils.java397
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypesUtils.java452
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/dist/ManualTaglet.java124
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/DetachedVarSymbol.java36
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeBuilder.java655
-rw-r--r--third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeParser.java141
-rw-r--r--third_party/checker_framework_javacutil/javacutil-2.4.0-sources.jarbin0 -> 55484 bytes
-rw-r--r--third_party/checker_framework_javacutil/javacutil-2.4.0.jarbin0 -> 89501 bytes
142 files changed, 11 insertions, 21344 deletions
diff --git a/third_party/BUILD b/third_party/BUILD
index 82f59faf5c..043047cb3a 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -386,6 +386,7 @@ filegroup(
"jsr305/jsr-305.jar",
"pcollections/pcollections-2.1.2.jar",
"//third_party/checker_framework_dataflow:bootstrap",
+ "//third_party/checker_framework_javacutil:bootstrap",
"//third_party/jformatstring:bootstrap",
],
)
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;
- }
-}
diff --git a/third_party/checker_framework_javacutil/BUILD b/third_party/checker_framework_javacutil/BUILD
index cc18ab2020..77e0c5cc2b 100644
--- a/third_party/checker_framework_javacutil/BUILD
+++ b/third_party/checker_framework_javacutil/BUILD
@@ -7,16 +7,13 @@ filegroup(
srcs = glob(["**"]),
)
-java_library(
+java_import(
name = "checker_framework_javacutil",
- srcs = glob(["java/**"]),
- deps = ["@local_jdk//:langtools-neverlink"],
+ jars = ["javacutil-2.4.0.jar"],
+ srcjar = "javacutil-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/**"]),
- neverlink_jars = ["@local_jdk//:langtools"],
+ srcs = ["javacutil-2.4.0.jar"],
)
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AbstractTypeProcessor.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AbstractTypeProcessor.java
deleted file mode 100644
index 114ce6d0b6..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AbstractTypeProcessor.java
+++ /dev/null
@@ -1,196 +0,0 @@
-package org.checkerframework.javacutil;
-
-import com.sun.source.tree.ClassTree;
-import com.sun.source.util.JavacTask;
-import com.sun.source.util.TaskEvent;
-import com.sun.source.util.TaskListener;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.comp.CompileStates.CompileState;
-import com.sun.tools.javac.main.JavaCompiler;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Log;
-import java.util.HashSet;
-import java.util.Set;
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.annotation.processing.Processor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.ElementFilter;
-
-/**
- * This class is an abstract annotation processor designed to be a convenient superclass for
- * concrete "type processors", processors that require the type information in the processed source.
- *
- * <p>Type processing occurs in one round after the tool (e.g. Java compiler) analyzes the source
- * (all sources taken as input to the tool and sources generated by other annotation processors).
- *
- * <p>The tool infrastructure will interact with classes extending this abstract class as follows.
- *
- * <p>1-3 are identical to the {@link Processor} life cycle. 4-5 are unique to {@code
- * AbstractTypeProcessor} subclasses.
- *
- * <ol>
- * <li>If an existing {@code Processor} object is not being used, to create an instance of a
- * processor the tool calls the no-arg constructor of the processor class.
- * <li>Next, the tool calls the {@link #init init} method with an appropriate {@code
- * ProcessingEnvironment}.
- * <li>Afterwards, the tool calls {@link #getSupportedAnnotationTypes
- * getSupportedAnnotationTypes}, {@link #getSupportedOptions getSupportedOptions}, and {@link
- * #getSupportedSourceVersion getSupportedSourceVersion}. These methods are only called once
- * per run, not on each round.
- * <li>For each class containing a supported annotation, the tool calls {@link
- * #typeProcess(TypeElement, TreePath) typeProcess} method on the {@code Processor}. The class
- * is guaranteed to be type-checked Java code and all the tree type and symbol information is
- * resolved.
- * <li>Finally, the tools calls the {@link #typeProcessingOver() typeProcessingOver} method on the
- * {@code Processor}.
- * </ol>
- *
- * <p>The tool is permitted to ask type processors to process a class once it is analyzed before the
- * rest of classes are analyzed. The tool is also permitted to stop type processing immediately if
- * any errors are raised, without invoking {@code typeProcessingOver}
- *
- * <p>A subclass may override any of the methods in this class, as long as the general {@link
- * javax.annotation.processing.Processor Processor} contract is obeyed, with one notable exception.
- * {@link #process(Set, RoundEnvironment)} may not be overridden, as it is called during the
- * declaration annotation phase before classes are analyzed.
- *
- * @author Mahmood Ali
- * @author Werner Dietl
- */
-public abstract class AbstractTypeProcessor extends AbstractProcessor {
- /**
- * The set of fully-qualified element names that should be type-checked. We store the names of
- * the elements, in order to prevent possible confusion between different Element
- * instantiations.
- */
- private final Set<Name> elements = new HashSet<Name>();
-
- /**
- * Method {@link #typeProcessingStart()} must be invoked exactly once, before any invocation of
- * {@link #typeProcess(TypeElement, TreePath)}.
- */
- private boolean hasInvokedTypeProcessingStart = false;
-
- /**
- * Method {@link #typeProcessingOver()} must be invoked exactly once, after the last invocation
- * of {@link #typeProcess(TypeElement, TreePath)}.
- */
- private static boolean hasInvokedTypeProcessingOver = false;
-
- /** The TaskListener registered for completion of attribution. */
- private final AttributionTaskListener listener = new AttributionTaskListener();
-
- /** Constructor for subclasses to call. */
- protected AbstractTypeProcessor() {}
-
- /**
- * {@inheritDoc}
- *
- * <p>Register a TaskListener that will get called after FLOW.
- */
- @Override
- public synchronized void init(ProcessingEnvironment env) {
- super.init(env);
- JavacTask.instance(env).addTaskListener(listener);
- Context ctx = ((JavacProcessingEnvironment) processingEnv).getContext();
- JavaCompiler compiler = JavaCompiler.instance(ctx);
- compiler.shouldStopPolicyIfNoError =
- CompileState.max(compiler.shouldStopPolicyIfNoError, CompileState.FLOW);
- compiler.shouldStopPolicyIfError =
- CompileState.max(compiler.shouldStopPolicyIfError, CompileState.FLOW);
- }
-
- /**
- * The use of this method is obsolete in type processors. The method is called during
- * declaration annotation processing phase only. It registers the names of elements to process.
- */
- @Override
- public final boolean process(
- Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- for (TypeElement elem : ElementFilter.typesIn(roundEnv.getRootElements())) {
- elements.add(elem.getQualifiedName());
- }
- return false;
- }
-
- /**
- * A method to be called once before the first call to typeProcess.
- *
- * <p>Subclasses may override this method to do any initialization work.
- */
- public void typeProcessingStart() {}
-
- /**
- * Processes a fully-analyzed class that contains a supported annotation (see {@link
- * #getSupportedAnnotationTypes()}).
- *
- * <p>The passed class is always valid type-checked Java code.
- *
- * @param element element of the analyzed class
- * @param tree the tree path to the element, with the leaf being a {@link ClassTree}
- */
- public abstract void typeProcess(TypeElement element, TreePath tree);
-
- /**
- * A method to be called once all the classes are processed and no error is reported.
- *
- * <p>Subclasses may override this method to do any aggregate analysis (e.g. generate report,
- * persistence) or resource deallocation.
- *
- * <p>If an error (a Java error or a processor error) is reported, this method is not guaranteed
- * to be invoked.
- */
- public void typeProcessingOver() {}
-
- /** A task listener that invokes the processor whenever a class is fully analyzed. */
- private final class AttributionTaskListener implements TaskListener {
-
- @Override
- public void finished(TaskEvent e) {
- if (e.getKind() != TaskEvent.Kind.ANALYZE) {
- return;
- }
-
- if (!hasInvokedTypeProcessingStart) {
- typeProcessingStart();
- hasInvokedTypeProcessingStart = true;
- }
-
- Log log = Log.instance(((JavacProcessingEnvironment) processingEnv).getContext());
-
- if (!hasInvokedTypeProcessingOver && elements.isEmpty() && log.nerrors == 0) {
- typeProcessingOver();
- hasInvokedTypeProcessingOver = true;
- }
-
- if (e.getTypeElement() == null) {
- throw new AssertionError("event task without a type element");
- }
- if (e.getCompilationUnit() == null) {
- throw new AssertionError("event task without compilation unit");
- }
-
- if (!elements.remove(e.getTypeElement().getQualifiedName())) {
- return;
- }
-
- TypeElement elem = e.getTypeElement();
- TreePath p = Trees.instance(processingEnv).getPath(elem);
-
- typeProcess(elem, p);
-
- if (!hasInvokedTypeProcessingOver && elements.isEmpty() && log.nerrors == 0) {
- typeProcessingOver();
- hasInvokedTypeProcessingOver = true;
- }
- }
-
- @Override
- public void started(TaskEvent e) {}
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationProvider.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationProvider.java
deleted file mode 100644
index 1245960edd..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationProvider.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.checkerframework.javacutil;
-
-import com.sun.source.tree.Tree;
-import java.lang.annotation.Annotation;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-
-/** An implementation of AnnotationProvider returns annotations on Java AST elements. */
-public interface AnnotationProvider {
-
- /**
- * Returns the actual annotation mirror used to annotate this type, whose name equals the passed
- * annotationName if one exists, null otherwise.
- *
- * @param anno annotation class
- * @return the annotation mirror for anno
- */
- public AnnotationMirror getDeclAnnotation(Element elt, Class<? extends Annotation> anno);
-
- /**
- * Return the annotation on {@code tree} that has the class {@code target}. If no annotation for
- * the given target class exists, the result is {@code null}
- *
- * @param tree the tree of which the annotation is returned
- * @param target the class of the annotation
- */
- public AnnotationMirror getAnnotationMirror(Tree tree, Class<? extends Annotation> target);
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationUtils.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationUtils.java
deleted file mode 100644
index c80f57cc5d..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/AnnotationUtils.java
+++ /dev/null
@@ -1,650 +0,0 @@
-package org.checkerframework.javacutil;
-
-/*>>>
-import org.checkerframework.dataflow.qual.Pure;
-import org.checkerframework.dataflow.qual.SideEffectFree;
-import org.checkerframework.checker.nullness.qual.*;
-import org.checkerframework.checker.interning.qual.*;
-*/
-
-import com.sun.source.tree.AnnotationTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.ModifiersTree;
-import com.sun.tools.javac.code.Symbol.VarSymbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.model.JavacElements;
-import java.lang.annotation.Annotation;
-import java.lang.annotation.Inherited;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.Elements;
-
-/** A utility class for working with annotations. */
-public class AnnotationUtils {
-
- // Class cannot be instantiated.
- private AnnotationUtils() {
- throw new AssertionError("Class AnnotationUtils cannot be instantiated.");
- }
-
- // TODO: hack to clear out static state.
- public static void clear() {
- annotationsFromNames.clear();
- annotationMirrorNames.clear();
- annotationMirrorSimpleNames.clear();
- annotationClassNames.clear();
- }
-
- // **********************************************************************
- // Factory Methods to create instances of AnnotationMirror
- // **********************************************************************
-
- /** Caching for annotation creation. */
- private static final Map<CharSequence, AnnotationMirror> annotationsFromNames =
- Collections.synchronizedMap(new HashMap<CharSequence, AnnotationMirror>());
-
- private static final int ANNOTATION_CACHE_SIZE = 500;
-
- /**
- * Cache names of AnnotationMirrors for faster access. Values in the map are interned Strings,
- * so they can be compared with ==.
- */
- private static final Map<AnnotationMirror, /*@Interned*/ String> annotationMirrorNames =
- Collections.synchronizedMap(
- CollectionUtils.<AnnotationMirror, /*@Interned*/ String>createLRUCache(
- ANNOTATION_CACHE_SIZE));
-
- /**
- * Cache simple names of AnnotationMirrors for faster access. Values in the map are interned
- * Strings, so they can be compared with ==.
- */
- private static final Map<AnnotationMirror, /*@Interned*/ String> annotationMirrorSimpleNames =
- Collections.synchronizedMap(
- CollectionUtils.<AnnotationMirror, /*@Interned*/ String>createLRUCache(
- ANNOTATION_CACHE_SIZE));
-
- /**
- * Cache names of classes representing AnnotationMirrors for faster access. Values in the map
- * are interned Strings, so they can be compared with ==.
- */
- private static final Map<Class<? extends Annotation>, /*@Interned*/ String>
- annotationClassNames =
- Collections.synchronizedMap(
- new HashMap<Class<? extends Annotation>, /*@Interned*/ String>());
-
- /**
- * Creates an {@link AnnotationMirror} given by a particular fully-qualified name.
- * getElementValues on the result returns an empty map.
- *
- * @param elements the element utilities to use
- * @param name the name of the annotation to create
- * @return an {@link AnnotationMirror} of type {@code} name
- */
- public static AnnotationMirror fromName(Elements elements, CharSequence name) {
- AnnotationMirror res = annotationsFromNames.get(name);
- if (res != null) {
- return res;
- }
- final DeclaredType annoType = typeFromName(elements, name);
- if (annoType == null) {
- return null;
- }
- if (annoType.asElement().getKind() != ElementKind.ANNOTATION_TYPE) {
- ErrorReporter.errorAbort(annoType + " is not an annotation");
- return null; // dead code
- }
- AnnotationMirror result =
- new AnnotationMirror() {
- String toString = "@" + annoType;
-
- @Override
- public DeclaredType getAnnotationType() {
- return annoType;
- }
-
- @Override
- public Map<? extends ExecutableElement, ? extends AnnotationValue>
- getElementValues() {
- return Collections.emptyMap();
- }
- /*@SideEffectFree*/
- @Override
- public String toString() {
- return toString;
- }
- };
- annotationsFromNames.put(name, result);
- return result;
- }
-
- /**
- * Creates an {@link AnnotationMirror} given by a particular annotation class.
- *
- * @param elements the element utilities to use
- * @param clazz the annotation class
- * @return an {@link AnnotationMirror} of type given type
- */
- public static AnnotationMirror fromClass(Elements elements, Class<? extends Annotation> clazz) {
- return fromName(elements, clazz.getCanonicalName());
- }
-
- /**
- * A utility method that converts a {@link CharSequence} (usually a {@link String}) into a
- * {@link TypeMirror} named thereby.
- *
- * @param elements the element utilities to use
- * @param name the name of a type
- * @return the {@link TypeMirror} corresponding to that name
- */
- private static DeclaredType typeFromName(Elements elements, CharSequence name) {
- /*@Nullable*/ TypeElement typeElt = elements.getTypeElement(name);
- if (typeElt == null) {
- return null;
- }
-
- return (DeclaredType) typeElt.asType();
- }
-
- // **********************************************************************
- // Helper methods to handle annotations. mainly workaround
- // AnnotationMirror.equals undesired property
- // (I think the undesired property is that it's reference equality.)
- // **********************************************************************
-
- /** @return the fully-qualified name of an annotation as a String */
- public static final /*@Interned*/ String annotationName(AnnotationMirror annotation) {
- String res = annotationMirrorNames.get(annotation);
- if (res != null) {
- return res;
- }
- final DeclaredType annoType = annotation.getAnnotationType();
- final TypeElement elm = (TypeElement) annoType.asElement();
- /*@Interned*/ String name = elm.getQualifiedName().toString().intern();
- annotationMirrorNames.put(annotation, name);
- return name;
- }
-
- /** @return the simple name of an annotation as a String */
- public static String annotationSimpleName(AnnotationMirror annotation) {
- String res = annotationMirrorSimpleNames.get(annotation);
- if (res != null) {
- return res;
- }
- final DeclaredType annoType = annotation.getAnnotationType();
- final TypeElement elm = (TypeElement) annoType.asElement();
- /*@Interned*/ String name = elm.getSimpleName().toString().intern();
- annotationMirrorSimpleNames.put(annotation, name);
- return name;
- }
-
- /**
- * Checks if both annotations are the same.
- *
- * <p>Returns true iff both annotations are of the same type and have the same annotation
- * values. This behavior differs from {@code AnnotationMirror.equals(Object)}. The equals method
- * returns true iff both annotations are the same and annotate the same annotation target (e.g.
- * field, variable, etc).
- *
- * @return true iff a1 and a2 are the same annotation
- */
- public static boolean areSame(
- /*@Nullable*/ AnnotationMirror a1, /*@Nullable*/ AnnotationMirror a2) {
- if (a1 != null && a2 != null) {
- if (annotationName(a1) != annotationName(a2)) {
- return false;
- }
-
- Map<? extends ExecutableElement, ? extends AnnotationValue> elval1 =
- getElementValuesWithDefaults(a1);
- Map<? extends ExecutableElement, ? extends AnnotationValue> elval2 =
- getElementValuesWithDefaults(a2);
-
- return elval1.toString().equals(elval2.toString());
- }
-
- // only true, iff both are null
- return a1 == a2;
- }
-
- /**
- * @see #areSame(AnnotationMirror, AnnotationMirror)
- * @return true iff a1 and a2 have the same annotation type
- */
- public static boolean areSameIgnoringValues(AnnotationMirror a1, AnnotationMirror a2) {
- if (a1 != null && a2 != null) {
- return annotationName(a1) == annotationName(a2);
- }
- return a1 == a2;
- }
-
- /** Checks that the annotation {@code am} has the name {@code aname}. Values are ignored. */
- public static boolean areSameByName(AnnotationMirror am, /*@Interned*/ String aname) {
- // Both strings are interned.
- return annotationName(am) == aname;
- }
-
- /** Checks that the annotation {@code am} has the name of {@code anno}. Values are ignored. */
- public static boolean areSameByClass(AnnotationMirror am, Class<? extends Annotation> anno) {
- /*@Interned*/ String canonicalName = annotationClassNames.get(anno);
- if (canonicalName == null) {
- canonicalName = anno.getCanonicalName().intern();
- annotationClassNames.put(anno, canonicalName);
- }
- return areSameByName(am, canonicalName);
- }
-
- /**
- * Checks that two collections contain the same annotations.
- *
- * @return true iff c1 and c2 contain the same annotations
- */
- public static boolean areSame(
- Collection<? extends AnnotationMirror> c1, Collection<? extends AnnotationMirror> c2) {
- if (c1.size() != c2.size()) {
- return false;
- }
- if (c1.size() == 1) {
- return areSame(c1.iterator().next(), c2.iterator().next());
- }
-
- Set<AnnotationMirror> s1 = createAnnotationSet();
- Set<AnnotationMirror> s2 = createAnnotationSet();
- s1.addAll(c1);
- s2.addAll(c2);
-
- // depend on the fact that Set is an ordered set.
- Iterator<AnnotationMirror> iter1 = s1.iterator();
- Iterator<AnnotationMirror> iter2 = s2.iterator();
-
- while (iter1.hasNext()) {
- AnnotationMirror anno1 = iter1.next();
- AnnotationMirror anno2 = iter2.next();
- if (!areSame(anno1, anno2)) {
- return false;
- }
- }
- return true;
- }
-
- /**
- * Checks that the collection contains the annotation. Using Collection.contains does not always
- * work, because it does not use areSame for comparison.
- *
- * @return true iff c contains anno, according to areSame
- */
- public static boolean containsSame(
- Collection<? extends AnnotationMirror> c, AnnotationMirror anno) {
- return getSame(c, anno) != null;
- }
-
- /**
- * Returns the AnnotationMirror in {@code c} that is the same annotation as {@code anno}.
- *
- * @return AnnotationMirror with the same class as {@code anno} iff c contains anno, according
- * to areSame; otherwise, {@code null}
- */
- public static AnnotationMirror getSame(
- Collection<? extends AnnotationMirror> c, AnnotationMirror anno) {
- for (AnnotationMirror an : c) {
- if (AnnotationUtils.areSame(an, anno)) {
- return an;
- }
- }
- return null;
- }
-
- /**
- * Checks that the collection contains the annotation. Using Collection.contains does not always
- * work, because it does not use areSame for comparison.
- *
- * @return true iff c contains anno, according to areSameByClass
- */
- public static boolean containsSameByClass(
- Collection<? extends AnnotationMirror> c, Class<? extends Annotation> anno) {
- return getAnnotationByClass(c, anno) != null;
- }
-
- /**
- * Returns the AnnotationMirror in {@code c} that has the same class as {@code anno}.
- *
- * @return AnnotationMirror with the same class as {@code anno} iff c contains anno, according
- * to areSameByClass; otherwise, {@code null}
- */
- public static AnnotationMirror getAnnotationByClass(
- Collection<? extends AnnotationMirror> c, Class<? extends Annotation> anno) {
- for (AnnotationMirror an : c) {
- if (AnnotationUtils.areSameByClass(an, anno)) {
- return an;
- }
- }
- return null;
- }
-
- /**
- * Checks that the collection contains the annotation ignoring values. Using Collection.contains
- * does not always work, because it does not use areSameIgnoringValues for comparison.
- *
- * @return true iff c contains anno, according to areSameIgnoringValues
- */
- public static boolean containsSameIgnoringValues(
- Collection<? extends AnnotationMirror> c, AnnotationMirror anno) {
- return getSameIgnoringValues(c, anno) != null;
- }
-
- /**
- * Returns the AnnotationMirror in {@code c} that is the same annotation as {@code anno}
- * ignoring values.
- *
- * @return AnnotationMirror with the same class as {@code anno} iff c contains anno, according
- * to areSameIgnoringValues; otherwise, {@code null}
- */
- public static AnnotationMirror getSameIgnoringValues(
- Collection<? extends AnnotationMirror> c, AnnotationMirror anno) {
- for (AnnotationMirror an : c) {
- if (AnnotationUtils.areSameIgnoringValues(an, anno)) {
- return an;
- }
- }
- return null;
- }
-
- private static final Comparator<AnnotationMirror> ANNOTATION_ORDERING =
- new Comparator<AnnotationMirror>() {
- @Override
- public int compare(AnnotationMirror a1, AnnotationMirror a2) {
- // AnnotationMirror.toString() prints the elements of an annotation in the
- // order in which they were written. So, use areSame to check for equality.
- if (AnnotationUtils.areSame(a1, a2)) {
- return 0;
- }
-
- String n1 = a1.toString();
- String n2 = a2.toString();
-
- // Because the AnnotationMirror.toString prints the annotation as it appears
- // in source code, the order in which annotations of the same class are
- // sorted may be confusing. For example, it might order
- // @IntRange(from=1, to=MAX) before @IntRange(to=MAX,from=0).
- return n1.compareTo(n2);
- }
- };
-
- /**
- * provide ordering for {@link AnnotationMirror} based on their fully qualified name. The
- * ordering ignores annotation values when ordering.
- *
- * <p>The ordering is meant to be used as {@link TreeSet} or {@link TreeMap} ordering. A {@link
- * Set} should not contain two annotations that only differ in values.
- */
- public static Comparator<AnnotationMirror> annotationOrdering() {
- return ANNOTATION_ORDERING;
- }
-
- /**
- * Create a map suitable for storing {@link AnnotationMirror} as keys.
- *
- * <p>It can store one instance of {@link AnnotationMirror} of a given declared type, regardless
- * of the annotation element values.
- *
- * @param <V> the value of the map
- * @return a new map with {@link AnnotationMirror} as key
- */
- public static <V> Map<AnnotationMirror, V> createAnnotationMap() {
- return new TreeMap<AnnotationMirror, V>(annotationOrdering());
- }
-
- /**
- * Constructs a {@link Set} suitable for storing {@link AnnotationMirror}s.
- *
- * <p>It stores at most once instance of {@link AnnotationMirror} of a given type, regardless of
- * the annotation element values.
- *
- * @return a new set to store {@link AnnotationMirror} as element
- */
- public static Set<AnnotationMirror> createAnnotationSet() {
- return new TreeSet<AnnotationMirror>(annotationOrdering());
- }
-
- /** Returns true if the given annotation has a @Inherited meta-annotation. */
- public static boolean hasInheritedMeta(AnnotationMirror anno) {
- return anno.getAnnotationType().asElement().getAnnotation(Inherited.class) != null;
- }
-
- // **********************************************************************
- // Extractors for annotation values
- // **********************************************************************
-
- /**
- * Returns the values of an annotation's attributes, including defaults. The method with the
- * same name in JavacElements cannot be used directly, because it includes a cast to
- * Attribute.Compound, which doesn't hold for annotations generated by the Checker Framework.
- *
- * @see AnnotationMirror#getElementValues()
- * @see JavacElements#getElementValuesWithDefaults(AnnotationMirror)
- * @param ad annotation to examine
- * @return the values of the annotation's elements, including defaults
- */
- public static Map<? extends ExecutableElement, ? extends AnnotationValue>
- getElementValuesWithDefaults(AnnotationMirror ad) {
- Map<ExecutableElement, AnnotationValue> valMap =
- new HashMap<ExecutableElement, AnnotationValue>();
- if (ad.getElementValues() != null) {
- valMap.putAll(ad.getElementValues());
- }
- for (ExecutableElement meth :
- ElementFilter.methodsIn(ad.getAnnotationType().asElement().getEnclosedElements())) {
- AnnotationValue defaultValue = meth.getDefaultValue();
- if (defaultValue != null && !valMap.containsKey(meth)) {
- valMap.put(meth, defaultValue);
- }
- }
- return valMap;
- }
-
- /**
- * Verify whether the attribute with the name {@code name} exists in the annotation {@code
- * anno}.
- *
- * @param anno the annotation to examine
- * @param name the name of the attribute
- * @return whether the attribute exists in anno
- */
- public static <T> boolean hasElementValue(AnnotationMirror anno, CharSequence name) {
- Map<? extends ExecutableElement, ? extends AnnotationValue> valmap =
- anno.getElementValues();
- for (ExecutableElement elem : valmap.keySet()) {
- if (elem.getSimpleName().contentEquals(name)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Get the attribute with the name {@code name} of the annotation {@code anno}. The result is
- * expected to have type {@code expectedType}.
- *
- * <p><em>Note 1</em>: The method does not work well for attributes of an array type (as it
- * would return a list of {@link AnnotationValue}s). Use {@code getElementValueArray} instead.
- *
- * <p><em>Note 2</em>: The method does not work for attributes of an enum type, as the
- * AnnotationValue is a VarSymbol and would be cast to the enum type, which doesn't work. Use
- * {@code getElementValueEnum} instead.
- *
- * @param anno the annotation to disassemble
- * @param name the name of the attribute to access
- * @param expectedType the expected type used to cast the return type
- * @param useDefaults whether to apply default values to the attribute
- * @return the value of the attribute with the given name
- */
- public static <T> T getElementValue(
- AnnotationMirror anno, CharSequence name, Class<T> expectedType, boolean useDefaults) {
- Map<? extends ExecutableElement, ? extends AnnotationValue> valmap;
- if (useDefaults) {
- valmap = getElementValuesWithDefaults(anno);
- } else {
- valmap = anno.getElementValues();
- }
- for (ExecutableElement elem : valmap.keySet()) {
- if (elem.getSimpleName().contentEquals(name)) {
- AnnotationValue val = valmap.get(elem);
- return expectedType.cast(val.getValue());
- }
- }
- ErrorReporter.errorAbort("No element with name \'" + name + "\' in annotation " + anno);
- return null; // dead code
- }
-
- /** Version that is suitable for Enum elements. */
- public static <T extends Enum<T>> T getElementValueEnum(
- AnnotationMirror anno, CharSequence name, Class<T> t, boolean useDefaults) {
- VarSymbol vs = getElementValue(anno, name, VarSymbol.class, useDefaults);
- T value = Enum.valueOf(t, vs.getSimpleName().toString());
- return value;
- }
-
- /**
- * Get the attribute with the name {@code name} of the annotation {@code anno}, where the
- * attribute has an array type. One element of the result is expected to have type {@code
- * expectedType}.
- *
- * <p>Parameter useDefaults is used to determine whether default values should be used for
- * annotation values. Finding defaults requires more computation, so should be false when no
- * defaulting is needed.
- *
- * @param anno the annotation to disassemble
- * @param name the name of the attribute to access
- * @param expectedType the expected type used to cast the return type
- * @param useDefaults whether to apply default values to the attribute
- * @return the value of the attribute with the given name
- */
- public static <T> List<T> getElementValueArray(
- AnnotationMirror anno, CharSequence name, Class<T> expectedType, boolean useDefaults) {
- @SuppressWarnings("unchecked")
- List<AnnotationValue> la = getElementValue(anno, name, List.class, useDefaults);
- List<T> result = new ArrayList<T>(la.size());
- for (AnnotationValue a : la) {
- result.add(expectedType.cast(a.getValue()));
- }
- return result;
- }
-
- /**
- * Get the attribute with the name {@code name} of the annotation {@code anno}, or the default
- * value if no attribute is present explicitly, where the attribute has an array type and the
- * elements are {@code Enum}s. One element of the result is expected to have type {@code
- * expectedType}.
- */
- public static <T extends Enum<T>> List<T> getElementValueEnumArray(
- AnnotationMirror anno, CharSequence name, Class<T> t, boolean useDefaults) {
- @SuppressWarnings("unchecked")
- List<AnnotationValue> la = getElementValue(anno, name, List.class, useDefaults);
- List<T> result = new ArrayList<T>(la.size());
- for (AnnotationValue a : la) {
- T value = Enum.valueOf(t, a.getValue().toString());
- result.add(value);
- }
- return result;
- }
-
- /**
- * Get the Name of the class that is referenced by attribute {@code name}.
- *
- * <p>This is a convenience method for the most common use-case. Like getElementValue(anno,
- * name, ClassType.class).getQualifiedName(), but this method ensures consistent use of the
- * qualified name.
- */
- public static Name getElementValueClassName(
- AnnotationMirror anno, CharSequence name, boolean useDefaults) {
- Type.ClassType ct = getElementValue(anno, name, Type.ClassType.class, useDefaults);
- // TODO: Is it a problem that this returns the type parameters too? Should I cut them off?
- return ct.asElement().getQualifiedName();
- }
-
- /** Get the list of Names of the classes that are referenced by attribute {@code name}. */
- public static List<Name> getElementValueClassNames(
- AnnotationMirror anno, CharSequence name, boolean useDefaults) {
- List<Type.ClassType> la =
- getElementValueArray(anno, name, Type.ClassType.class, useDefaults);
- List<Name> names = new ArrayList<>();
- for (Type.ClassType classType : la) {
- names.add(classType.asElement().getQualifiedName());
- }
- return names;
- }
-
- /**
- * Get the Class that is referenced by attribute {@code name}. This method uses Class.forName to
- * load the class. It returns null if the class wasn't found.
- */
- public static Class<?> getElementValueClass(
- AnnotationMirror anno, CharSequence name, boolean useDefaults) {
- Name cn = getElementValueClassName(anno, name, useDefaults);
- try {
- ClassLoader classLoader = InternalUtils.getClassLoaderForClass(AnnotationUtils.class);
- Class<?> cls = Class.forName(cn.toString(), true, classLoader);
- return cls;
- } catch (ClassNotFoundException e) {
- String msg =
- String.format(
- "Could not load class '%s' for field '%s' in annotation %s",
- cn, name, anno);
- ErrorReporter.errorAbort(msg, e);
- return null; // dead code
- }
- }
-
- /**
- * See checkers.types.QualifierHierarchy#updateMappingToMutableSet(QualifierHierarchy, Map,
- * Object, AnnotationMirror) (Not linked because it is in an independent project.
- */
- public static <T> void updateMappingToImmutableSet(
- Map<T, Set<AnnotationMirror>> map, T key, Set<AnnotationMirror> newQual) {
-
- Set<AnnotationMirror> result = AnnotationUtils.createAnnotationSet();
- // TODO: if T is also an AnnotationMirror, should we use areSame?
- if (!map.containsKey(key)) {
- result.addAll(newQual);
- } else {
- result.addAll(map.get(key));
- result.addAll(newQual);
- }
- map.put(key, Collections.unmodifiableSet(result));
- }
-
- /**
- * Returns the annotations explicitly written on a constructor result. Callers should check that
- * {@code constructorDeclaration} is in fact a declaration of a constructor.
- *
- * @param constructorDeclaration declaration tree of constructor
- * @return set of annotations explicit on the resulting type of the constructor
- */
- public static Set<AnnotationMirror> getExplicitAnnotationsOnConstructorResult(
- MethodTree constructorDeclaration) {
- Set<AnnotationMirror> annotationSet = AnnotationUtils.createAnnotationSet();
- ModifiersTree modifiersTree = constructorDeclaration.getModifiers();
- if (modifiersTree != null) {
- List<? extends AnnotationTree> annotationTrees = modifiersTree.getAnnotations();
- annotationSet.addAll(InternalUtils.annotationsFromTypeAnnotationTrees(annotationTrees));
- }
- return annotationSet;
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicAnnotationProvider.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicAnnotationProvider.java
deleted file mode 100644
index 6cf40e79cf..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicAnnotationProvider.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.checkerframework.javacutil;
-
-import com.sun.source.tree.Tree;
-import java.lang.annotation.Annotation;
-import java.util.List;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-
-public class BasicAnnotationProvider implements AnnotationProvider {
-
- @Override
- public AnnotationMirror getDeclAnnotation(Element elt, Class<? extends Annotation> anno) {
- List<? extends AnnotationMirror> annotationMirrors = elt.getAnnotationMirrors();
-
- // Then look at the real annotations.
- for (AnnotationMirror am : annotationMirrors) {
- if (AnnotationUtils.areSameByClass(am, anno)) {
- return am;
- }
- }
-
- return null;
- }
-
- @Override
- public AnnotationMirror getAnnotationMirror(Tree tree, Class<? extends Annotation> target) {
- return null;
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicTypeProcessor.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicTypeProcessor.java
deleted file mode 100644
index 6b68fa4dc2..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/BasicTypeProcessor.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.checkerframework.javacutil;
-
-import com.sun.source.tree.CompilationUnitTree;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.TreePathScanner;
-import javax.lang.model.element.TypeElement;
-
-/**
- * Process the types in an AST in a trivial manner, with hooks for derived classes to actually do
- * something.
- */
-public abstract class BasicTypeProcessor extends AbstractTypeProcessor {
- /** The source tree that's being scanned. */
- protected CompilationUnitTree currentRoot;
-
- /** Create a TreePathScanner at the given root. */
- protected abstract TreePathScanner<?, ?> createTreePathScanner(CompilationUnitTree root);
-
- /** Visit the tree path for the type element. */
- @Override
- public void typeProcess(TypeElement e, TreePath p) {
- currentRoot = p.getCompilationUnit();
-
- TreePathScanner<?, ?> scanner = null;
- try {
- scanner = createTreePathScanner(currentRoot);
- scanner.scan(p, null);
- } catch (Throwable t) {
- System.err.println(
- "BasicTypeProcessor.typeProcess: unexpected Throwable ("
- + t.getClass().getSimpleName()
- + ") when processing "
- + currentRoot.getSourceFile().getName()
- + (t.getMessage() != null ? "; message: " + t.getMessage() : ""));
- }
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/CollectionUtils.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/CollectionUtils.java
deleted file mode 100644
index a6a58250fc..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/CollectionUtils.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.checkerframework.javacutil;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/** Utility methods related to Java Collections */
-public class CollectionUtils {
-
- /**
- * A Utility method for creating LRU cache
- *
- * @param size size of the cache
- * @return a new cache with the provided size
- */
- public static <K, V> Map<K, V> createLRUCache(final int size) {
- return new LinkedHashMap<K, V>() {
-
- private static final long serialVersionUID = 5261489276168775084L;
-
- @Override
- protected boolean removeEldestEntry(Map.Entry<K, V> entry) {
- return size() > size;
- }
- };
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ElementUtils.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ElementUtils.java
deleted file mode 100644
index 4abfa86cb7..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ElementUtils.java
+++ /dev/null
@@ -1,492 +0,0 @@
-package org.checkerframework.javacutil;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-import static com.sun.tools.javac.code.Flags.ABSTRACT;
-import static com.sun.tools.javac.code.Flags.EFFECTIVELY_FINAL;
-import static com.sun.tools.javac.code.Flags.FINAL;
-
-import com.sun.tools.javac.code.Symbol;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.PackageElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.Elements;
-
-/** A Utility class for analyzing {@code Element}s. */
-public class ElementUtils {
-
- // Class cannot be instantiated.
- private ElementUtils() {
- throw new AssertionError("Class ElementUtils cannot be instantiated.");
- }
-
- /**
- * Returns the innermost type element enclosing the given element
- *
- * @param elem the enclosed element of a class
- * @return the innermost type element
- */
- public static TypeElement enclosingClass(final Element elem) {
- Element result = elem;
- while (result != null && !result.getKind().isClass() && !result.getKind().isInterface()) {
- /*@Nullable*/ Element encl = result.getEnclosingElement();
- result = encl;
- }
- return (TypeElement) result;
- }
-
- /**
- * Returns the innermost package element enclosing the given element. The same effect as {@link
- * javax.lang.model.util.Elements#getPackageOf(Element)}. Returns the element itself if it is a
- * package.
- *
- * @param elem the enclosed element of a package
- * @return the innermost package element
- */
- public static PackageElement enclosingPackage(final Element elem) {
- Element result = elem;
- while (result != null && result.getKind() != ElementKind.PACKAGE) {
- /*@Nullable*/ Element encl = result.getEnclosingElement();
- result = encl;
- }
- return (PackageElement) result;
- }
-
- /**
- * Returns the "parent" package element for the given package element. For package "A.B" it
- * gives "A". For package "A" it gives the default package. For the default package it returns
- * null;
- *
- * <p>Note that packages are not enclosed within each other, we have to manually climb the
- * namespaces. Calling "enclosingPackage" on a package element returns the package element
- * itself again.
- *
- * @param elem the package to start from
- * @return the parent package element
- */
- public static PackageElement parentPackage(final Elements e, final PackageElement elem) {
- // The following might do the same thing:
- // ((Symbol) elt).owner;
- // TODO: verify and see whether the change is worth it.
- String fqnstart = elem.getQualifiedName().toString();
- String fqn = fqnstart;
- if (fqn != null && !fqn.isEmpty() && fqn.contains(".")) {
- fqn = fqn.substring(0, fqn.lastIndexOf('.'));
- return e.getPackageElement(fqn);
- }
- return null;
- }
-
- /**
- * Returns true if the element is a static element: whether it is a static field, static method,
- * or static class
- *
- * @return true if element is static
- */
- public static boolean isStatic(Element element) {
- return element.getModifiers().contains(Modifier.STATIC);
- }
-
- /**
- * Returns true if the element is a final element: a final field, final method, or final class
- *
- * @return true if the element is final
- */
- public static boolean isFinal(Element element) {
- return element.getModifiers().contains(Modifier.FINAL);
- }
-
- /**
- * Returns true if the element is a effectively final element.
- *
- * @return true if the element is effectively final
- */
- public static boolean isEffectivelyFinal(Element element) {
- Symbol sym = (Symbol) element;
- if (sym.getEnclosingElement().getKind() == ElementKind.METHOD
- && (sym.getEnclosingElement().flags() & ABSTRACT) != 0) {
- return true;
- }
- return (sym.flags() & (FINAL | EFFECTIVELY_FINAL)) != 0;
- }
-
- /**
- * Returns the {@code TypeMirror} for usage of Element as a value. It returns the return type of
- * a method element, the class type of a constructor, or simply the type mirror of the element
- * itself.
- *
- * @return the type for the element used as a value
- */
- public static TypeMirror getType(Element element) {
- if (element.getKind() == ElementKind.METHOD) {
- return ((ExecutableElement) element).getReturnType();
- } else if (element.getKind() == ElementKind.CONSTRUCTOR) {
- return enclosingClass(element).asType();
- } else {
- return element.asType();
- }
- }
-
- /**
- * Returns the qualified name of the inner most class enclosing the provided {@code Element}
- *
- * @param element an element enclosed by a class, or a {@code TypeElement}
- * @return the qualified {@code Name} of the innermost class enclosing the element
- */
- public static /*@Nullable*/ Name getQualifiedClassName(Element element) {
- if (element.getKind() == ElementKind.PACKAGE) {
- PackageElement elem = (PackageElement) element;
- return elem.getQualifiedName();
- }
-
- TypeElement elem = enclosingClass(element);
- if (elem == null) {
- return null;
- }
-
- return elem.getQualifiedName();
- }
-
- /** Returns a verbose name that identifies the element. */
- public static String getVerboseName(Element elt) {
- if (elt.getKind() == ElementKind.PACKAGE
- || elt.getKind().isClass()
- || elt.getKind().isInterface()) {
- return getQualifiedClassName(elt).toString();
- } else {
- return getQualifiedClassName(elt) + "." + elt.toString();
- }
- }
-
- /**
- * Check if the element is an element for 'java.lang.Object'
- *
- * @param element the type element
- * @return true iff the element is java.lang.Object element
- */
- public static boolean isObject(TypeElement element) {
- return element.getQualifiedName().contentEquals("java.lang.Object");
- }
-
- /** Returns true if the element is a constant time reference */
- public static boolean isCompileTimeConstant(Element elt) {
- return elt != null
- && (elt.getKind() == ElementKind.FIELD
- || elt.getKind() == ElementKind.LOCAL_VARIABLE)
- && ((VariableElement) elt).getConstantValue() != null;
- }
-
- /**
- * Returns true if the element is declared in ByteCode. Always return false if elt is a package.
- */
- public static boolean isElementFromByteCode(Element elt) {
- if (elt == null) {
- return false;
- }
-
- if (elt instanceof Symbol.ClassSymbol) {
- Symbol.ClassSymbol clss = (Symbol.ClassSymbol) elt;
- if (null != clss.classfile) {
- // The class file could be a .java file
- return clss.classfile.getName().endsWith(".class");
- } else {
- return false;
- }
- }
- return isElementFromByteCode(elt.getEnclosingElement(), elt);
- }
-
- /**
- * Returns true if the element is declared in ByteCode. Always return false if elt is a package.
- */
- private static boolean isElementFromByteCode(Element elt, Element orig) {
- if (elt == null) {
- return false;
- }
- if (elt instanceof Symbol.ClassSymbol) {
- Symbol.ClassSymbol clss = (Symbol.ClassSymbol) elt;
- if (null != clss.classfile) {
- // The class file could be a .java file
- return (clss.classfile.getName().endsWith(".class")
- || clss.classfile.getName().endsWith(".class)")
- || clss.classfile.getName().endsWith(".class)]"));
- } else {
- return false;
- }
- }
- return isElementFromByteCode(elt.getEnclosingElement(), elt);
- }
-
- /** Returns the field of the class */
- public static VariableElement findFieldInType(TypeElement type, String name) {
- for (VariableElement field : ElementFilter.fieldsIn(type.getEnclosedElements())) {
- if (field.getSimpleName().toString().equals(name)) {
- return field;
- }
- }
- return null;
- }
-
- /**
- * Returns the elements of the fields whose simple names are {@code names} and are declared in
- * {@code type}.
- *
- * <p>If a field isn't declared in {@code type}, its element isn't included in the returned set.
- * If none of the fields is declared in {@code type}, the empty set is returned.
- *
- * @param type where to look for fields
- * @param names simple names of fields that might be declared in {@code type}
- * @return the elements of the fields whose simple names are {@code names} and are declared in
- * {@code type}
- */
- public static Set<VariableElement> findFieldsInType(
- TypeElement type, Collection<String> names) {
- Set<VariableElement> results = new HashSet<VariableElement>();
- for (VariableElement field : ElementFilter.fieldsIn(type.getEnclosedElements())) {
- if (names.contains(field.getSimpleName().toString())) {
- results.add(field);
- }
- }
- return results;
- }
-
- /**
- * Returns non-private field elements, and side-effects {@code names} to remove them. For every
- * field name in {@code names} that is declared in {@code type} or a supertype, add its element
- * to the returned set and remove it from {@code names}.
- *
- * <p>When this routine returns, the combination of the return value and {@code names} has the
- * same cardinality, and represents the same fields, as {@code names} did when the method was
- * called.
- *
- * @param type where to look for fields
- * @param names simple names of fields that might be declared in {@code type} or a supertype.
- * (Names that are found are removed from this list.)
- * @return the {@code VariableElement}s for non-private fields that are declared in {@code type}
- * whose simple names were in {@code names} when the method was called.
- */
- public static Set<VariableElement> findFieldsInTypeOrSuperType(
- TypeMirror type, Collection<String> names) {
- Set<VariableElement> elements = new HashSet<>();
- findFieldsInTypeOrSuperType(type, names, elements);
- return elements;
- }
-
- /**
- * Side-effects both {@code foundFields} (which starts empty) and {@code notFound}, conceptually
- * moving elements from {@code notFound} to {@code foundFields}.
- */
- private static void findFieldsInTypeOrSuperType(
- TypeMirror type, Collection<String> notFound, Set<VariableElement> foundFields) {
- if (TypesUtils.isObject(type)) {
- return;
- }
- TypeElement elt = InternalUtils.getTypeElement(type);
-
- Set<VariableElement> fieldElts = findFieldsInType(elt, notFound);
- for (VariableElement field : new HashSet<>(fieldElts)) {
- if (!field.getModifiers().contains(Modifier.PRIVATE)) {
- notFound.remove(field.getSimpleName().toString());
- } else {
- fieldElts.remove(field);
- }
- }
- foundFields.addAll(fieldElts);
-
- if (!notFound.isEmpty()) {
- findFieldsInTypeOrSuperType(elt.getSuperclass(), notFound, foundFields);
- }
- }
-
- public static boolean isError(Element element) {
- return element.getClass()
- .getName()
- .equals("com.sun.tools.javac.comp.Resolve$SymbolNotFoundError");
- }
-
- /**
- * Does the given element need a receiver for accesses? For example, an access to a local
- * variable does not require a receiver.
- *
- * @param element the element to test
- * @return whether the element requires a receiver for accesses
- */
- public static boolean hasReceiver(Element element) {
- return (element.getKind().isField()
- || element.getKind() == ElementKind.METHOD
- || element.getKind() == ElementKind.CONSTRUCTOR)
- && !ElementUtils.isStatic(element);
- }
-
- /**
- * Determine all type elements for the classes and interfaces referenced (directly or
- * indirectly) in the extends/implements clauses of the given type element.
- *
- * <p>TODO: can we learn from the implementation of
- * com.sun.tools.javac.model.JavacElements.getAllMembers(TypeElement)?
- */
- public static List<TypeElement> getSuperTypes(Elements elements, TypeElement type) {
-
- List<TypeElement> superelems = new ArrayList<TypeElement>();
- if (type == null) {
- return superelems;
- }
-
- // Set up a stack containing type, which is our starting point.
- Deque<TypeElement> stack = new ArrayDeque<TypeElement>();
- stack.push(type);
-
- while (!stack.isEmpty()) {
- TypeElement current = stack.pop();
-
- // For each direct supertype of the current type element, if it
- // hasn't already been visited, push it onto the stack and
- // add it to our superelems set.
- TypeMirror supertypecls;
- try {
- supertypecls = current.getSuperclass();
- } catch (com.sun.tools.javac.code.Symbol.CompletionFailure cf) {
- // Looking up a supertype failed. This sometimes happens
- // when transitive dependencies are not on the classpath.
- // As javac didn't complain, let's also not complain.
- // TODO: Use an expanded ErrorReporter to output a message.
- supertypecls = null;
- }
-
- if (supertypecls != null && supertypecls.getKind() != TypeKind.NONE) {
- TypeElement supercls = (TypeElement) ((DeclaredType) supertypecls).asElement();
- if (!superelems.contains(supercls)) {
- stack.push(supercls);
- superelems.add(supercls);
- }
- }
-
- for (TypeMirror supertypeitf : current.getInterfaces()) {
- TypeElement superitf = (TypeElement) ((DeclaredType) supertypeitf).asElement();
- if (!superelems.contains(superitf)) {
- stack.push(superitf);
- superelems.add(superitf);
- }
- }
- }
-
- // Include java.lang.Object as implicit superclass for all classes and interfaces.
- TypeElement jlobject = elements.getTypeElement("java.lang.Object");
- if (!superelems.contains(jlobject)) {
- superelems.add(jlobject);
- }
-
- return Collections.<TypeElement>unmodifiableList(superelems);
- }
-
- /**
- * Return all fields declared in the given type or any superclass/interface. TODO: should this
- * use javax.lang.model.util.Elements.getAllMembers(TypeElement) instead of our own
- * getSuperTypes?
- */
- public static List<VariableElement> getAllFieldsIn(Elements elements, TypeElement type) {
- List<VariableElement> fields = new ArrayList<VariableElement>();
- fields.addAll(ElementFilter.fieldsIn(type.getEnclosedElements()));
- List<TypeElement> alltypes = getSuperTypes(elements, type);
- for (TypeElement atype : alltypes) {
- fields.addAll(ElementFilter.fieldsIn(atype.getEnclosedElements()));
- }
- return Collections.<VariableElement>unmodifiableList(fields);
- }
-
- /**
- * Return all methods declared in the given type or any superclass/interface. Note that no
- * constructors will be returned. TODO: should this use
- * javax.lang.model.util.Elements.getAllMembers(TypeElement) instead of our own getSuperTypes?
- */
- public static List<ExecutableElement> getAllMethodsIn(Elements elements, TypeElement type) {
- List<ExecutableElement> meths = new ArrayList<ExecutableElement>();
- meths.addAll(ElementFilter.methodsIn(type.getEnclosedElements()));
-
- List<TypeElement> alltypes = getSuperTypes(elements, type);
- for (TypeElement atype : alltypes) {
- meths.addAll(ElementFilter.methodsIn(atype.getEnclosedElements()));
- }
- return Collections.<ExecutableElement>unmodifiableList(meths);
- }
-
- public static boolean isTypeDeclaration(Element elt) {
- switch (elt.getKind()) {
- // These tree kinds are always declarations. Uses of the declared
- // types have tree kind IDENTIFIER.
- case ANNOTATION_TYPE:
- case CLASS:
- case ENUM:
- case INTERFACE:
- case TYPE_PARAMETER:
- return true;
-
- default:
- return false;
- }
- }
-
- /**
- * Check that a method Element matches a signature.
- *
- * <p>Note: Matching the receiver type must be done elsewhere as the Element receiver type is
- * only populated when annotated.
- *
- * @param method the method Element
- * @param methodName the name of the method
- * @param parameters the formal parameters' Classes
- * @return true if the method matches
- */
- public static boolean matchesElement(
- ExecutableElement method, String methodName, Class<?>... parameters) {
-
- if (!method.getSimpleName().toString().equals(methodName)) {
- return false;
- }
-
- if (method.getParameters().size() != parameters.length) {
- return false;
- } else {
- for (int i = 0; i < method.getParameters().size(); i++) {
- if (!method.getParameters()
- .get(i)
- .asType()
- .toString()
- .equals(parameters[i].getName())) {
-
- return false;
- }
- }
- }
-
- return true;
- }
-
- /** Returns true if the given element is, or overrides, method. */
- public static boolean isMethod(
- ExecutableElement questioned, ExecutableElement method, ProcessingEnvironment env) {
- TypeElement enclosing = (TypeElement) questioned.getEnclosingElement();
- return questioned.equals(method)
- || env.getElementUtils().overrides(questioned, method, enclosing);
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorHandler.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorHandler.java
deleted file mode 100644
index 76ee74eaca..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorHandler.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.checkerframework.javacutil;
-
-/**
- * An implementation of the ErrorHandler interface can be registered with the ErrorReporter class to
- * change the default behavior on errors.
- */
-public interface ErrorHandler {
-
- /**
- * Log an error message and abort processing.
- *
- * @param msg the error message to log
- */
- public void errorAbort(String msg);
-
- public void errorAbort(String msg, Throwable cause);
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorReporter.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorReporter.java
deleted file mode 100644
index 4ff62e05d1..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/ErrorReporter.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.checkerframework.javacutil;
-
-/**
- * Handle errors detected in utility classes. By default, the error reporter throws a
- * RuntimeException, but clients of the utility library may register a handler to change the
- * behavior. For example, type checkers can direct errors to the
- * org.checkerframework.framework.source.SourceChecker class.
- */
-public class ErrorReporter {
-
- protected static ErrorHandler handler = null;
-
- /** Register a handler to customize error reporting. */
- public static void setHandler(ErrorHandler h) {
- handler = h;
- }
-
- /**
- * Log an error message and abort processing. Call this method instead of raising an exception.
- *
- * @param msg the error message to log
- */
- public static void errorAbort(String msg) {
- if (handler != null) {
- handler.errorAbort(msg);
- } else {
- throw new RuntimeException(msg, new Throwable());
- }
- }
-
- /**
- * Log an error message use {@link String#format(String, Object...)}} and abort processing. Call
- * this method instead of raising an exception.
- *
- * @param format a format string
- * @param args arguments to the format string
- */
- public static void errorAbort(String format, Object... args) {
- String formattedMsg = String.format(format, args);
- if (handler != null) {
- handler.errorAbort(formattedMsg);
- } else {
- throw new RuntimeException(formattedMsg, new Throwable());
- }
- }
-
- public static void errorAbort(String msg, Throwable cause) {
- if (handler != null) {
- handler.errorAbort(msg, cause);
- } else {
- throw new RuntimeException(msg, cause);
- }
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/InternalUtils.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/InternalUtils.java
deleted file mode 100644
index 10a48cd719..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/InternalUtils.java
+++ /dev/null
@@ -1,483 +0,0 @@
-package org.checkerframework.javacutil;
-
-import com.sun.source.tree.AnnotatedTypeTree;
-import com.sun.source.tree.AnnotationTree;
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.ExpressionTree;
-import com.sun.source.tree.MethodTree;
-import com.sun.source.tree.NewArrayTree;
-import com.sun.source.tree.NewClassTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.TypeParameterTree;
-import com.sun.source.util.TreePath;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symbol.TypeSymbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.code.Type.CapturedType;
-import com.sun.tools.javac.code.Types;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCAnnotatedType;
-import com.sun.tools.javac.tree.JCTree.JCAnnotation;
-import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
-import com.sun.tools.javac.tree.JCTree.JCMemberReference;
-import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
-import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
-import com.sun.tools.javac.tree.JCTree.JCNewArray;
-import com.sun.tools.javac.tree.JCTree.JCNewClass;
-import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
-import com.sun.tools.javac.tree.TreeInfo;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.WildcardType;
-import javax.lang.model.util.Elements;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.*;
-*/
-
-/**
- * Static utility methods used by annotation abstractions in this package. Some methods in this
- * class depend on the use of Sun javac internals; any procedure in the Checker Framework that uses
- * a non-public API should be placed here.
- */
-public class InternalUtils {
-
- // Class cannot be instantiated.
- private InternalUtils() {
- throw new AssertionError("Class InternalUtils cannot be instantiated.");
- }
-
- /**
- * Gets the {@link Element} ("symbol") for the given Tree API node.
- *
- * @param tree the {@link Tree} node to get the symbol for
- * @throws IllegalArgumentException if {@code tree} is null or is not a valid javac-internal
- * tree (JCTree)
- * @return the {@link Symbol} for the given tree, or null if one could not be found
- */
- public static /*@Nullable*/ Element symbol(Tree tree) {
- if (tree == null) {
- ErrorReporter.errorAbort("InternalUtils.symbol: tree is null");
- return null; // dead code
- }
-
- if (!(tree instanceof JCTree)) {
- ErrorReporter.errorAbort("InternalUtils.symbol: tree is not a valid Javac tree");
- return null; // dead code
- }
-
- if (TreeUtils.isExpressionTree(tree)) {
- tree = TreeUtils.skipParens((ExpressionTree) tree);
- }
-
- switch (tree.getKind()) {
- case VARIABLE:
- case METHOD:
- case CLASS:
- case ENUM:
- case INTERFACE:
- case ANNOTATION_TYPE:
- case TYPE_PARAMETER:
- return TreeInfo.symbolFor((JCTree) tree);
-
- // symbol() only works on MethodSelects, so we need to get it manually
- // for method invocations.
- case METHOD_INVOCATION:
- return TreeInfo.symbol(((JCMethodInvocation) tree).getMethodSelect());
-
- case ASSIGNMENT:
- return TreeInfo.symbol((JCTree) ((AssignmentTree) tree).getVariable());
-
- case ARRAY_ACCESS:
- return symbol(((ArrayAccessTree) tree).getExpression());
-
- case NEW_CLASS:
- return ((JCNewClass) tree).constructor;
-
- case MEMBER_REFERENCE:
- // TreeInfo.symbol, which is used in the default case, didn't handle
- // member references until JDK8u20. So handle it here.
- return ((JCMemberReference) tree).sym;
-
- default:
- return TreeInfo.symbol((JCTree) tree);
- }
- }
-
- /**
- * Determines whether or not the node referred to by the given {@link TreePath} is an anonymous
- * constructor (the constructor for an anonymous class.
- *
- * @param method the {@link TreePath} for a node that may be an anonymous constructor
- * @return true if the given path points to an anonymous constructor, false if it does not
- */
- public static boolean isAnonymousConstructor(final MethodTree method) {
- /*@Nullable*/ Element e = InternalUtils.symbol(method);
- if (e == null || !(e instanceof Symbol)) {
- return false;
- }
-
- if ((((/*@NonNull*/ Symbol) e).flags() & Flags.ANONCONSTR) != 0) {
- return true;
- }
-
- return false;
- }
-
- /**
- * indicates whether it should return the constructor that gets invoked in cases of anonymous
- * classes
- */
- private static final boolean RETURN_INVOKE_CONSTRUCTOR = true;
-
- /**
- * Determines the symbol for a constructor given an invocation via {@code new}.
- *
- * <p>If the tree is a declaration of an anonymous class, then method returns constructor that
- * gets invoked in the extended class, rather than the anonymous constructor implicitly added by
- * the constructor (JLS 15.9.5.1)
- *
- * @param tree the constructor invocation
- * @return the {@link ExecutableElement} corresponding to the constructor call in {@code tree}
- */
- public static ExecutableElement constructor(NewClassTree tree) {
-
- if (!(tree instanceof JCTree.JCNewClass)) {
- ErrorReporter.errorAbort("InternalUtils.constructor: not a javac internal tree");
- return null; // dead code
- }
-
- JCNewClass newClassTree = (JCNewClass) tree;
-
- if (RETURN_INVOKE_CONSTRUCTOR && tree.getClassBody() != null) {
- // anonymous constructor bodies should contain exactly one statement
- // in the form:
- // super(arg1, ...)
- // or
- // o.super(arg1, ...)
- //
- // which is a method invocation (!) to the actual constructor
-
- // the method call is guaranteed to return nonnull
- JCMethodDecl anonConstructor =
- (JCMethodDecl) TreeInfo.declarationFor(newClassTree.constructor, newClassTree);
- assert anonConstructor != null;
- assert anonConstructor.body.stats.size() == 1;
- JCExpressionStatement stmt = (JCExpressionStatement) anonConstructor.body.stats.head;
- JCTree.JCMethodInvocation superInvok = (JCMethodInvocation) stmt.expr;
- return (ExecutableElement) TreeInfo.symbol(superInvok.meth);
- }
-
- Element e = newClassTree.constructor;
-
- assert e instanceof ExecutableElement;
-
- return (ExecutableElement) e;
- }
-
- public static final List<AnnotationMirror> annotationsFromTypeAnnotationTrees(
- List<? extends AnnotationTree> annos) {
- List<AnnotationMirror> annotations = new ArrayList<AnnotationMirror>(annos.size());
- for (AnnotationTree anno : annos) {
- annotations.add(annotationFromAnnotationTree(anno));
- }
- return annotations;
- }
-
- public static AnnotationMirror annotationFromAnnotationTree(AnnotationTree tree) {
- return ((JCAnnotation) tree).attribute;
- }
-
- public static final List<? extends AnnotationMirror> annotationsFromTree(
- AnnotatedTypeTree node) {
- return annotationsFromTypeAnnotationTrees(((JCAnnotatedType) node).annotations);
- }
-
- public static final List<? extends AnnotationMirror> annotationsFromTree(
- TypeParameterTree node) {
- return annotationsFromTypeAnnotationTrees(((JCTypeParameter) node).annotations);
- }
-
- public static final List<? extends AnnotationMirror> annotationsFromArrayCreation(
- NewArrayTree node, int level) {
-
- assert node instanceof JCNewArray;
- final JCNewArray newArray = ((JCNewArray) node);
-
- if (level == -1) {
- return annotationsFromTypeAnnotationTrees(newArray.annotations);
- }
-
- if (newArray.dimAnnotations.length() > 0
- && (level >= 0)
- && (level < newArray.dimAnnotations.size()))
- return annotationsFromTypeAnnotationTrees(newArray.dimAnnotations.get(level));
-
- return Collections.emptyList();
- }
-
- public static TypeMirror typeOf(Tree tree) {
- return ((JCTree) tree).type;
- }
-
- /** Returns whether a TypeVariable represents a captured type. */
- public static boolean isCaptured(TypeVariable typeVar) {
- return ((Type.TypeVar) TypeAnnotationUtils.unannotatedType(typeVar)).isCaptured();
- }
-
- /** If typeVar is a captured wildcard, returns that wildcard; otherwise returns null. */
- public static WildcardType getCapturedWildcard(TypeVariable typeVar) {
- if (isCaptured(typeVar)) {
- return ((CapturedType) TypeAnnotationUtils.unannotatedType(typeVar)).wildcard;
- }
- return null;
- }
-
- /** Returns whether a TypeMirror represents a class type. */
- public static boolean isClassType(TypeMirror type) {
- return (type instanceof Type.ClassType);
- }
-
- /**
- * Returns the least upper bound of two {@link TypeMirror}s, ignoring any annotations on the
- * types.
- *
- * <p>Wrapper around Types.lub to add special handling for null types, primitives, and
- * wildcards.
- *
- * @param processingEnv the {@link ProcessingEnvironment} to use
- * @param tm1 a {@link TypeMirror}
- * @param tm2 a {@link TypeMirror}
- * @return the least upper bound of {@code tm1} and {@code tm2}.
- */
- public static TypeMirror leastUpperBound(
- ProcessingEnvironment processingEnv, TypeMirror tm1, TypeMirror tm2) {
- Type t1 = TypeAnnotationUtils.unannotatedType(tm1);
- Type t2 = TypeAnnotationUtils.unannotatedType(tm2);
- JavacProcessingEnvironment javacEnv = (JavacProcessingEnvironment) processingEnv;
- Types types = Types.instance(javacEnv.getContext());
- if (types.isSameType(t1, t2)) {
- // Special case if the two types are equal.
- return t1;
- }
- // Handle the 'null' type manually (not done by types.lub).
- if (t1.getKind() == TypeKind.NULL) {
- return t2;
- }
- if (t2.getKind() == TypeKind.NULL) {
- return t1;
- }
- if (t1.getKind() == TypeKind.WILDCARD) {
- WildcardType wc1 = (WildcardType) t1;
- Type bound = (Type) wc1.getExtendsBound();
- if (bound == null) {
- // Implicit upper bound of java.lang.Object
- Elements elements = processingEnv.getElementUtils();
- return elements.getTypeElement("java.lang.Object").asType();
- }
- t1 = bound;
- }
- if (t2.getKind() == TypeKind.WILDCARD) {
- WildcardType wc2 = (WildcardType) t2;
- Type bound = (Type) wc2.getExtendsBound();
- if (bound == null) {
- // Implicit upper bound of java.lang.Object
- Elements elements = processingEnv.getElementUtils();
- return elements.getTypeElement("java.lang.Object").asType();
- }
- t2 = bound;
- }
- // Special case for primitives.
- if (TypesUtils.isPrimitive(t1) || TypesUtils.isPrimitive(t2)) {
- if (types.isAssignable(t1, t2)) {
- return t2;
- } else if (types.isAssignable(t2, t1)) {
- return t1;
- } else {
- Elements elements = processingEnv.getElementUtils();
- return elements.getTypeElement("java.lang.Object").asType();
- }
- }
- return types.lub(t1, t2);
- }
-
- /**
- * Returns the greatest lower bound of two {@link TypeMirror}s, ignoring any annotations on the
- * types.
- *
- * <p>Wrapper around Types.glb to add special handling for null types, primitives, and
- * wildcards.
- *
- * @param processingEnv the {@link ProcessingEnvironment} to use
- * @param tm1 a {@link TypeMirror}
- * @param tm2 a {@link TypeMirror}
- * @return the greatest lower bound of {@code tm1} and {@code tm2}.
- */
- public static TypeMirror greatestLowerBound(
- ProcessingEnvironment processingEnv, TypeMirror tm1, TypeMirror tm2) {
- Type t1 = TypeAnnotationUtils.unannotatedType(tm1);
- Type t2 = TypeAnnotationUtils.unannotatedType(tm2);
- JavacProcessingEnvironment javacEnv = (JavacProcessingEnvironment) processingEnv;
- Types types = Types.instance(javacEnv.getContext());
- if (types.isSameType(t1, t2)) {
- // Special case if the two types are equal.
- return t1;
- }
- // Handle the 'null' type manually.
- if (t1.getKind() == TypeKind.NULL) {
- return t1;
- }
- if (t2.getKind() == TypeKind.NULL) {
- return t2;
- }
- // Special case for primitives.
- if (TypesUtils.isPrimitive(t1) || TypesUtils.isPrimitive(t2)) {
- if (types.isAssignable(t1, t2)) {
- return t1;
- } else if (types.isAssignable(t2, t1)) {
- return t2;
- } else {
- // Javac types.glb returns TypeKind.Error when the GLB does
- // not exist, but we can't create one. Use TypeKind.NONE
- // instead.
- return processingEnv.getTypeUtils().getNoType(TypeKind.NONE);
- }
- }
- if (t1.getKind() == TypeKind.WILDCARD) {
- return t2;
- }
- if (t2.getKind() == TypeKind.WILDCARD) {
- return t1;
- }
-
- // If neither type is a primitive type, null type, or wildcard
- // and if the types are not the same, use javac types.glb
- return types.glb(t1, t2);
- }
-
- /**
- * Returns the return type of a method, where the "raw" return type of that method is given
- * (i.e., the return type might still contain unsubstituted type variables), given the receiver
- * of the method call.
- */
- public static TypeMirror substituteMethodReturnType(
- TypeMirror methodType, TypeMirror substitutedReceiverType) {
- if (methodType.getKind() != TypeKind.TYPEVAR) {
- return methodType;
- }
- // TODO: find a nicer way to substitute type variables
- String t = TypeAnnotationUtils.unannotatedType(methodType).toString();
- Type finalReceiverType = (Type) substitutedReceiverType;
- int i = 0;
- for (TypeSymbol typeParam : finalReceiverType.tsym.getTypeParameters()) {
- if (t.equals(typeParam.toString())) {
- return finalReceiverType.getTypeArguments().get(i);
- }
- i++;
- }
- assert false;
- return null;
- }
-
- /**
- * Helper function to extract the javac Context from the javac processing environment.
- *
- * @param env the processing environment
- * @return the javac Context
- */
- public static Context getJavacContext(ProcessingEnvironment env) {
- return ((JavacProcessingEnvironment) env).getContext();
- }
-
- /**
- * Returns the type element for {@code type} if {@code type} is a class, interface, annotation
- * type, or enum. Otherwise, returns null.
- *
- * @param type whose element is returned
- * @return the type element for {@code type} if {@code type} is a class, interface, annotation
- * type, or enum; otherwise, returns null
- */
- public static TypeElement getTypeElement(TypeMirror type) {
- Element element = ((Type) type).asElement();
- switch (element.getKind()) {
- case ANNOTATION_TYPE:
- case CLASS:
- case ENUM:
- case INTERFACE:
- return (TypeElement) element;
- default:
- return null;
- }
- }
-
- /**
- * Obtain the class loader for {@code clazz}. If that is not available, return the system class
- * loader.
- *
- * @param clazz the class whose class loader to find
- * @return the class loader used to {@code clazz}, or the system class loader, or null if both
- * are unavailable
- */
- public static ClassLoader getClassLoaderForClass(Class<? extends Object> clazz) {
- ClassLoader classLoader = clazz.getClassLoader();
- return classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader;
- }
-
- /**
- * Compares tree1 to tree2 by the position at which a diagnostic (e.g., an error message) for
- * the tree should be printed.
- */
- public static int compareDiagnosticPosition(Tree tree1, Tree tree2) {
- DiagnosticPosition pos1 = (DiagnosticPosition) tree1;
- DiagnosticPosition pos2 = (DiagnosticPosition) tree2;
-
- int preferred = Integer.compare(pos1.getPreferredPosition(), pos2.getPreferredPosition());
- if (preferred != 0) {
- return preferred;
- }
-
- return Integer.compare(pos1.getStartPosition(), pos2.getStartPosition());
- }
-
- /**
- * Returns whether or not {@code type} is a functional interface type (as defined in JLS 9.8).
- *
- * @param type possible functional interface type
- * @param env ProcessingEnvironment
- * @return whether or not {@code type} is a functional interface type (as defined in JLS 9.8)
- */
- public static boolean isFunctionalInterface(TypeMirror type, ProcessingEnvironment env) {
- Context ctx = ((JavacProcessingEnvironment) env).getContext();
- com.sun.tools.javac.code.Types javacTypes = com.sun.tools.javac.code.Types.instance(ctx);
- return javacTypes.isFunctionalInterface((Type) type);
- }
-
- /**
- * The type of the lambda or method reference tree is a functional interface type. This method
- * returns the single abstract method declared by that functional interface. (The type of this
- * method is referred to as the function type.)
- *
- * @param tree lambda or member reference tree
- * @param env ProcessingEnvironment
- * @return the single abstract method declared by the type of the tree
- */
- public static Symbol findFunction(Tree tree, ProcessingEnvironment env) {
- Context ctx = ((JavacProcessingEnvironment) env).getContext();
- com.sun.tools.javac.code.Types javacTypes = com.sun.tools.javac.code.Types.instance(ctx);
- return javacTypes.findDescriptorSymbol(((Type) typeOf(tree)).asElement());
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Pair.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Pair.java
deleted file mode 100644
index 161af82605..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Pair.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package org.checkerframework.javacutil;
-
-/*>>>
-import org.checkerframework.dataflow.qual.Pure;
-import org.checkerframework.dataflow.qual.SideEffectFree;
-*/
-
-/**
- * Simple pair class for multiple returns.
- *
- * <p>TODO: as class is immutable, use @Covariant annotation.
- */
-public class Pair<V1, V2> {
- public final V1 first;
- public final V2 second;
-
- private Pair(V1 v1, V2 v2) {
- this.first = v1;
- this.second = v2;
- }
-
- public static <V1, V2> Pair<V1, V2> of(V1 v1, V2 v2) {
- return new Pair<V1, V2>(v1, v2);
- }
-
- /*@SideEffectFree*/
- @Override
- public String toString() {
- return "Pair(" + first + ", " + second + ")";
- }
-
- private int hashCode = -1;
-
- /*@Pure*/
- @Override
- public int hashCode() {
- if (hashCode == -1) {
- hashCode = 31;
- if (first != null) {
- hashCode += 17 * first.hashCode();
- }
- if (second != null) {
- hashCode += 17 * second.hashCode();
- }
- }
- return hashCode;
- }
-
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof Pair)) {
- return false;
- }
- @SuppressWarnings("unchecked")
- Pair<V1, V2> other = (Pair<V1, V2>) o;
- if (this.first == null) {
- if (other.first != null) return false;
- } else {
- if (!this.first.equals(other.first)) return false;
- }
- if (this.second == null) {
- if (other.second != null) return false;
- } else {
- if (!this.second.equals(other.second)) return false;
- }
-
- return true;
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Resolver.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Resolver.java
deleted file mode 100644
index 361c6aef99..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/Resolver.java
+++ /dev/null
@@ -1,397 +0,0 @@
-package org.checkerframework.javacutil;
-
-import static com.sun.tools.javac.code.Kinds.PCK;
-import static com.sun.tools.javac.code.Kinds.TYP;
-import static com.sun.tools.javac.code.Kinds.VAR;
-
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.api.JavacScope;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symbol.ClassSymbol;
-import com.sun.tools.javac.code.Symbol.PackageSymbol;
-import com.sun.tools.javac.code.Symbol.TypeSymbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.comp.AttrContext;
-import com.sun.tools.javac.comp.DeferredAttr;
-import com.sun.tools.javac.comp.Env;
-import com.sun.tools.javac.comp.Resolve;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Log;
-import com.sun.tools.javac.util.Name;
-import com.sun.tools.javac.util.Names;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeMirror;
-
-/** A Utility class to find symbols corresponding to string references. */
-public class Resolver {
- private final Resolve resolve;
- private final Names names;
- private final Trees trees;
- private final Log log;
-
- private static final Method FIND_METHOD;
- private static final Method FIND_VAR;
- private static final Method FIND_IDENT;
- private static final Method FIND_IDENT_IN_TYPE;
- private static final Method FIND_IDENT_IN_PACKAGE;
- private static final Method FIND_TYPE;
-
- private static final Class<?> ACCESSERROR;
- // Note that currently access(...) is defined in InvalidSymbolError, a superclass of AccessError
- private static final Method ACCESSERROR_ACCESS;
-
- static {
- try {
- FIND_METHOD =
- Resolve.class.getDeclaredMethod(
- "findMethod",
- Env.class,
- Type.class,
- Name.class,
- List.class,
- List.class,
- boolean.class,
- boolean.class,
- boolean.class);
- FIND_METHOD.setAccessible(true);
-
- FIND_VAR = Resolve.class.getDeclaredMethod("findVar", Env.class, Name.class);
- FIND_VAR.setAccessible(true);
-
- FIND_IDENT =
- Resolve.class.getDeclaredMethod("findIdent", Env.class, Name.class, int.class);
- FIND_IDENT.setAccessible(true);
-
- FIND_IDENT_IN_TYPE =
- Resolve.class.getDeclaredMethod(
- "findIdentInType", Env.class, Type.class, Name.class, int.class);
- FIND_IDENT_IN_TYPE.setAccessible(true);
-
- FIND_IDENT_IN_PACKAGE =
- Resolve.class.getDeclaredMethod(
- "findIdentInPackage",
- Env.class,
- TypeSymbol.class,
- Name.class,
- int.class);
- FIND_IDENT_IN_PACKAGE.setAccessible(true);
-
- FIND_TYPE = Resolve.class.getDeclaredMethod("findType", Env.class, Name.class);
- FIND_TYPE.setAccessible(true);
- } catch (Exception e) {
- Error err =
- new AssertionError(
- "Compiler 'Resolve' class doesn't contain required 'find' method");
- err.initCause(e);
- throw err;
- }
-
- try {
- ACCESSERROR = Class.forName("com.sun.tools.javac.comp.Resolve$AccessError");
- ACCESSERROR_ACCESS = ACCESSERROR.getMethod("access", Name.class, TypeSymbol.class);
- ACCESSERROR_ACCESS.setAccessible(true);
- } catch (ClassNotFoundException e) {
- ErrorReporter.errorAbort(
- "Compiler 'Resolve$AccessError' class could not be retrieved.", e);
- // Unreachable code - needed so the compiler does not warn about a possibly uninitialized final field.
- throw new AssertionError();
- } catch (NoSuchMethodException e) {
- ErrorReporter.errorAbort(
- "Compiler 'Resolve$AccessError' class doesn't contain required 'access' method",
- e);
- // Unreachable code - needed so the compiler does not warn about a possibly uninitialized final field.
- throw new AssertionError();
- }
- }
-
- public Resolver(ProcessingEnvironment env) {
- Context context = ((JavacProcessingEnvironment) env).getContext();
- this.resolve = Resolve.instance(context);
- this.names = Names.instance(context);
- this.trees = Trees.instance(env);
- this.log = Log.instance(context);
- }
-
- /**
- * Determine the environment for the given path.
- *
- * @param path the tree path to the local scope
- * @return the corresponding attribution environment
- */
- public Env<AttrContext> getEnvForPath(TreePath path) {
- TreePath iter = path;
- JavacScope scope = null;
- while (scope == null && iter != null) {
- try {
- scope = (JavacScope) trees.getScope(iter);
- } catch (Throwable t) {
- // Work around Issue #1059 by skipping through the TreePath until something
- // doesn't crash. This probably returns the class scope, so users might not
- // get the variables they expect. But that is better than crashing.
- iter = iter.getParentPath();
- }
- }
- if (scope != null) {
- return scope.getEnv();
- } else {
- ErrorReporter.errorAbort(
- "Could not determine any possible scope for path: " + path.getLeaf());
- return null;
- }
- }
-
- /**
- * Finds the package with name {@code name}.
- *
- * @param name the name of the package
- * @param path the tree path to the local scope
- * @return the {@code PackageSymbol} for the package if it is found, {@code null} otherwise
- */
- public PackageSymbol findPackage(String name, TreePath path) {
- Log.DiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log);
- try {
- Env<AttrContext> env = getEnvForPath(path);
- Element res =
- wrapInvocationOnResolveInstance(FIND_IDENT, env, names.fromString(name), PCK);
- // findIdent will return a PackageSymbol even for a symbol that is not a package,
- // such as a.b.c.MyClass.myStaticField. "exists()" must be called on it to ensure
- // that it exists.
- if (res.getKind() == ElementKind.PACKAGE) {
- PackageSymbol ps = (PackageSymbol) res;
- return ps.exists() ? ps : null;
- } else {
- return null;
- }
- } finally {
- log.popDiagnosticHandler(discardDiagnosticHandler);
- }
- }
-
- /**
- * Finds the field with name {@code name} in a given type.
- *
- * <p>The method adheres to all the rules of Java's scoping (while also considering the imports)
- * for name resolution.
- *
- * @param name the name of the field
- * @param type the type of the receiver (i.e., the type in which to look for the field).
- * @param path the tree path to the local scope
- * @return the element for the field
- */
- public VariableElement findField(String name, TypeMirror type, TreePath path) {
- Log.DiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log);
- try {
- Env<AttrContext> env = getEnvForPath(path);
- Element res =
- wrapInvocationOnResolveInstance(
- FIND_IDENT_IN_TYPE, env, type, names.fromString(name), VAR);
- if (res.getKind() == ElementKind.FIELD) {
- return (VariableElement) res;
- } else if (res.getKind() == ElementKind.OTHER && ACCESSERROR.isInstance(res)) {
- // Return the inaccessible field that was found
- return (VariableElement) wrapInvocation(res, ACCESSERROR_ACCESS, null, null);
- } else {
- // Most likely didn't find the field and the Element is a SymbolNotFoundError
- return null;
- }
- } finally {
- log.popDiagnosticHandler(discardDiagnosticHandler);
- }
- }
-
- /**
- * Finds the local variable with name {@code name} in the given scope.
- *
- * @param name the name of the local variable
- * @param path the tree path to the local scope
- * @return the element for the local variable
- */
- public VariableElement findLocalVariableOrParameterOrField(String name, TreePath path) {
- Log.DiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log);
- try {
- Env<AttrContext> env = getEnvForPath(path);
- Element res = wrapInvocationOnResolveInstance(FIND_VAR, env, names.fromString(name));
- if (res.getKind() == ElementKind.LOCAL_VARIABLE
- || res.getKind() == ElementKind.PARAMETER
- || res.getKind() == ElementKind.FIELD) {
- return (VariableElement) res;
- } else {
- // Most likely didn't find the variable and the Element is a SymbolNotFoundError
- return null;
- }
- } finally {
- log.popDiagnosticHandler(discardDiagnosticHandler);
- }
- }
-
- /**
- * Finds the class literal with name {@code name}.
- *
- * <p>The method adheres to all the rules of Java's scoping (while also considering the imports)
- * for name resolution.
- *
- * @param name the name of the class
- * @param path the tree path to the local scope
- * @return the element for the class
- */
- public Element findClass(String name, TreePath path) {
- Log.DiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log);
- try {
- Env<AttrContext> env = getEnvForPath(path);
- return wrapInvocationOnResolveInstance(FIND_TYPE, env, names.fromString(name));
- } finally {
- log.popDiagnosticHandler(discardDiagnosticHandler);
- }
- }
-
- /**
- * Finds the class with name {@code name} in a given package.
- *
- * @param name the name of the class
- * @param pck the PackageSymbol for the package
- * @param path the tree path to the local scope
- * @return the {@code ClassSymbol} for the class if it is found, {@code null} otherwise
- */
- public ClassSymbol findClassInPackage(String name, PackageSymbol pck, TreePath path) {
- Log.DiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log);
- try {
- Env<AttrContext> env = getEnvForPath(path);
- Element res =
- wrapInvocationOnResolveInstance(
- FIND_IDENT_IN_PACKAGE, env, pck, names.fromString(name), TYP);
- if (res.getKind() == ElementKind.CLASS) {
- return (ClassSymbol) res;
- } else {
- return null;
- }
- } finally {
- log.popDiagnosticHandler(discardDiagnosticHandler);
- }
- }
-
- /**
- * Finds the method element for a given name and list of expected parameter types.
- *
- * <p>The method adheres to all the rules of Java's scoping (while also considering the imports)
- * for name resolution.
- *
- * @param methodName name of the method to find
- * @param receiverType type of the receiver of the method
- * @param path tree path
- * @return the method element (if found)
- */
- public Element findMethod(
- String methodName,
- TypeMirror receiverType,
- TreePath path,
- java.util.List<TypeMirror> argumentTypes) {
- Log.DiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log);
- try {
- Env<AttrContext> env = getEnvForPath(path);
-
- Type site = (Type) receiverType;
- Name name = names.fromString(methodName);
- List<Type> argtypes = List.nil();
- for (TypeMirror a : argumentTypes) {
- argtypes = argtypes.append((Type) a);
- }
- List<Type> typeargtypes = List.nil();
- boolean allowBoxing = true;
- boolean useVarargs = false;
- boolean operator = true;
-
- try {
- // For some reason we have to set our own method context, which is rather ugly.
- // TODO: find a nicer way to do this.
- Object methodContext = buildMethodContext();
- Object oldContext = getField(resolve, "currentResolutionContext");
- setField(resolve, "currentResolutionContext", methodContext);
- Element result =
- wrapInvocationOnResolveInstance(
- FIND_METHOD,
- env,
- site,
- name,
- argtypes,
- typeargtypes,
- allowBoxing,
- useVarargs,
- operator);
- setField(resolve, "currentResolutionContext", oldContext);
- return result;
- } catch (Throwable t) {
- Error err = new AssertionError("Unexpected Reflection error");
- err.initCause(t);
- throw err;
- }
- } finally {
- log.popDiagnosticHandler(discardDiagnosticHandler);
- }
- }
-
- /** Build an instance of {@code Resolve$MethodResolutionContext}. */
- protected Object buildMethodContext()
- throws ClassNotFoundException, InstantiationException, IllegalAccessException,
- InvocationTargetException, NoSuchFieldException {
- // Class is not accessible, instantiate reflectively.
- Class<?> methCtxClss =
- Class.forName("com.sun.tools.javac.comp.Resolve$MethodResolutionContext");
- Constructor<?> constructor = methCtxClss.getDeclaredConstructors()[0];
- constructor.setAccessible(true);
- Object methodContext = constructor.newInstance(resolve);
- // we need to also initialize the fields attrMode and step
- setField(methodContext, "attrMode", DeferredAttr.AttrMode.CHECK);
- @SuppressWarnings("rawtypes")
- List<?> phases = (List) getField(resolve, "methodResolutionSteps");
- setField(methodContext, "step", phases.get(1));
- return methodContext;
- }
-
- /** Reflectively set a field. */
- private void setField(Object receiver, String fieldName, Object value)
- throws NoSuchFieldException, IllegalAccessException {
- Field f = receiver.getClass().getDeclaredField(fieldName);
- f.setAccessible(true);
- f.set(receiver, value);
- }
-
- /** Reflectively get the value of a field. */
- private Object getField(Object receiver, String fieldName)
- throws NoSuchFieldException, IllegalAccessException {
- Field f = receiver.getClass().getDeclaredField(fieldName);
- f.setAccessible(true);
- return f.get(receiver);
- }
-
- private Symbol wrapInvocationOnResolveInstance(Method method, Object... args) {
- return wrapInvocation(resolve, method, args);
- }
-
- private Symbol wrapInvocation(Object receiver, Method method, Object... args) {
- try {
- return (Symbol) method.invoke(receiver, args);
- } catch (IllegalAccessException e) {
- Error err = new AssertionError("Unexpected Reflection error");
- err.initCause(e);
- throw err;
- } catch (IllegalArgumentException e) {
- Error err = new AssertionError("Unexpected Reflection error");
- err.initCause(e);
- throw err;
- } catch (InvocationTargetException e) {
- Error err = new AssertionError("Unexpected Reflection error");
- err.initCause(e);
- throw err;
- }
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TreeUtils.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TreeUtils.java
deleted file mode 100644
index 4da97b400d..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TreeUtils.java
+++ /dev/null
@@ -1,1020 +0,0 @@
-package org.checkerframework.javacutil;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.*;
-*/
-
-import com.sun.source.tree.AnnotatedTypeTree;
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.BinaryTree;
-import com.sun.source.tree.BlockTree;
-import com.sun.source.tree.ClassTree;
-import com.sun.source.tree.CompoundAssignmentTree;
-import com.sun.source.tree.ConditionalExpressionTree;
-import com.sun.source.tree.ExpressionStatementTree;
-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.NewClassTree;
-import com.sun.source.tree.ParameterizedTypeTree;
-import com.sun.source.tree.ParenthesizedTree;
-import com.sun.source.tree.PrimitiveTypeTree;
-import com.sun.source.tree.StatementTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.Tree.Kind;
-import com.sun.source.tree.TypeCastTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.source.util.TreePath;
-import com.sun.source.util.Trees;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Symbol.MethodSymbol;
-import com.sun.tools.javac.tree.JCTree;
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Set;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.Modifier;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.util.ElementFilter;
-
-/** A utility class made for helping to analyze a given {@code Tree}. */
-// TODO: This class needs significant restructuring
-public final class TreeUtils {
-
- // Class cannot be instantiated.
- private TreeUtils() {
- throw new AssertionError("Class TreeUtils cannot be instantiated.");
- }
-
- /**
- * Checks if the provided method is a constructor method or no.
- *
- * @param tree a tree defining the method
- * @return true iff tree describes a constructor
- */
- public static boolean isConstructor(final MethodTree tree) {
- return tree.getName().contentEquals("<init>");
- }
-
- /**
- * Checks if the method invocation is a call to super.
- *
- * @param tree a tree defining a method invocation
- * @return true iff tree describes a call to super
- */
- public static boolean isSuperCall(MethodInvocationTree tree) {
- return isNamedMethodCall("super", tree);
- }
-
- /**
- * Checks if the method invocation is a call to this.
- *
- * @param tree a tree defining a method invocation
- * @return true iff tree describes a call to this
- */
- public static boolean isThisCall(MethodInvocationTree tree) {
- return isNamedMethodCall("this", tree);
- }
-
- protected static boolean isNamedMethodCall(String name, MethodInvocationTree tree) {
- /*@Nullable*/ ExpressionTree mst = tree.getMethodSelect();
- assert mst != null; /*nninvariant*/
-
- if (mst.getKind() == Tree.Kind.IDENTIFIER) {
- return ((IdentifierTree) mst).getName().contentEquals(name);
- }
-
- if (mst.getKind() == Tree.Kind.MEMBER_SELECT) {
- MemberSelectTree selectTree = (MemberSelectTree) mst;
-
- if (selectTree.getExpression().getKind() != Tree.Kind.IDENTIFIER) {
- return false;
- }
-
- return ((IdentifierTree) selectTree.getExpression()).getName().contentEquals(name);
- }
-
- return false;
- }
-
- /**
- * Returns true if the tree is a tree that 'looks like' either an access of a field or an
- * invocation of a method that are owned by the same accessing instance.
- *
- * <p>It would only return true if the access tree is of the form:
- *
- * <pre>
- * field
- * this.field
- *
- * method()
- * this.method()
- * </pre>
- *
- * It does not perform any semantical check to differentiate between fields and local variables;
- * local methods or imported static methods.
- *
- * @param tree expression tree representing an access to object member
- * @return {@code true} iff the member is a member of {@code this} instance
- */
- public static boolean isSelfAccess(final ExpressionTree tree) {
- ExpressionTree tr = TreeUtils.skipParens(tree);
- // If method invocation check the method select
- if (tr.getKind() == Tree.Kind.ARRAY_ACCESS) {
- return false;
- }
-
- if (tree.getKind() == Tree.Kind.METHOD_INVOCATION) {
- tr = ((MethodInvocationTree) tree).getMethodSelect();
- }
- tr = TreeUtils.skipParens(tr);
- if (tr.getKind() == Tree.Kind.TYPE_CAST) {
- tr = ((TypeCastTree) tr).getExpression();
- }
- tr = TreeUtils.skipParens(tr);
-
- if (tr.getKind() == Tree.Kind.IDENTIFIER) {
- return true;
- }
-
- if (tr.getKind() == Tree.Kind.MEMBER_SELECT) {
- tr = ((MemberSelectTree) tr).getExpression();
- if (tr.getKind() == Tree.Kind.IDENTIFIER) {
- Name ident = ((IdentifierTree) tr).getName();
- return ident.contentEquals("this") || ident.contentEquals("super");
- }
- }
-
- return false;
- }
-
- /**
- * Gets the first enclosing tree in path, of the specified kind.
- *
- * @param path the path defining the tree node
- * @param kind the kind of the desired tree
- * @return the enclosing tree of the given type as given by the path
- */
- public static Tree enclosingOfKind(final TreePath path, final Tree.Kind kind) {
- return enclosingOfKind(path, EnumSet.of(kind));
- }
-
- /**
- * Gets the first enclosing tree in path, with any one of the specified kinds.
- *
- * @param path the path defining the tree node
- * @param kinds the set of kinds of the desired tree
- * @return the enclosing tree of the given type as given by the path
- */
- public static Tree enclosingOfKind(final TreePath path, final Set<Tree.Kind> kinds) {
- TreePath p = path;
-
- while (p != null) {
- Tree leaf = p.getLeaf();
- assert leaf != null; /*nninvariant*/
- if (kinds.contains(leaf.getKind())) {
- return leaf;
- }
- p = p.getParentPath();
- }
-
- return null;
- }
-
- /**
- * Gets path to the first enclosing class tree, where class is defined by the classTreeKinds
- * method.
- *
- * @param path the path defining the tree node
- * @return the path to the enclosing class tree
- */
- public static TreePath pathTillClass(final TreePath path) {
- return pathTillOfKind(path, classTreeKinds());
- }
-
- /**
- * Gets path to the first enclosing tree of the specified kind.
- *
- * @param path the path defining the tree node
- * @param kind the kind of the desired tree
- * @return the path to the enclosing tree of the given type
- */
- public static TreePath pathTillOfKind(final TreePath path, final Tree.Kind kind) {
- return pathTillOfKind(path, EnumSet.of(kind));
- }
-
- /**
- * Gets path to the first enclosing tree with any one of the specified kinds.
- *
- * @param path the path defining the tree node
- * @param kinds the set of kinds of the desired tree
- * @return the path to the enclosing tree of the given type
- */
- public static TreePath pathTillOfKind(final TreePath path, final Set<Tree.Kind> kinds) {
- TreePath p = path;
-
- while (p != null) {
- Tree leaf = p.getLeaf();
- assert leaf != null; /*nninvariant*/
- if (kinds.contains(leaf.getKind())) {
- return p;
- }
- p = p.getParentPath();
- }
-
- return null;
- }
-
- /**
- * Gets the first enclosing tree in path, of the specified class
- *
- * @param path the path defining the tree node
- * @param treeClass the class of the desired tree
- * @return the enclosing tree of the given type as given by the path
- */
- public static <T extends Tree> T enclosingOfClass(
- final TreePath path, final Class<T> treeClass) {
- TreePath p = path;
-
- while (p != null) {
- Tree leaf = p.getLeaf();
- if (treeClass.isInstance(leaf)) {
- return treeClass.cast(leaf);
- }
- p = p.getParentPath();
- }
-
- return null;
- }
-
- /**
- * Gets the enclosing class of the tree node defined by the given {@link TreePath}. It returns a
- * {@link Tree}, from which {@code checkers.types.AnnotatedTypeMirror} or {@link Element} can be
- * obtained.
- *
- * @param path the path defining the tree node
- * @return the enclosing class (or interface) as given by the path, or null if one does not
- * exist
- */
- public static /*@Nullable*/ ClassTree enclosingClass(final /*@Nullable*/ TreePath path) {
- return (ClassTree) enclosingOfKind(path, classTreeKinds());
- }
-
- /**
- * Gets the enclosing variable of a tree node defined by the given {@link TreePath}.
- *
- * @param path the path defining the tree node
- * @return the enclosing variable as given by the path, or null if one does not exist
- */
- public static VariableTree enclosingVariable(final TreePath path) {
- return (VariableTree) enclosingOfKind(path, Tree.Kind.VARIABLE);
- }
-
- /**
- * Gets the enclosing method of the tree node defined by the given {@link TreePath}. It returns
- * a {@link Tree}, from which an {@code checkers.types.AnnotatedTypeMirror} or {@link Element}
- * can be obtained.
- *
- * @param path the path defining the tree node
- * @return the enclosing method as given by the path, or null if one does not exist
- */
- public static /*@Nullable*/ MethodTree enclosingMethod(final /*@Nullable*/ TreePath path) {
- return (MethodTree) enclosingOfKind(path, Tree.Kind.METHOD);
- }
-
- public static /*@Nullable*/ BlockTree enclosingTopLevelBlock(TreePath path) {
- TreePath parpath = path.getParentPath();
- while (parpath != null && !classTreeKinds.contains(parpath.getLeaf().getKind())) {
- path = parpath;
- parpath = parpath.getParentPath();
- }
- if (path.getLeaf().getKind() == Tree.Kind.BLOCK) {
- return (BlockTree) path.getLeaf();
- }
- return null;
- }
-
- /**
- * If the given tree is a parenthesized tree, it returns the enclosed non-parenthesized tree.
- * Otherwise, it returns the same tree.
- *
- * @param tree an expression tree
- * @return the outermost non-parenthesized tree enclosed by the given tree
- */
- public static ExpressionTree skipParens(final ExpressionTree tree) {
- ExpressionTree t = tree;
- while (t.getKind() == Tree.Kind.PARENTHESIZED) {
- t = ((ParenthesizedTree) t).getExpression();
- }
- return t;
- }
-
- /**
- * Returns the tree with the assignment context for the treePath leaf node. (Does not handle
- * pseudo-assignment of an argument to a parameter or a receiver expression to a receiver.)
- *
- * <p>The assignment context for the {@code treePath} is the leaf of its parent, if the parent
- * is one of the following trees:
- *
- * <ul>
- * <li>AssignmentTree
- * <li>CompoundAssignmentTree
- * <li>MethodInvocationTree
- * <li>NewArrayTree
- * <li>NewClassTree
- * <li>ReturnTree
- * <li>VariableTree
- * </ul>
- *
- * If the parent is a ConditionalExpressionTree we need to distinguish two cases: If the leaf is
- * either the then or else branch of the ConditionalExpressionTree, then recurse on the parent.
- * If the leaf is the condition of the ConditionalExpressionTree, then return null to not
- * consider this assignment context.
- *
- * <p>If the leaf is a ParenthesizedTree, then recurse on the parent.
- *
- * <p>Otherwise, null is returned.
- *
- * @return the assignment context as described
- */
- public static Tree getAssignmentContext(final TreePath treePath) {
- TreePath parentPath = treePath.getParentPath();
-
- if (parentPath == null) {
- return null;
- }
-
- Tree parent = parentPath.getLeaf();
- switch (parent.getKind()) {
- case PARENTHESIZED:
- return getAssignmentContext(parentPath);
- case CONDITIONAL_EXPRESSION:
- ConditionalExpressionTree cet = (ConditionalExpressionTree) parent;
- if (cet.getCondition() == treePath.getLeaf()) {
- // The assignment context for the condition is simply boolean.
- // No point in going on.
- return null;
- }
- // Otherwise use the context of the ConditionalExpressionTree.
- return getAssignmentContext(parentPath);
- case ASSIGNMENT:
- case METHOD_INVOCATION:
- case NEW_ARRAY:
- case NEW_CLASS:
- case RETURN:
- case VARIABLE:
- return parent;
- default:
- // 11 Tree.Kinds are CompoundAssignmentTrees,
- // so use instanceof rather than listing all 11.
- if (parent instanceof CompoundAssignmentTree) {
- return parent;
- }
- return null;
- }
- }
-
- /**
- * Gets the element for a class corresponding to a declaration.
- *
- * @return the element for the given class
- */
- public static final TypeElement elementFromDeclaration(ClassTree node) {
- TypeElement elt = (TypeElement) InternalUtils.symbol(node);
- return elt;
- }
-
- /**
- * Gets the element for a method corresponding to a declaration.
- *
- * @return the element for the given method
- */
- public static final ExecutableElement elementFromDeclaration(MethodTree node) {
- ExecutableElement elt = (ExecutableElement) InternalUtils.symbol(node);
- return elt;
- }
-
- /**
- * Gets the element for a variable corresponding to its declaration.
- *
- * @return the element for the given variable
- */
- public static final VariableElement elementFromDeclaration(VariableTree node) {
- VariableElement elt = (VariableElement) InternalUtils.symbol(node);
- return elt;
- }
-
- /**
- * Gets the element for the declaration corresponding to this use of an element. To get the
- * element for a declaration, use {@link Trees#getElement(TreePath)} instead.
- *
- * <p>TODO: remove this method, as it really doesn't do anything.
- *
- * @param node the tree corresponding to a use of an element
- * @return the element for the corresponding declaration
- */
- public static final Element elementFromUse(ExpressionTree node) {
- return InternalUtils.symbol(node);
- }
-
- // Specialization for return type.
- // Might return null if element wasn't found.
- public static final ExecutableElement elementFromUse(MethodInvocationTree node) {
- Element el = elementFromUse((ExpressionTree) node);
- if (el instanceof ExecutableElement) {
- return (ExecutableElement) el;
- } else {
- return null;
- }
- }
-
- // Specialization for return type.
- public static final ExecutableElement elementFromUse(NewClassTree node) {
- return (ExecutableElement) elementFromUse((ExpressionTree) node);
- }
-
- /**
- * Determine whether the given ExpressionTree has an underlying element.
- *
- * @param node the ExpressionTree to test
- * @return whether the tree refers to an identifier, member select, or method invocation
- */
- public static final boolean isUseOfElement(ExpressionTree node) {
- node = TreeUtils.skipParens(node);
- switch (node.getKind()) {
- case IDENTIFIER:
- case MEMBER_SELECT:
- case METHOD_INVOCATION:
- case NEW_CLASS:
- return true;
- default:
- return false;
- }
- }
-
- /** @return the name of the invoked method */
- public static final Name methodName(MethodInvocationTree node) {
- ExpressionTree expr = node.getMethodSelect();
- if (expr.getKind() == Tree.Kind.IDENTIFIER) {
- return ((IdentifierTree) expr).getName();
- } else if (expr.getKind() == Tree.Kind.MEMBER_SELECT) {
- return ((MemberSelectTree) expr).getIdentifier();
- }
- ErrorReporter.errorAbort("TreeUtils.methodName: cannot be here: " + node);
- return null; // dead code
- }
-
- /**
- * @return true if the first statement in the body is a self constructor invocation within a
- * constructor
- */
- public static final boolean containsThisConstructorInvocation(MethodTree node) {
- if (!TreeUtils.isConstructor(node) || node.getBody().getStatements().isEmpty())
- return false;
-
- StatementTree st = node.getBody().getStatements().get(0);
- if (!(st instanceof ExpressionStatementTree)
- || !(((ExpressionStatementTree) st).getExpression()
- instanceof MethodInvocationTree)) {
- return false;
- }
-
- MethodInvocationTree invocation =
- (MethodInvocationTree) ((ExpressionStatementTree) st).getExpression();
-
- return "this".contentEquals(TreeUtils.methodName(invocation));
- }
-
- public static final Tree firstStatement(Tree tree) {
- Tree first;
- if (tree.getKind() == Tree.Kind.BLOCK) {
- BlockTree block = (BlockTree) tree;
- if (block.getStatements().isEmpty()) {
- first = block;
- } else {
- first = block.getStatements().iterator().next();
- }
- } else {
- first = tree;
- }
- return first;
- }
-
- /**
- * Determine whether the given class contains an explicit constructor.
- *
- * @param node a class tree
- * @return true, iff there is an explicit constructor
- */
- public static boolean hasExplicitConstructor(ClassTree node) {
- TypeElement elem = TreeUtils.elementFromDeclaration(node);
-
- for (ExecutableElement ee : ElementFilter.constructorsIn(elem.getEnclosedElements())) {
- MethodSymbol ms = (MethodSymbol) ee;
- long mod = ms.flags();
-
- if ((mod & Flags.SYNTHETIC) == 0) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns true if the tree is of a diamond type. In contrast to the implementation in TreeInfo,
- * this version works on Trees.
- *
- * @see com.sun.tools.javac.tree.TreeInfo#isDiamond(JCTree)
- */
- public static final boolean isDiamondTree(Tree tree) {
- switch (tree.getKind()) {
- case ANNOTATED_TYPE:
- return isDiamondTree(((AnnotatedTypeTree) tree).getUnderlyingType());
- case PARAMETERIZED_TYPE:
- return ((ParameterizedTypeTree) tree).getTypeArguments().isEmpty();
- case NEW_CLASS:
- return isDiamondTree(((NewClassTree) tree).getIdentifier());
- default:
- return false;
- }
- }
-
- /** Returns true if the tree represents a {@code String} concatenation operation */
- public static final boolean isStringConcatenation(Tree tree) {
- return (tree.getKind() == Tree.Kind.PLUS
- && TypesUtils.isString(InternalUtils.typeOf(tree)));
- }
-
- /** Returns true if the compound assignment tree is a string concatenation */
- public static final boolean isStringCompoundConcatenation(CompoundAssignmentTree tree) {
- return (tree.getKind() == Tree.Kind.PLUS_ASSIGNMENT
- && TypesUtils.isString(InternalUtils.typeOf(tree)));
- }
-
- /**
- * Returns true if the node is a constant-time expression.
- *
- * <p>A tree is a constant-time expression if it is:
- *
- * <ol>
- * <li>a literal tree
- * <li>a reference to a final variable initialized with a compile time constant
- * <li>a String concatenation of two compile time constants
- * </ol>
- */
- public static boolean isCompileTimeString(ExpressionTree node) {
- ExpressionTree tree = TreeUtils.skipParens(node);
- if (tree instanceof LiteralTree) {
- return true;
- }
-
- if (TreeUtils.isUseOfElement(tree)) {
- Element elt = TreeUtils.elementFromUse(tree);
- return ElementUtils.isCompileTimeConstant(elt);
- } else if (TreeUtils.isStringConcatenation(tree)) {
- BinaryTree binOp = (BinaryTree) tree;
- return isCompileTimeString(binOp.getLeftOperand())
- && isCompileTimeString(binOp.getRightOperand());
- } else {
- return false;
- }
- }
-
- /** Returns the receiver tree of a field access or a method invocation */
- public static ExpressionTree getReceiverTree(ExpressionTree expression) {
- ExpressionTree receiver = TreeUtils.skipParens(expression);
-
- if (!(receiver.getKind() == Tree.Kind.METHOD_INVOCATION
- || receiver.getKind() == Tree.Kind.MEMBER_SELECT
- || receiver.getKind() == Tree.Kind.IDENTIFIER
- || receiver.getKind() == Tree.Kind.ARRAY_ACCESS)) {
- // No receiver tree for anything but these four kinds.
- return null;
- }
-
- if (receiver.getKind() == Tree.Kind.METHOD_INVOCATION) {
- // Trying to handle receiver calls to trees of the form
- // ((m).getArray())
- // returns the type of 'm' in this case
- receiver = ((MethodInvocationTree) receiver).getMethodSelect();
-
- if (receiver.getKind() == Tree.Kind.IDENTIFIER) {
- // It's a method call "m(foo)" without an explicit receiver
- return null;
- } else if (receiver.getKind() == Tree.Kind.MEMBER_SELECT) {
- receiver = ((MemberSelectTree) receiver).getExpression();
- } else {
- // Otherwise, e.g. a NEW_CLASS: nothing to do.
- }
- } else if (receiver.getKind() == Tree.Kind.IDENTIFIER) {
- // It's a field access on implicit this or a local variable/parameter.
- return null;
- } else if (receiver.getKind() == Tree.Kind.ARRAY_ACCESS) {
- return TreeUtils.skipParens(((ArrayAccessTree) receiver).getExpression());
- } else if (receiver.getKind() == Tree.Kind.MEMBER_SELECT) {
- receiver = ((MemberSelectTree) receiver).getExpression();
- // Avoid int.class
- if (receiver instanceof PrimitiveTypeTree) {
- return null;
- }
- }
-
- // Receiver is now really just the receiver tree.
- return TreeUtils.skipParens(receiver);
- }
-
- // TODO: What about anonymous classes?
- // Adding Tree.Kind.NEW_CLASS here doesn't work, because then a
- // tree gets cast to ClassTree when it is actually a NewClassTree,
- // for example in enclosingClass above.
- private static final Set<Tree.Kind> classTreeKinds =
- EnumSet.of(
- Tree.Kind.CLASS,
- Tree.Kind.ENUM,
- Tree.Kind.INTERFACE,
- Tree.Kind.ANNOTATION_TYPE);
-
- public static Set<Tree.Kind> classTreeKinds() {
- return classTreeKinds;
- }
-
- /**
- * Is the given tree kind a class, i.e. a class, enum, interface, or annotation type.
- *
- * @param tree the tree to test
- * @return true, iff the given kind is a class kind
- */
- public static boolean isClassTree(Tree tree) {
- return classTreeKinds().contains(tree.getKind());
- }
-
- private static final Set<Tree.Kind> typeTreeKinds =
- EnumSet.of(
- Tree.Kind.PRIMITIVE_TYPE,
- Tree.Kind.PARAMETERIZED_TYPE,
- Tree.Kind.TYPE_PARAMETER,
- Tree.Kind.ARRAY_TYPE,
- Tree.Kind.UNBOUNDED_WILDCARD,
- Tree.Kind.EXTENDS_WILDCARD,
- Tree.Kind.SUPER_WILDCARD,
- Tree.Kind.ANNOTATED_TYPE);
-
- public static Set<Tree.Kind> typeTreeKinds() {
- return typeTreeKinds;
- }
-
- /**
- * Is the given tree a type instantiation?
- *
- * <p>TODO: this is an under-approximation: e.g. an identifier could be either a type use or an
- * expression. How can we distinguish.
- *
- * @param tree the tree to test
- * @return true, iff the given tree is a type
- */
- public static boolean isTypeTree(Tree tree) {
- return typeTreeKinds().contains(tree.getKind());
- }
-
- /**
- * Returns true if the given element is an invocation of the method, or of any method that
- * overrides that one.
- */
- public static boolean isMethodInvocation(
- Tree tree, ExecutableElement method, ProcessingEnvironment env) {
- if (!(tree instanceof MethodInvocationTree)) {
- return false;
- }
- MethodInvocationTree methInvok = (MethodInvocationTree) tree;
- ExecutableElement invoked = TreeUtils.elementFromUse(methInvok);
- return ElementUtils.isMethod(invoked, method, env);
- }
-
- /**
- * Returns the ExecutableElement for a method declaration of methodName, in class typeName, with
- * params parameters.
- *
- * <p>TODO: to precisely resolve method overloading, we should use parameter types and not just
- * the number of parameters!
- */
- public static ExecutableElement getMethod(
- String typeName, String methodName, int params, ProcessingEnvironment env) {
- TypeElement typeElt = env.getElementUtils().getTypeElement(typeName);
- for (ExecutableElement exec : ElementFilter.methodsIn(typeElt.getEnclosedElements())) {
- if (exec.getSimpleName().contentEquals(methodName)
- && exec.getParameters().size() == params) {
- return exec;
- }
- }
- ErrorReporter.errorAbort("TreeUtils.getMethod: shouldn't be here!");
- return null; // dead code
- }
-
- public static List<ExecutableElement> getMethodList(
- String typeName, String methodName, int params, ProcessingEnvironment env) {
- List<ExecutableElement> methods = new ArrayList<>();
- TypeElement typeElement = env.getElementUtils().getTypeElement(typeName);
- for (ExecutableElement exec : ElementFilter.methodsIn(typeElement.getEnclosedElements())) {
- if (exec.getSimpleName().contentEquals(methodName)
- && exec.getParameters().size() == params) {
- methods.add(exec);
- }
- }
- return methods;
- }
-
- /**
- * Determine whether the given expression is either "this" or an outer "C.this".
- *
- * <p>TODO: Should this also handle "super"?
- */
- public static final boolean isExplicitThisDereference(ExpressionTree tree) {
- if (tree.getKind() == Tree.Kind.IDENTIFIER
- && ((IdentifierTree) tree).getName().contentEquals("this")) {
- // Explicit this reference "this"
- return true;
- }
-
- if (tree.getKind() != Tree.Kind.MEMBER_SELECT) {
- return false;
- }
-
- MemberSelectTree memSelTree = (MemberSelectTree) tree;
- if (memSelTree.getIdentifier().contentEquals("this")) {
- // Outer this reference "C.this"
- return true;
- }
- return false;
- }
-
- /**
- * Determine whether {@code tree} is a class literal, such as
- *
- * <pre>
- * <em>Object</em> . <em>class</em>
- * </pre>
- *
- * @return true iff if tree is a class literal
- */
- public static boolean isClassLiteral(Tree tree) {
- if (tree.getKind() != Tree.Kind.MEMBER_SELECT) {
- return false;
- }
- return "class".equals(((MemberSelectTree) tree).getIdentifier().toString());
- }
-
- /**
- * Determine whether {@code tree} is a field access expressions, such as
- *
- * <pre>
- * <em>f</em>
- * <em>obj</em> . <em>f</em>
- * </pre>
- *
- * @return true iff if tree is a field access expression (implicit or explicit)
- */
- public static boolean isFieldAccess(Tree tree) {
- if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
- // explicit field access
- MemberSelectTree memberSelect = (MemberSelectTree) tree;
- Element el = TreeUtils.elementFromUse(memberSelect);
- return el.getKind().isField();
- } else if (tree.getKind().equals(Tree.Kind.IDENTIFIER)) {
- // implicit field access
- IdentifierTree ident = (IdentifierTree) tree;
- Element el = TreeUtils.elementFromUse(ident);
- return el.getKind().isField()
- && !ident.getName().contentEquals("this")
- && !ident.getName().contentEquals("super");
- }
- return false;
- }
-
- /**
- * Compute the name of the field that the field access {@code tree} accesses. Requires {@code
- * tree} to be a field access, as determined by {@code isFieldAccess}.
- *
- * @return the name of the field accessed by {@code tree}.
- */
- public static String getFieldName(Tree tree) {
- assert isFieldAccess(tree);
- if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
- MemberSelectTree mtree = (MemberSelectTree) tree;
- return mtree.getIdentifier().toString();
- } else {
- IdentifierTree itree = (IdentifierTree) tree;
- return itree.getName().toString();
- }
- }
-
- /**
- * Determine whether {@code tree} refers to a method element, such as
- *
- * <pre>
- * <em>m</em>(...)
- * <em>obj</em> . <em>m</em>(...)
- * </pre>
- *
- * @return true iff if tree is a method access expression (implicit or explicit)
- */
- public static boolean isMethodAccess(Tree tree) {
- if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
- // explicit method access
- MemberSelectTree memberSelect = (MemberSelectTree) tree;
- Element el = TreeUtils.elementFromUse(memberSelect);
- return el.getKind() == ElementKind.METHOD || el.getKind() == ElementKind.CONSTRUCTOR;
- } else if (tree.getKind().equals(Tree.Kind.IDENTIFIER)) {
- // implicit method access
- IdentifierTree ident = (IdentifierTree) tree;
- // The field "super" and "this" are also legal methods
- if (ident.getName().contentEquals("super") || ident.getName().contentEquals("this")) {
- return true;
- }
- Element el = TreeUtils.elementFromUse(ident);
- return el.getKind() == ElementKind.METHOD || el.getKind() == ElementKind.CONSTRUCTOR;
- }
- return false;
- }
-
- /**
- * Compute the name of the method that the method access {@code tree} accesses. Requires {@code
- * tree} to be a method access, as determined by {@code isMethodAccess}.
- *
- * @return the name of the method accessed by {@code tree}.
- */
- public static String getMethodName(Tree tree) {
- assert isMethodAccess(tree);
- if (tree.getKind().equals(Tree.Kind.MEMBER_SELECT)) {
- MemberSelectTree mtree = (MemberSelectTree) tree;
- return mtree.getIdentifier().toString();
- } else {
- IdentifierTree itree = (IdentifierTree) tree;
- return itree.getName().toString();
- }
- }
-
- /**
- * @return {@code true} if and only if {@code tree} can have a type annotation.
- * <p>TODO: is this implementation precise enough? E.g. does a .class literal work
- * correctly?
- */
- public static boolean canHaveTypeAnnotation(Tree tree) {
- return ((JCTree) tree).type != null;
- }
-
- /**
- * Returns true if and only if the given {@code tree} represents a field access of the given
- * {@link VariableElement}.
- */
- public static boolean isSpecificFieldAccess(Tree tree, VariableElement var) {
- if (tree instanceof MemberSelectTree) {
- MemberSelectTree memSel = (MemberSelectTree) tree;
- Element field = TreeUtils.elementFromUse(memSel);
- return field.equals(var);
- } else if (tree instanceof IdentifierTree) {
- IdentifierTree idTree = (IdentifierTree) tree;
- Element field = TreeUtils.elementFromUse(idTree);
- return field.equals(var);
- } else {
- return false;
- }
- }
-
- /**
- * Returns the VariableElement for a field declaration.
- *
- * @param typeName the class where the field is declared
- * @param fieldName the name of the field
- * @param env the processing environment
- * @return the VariableElement for typeName.fieldName
- */
- public static VariableElement getField(
- String typeName, String fieldName, ProcessingEnvironment env) {
- TypeElement mapElt = env.getElementUtils().getTypeElement(typeName);
- for (VariableElement var : ElementFilter.fieldsIn(mapElt.getEnclosedElements())) {
- if (var.getSimpleName().contentEquals(fieldName)) {
- return var;
- }
- }
- ErrorReporter.errorAbort("TreeUtils.getField: shouldn't be here!");
- return null; // dead code
- }
-
- /**
- * Determine whether the given tree represents an ExpressionTree.
- *
- * <p>TODO: is there a nicer way than an instanceof?
- *
- * @param tree the Tree to test
- * @return whether the tree is an ExpressionTree
- */
- public static boolean isExpressionTree(Tree tree) {
- return tree instanceof ExpressionTree;
- }
-
- /**
- * @param node the method invocation to check
- * @return true if this is a super call to the {@link Enum} constructor
- */
- public static boolean isEnumSuper(MethodInvocationTree node) {
- ExecutableElement ex = TreeUtils.elementFromUse(node);
- Name name = ElementUtils.getQualifiedClassName(ex);
- boolean correctClass = "java.lang.Enum".contentEquals(name);
- boolean correctMethod = "<init>".contentEquals(ex.getSimpleName());
- return correctClass && correctMethod;
- }
-
- /**
- * Determine whether the given tree represents a declaration of a type (including type
- * parameters).
- *
- * @param node the Tree to test
- * @return true if the tree is a type declaration
- */
- public static boolean isTypeDeclaration(Tree node) {
- switch (node.getKind()) {
- // These tree kinds are always declarations. Uses of the declared
- // types have tree kind IDENTIFIER.
- case ANNOTATION_TYPE:
- case CLASS:
- case ENUM:
- case INTERFACE:
- case TYPE_PARAMETER:
- return true;
-
- default:
- return false;
- }
- }
-
- /**
- * @see Object#getClass()
- * @return true iff invocationTree is an instance of getClass()
- */
- public static boolean isGetClassInvocation(MethodInvocationTree invocationTree) {
- final Element declarationElement = elementFromUse(invocationTree);
- String ownerName =
- ElementUtils.getQualifiedClassName(declarationElement.getEnclosingElement())
- .toString();
- return ownerName.equals("java.lang.Object")
- && declarationElement.getSimpleName().toString().equals("getClass");
- }
-
- /**
- * Returns whether or not the leaf of the tree path is in a static scope.
- *
- * @param path TreePath whose leaf may or may not be in static scope
- * @return returns whether or not the leaf of the tree path is in a static scope
- */
- public static boolean isTreeInStaticScope(TreePath path) {
- MethodTree enclosingMethod = TreeUtils.enclosingMethod(path);
-
- if (enclosingMethod != null) {
- return enclosingMethod.getModifiers().getFlags().contains(Modifier.STATIC);
- }
- // no enclosing method, check for static or initializer block
- BlockTree block = enclosingTopLevelBlock(path);
- if (block != null) {
- return block.isStatic();
- }
-
- // check if its in a variable initializer
- Tree t = enclosingVariable(path);
- if (t != null) {
- return ((VariableTree) t).getModifiers().getFlags().contains((Modifier.STATIC));
- }
- ClassTree classTree = enclosingClass(path);
- if (classTree != null) {
- return classTree.getModifiers().getFlags().contains((Modifier.STATIC));
- }
- return false;
- }
-
- /**
- * Returns whether or not tree is an access of array length.
- *
- * @param tree tree to check
- * @return true if tree is an access of array length
- */
- public static boolean isArrayLengthAccess(Tree tree) {
- if (tree.getKind() == Kind.MEMBER_SELECT
- && isFieldAccess(tree)
- && getFieldName(tree).equals("length")) {
- ExpressionTree expressionTree = ((MemberSelectTree) tree).getExpression();
- if (InternalUtils.typeOf(expressionTree).getKind() == TypeKind.ARRAY) {
- return true;
- }
- }
- return false;
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypeAnnotationUtils.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypeAnnotationUtils.java
deleted file mode 100644
index b925f91b04..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypeAnnotationUtils.java
+++ /dev/null
@@ -1,397 +0,0 @@
-package org.checkerframework.javacutil;
-
-import com.sun.tools.javac.code.Attribute;
-import com.sun.tools.javac.code.Attribute.TypeCompound;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.TargetType;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.code.TypeAnnotationPosition;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.Name;
-import com.sun.tools.javac.util.Pair;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.Map;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.AnnotationMirror;
-import javax.lang.model.element.AnnotationValue;
-import javax.lang.model.element.AnnotationValueVisitor;
-import javax.lang.model.element.ElementKind;
-import javax.lang.model.element.ExecutableElement;
-import javax.lang.model.element.VariableElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-
-/**
- * A collection of helper methods related to type annotation handling.
- *
- * @see AnnotationUtils
- */
-public class TypeAnnotationUtils {
-
- // Class cannot be instantiated.
- private TypeAnnotationUtils() {
- throw new AssertionError("Class TypeAnnotationUtils cannot be instantiated.");
- }
-
- /**
- * Check whether a TypeCompound is contained in a list of TypeCompounds.
- *
- * @param list the input list of TypeCompounds
- * @param tc the TypeCompound to find
- * @return true, iff a TypeCompound equal to tc is contained in list
- */
- public static boolean isTypeCompoundContained(
- Types types, List<TypeCompound> list, TypeCompound tc) {
- for (Attribute.TypeCompound rawat : list) {
- if (contentEquals(rawat.type.tsym.name, tc.type.tsym.name)
- // TODO: in previous line, it would be nicer to use reference equality:
- // rawat.type == tc.type &&
- // or at least "isSameType":
- // types.isSameType(rawat.type, tc.type) &&
- // but each fails in some cases.
- && rawat.values.equals(tc.values)
- && isSameTAPositionExceptTreePos(rawat.position, tc.position)) {
- return true;
- }
- }
- return false;
- }
-
- private static boolean contentEquals(Name n1, Name n2) {
- // Views of underlying bytes, not copies as with Name#contentEquals
- ByteBuffer b1 = ByteBuffer.wrap(n1.getByteArray(), n1.getByteOffset(), n1.getByteLength());
- ByteBuffer b2 = ByteBuffer.wrap(n2.getByteArray(), n2.getByteOffset(), n2.getByteLength());
-
- return b1.equals(b2);
- }
-
- /**
- * Compare two TypeAnnotationPositions for equality.
- *
- * @param p1 the first position
- * @param p2 the second position
- * @return true, iff the two positions are equal
- */
- public static boolean isSameTAPosition(TypeAnnotationPosition p1, TypeAnnotationPosition p2) {
- return isSameTAPositionExceptTreePos(p1, p2) && p1.pos == p2.pos;
- }
-
- public static boolean isSameTAPositionExceptTreePos(
- TypeAnnotationPosition p1, TypeAnnotationPosition p2) {
- return p1.isValidOffset == p2.isValidOffset
- && p1.bound_index == p2.bound_index
- && p1.exception_index == p2.exception_index
- && p1.location.equals(p2.location)
- && Arrays.equals(p1.lvarIndex, p2.lvarIndex)
- && Arrays.equals(p1.lvarLength, p2.lvarLength)
- && Arrays.equals(p1.lvarOffset, p2.lvarOffset)
- && p1.offset == p2.offset
- && p1.onLambda == p2.onLambda
- && p1.parameter_index == p2.parameter_index
- && p1.type == p2.type
- && p1.type_index == p2.type_index;
- }
-
- /**
- * Returns a newly created Attribute.Compound corresponding to an argument AnnotationMirror.
- *
- * @param am an AnnotationMirror, which may be part of an AST or an internally created subclass
- * @return a new Attribute.Compound corresponding to the AnnotationMirror
- */
- public static Attribute.Compound createCompoundFromAnnotationMirror(
- ProcessingEnvironment env, AnnotationMirror am) {
- // Create a new Attribute to match the AnnotationMirror.
- List<Pair<Symbol.MethodSymbol, Attribute>> values = List.nil();
- for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry :
- am.getElementValues().entrySet()) {
- Attribute attribute =
- attributeFromAnnotationValue(env, entry.getKey(), entry.getValue());
- values = values.append(new Pair<>((Symbol.MethodSymbol) entry.getKey(), attribute));
- }
- return new Attribute.Compound((Type.ClassType) am.getAnnotationType(), values);
- }
-
- /**
- * Returns a newly created Attribute.TypeCompound corresponding to an argument AnnotationMirror.
- *
- * @param am an AnnotationMirror, which may be part of an AST or an internally created subclass
- * @param tapos the type annotation position to use
- * @return a new Attribute.TypeCompound corresponding to the AnnotationMirror
- */
- public static Attribute.TypeCompound createTypeCompoundFromAnnotationMirror(
- ProcessingEnvironment env, AnnotationMirror am, TypeAnnotationPosition tapos) {
- // Create a new Attribute to match the AnnotationMirror.
- List<Pair<Symbol.MethodSymbol, Attribute>> values = List.nil();
- for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry :
- am.getElementValues().entrySet()) {
- Attribute attribute =
- attributeFromAnnotationValue(env, entry.getKey(), entry.getValue());
- values = values.append(new Pair<>((Symbol.MethodSymbol) entry.getKey(), attribute));
- }
- return new Attribute.TypeCompound((Type.ClassType) am.getAnnotationType(), values, tapos);
- }
-
- /**
- * Returns a newly created Attribute corresponding to an argument AnnotationValue.
- *
- * @param meth the ExecutableElement that is assigned the value, needed for empty arrays
- * @param av an AnnotationValue, which may be part of an AST or an internally created subclass
- * @return a new Attribute corresponding to the AnnotationValue
- */
- public static Attribute attributeFromAnnotationValue(
- ProcessingEnvironment env, ExecutableElement meth, AnnotationValue av) {
- return av.accept(new AttributeCreator(env, meth), null);
- }
-
- private static class AttributeCreator implements AnnotationValueVisitor<Attribute, Void> {
- private final ProcessingEnvironment processingEnv;
- private final Types modelTypes;
- private final Elements elements;
- private final com.sun.tools.javac.code.Types javacTypes;
-
- private final ExecutableElement meth;
-
- public AttributeCreator(ProcessingEnvironment env, ExecutableElement meth) {
- this.processingEnv = env;
- Context context = ((JavacProcessingEnvironment) env).getContext();
- this.elements = env.getElementUtils();
- this.modelTypes = env.getTypeUtils();
- this.javacTypes = com.sun.tools.javac.code.Types.instance(context);
-
- this.meth = meth;
- }
-
- @Override
- public Attribute visit(AnnotationValue av, Void p) {
- return av.accept(this, p);
- }
-
- @Override
- public Attribute visit(AnnotationValue av) {
- return visit(av, null);
- }
-
- @Override
- public Attribute visitBoolean(boolean b, Void p) {
- TypeMirror booleanType = modelTypes.getPrimitiveType(TypeKind.BOOLEAN);
- return new Attribute.Constant((Type) booleanType, b ? 1 : 0);
- }
-
- @Override
- public Attribute visitByte(byte b, Void p) {
- TypeMirror byteType = modelTypes.getPrimitiveType(TypeKind.BYTE);
- return new Attribute.Constant((Type) byteType, b);
- }
-
- @Override
- public Attribute visitChar(char c, Void p) {
- TypeMirror charType = modelTypes.getPrimitiveType(TypeKind.CHAR);
- return new Attribute.Constant((Type) charType, c);
- }
-
- @Override
- public Attribute visitDouble(double d, Void p) {
- TypeMirror doubleType = modelTypes.getPrimitiveType(TypeKind.DOUBLE);
- return new Attribute.Constant((Type) doubleType, d);
- }
-
- @Override
- public Attribute visitFloat(float f, Void p) {
- TypeMirror floatType = modelTypes.getPrimitiveType(TypeKind.FLOAT);
- return new Attribute.Constant((Type) floatType, f);
- }
-
- @Override
- public Attribute visitInt(int i, Void p) {
- TypeMirror intType = modelTypes.getPrimitiveType(TypeKind.INT);
- return new Attribute.Constant((Type) intType, i);
- }
-
- @Override
- public Attribute visitLong(long i, Void p) {
- TypeMirror longType = modelTypes.getPrimitiveType(TypeKind.LONG);
- return new Attribute.Constant((Type) longType, i);
- }
-
- @Override
- public Attribute visitShort(short s, Void p) {
- TypeMirror shortType = modelTypes.getPrimitiveType(TypeKind.SHORT);
- return new Attribute.Constant((Type) shortType, s);
- }
-
- @Override
- public Attribute visitString(String s, Void p) {
- TypeMirror stringType = elements.getTypeElement("java.lang.String").asType();
- return new Attribute.Constant((Type) stringType, s);
- }
-
- @Override
- public Attribute visitType(TypeMirror t, Void p) {
- if (t instanceof Type) {
- return new Attribute.Class(javacTypes, (Type) t);
- }
-
- assert false : "Unexpected type of TypeMirror: " + t.getClass();
- return null;
- }
-
- @Override
- public Attribute visitEnumConstant(VariableElement c, Void p) {
- if (c instanceof Symbol.VarSymbol) {
- Symbol.VarSymbol sym = (Symbol.VarSymbol) c;
- if (sym.getKind() == ElementKind.ENUM_CONSTANT) {
- return new Attribute.Enum(sym.type, sym);
- }
- }
-
- assert false : "Unexpected type of VariableElement: " + c.getClass();
- return null;
- }
-
- @Override
- public Attribute visitAnnotation(AnnotationMirror a, Void p) {
- return createCompoundFromAnnotationMirror(processingEnv, a);
- }
-
- @Override
- public Attribute visitArray(java.util.List<? extends AnnotationValue> vals, Void p) {
- if (!vals.isEmpty()) {
- List<Attribute> valAttrs = List.nil();
- for (AnnotationValue av : vals) {
- valAttrs = valAttrs.append(av.accept(this, p));
- }
- ArrayType arrayType = modelTypes.getArrayType(valAttrs.get(0).type);
- return new Attribute.Array((Type) arrayType, valAttrs);
- } else {
- return new Attribute.Array((Type) meth.getReturnType(), List.<Attribute>nil());
- }
- }
-
- @Override
- public Attribute visitUnknown(AnnotationValue av, Void p) {
- assert false : "Unexpected type of AnnotationValue: " + av.getClass();
- return null;
- }
- }
-
- public static TypeAnnotationPosition unknownTAPosition() {
- return new TypeAnnotationPosition();
- }
-
- public static TypeAnnotationPosition methodReturnTAPosition(final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.METHOD_RETURN;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition methodReceiverTAPosition(final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.METHOD_RECEIVER;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition methodParameterTAPosition(final int pidx, final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.METHOD_FORMAL_PARAMETER;
- tapos.parameter_index = pidx;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition methodThrowsTAPosition(final int tidx, final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.THROWS;
- tapos.type_index = tidx;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition fieldTAPosition(final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.FIELD;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition classExtendsTAPosition(final int implidx, final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.CLASS_EXTENDS;
- tapos.type_index = implidx;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition typeParameterTAPosition(final int tpidx, final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.CLASS_TYPE_PARAMETER;
- tapos.parameter_index = tpidx;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition methodTypeParameterTAPosition(
- final int tpidx, final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.METHOD_TYPE_PARAMETER;
- tapos.parameter_index = tpidx;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition typeParameterBoundTAPosition(
- final int tpidx, final int bndidx, final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
- tapos.parameter_index = tpidx;
- tapos.bound_index = bndidx;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition methodTypeParameterBoundTAPosition(
- final int tpidx, final int bndidx, final int pos) {
- TypeAnnotationPosition tapos = new TypeAnnotationPosition();
- tapos.type = TargetType.METHOD_TYPE_PARAMETER_BOUND;
- tapos.parameter_index = tpidx;
- tapos.bound_index = bndidx;
- tapos.pos = pos;
- return tapos;
- }
-
- public static TypeAnnotationPosition copyTAPosition(final TypeAnnotationPosition tapos) {
- TypeAnnotationPosition res = new TypeAnnotationPosition();
- res.isValidOffset = tapos.isValidOffset;
- res.bound_index = tapos.bound_index;
- res.exception_index = tapos.exception_index;
- res.location = List.from(tapos.location);
- if (tapos.lvarIndex != null) {
- res.lvarIndex = Arrays.copyOf(tapos.lvarIndex, tapos.lvarIndex.length);
- }
- if (tapos.lvarLength != null) {
- res.lvarLength = Arrays.copyOf(tapos.lvarLength, tapos.lvarLength.length);
- }
- if (tapos.lvarOffset != null) {
- res.lvarOffset = Arrays.copyOf(tapos.lvarOffset, tapos.lvarOffset.length);
- }
- res.offset = tapos.offset;
- res.onLambda = tapos.onLambda;
- res.parameter_index = tapos.parameter_index;
- res.pos = tapos.pos;
- res.type = tapos.type;
- res.type_index = tapos.type_index;
- return res;
- }
-
- public static Type unannotatedType(final TypeMirror in) {
- final Type impl = (Type) in;
- return impl.unannotatedType();
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypesUtils.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypesUtils.java
deleted file mode 100644
index fe7456f6d2..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/TypesUtils.java
+++ /dev/null
@@ -1,452 +0,0 @@
-package org.checkerframework.javacutil;
-
-import static com.sun.tools.javac.code.TypeTag.WILDCARD;
-
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.code.TypeTag;
-import com.sun.tools.javac.model.JavacTypes;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.util.Context;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.Name;
-import javax.lang.model.element.NestingKind;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.element.TypeParameterElement;
-import javax.lang.model.type.ArrayType;
-import javax.lang.model.type.DeclaredType;
-import javax.lang.model.type.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.type.TypeVariable;
-import javax.lang.model.type.WildcardType;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-
-/** A utility class that helps with {@link TypeMirror}s. */
-// TODO: This class needs significant restructuring
-public final class TypesUtils {
-
- // Class cannot be instantiated
- private TypesUtils() {
- throw new AssertionError("Class TypesUtils cannot be instantiated.");
- }
-
- /**
- * Gets the fully qualified name for a provided type. It returns an empty name if type is an
- * anonymous type.
- *
- * @param type the declared type
- * @return the name corresponding to that type
- */
- public static Name getQualifiedName(DeclaredType type) {
- TypeElement element = (TypeElement) type.asElement();
- return element.getQualifiedName();
- }
-
- /**
- * Checks if the type represents a java.lang.Object declared type.
- *
- * @param type the type
- * @return true iff type represents java.lang.Object
- */
- public static boolean isObject(TypeMirror type) {
- return isDeclaredOfName(type, "java.lang.Object");
- }
-
- /**
- * Checks if the type represents a java.lang.Class declared type.
- *
- * @param type the type
- * @return true iff type represents java.lang.Class
- */
- public static boolean isClass(TypeMirror type) {
- return isDeclaredOfName(type, "java.lang.Class");
- }
-
- /**
- * Checks if the type represents a java.lang.String declared type. TODO: it would be cleaner to
- * use String.class.getCanonicalName(), but the two existing methods above don't do that, I
- * guess for performance reasons.
- *
- * @param type the type
- * @return true iff type represents java.lang.String
- */
- public static boolean isString(TypeMirror type) {
- return isDeclaredOfName(type, "java.lang.String");
- }
-
- /**
- * Checks if the type represents a boolean type, that is either boolean (primitive type) or
- * java.lang.Boolean.
- *
- * @param type the type to test
- * @return true iff type represents a boolean type
- */
- public static boolean isBooleanType(TypeMirror type) {
- return isDeclaredOfName(type, "java.lang.Boolean")
- || type.getKind().equals(TypeKind.BOOLEAN);
- }
-
- /**
- * Check if the type represent a declared type of the given qualified name
- *
- * @param type the type
- * @return type iff type represents a declared type of the qualified name
- */
- public static boolean isDeclaredOfName(TypeMirror type, CharSequence qualifiedName) {
- return type.getKind() == TypeKind.DECLARED
- && getQualifiedName((DeclaredType) type).contentEquals(qualifiedName);
- }
-
- public static boolean isBoxedPrimitive(TypeMirror type) {
- if (type.getKind() != TypeKind.DECLARED) {
- return false;
- }
-
- String qualifiedName = getQualifiedName((DeclaredType) type).toString();
-
- return (qualifiedName.equals("java.lang.Boolean")
- || qualifiedName.equals("java.lang.Byte")
- || qualifiedName.equals("java.lang.Character")
- || qualifiedName.equals("java.lang.Short")
- || qualifiedName.equals("java.lang.Integer")
- || qualifiedName.equals("java.lang.Long")
- || qualifiedName.equals("java.lang.Double")
- || qualifiedName.equals("java.lang.Float"));
- }
-
- /** @return type represents a Throwable type (e.g. Exception, Error) */
- public static boolean isThrowable(TypeMirror type) {
- while (type != null && type.getKind() == TypeKind.DECLARED) {
- DeclaredType dt = (DeclaredType) type;
- TypeElement elem = (TypeElement) dt.asElement();
- Name name = elem.getQualifiedName();
- if ("java.lang.Throwable".contentEquals(name)) {
- return true;
- }
- type = elem.getSuperclass();
- }
- return false;
- }
-
- /**
- * Returns true iff the argument is an anonymous type.
- *
- * @return whether the argument is an anonymous type
- */
- public static boolean isAnonymous(TypeMirror type) {
- return (type instanceof DeclaredType)
- && (((TypeElement) ((DeclaredType) type).asElement())
- .getNestingKind()
- .equals(NestingKind.ANONYMOUS));
- }
-
- /**
- * Returns true iff the argument is a primitive type.
- *
- * @return whether the argument is a primitive type
- */
- public static boolean isPrimitive(TypeMirror type) {
- switch (type.getKind()) {
- case BOOLEAN:
- case BYTE:
- case CHAR:
- case DOUBLE:
- case FLOAT:
- case INT:
- case LONG:
- case SHORT:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Returns true iff the arguments are both the same primitive types.
- *
- * @return whether the arguments are the same primitive types
- */
- public static boolean areSamePrimitiveTypes(TypeMirror left, TypeMirror right) {
- if (!isPrimitive(left) || !isPrimitive(right)) {
- return false;
- }
-
- return (left.getKind() == right.getKind());
- }
-
- /**
- * Returns true iff the argument is a primitive numeric type.
- *
- * @return whether the argument is a primitive numeric type
- */
- public static boolean isNumeric(TypeMirror type) {
- switch (type.getKind()) {
- case BYTE:
- case CHAR:
- case DOUBLE:
- case FLOAT:
- case INT:
- case LONG:
- case SHORT:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Returns true iff the argument is an integral type.
- *
- * @return whether the argument is an integral type
- */
- public static boolean isIntegral(TypeMirror type) {
- switch (type.getKind()) {
- case BYTE:
- case CHAR:
- case INT:
- case LONG:
- case SHORT:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Returns true iff the argument is a floating point type.
- *
- * @return whether the argument is a floating point type
- */
- public static boolean isFloating(TypeMirror type) {
- switch (type.getKind()) {
- case DOUBLE:
- case FLOAT:
- return true;
- default:
- return false;
- }
- }
-
- /**
- * Returns the widened numeric type for an arithmetic operation performed on a value of the left
- * type and the right type. Defined in JLS 5.6.2. We return a {@link TypeKind} because creating
- * a {@link TypeMirror} requires a {@link Types} object from the {@link
- * javax.annotation.processing.ProcessingEnvironment}.
- *
- * @return the result of widening numeric conversion, or NONE when the conversion cannot be
- * performed
- */
- public static TypeKind widenedNumericType(TypeMirror left, TypeMirror right) {
- if (!isNumeric(left) || !isNumeric(right)) {
- return TypeKind.NONE;
- }
-
- TypeKind leftKind = left.getKind();
- TypeKind rightKind = right.getKind();
-
- if (leftKind == TypeKind.DOUBLE || rightKind == TypeKind.DOUBLE) {
- return TypeKind.DOUBLE;
- }
-
- if (leftKind == TypeKind.FLOAT || rightKind == TypeKind.FLOAT) {
- return TypeKind.FLOAT;
- }
-
- if (leftKind == TypeKind.LONG || rightKind == TypeKind.LONG) {
- return TypeKind.LONG;
- }
-
- return TypeKind.INT;
- }
-
- /**
- * If the argument is a bounded TypeVariable or WildcardType, return its non-variable,
- * non-wildcard upper bound. Otherwise, return the type itself.
- *
- * @param type a type
- * @return the non-variable, non-wildcard upper bound of a type, if it has one, or itself if it
- * has no bounds
- */
- public static TypeMirror upperBound(TypeMirror type) {
- do {
- if (type instanceof TypeVariable) {
- TypeVariable tvar = (TypeVariable) type;
- if (tvar.getUpperBound() != null) {
- type = tvar.getUpperBound();
- } else {
- break;
- }
- } else if (type instanceof WildcardType) {
- WildcardType wc = (WildcardType) type;
- if (wc.getExtendsBound() != null) {
- type = wc.getExtendsBound();
- } else {
- break;
- }
- } else {
- break;
- }
- } while (true);
- return type;
- }
-
- /**
- * Get the type parameter for this wildcard from the underlying type's bound field This field is
- * sometimes null, in that case this method will return null
- *
- * @return the TypeParameterElement the wildcard is an argument to
- */
- public static TypeParameterElement wildcardToTypeParam(final Type.WildcardType wildcard) {
-
- final Element typeParamElement;
- if (wildcard.bound != null) {
- typeParamElement = wildcard.bound.asElement();
- } else {
- typeParamElement = null;
- }
-
- return (TypeParameterElement) typeParamElement;
- }
-
- /**
- * Version of com.sun.tools.javac.code.Types.wildUpperBound(Type) that works with both jdk8
- * (called upperBound there) and jdk8u.
- */
- // TODO: contrast to upperBound.
- public static Type wildUpperBound(ProcessingEnvironment env, TypeMirror tm) {
- Type t = (Type) tm;
- if (t.hasTag(TypeTag.WILDCARD)) {
- Context context = ((JavacProcessingEnvironment) env).getContext();
- Type.WildcardType w = (Type.WildcardType) TypeAnnotationUtils.unannotatedType(t);
- if (w.isSuperBound()) {
- Symtab syms = Symtab.instance(context);
- return w.bound == null ? syms.objectType : w.bound.bound;
- } else {
- return wildUpperBound(env, w.type);
- }
- } else {
- return TypeAnnotationUtils.unannotatedType(t);
- }
- }
-
- /**
- * Version of com.sun.tools.javac.code.Types.wildLowerBound(Type) that works with both jdk8
- * (called upperBound there) and jdk8u.
- */
- public static Type wildLowerBound(ProcessingEnvironment env, TypeMirror tm) {
- Type t = (Type) tm;
- if (t.hasTag(WILDCARD)) {
- Context context = ((JavacProcessingEnvironment) env).getContext();
- Symtab syms = Symtab.instance(context);
- Type.WildcardType w = (Type.WildcardType) TypeAnnotationUtils.unannotatedType(t);
- return w.isExtendsBound() ? syms.botType : wildLowerBound(env, w.type);
- } else {
- return TypeAnnotationUtils.unannotatedType(t);
- }
- }
- /** Returns the {@link TypeMirror} for a given {@link Class}. */
- public static TypeMirror typeFromClass(Types types, Elements elements, Class<?> clazz) {
- if (clazz == void.class) {
- return types.getNoType(TypeKind.VOID);
- } else if (clazz.isPrimitive()) {
- String primitiveName = clazz.getName().toUpperCase();
- TypeKind primitiveKind = TypeKind.valueOf(primitiveName);
- return types.getPrimitiveType(primitiveKind);
- } else if (clazz.isArray()) {
- TypeMirror componentType = typeFromClass(types, elements, clazz.getComponentType());
- return types.getArrayType(componentType);
- } else {
- TypeElement element = elements.getTypeElement(clazz.getCanonicalName());
- if (element == null) {
- ErrorReporter.errorAbort("Unrecognized class: " + clazz);
- return null; // dead code
- }
- return element.asType();
- }
- }
-
- /** Returns an {@link ArrayType} with elements of type {@code componentType}. */
- public static ArrayType createArrayType(Types types, TypeMirror componentType) {
- JavacTypes t = (JavacTypes) types;
- return t.getArrayType(componentType);
- }
-
- /**
- * Returns true if declaredType is a Class that is used to box primitive type (e.g.
- * declaredType=java.lang.Double and primitiveType=22.5d )
- */
- public static boolean isBoxOf(TypeMirror declaredType, TypeMirror primitiveType) {
- if (declaredType.getKind() != TypeKind.DECLARED) {
- return false;
- }
-
- final String qualifiedName = getQualifiedName((DeclaredType) declaredType).toString();
- switch (primitiveType.getKind()) {
- case BOOLEAN:
- return qualifiedName.equals("java.lang.Boolean");
- case BYTE:
- return qualifiedName.equals("java.lang.Byte");
- case CHAR:
- return qualifiedName.equals("java.lang.Character");
- case DOUBLE:
- return qualifiedName.equals("java.lang.Double");
- case FLOAT:
- return qualifiedName.equals("java.lang.Float");
- case INT:
- return qualifiedName.equals("java.lang.Integer");
- case LONG:
- return qualifiedName.equals("java.lang.Long");
- case SHORT:
- return qualifiedName.equals("java.lang.Short");
-
- default:
- return false;
- }
- }
-
- /**
- * Given a bounded type (wildcard or typevar) get the concrete type of its upper bound. If the
- * bounded type extends other bounded types, this method will iterate through their bounds until
- * a class, interface, or intersection is found.
- *
- * @return a type that is not a wildcard or typevar, or null if this type is an unbounded
- * wildcard
- */
- public static TypeMirror findConcreteUpperBound(final TypeMirror boundedType) {
- TypeMirror effectiveUpper = boundedType;
- outerLoop:
- while (true) {
- switch (effectiveUpper.getKind()) {
- case WILDCARD:
- effectiveUpper =
- ((javax.lang.model.type.WildcardType) effectiveUpper).getExtendsBound();
- if (effectiveUpper == null) {
- return null;
- }
- break;
-
- case TYPEVAR:
- effectiveUpper = ((TypeVariable) effectiveUpper).getUpperBound();
- break;
-
- default:
- break outerLoop;
- }
- }
- return effectiveUpper;
- }
-
- /**
- * Returns true if the erased type of subtype is a subtype of the erased type of supertype.
- *
- * @param types Types
- * @param subtype possible subtype
- * @param supertype possible supertype
- * @return true if the erased type of subtype is a subtype of the erased type of supertype
- */
- public static boolean isErasedSubtype(Types types, TypeMirror subtype, TypeMirror supertype) {
- return types.isSubtype(types.erasure(subtype), types.erasure(supertype));
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/dist/ManualTaglet.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/dist/ManualTaglet.java
deleted file mode 100644
index 01f35485e5..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/dist/ManualTaglet.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package org.checkerframework.javacutil.dist;
-
-import com.sun.javadoc.Tag;
-import com.sun.tools.doclets.Taglet;
-import java.util.Map;
-
-/**
- * A taglet for processing the {@code @checker_framework.manual} javadoc block tag, which inserts
- * references to the Checker Framework manual into javadoc.
- *
- * <p>The {@code @checker_framework.manual} tag is used as follows:
- *
- * <ul>
- * <li>{@code @checker_framework.manual #} expands to a top-level link to the Checker Framework
- * manual
- * <li>{@code @checker_framework.manual #anchor text} expands to a link with some text to a
- * particular part of the manual
- * </ul>
- */
-public class ManualTaglet implements Taglet {
-
- @Override
- public String getName() {
- return "checker_framework.manual";
- }
-
- @Override
- public boolean inConstructor() {
- return true;
- }
-
- @Override
- public boolean inField() {
- return true;
- }
-
- @Override
- public boolean inMethod() {
- return true;
- }
-
- @Override
- public boolean inOverview() {
- return true;
- }
-
- @Override
- public boolean inPackage() {
- return true;
- }
-
- @Override
- public boolean inType() {
- return true;
- }
-
- @Override
- public boolean isInlineTag() {
- return false;
- }
-
- /**
- * Formats a link, given an array of tokens.
- *
- * @param parts the array of tokens
- * @return a link to the manual top-level if the array size is one, or a link to a part of the
- * manual if it's larger than one
- */
- private String formatLink(String[] parts) {
- String anchor, text;
- if (parts.length < 2) {
- anchor = "";
- text = "Checker Framework";
- } else {
- anchor = parts[0];
- text = parts[1];
- }
- return String.format(
- "<A HREF=\"https://checkerframework.org/manual/%s\">%s</A>", anchor, text);
- }
-
- /**
- * Formats the {@code @checker_framework.manual} tag, prepending the tag header to the tag
- * content.
- *
- * @param text the tag content
- * @return the formatted tag
- */
- private String formatHeader(String text) {
- return String.format("<DT><B>See the Checker Framework Manual:</B><DD>%s<BR>", text);
- }
-
- @Override
- public String toString(Tag tag) {
- String[] split = tag.text().split(" ", 2);
- return formatHeader(formatLink(split));
- }
-
- @Override
- public String toString(Tag[] tags) {
- if (tags.length == 0) {
- return "";
- }
- StringBuilder sb = new StringBuilder();
- for (Tag t : tags) {
- String[] split = t.text().split(" ", 2);
- if (t != tags[0]) {
- sb.append(", ");
- }
- sb.append(formatLink(split));
- }
- return formatHeader(sb.toString());
- }
-
- @SuppressWarnings({"unchecked", "rawtypes"})
- public static void register(Map tagletMap) {
- ManualTaglet tag = new ManualTaglet();
- Taglet t = (Taglet) tagletMap.get(tag.getName());
- if (t != null) {
- tagletMap.remove(tag.getName());
- }
- tagletMap.put(tag.getName(), tag);
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/DetachedVarSymbol.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/DetachedVarSymbol.java
deleted file mode 100644
index 43d79cc710..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/DetachedVarSymbol.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.checkerframework.javacutil.trees;
-
-import com.sun.source.tree.VariableTree;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.util.Name;
-
-/*>>>
-import org.checkerframework.checker.nullness.qual.Nullable;
-*/
-
-/**
- * A DetachedVarSymbol represents a variable that is not part of any AST Tree. DetachedVarSymbols
- * are created when desugaring source code constructs and they carry important type information, but
- * some methods such as TreeInfo.declarationFor do not work on them.
- */
-public class DetachedVarSymbol extends Symbol.VarSymbol {
-
- protected /*@Nullable*/ VariableTree decl;
-
- /** Construct a detached variable symbol, given its flags, name, type and owner. */
- public DetachedVarSymbol(long flags, Name name, Type type, Symbol owner) {
- super(flags, name, type, owner);
- this.decl = null;
- }
-
- /** Set the declaration tree for the variable. */
- public void setDeclaration(VariableTree decl) {
- this.decl = decl;
- }
-
- /** Get the declaration tree for the variable. */
- public /*@Nullable*/ VariableTree getDeclaration() {
- return decl;
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeBuilder.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeBuilder.java
deleted file mode 100644
index eab005dea8..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeBuilder.java
+++ /dev/null
@@ -1,655 +0,0 @@
-package org.checkerframework.javacutil.trees;
-
-import com.sun.source.tree.ArrayAccessTree;
-import com.sun.source.tree.AssignmentTree;
-import com.sun.source.tree.BinaryTree;
-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.StatementTree;
-import com.sun.source.tree.Tree;
-import com.sun.source.tree.TypeCastTree;
-import com.sun.source.tree.VariableTree;
-import com.sun.tools.javac.code.Symbol;
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.code.Type;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.TreeInfo;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.Names;
-import java.util.List;
-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.TypeKind;
-import javax.lang.model.type.TypeMirror;
-import javax.lang.model.util.ElementFilter;
-import javax.lang.model.util.Elements;
-import javax.lang.model.util.Types;
-import org.checkerframework.javacutil.InternalUtils;
-import org.checkerframework.javacutil.TypesUtils;
-
-/**
- * The TreeBuilder permits the creation of new AST Trees using the non-public Java compiler API
- * TreeMaker.
- */
-public class TreeBuilder {
- protected final Elements elements;
- protected final Types modelTypes;
- protected final com.sun.tools.javac.code.Types javacTypes;
- protected final TreeMaker maker;
- protected final Names names;
- protected final Symtab symtab;
- protected final ProcessingEnvironment env;
-
- public TreeBuilder(ProcessingEnvironment env) {
- this.env = env;
- Context context = ((JavacProcessingEnvironment) env).getContext();
- elements = env.getElementUtils();
- modelTypes = env.getTypeUtils();
- javacTypes = com.sun.tools.javac.code.Types.instance(context);
- maker = TreeMaker.instance(context);
- names = Names.instance(context);
- symtab = Symtab.instance(context);
- }
-
- /**
- * Builds an AST Tree to access the iterator() method of some iterable expression.
- *
- * @param iterableExpr an expression whose type is a subtype of Iterable
- * @return a MemberSelectTree that accesses the iterator() method of the expression
- */
- public MemberSelectTree buildIteratorMethodAccess(ExpressionTree iterableExpr) {
- DeclaredType exprType =
- (DeclaredType) TypesUtils.upperBound(InternalUtils.typeOf(iterableExpr));
- assert exprType != null : "expression must be of declared type Iterable<>";
-
- TypeElement exprElement = (TypeElement) exprType.asElement();
-
- // Find the iterator() method of the iterable type
- Symbol.MethodSymbol iteratorMethod = null;
-
- for (ExecutableElement method :
- ElementFilter.methodsIn(elements.getAllMembers(exprElement))) {
- Name methodName = method.getSimpleName();
-
- if (method.getParameters().size() == 0) {
- if (methodName.contentEquals("iterator")) {
- iteratorMethod = (Symbol.MethodSymbol) method;
- }
- }
- }
-
- assert iteratorMethod != null : "no iterator method declared for expression type";
-
- Type.MethodType methodType = (Type.MethodType) iteratorMethod.asType();
- Symbol.TypeSymbol methodClass = methodType.asElement();
- DeclaredType iteratorType = (DeclaredType) methodType.getReturnType();
- TypeMirror elementType;
-
- if (iteratorType.getTypeArguments().size() > 0) {
- elementType = iteratorType.getTypeArguments().get(0);
- // Remove captured type from a wildcard.
- if (elementType instanceof Type.CapturedType) {
- elementType = ((Type.CapturedType) elementType).wildcard;
- }
-
- iteratorType =
- modelTypes.getDeclaredType(
- (TypeElement) modelTypes.asElement(iteratorType), elementType);
- }
-
- // Replace the iterator method's generic return type with
- // the actual element type of the expression.
- Type.MethodType updatedMethodType =
- new Type.MethodType(
- com.sun.tools.javac.util.List.<Type>nil(),
- (Type) iteratorType,
- com.sun.tools.javac.util.List.<Type>nil(),
- methodClass);
-
- JCTree.JCFieldAccess iteratorAccess =
- (JCTree.JCFieldAccess)
- maker.Select((JCTree.JCExpression) iterableExpr, iteratorMethod);
- iteratorAccess.setType(updatedMethodType);
-
- return iteratorAccess;
- }
-
- /**
- * Builds an AST Tree to access the hasNext() method of an iterator.
- *
- * @param iteratorExpr an expression whose type is a subtype of Iterator
- * @return a MemberSelectTree that accesses the hasNext() method of the expression
- */
- public MemberSelectTree buildHasNextMethodAccess(ExpressionTree iteratorExpr) {
- DeclaredType exprType = (DeclaredType) InternalUtils.typeOf(iteratorExpr);
- assert exprType != null : "expression must be of declared type Iterator<>";
-
- TypeElement exprElement = (TypeElement) exprType.asElement();
-
- // Find the hasNext() method of the iterator type
- Symbol.MethodSymbol hasNextMethod = null;
-
- for (ExecutableElement method :
- ElementFilter.methodsIn(elements.getAllMembers(exprElement))) {
- Name methodName = method.getSimpleName();
-
- if (method.getParameters().size() == 0) {
- if (methodName.contentEquals("hasNext")) {
- hasNextMethod = (Symbol.MethodSymbol) method;
- }
- }
- }
-
- assert hasNextMethod != null : "no hasNext method declared for expression type";
-
- JCTree.JCFieldAccess hasNextAccess =
- (JCTree.JCFieldAccess)
- maker.Select((JCTree.JCExpression) iteratorExpr, hasNextMethod);
- hasNextAccess.setType(hasNextMethod.asType());
-
- return hasNextAccess;
- }
-
- /**
- * Builds an AST Tree to access the next() method of an iterator.
- *
- * @param iteratorExpr an expression whose type is a subtype of Iterator
- * @return a MemberSelectTree that accesses the next() method of the expression
- */
- public MemberSelectTree buildNextMethodAccess(ExpressionTree iteratorExpr) {
- DeclaredType exprType = (DeclaredType) InternalUtils.typeOf(iteratorExpr);
- assert exprType != null : "expression must be of declared type Iterator<>";
-
- TypeElement exprElement = (TypeElement) exprType.asElement();
-
- // Find the next() method of the iterator type
- Symbol.MethodSymbol nextMethod = null;
-
- for (ExecutableElement method :
- ElementFilter.methodsIn(elements.getAllMembers(exprElement))) {
- Name methodName = method.getSimpleName();
-
- if (method.getParameters().size() == 0) {
- if (methodName.contentEquals("next")) {
- nextMethod = (Symbol.MethodSymbol) method;
- }
- }
- }
-
- assert nextMethod != null : "no next method declared for expression type";
-
- Type.MethodType methodType = (Type.MethodType) nextMethod.asType();
- Symbol.TypeSymbol methodClass = methodType.asElement();
- Type elementType;
-
- if (exprType.getTypeArguments().size() > 0) {
- elementType = (Type) exprType.getTypeArguments().get(0);
- } else {
- elementType = symtab.objectType;
- }
-
- // Replace the next method's generic return type with
- // the actual element type of the expression.
- Type.MethodType updatedMethodType =
- new Type.MethodType(
- com.sun.tools.javac.util.List.<Type>nil(),
- elementType,
- com.sun.tools.javac.util.List.<Type>nil(),
- methodClass);
-
- JCTree.JCFieldAccess nextAccess =
- (JCTree.JCFieldAccess) maker.Select((JCTree.JCExpression) iteratorExpr, nextMethod);
- nextAccess.setType(updatedMethodType);
-
- return nextAccess;
- }
-
- /**
- * Builds an AST Tree to dereference the length field of an array
- *
- * @param expression the array expression whose length is being accessed
- * @return a MemberSelectTree to dereference the length of the array
- */
- public MemberSelectTree buildArrayLengthAccess(ExpressionTree expression) {
-
- return (JCTree.JCFieldAccess)
- maker.Select((JCTree.JCExpression) expression, symtab.lengthVar);
- }
-
- /**
- * Builds an AST Tree to call a method designated by the argument expression.
- *
- * @param methodExpr an expression denoting a method with no arguments
- * @return a MethodInvocationTree to call the argument method
- */
- public MethodInvocationTree buildMethodInvocation(ExpressionTree methodExpr) {
- return maker.App((JCTree.JCExpression) methodExpr);
- }
-
- /**
- * Builds an AST Tree to call a method designated by methodExpr, with one argument designated by
- * argExpr.
- *
- * @param methodExpr an expression denoting a method with one argument
- * @param argExpr an expression denoting an argument to the method
- * @return a MethodInvocationTree to call the argument method
- */
- public MethodInvocationTree buildMethodInvocation(
- ExpressionTree methodExpr, ExpressionTree argExpr) {
- return maker.App(
- (JCTree.JCExpression) methodExpr,
- com.sun.tools.javac.util.List.of((JCTree.JCExpression) argExpr));
- }
-
- /**
- * Builds an AST Tree to declare and initialize a variable, with no modifiers.
- *
- * @param type the type of the variable
- * @param name the name of the variable
- * @param owner the element containing the new symbol
- * @param initializer the initializer expression
- * @return a VariableDeclTree declaring the new variable
- */
- public VariableTree buildVariableDecl(
- TypeMirror type, String name, Element owner, ExpressionTree initializer) {
- DetachedVarSymbol sym =
- new DetachedVarSymbol(0, names.fromString(name), (Type) type, (Symbol) owner);
- VariableTree tree = maker.VarDef(sym, (JCTree.JCExpression) initializer);
- sym.setDeclaration(tree);
- return tree;
- }
-
- /**
- * Builds an AST Tree to declare and initialize a variable. The type of the variable is
- * specified by a Tree.
- *
- * @param type the type of the variable, as a Tree
- * @param name the name of the variable
- * @param owner the element containing the new symbol
- * @param initializer the initializer expression
- * @return a VariableDeclTree declaring the new variable
- */
- public VariableTree buildVariableDecl(
- Tree type, String name, Element owner, ExpressionTree initializer) {
- Type typeMirror = (Type) InternalUtils.typeOf(type);
- DetachedVarSymbol sym =
- new DetachedVarSymbol(0, names.fromString(name), typeMirror, (Symbol) owner);
- JCTree.JCModifiers mods = maker.Modifiers(0);
- JCTree.JCVariableDecl decl =
- maker.VarDef(
- mods,
- sym.name,
- (JCTree.JCExpression) type,
- (JCTree.JCExpression) initializer);
- decl.setType(typeMirror);
- decl.sym = sym;
- sym.setDeclaration(decl);
- return decl;
- }
-
- /**
- * Builds an AST Tree to refer to a variable.
- *
- * @param decl the declaration of the variable
- * @return an IdentifierTree to refer to the variable
- */
- public IdentifierTree buildVariableUse(VariableTree decl) {
- return (IdentifierTree) maker.Ident((JCTree.JCVariableDecl) decl);
- }
-
- /**
- * Builds an AST Tree to cast the type of an expression.
- *
- * @param type the type to cast to
- * @param expr the expression to be cast
- * @return a cast of the expression to the type
- */
- public TypeCastTree buildTypeCast(TypeMirror type, ExpressionTree expr) {
- return maker.TypeCast((Type) type, (JCTree.JCExpression) expr);
- }
-
- /**
- * Builds an AST Tree to assign an expression to a variable.
- *
- * @param variable the declaration of the variable to assign to
- * @param expr the expression to be assigned
- * @return a statement assigning the expression to the variable
- */
- public StatementTree buildAssignment(VariableTree variable, ExpressionTree expr) {
- return maker.Assignment(TreeInfo.symbolFor((JCTree) variable), (JCTree.JCExpression) expr);
- }
-
- /**
- * Builds an AST Tree to assign an RHS expression to an LHS expression.
- *
- * @param lhs the expression to be assigned to
- * @param rhs the expression to be assigned
- * @return a statement assigning the expression to the variable
- */
- public AssignmentTree buildAssignment(ExpressionTree lhs, ExpressionTree rhs) {
- JCTree.JCAssign assign = maker.Assign((JCTree.JCExpression) lhs, (JCTree.JCExpression) rhs);
- assign.setType((Type) InternalUtils.typeOf(lhs));
- return assign;
- }
-
- /** Builds an AST Tree representing a literal value of primitive or String type. */
- public LiteralTree buildLiteral(Object value) {
- return maker.Literal(value);
- }
-
- /**
- * Builds an AST Tree to compare two operands with less than.
- *
- * @param left the left operand tree
- * @param right the right operand tree
- * @return a Tree representing "left &lt; right"
- */
- public BinaryTree buildLessThan(ExpressionTree left, ExpressionTree right) {
- JCTree.JCBinary binary =
- maker.Binary(
- JCTree.Tag.LT, (JCTree.JCExpression) left, (JCTree.JCExpression) right);
- binary.setType((Type) modelTypes.getPrimitiveType(TypeKind.BOOLEAN));
- return binary;
- }
-
- /**
- * Builds an AST Tree to dereference an array.
- *
- * @param array the array to dereference
- * @param index the index at which to dereference
- * @return a Tree representing the dereference
- */
- public ArrayAccessTree buildArrayAccess(ExpressionTree array, ExpressionTree index) {
- ArrayType arrayType = (ArrayType) InternalUtils.typeOf(array);
- JCTree.JCArrayAccess access =
- maker.Indexed((JCTree.JCExpression) array, (JCTree.JCExpression) index);
- access.setType((Type) arrayType.getComponentType());
- return access;
- }
-
- /**
- * Builds an AST Tree to refer to a class name.
- *
- * @param elt an element representing the class
- * @return an IdentifierTree referring to the class
- */
- public IdentifierTree buildClassUse(Element elt) {
- return maker.Ident((Symbol) elt);
- }
-
- /**
- * Builds an AST Tree to access the valueOf() method of boxed type such as Short or Float.
- *
- * @param expr an expression whose type is a boxed type
- * @return a MemberSelectTree that accesses the valueOf() method of the expression
- */
- public MemberSelectTree buildValueOfMethodAccess(Tree expr) {
- TypeMirror boxedType = InternalUtils.typeOf(expr);
-
- assert TypesUtils.isBoxedPrimitive(boxedType);
-
- // Find the valueOf(unboxedType) method of the boxed type
- Symbol.MethodSymbol valueOfMethod = getValueOfMethod(env, boxedType);
-
- Type.MethodType methodType = (Type.MethodType) valueOfMethod.asType();
-
- JCTree.JCFieldAccess valueOfAccess =
- (JCTree.JCFieldAccess) maker.Select((JCTree.JCExpression) expr, valueOfMethod);
- valueOfAccess.setType(methodType);
-
- return valueOfAccess;
- }
-
- /** Returns the valueOf method of a boxed type such as Short or Float. */
- public static Symbol.MethodSymbol getValueOfMethod(
- ProcessingEnvironment env, TypeMirror boxedType) {
- Symbol.MethodSymbol valueOfMethod = null;
-
- TypeMirror unboxedType = env.getTypeUtils().unboxedType(boxedType);
- TypeElement boxedElement = (TypeElement) ((DeclaredType) boxedType).asElement();
- for (ExecutableElement method :
- ElementFilter.methodsIn(env.getElementUtils().getAllMembers(boxedElement))) {
- Name methodName = method.getSimpleName();
-
- if (methodName.contentEquals("valueOf")) {
- List<? extends VariableElement> params = method.getParameters();
- if (params.size() == 1
- && env.getTypeUtils().isSameType(params.get(0).asType(), unboxedType)) {
- valueOfMethod = (Symbol.MethodSymbol) method;
- }
- }
- }
-
- assert valueOfMethod != null : "no valueOf method declared for boxed type";
- return valueOfMethod;
- }
-
- /**
- * Builds an AST Tree to access the *Value() method of a boxed type such as Short or Float,
- * where * is the corresponding primitive type (i.e. shortValue or floatValue).
- *
- * @param expr an expression whose type is a boxed type
- * @return a MemberSelectTree that accesses the *Value() method of the expression
- */
- public MemberSelectTree buildPrimValueMethodAccess(Tree expr) {
- TypeMirror boxedType = InternalUtils.typeOf(expr);
- TypeElement boxedElement = (TypeElement) ((DeclaredType) boxedType).asElement();
-
- assert TypesUtils.isBoxedPrimitive(boxedType);
- TypeMirror unboxedType = modelTypes.unboxedType(boxedType);
-
- // Find the *Value() method of the boxed type
- String primValueName = unboxedType.toString() + "Value";
- Symbol.MethodSymbol primValueMethod = null;
-
- for (ExecutableElement method :
- ElementFilter.methodsIn(elements.getAllMembers(boxedElement))) {
- Name methodName = method.getSimpleName();
-
- if (methodName.contentEquals(primValueName) && method.getParameters().size() == 0) {
- primValueMethod = (Symbol.MethodSymbol) method;
- }
- }
-
- assert primValueMethod != null : "no *Value method declared for boxed type";
-
- Type.MethodType methodType = (Type.MethodType) primValueMethod.asType();
-
- JCTree.JCFieldAccess primValueAccess =
- (JCTree.JCFieldAccess) maker.Select((JCTree.JCExpression) expr, primValueMethod);
- primValueAccess.setType(methodType);
-
- return primValueAccess;
- }
-
- /** Map public AST Tree.Kinds to internal javac JCTree.Tags. */
- public JCTree.Tag kindToTag(Tree.Kind kind) {
- switch (kind) {
- case AND:
- return JCTree.Tag.BITAND;
- case AND_ASSIGNMENT:
- return JCTree.Tag.BITAND_ASG;
- case ANNOTATION:
- return JCTree.Tag.ANNOTATION;
- case ANNOTATION_TYPE:
- return JCTree.Tag.TYPE_ANNOTATION;
- case ARRAY_ACCESS:
- return JCTree.Tag.INDEXED;
- case ARRAY_TYPE:
- return JCTree.Tag.TYPEARRAY;
- case ASSERT:
- return JCTree.Tag.ASSERT;
- case ASSIGNMENT:
- return JCTree.Tag.ASSIGN;
- case BITWISE_COMPLEMENT:
- return JCTree.Tag.COMPL;
- case BLOCK:
- return JCTree.Tag.BLOCK;
- case BREAK:
- return JCTree.Tag.BREAK;
- case CASE:
- return JCTree.Tag.CASE;
- case CATCH:
- return JCTree.Tag.CATCH;
- case CLASS:
- return JCTree.Tag.CLASSDEF;
- case CONDITIONAL_AND:
- return JCTree.Tag.AND;
- case CONDITIONAL_EXPRESSION:
- return JCTree.Tag.CONDEXPR;
- case CONDITIONAL_OR:
- return JCTree.Tag.OR;
- case CONTINUE:
- return JCTree.Tag.CONTINUE;
- case DIVIDE:
- return JCTree.Tag.DIV;
- case DIVIDE_ASSIGNMENT:
- return JCTree.Tag.DIV_ASG;
- case DO_WHILE_LOOP:
- return JCTree.Tag.DOLOOP;
- case ENHANCED_FOR_LOOP:
- return JCTree.Tag.FOREACHLOOP;
- case EQUAL_TO:
- return JCTree.Tag.EQ;
- case EXPRESSION_STATEMENT:
- return JCTree.Tag.EXEC;
- case FOR_LOOP:
- return JCTree.Tag.FORLOOP;
- case GREATER_THAN:
- return JCTree.Tag.GT;
- case GREATER_THAN_EQUAL:
- return JCTree.Tag.GE;
- case IDENTIFIER:
- return JCTree.Tag.IDENT;
- case IF:
- return JCTree.Tag.IF;
- case IMPORT:
- return JCTree.Tag.IMPORT;
- case INSTANCE_OF:
- return JCTree.Tag.TYPETEST;
- case LABELED_STATEMENT:
- return JCTree.Tag.LABELLED;
- case LEFT_SHIFT:
- return JCTree.Tag.SL;
- case LEFT_SHIFT_ASSIGNMENT:
- return JCTree.Tag.SL_ASG;
- case LESS_THAN:
- return JCTree.Tag.LT;
- case LESS_THAN_EQUAL:
- return JCTree.Tag.LE;
- case LOGICAL_COMPLEMENT:
- return JCTree.Tag.NOT;
- case MEMBER_SELECT:
- return JCTree.Tag.SELECT;
- case METHOD:
- return JCTree.Tag.METHODDEF;
- case METHOD_INVOCATION:
- return JCTree.Tag.APPLY;
- case MINUS:
- return JCTree.Tag.MINUS;
- case MINUS_ASSIGNMENT:
- return JCTree.Tag.MINUS_ASG;
- case MODIFIERS:
- return JCTree.Tag.MODIFIERS;
- case MULTIPLY:
- return JCTree.Tag.MUL;
- case MULTIPLY_ASSIGNMENT:
- return JCTree.Tag.MUL_ASG;
- case NEW_ARRAY:
- return JCTree.Tag.NEWARRAY;
- case NEW_CLASS:
- return JCTree.Tag.NEWCLASS;
- case NOT_EQUAL_TO:
- return JCTree.Tag.NE;
- case OR:
- return JCTree.Tag.BITOR;
- case OR_ASSIGNMENT:
- return JCTree.Tag.BITOR_ASG;
- case PARENTHESIZED:
- return JCTree.Tag.PARENS;
- case PLUS:
- return JCTree.Tag.PLUS;
- case PLUS_ASSIGNMENT:
- return JCTree.Tag.PLUS_ASG;
- case POSTFIX_DECREMENT:
- return JCTree.Tag.POSTDEC;
- case POSTFIX_INCREMENT:
- return JCTree.Tag.POSTINC;
- case PREFIX_DECREMENT:
- return JCTree.Tag.PREDEC;
- case PREFIX_INCREMENT:
- return JCTree.Tag.PREINC;
- case REMAINDER:
- return JCTree.Tag.MOD;
- case REMAINDER_ASSIGNMENT:
- return JCTree.Tag.MOD_ASG;
- case RETURN:
- return JCTree.Tag.RETURN;
- case RIGHT_SHIFT:
- return JCTree.Tag.SR;
- case RIGHT_SHIFT_ASSIGNMENT:
- return JCTree.Tag.SR_ASG;
- case SWITCH:
- return JCTree.Tag.SWITCH;
- case SYNCHRONIZED:
- return JCTree.Tag.SYNCHRONIZED;
- case THROW:
- return JCTree.Tag.THROW;
- case TRY:
- return JCTree.Tag.TRY;
- case TYPE_CAST:
- return JCTree.Tag.TYPECAST;
- case TYPE_PARAMETER:
- return JCTree.Tag.TYPEPARAMETER;
- case UNARY_MINUS:
- return JCTree.Tag.NEG;
- case UNARY_PLUS:
- return JCTree.Tag.POS;
- case UNION_TYPE:
- return JCTree.Tag.TYPEUNION;
- case UNSIGNED_RIGHT_SHIFT:
- return JCTree.Tag.USR;
- case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT:
- return JCTree.Tag.USR_ASG;
- case VARIABLE:
- return JCTree.Tag.VARDEF;
- case WHILE_LOOP:
- return JCTree.Tag.WHILELOOP;
- case XOR:
- return JCTree.Tag.BITXOR;
- case XOR_ASSIGNMENT:
- return JCTree.Tag.BITXOR_ASG;
- default:
- return JCTree.Tag.NO_TAG;
- }
- }
-
- /**
- * Builds an AST Tree to perform a binary operation.
- *
- * @param type result type of the operation
- * @param op AST Tree operator
- * @param left the left operand tree
- * @param right the right operand tree
- * @return a Tree representing "left &lt; right"
- */
- public BinaryTree buildBinary(
- TypeMirror type, Tree.Kind op, ExpressionTree left, ExpressionTree right) {
- JCTree.Tag jcOp = kindToTag(op);
- JCTree.JCBinary binary =
- maker.Binary(jcOp, (JCTree.JCExpression) left, (JCTree.JCExpression) right);
- binary.setType((Type) type);
- return binary;
- }
-}
diff --git a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeParser.java b/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeParser.java
deleted file mode 100644
index 9ea545e55c..0000000000
--- a/third_party/checker_framework_javacutil/java/org/checkerframework/javacutil/trees/TreeParser.java
+++ /dev/null
@@ -1,141 +0,0 @@
-package org.checkerframework.javacutil.trees;
-
-import com.sun.source.tree.ExpressionTree;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.tree.JCTree.JCExpression;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.Context;
-import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Names;
-import java.util.StringTokenizer;
-import javax.annotation.processing.ProcessingEnvironment;
-
-/**
- * A Utility class for parsing Java expression snippets, and converting them to proper Javac AST
- * nodes.
- *
- * <p>This is useful for parsing {@code EnsuresNonNull*}, and {@code KeyFor} values.
- *
- * <p>Currently, it handles four tree types only:
- *
- * <ul>
- * <li>Identifier tree (e.g. {@code id})
- * <li>Literal tree (e.g. 2, 3)
- * <li>Method invocation tree (e.g. {@code method(2, 3)})
- * <li>Member select tree (e.g. {@code Class.field}, {@code instance.method()})
- * <li>Array access tree (e.g. {@code array[id]})
- * </ul>
- *
- * Notable limitation: Doesn't handle spaces, or non-method-argument parenthesis.
- *
- * <p>It's implemented via a Recursive-Descend parser.
- */
-public class TreeParser {
- private static final String DELIMS = ".[](),";
- private static final String SENTINAL = "";
-
- private final TreeMaker maker;
- private final Names names;
-
- public TreeParser(ProcessingEnvironment env) {
- Context context = ((JavacProcessingEnvironment) env).getContext();
- maker = TreeMaker.instance(context);
- names = Names.instance(context);
- }
-
- /**
- * Parses the snippet in the string as an internal Javac AST expression node
- *
- * @param s the java snippet
- * @return the AST corresponding to the snippet
- */
- public ExpressionTree parseTree(String s) {
- tokenizer = new StringTokenizer(s, DELIMS, true);
- token = tokenizer.nextToken();
-
- try {
- return parseExpression();
- } catch (Exception e) {
- throw new ParseError(e);
- } finally {
- tokenizer = null;
- token = null;
- }
- }
-
- StringTokenizer tokenizer = null;
- String token = null;
-
- private String nextToken() {
- token = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : SENTINAL;
- return token;
- }
-
- JCExpression fromToken(String token) {
- // Optimization
- if ("true".equals(token)) {
- return maker.Literal(true);
- } else if ("false".equals(token)) {
- return maker.Literal(false);
- }
-
- if (Character.isLetter(token.charAt(0))) {
- return maker.Ident(names.fromString(token));
- }
-
- Object value = null;
- try {
- value = Integer.valueOf(token);
- } catch (Exception e2) {
- try {
- value = Double.valueOf(token);
- } catch (Exception ef) {
- }
- }
- assert value != null;
- return maker.Literal(value);
- }
-
- JCExpression parseExpression() {
- JCExpression tree = fromToken(token);
-
- while (tokenizer.hasMoreTokens()) {
- String delim = nextToken();
- if (".".equals(delim)) {
- nextToken();
- tree = maker.Select(tree, names.fromString(token));
- } else if ("(".equals(delim)) {
- nextToken();
- ListBuffer<JCExpression> args = new ListBuffer<>();
- while (!")".equals(token)) {
- JCExpression arg = parseExpression();
- args.append(arg);
- if (",".equals(token)) {
- nextToken();
- }
- }
- // For now, handle empty args only
- assert ")".equals(token);
- tree = maker.Apply(List.<JCExpression>nil(), tree, args.toList());
- } else if ("[".equals(token)) {
- nextToken();
- JCExpression index = parseExpression();
- assert "]".equals(token);
- tree = maker.Indexed(tree, index);
- } else {
- return tree;
- }
- }
-
- return tree;
- }
-
- private static class ParseError extends RuntimeException {
- private static final long serialVersionUID = 1887754619522101929L;
-
- ParseError(Throwable cause) {
- super(cause);
- }
- }
-}
diff --git a/third_party/checker_framework_javacutil/javacutil-2.4.0-sources.jar b/third_party/checker_framework_javacutil/javacutil-2.4.0-sources.jar
new file mode 100644
index 0000000000..59f143b271
--- /dev/null
+++ b/third_party/checker_framework_javacutil/javacutil-2.4.0-sources.jar
Binary files differ
diff --git a/third_party/checker_framework_javacutil/javacutil-2.4.0.jar b/third_party/checker_framework_javacutil/javacutil-2.4.0.jar
new file mode 100644
index 0000000000..7837305f82
--- /dev/null
+++ b/third_party/checker_framework_javacutil/javacutil-2.4.0.jar
Binary files differ