Skip to content
Snippets Groups Projects
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
No related branches found
No related tags found
No related merge requests found
......@@ -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;
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));
}
for (VariableAction action : graphNode.getVariableActions()) {
if (action.isUsage() && action.getName().equals(n.getNameAsString())) {
list.add(new Pair<>(action, arg));
return;
}
}
throw new IllegalStateException("Cannot find USE action for var " + n);
}
@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;
}
}
throw new IllegalStateException("Could not find USE(this)");
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;
}
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -250,4 +250,9 @@ public class ASTUtils {
}
return classInit;
}
public static ResolvedType resolvedTypeOfCurrentClass(Node n) {
return ASTUtils.resolvedTypeDeclarationToResolvedType(
n.findAncestor(ClassOrInterfaceDeclaration.class).orElseThrow().resolve());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment