Newer
Older
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.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;
* Asumimos que procesamos 1 clase con uno o mas metodos estaticos donde el primer metodo es el main
public class SDGVisitor extends VoidVisitorAdapter<Void> {
private SDGNode<ClassOrInterfaceDeclaration> currentClassNode;
public SDGVisitor(SDGGraph sdgGraph) {
this.sdgGraph = sdgGraph;
this.pdgGraphs = new ArrayList<>();
}
@Override
public void visit(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, Void ignored) {
if (sdgGraph.getRootNode() != null) {
throw new IllegalStateException("¡Solo podemos procesar una clase por el momento!");
}
if (classOrInterfaceDeclaration.isInterface()) {
throw new IllegalArgumentException("¡Las interfaces no estan permitidas!");
}
currentClassNode = sdgGraph.addNode(
"class " + classOrInterfaceDeclaration.getNameAsString(),
classOrInterfaceDeclaration
);
sdgGraph.setRootVertex(currentClassNode);
classOrInterfaceDeclaration.accept(this, ignored);
@Override
public void visit(MethodDeclaration methodDeclaration, Void ignored) {
if (!methodDeclaration.getBody().isPresent())
return;
PDGGraph pdgGraph = new PDGGraph();
PDGCFGVisitor pdgcfgVisitor = new PDGCFGVisitor(pdgGraph) {
@Override
public void visit(MethodCallExpr methodCallExpr, PDGNode<?> parent) {
if (methodCallExpr.getScope().isPresent()) {
String scopeName = methodCallExpr.getScope().get().toString();
String currentClassName = currentClassNode.getAstNode().getNameAsString();
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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);
pdgGraphs.add(pdgGraph);
// @Override
// public void visit(CompilationUnit compilationUnit, Void ignored) {
// super.visit(compilationUnit, ignored);
//
//
// }