org.checkerframework.dataflow.cfg.visualize.StringCFGVisualizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of checker Show documentation
Show all versions of checker Show documentation
The Checker Framework enhances Java's type system to
make it more powerful and useful. This lets software developers
detect and prevent errors in their Java programs.
The Checker Framework includes compiler plug-ins ("checkers")
that find bugs or verify their absence. It also permits you to
write your own compiler plug-ins.
The newest version!
package org.checkerframework.dataflow.cfg.visualize;
import org.checkerframework.checker.nullness.qual.KeyFor;
import org.checkerframework.checker.nullness.qual.Nullable;
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.dataflow.cfg.ControlFlowGraph;
import org.checkerframework.dataflow.cfg.block.Block;
import org.checkerframework.dataflow.cfg.block.ConditionalBlock;
import org.checkerframework.dataflow.cfg.block.SpecialBlock;
import org.checkerframework.dataflow.cfg.visualize.AbstractCFGVisualizer.VisualizeWhere;
import org.checkerframework.dataflow.expression.ArrayAccess;
import org.checkerframework.dataflow.expression.ClassName;
import org.checkerframework.dataflow.expression.FieldAccess;
import org.checkerframework.dataflow.expression.LocalVariable;
import org.checkerframework.dataflow.expression.MethodCall;
import java.io.PrintStream;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
/** Generate the String representation of a control flow graph. */
public class StringCFGVisualizer<
V extends AbstractValue, S extends Store, T extends TransferFunction>
extends AbstractCFGVisualizer {
/** Stream to output String representation to. */
protected PrintStream out;
/** Create a StringCFGVisualizer. */
public StringCFGVisualizer() {
out = System.out;
}
@Override
public void init(Map args) {
super.init(args);
PrintStream argout = (PrintStream) args.get("output");
if (argout != null) {
out = argout;
}
}
@Override
public String getSeparator() {
return "\n";
}
@Override
public Map visualize(
ControlFlowGraph cfg, Block entry, @Nullable Analysis analysis) {
String stringGraph = visualizeGraph(cfg, entry, analysis);
return Collections.singletonMap("stringGraph", stringGraph);
}
@Override
public Map visualizeWithAction(
ControlFlowGraph cfg, Block entry, @Nullable Analysis analysis) {
Map vis = visualize(cfg, entry, analysis);
String stringGraph = (String) vis.get("stringGraph");
out.println(stringGraph);
return vis;
}
@SuppressWarnings("keyfor:enhancedfor.type.incompatible")
@Override
public String visualizeNodes(
Set blocks, ControlFlowGraph cfg, @Nullable Analysis analysis) {
StringJoiner sjStringNodes = new StringJoiner(lineSeparator);
IdentityHashMap> processOrder = getProcessOrder(cfg);
// Generate all the Nodes.
for (@KeyFor("processOrder") Block v : blocks) {
sjStringNodes.add(v.getUid() + ":");
if (verbose) {
sjStringNodes.add(getProcessOrderSimpleString(processOrder.get(v)));
}
sjStringNodes.add(visualizeBlock(v, analysis));
sjStringNodes.add("");
}
return sjStringNodes.toString().trim();
}
@Override
protected String visualizeEdge(Object sId, Object eId, String flowRule) {
if (this.verbose) {
return sId + " -> " + eId + " " + flowRule;
}
return sId + " -> " + eId;
}
@Override
public String visualizeBlock(Block bb, @Nullable Analysis analysis) {
return super.visualizeBlockHelper(bb, analysis, lineSeparator).trim();
}
@Override
public String visualizeSpecialBlock(SpecialBlock sbb) {
return super.visualizeSpecialBlockHelper(sbb);
}
@Override
public String visualizeConditionalBlock(ConditionalBlock cbb) {
return "ConditionalBlock: then: "
+ cbb.getThenSuccessor().getUid()
+ ", else: "
+ cbb.getElseSuccessor().getUid();
}
@Override
public String visualizeBlockTransferInputBefore(Block bb, Analysis analysis) {
return super.visualizeBlockTransferInputHelper(
VisualizeWhere.BEFORE, bb, analysis, lineSeparator);
}
@Override
public String visualizeBlockTransferInputAfter(Block bb, Analysis analysis) {
return super.visualizeBlockTransferInputHelper(
VisualizeWhere.AFTER, bb, analysis, lineSeparator);
}
@Override
protected String format(Object obj) {
return obj.toString();
}
@Override
public String visualizeStoreThisVal(V value) {
return storeEntryIndent + "this > " + value;
}
@Override
public String visualizeStoreLocalVar(LocalVariable localVar, V value) {
return storeEntryIndent + localVar + " > " + value;
}
@Override
public String visualizeStoreFieldVal(FieldAccess fieldAccess, V value) {
return storeEntryIndent + fieldAccess + " > " + value;
}
@Override
public String visualizeStoreArrayVal(ArrayAccess arrayValue, V value) {
return storeEntryIndent + arrayValue + " > " + value;
}
@Override
public String visualizeStoreMethodVals(MethodCall methodCall, V value) {
return storeEntryIndent + methodCall + " > " + value;
}
@Override
public String visualizeStoreClassVals(ClassName className, V value) {
return storeEntryIndent + className + " > " + value;
}
@Override
public String visualizeStoreKeyVal(String keyName, Object value) {
return storeEntryIndent + keyName + " = " + value;
}
/**
* {@inheritDoc}
*
* StringCFGVisualizer does not write into file, so left intentionally blank.
*/
@Override
public void shutdown() {}
/**
* {@inheritDoc}
*
*
StringCFGVisualizer does not need a specific header, so just return an empty string.
*/
@Override
protected String visualizeGraphHeader() {
return "";
}
/**
* {@inheritDoc}
*
*
StringCFGVisualizer does not need a specific footer, so just return an empty string.
*/
@Override
protected String visualizeGraphFooter() {
return "";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy