Loading src/main/java/tfm/graphs/PDGGraph.java +15 −13 Original line number Diff line number Diff line Loading @@ -6,11 +6,13 @@ import edg.graphlib.Arrow; import tfm.arcs.Arc; import tfm.arcs.pdg.ControlDependencyArc; import tfm.arcs.pdg.DataDependencyArc; import tfm.nodes.CFGNode; import tfm.nodes.Node; import tfm.nodes.PDGNode; import tfm.slicing.SlicingCriterion; import tfm.utils.Logger; import tfm.utils.NodeNotFoundException; import tfm.utils.Utils; import tfm.visitors.PDGCFGVisitor; import java.util.Comparator; Loading Loading @@ -152,9 +154,21 @@ public class PDGGraph extends Graph<PDGNode> { PDGNode node = optionalPDGNode.get(); // Find CFGNode and find last definition of variable CFGNode cfgNode = this.cfgGraph.findNodeByASTNode(node.getAstNode()) .orElseThrow(() -> new NodeNotFoundException("CFGNode not found")); Set<CFGNode> definitionNodes = Utils.findLastDefinitionsFrom(cfgNode, slicingCriterion.getVariable()); Logger.format("Slicing node: %s", node); Set<Integer> sliceNodes = getSliceNodes(new HashSet<>(), node); Set<Integer> sliceNodes = definitionNodes.stream() .flatMap(definitionNode -> getSliceNodes(new HashSet<>(), this.findNodeByASTNode(definitionNode.getAstNode()).get()).stream()) .collect(Collectors.toSet()); sliceNodes.add(node.getId()); // Set<Integer> sliceNodes = getSliceNodes(new HashSet<>(), node); PDGGraph sliceGraph = new PDGGraph(); Loading Loading @@ -193,30 +207,18 @@ public class PDGGraph extends Graph<PDGNode> { private Set<Integer> getSliceNodes(Set<Integer> visited, PDGNode root) { visited.add(root.getId()); // Set<String> searchVariables = new HashSet<>(variables); for (Arrow arrow : root.getIncomingArrows()) { Arc arc = (Arc) arrow; // if (arc.isDataDependencyArrow() // && Collections.disjoint(((DataDependencyArc) arc).getData().getVariables(), searchVariables)) { // continue; // } PDGNode from = (PDGNode) arc.getFromNode(); // Logger.log("Arrow from node: " + from); if (visited.contains(from.getId())) { // Logger.log("It's already visited. Continuing..."); continue; } getSliceNodes(visited, from); } // Logger.format("Done with node %s", root.getId()); return visited; } Loading src/main/java/tfm/slicing/Slice.java +2 −44 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ import java.io.IOException; public class Slice { public static final String PROGRAM_FOLDER = Utils.PROGRAMS_FOLDER + "pdg/"; public static final String PROGRAM_NAME = "Example3"; public static final String PROGRAM_NAME = "Example2"; public static void main(String[] args) throws IOException { CompilationUnit compilationUnit = JavaParser.parse(new File(PROGRAM_FOLDER + PROGRAM_NAME + ".java")); Loading @@ -28,48 +28,7 @@ public class Slice { Logger.log("= Starting slice ="); Logger.log("=================="); PDGGraph sliced = pdgGraph.slice(new LineNumberCriterion(21, "sum")); // for (PDGNode node : slice) { // sliced.addNode(new PDGNode(node.getId(), node.getData(), node.getAstNode())); // } // // for (Arc arc : pdgGraph.getArcs()) { // // Optional<PDGNode> fromOptional = sliced.findNodeById(arc.getFromNode().getId()); // Optional<PDGNode> toOptional = sliced.findNodeById(arc.getToNode().getId()); // // if (fromOptional.isPresent() && toOptional.isPresent()) { // PDGNode from = fromOptional.get(); // PDGNode to = toOptional.get(); // // if (arc.isControlDependencyArrow()) { // sliced.addControlDependencyArc(from, to); // } else { // DataDependencyArc dataDependencyArc = (DataDependencyArc) arc; // sliced.addDataDependencyArc(from, to, dataDependencyArc.getData().getVariables().get(0)); // } // } // Logger.log(arc); // Logger.log("Must add? " + (sliceIds.contains(arc.getFromNode().getId()) && sliceIds.contains(arc.getToNode().getId()))); // // if (sliceIds.contains(arc.getFromNode().getId()) && sliceIds.contains(arc.getToNode().getId())) { // Logger.format("Added? %s", sliced.addEdge(arc)); // } // } // Set<Arc> arcs = pdgGraph.getArcs().stream() // .filter(arc -> sliced.getNodes().contains(arc.getFrom()) || sliced.getNodes().contains(arc.getTo())) // .collect(Collectors.toSet()); //// .forEach(sliced::addEdge); // // arcs.forEach(sliced::addEdge); // Logger.log("==== Arcs ===="); // sliced.getArcs().forEach(Logger::log); // Logger.log(sliced.getArcs().stream().map(Arc::toString).collect(Collectors.joining(System.lineSeparator()))); PDGGraph sliced = pdgGraph.slice(new LineNumberCriterion(18, "x")); PDGLog pdgLog = new PDGLog(sliced); pdgLog.log(); Loading @@ -77,6 +36,5 @@ public class Slice { pdgLog.openVisualRepresentation(); PDGValidator.printPDGProgram("Slice" + PROGRAM_NAME, sliced); PDGValidator.printPDGProgram("Generated" + PROGRAM_NAME, pdgGraph); } } src/main/java/tfm/utils/NodeNotFoundException.java +4 −0 Original line number Diff line number Diff line Loading @@ -7,4 +7,8 @@ public class NodeNotFoundException extends RuntimeException { public NodeNotFoundException(SlicingCriterion slicingCriterion) { super("Node not found for slicing criterion: " + slicingCriterion); } public NodeNotFoundException(String message) { super(message); } } src/main/java/tfm/utils/Utils.java +46 −4 Original line number Diff line number Diff line Loading @@ -4,11 +4,12 @@ import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.EmptyStmt; import com.github.javaparser.ast.stmt.Statement; import edg.graphlib.Arrow; import tfm.arcs.cfg.ControlFlowArc; import tfm.graphs.CFGGraph; import tfm.nodes.CFGNode; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.*; import java.util.function.Predicate; public class Utils { Loading Loading @@ -48,4 +49,45 @@ public class Utils { public static <E> Set<E> emptySet() { return new HashSet<>(0); } public static Set<CFGNode> findLastDefinitionsFrom(CFGNode startNode, String variable) { // Logger.log("======================================================="); // Logger.log("Starting from " + startNode); // Logger.log("Looking for variable " + variable); // Logger.log(cfgGraph.toString()); return findLastDefinitionsFrom(new HashSet<>(), startNode, startNode, variable); } private static Set<CFGNode> findLastDefinitionsFrom(Set<Integer> visited, CFGNode startNode, CFGNode currentNode, String variable) { visited.add(currentNode.getId()); // Logger.log("On " + currentNode); Set<CFGNode> res = new HashSet<>(); for (Arrow arrow : currentNode.getIncomingArrows()) { ControlFlowArc controlFlowArc = (ControlFlowArc) arrow; CFGNode from = (CFGNode) controlFlowArc.getFromNode(); // Logger.log("Arrow from node: " + from); if (!Objects.equals(startNode, from) && visited.contains(from.getId())) { // Logger.log("It's already visited. Continuing..."); continue; } if (from.getDefinedVariables().contains(variable)) { // Logger.log("Contains defined variable: " + variable); res.add(from); } else { // Logger.log("Doesn't contain the variable, searching inside it"); res.addAll(findLastDefinitionsFrom(visited, startNode, from, variable)); } } // Logger.format("Done with node %s", currentNode.getId()); return res; } } src/main/java/tfm/validation/PDGValidator.java +68 −25 Original line number Diff line number Diff line Loading @@ -10,70 +10,113 @@ import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.type.ArrayType; import com.github.javaparser.ast.type.VoidType; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import tfm.graphs.PDGGraph; import tfm.nodes.Node; import tfm.utils.Logger; import tfm.utils.Utils; import tfm.visitors.PDGCFGVisitor; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.Arrays; import java.util.Comparator; import java.util.Objects; import java.util.Optional; public class PDGValidator { private static final String PROGRAM_FOLDER = Utils.PROGRAMS_FOLDER + "pdg"; private static final String PROGRAM_NAME = "Example2"; private static final String METHOD_NAME = "main"; public static void main(String[] args) throws FileNotFoundException { JavaParser.getStaticConfiguration().setAttributeComments(false); CompilationUnit originalProgram = JavaParser.parse(new File(String.format("%s/%s.java", PROGRAM_FOLDER, PROGRAM_NAME))); if (METHOD_NAME.isEmpty()) { originalProgram.accept(new VoidVisitorAdapter<Void>() { @Override public void visit(MethodDeclaration n, Void arg) { Logger.format("On method: %s. Generating and comparing...", n.getNameAsString()); boolean check = generateAndCheck(n); Logger.format("Result: %s", check ? "equal" : "not equal"); } }, null); } else { Optional<MethodDeclaration> optionalTarget = originalProgram.findFirst(MethodDeclaration.class, methodDeclaration -> Objects.equals(methodDeclaration.getNameAsString(), METHOD_NAME)); if (!optionalTarget.isPresent()) { throw new RuntimeException(String.format("Method '%s' not found", METHOD_NAME)); } Logger.format("On method: %s. Generating and comparing...", METHOD_NAME); boolean check = generateAndCheck(optionalTarget.get()); Logger.format("Result: %s", check ? "equal" : "not equal"); } } public static boolean generateAndCheck(MethodDeclaration methodDeclaration) { PDGGraph graph = new PDGGraph(); originalProgram.accept(new PDGCFGVisitor(graph), graph.getRootNode()); // graph.depthFirstSearch(graph.getRootNode(), new NodeVisitor<PDGNode>() { // @Override // public void visit(PDGNode node) { // if (node.equals(graph.getRootNode())) // return; // // Logger.log(node); // // methodBody.addStatement(node.get); // } // }); printPDGProgram("Generated" + PROGRAM_NAME, graph); methodDeclaration.accept(new PDGCFGVisitor(graph), graph.getRootNode()); return check(methodDeclaration, graph); } public static boolean check(MethodDeclaration methodDeclaration, PDGGraph graph) { MethodDeclaration generatedMethod = generateMethod(methodDeclaration, graph); return ProgramComparator.areEqual(methodDeclaration, generatedMethod); } public static MethodDeclaration generateMethod(MethodDeclaration info, PDGGraph graph) { MethodDeclaration methodDeclaration = new MethodDeclaration(); methodDeclaration.setName(info.getNameAsString()); methodDeclaration.setModifiers(info.getModifiers()); methodDeclaration.setType(info.getType()); methodDeclaration.setParameters(info.getParameters()); BlockStmt methodBody = new BlockStmt(); methodDeclaration.setBody(methodBody); graph.getNodesAtLevel(1).stream() .sorted(Comparator.comparingInt(Node::getId)) .forEach(node -> methodBody.addStatement(node.getAstNode())); return methodDeclaration; } public static void printPDGProgram(String fileName, PDGGraph graph) throws FileNotFoundException { CompilationUnit generatedProgram = new CompilationUnit(); ClassOrInterfaceDeclaration clazz = generatedProgram.addClass(fileName).setPublic(true); MethodDeclaration methodDeclaration = clazz.addMethod("main", Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC); methodDeclaration.setType(new VoidType()); MethodDeclaration info = new MethodDeclaration(); info.setModifiers(Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC); info.setType(new VoidType()); info.setName("main"); Parameter parameter = new Parameter( new ArrayType(JavaParser.parseClassOrInterfaceType("String")), "args" ); info.setParameters(new NodeList<>(parameter)); methodDeclaration.setParameters(new NodeList<>(Arrays.asList(parameter))); BlockStmt methodBody = new BlockStmt(); methodDeclaration.setBody(methodBody); MethodDeclaration generated = generateMethod(info, graph); graph.getNodesAtLevel(1).stream() .sorted(Comparator.comparingInt(Node::getId)) .forEach(node -> methodBody.addStatement(node.getAstNode())); clazz.addMember(generated); PrintWriter printWriter = new PrintWriter(new File(String.format("out/%s.java", fileName))); printWriter.print(clazz.toString()); printWriter.close(); } } Loading
src/main/java/tfm/graphs/PDGGraph.java +15 −13 Original line number Diff line number Diff line Loading @@ -6,11 +6,13 @@ import edg.graphlib.Arrow; import tfm.arcs.Arc; import tfm.arcs.pdg.ControlDependencyArc; import tfm.arcs.pdg.DataDependencyArc; import tfm.nodes.CFGNode; import tfm.nodes.Node; import tfm.nodes.PDGNode; import tfm.slicing.SlicingCriterion; import tfm.utils.Logger; import tfm.utils.NodeNotFoundException; import tfm.utils.Utils; import tfm.visitors.PDGCFGVisitor; import java.util.Comparator; Loading Loading @@ -152,9 +154,21 @@ public class PDGGraph extends Graph<PDGNode> { PDGNode node = optionalPDGNode.get(); // Find CFGNode and find last definition of variable CFGNode cfgNode = this.cfgGraph.findNodeByASTNode(node.getAstNode()) .orElseThrow(() -> new NodeNotFoundException("CFGNode not found")); Set<CFGNode> definitionNodes = Utils.findLastDefinitionsFrom(cfgNode, slicingCriterion.getVariable()); Logger.format("Slicing node: %s", node); Set<Integer> sliceNodes = getSliceNodes(new HashSet<>(), node); Set<Integer> sliceNodes = definitionNodes.stream() .flatMap(definitionNode -> getSliceNodes(new HashSet<>(), this.findNodeByASTNode(definitionNode.getAstNode()).get()).stream()) .collect(Collectors.toSet()); sliceNodes.add(node.getId()); // Set<Integer> sliceNodes = getSliceNodes(new HashSet<>(), node); PDGGraph sliceGraph = new PDGGraph(); Loading Loading @@ -193,30 +207,18 @@ public class PDGGraph extends Graph<PDGNode> { private Set<Integer> getSliceNodes(Set<Integer> visited, PDGNode root) { visited.add(root.getId()); // Set<String> searchVariables = new HashSet<>(variables); for (Arrow arrow : root.getIncomingArrows()) { Arc arc = (Arc) arrow; // if (arc.isDataDependencyArrow() // && Collections.disjoint(((DataDependencyArc) arc).getData().getVariables(), searchVariables)) { // continue; // } PDGNode from = (PDGNode) arc.getFromNode(); // Logger.log("Arrow from node: " + from); if (visited.contains(from.getId())) { // Logger.log("It's already visited. Continuing..."); continue; } getSliceNodes(visited, from); } // Logger.format("Done with node %s", root.getId()); return visited; } Loading
src/main/java/tfm/slicing/Slice.java +2 −44 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ import java.io.IOException; public class Slice { public static final String PROGRAM_FOLDER = Utils.PROGRAMS_FOLDER + "pdg/"; public static final String PROGRAM_NAME = "Example3"; public static final String PROGRAM_NAME = "Example2"; public static void main(String[] args) throws IOException { CompilationUnit compilationUnit = JavaParser.parse(new File(PROGRAM_FOLDER + PROGRAM_NAME + ".java")); Loading @@ -28,48 +28,7 @@ public class Slice { Logger.log("= Starting slice ="); Logger.log("=================="); PDGGraph sliced = pdgGraph.slice(new LineNumberCriterion(21, "sum")); // for (PDGNode node : slice) { // sliced.addNode(new PDGNode(node.getId(), node.getData(), node.getAstNode())); // } // // for (Arc arc : pdgGraph.getArcs()) { // // Optional<PDGNode> fromOptional = sliced.findNodeById(arc.getFromNode().getId()); // Optional<PDGNode> toOptional = sliced.findNodeById(arc.getToNode().getId()); // // if (fromOptional.isPresent() && toOptional.isPresent()) { // PDGNode from = fromOptional.get(); // PDGNode to = toOptional.get(); // // if (arc.isControlDependencyArrow()) { // sliced.addControlDependencyArc(from, to); // } else { // DataDependencyArc dataDependencyArc = (DataDependencyArc) arc; // sliced.addDataDependencyArc(from, to, dataDependencyArc.getData().getVariables().get(0)); // } // } // Logger.log(arc); // Logger.log("Must add? " + (sliceIds.contains(arc.getFromNode().getId()) && sliceIds.contains(arc.getToNode().getId()))); // // if (sliceIds.contains(arc.getFromNode().getId()) && sliceIds.contains(arc.getToNode().getId())) { // Logger.format("Added? %s", sliced.addEdge(arc)); // } // } // Set<Arc> arcs = pdgGraph.getArcs().stream() // .filter(arc -> sliced.getNodes().contains(arc.getFrom()) || sliced.getNodes().contains(arc.getTo())) // .collect(Collectors.toSet()); //// .forEach(sliced::addEdge); // // arcs.forEach(sliced::addEdge); // Logger.log("==== Arcs ===="); // sliced.getArcs().forEach(Logger::log); // Logger.log(sliced.getArcs().stream().map(Arc::toString).collect(Collectors.joining(System.lineSeparator()))); PDGGraph sliced = pdgGraph.slice(new LineNumberCriterion(18, "x")); PDGLog pdgLog = new PDGLog(sliced); pdgLog.log(); Loading @@ -77,6 +36,5 @@ public class Slice { pdgLog.openVisualRepresentation(); PDGValidator.printPDGProgram("Slice" + PROGRAM_NAME, sliced); PDGValidator.printPDGProgram("Generated" + PROGRAM_NAME, pdgGraph); } }
src/main/java/tfm/utils/NodeNotFoundException.java +4 −0 Original line number Diff line number Diff line Loading @@ -7,4 +7,8 @@ public class NodeNotFoundException extends RuntimeException { public NodeNotFoundException(SlicingCriterion slicingCriterion) { super("Node not found for slicing criterion: " + slicingCriterion); } public NodeNotFoundException(String message) { super(message); } }
src/main/java/tfm/utils/Utils.java +46 −4 Original line number Diff line number Diff line Loading @@ -4,11 +4,12 @@ import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.stmt.EmptyStmt; import com.github.javaparser.ast.stmt.Statement; import edg.graphlib.Arrow; import tfm.arcs.cfg.ControlFlowArc; import tfm.graphs.CFGGraph; import tfm.nodes.CFGNode; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.*; import java.util.function.Predicate; public class Utils { Loading Loading @@ -48,4 +49,45 @@ public class Utils { public static <E> Set<E> emptySet() { return new HashSet<>(0); } public static Set<CFGNode> findLastDefinitionsFrom(CFGNode startNode, String variable) { // Logger.log("======================================================="); // Logger.log("Starting from " + startNode); // Logger.log("Looking for variable " + variable); // Logger.log(cfgGraph.toString()); return findLastDefinitionsFrom(new HashSet<>(), startNode, startNode, variable); } private static Set<CFGNode> findLastDefinitionsFrom(Set<Integer> visited, CFGNode startNode, CFGNode currentNode, String variable) { visited.add(currentNode.getId()); // Logger.log("On " + currentNode); Set<CFGNode> res = new HashSet<>(); for (Arrow arrow : currentNode.getIncomingArrows()) { ControlFlowArc controlFlowArc = (ControlFlowArc) arrow; CFGNode from = (CFGNode) controlFlowArc.getFromNode(); // Logger.log("Arrow from node: " + from); if (!Objects.equals(startNode, from) && visited.contains(from.getId())) { // Logger.log("It's already visited. Continuing..."); continue; } if (from.getDefinedVariables().contains(variable)) { // Logger.log("Contains defined variable: " + variable); res.add(from); } else { // Logger.log("Doesn't contain the variable, searching inside it"); res.addAll(findLastDefinitionsFrom(visited, startNode, from, variable)); } } // Logger.format("Done with node %s", currentNode.getId()); return res; } }
src/main/java/tfm/validation/PDGValidator.java +68 −25 Original line number Diff line number Diff line Loading @@ -10,70 +10,113 @@ import com.github.javaparser.ast.body.Parameter; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.type.ArrayType; import com.github.javaparser.ast.type.VoidType; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import tfm.graphs.PDGGraph; import tfm.nodes.Node; import tfm.utils.Logger; import tfm.utils.Utils; import tfm.visitors.PDGCFGVisitor; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.Arrays; import java.util.Comparator; import java.util.Objects; import java.util.Optional; public class PDGValidator { private static final String PROGRAM_FOLDER = Utils.PROGRAMS_FOLDER + "pdg"; private static final String PROGRAM_NAME = "Example2"; private static final String METHOD_NAME = "main"; public static void main(String[] args) throws FileNotFoundException { JavaParser.getStaticConfiguration().setAttributeComments(false); CompilationUnit originalProgram = JavaParser.parse(new File(String.format("%s/%s.java", PROGRAM_FOLDER, PROGRAM_NAME))); if (METHOD_NAME.isEmpty()) { originalProgram.accept(new VoidVisitorAdapter<Void>() { @Override public void visit(MethodDeclaration n, Void arg) { Logger.format("On method: %s. Generating and comparing...", n.getNameAsString()); boolean check = generateAndCheck(n); Logger.format("Result: %s", check ? "equal" : "not equal"); } }, null); } else { Optional<MethodDeclaration> optionalTarget = originalProgram.findFirst(MethodDeclaration.class, methodDeclaration -> Objects.equals(methodDeclaration.getNameAsString(), METHOD_NAME)); if (!optionalTarget.isPresent()) { throw new RuntimeException(String.format("Method '%s' not found", METHOD_NAME)); } Logger.format("On method: %s. Generating and comparing...", METHOD_NAME); boolean check = generateAndCheck(optionalTarget.get()); Logger.format("Result: %s", check ? "equal" : "not equal"); } } public static boolean generateAndCheck(MethodDeclaration methodDeclaration) { PDGGraph graph = new PDGGraph(); originalProgram.accept(new PDGCFGVisitor(graph), graph.getRootNode()); // graph.depthFirstSearch(graph.getRootNode(), new NodeVisitor<PDGNode>() { // @Override // public void visit(PDGNode node) { // if (node.equals(graph.getRootNode())) // return; // // Logger.log(node); // // methodBody.addStatement(node.get); // } // }); printPDGProgram("Generated" + PROGRAM_NAME, graph); methodDeclaration.accept(new PDGCFGVisitor(graph), graph.getRootNode()); return check(methodDeclaration, graph); } public static boolean check(MethodDeclaration methodDeclaration, PDGGraph graph) { MethodDeclaration generatedMethod = generateMethod(methodDeclaration, graph); return ProgramComparator.areEqual(methodDeclaration, generatedMethod); } public static MethodDeclaration generateMethod(MethodDeclaration info, PDGGraph graph) { MethodDeclaration methodDeclaration = new MethodDeclaration(); methodDeclaration.setName(info.getNameAsString()); methodDeclaration.setModifiers(info.getModifiers()); methodDeclaration.setType(info.getType()); methodDeclaration.setParameters(info.getParameters()); BlockStmt methodBody = new BlockStmt(); methodDeclaration.setBody(methodBody); graph.getNodesAtLevel(1).stream() .sorted(Comparator.comparingInt(Node::getId)) .forEach(node -> methodBody.addStatement(node.getAstNode())); return methodDeclaration; } public static void printPDGProgram(String fileName, PDGGraph graph) throws FileNotFoundException { CompilationUnit generatedProgram = new CompilationUnit(); ClassOrInterfaceDeclaration clazz = generatedProgram.addClass(fileName).setPublic(true); MethodDeclaration methodDeclaration = clazz.addMethod("main", Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC); methodDeclaration.setType(new VoidType()); MethodDeclaration info = new MethodDeclaration(); info.setModifiers(Modifier.Keyword.PUBLIC, Modifier.Keyword.STATIC); info.setType(new VoidType()); info.setName("main"); Parameter parameter = new Parameter( new ArrayType(JavaParser.parseClassOrInterfaceType("String")), "args" ); info.setParameters(new NodeList<>(parameter)); methodDeclaration.setParameters(new NodeList<>(Arrays.asList(parameter))); BlockStmt methodBody = new BlockStmt(); methodDeclaration.setBody(methodBody); MethodDeclaration generated = generateMethod(info, graph); graph.getNodesAtLevel(1).stream() .sorted(Comparator.comparingInt(Node::getId)) .forEach(node -> methodBody.addStatement(node.getAstNode())); clazz.addMember(generated); PrintWriter printWriter = new PrintWriter(new File(String.format("out/%s.java", fileName))); printWriter.print(clazz.toString()); printWriter.close(); } }