update argument resolution to
This commit is contained in:
@@ -132,6 +132,10 @@ public class HeuristicBeanResolutionEngine implements BeanResolutionEngine {
|
||||
}
|
||||
}
|
||||
|
||||
if (matchIdx < 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Set<String> smDivergentTerms = new HashSet<>();
|
||||
if (smPrefix != null) smDivergentTerms.add(smPrefix.toLowerCase());
|
||||
for (int i = matchIdx + 1; i < p1.length; i++) {
|
||||
|
||||
@@ -2,10 +2,12 @@ package click.kamil.springstatemachineexporter.analysis.service;
|
||||
|
||||
import click.kamil.springstatemachineexporter.analysis.resolver.ConstantResolver;
|
||||
import click.kamil.springstatemachineexporter.ast.common.CodebaseContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.jdt.core.dom.*;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Slf4j
|
||||
public class ConstantExtractor {
|
||||
private final CodebaseContext context;
|
||||
private final ConstantResolver constantResolver;
|
||||
@@ -132,7 +134,17 @@ public class ConstantExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
if (mi.getExpression() instanceof ClassInstanceCreation cic) {
|
||||
List<Expression> receivers = new ArrayList<>();
|
||||
if (mi.getExpression() != null) {
|
||||
if (mi.getExpression() instanceof ClassInstanceCreation) {
|
||||
receivers.add(mi.getExpression());
|
||||
} else if (variableTracer != null) {
|
||||
receivers.addAll(variableTracer.traceVariableAll(mi.getExpression()));
|
||||
}
|
||||
}
|
||||
|
||||
for (Expression receiverExpr : receivers) {
|
||||
if (receiverExpr instanceof ClassInstanceCreation cic) {
|
||||
if (cic.getAnonymousClassDeclaration() != null) {
|
||||
for (Object declObj : cic.getAnonymousClassDeclaration().bodyDeclarations()) {
|
||||
if (declObj instanceof MethodDeclaration mdecl) {
|
||||
@@ -177,13 +189,8 @@ public class ConstantExtractor {
|
||||
}
|
||||
if (narrowed != null && !narrowed.isEmpty()) {
|
||||
constants.addAll(narrowed);
|
||||
handledByLombok = true;
|
||||
}
|
||||
}
|
||||
if (!handledByLombok) {
|
||||
for (Object argObj : cic.arguments()) {
|
||||
extractConstantsFromArgument((Expression) argObj, constants);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -258,9 +265,16 @@ public class ConstantExtractor {
|
||||
}
|
||||
|
||||
public List<String> resolveMethodReturnConstant(String className, String methodName, int depth, Set<String> visited, CompilationUnit contextCu) {
|
||||
if (depth > 20) return Collections.emptyList();
|
||||
log.debug("Entering resolveMethodReturnConstant with className={}, methodName={}, depth={}", className, methodName, depth);
|
||||
if (depth > 20) {
|
||||
log.debug("Exiting resolveMethodReturnConstant early (depth limit) for {}.{}", className, methodName);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String fqn = className + "." + methodName;
|
||||
if (!visited.add(fqn)) return Collections.emptyList();
|
||||
if (!visited.add(fqn)) {
|
||||
log.debug("Exiting resolveMethodReturnConstant early (cycle detected) for fqn={}", fqn);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> constants = new ArrayList<>();
|
||||
TypeDeclaration tempTd = contextCu != null ? context.getTypeDeclaration(className, contextCu) : null;
|
||||
@@ -358,6 +372,7 @@ public class ConstantExtractor {
|
||||
}
|
||||
}
|
||||
visited.remove(fqn);
|
||||
log.debug("resolveMethodReturnConstant for class={}, method={} resolved constants: {}", className, methodName, constants);
|
||||
return constants;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,15 @@ public class ConstructorAnalyzer {
|
||||
}
|
||||
|
||||
public List<String> traceFieldInConstructors(TypeDeclaration td, String fieldName, CodebaseContext context, Set<String> visited) {
|
||||
if (td == null || fieldName == null) return Collections.emptyList();
|
||||
String fqn = context.getFqn(td);
|
||||
if (fqn == null) return Collections.emptyList();
|
||||
|
||||
String cycleKey = fqn + "#" + fieldName;
|
||||
if (!visited.add(cycleKey)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> results = new ArrayList<>();
|
||||
|
||||
for (FieldDeclaration fd : td.getFields()) {
|
||||
@@ -136,6 +145,49 @@ public class ConstructorAnalyzer {
|
||||
}
|
||||
}
|
||||
|
||||
if (results.isEmpty()) {
|
||||
// Context-Aware Fallback (Up): Check superclass constructors
|
||||
String superFqn = context.getSuperclassFqn(td);
|
||||
if (superFqn != null && !superFqn.equals("java.lang.Object")) {
|
||||
TypeDeclaration superTd = context.getTypeDeclaration(superFqn);
|
||||
if (superTd != null) {
|
||||
results.addAll(traceFieldInConstructors(superTd, fieldName, context, visited));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (results.isEmpty()) {
|
||||
// Context-Aware Fallback (Down): Check subclasses/implementations
|
||||
List<String> impls = context.getImplementations(fqn);
|
||||
if (impls != null) {
|
||||
for (String implFqn : impls) {
|
||||
TypeDeclaration implTd = context.getTypeDeclaration(implFqn);
|
||||
if (implTd != null) {
|
||||
results.addAll(traceFieldInConstructors(implTd, fieldName, context, visited));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (results.isEmpty()) {
|
||||
// Global Fallback: Search all parsed classes in the workspace
|
||||
Collection<TypeDeclaration> allTypes = context.getTypeDeclarations();
|
||||
if (allTypes != null) {
|
||||
int matchedCount = 0;
|
||||
for (TypeDeclaration typeDecl : allTypes) {
|
||||
if (typeDecl == null) continue;
|
||||
if (context.hasField(typeDecl, fieldName)) {
|
||||
results.addAll(traceFieldInConstructors(typeDecl, fieldName, context, visited));
|
||||
matchedCount++;
|
||||
if (matchedCount >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visited.remove(cycleKey);
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -473,9 +525,47 @@ public class ConstructorAnalyzer {
|
||||
|
||||
String typeName = click.kamil.springstatemachineexporter.ast.common.AstUtils.extractSimpleTypeName(cic.getType());
|
||||
CompilationUnit contextCu = cic.getRoot() instanceof CompilationUnit ? (CompilationUnit) cic.getRoot() : null;
|
||||
TypeDeclaration td = contextCu != null ? context.getTypeDeclaration(typeName, contextCu) : context.getTypeDeclaration(typeName);
|
||||
if (td == null) td = context.getTypeDeclaration(typeName);
|
||||
if (td == null) return Collections.emptyList();
|
||||
AbstractTypeDeclaration atd = contextCu != null ? context.getAbstractTypeDeclaration(typeName, contextCu) : context.getAbstractTypeDeclaration(typeName);
|
||||
if (atd == null) atd = context.getAbstractTypeDeclaration(typeName);
|
||||
if (atd == null) return Collections.emptyList();
|
||||
|
||||
if (atd instanceof RecordDeclaration rd) {
|
||||
int compIdx = -1;
|
||||
List<?> components = rd.recordComponents();
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
Object compObj = components.get(i);
|
||||
if (compObj != null) {
|
||||
try {
|
||||
java.lang.reflect.Method getNameMethod = compObj.getClass().getMethod("getName");
|
||||
SimpleName nameObj = (SimpleName) getNameMethod.invoke(compObj);
|
||||
if (nameObj != null && nameObj.getIdentifier().equals(getterName)) {
|
||||
compIdx = i;
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// ignore reflection errors
|
||||
}
|
||||
}
|
||||
}
|
||||
if (compIdx >= 0 && compIdx < cic.arguments().size()) {
|
||||
Expression argExpr = (Expression) cic.arguments().get(compIdx);
|
||||
List<String> consts = new ArrayList<>();
|
||||
if (constantExtractor != null) {
|
||||
constantExtractor.extractConstantsFromArgument(argExpr, consts);
|
||||
}
|
||||
if (!consts.isEmpty()) {
|
||||
return consts;
|
||||
} else {
|
||||
String resolved = constantResolver.resolve(argExpr, context);
|
||||
if (resolved != null) {
|
||||
return List.of(resolved);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (!(atd instanceof TypeDeclaration td)) return Collections.emptyList();
|
||||
|
||||
MethodDeclaration getter = context.findMethodDeclaration(td, getterName, true);
|
||||
if (getter == null || getter.getBody() == null) return Collections.emptyList();
|
||||
|
||||
Reference in New Issue
Block a user