Commit 7cb05e5d authored by jacosro's avatar jacosro
Browse files

Added diary

parent 34a967f7
Loading
Loading
Loading
Loading

doc/diary/diary.md

0 → 100644
+34 −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 if `a` is a variable
 No newline at end of file
+50 −0
Original line number Diff line number Diff line
package tfm.utils;

import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.resolution.UnsolvedSymbolException;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import tfm.nodes.GraphNode;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class SymbolSolverWrapper {

    private static final SymbolSolverWrapper instance = new SymbolSolverWrapper();
    private static final List<TypeSolver> typeSolvers = new ArrayList<>();

    private SymbolSolverWrapper() {

    }

    public static void addTypeSolver(TypeSolver typeSolver) {
        typeSolvers.add(typeSolver);
    }

    public static SymbolSolverWrapper getInstance() {
        return instance;
    }

    private <N extends Node> Optional<N> findNodeFrom(MethodCallExpr methodCallExpr) {
        CombinedTypeSolver combinedTypeSolver = new CombinedTypeSolver();

        try {
            SymbolReference<ResolvedMethodDeclaration> solver = JavaParserFacade.get(typeSolver).solve(methodCallExpr);

            return solver.isSolved()
                    ? solver.getCorrespondingDeclaration().toAst()
                    .flatMap(methodDeclaration -> sdg.findNodeByASTNode(methodDeclaration))
                    : Optional.empty();
        } catch (UnsolvedSymbolException e) {
            return Optional.empty();
        }
    }
}