fix 6
This commit is contained in:
@@ -222,6 +222,50 @@ public class CallGraphBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LAST RESORT FALLBACK: If AST deep trace failed to find a valid ALL_CAPS constant
|
||||||
|
// (e.g. it returned a field name like 'type', or nothing), we can scrape the resolvedValue string directly
|
||||||
|
// for string literals or enum-like constants.
|
||||||
|
boolean hasValidConstant = false;
|
||||||
|
for (String ev : polymorphicEvents) {
|
||||||
|
String val = ev.contains(".") ? ev.substring(ev.lastIndexOf('.') + 1) : ev;
|
||||||
|
if (val.equals(val.toUpperCase()) && val.length() > 2) {
|
||||||
|
hasValidConstant = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidConstant && resolvedValue.contains("(")) {
|
||||||
|
java.util.List<String> scraped = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
// Extract "STRING_LITERALS"
|
||||||
|
java.util.regex.Matcher m1 = java.util.regex.Pattern.compile("\"([^\"]+)\"").matcher(resolvedValue);
|
||||||
|
while (m1.find()) {
|
||||||
|
scraped.add(m1.group(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract ENUM_LIKE_CONSTANTS
|
||||||
|
java.util.regex.Matcher m2 = java.util.regex.Pattern.compile("\\b([A-Z_]{3,})\\b").matcher(resolvedValue);
|
||||||
|
while (m2.find()) {
|
||||||
|
if (!scraped.contains(m2.group(1))) {
|
||||||
|
scraped.add(m2.group(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scraped.isEmpty()) {
|
||||||
|
polymorphicEvents.clear();
|
||||||
|
polymorphicEvents.addAll(scraped);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up any remaining invalid AST fallbacks (like 'type', 'event') if we found valid ones
|
||||||
|
if (polymorphicEvents.size() > 1) {
|
||||||
|
polymorphicEvents.removeIf(e -> {
|
||||||
|
String val = e.contains(".") ? e.substring(e.lastIndexOf('.') + 1) : e;
|
||||||
|
return !val.equals(val.toUpperCase()) || val.length() <= 2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!resolvedValue.equals(event) || !polymorphicEvents.isEmpty()) {
|
if (!resolvedValue.equals(event) || !polymorphicEvents.isEmpty()) {
|
||||||
return TriggerPoint.builder()
|
return TriggerPoint.builder()
|
||||||
.event(resolvedValue)
|
.event(resolvedValue)
|
||||||
|
|||||||
@@ -1856,4 +1856,45 @@ class CallGraphBuilderTest {
|
|||||||
org.assertj.core.api.Assertions.assertThat(allEvents).containsExactlyInAnyOrder("FIELD_DECL", "INIT_BLOCK");
|
org.assertj.core.api.Assertions.assertThat(allEvents).containsExactlyInAnyOrder("FIELD_DECL", "INIT_BLOCK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldFallbackToScraperForComplexInlineInstantiations() throws IOException {
|
||||||
|
String source = """
|
||||||
|
package com.example;
|
||||||
|
public class OrderController {
|
||||||
|
private OrderService service;
|
||||||
|
public void handleStatus() {
|
||||||
|
// The AST tracer will trace EventWithConstructorArg.getType()
|
||||||
|
// It will find `this.type = typeArg`, which it cannot resolve because it's a parameter.
|
||||||
|
// The fallback scraper should catch "COMPLEX_INLINE_CONST".
|
||||||
|
service.process(new EventWithConstructorArg("COMPLEX_INLINE_CONST", 123).getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EventWithConstructorArg {
|
||||||
|
private String type;
|
||||||
|
public EventWithConstructorArg(String typeArg, int other) {
|
||||||
|
this.type = typeArg;
|
||||||
|
}
|
||||||
|
public String getType() { return type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
class OrderService {
|
||||||
|
public void process(String event) {}
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
Path tempDir = Files.createTempDirectory("callgraph_scraper");
|
||||||
|
Files.writeString(tempDir.resolve("OrderConfig.java"), source);
|
||||||
|
CodebaseContext context = new CodebaseContext();
|
||||||
|
context.scan(tempDir);
|
||||||
|
CallGraphBuilder builder = new CallGraphBuilder(context);
|
||||||
|
|
||||||
|
EntryPoint entryPoint = EntryPoint.builder().className("com.example.OrderController").methodName("handleStatus").build();
|
||||||
|
TriggerPoint trigger = TriggerPoint.builder().className("com.example.OrderService").methodName("process").event("event").build();
|
||||||
|
List<CallChain> chains = builder.findChains(List.of(entryPoint), List.of(trigger));
|
||||||
|
|
||||||
|
org.assertj.core.api.Assertions.assertThat(chains).hasSize(1);
|
||||||
|
org.assertj.core.api.Assertions.assertThat(chains.get(0).getTriggerPoint().getPolymorphicEvents()).contains("COMPLEX_INLINE_CONST");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user