Commit 0c4f566b authored by jacosro's avatar jacosro
Browse files

Added node type

parent c1260151
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -19,8 +19,8 @@ import java.util.Optional;
public class Main {

    public static final String PROGRAM = Utils.PROGRAMS_FOLDER + "sdg/Example1.java";
    public static final String GRAPH = GraphLog.SDG;
    public static final String METHOD = "main";
    public static final String GRAPH = GraphLog.PDG;
    public static final String METHOD = "sum";

    public static void main(String[] args) throws IOException {
        JavaParser.getStaticConfiguration().setAttributeComments(false);
+9 −4
Original line number Diff line number Diff line
package tfm.graphs;

import com.github.javaparser.ast.Node;
import org.jetbrains.annotations.NotNull;
import org.jgrapht.graph.DirectedPseudograph;
import org.jgrapht.io.DOTExporter;
import tfm.arcs.Arc;
import tfm.nodes.GraphNode;
import tfm.nodes.NodeFactory;
import tfm.nodes.factories.NodeFactory;
import tfm.utils.ASTUtils;

import java.util.*;
@@ -25,12 +26,16 @@ public abstract class Graph extends DirectedPseudograph<GraphNode<?>, Arc> {
     *
     * @param node the node to add to the graph
     */
    public <ASTNode extends Node> void addNode(GraphNode<ASTNode> node) {
    public <ASTNode extends Node> void addNode(@NotNull GraphNode<ASTNode> node) {
        this.addVertex(node);
    }

    public <ASTNode extends Node> GraphNode<ASTNode> addNode(String instruction, ASTNode node) {
        GraphNode<ASTNode> newNode = NodeFactory.graphNode(instruction, node);
    public <ASTNode extends Node> GraphNode<ASTNode> addNode(@NotNull String instruction, @NotNull ASTNode node) {
        return this.addNode(instruction, node, GraphNode.DEFAULT_FACTORY);
    }

    public <ASTNode extends Node> GraphNode<ASTNode> addNode(@NotNull String instruction, @NotNull ASTNode node, @NotNull NodeFactory nodeFactory) {
        GraphNode<ASTNode> newNode = nodeFactory.graphNode(instruction, node);

        this.addNode(newNode);

+4 −3
Original line number Diff line number Diff line
@@ -2,8 +2,9 @@ package tfm.graphs;

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.MethodDeclaration;
import org.jetbrains.annotations.NotNull;
import tfm.nodes.GraphNode;
import tfm.nodes.NodeFactory;
import tfm.nodes.factories.NodeFactory;

import java.util.Objects;
import java.util.Optional;
@@ -24,12 +25,12 @@ public abstract class GraphWithRootNode<ASTRootNode extends Node> extends Graph
     * @param rootNodeAst the AST node
     * @return true if the root node is created, false otherwise
     */
    public boolean buildRootNode(String instruction, ASTRootNode rootNodeAst) {
    public boolean buildRootNode(@NotNull String instruction, @NotNull ASTRootNode rootNodeAst, @NotNull NodeFactory nodeFactory) {
        if (rootNode != null) {
            return false;
        }

        GraphNode<ASTRootNode> root = NodeFactory.graphNode(instruction, rootNodeAst);
        GraphNode<ASTRootNode> root = nodeFactory.graphNode(instruction, rootNodeAst);
        this.rootNode = root;
        this.addVertex(root);

+2 −1
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.visitor.VoidVisitor;
import tfm.graphs.cfg.CFGBuilder;
import tfm.nodes.GraphNode;
import tfm.nodes.factories.MethodNodeFactory;
import tfm.utils.ASTUtils;

import java.util.LinkedList;
@@ -237,7 +238,7 @@ public class ACFGBuilder extends CFGBuilder {
        if (!methodDeclaration.getBody().isPresent())
            throw new IllegalStateException("The method must have a body!");

        graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration);
        graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, new MethodNodeFactory());

        hangingNodes.add(graph.getRootNode().get());
        methodDeclaration.getBody().get().accept(this, arg);
+82 −14
Original line number Diff line number Diff line
@@ -2,13 +2,16 @@ package tfm.graphs.cfg;

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.BooleanLiteralExpr;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.SimpleName;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.body.VariableDeclarator;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.visitor.VoidVisitor;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import tfm.nodes.GraphNode;
import tfm.nodes.factories.InVariableNodeFactory;
import tfm.nodes.factories.MethodNodeFactory;
import tfm.nodes.factories.OutVariableNodeFactory;
import tfm.utils.ASTUtils;

import java.util.*;
@@ -30,22 +33,38 @@ import java.util.*;
 * </ol>
 */
public class CFGBuilder extends VoidVisitorAdapter<Void> {
    /** Stores the CFG representing the method analyzed. */
    /**
     * Stores the CFG representing the method analyzed.
     */
    protected final CFG graph;
    /** Nodes that haven't yet been connected to another one.
     * The next node will be the destination, they are the source. */
    /**
     * Nodes that haven't yet been connected to another one.
     * The next node will be the destination, they are the source.
     */
    protected final List<GraphNode<?>> hangingNodes = new LinkedList<>();
    /** Stack of break statements collected in various (nestable) breakable blocks. */
    /**
     * Stack of break statements collected in various (nestable) breakable blocks.
     */
    protected final Deque<List<GraphNode<BreakStmt>>> breakStack = new LinkedList<>();
    /** Stack of continue statements collected in various (nestable) continuable blocks. */
    /**
     * Stack of continue statements collected in various (nestable) continuable blocks.
     */
    protected final Deque<List<GraphNode<ContinueStmt>>> continueStack = new LinkedList<>();
    /** Lists of labelled break statements, mapped according to their label. */
    /**
     * Lists of labelled break statements, mapped according to their label.
     */
    protected final Map<SimpleName, List<GraphNode<BreakStmt>>> breakMap = new HashMap<>();
    /** Lists of labelled continue statements, mapped according to their label. */
    /**
     * Lists of labelled continue statements, mapped according to their label.
     */
    protected final Map<SimpleName, List<GraphNode<ContinueStmt>>> continueMap = new HashMap<>();
    /** Return statements that should be connected to the final node, if it is created at the end of the  */
    /**
     * Return statements that should be connected to the final node, if it is created at the end of the
     */
    protected final List<GraphNode<ReturnStmt>> returnList = new LinkedList<>();
    /** Stack of lists of hanging cases on switch statements */
    /**
     * Stack of lists of hanging cases on switch statements
     */
    protected final Deque<List<GraphNode<SwitchEntryStmt>>> switchEntriesStack = new LinkedList<>();

    protected CFGBuilder(CFG graph) {
@@ -197,7 +216,9 @@ public class CFGBuilder extends VoidVisitorAdapter<Void> {
        hangingNodes.addAll(breakStack.pop());
    }

    /** Switch entry, considered part of the condition of the switch. */
    /**
     * Switch entry, considered part of the condition of the switch.
     */
    @Override
    public void visit(SwitchEntryStmt entryStmt, Void arg) {
        // Case header (prev -> case EXPR)
@@ -270,11 +291,58 @@ public class CFGBuilder extends VoidVisitorAdapter<Void> {
        if (!methodDeclaration.getBody().isPresent())
            throw new IllegalStateException("The method must have a body!");

        graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration);
        graph.buildRootNode("ENTER " + methodDeclaration.getNameAsString(), methodDeclaration, new MethodNodeFactory());

        // Compute variable in and out expressions (necessary to compute data dependence in SDG)
        List<ExpressionStmt> inVariableExpressions = new ArrayList<>();
        List<ExpressionStmt> outVariableExpressions = new ArrayList<>();

        for (Parameter parameter : methodDeclaration.getParameters()) {
            // In expression
            VariableDeclarationExpr inVariableDeclarationExpr = new VariableDeclarationExpr(
                new VariableDeclarator(
                    parameter.getType(),
                    parameter.getNameAsString(),
                    new NameExpr(parameter.getNameAsString() + "_in")
                )
            );

            ExpressionStmt inExprStmt = new ExpressionStmt(inVariableDeclarationExpr);

            inVariableExpressions.add(inExprStmt);

            // Out expression
            VariableDeclarationExpr outVariableDeclarationExpr = new VariableDeclarationExpr(
                    new VariableDeclarator(
                            parameter.getType(),
                            parameter.getNameAsString() + "_out",
                            new NameExpr(parameter.getNameAsString())
                    )
            );

            ExpressionStmt outExprStmt = new ExpressionStmt(outVariableDeclarationExpr);

            outVariableExpressions.add(outExprStmt);
        }

        hangingNodes.add(graph.getRootNode().get());

        // Add in variable nodes
        for (ExpressionStmt expressionStmt : inVariableExpressions) {
            GraphNode<ExpressionStmt> node = this.graph.addNode(expressionStmt.toString(), expressionStmt, new InVariableNodeFactory());
            connectTo(node);
        }

        methodDeclaration.getBody().get().accept(this, arg);

        returnList.stream().filter(node -> !hangingNodes.contains(node)).forEach(hangingNodes::add);

        // Add out variable nodes
        for (ExpressionStmt expressionStmt : outVariableExpressions) {
            GraphNode<ExpressionStmt> node = this.graph.addNode(expressionStmt.toString(), expressionStmt, new OutVariableNodeFactory());
            connectTo(node);
        }

        GraphNode<EmptyStmt> exitNode = connectTo(new EmptyStmt(), "Exit");
        graph.setExitNode(exitNode);
    }
Loading