From bc232dfd2e804fe0ee5bba30e658d4bdb1b8de16 Mon Sep 17 00:00:00 2001 From: Kamil Patryk Kozakowski Date: Thu, 25 Jun 2026 00:18:46 +0200 Subject: [PATCH] heuristics updated consolidation --- .../service/AbstractCallGraphEngine.java | 178 +++++++++--------- .../service/HeuristicCallGraphEngine.java | 86 --------- 2 files changed, 89 insertions(+), 175 deletions(-) diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AbstractCallGraphEngine.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AbstractCallGraphEngine.java index 7e7a8f6..b0ebab1 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AbstractCallGraphEngine.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/AbstractCallGraphEngine.java @@ -26,94 +26,6 @@ import java.util.*; String resolve(Expression rhs, Map paramValues, TypeDeclaration td); } - protected Map buildParameterValuesMap(String caller, String target, - Map> callGraph, List path, int pathIndex) { - Map paramValues = new HashMap<>(); - List edges = callGraph.get(caller); - if (edges == null) { - return paramValues; - } - - for (CallEdge edge : edges) { - if (edge.getTargetMethod().equals(target) || isHeuristicMatch(edge.getTargetMethod(), target)) { - List args = edge.getArguments(); - if (args == null || args.isEmpty()) break; - - int lastDot = target.lastIndexOf('.'); - if (lastDot < 0) break; - String className = target.substring(0, lastDot); - String methodName = target.substring(lastDot + 1); - - TypeDeclaration td = context.getTypeDeclaration(className); - if (td == null) break; - - MethodDeclaration md = context.findMethodDeclaration(td, methodName, true); - if (md == null) break; - - List paramNames = new ArrayList<>(); - for (Object paramObj : md.parameters()) { - SingleVariableDeclaration param = (SingleVariableDeclaration) paramObj; - paramNames.add(param.getName().getIdentifier()); - } - - int minSize = Math.min(paramNames.size(), args.size()); - for (int j = 0; j < minSize; j++) { - String argValue = args.get(j); - String resolvedArgValue = resolveArgumentValue(argValue, caller, path, pathIndex, callGraph); - paramValues.put(paramNames.get(j), resolvedArgValue); - } - break; - } - } - return paramValues; - } - - protected String resolveArgumentValue(String argValue, String callerMethod, List path, int pathIndex, Map> callGraph) { - if (argValue == null) return null; - if (argValue.contains(".") || argValue.startsWith("new ") || argValue.matches(".*[0-9].*")) { - return argValue; - } - - int callerIndex = path.indexOf(callerMethod); - if (callerIndex <= 0) return argValue; - - String prevCaller = path.get(callerIndex - 1); - List prevEdges = callGraph.get(prevCaller); - if (prevEdges == null) return argValue; - - for (CallEdge edge : prevEdges) { - if (edge.getTargetMethod().equals(callerMethod) || isHeuristicMatch(edge.getTargetMethod(), callerMethod)) { - List prevArgs = edge.getArguments(); - if (prevArgs == null || prevArgs.isEmpty()) break; - - int lastDot = callerMethod.lastIndexOf('.'); - if (lastDot < 0) break; - String className = callerMethod.substring(0, lastDot); - String methodName = callerMethod.substring(lastDot + 1); - - TypeDeclaration td = context.getTypeDeclaration(className); - if (td == null) break; - - MethodDeclaration md = context.findMethodDeclaration(td, methodName, true); - if (md == null) break; - - List paramNames = new ArrayList<>(); - for (Object paramObj : md.parameters()) { - SingleVariableDeclaration param = (SingleVariableDeclaration) paramObj; - paramNames.add(param.getName().getIdentifier()); - } - - int paramIdx = paramNames.indexOf(argValue); - if (paramIdx >= 0 && paramIdx < prevArgs.size()) { - String prevArg = prevArgs.get(paramIdx); - return resolveArgumentValue(prevArg, prevCaller, path, pathIndex, callGraph); - } - break; - } - } - return argValue; - } - public List findChains(List entryPoints, List triggers) { Map> callGraph = buildCallGraph(); List chains = new ArrayList<>(); @@ -166,7 +78,8 @@ import java.util.*; int paramIndex = getParameterIndex(target, currentParamName); if (paramIndex < 0) { // Not a parameter. Maybe it's a local variable initialized from a parameter or method call? - String tracedVar = traceLocalVariable(target, currentParamName); + Map parameterValues = buildParameterValuesMap(caller, target, callGraph, path, i); + String tracedVar = traceLocalVariable(target, currentParamName, parameterValues); if (tracedVar != null && !tracedVar.equals(currentParamName)) { // Extract method calls like .getType() from the traced variable String[] extractedTraced = extractMethodSuffix(tracedVar, methodSuffix); @@ -1655,6 +1568,93 @@ import java.util.*; return result; } + protected java.util.Map buildParameterValuesMap(String caller, String target, Map> callGraph, List path, int pathIndex) { + java.util.Map paramValues = new java.util.HashMap<>(); + List edges = callGraph.get(caller); + if (edges == null) { + return paramValues; + } + + for (CallEdge edge : edges) { + if (edge.getTargetMethod().equals(target) || isHeuristicMatch(edge.getTargetMethod(), target)) { + List args = edge.getArguments(); + if (args == null || args.isEmpty()) break; + + int lastDot = target.lastIndexOf('.'); + if (lastDot < 0) break; + String className = target.substring(0, lastDot); + String methodName = target.substring(lastDot + 1); + + TypeDeclaration td = context.getTypeDeclaration(className); + if (td == null) break; + + MethodDeclaration md = context.findMethodDeclaration(td, methodName, true); + if (md == null) break; + + List paramNames = new java.util.ArrayList<>(); + for (Object paramObj : md.parameters()) { + org.eclipse.jdt.core.dom.SingleVariableDeclaration param = (org.eclipse.jdt.core.dom.SingleVariableDeclaration) paramObj; + paramNames.add(param.getName().getIdentifier()); + } + + int minSize = java.lang.Math.min(paramNames.size(), args.size()); + for (int j = 0; j < minSize; j++) { + String argValue = args.get(j); + String resolvedArgValue = resolveArgumentValue(argValue, caller, path, pathIndex, callGraph); + paramValues.put(paramNames.get(j), resolvedArgValue); + } + break; + } + } + return paramValues; + } + + protected String resolveArgumentValue(String argValue, String callerMethod, List path, int pathIndex, Map> callGraph) { + if (argValue == null) return null; + if (argValue.contains(".") || argValue.startsWith("new ") || argValue.matches(".*[0-9].*")) { + return argValue; + } + + int callerIndex = path.indexOf(callerMethod); + if (callerIndex <= 0) return argValue; + + String prevCaller = path.get(callerIndex - 1); + List prevEdges = callGraph.get(prevCaller); + if (prevEdges == null) return argValue; + + for (CallEdge edge : prevEdges) { + if (edge.getTargetMethod().equals(callerMethod) || isHeuristicMatch(edge.getTargetMethod(), callerMethod)) { + List prevArgs = edge.getArguments(); + if (prevArgs == null || prevArgs.isEmpty()) break; + + int lastDot = callerMethod.lastIndexOf('.'); + if (lastDot < 0) break; + String className = callerMethod.substring(0, lastDot); + String methodName = callerMethod.substring(lastDot + 1); + + TypeDeclaration td = context.getTypeDeclaration(className); + if (td == null) break; + + MethodDeclaration md = context.findMethodDeclaration(td, methodName, true); + if (md == null) break; + + List paramNames = new java.util.ArrayList<>(); + for (Object paramObj : md.parameters()) { + org.eclipse.jdt.core.dom.SingleVariableDeclaration param = (org.eclipse.jdt.core.dom.SingleVariableDeclaration) paramObj; + paramNames.add(param.getName().getIdentifier()); + } + + int paramIdx = paramNames.indexOf(argValue); + if (paramIdx >= 0 && paramIdx < prevArgs.size()) { + String prevArg = prevArgs.get(paramIdx); + return resolveArgumentValue(prevArg, prevCaller, path, pathIndex, callGraph); + } + break; + } + } + return argValue; + } + protected org.eclipse.jdt.core.dom.Expression traceLocalSetter(String methodFqn, String varName, String getterName) { if (methodFqn == null || !methodFqn.contains(".")) return null; String className = methodFqn.substring(0, methodFqn.lastIndexOf('.')); diff --git a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/HeuristicCallGraphEngine.java b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/HeuristicCallGraphEngine.java index 1dc53ad..dc31169 100644 --- a/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/HeuristicCallGraphEngine.java +++ b/state_machine_exporter/src/main/java/click/kamil/springstatemachineexporter/analysis/service/HeuristicCallGraphEngine.java @@ -839,90 +839,4 @@ public class HeuristicCallGraphEngine extends AbstractCallGraphEngine { return initExpr[0]; } - private java.util.Map buildParameterValuesMap(String caller, String target, Map> callGraph, List path, int pathIndex) { - java.util.Map paramValues = new java.util.HashMap<>(); - List edges = callGraph.get(caller); - if (edges == null) { - return paramValues; - } - - for (CallEdge edge : edges) { - if (edge.getTargetMethod().equals(target) || isHeuristicMatch(edge.getTargetMethod(), target)) { - List args = edge.getArguments(); - if (args == null || args.isEmpty()) break; - - int lastDot = target.lastIndexOf('.'); - if (lastDot < 0) break; - String className = target.substring(0, lastDot); - String methodName = target.substring(lastDot + 1); - - TypeDeclaration td = context.getTypeDeclaration(className); - if (td == null) break; - - MethodDeclaration md = context.findMethodDeclaration(td, methodName, true); - if (md == null) break; - - List paramNames = new java.util.ArrayList<>(); - for (Object paramObj : md.parameters()) { - org.eclipse.jdt.core.dom.SingleVariableDeclaration param = (org.eclipse.jdt.core.dom.SingleVariableDeclaration) paramObj; - paramNames.add(param.getName().getIdentifier()); - } - - int minSize = java.lang.Math.min(paramNames.size(), args.size()); - for (int j = 0; j < minSize; j++) { - String argValue = args.get(j); - String resolvedArgValue = resolveArgumentValue(argValue, caller, path, pathIndex, callGraph); - paramValues.put(paramNames.get(j), resolvedArgValue); - } - break; - } - } - return paramValues; - } - - private String resolveArgumentValue(String argValue, String callerMethod, List path, int pathIndex, Map> callGraph) { - if (argValue == null) return null; - if (argValue.contains(".") || argValue.startsWith("new ") || argValue.matches(".*[0-9].*")) { - return argValue; - } - - int callerIndex = path.indexOf(callerMethod); - if (callerIndex <= 0) return argValue; - - String prevCaller = path.get(callerIndex - 1); - List prevEdges = callGraph.get(prevCaller); - if (prevEdges == null) return argValue; - - for (CallEdge edge : prevEdges) { - if (edge.getTargetMethod().equals(callerMethod) || isHeuristicMatch(edge.getTargetMethod(), callerMethod)) { - List prevArgs = edge.getArguments(); - if (prevArgs == null || prevArgs.isEmpty()) break; - - int lastDot = callerMethod.lastIndexOf('.'); - if (lastDot < 0) break; - String className = callerMethod.substring(0, lastDot); - String methodName = callerMethod.substring(lastDot + 1); - - TypeDeclaration td = context.getTypeDeclaration(className); - if (td == null) break; - - MethodDeclaration md = context.findMethodDeclaration(td, methodName, true); - if (md == null) break; - - List paramNames = new java.util.ArrayList<>(); - for (Object paramObj : md.parameters()) { - org.eclipse.jdt.core.dom.SingleVariableDeclaration param = (org.eclipse.jdt.core.dom.SingleVariableDeclaration) paramObj; - paramNames.add(param.getName().getIdentifier()); - } - - int paramIdx = paramNames.indexOf(argValue); - if (paramIdx >= 0 && paramIdx < prevArgs.size()) { - String prevArg = prevArgs.get(paramIdx); - return resolveArgumentValue(prevArg, prevCaller, path, pathIndex, callGraph); - } - break; - } - } - return argValue; - } } \ No newline at end of file