From a2578661214e1f8fa74f8fa1ad5f7c5ac7f3b16b Mon Sep 17 00:00:00 2001 From: Saurabh Sinha Date: Fri, 7 Jun 2024 11:13:24 -0400 Subject: [PATCH] Optimized type/expression resolution and improved exception handling Signed-off-by: Saurabh Sinha --- .../java/com/ibm/northstar/SymbolTable.java | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/ibm/northstar/SymbolTable.java b/src/main/java/com/ibm/northstar/SymbolTable.java index 8cc5a786..1f6dcc55 100644 --- a/src/main/java/com/ibm/northstar/SymbolTable.java +++ b/src/main/java/com/ibm/northstar/SymbolTable.java @@ -39,6 +39,8 @@ public class SymbolTable { private static JavaSymbolSolver javaSymbolSolver; + private static Set unresolvedTypes = new HashSet<>(); + private static Set unresolvedExpressions = new HashSet<>(); /** * Processes the given compilation unit to extract information about classes and @@ -408,6 +410,7 @@ private static List getAccessedFields(Optional callableBody, // process field access expressions in the callable callableBody.ifPresent(cb -> cb.findAll(FieldAccessExpr.class) .stream() + .filter(faExpr -> faExpr.getParentNode().isPresent() && !(faExpr.getParentNode().get() instanceof FieldAccessExpr)) .map(faExpr -> { String fieldDeclaringType = resolveExpression(faExpr.getScope()); if (!fieldDeclaringType.isEmpty()) { @@ -474,12 +477,8 @@ private static List getCallSites(Optional callableBody) { 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()); - } + String instantiatedType = resolveType(objectCreationExpr.getType()); + // resolve arguments of the constructor call to types List arguments = objectCreationExpr.getArguments().stream() .map(arg -> resolveExpression(arg)).collect(Collectors.toList()); @@ -538,13 +537,17 @@ private static CallSite createCallSite(Expression callExpr, String calleeName, S * @return Resolved type name or empty string if type resolution fails */ private static String resolveExpression(Expression expression) { - try { - ResolvedType resolvedType = javaSymbolSolver.calculateType(expression); - if (resolvedType.isReferenceType() || resolvedType.isUnionType()) { - return resolvedType.describe(); + // perform expression resolution if resolution of this expression did not fail previously + if (!unresolvedExpressions.contains(expression.toString())) { + try { + ResolvedType resolvedType = javaSymbolSolver.calculateType(expression); + if (resolvedType.isReferenceType() || resolvedType.isUnionType()) { + return resolvedType.describe(); + } + } catch (RuntimeException exception) { + Log.debug("Could not resolve expression: " + expression + ": " + exception.getMessage()); + unresolvedExpressions.add(expression.toString()); } - } catch (RuntimeException exception) { - Log.warn("Could not resolve expression: "+expression+"\n"+exception.getMessage()); } return ""; } @@ -556,12 +559,16 @@ private static String resolveExpression(Expression expression) { * @return Resolved (qualified) type name */ private static String resolveType(Type type) { - try { - return type.resolve().describe(); - } catch (UnsolvedSymbolException | IllegalStateException | MethodAmbiguityException e) { - Log.warn("Could not resolve "+type.asString()+": "+e.getMessage()); - return type.asString(); + // perform type resolution if resolution of this type did not fail previously + if (!unresolvedTypes.contains(type.asString())) { + try { + return type.resolve().describe(); + } catch (RuntimeException e) { + Log.warn("Could not resolve type: " + type.asString() + ": " + e.getMessage()); + unresolvedTypes.add(type.asString()); + } } + return type.asString(); } /**