Commit 15575d4a authored by Carlos Galindo's avatar Carlos Galindo
Browse files

Store associated expressions in each VA, to avoid confusion between them

ExpressionObjectTreeFinder will now locate the correct VA, by searching for the matching call or expression.
parent 06f3b65e
Loading
Loading
Loading
Loading
+44 −16
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ import es.upv.mist.slicing.utils.ASTUtils;

import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

import static es.upv.mist.slicing.graphs.cfg.CFGBuilder.VARIABLE_NAME_OUTPUT;

@@ -124,6 +126,26 @@ public class ExpressionObjectTreeFinder {
                .forEach(pair -> markTransference(pair, targetAction, ""));
    }

    public void locateAndMarkTransferenceToRoot(Resolvable<? extends ResolvedMethodLikeDeclaration> call, VariableAction targetAction) {
        boolean enteredCall = false;
        for (VariableAction va : graphNode.getVariableActions()) {
            if (va instanceof VariableAction.CallMarker &&
                    ASTUtils.equalsWithRange(((VariableAction.CallMarker) va).getCall(), call)) {
                if (((VariableAction.CallMarker) va).isEnter())
                    enteredCall = true;
                else
                    break;
            }
            if (enteredCall && va.isDefinition() && va.getName().equals("-scope-in-"))
                break;
            if (enteredCall && va.isUsage() && va.getName().equals("this")) {
                markTransference(new Pair<>(va, ""), targetAction, "");
                return;
            }
        }
        throw new IllegalStateException("Can't locate USE(this)--scope--for call " + call);
    }

    /**
     * Finds object trees that correspond to the output of the given expression.
     * @param expression An expression that outputs an object.
@@ -155,27 +177,25 @@ public class ExpressionObjectTreeFinder {
                if (resolved.isType())
                    return;
                if (resolved.isField() && !resolved.asField().isStatic()) {
                    new FieldAccessExpr(new ThisExpr(), n.getNameAsString()).accept(this, arg);
                    return;
                }
                for (VariableAction action : graphNode.getVariableActions()) {
                    if (action.isUsage() && action.getName().equals(n.getNameAsString())) {
                        list.add(new Pair<>(action, arg));
                        return;
                    }
                }
                    String newArg = n.getNameAsString() + (!arg.isEmpty() ? "." : "") + arg;
                    var optVa = locateVariableAction(n, va -> va.getName().matches("^.*this$"));
                    if (optVa.isEmpty())
                        throw new IllegalStateException("Could not find USE action for var " + newArg);
                    list.add(new Pair<>(optVa.get(), newArg));
                } else {
                    var optVa = locateVariableAction(n, va -> va.getName().equals(n.getNameAsString()));
                    if (optVa.isEmpty())
                        throw new IllegalStateException("Cannot find USE action for var " + n);
                    list.add(new Pair<>(optVa.get(), arg));
                }
            }

            @Override
            public void visit(ThisExpr n, String arg) {
                for (VariableAction action : graphNode.getVariableActions()) {
                    if (action.isUsage() && action.getName().matches("^.*this$")) {
                        list.add(new Pair<>(action, arg));
                        return;
                    }
                }
                var vaOpt = locateVariableAction(n, va -> va.getName().matches("^.*this$"));
                if (vaOpt.isEmpty())
                    throw new IllegalStateException("Could not find USE(this)");
                list.add(new Pair<>(vaOpt.get(), arg));
            }

            @Override
@@ -247,6 +267,14 @@ public class ExpressionObjectTreeFinder {

            @Override
            public void visit(PatternExpr n, String arg) {}

            protected Optional<VariableAction> locateVariableAction(Expression expression, Predicate<VariableAction> predicate) {
                return graphNode.getVariableActions().stream()
                        .filter(VariableAction::isUsage)
                        .filter(predicate)
                        .filter(va -> va.matches(expression))
                        .findAny();
            }
        }, "");
        return list;
    }
+4 −4
Original line number Diff line number Diff line
@@ -3,7 +3,6 @@ package es.upv.mist.slicing.graphs.sdg;
import com.github.javaparser.ast.body.CallableDeclaration;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
import com.github.javaparser.ast.expr.ThisExpr;
import com.github.javaparser.resolution.Resolvable;
import com.github.javaparser.resolution.declarations.ResolvedMethodLikeDeclaration;
import es.upv.mist.slicing.graphs.CallGraph;
@@ -18,7 +17,6 @@ import es.upv.mist.slicing.nodes.io.FormalIONode;
import es.upv.mist.slicing.utils.ASTUtils;

import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -45,8 +43,10 @@ public class InterproceduralUsageFinder extends InterproceduralActionFinder<Usag
                    if (va instanceof Movable && ((Movable) va).getRealNode().equals(actualIn)) {
                        ExpressionObjectTreeFinder finder = new ExpressionObjectTreeFinder(edge.getGraphNode());
                        if (va.getName().equals("-scope-in-")) {
                            Expression scope = Objects.requireNonNullElseGet(actualIn.getArgument(), ThisExpr::new);
                            finder.locateAndMarkTransferenceToRoot(scope, va);
                            if (actualIn.getArgument() == null)
                                finder.locateAndMarkTransferenceToRoot(edge.getCall(), va);
                            else
                                finder.locateAndMarkTransferenceToRoot(actualIn.getArgument(), va);
                        } else if (va.getName().equals("-arg-in-")) {
                            finder.locateAndMarkTransferenceToRoot(actualIn.getArgument(), va);
                        }
+27 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ import es.upv.mist.slicing.graphs.jsysdg.JSysDG;
import es.upv.mist.slicing.graphs.jsysdg.JSysPDG;
import es.upv.mist.slicing.graphs.pdg.PDG;
import es.upv.mist.slicing.utils.ASTUtils;
import es.upv.mist.slicing.utils.NodeHashSet;

import java.util.*;
import java.util.stream.Collectors;
@@ -64,6 +65,7 @@ public abstract class VariableAction {
    protected final String name;
    protected final DeclarationType declarationType;
    protected final Set<ResolvedType> dynamicTypes = new HashSet<>();
    protected final Set<Expression> expressions = new NodeHashSet<>();

    protected ResolvedType staticType;
    protected GraphNode<?> graphNode;
@@ -176,6 +178,21 @@ public abstract class VariableAction {
        return dynamicTypes;
    }

    public void addExpression(Expression expression) {
        expressions.add(expression);
    }

    public void copyExpressions(VariableAction variableAction) {
        if (variableAction instanceof Movable)
            variableAction = ((Movable) variableAction).inner;
        variableAction.expressions.forEach(this::addExpression);
    }

    /** Whether this variable action represents the given expression. */
    public boolean matches(Expression expression) {
        return expressions.contains(expression);
    }

    // ======================================================
    // =================== OBJECT TREE ======================
    // ======================================================
@@ -521,6 +538,16 @@ public abstract class VariableAction {
            inner.applySDGTreeConnection(sdg, targetAction);
        }

        @Override
        public void addExpression(Expression expression) {
            inner.addExpression(expression);
        }

        @Override
        public boolean matches(Expression expression) {
            return inner.matches(expression);
        }

        @Override
        public void setStaticType(ResolvedType staticType) {
            inner.setStaticType(staticType);
+93 −87

File changed.

Preview size limit exceeded, changes collapsed.

+5 −0
Original line number Diff line number Diff line
@@ -250,4 +250,9 @@ public class ASTUtils {
        }
        return classInit;
    }

    public static ResolvedType resolvedTypeOfCurrentClass(Node n) {
        return ASTUtils.resolvedTypeDeclarationToResolvedType(
                n.findAncestor(ClassOrInterfaceDeclaration.class).orElseThrow().resolve());
    }
}