From e580cfa14b7a6f31115f53a5f1c285c6ca11af30 Mon Sep 17 00:00:00 2001 From: Saurabh Sinha Date: Mon, 27 May 2024 21:09:27 -0400 Subject: [PATCH 1/2] Updated call sites information to indicate static calls and include constructor calls. Signed-off-by: Saurabh Sinha --- .../java/com/ibm/northstar/SymbolTable.java | 81 ++++++++++++++----- .../com/ibm/northstar/entities/CallSite.java | 2 + 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/ibm/northstar/SymbolTable.java b/src/main/java/com/ibm/northstar/SymbolTable.java index 078d67f1..151f33e1 100644 --- a/src/main/java/com/ibm/northstar/SymbolTable.java +++ b/src/main/java/com/ibm/northstar/SymbolTable.java @@ -7,10 +7,7 @@ import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.body.*; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.FieldAccessExpr; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; +import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.nodeTypes.NodeWithName; import com.github.javaparser.ast.stmt.BlockStmt; import com.github.javaparser.ast.type.ReferenceType; @@ -479,39 +476,81 @@ private static List getCallSites(Optional callableBody) { } for (MethodCallExpr methodCallExpr : callableBody.get().findAll(MethodCallExpr.class)) { // resolve declaring type for called method + boolean isStaticCall = false; String declaringType = ""; if (methodCallExpr.getScope().isPresent()) { + Expression scopeExpr = methodCallExpr.getScope().get(); declaringType = resolveExpression(methodCallExpr.getScope().get()); if (declaringType.contains(" | ")) { declaringType = declaringType.split(" \\| ")[0]; } + String declaringTypeName = declaringType.substring(declaringType.lastIndexOf(".")+1); + if (declaringTypeName.equals(scopeExpr.toString())) { + isStaticCall = true; + } } - // resolve arguments of the method call to types List arguments = methodCallExpr.getArguments().stream() .map(arg -> resolveExpression(arg)).collect(Collectors.toList()); - // add a new call site object - CallSite callSite = new CallSite(); - callSite.setMethodName(methodCallExpr.getNameAsString()); - callSite.setDeclaringType(declaringType); - callSite.setArgumentTypes(arguments); - if (methodCallExpr.getRange().isPresent()) { - callSite.setStartLine(methodCallExpr.getRange().get().begin.line); - callSite.setStartColumn(methodCallExpr.getRange().get().begin.column); - callSite.setEndLine(methodCallExpr.getRange().get().end.line); - callSite.setEndColumn(methodCallExpr.getRange().get().end.column); - } else { - callSite.setStartLine(-1); - callSite.setStartColumn(-1); - callSite.setEndLine(-1); - callSite.setEndColumn(-1); + callSites.add(createCallSite(methodCallExpr, methodCallExpr.getNameAsString(), declaringType, + arguments, isStaticCall, false)); + } + + for (ObjectCreationExpr objectCreationExpr : callableBody.get().findAll(ObjectCreationExpr.class)) { + // resolve declaring type for called method + String instantiatedType = objectCreationExpr.getTypeAsString(); + try { + instantiatedType = objectCreationExpr.getType().resolve().describe(); + } catch (UnsolvedSymbolException | IllegalStateException e) { + Log.warn("Could not resolve "+instantiatedType+": "+e.getMessage()); } - callSites.add(callSite); + // resolve arguments of the constructor call to types + List arguments = objectCreationExpr.getArguments().stream() + .map(arg -> resolveExpression(arg)).collect(Collectors.toList()); + + // add a new call site object + callSites.add(createCallSite(objectCreationExpr, "", + instantiatedType, arguments, false, true)); } + return callSites; } + /** + * Creates and returns a new CallSite object for the given expression, which can be a method-call or + * object-creation expression. + * + * @param callExpr + * @param calleeName + * @param declaringType + * @param arguments + * @param isStaticCall + * @param isConstructorCall + * @return + */ + private static CallSite createCallSite(Expression callExpr, String calleeName, String declaringType, + List arguments, boolean isStaticCall, boolean isConstructorCall) { + CallSite callSite = new CallSite(); + callSite.setMethodName(calleeName); + callSite.setDeclaringType(declaringType); + callSite.setArgumentTypes(arguments); + callSite.setStaticCall(isStaticCall); + callSite.setConstructorCall(isConstructorCall); + if (callExpr.getRange().isPresent()) { + callSite.setStartLine(callExpr.getRange().get().begin.line); + callSite.setStartColumn(callExpr.getRange().get().begin.column); + callSite.setEndLine(callExpr.getRange().get().end.line); + callSite.setEndColumn(callExpr.getRange().get().end.column); + } else { + callSite.setStartLine(-1); + callSite.setStartColumn(-1); + callSite.setEndLine(-1); + callSite.setEndColumn(-1); + } + return callSite; + } + /** * Calculates type for the given expression and returns the resolved type name, or empty string if * exception occurs during type resolution. diff --git a/src/main/java/com/ibm/northstar/entities/CallSite.java b/src/main/java/com/ibm/northstar/entities/CallSite.java index 314045b2..d34015a8 100644 --- a/src/main/java/com/ibm/northstar/entities/CallSite.java +++ b/src/main/java/com/ibm/northstar/entities/CallSite.java @@ -9,6 +9,8 @@ public class CallSite { private String methodName; private String declaringType; private List argumentTypes; + private boolean isStaticCall; + private boolean isConstructorCall; private int startLine; private int startColumn; private int endLine; From 6ad7e6c40f63494b78c8915008b3afd27bd71431 Mon Sep 17 00:00:00 2001 From: Saurabh Sinha Date: Mon, 27 May 2024 21:36:36 -0400 Subject: [PATCH 2/2] Handle unresolved types for static calls Signed-off-by: Saurabh Sinha --- src/main/java/com/ibm/northstar/SymbolTable.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/ibm/northstar/SymbolTable.java b/src/main/java/com/ibm/northstar/SymbolTable.java index 151f33e1..c85c5be8 100644 --- a/src/main/java/com/ibm/northstar/SymbolTable.java +++ b/src/main/java/com/ibm/northstar/SymbolTable.java @@ -484,7 +484,8 @@ private static List getCallSites(Optional callableBody) { if (declaringType.contains(" | ")) { declaringType = declaringType.split(" \\| ")[0]; } - String declaringTypeName = declaringType.substring(declaringType.lastIndexOf(".")+1); + String declaringTypeName = declaringType.contains(".") ? + declaringType.substring(declaringType.lastIndexOf(".")+1) : declaringType; if (declaringTypeName.equals(scopeExpr.toString())) { isStaticCall = true; }