Commit ee494981 authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Simple array handling, equivalent to old handling as primitives.

parent cf735a3f
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -59,6 +59,11 @@ public class ExpressionObjectTreeFinder {
                .forEach(pair -> markTransference(pair, assignTarget, targetMember));
    }

    public void handleArrayAssignExpr(AssignExpr assignExpr) {
        locateExpressionResultTrees(assignExpr.getValue())
                .forEach(pair -> pair.a.setPDGValueConnection(pair.b));
    }

    public void locateAndMarkTransferenceToRoot(Expression expr, int index) {
        List<VariableAction> list = graphNode.getVariableActions();
        if (index < 0)
@@ -77,7 +82,7 @@ public class ExpressionObjectTreeFinder {
        expression.accept(new VoidVisitorAdapter<String>() {
            @Override
            public void visit(ArrayAccessExpr n, String arg) {
                throw new UnsupportedOperationException("Array accesses are not supported as argument for return, call scope or argument. Please, pre-process your graph or use the EDG.");
                n.getName().accept(this, arg);
            }

            @Override
+2 −2
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ import es.upv.mist.slicing.nodes.oo.MemberNode;

import java.util.function.Supplier;

class ObjectTreeConnection {
class ObjectTreeConnection implements VariableAction.PDGConnection {

    protected final VariableAction sourceAction;
    protected final VariableAction targetAction;
@@ -34,7 +34,7 @@ class ObjectTreeConnection {
        }
    }

    public void applyPDG(JSysPDG graph) {
    public void apply(JSysPDG graph) {
        if (!applied) {
            connectTrees(graph, FlowDependencyArc::new, ObjectFlowDependencyArc::new);
            applied = true;
+28 −0
Original line number Diff line number Diff line
package es.upv.mist.slicing.nodes;

import es.upv.mist.slicing.arcs.pdg.FlowDependencyArc;
import es.upv.mist.slicing.graphs.jsysdg.JSysPDG;

public class ValueConnection implements VariableAction.PDGConnection {
    protected final VariableAction action;
    protected final String member;

    public ValueConnection(VariableAction action, String member) {
        this.action = action;
        if (member.isEmpty())
            this.member = "-root-";
        else
            this.member = "-root-." + member;
    }

    @Override
    public void apply(JSysPDG graph) {
        GraphNode<?> statementNode;
        if (action instanceof VariableAction.Movable)
            statementNode = ((VariableAction.Movable) action).getRealNode();
        else
            statementNode = action.getGraphNode();
        if (action.hasTreeMember(member))
            graph.addEdge(action.getObjectTree().getNodeFor(member), statementNode, new FlowDependencyArc());
    }
}
+10 −2
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ public abstract class VariableAction {
     *  The variable action that contains the tree we must connect to in the PDG.
     *  The string, or member where the tree connection must start (in PDG). E.g.: our tree is "a.b.c" and this variable is "a",
     *  the members "a.b" and "a.b.c" will be connected to "b" and "b.c" in treeConnectionTarget's tree.. */
    protected final List<ObjectTreeConnection> pdgTreeConnections = new LinkedList<>();
    protected final List<PDGConnection> pdgTreeConnections = new LinkedList<>();

    private VariableAction(DeclarationType declarationType, String name, GraphNode<?> graphNode) {
        this(declarationType, name, graphNode, null);
@@ -177,8 +177,12 @@ public abstract class VariableAction {
        pdgTreeConnections.add(new ObjectTreeConnection(this, targetAction, sourcePrefixWithoutRoot, targetPrefixWithoutRoot));
    }

    public void setPDGValueConnection(String member) {
        pdgTreeConnections.add(new ValueConnection(this, member));
    }

    public void applyPDGTreeConnections(JSysPDG pdg) {
        pdgTreeConnections.forEach(c -> c.applyPDG(pdg));
        pdgTreeConnections.forEach(c -> c.apply(pdg));
    }

    public void applySDGTreeConnection(JSysDG sdg, VariableAction targetAction) {
@@ -549,4 +553,8 @@ public abstract class VariableAction {
            return Objects.hash(super.hashCode(), realNode, inner);
        }
    }

    public interface PDGConnection {
        void apply(JSysPDG graph);
    }
}
+24 −4
Original line number Diff line number Diff line
@@ -160,6 +160,18 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
    }

    // Modified traversal (there may be variable definitions or declarations)
    @Override
    public void visit(ArrayAccessExpr n, Action arg) {
        if (arg == DEFINITION) {
            n.getName().accept(this, arg);
            n.getIndex().accept(this, USE);
        } else if (arg == USE) {
            super.visit(n, arg);
        } else {
            throw new IllegalStateException("Array accesses cannot be defined");
        }
    }

    @Override
    public void visit(ReturnStmt n, Action arg) {
        super.visit(n, arg);
@@ -227,6 +239,7 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act
        if (n.getOperator() != AssignExpr.Operator.ASSIGN)
            n.getTarget().accept(this, action);
        List<String> realNameWithoutRootList = new LinkedList<>();
        List<Boolean> foundArray = new LinkedList<>();
        n.getTarget().accept(new VoidVisitorAdapter<Void>() {
            @Override
            public void visit(NameExpr nameExpr, Void arg) {
@@ -280,13 +293,18 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act

            @Override
            public void visit(ArrayAccessExpr n, Void arg) {
                throw new UnsupportedOperationException("Arrays are not yet supported as target of assignment.");
                n.getName().accept(this, arg);
                n.getIndex().accept(VariableVisitor.this, USE);
                foundArray.add(true);
            }
        }, null);
        assert realNameWithoutRootList.size() == 1;
        assert realNameWithoutRootList.size() == 1 || !foundArray.isEmpty();
        groupActionsByRoot(graphNode);
        ExpressionObjectTreeFinder finder = new ExpressionObjectTreeFinder(graphNode);
        if (foundArray.isEmpty()) // Handle a field access or normal variable
            finder.handleAssignExpr(n, getLastDefinition(), realNameWithoutRootList.get(0));
        else // Handle an array access
            finder.handleArrayAssignExpr(n);
    }

    @Override
@@ -344,9 +362,11 @@ public class VariableVisitor extends GraphNodeContentVisitor<VariableVisitor.Act

    @Override
    public void visit(VariableDeclarator n, Action arg) {
        if (n.getType().isClassOrInterfaceType() && n.getInitializer().isPresent())
        if (n.getType().isClassOrInterfaceType() && n.getInitializer().isPresent()) {
            groupActionsByRoot(graphNode);
            new ExpressionObjectTreeFinder(graphNode).handleVariableDeclarator(n);
        }
    }

    @Override
    public void visit(CatchClause n, Action arg) {