edge case fixes

This commit is contained in:
2026-06-21 18:45:24 +02:00
parent cbb00e8a0f
commit 32de0a51c6
2 changed files with 154 additions and 5 deletions

View File

@@ -261,6 +261,7 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
if (varName != null && declaredType == null) {
for (String methodFqn : path) {
declaredType = getVariableDeclaredType(methodFqn, varName);
System.out.println("DEBUG getVariableDeclaredType(" + methodFqn + ", " + varName + ") = " + declaredType);
if (declaredType != null) {
sourceMethod = methodFqn;
break;
@@ -383,11 +384,12 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
String methodName = methodFqn.substring(methodFqn.lastIndexOf('.') + 1);
TypeDeclaration td = context.getTypeDeclaration(className);
if (td != null) {
String cleanFieldName = varName.startsWith("this.") ? varName.substring(5) : varName;
MethodDeclaration md = context.findMethodDeclaration(td, methodName, true);
if (md != null) {
for (Object pObj : md.parameters()) {
SingleVariableDeclaration svd = (SingleVariableDeclaration) pObj;
if (svd.getName().getIdentifier().equals(varName)) {
if (svd.getName().getIdentifier().equals(cleanFieldName)) {
return svd.getType().toString();
}
}
@@ -398,15 +400,71 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
public boolean visit(VariableDeclarationStatement node) {
for (Object fragObj : node.fragments()) {
VariableDeclarationFragment frag = (VariableDeclarationFragment) fragObj;
if (frag.getName().getIdentifier().equals(varName)) {
if (frag.getName().getIdentifier().equals(cleanFieldName)) {
foundType[0] = node.getType().toString();
}
}
return super.visit(node);
}
@Override
public boolean visit(org.eclipse.jdt.core.dom.LambdaExpression node) {
for (Object paramObj : node.parameters()) {
org.eclipse.jdt.core.dom.VariableDeclaration param = (org.eclipse.jdt.core.dom.VariableDeclaration) paramObj;
if (param.getName().getIdentifier().equals(cleanFieldName)) {
if (param instanceof SingleVariableDeclaration svd && svd.getType() != null) {
foundType[0] = svd.getType().toString();
return false;
}
org.eclipse.jdt.core.dom.ASTNode parent = node.getParent();
if (parent instanceof org.eclipse.jdt.core.dom.MethodInvocation mi) {
org.eclipse.jdt.core.dom.Expression caller = mi.getExpression();
if (caller instanceof org.eclipse.jdt.core.dom.SimpleName callerSn) {
String callerName = callerSn.getIdentifier();
if (!callerName.equals(cleanFieldName)) {
String callerType = getVariableDeclaredType(methodFqn, callerName);
if (callerType != null && callerType.contains("<")) {
int start = callerType.indexOf('<');
int end = callerType.lastIndexOf('>');
if (start >= 0 && end > start) {
foundType[0] = callerType.substring(start + 1, end);
return false;
}
}
}
} else if (caller instanceof org.eclipse.jdt.core.dom.FieldAccess fa) {
String callerName = fa.getName().getIdentifier();
if (!callerName.equals(cleanFieldName)) {
String callerType = getVariableDeclaredType(methodFqn, callerName);
if (callerType != null && callerType.contains("<")) {
int start = callerType.indexOf('<');
int end = callerType.lastIndexOf('>');
if (start >= 0 && end > start) {
foundType[0] = callerType.substring(start + 1, end);
return false;
}
}
}
}
}
}
}
return super.visit(node);
}
});
}
return foundType[0];
if (foundType[0] != null) return foundType[0];
}
// Fallback to fields
for (org.eclipse.jdt.core.dom.FieldDeclaration fd : td.getFields()) {
for (Object fragObj : fd.fragments()) {
org.eclipse.jdt.core.dom.VariableDeclarationFragment frag = (org.eclipse.jdt.core.dom.VariableDeclarationFragment) fragObj;
if (frag.getName().getIdentifier().equals(cleanFieldName)) {
return fd.getType().toString();
}
}
}
}
return null;
@@ -618,8 +676,26 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
// 2. Inline Instantiation Getter (e.g. new Event(CONSTANT).getType())
if (mi.getExpression() instanceof org.eclipse.jdt.core.dom.ClassInstanceCreation cic) {
for (Object argObj : cic.arguments()) {
extractConstantsFromExpression((org.eclipse.jdt.core.dom.Expression) argObj, constants);
if (cic.getAnonymousClassDeclaration() != null) {
for (Object declObj : cic.getAnonymousClassDeclaration().bodyDeclarations()) {
if (declObj instanceof org.eclipse.jdt.core.dom.MethodDeclaration mdecl) {
if (mdecl.getName().getIdentifier().equals(methodName) && mdecl.getBody() != null) {
mdecl.getBody().accept(new org.eclipse.jdt.core.dom.ASTVisitor() {
@Override
public boolean visit(org.eclipse.jdt.core.dom.ReturnStatement rs) {
if (rs.getExpression() != null) {
extractConstantsFromExpression(rs.getExpression(), constants);
}
return super.visit(rs);
}
});
}
}
}
} else {
for (Object argObj : cic.arguments()) {
extractConstantsFromExpression((org.eclipse.jdt.core.dom.Expression) argObj, constants);
}
}
}