Commit dd3857a4 authored by Jonathan Andrade's avatar Jonathan Andrade
Browse files

set topological numbers into the IntraSCRs node

parent d7566813
Loading
Loading
Loading
Loading
Loading
+74 −2
Original line number Diff line number Diff line
@@ -86,10 +86,22 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
        protected final Map<CallSCR, Set<IntraSCR>> transitiveMap = new HashMap<>();
        /** The strongly connected components of the {@link ICFG}, computed while ignoring
         *  interprocedural edges that connect {@link #cSCRs} nodes. <br>
         *  Fulfils steps 2-3 of the Nanda-Ramesh topological numbers algorithm. */
         *  Fulfils steps 2-3 of the Nanda-Ramesh topological numbers' algorithm. */
        protected IntraSCRGraph intraSCRs;
        /** Non-Recursive interprocedural Arcs from {@link  #intraSCRs} */
        protected Set<Triple<GraphNode<?>, GraphNode<?>, ControlFlowArc>> interprocNonRecArcs = new HashSet<>();
        /** A list of all {@link  #intraSCRs} that have an callSite type in Nanda-Ramesh algorithm */
        protected Set<IntraSCR> callSiteIntraSCRs = new HashSet<>();
        /** A list of all {@link  #intraSCRs} that have an returnSite type in Nanda-Ramesh algorithm */
        protected Set<IntraSCR> returnSiteIntraSCRs = new HashSet<>();
        /** A map to locate the correspondent call node from a return node */
        protected final Map<IntraSCR, IntraSCR> returnToCorrespondentCallSiteMap = new HashMap<>();
        /** A map to locate the {@link  #intraSCRs} within a call*/
        protected final Map<IntraSCR, Set<IntraSCR>> callNodeProcessMap = new HashMap<>();
        /** A map to get the topological number associated to the {@link  #intraSCRs} */
        protected final Map<Integer, IntraSCR> topologicalNumbersMap = new HashMap<>();
        /** counter for topologicalNumbers */
        protected int topologicalNumber = 0;

        public void build(NodeList<CompilationUnit> units) {
            createClassGraph(units);
@@ -111,7 +123,53 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
            computeCallSCRs();
            computeIntraSCRs();
            buildISCR();
            System.out.println("testing");
            generateTopologicalNumbers();
        }

        private void generateTopologicalNumbers() {
            Set<IntraSCR> proccessedIntraSCRs = new HashSet<>();
            Stack<IntraSCR> callStack = new Stack<>();
            // get exit node
            IntraSCR exitNode = null;
            for (IntraSCR cSCRNode : intraSCRs.vertexSet()) {
                if (intraSCRs.outDegreeOf(cSCRNode) == 0) {
                    exitNode = cSCRNode;
                    break;
                }
            }
            //callGetTopologicalNumber for exitNode (predecessors are visited inside)
            getTopologicalNumber(exitNode, proccessedIntraSCRs, callStack);
        }

        private <V> void getTopologicalNumber(IntraSCR node, Set<IntraSCR> proccessedIntraSCRs, Stack<IntraSCR> callStack) {
            if(proccessedIntraSCRs.contains(node)) {
                return;
            }

            for(IntraSCR predecessor : Graphs.predecessorListOf(intraSCRs, node)) {
                if(callSiteIntraSCRs.contains(predecessor) && !callStack.isEmpty() && predecessor == callStack.peek()) {
                    callStack.pop();
                    getTopologicalNumber(predecessor, proccessedIntraSCRs, callStack);
                } else if(returnSiteIntraSCRs.contains(predecessor) ) {
                    IntraSCR callNode = returnToCorrespondentCallSiteMap.get(predecessor);
                    callStack.push(callNode);
                    getTopologicalNumber(predecessor, proccessedIntraSCRs, callStack);
                    if(callNodeProcessMap.containsKey(callNode)) {
                        for (IntraSCR intraSCR : callNodeProcessMap.get(callNode)) {
                            proccessedIntraSCRs.remove(intraSCR);
                        }
                    }
                } else {
                    if(!callStack.isEmpty()) {
                        callNodeProcessMap.computeIfAbsent(callStack.peek(), k -> new HashSet<>()).add(predecessor);
                    }
                    getTopologicalNumber(predecessor, proccessedIntraSCRs, callStack);
                }
            }
            node.addTopologicalNumber(topologicalNumber);
            topologicalNumber++;

            proccessedIntraSCRs.add(node);
        }

        private void addEdgesToIntraSCRs(Set<Triple<GraphNode<?>, GraphNode<?>, ControlFlowArc>> deletedArcs) {
@@ -205,6 +263,7 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
            }
            buildISCRGraph(mainIntraSCR, processedIntraSCRs);
            deleteCallReturnEdges();
            deleteMainExitEdge(mainIntraSCR);
            getMainProcess(mainIntraSCR);
        }

@@ -222,6 +281,15 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
            }
        }

        private void deleteMainExitEdge(IntraSCR mainIntraSCR) {
            IntraSCR exitNode = intraSCRs.outgoingEdgesOf(mainIntraSCR).stream()
                    .map(intraSCRs::getEdgeTarget)
                    .filter(target -> target.vertexSet().stream().anyMatch(node -> node instanceof MethodExitNode))
                    .findFirst().orElseThrow();

            intraSCRs.removeEdge(mainIntraSCR, exitNode);
        }

        private void deleteCallReturnEdges() {
            Set<DefaultEdge> toBeDeletedSet = new HashSet<>();
            for (DefaultEdge e : intraSCRs.edgeSet()) {
@@ -233,6 +301,7 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
                    for(GraphNode<?> src : source.vertexSet()) {
                        for(GraphNode<?> tgt : target.vertexSet()) {
                            if(src instanceof CallNode && tgt instanceof CallNode.Return) {
                                returnToCorrespondentCallSiteMap.put(target, source);
                                toBeDeletedSet.add(e);
                            }
                        }
@@ -299,12 +368,15 @@ public class ICFG extends es.upv.mist.slicing.graphs.Graph implements Buildable<
                if (graphNode instanceof CallNode) {
                    for (Triple<GraphNode<?>, GraphNode<?>, ControlFlowArc> arc : interprocNonRecArcs) {
                        if (graphNode.equals(arc.getFirst())) {
                            callSiteIntraSCRs.add(intraSCR);
                            @SuppressWarnings("unchecked")
                            GraphNode<CallableDeclaration<?>> enterNode = (GraphNode<CallableDeclaration<?>>) arc.getSecond();
                            IntraSCR enterIntraSCR = getEnterIntraSCR(enterNode);
                            buildISCRGraph(enterIntraSCR, processedIntraSCRs);
                        }
                    }
                } else if(graphNode instanceof CallNode.Return){
                    returnSiteIntraSCRs.add(intraSCR);
                }
            } else {
                throw new IllegalStateException("The intraSCRs is empty");
+13 −0
Original line number Diff line number Diff line
@@ -5,7 +5,9 @@ import es.upv.mist.slicing.graphs.icfg.ICFG;
import es.upv.mist.slicing.nodes.GraphNode;
import org.jgrapht.Graph;

import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * A strongly connected region (or component) in a {@link ICFG}.
@@ -13,9 +15,20 @@ import java.util.Set;
 */
public class IntraSCR extends AbstractSCR<GraphNode<?>, Arc> {
    private static int nextId = 1;
    private final Set<Integer> topologicalNumberSet = new HashSet<>();

    public IntraSCR(Graph<GraphNode<?>, Arc> base, Set<? extends GraphNode<?>> vertexSubset, Set<? extends Arc> edgeSubset) {
        super(base, vertexSubset, edgeSubset);
        this.id = nextId++;
    }

    public void addTopologicalNumber(Integer topologicalNumber) {
        this.topologicalNumberSet.add(topologicalNumber);
    }

    public String getTopologicalNumber() {
        return this.topologicalNumberSet.stream()
                .map(String::valueOf)
                .collect(Collectors.joining("-"));
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ public abstract class GraphLogIntraSCR<G extends IntraSCRGraph> {

    protected DOTAttributes vertexAttributes(IntraSCR vertex) {
        DOTAttributes res = new DOTAttributes();
        res.set("label", "X" + vertex.getId() + "\n" + vertex.vertexSet().stream()
        res.set("label", "X" + vertex.getId() + "\n" + "TOP-" + vertex.getTopologicalNumber() + "\n" + vertex.vertexSet().stream()
                .map(graphNode -> "%04d: %s".formatted(graphNode.getId(), graphNode.getLabel()))
                .sorted()
                .collect(Collectors.joining("\n")));
+2 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ public class ICFGTest {
        StaticJavaParser.getConfiguration().setAttributeComments(false);
        StaticTypeSolver.addTypeSolverJRE();

        createGraph("TestInicial.java", "grafoInicial");
        /*createGraph("TestInicial.java", "grafoInicial");
        System.out.println("Grafo 1 generado...");

        createGraph("TestGlobalVariables.java", "grafoGlobalVariables");
@@ -28,6 +28,7 @@ public class ICFGTest {

        createGraph("TestExamplePaper.java", "grafoPaper");
        System.out.println("Grafo 5 generado...");
         */

        createGraph("TestExamplePaperSimple.java", "grafoPaperSimple");
        System.out.println("Grafo 6 generado...");