Loading src/main/java/tfm/graphs/Graph.java +6 −0 Original line number Diff line number Diff line Loading @@ -147,4 +147,10 @@ public abstract class Graph<NodeType extends GraphNode<?>> extends edg.graphlib. edges.removeAll(node.getOutgoingArrows()); edges.removeAll(node.getIncomingArrows()); } public List<NodeType> findDeclarationsOfVariable(String variable) { return getNodes().stream() .filter(node -> node.getDeclaredVariables().contains(variable)) .collect(Collectors.toList()); } } src/main/java/tfm/nodes/MethodCallNode.java 0 → 100644 +55 −0 Original line number Diff line number Diff line package tfm.nodes; import com.github.javaparser.ast.stmt.ExpressionStmt; import edg.graphlib.Arrow; import org.checkerframework.checker.nullness.qual.NonNull; import tfm.arcs.data.ArcData; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; public class MethodCallNode extends SDGNode<ExpressionStmt> { private List<AuxiliarSDGNode> inParameters; private List<AuxiliarSDGNode> outParameters; public <N1 extends GraphNode<ExpressionStmt>> MethodCallNode(N1 node) { super(node); this.inParameters = new ArrayList<>(); this.outParameters = new ArrayList<>(); } public MethodCallNode(int id, String representation, ExpressionStmt node) { super(id, representation, node); this.inParameters = new ArrayList<>(); this.outParameters = new ArrayList<>(); } public MethodCallNode(int id, String representation, @NonNull ExpressionStmt node, Collection<? extends Arrow<String, ArcData>> incomingArcs, Collection<? extends Arrow<String, ArcData>> outgoingArcs, Set<String> declaredVariables, Set<String> definedVariables, Set<String> usedVariables) { super(id, representation, node, incomingArcs, outgoingArcs, declaredVariables, definedVariables, usedVariables); this.inParameters = new ArrayList<>(); this.outParameters = new ArrayList<>(); } public List<AuxiliarSDGNode> getOutParameters() { return outParameters; } public void setOutParameters(List<AuxiliarSDGNode> outParameters) { this.outParameters = outParameters; } public List<AuxiliarSDGNode> getInParameters() { return inParameters; } public void setInParameters(List<AuxiliarSDGNode> inParameters) { this.inParameters = inParameters; } } src/main/java/tfm/programs/sdg/Example1.java +2 −1 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ public class Example1 { } private static int sum(int x, int y) { return x + y; int res = x + y; return res; } } src/main/java/tfm/visitors/SDGVisitor.java +85 −4 Original line number Diff line number Diff line Loading @@ -3,16 +3,25 @@ package tfm.visitors; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.expr.VariableDeclarationExpr; import com.github.javaparser.ast.stmt.ExpressionStmt; import com.github.javaparser.ast.stmt.Statement; import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import edg.graphlib.Graph; import edg.graphlib.Vertex; import edg.graphlib.Visitor; import tfm.arcs.data.ArcData; import tfm.graphs.PDGGraph; import tfm.graphs.SDGGraph; import tfm.nodes.PDGNode; import tfm.nodes.SDGNode; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.*; import java.util.stream.Collectors; /** * 31/8/19 Loading Loading @@ -63,15 +72,87 @@ public class SDGVisitor extends VoidVisitorAdapter<Void> { if (methodCallExpr.getScope().isPresent()) { String scopeName = methodCallExpr.getScope().get().toString(); if (Objects.equals(scopeName, currentClassNode.getAstNode())) { String currentClassName = currentClassNode.getAstNode().getNameAsString(); // Check if it's a static method call of current class if (!Objects.equals(scopeName, currentClassName)) { // Check if 'scopeName' is a variable List<SDGNode<?>> declarations = sdgGraph.findDeclarationsOfVariable(scopeName); if (declarations.isEmpty()) { // It is a static method call of another class. We don't do anything return; } else { /* It's a variable since it has declarations. We now have to check if the class name is the same as the current class (the object is an instance of our class) */ SDGNode<?> declarationNode = declarations.get(declarations.size() - 1); ExpressionStmt declarationExpr = (ExpressionStmt) declarationNode.getAstNode(); VariableDeclarationExpr variableDeclarationExpr = declarationExpr.getExpression().asVariableDeclarationExpr(); Optional<VariableDeclarator> optionalVariableDeclarator = variableDeclarationExpr.getVariables().stream() .filter(variableDeclarator -> Objects.equals(variableDeclarator.getNameAsString(), scopeName)) .findFirst(); if (!optionalVariableDeclarator.isPresent()) { // should not happen return; } Type variableType = optionalVariableDeclarator.get().getType(); if (!variableType.isClassOrInterfaceType()) { // Not class type return; } if (!Objects.equals(variableType.asClassOrInterfaceType().getNameAsString(), currentClassName)) { // object is not instance of our class return; } // if we got here, the object is instance of our class, so we make the call } } // It's a static method call to a method of the current class } } }; pdgcfgVisitor.visit(methodDeclaration, pdgGraph.getRootNode()); sdgGraph.addNode(methodDeclaration.getNameAsString(), methodDeclaration); pdgGraph.breadthFirstSearch(pdgGraph.getRootNode(), (Visitor<String, ArcData>) (g, v) -> { PDGNode<?> pdgNode = (PDGNode) v; }); pdgGraph.getNodes().stream().skip(1).forEach(pdgNode -> { Statement statement = (Statement) pdgNode.getAstNode(); if (statement.isExpressionStmt()) { Expression expression = statement.asExpressionStmt().getExpression(); expression.findFirst(MethodCallExpr.class).ifPresent(methodCallExpr -> { }); } else { } }); sdgGraph.addPDG(pdgGraph, methodDeclaration); methodDeclaration.accept(this, ignored); Loading Loading
src/main/java/tfm/graphs/Graph.java +6 −0 Original line number Diff line number Diff line Loading @@ -147,4 +147,10 @@ public abstract class Graph<NodeType extends GraphNode<?>> extends edg.graphlib. edges.removeAll(node.getOutgoingArrows()); edges.removeAll(node.getIncomingArrows()); } public List<NodeType> findDeclarationsOfVariable(String variable) { return getNodes().stream() .filter(node -> node.getDeclaredVariables().contains(variable)) .collect(Collectors.toList()); } }
src/main/java/tfm/nodes/MethodCallNode.java 0 → 100644 +55 −0 Original line number Diff line number Diff line package tfm.nodes; import com.github.javaparser.ast.stmt.ExpressionStmt; import edg.graphlib.Arrow; import org.checkerframework.checker.nullness.qual.NonNull; import tfm.arcs.data.ArcData; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; public class MethodCallNode extends SDGNode<ExpressionStmt> { private List<AuxiliarSDGNode> inParameters; private List<AuxiliarSDGNode> outParameters; public <N1 extends GraphNode<ExpressionStmt>> MethodCallNode(N1 node) { super(node); this.inParameters = new ArrayList<>(); this.outParameters = new ArrayList<>(); } public MethodCallNode(int id, String representation, ExpressionStmt node) { super(id, representation, node); this.inParameters = new ArrayList<>(); this.outParameters = new ArrayList<>(); } public MethodCallNode(int id, String representation, @NonNull ExpressionStmt node, Collection<? extends Arrow<String, ArcData>> incomingArcs, Collection<? extends Arrow<String, ArcData>> outgoingArcs, Set<String> declaredVariables, Set<String> definedVariables, Set<String> usedVariables) { super(id, representation, node, incomingArcs, outgoingArcs, declaredVariables, definedVariables, usedVariables); this.inParameters = new ArrayList<>(); this.outParameters = new ArrayList<>(); } public List<AuxiliarSDGNode> getOutParameters() { return outParameters; } public void setOutParameters(List<AuxiliarSDGNode> outParameters) { this.outParameters = outParameters; } public List<AuxiliarSDGNode> getInParameters() { return inParameters; } public void setInParameters(List<AuxiliarSDGNode> inParameters) { this.inParameters = inParameters; } }
src/main/java/tfm/programs/sdg/Example1.java +2 −1 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ public class Example1 { } private static int sum(int x, int y) { return x + y; int res = x + y; return res; } }
src/main/java/tfm/visitors/SDGVisitor.java +85 −4 Original line number Diff line number Diff line Loading @@ -3,16 +3,25 @@ package tfm.visitors; import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.body.VariableDeclarator; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.MethodCallExpr; import com.github.javaparser.ast.expr.VariableDeclarationExpr; import com.github.javaparser.ast.stmt.ExpressionStmt; import com.github.javaparser.ast.stmt.Statement; import com.github.javaparser.ast.type.Type; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import edg.graphlib.Graph; import edg.graphlib.Vertex; import edg.graphlib.Visitor; import tfm.arcs.data.ArcData; import tfm.graphs.PDGGraph; import tfm.graphs.SDGGraph; import tfm.nodes.PDGNode; import tfm.nodes.SDGNode; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.*; import java.util.stream.Collectors; /** * 31/8/19 Loading Loading @@ -63,15 +72,87 @@ public class SDGVisitor extends VoidVisitorAdapter<Void> { if (methodCallExpr.getScope().isPresent()) { String scopeName = methodCallExpr.getScope().get().toString(); if (Objects.equals(scopeName, currentClassNode.getAstNode())) { String currentClassName = currentClassNode.getAstNode().getNameAsString(); // Check if it's a static method call of current class if (!Objects.equals(scopeName, currentClassName)) { // Check if 'scopeName' is a variable List<SDGNode<?>> declarations = sdgGraph.findDeclarationsOfVariable(scopeName); if (declarations.isEmpty()) { // It is a static method call of another class. We don't do anything return; } else { /* It's a variable since it has declarations. We now have to check if the class name is the same as the current class (the object is an instance of our class) */ SDGNode<?> declarationNode = declarations.get(declarations.size() - 1); ExpressionStmt declarationExpr = (ExpressionStmt) declarationNode.getAstNode(); VariableDeclarationExpr variableDeclarationExpr = declarationExpr.getExpression().asVariableDeclarationExpr(); Optional<VariableDeclarator> optionalVariableDeclarator = variableDeclarationExpr.getVariables().stream() .filter(variableDeclarator -> Objects.equals(variableDeclarator.getNameAsString(), scopeName)) .findFirst(); if (!optionalVariableDeclarator.isPresent()) { // should not happen return; } Type variableType = optionalVariableDeclarator.get().getType(); if (!variableType.isClassOrInterfaceType()) { // Not class type return; } if (!Objects.equals(variableType.asClassOrInterfaceType().getNameAsString(), currentClassName)) { // object is not instance of our class return; } // if we got here, the object is instance of our class, so we make the call } } // It's a static method call to a method of the current class } } }; pdgcfgVisitor.visit(methodDeclaration, pdgGraph.getRootNode()); sdgGraph.addNode(methodDeclaration.getNameAsString(), methodDeclaration); pdgGraph.breadthFirstSearch(pdgGraph.getRootNode(), (Visitor<String, ArcData>) (g, v) -> { PDGNode<?> pdgNode = (PDGNode) v; }); pdgGraph.getNodes().stream().skip(1).forEach(pdgNode -> { Statement statement = (Statement) pdgNode.getAstNode(); if (statement.isExpressionStmt()) { Expression expression = statement.asExpressionStmt().getExpression(); expression.findFirst(MethodCallExpr.class).ifPresent(methodCallExpr -> { }); } else { } }); sdgGraph.addPDG(pdgGraph, methodDeclaration); methodDeclaration.accept(this, ignored); Loading