Commit 73c41549 authored by Javier Costa's avatar Javier Costa
Browse files

Variable model

parent b9c3e08b
Loading
Loading
Loading
Loading
+22 −25
Original line number Diff line number Diff line
package tfm.graphs;

import com.github.javaparser.ast.expr.VariableDeclarationExpr;
import tfm.arcs.Arc;
import tfm.arcs.pdg.ControlDependencyArc;
import tfm.arcs.pdg.DataDependencyArc;
import tfm.nodes.PDGVertex;
import tfm.nodes.Vertex;
import tfm.variables.*;
import tfm.variables.actions.VariableAction;
import tfm.variables.actions.VariableDeclaration;
import tfm.variables.actions.VariableRead;
import tfm.variables.actions.VariableWrite;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

public abstract class PDGGraph extends Graph<PDGVertex> {

    private Map<String, List<VariableDeclarationExpr>> variablesDeclarations;
    private Map<String, List<VariableDeclarationExpr>> variablesUses;
    private VariableSet variableSet;

    public PDGGraph() {
        setRootVertex(new PDGVertex(VertexId.getVertexId(), getRootNodeData()));

        variablesDeclarations = new HashMap<>();
        variablesUses = new HashMap<>();
        variableSet = new VariableSet();
    }

    protected abstract String getRootNodeData();
@@ -50,28 +51,24 @@ public abstract class PDGGraph extends Graph<PDGVertex> {
        this.addArc(dataDataDependencyArc);
    }

    public void addVariableDeclaration(String variable, VariableDeclarationExpr expr) {
        doAddVariableUseOrDeclaration(variable, expr, variablesDeclarations);
    }
    public <T> Variable<T> addNewVariable(String name, T value, Vertex declarationNode) {
        Variable<T> variable = new Variable<>(new VariableDeclaration<>(declarationNode, value), name);
        variableSet.addVariable(variable);

    public void addVariableUse(String variable, VariableDeclarationExpr expr) {
        doAddVariableUseOrDeclaration(variable, expr, variablesUses);
        return variable;
    }

    private void doAddVariableUseOrDeclaration(String variable, VariableDeclarationExpr expr, Map<String, List<VariableDeclarationExpr>> map) {
        List<VariableDeclarationExpr> list = map.getOrDefault(variable, new ArrayList<>());
        list.add(expr);

        if (!map.containsKey(variable)) {
            map.put(variable, list);
        }
    public <T> void addVariableWrite(Vertex currentNode, T newValue, String variable) {
        variableSet.findVariableByName(variable)
                .ifPresent(objectVariable -> objectVariable.addWrite(new VariableWrite<>(currentNode, newValue)));
    }

    public List<VariableDeclarationExpr> getDeclarationsOf(String variable) {
        return variablesDeclarations.get(variable);
    public <T> void addVariableRead(Vertex currentNode, T currentValue, String variable) {
        variableSet.findVariableByName(variable)
                .ifPresent(objectVariable -> objectVariable.addRead(new VariableRead<>(currentNode, currentValue)));
    }

    public List<VariableDeclarationExpr> getUsesOf(String variable) {
        return variablesUses.get(variable);
    public VariableSet getVariableSet() {
        return variableSet;
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ import java.util.stream.Collectors;

public class Vertex extends edg.graphlib.Vertex<String, ArcData> {

    private int fileLineNumber;
    private Integer fileLineNumber;

    public Vertex(Graph.VertexId id, String instruction) {
        this(id, instruction, null);
@@ -17,7 +17,7 @@ public class Vertex extends edg.graphlib.Vertex<String, ArcData> {
    public Vertex(Graph.VertexId id, String instruction, Integer fileLineNumber) {
        super(id.toString(), instruction);

        this.fileLineNumber = Optional.ofNullable(fileLineNumber).orElse(-1);
        this.fileLineNumber = fileLineNumber;
    }

    public int getId() {
@@ -33,7 +33,7 @@ public class Vertex extends edg.graphlib.Vertex<String, ArcData> {
    }

    public Optional<Integer> getFileLineNumber() {
        return fileLineNumber == -1 ? Optional.empty() : Optional.of(fileLineNumber);
        return Optional.ofNullable(fileLineNumber);
    }

    public void setFileLineNumber(Integer fileLineNumber) {
+35 −22
Original line number Diff line number Diff line
package tfm.variables;

import tfm.utils.Scope;
import tfm.variables.actions.VariableDeclaration;
import tfm.variables.actions.VariableRead;
import tfm.variables.actions.VariableWrite;

public class Variable<T> {
import java.util.ArrayList;
import java.util.List;

    private Scope scope;
public class Variable<T> {
    private VariableDeclaration<T> declaration;
    private String name;
    private T value;

    public Variable(Scope scope, String name) {
        this(scope, name, null);
    }
    private List<VariableWrite<T>> writes;
    private List<VariableRead<T>> reads;

    public Variable(Scope scope, String name, T value) {
        this.scope = scope;
    public Variable(VariableDeclaration<T> variableDeclaration, String name) {
        this.declaration = variableDeclaration;
        this.name = name;
        this.value = value;
        this.writes = new ArrayList<>();
        this.reads = new ArrayList<>();
    }

    public String getName() {
        return name;
    }

    public Scope getScope() {
        return scope;
    public void addWrite(VariableWrite<T> declaration) {
        this.writes.add(declaration);
    }

    @Override
    public int hashCode() {
        return scope.hashCode() + name.hashCode();
    public void addWrites(List<VariableWrite<T>> declarations) {
        this.writes.addAll(declarations);
    }

    public void addRead(VariableRead<T> uses) {
        this.reads.add(uses);
    }

    public void addReads(List<VariableRead<T>> uses) {
        this.reads.addAll(uses);
    }

    @Override
@@ -42,19 +51,23 @@ public class Variable<T> {

        Variable other = (Variable) o;

        return name.equals(other.name) && scope.equals(other.scope);
        return name.equals(other.name) && declaration.equals(other.declaration);
    }

    @Override
    public String toString() {
        return String.format("Variable %s defined in scope %s", name, scope);
        return String.format("Variable %s declared on vertex %s", name, declaration.getNode().getId());
    }

    public List<VariableWrite<T>> getWrites() {
        return writes;
    }

    public T getValue() {
        return value;
    public List<VariableRead<T>> getReads() {
        return reads;
    }

    public void setValue(T value) {
        this.value = value;
    public VariableDeclaration<T> getDeclaration() {
        return declaration;
    }
}
+53 −0
Original line number Diff line number Diff line
package tfm.variables;

import org.checkerframework.checker.nullness.qual.NonNull;
import tfm.variables.actions.VariableDeclaration;
import tfm.variables.actions.VariableWrite;

import java.util.*;

public class VariableSet {

    private Set<Variable> variableSet;

    public VariableSet() {
        variableSet = new HashSet<>();
    }

    public <T> Optional<Variable<T>> findVariableByName(String name) {
        return variableSet.stream()
                .filter(variable -> Objects.equals(variable.getName(), name))
                .findFirst()
                .map(variable -> (Variable<T>) variable);
    }

    public <T> Optional<Variable<T>> findVariableByDeclaration(VariableDeclaration<T> declaration) {
        return variableSet.stream()
                .filter(variable -> Objects.equals(variable.getDeclaration(), declaration))
                .findFirst()
                .map(variable -> (Variable<T>) variable);
    }

    public void addVariable(Variable<?> variable) {
        this.variableSet.add(variable);
    }


    public <T> Optional<VariableWrite<T>> getLastWriteOf(@NonNull Variable<T> variable) {
        List<VariableWrite<T>> writes = variable.getWrites();

        if (writes.isEmpty())
            return Optional.empty();

        return Optional.of(writes.get(writes.size() - 1));
    }

    public <T> Optional<VariableWrite<T>> getLastWriteOf(@NonNull String variableName) {
        Optional<Variable<T>> variable = findVariableByName(variableName);

        if (!variable.isPresent())
            return Optional.empty();

        return getLastWriteOf(variable.get());
    }
}
+4 −3
Original line number Diff line number Diff line
package tfm.variables;
package tfm.variables.actions;

import tfm.nodes.Vertex;
import tfm.utils.Scope;

public abstract class VariableAction<T> {

@@ -28,7 +29,7 @@ public abstract class VariableAction<T> {
        this.node = node;
    }

    public abstract boolean isDeclaration();
    public abstract boolean isWrite();

    public abstract boolean isUse();
    public abstract boolean isRead();
}
Loading