blob: 8cf1399ea0141d267d4f22443d2d2fb9b73fff83 [file] [log] [blame]
package org.checkerframework.dataflow.cfg.builder;
import com.sun.source.tree.ClassTree;
import com.sun.source.tree.LambdaExpressionTree;
import com.sun.source.tree.Tree;
import com.sun.source.tree.UnaryTree;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import org.checkerframework.dataflow.cfg.UnderlyingAST;
import org.checkerframework.dataflow.cfg.builder.ExtendedNode.ExtendedNodeType;
import org.checkerframework.dataflow.cfg.node.AssignmentNode;
import org.checkerframework.dataflow.cfg.node.Node;
import org.checkerframework.dataflow.cfg.node.ReturnNode;
/* --------------------------------------------------------- */
/* Phase One */
/* --------------------------------------------------------- */
/**
* A wrapper object to pass around the result of phase one. For a documentation of the fields see
* {@link CFGTranslationPhaseOne}.
*/
public class PhaseOneResult {
final IdentityHashMap<Tree, Set<Node>> treeLookupMap;
final IdentityHashMap<Tree, Set<Node>> convertedTreeLookupMap;
final IdentityHashMap<UnaryTree, AssignmentNode> unaryAssignNodeLookupMap;
final UnderlyingAST underlyingAST;
final Map<Label, Integer> bindings;
final ArrayList<ExtendedNode> nodeList;
final Set<Integer> leaders;
final List<ReturnNode> returnNodes;
final Label regularExitLabel;
final Label exceptionalExitLabel;
final List<ClassTree> declaredClasses;
final List<LambdaExpressionTree> declaredLambdas;
public PhaseOneResult(
UnderlyingAST underlyingAST,
IdentityHashMap<Tree, Set<Node>> treeLookupMap,
IdentityHashMap<Tree, Set<Node>> convertedTreeLookupMap,
IdentityHashMap<UnaryTree, AssignmentNode> unaryAssignNodeLookupMap,
ArrayList<ExtendedNode> nodeList,
Map<Label, Integer> bindings,
Set<Integer> leaders,
List<ReturnNode> returnNodes,
Label regularExitLabel,
Label exceptionalExitLabel,
List<ClassTree> declaredClasses,
List<LambdaExpressionTree> declaredLambdas) {
this.underlyingAST = underlyingAST;
this.treeLookupMap = treeLookupMap;
this.convertedTreeLookupMap = convertedTreeLookupMap;
this.unaryAssignNodeLookupMap = unaryAssignNodeLookupMap;
this.nodeList = nodeList;
this.bindings = bindings;
this.leaders = leaders;
this.returnNodes = returnNodes;
this.regularExitLabel = regularExitLabel;
this.exceptionalExitLabel = exceptionalExitLabel;
this.declaredClasses = declaredClasses;
this.declaredLambdas = declaredLambdas;
}
@Override
public String toString() {
StringJoiner sj = new StringJoiner(System.lineSeparator());
for (ExtendedNode n : nodeList) {
sj.add(nodeToString(n));
}
return sj.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 "unbound label: " + label;
}
return nodeToString(nodeList.get(index));
}
/**
* Returns a representation of a map, one entry per line.
*
* @param <K> the key type of the map
* @param <V> the value type of the map
* @param map a map
* @return a representation of a map, one entry per line
*/
private <K, V> String mapToString(Map<K, V> map) {
if (map.isEmpty()) {
return "{}";
}
StringJoiner result =
new StringJoiner(
String.format("%n "), String.format("{%n "), String.format("%n }"));
for (Map.Entry<K, V> entry : map.entrySet()) {
result.add(entry.getKey() + " => " + entry.getValue());
}
return result.toString();
}
/**
* Returns a verbose string representation of this, useful for debugging.
*
* @return a string representation of this
*/
public String toStringDebug() {
StringJoiner result =
new StringJoiner(
String.format("%n "), String.format("PhaseOneResult{%n "), String.format("%n }"));
result.add("treeLookupMap=" + mapToString(treeLookupMap));
result.add("convertedTreeLookupMap=" + mapToString(convertedTreeLookupMap));
result.add("unaryAssignNodeLookupMap=" + mapToString(unaryAssignNodeLookupMap));
result.add("underlyingAST=" + underlyingAST);
result.add("bindings=" + bindings);
result.add("nodeList=" + CFGBuilder.extendedNodeCollectionToStringDebug(nodeList));
result.add("leaders=" + leaders);
result.add("returnNodes=" + Node.nodeCollectionToString(returnNodes));
result.add("regularExitLabel=" + regularExitLabel);
result.add("exceptionalExitLabel=" + exceptionalExitLabel);
result.add("declaredClasses=" + declaredClasses);
result.add("declaredLambdas=" + declaredLambdas);
return result.toString();
}
}