diff --git a/src/main/java/com/ibm/northstar/SymbolTable.java b/src/main/java/com/ibm/northstar/SymbolTable.java index 226dc571..59c2803e 100644 --- a/src/main/java/com/ibm/northstar/SymbolTable.java +++ b/src/main/java/com/ibm/northstar/SymbolTable.java @@ -300,6 +300,7 @@ private static Pair processCallableDeclaration(CallableDeclara callableNode.setCalledMethodDeclaringTypes(getCalledMethodDeclaringTypes(body)); callableNode.setAccessedFields(getAccessedFields(body, classFields, typeName)); + callableNode.setCallSites(getCallSites(body)); String callableSignature = (callableDecl instanceof MethodDeclaration) ? callableDecl.getSignature().asString() : callableDecl.getSignature().asString().replace(callableDecl.getSignature().getName(), ""); return Pair.of(callableSignature, callableNode); @@ -425,6 +426,53 @@ private static List getCalledMethodDeclaringTypes(Optional ca return new ArrayList<>(calledMethodDeclaringTypes); } + /** + * Returns information about call sites in the given callable. The information includes: + * the method name, the declaring type name, and types of arguments used in method call. + * + * @param callableBody callable to compute call-site information for + * @return list of call sites + */ + private static List getCallSites(Optional callableBody) { + List callSites = new ArrayList<>(); + if (callableBody.isEmpty()) { + return callSites; + } + for (MethodCallExpr methodCallExpr : callableBody.get().findAll(MethodCallExpr.class)) { + // resolve declaring type for called method + String declaringType = ""; + if (methodCallExpr.getScope().isPresent()) { + declaringType = resolveExpression(methodCallExpr.getScope().get()); + if (declaringType.contains(" | ")) { + declaringType = declaringType.split(" \\| ")[0]; + } + } + + // 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(callSite); + } + return callSites; + } + /** * 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 new file mode 100644 index 00000000..314045b2 --- /dev/null +++ b/src/main/java/com/ibm/northstar/entities/CallSite.java @@ -0,0 +1,16 @@ +package com.ibm.northstar.entities; + +import lombok.Data; + +import java.util.List; + +@Data +public class CallSite { + private String methodName; + private String declaringType; + private List argumentTypes; + private int startLine; + private int startColumn; + private int endLine; + private int endColumn; +} diff --git a/src/main/java/com/ibm/northstar/entities/Callable.java b/src/main/java/com/ibm/northstar/entities/Callable.java index 27a18b2e..f63341c7 100644 --- a/src/main/java/com/ibm/northstar/entities/Callable.java +++ b/src/main/java/com/ibm/northstar/entities/Callable.java @@ -22,4 +22,5 @@ public class Callable { private List referencedTypes; private List accessedFields; private List calledMethodDeclaringTypes; + private List callSites; }