package net.ptnkjke.jbeditor.logic.bcel;
import net.ptnkjke.jbeditor.Configutation;
import net.ptnkjke.jbeditor.gui.main.model.ConsoleMessage;
import net.ptnkjke.jbeditor.gui.main.model.MessageType;
import net.ptnkjke.jbeditor.logic.bcel.bytecode.InstructionHandleWorker;
import net.ptnkjke.jbeditor.utils.Utils;
import org.apache.bcel.classfile.Constant;
import org.apache.bcel.generic.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
/**
* Created by Lopatin on 05.07.2014.
*/
public class GraphVizCreator extends InstructionHandleWorker {
private int lastCounter = 0;
StringBuilder sb = new StringBuilder();
InstructionList list;
ConstantPoolGen cpg;
public GraphVizCreator(InstructionList list, ConstantPoolGen cpg) {
this.list = list;
this.cpg = cpg;
}
private void visitBase(InstructionHandle instructionHandle) {
InstructionHandle nextHandle = instructionHandle.getNext();
sb.append(String.format("%d[label=\"%s\"];\n", instructionHandle.getPosition(), instructionHandle.toString()));
if (nextHandle != null) {
sb.append(String.format("%d -> %d[label=\"next\", color=\"#839096\"];\n", instructionHandle.getPosition(), nextHandle.getPosition()));
} else {
System.out.println("next == null");
}
}
private void visitBranchInstruction(InstructionHandle instructionHandle) {
InstructionHandle nextHandle = instructionHandle.getNext();
Instruction instruction = instructionHandle.getInstruction();
BranchInstruction branchInstruction = (BranchInstruction) instruction;
InstructionHandle target = branchInstruction.getTarget();
sb.append(String.format("%d[shape=diamond,label=\"%s\"];\n", instructionHandle.getPosition(), instructionHandle.toString()));
if (nextHandle != null) {
sb.append(String.format("%d -> %d[label=\"next\", color=\"#839096\"];\n", instructionHandle.getPosition(), nextHandle.getPosition()));
}
if (target != null) {
sb.append(String.format("%d -> %d[label=\"target\"];\n", instructionHandle.getPosition(), target.getPosition()));
}
}
private void visitSelect(InstructionHandle instructionHandle) {
InstructionHandle nextHandle = instructionHandle.getNext();
Select select = (Select) instructionHandle.getInstruction();
InstructionHandle[] targets = select.getTargets();
sb.append(String.format("%d[label=\"%s\"];\n", instructionHandle.getPosition(), instructionHandle.toString()));
if (nextHandle != null) {
sb.append(String.format("%d -> %d[label=\"next\", color=\"#839096\"];\n", instructionHandle.getPosition(), nextHandle.getPosition()));
}
InstructionHandle target = select.getTarget();
if (target != null) {
sb.append(String.format("%d -> %d [label=\"default\"];\n", instructionHandle.getPosition(), target.getPosition()));
}
int i = 0;
for (InstructionHandle h : targets) {
sb.append(String.format("%d -> %d [label=\"match%d\"];\n", instructionHandle.getPosition(), h.getPosition(), i));
i++;
}
}
public String getText() {
return sb.toString();
}
public void visitAll() {
lastCounter = 0;
sb = new StringBuilder();
visit(list.getStart());
}
public File getImage() {
visitAll();
File workDir = new File(Configutation.workDir);
if (!workDir.exists()) {
workDir.mkdirs();
}
String nameRandom = Utils.getRandomName();
File temp = new File(workDir, nameRandom + ".txt");
String path = Configutation.workDir + File.separator + nameRandom + ".txt";
String out = Configutation.workDir + File.separator + nameRandom + ".svg";
File outFile = new File(out);
File inFile = new File(path);
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(temp));
writer.write(sb.toString());
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
if (outFile.exists()) {
System.out.println("exists");
if (outFile.delete()) {
System.out.println("deleted");
}
}
if (!new File(Configutation.graphVizPath).exists()) {
return null;
}
String command = String.format("%s -Tsvg -o%s %s", Configutation.graphVizPath, outFile.getAbsolutePath(), inFile.getAbsolutePath());
try {
Runtime.getRuntime().exec(command);
} catch (IOException e1) {
e1.printStackTrace();
}
int counter = 0;
while (!outFile.canWrite() && !outFile.exists() && counter != 2000) {
try {
System.out.println("i waiting");
Thread.sleep(100);
counter++;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return outFile;
}
@Override
public void visit(InstructionHandle handle) {
sb.append("digraph g{");
sb.append("node [fontsize=8, shape = box];\nedge [fontsize=8]");
do {
try {
super.visit(handle);
} catch (Exception e) {
ConsoleMessage consoleMessage = new ConsoleMessage(
e.getClass().getName() + " " + e.getMessage(),
MessageType.CRITICAL,
"not_yet_info",
e);
e.printStackTrace();
}
handle = handle.getNext();
}
while (handle != null);
sb.append("}");
}
@Override
public void visitDADD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDDIV(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDMUL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDNEG(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDREM(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDSUB(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFADD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFDIV(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFMUL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFNEG(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFREM(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFSUB(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIADD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIAND(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIDIV(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIMUL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitINEG(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIOR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIREM(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitISHL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitISHR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitISUB(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIUSHR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIXOR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLADD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLAND(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLDIV(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLMUL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLNEG(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLOR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLREM(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLSHL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLSHR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLSUB(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLUSHR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLXOR(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitAALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitAASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitBALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitBASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitCALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitCASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitSALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitSASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitGOTO(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitGOTO_W(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIF_ACMPEQ(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIF_ACMPNE(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIF_ICMPEQ(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIF_ICMPGT(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIF_ICMPGE(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIF_ICMPLE(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIF_ICMPLT(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIF_ICMPNE(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFEQ(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFGE(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFGT(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFLE(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFLT(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFNE(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFNONNULL(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitIFNULL(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitJSR(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitJSR_W(InstructionHandle instructionHandle) {
visitBranchInstruction(instructionHandle);
}
@Override
public void visitLOOKUPSWITCH(InstructionHandle instructionHandle) {
visitSelect(instructionHandle);
}
@Override
public void visitTABLESWITCH(InstructionHandle instructionHandle) {
visitSelect(instructionHandle);
}
@Override
public void visitD2F(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitD2I(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitD2L(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitF2D(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitF2I(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitF2L(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitI2B(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitI2C(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitI2D(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitI2F(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitI2L(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitI2S(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitL2D(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitL2F(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitL2I(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitANEWARRAY(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitCHECKCAST(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitINSTANCEOF(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLDC(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLDC2_W(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitMULTIANEWARRAY(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitGETFIELD(InstructionHandle handle) {
visitBase(handle);
}
@Override
public void visitGETSTATIC(InstructionHandle handle) {
CPInstruction cpInstruction = (CPInstruction) handle.getInstruction();
Constant constant = cpg.getConstant(cpInstruction.getIndex());
InstructionHandle nextHandle = handle.getNext();
String text = handle.toString() + constant.toString();
sb.append(String.format("%d[label=\"%s\"];\n", handle.getPosition(), text));
if (nextHandle != null) {
sb.append(String.format("%d -> %d[label=\"next\"];\n", handle.getPosition(), nextHandle.getPosition()));
} else {
System.out.println("next == null");
}
}
@Override
public void visitINVOKEINTERFACE(InstructionHandle handle) {
visitBase(handle);
}
@Override
public void visitINVOKESPECIAL(InstructionHandle handle) {
visitBase(handle);
}
@Override
public void visitINVOKESTATIC(InstructionHandle handle) {
visitBase(handle);
}
@Override
public void visitINVOKEVIRTUAL(InstructionHandle handle) {
visitBase(handle);
}
@Override
public void visitPUTFIELD(InstructionHandle handle) {
visitBase(handle);
}
@Override
public void visitPUTSTATIC(InstructionHandle handle) {
visitBase(handle);
}
@Override
public void visitINVOKEDYNAMIC(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitNEW(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitALOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDLOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFLOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLLOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitILOAD(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitASTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDSTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFSTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitISTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLSTORE(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIINC(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitARETURN(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDRETURN(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFRETURN(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIRETURN(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLRETURN(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitRETURN(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDUP(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDUP2(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDUP_X1(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDUP_X2(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDUP2_X1(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDUP2_X2(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitPOP(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitPOP2(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitSWAP(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitACONST_NULL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitARRAYLENGTH(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitATHROW(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitBREAKPOINT(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDCMPG(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitDCONST(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFCMPG(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFCMPL(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitFCONST(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitICONST(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIMPDEP1(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitIMPDEP2(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLCMP(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitLCONST(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitMONITORENTER(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitMONITOREXIT(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitNEWARRAY(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitNOP(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitRET(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitSIPUSH(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
@Override
public void visitBIPUSH(InstructionHandle instructionHandle) {
visitBase(instructionHandle);
}
}