more bugs 2

This commit is contained in:
2026-06-27 15:35:20 +02:00
parent 7008f162b5
commit 22a0d3f5aa
3 changed files with 97 additions and 7 deletions

View File

@@ -153,9 +153,8 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
}
if ("this".equals(arg) || arg.startsWith("this.")) {
arg = arg.replaceFirst("^this", actualReceiver);
} else if ("super".equals(arg) || arg.startsWith("super.")) {
arg = arg.replaceFirst("^super", actualReceiver);
}
// Intentionally not replacing 'super' because super should remain statically bound to the superclass of where the code is defined.
}
String[] extractedArg = extractMethodSuffix(arg, methodSuffix);
arg = extractedArg[0];
@@ -728,8 +727,18 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
exprParser.setSource(resolvedValue.toCharArray());
ASTNode exprNode = exprParser.createAST(null);
if (exprNode instanceof MethodInvocation mi) {
if (exprNode instanceof SuperMethodInvocation smi) {
String getterName = smi.getName().getIdentifier();
int lastDot = entryMethod.lastIndexOf('.');
String className = lastDot > 0 ? entryMethod.substring(0, lastDot) : entryMethod;
TypeDeclaration currentTd = context.getTypeDeclaration(className);
if (currentTd != null) {
String receiverType = context.getSuperclassFqn(currentTd);
return constantExtractor.resolveMethodReturnConstant(receiverType, getterName, 0, new HashSet<>(), null);
}
} else if (exprNode instanceof MethodInvocation mi) {
String getterName = mi.getName().getIdentifier();
String propName = methodSuffix.startsWith(".get") ? methodSuffix.substring(4) : methodSuffix.substring(1);
Expression receiver = mi.getExpression();
String receiverName = null;
String receiverType = null;
@@ -738,7 +747,6 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
receiverName = sn.getIdentifier();
receiverType = variableTracer.getVariableDeclaredType(entryMethod, receiverName);
} else if (receiver instanceof MethodInvocation receiverMi) {
String propName = getterName.startsWith("get") ? getterName.substring(3) : getterName;
Expression currentMi = receiverMi;
while (currentMi instanceof MethodInvocation chainMi) {
String mName = chainMi.getName().getIdentifier();
@@ -754,6 +762,13 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
}
currentMi = chainMi.getExpression();
}
} else if (receiver instanceof SuperMethodInvocation) {
int lastDot = entryMethod.lastIndexOf('.');
String className = lastDot > 0 ? entryMethod.substring(0, lastDot) : entryMethod;
TypeDeclaration currentTd = context.getTypeDeclaration(className);
if (currentTd != null) {
receiverType = context.getSuperclassFqn(currentTd);
}
}
if (receiverType == null && path.size() > 1) {

View File

@@ -126,12 +126,12 @@ public class HeuristicCallGraphEngine extends AbstractCallGraphEngine {
protected String postProcessResolvedArgument(org.eclipse.jdt.core.dom.Expression originalExpr, String resolvedValue) {
// Preserve getter calls on 'this' or 'super' for later resolution in trigger parameter tracing
// where we can substitute the actual receiver from the call edge
boolean isThisOrSuperGetter = originalExpr instanceof org.eclipse.jdt.core.dom.MethodInvocation mi
boolean isThisOrSuperGetter = (originalExpr instanceof org.eclipse.jdt.core.dom.MethodInvocation mi
&& (mi.getExpression() instanceof org.eclipse.jdt.core.dom.ThisExpression || mi.getExpression() instanceof org.eclipse.jdt.core.dom.SuperMethodInvocation)
&& mi.arguments().isEmpty();
&& mi.arguments().isEmpty()) || (originalExpr instanceof org.eclipse.jdt.core.dom.SuperMethodInvocation smi && smi.arguments().isEmpty());
if (isThisOrSuperGetter) {
return originalExpr.toString(); // Preserve "this.getTransitionType()" for later substitution
return originalExpr.toString(); // Preserve "this.getTransitionType()" or "super.getEvent()" for later substitution
}
// Narrow resolution for "localVar.getX()" patterns where localVar is initialized