update number 6
This commit is contained in:
@@ -109,10 +109,6 @@ public class StrictFqnMatchingEngine implements EventMatchingEngine {
|
||||
eventStr.equals("payload")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (eventStr.contains(".valueOf(") || eventStr.contains("valueOf (")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (eventStr.contains(" ? ") && eventStr.contains(" : ")) {
|
||||
return true;
|
||||
|
||||
@@ -1410,21 +1410,25 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
String className = baseCalled.substring(0, baseCalled.lastIndexOf('.'));
|
||||
String methodName = baseCalled.substring(baseCalled.lastIndexOf('.') + 1);
|
||||
|
||||
List<String> impls = context.getImplementations(className);
|
||||
if (impls.isEmpty()) {
|
||||
TypeDeclaration td = context.getTypeDeclaration(className);
|
||||
if (isFunctionalInterface(className, td)) {
|
||||
allResolved.add(baseCalled);
|
||||
} else {
|
||||
TypeDeclaration td = context.getTypeDeclaration(className);
|
||||
boolean isAbstractOrInterface = false;
|
||||
if (td != null) {
|
||||
isAbstractOrInterface = td.isInterface() || (td.modifiers() != null && td.modifiers().toString().contains("abstract"));
|
||||
}
|
||||
boolean isImplicitThis = node.getExpression() == null || node.getExpression() instanceof ThisExpression;
|
||||
if (!isAbstractOrInterface || isImplicitThis) {
|
||||
List<String> impls = context.getImplementations(className);
|
||||
if (impls.isEmpty()) {
|
||||
allResolved.add(baseCalled);
|
||||
}
|
||||
for (String impl : impls) {
|
||||
allResolved.add(impl + "." + methodName);
|
||||
} else {
|
||||
boolean isAbstractOrInterface = false;
|
||||
if (td != null) {
|
||||
isAbstractOrInterface = td.isInterface() || (td.modifiers() != null && td.modifiers().toString().contains("abstract"));
|
||||
}
|
||||
boolean isImplicitThis = node.getExpression() == null || node.getExpression() instanceof ThisExpression;
|
||||
if (!isAbstractOrInterface || isImplicitThis) {
|
||||
allResolved.add(baseCalled);
|
||||
}
|
||||
for (String impl : impls) {
|
||||
allResolved.add(impl + "." + methodName);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1434,6 +1438,52 @@ public abstract class AbstractCallGraphEngine implements CallGraphEngine {
|
||||
return allResolved;
|
||||
}
|
||||
|
||||
private boolean isFunctionalInterface(String className, TypeDeclaration td) {
|
||||
if (className == null) return false;
|
||||
if (className.equals("java.lang.Runnable") || className.equals("Runnable")) return true;
|
||||
if (className.equals("java.util.concurrent.Callable") || className.equals("Callable")) return true;
|
||||
if (className.startsWith("java.util.function.")) return true;
|
||||
|
||||
if (td != null && td.isInterface()) {
|
||||
if (td.modifiers() != null) {
|
||||
for (Object mod : td.modifiers()) {
|
||||
if (mod instanceof Annotation ann) {
|
||||
String name = ann.getTypeName().toString();
|
||||
if (name.equals("FunctionalInterface") || name.endsWith(".FunctionalInterface")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int abstractMethodCount = 0;
|
||||
for (MethodDeclaration md : td.getMethods()) {
|
||||
if (md.getBody() == null) {
|
||||
String name = md.getName().getIdentifier();
|
||||
if (name.equals("equals") && md.parameters().size() == 1) continue;
|
||||
if (name.equals("hashCode") && md.parameters().isEmpty()) continue;
|
||||
if (name.equals("toString") && md.parameters().isEmpty()) continue;
|
||||
|
||||
boolean isStaticOrDefault = false;
|
||||
if (md.modifiers() != null) {
|
||||
for (Object mod : md.modifiers()) {
|
||||
if (mod instanceof Modifier m) {
|
||||
if (m.isStatic() || m.isDefault()) {
|
||||
isStaticOrDefault = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isStaticOrDefault) {
|
||||
abstractMethodCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return abstractMethodCount == 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String unwrapConverterMethods(String arg) {
|
||||
if (arg == null) return null;
|
||||
String current = arg;
|
||||
|
||||
@@ -102,6 +102,30 @@ public class CallGraphPathFinder {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle implementation fallback for interfaces/superclasses (interface -> concrete class)
|
||||
if (result.isEmpty() && start.contains(".")) {
|
||||
String className = start.substring(0, start.lastIndexOf('.'));
|
||||
String methodName = start.substring(start.lastIndexOf('.') + 1);
|
||||
if (className.contains("<")) {
|
||||
className = className.substring(0, className.indexOf('<'));
|
||||
}
|
||||
List<String> impls = context.getImplementations(className);
|
||||
if (impls != null) {
|
||||
for (String impl : impls) {
|
||||
String implMethod = impl + "." + methodName;
|
||||
if (graph.containsKey(implMethod)) {
|
||||
List<List<String>> implPaths = findAllPaths(implMethod, target, graph, visited);
|
||||
for (List<String> implPath : implPaths) {
|
||||
List<String> path = new ArrayList<>();
|
||||
path.add(start);
|
||||
path.addAll(implPath);
|
||||
result.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visited.remove(start);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user