Unverified Commit af64d37d authored by Javier Costa's avatar Javier Costa Committed by GitHub
Browse files

Merge pull request #29 from jacosro/6-method-call-nodes

Resolve 6-method-call-nodes
parents f938e9ed 21428b48
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@
target/
out/
.settings
.attach*

doc/diary/diary.md

0 → 100644
+52 −0
Original line number Diff line number Diff line
# TFM Diary

## 10/5/20

### Implemented

`out` nodes of method calls.

### What is left

#### Distinguish when an out node should exist

An `out` node shouldn't always exist. Primitive types cannot be modified in any way inside a method, while object types can.

An argument to a method call may be any kind of expression. In general, any literal expression, such as `1`, `null`, `""`, `true`, etc. will not have an `out` parameter. So we have to take care of the rest.

An `out` node should exist if there is a possibility to trace the value. And it only exists that possibility when the value comes from a **variable**

So, for the list of expressions that are not literal:
- `ArrayAccess (array[0])`: only if `array` is a variable
- `ArrayCreationExpr`: NO
- `ArrayInitializerExpr`: NO
- `BinaryExpr`: NO, it returns a value
- `CastExpr ((Cast) obj)`: only if `obj` is a variable
- `ClassExpr (obj.class)`: NO
- `ConditionalExpr (1?a:b)`: we'll have to check `a` and `b` expressions
- `FieldAccessExpr (obj.field)`: only if `obj` is a **variable** 
- `InstanceOfExpr`: NO
- `MethodCallExpr (foo.bar(x))`: NO
- `NameExpr`: YES
- `ObjectCreationExpr`: NO
- `SuperExpr`: NO
- `ThisExpr`: NO
- `UnaryExpr (a++)`: we'll have to check the operator (only `++`, `--` return the variable), and if `a` is a variable

## 11/5/20

### Implemented

- Added a CALL node between the node which contains the statement with the `MethodCallExpr` and the `MethodDeclaration`. This node is linked with `in` and `out` nodes. This is because if a statement has more than 1 `MethodCallExpr`, it may have repeated `in` and `out` nodes with the same variables
- Changed `out` node expression from `VariableDeclarationExpr` to `AssignExpr`, where the name of the variable is the argument expression

### WIP

- `OutNodeVariableVisitor`, a visitor that returns the expressions that should be candidate for being `out` nodes. This visitor overrides all `*Expr` methods who may contain a `NameExpr`
    - `ConditionalExpr`: Here, we have `ThenExpr` and `ElseExpr`. As we are performing a static analysis, both should be considered for `out` node in case they represented a variable (This is why `OutNodeVariableVisitor` uses a `List`, and doesn't just return a `String` representing the variable)

### Issues

- `Out` node is generated for `MethodCallExpr` as an argument

- When a `MethodCallExpr` is an argument of another, we have to link its output to the `in` node of the containing one
 No newline at end of file
+30 −7
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@ import org.jgrapht.io.Attribute;
import tfm.arcs.cfg.ControlFlowArc;
import tfm.arcs.pdg.ControlDependencyArc;
import tfm.arcs.pdg.DataDependencyArc;
import tfm.arcs.sdg.CallArc;
import tfm.nodes.GraphNode;

import java.util.HashMap;
@@ -12,6 +13,16 @@ import java.util.Map;
import java.util.Objects;

public abstract class Arc extends DefaultEdge {

    private String label;

    protected Arc() {
    }

    protected Arc(String label) {
        this.label = label;
    }

    /** @see tfm.arcs.cfg.ControlFlowArc */
    public final boolean isControlFlowArc() {
        return this instanceof ControlFlowArc;
@@ -51,16 +62,23 @@ public abstract class Arc extends DefaultEdge {
        throw new UnsupportedOperationException("Not a DataDependencyArc");
    }

    /** @see CallArc */
    public final boolean isCallArc() {
        return this instanceof CallArc;
    }

    public final CallArc asCallArc() {
        if (isCallArc())
            return (CallArc) this;
        throw new UnsupportedOperationException("Not a CallArc");
    }

    @Override
    public String toString() {
        return String.format("%s{%d -> %d}", getClass().getName(),
                ((GraphNode<?>) getSource()).getId(), ((GraphNode<?>) getTarget()).getId());
    }

    public String getLabel() {
        return "";
    }

    public Map<String, Attribute> getDotAttributes() {
        return new HashMap<>();
    }
@@ -73,12 +91,17 @@ public abstract class Arc extends DefaultEdge {
            return false;
        if (!o.getClass().equals(this.getClass()))
            return false;
        return Objects.equals(getSource(), ((Arc) o).getSource()) &&
                Objects.equals(getTarget(), ((Arc) o).getTarget());
        return Objects.equals(getSource(), ((Arc) o).getSource())
                && Objects.equals(getTarget(), ((Arc) o).getTarget())
                && Objects.equals(getLabel(), ((Arc) o).getLabel());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getClass(), getSource(), getTarget());
        return Objects.hash(getClass(), getLabel(), getSource(), getTarget());
    }

    public String getLabel() {
        return label;
    }
}
+1 −19
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@ import tfm.graphs.pdg.PDG;
import tfm.graphs.sdg.SDG;

import java.util.Map;
import java.util.Objects;

/**
 * An arc used in the {@link PDG} and {@link SDG},
@@ -17,16 +16,9 @@ import java.util.Objects;
 * path between the nodes where the variable is not redefined.
 */
public class DataDependencyArc extends Arc {
    private final String variable;

    public DataDependencyArc(String variable) {
        super();
        this.variable = variable;
    }

    @Override
    public String getLabel() {
        return variable;
        super(variable);
    }

    @Override
@@ -36,15 +28,5 @@ public class DataDependencyArc extends Arc {
        map.put("color", DefaultAttribute.createAttribute("red"));
        return map;
    }

    @Override
    public boolean equals(Object o) {
        return super.equals(o) && Objects.equals(variable, ((DataDependencyArc) o).variable);
    }

    @Override
    public int hashCode() {
        return Objects.hash(variable, super.hashCode());
    }
}
+16 −0
Original line number Diff line number Diff line
package tfm.arcs.sdg;

import org.jgrapht.io.Attribute;
import org.jgrapht.io.DefaultAttribute;
import tfm.arcs.Arc;

import java.util.Map;

public class CallArc extends Arc {
    @Override
    public Map<String, Attribute> getDotAttributes() {
        Map<String, Attribute> map = super.getDotAttributes();
        map.put("style", DefaultAttribute.createAttribute("dashed"));
        return map;
    }
}
Loading