fix: resolve properties before direct HTML generation
This commit is contained in:
@@ -17,7 +17,9 @@ import org.eclipse.jdt.core.dom.LambdaExpression;
|
||||
import org.eclipse.jdt.core.dom.MethodDeclaration;
|
||||
import org.eclipse.jdt.core.dom.MethodInvocation;
|
||||
import org.eclipse.jdt.core.dom.SimpleName;
|
||||
|
||||
import org.eclipse.jdt.core.dom.ITypeBinding;
|
||||
import org.eclipse.jdt.core.dom.MethodReference;
|
||||
import org.eclipse.jdt.core.dom.TypeDeclaration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -177,15 +179,15 @@ public class AstTransitionParser {
|
||||
Expression secondArg = resolveArg((Expression) args.get(1), argsMap);
|
||||
if ("last".equals(methodName)) {
|
||||
// For 'last', the second argument is an action, not a guard
|
||||
parseAction(secondArg, t, cu);
|
||||
parseAction(secondArg, t, cu, context);
|
||||
} else {
|
||||
// For 'first' and 'then', the second argument is a guard
|
||||
parseGuard(secondArg, t, cu);
|
||||
parseGuard(secondArg, t, cu, context);
|
||||
}
|
||||
}
|
||||
if (args.size() > 2) {
|
||||
Expression thirdArg = resolveArg((Expression) args.get(2), argsMap);
|
||||
parseAction(thirdArg, t, cu);
|
||||
parseAction(thirdArg, t, cu, context);
|
||||
}
|
||||
t.setOrder(orderCounter++);
|
||||
transitions.add(t);
|
||||
@@ -228,43 +230,96 @@ public class AstTransitionParser {
|
||||
}
|
||||
case "guard" -> {
|
||||
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
||||
parseGuard(resolved, t, cu);
|
||||
parseGuard(resolved, t, cu, context);
|
||||
}
|
||||
case "action" -> {
|
||||
Expression resolved = resolveArg((Expression) args.get(0), argsMap);
|
||||
parseAction(resolved, t, cu);
|
||||
parseAction(resolved, t, cu, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
private static String extractInternalLogic(Expression expr, CompilationUnit cu) {
|
||||
private static String extractInternalLogic(Expression expr, CompilationUnit cu, CodebaseContext context) {
|
||||
if (expr == null) return null;
|
||||
|
||||
// 1. Lambda Expressions
|
||||
if (expr instanceof LambdaExpression le) {
|
||||
return le.toString();
|
||||
}
|
||||
|
||||
// 2. Anonymous Classes
|
||||
if (expr instanceof ClassInstanceCreation cic && cic.getAnonymousClassDeclaration() != null) {
|
||||
return cic.toString();
|
||||
}
|
||||
|
||||
// 3. Method Invocations
|
||||
if (expr instanceof MethodInvocation mi) {
|
||||
IMethodBinding binding = mi.resolveMethodBinding();
|
||||
if (binding != null) {
|
||||
// Try same file
|
||||
ASTNode declNode = cu.findDeclaringNode(binding.getKey());
|
||||
if (declNode instanceof MethodDeclaration md) {
|
||||
return md.toString();
|
||||
}
|
||||
|
||||
// Try other files via CodebaseContext
|
||||
ITypeBinding declaringClass = binding.getDeclaringClass();
|
||||
if (declaringClass != null) {
|
||||
String fqn = declaringClass.getQualifiedName();
|
||||
TypeDeclaration td = context.getTypeDeclaration(fqn);
|
||||
if (td != null) {
|
||||
for (MethodDeclaration md : td.getMethods()) {
|
||||
if (md.getName().getIdentifier().equals(binding.getName()) &&
|
||||
md.parameters().size() == binding.getParameterTypes().length) {
|
||||
return md.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Method References
|
||||
if (expr instanceof MethodReference mr) {
|
||||
IMethodBinding binding = mr.resolveMethodBinding();
|
||||
if (binding != null) {
|
||||
ITypeBinding declaringClass = binding.getDeclaringClass();
|
||||
if (declaringClass != null) {
|
||||
String fqn = declaringClass.getQualifiedName();
|
||||
TypeDeclaration td = context.getTypeDeclaration(fqn);
|
||||
if (td != null) {
|
||||
for (MethodDeclaration md : td.getMethods()) {
|
||||
if (md.getName().getIdentifier().equals(binding.getName()) &&
|
||||
md.parameters().size() == binding.getParameterTypes().length) {
|
||||
return md.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return mr.toString();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void parseGuard(Object arg, Transition t, CompilationUnit cu) {
|
||||
private static void parseGuard(Object arg, Transition t, CompilationUnit cu, CodebaseContext context) {
|
||||
QuotedExpression quotedExpr = QuotedExpression.of(arg);
|
||||
if (quotedExpr != null) {
|
||||
String internalLogic = extractInternalLogic(quotedExpr.getExpression(), cu);
|
||||
t.setGuard(Guard.of(quotedExpr.toStringWithoutQuotes(), isLambdaOrAnonymous(quotedExpr.getExpression()), internalLogic));
|
||||
String internalLogic = extractInternalLogic(quotedExpr.getExpression(), cu, context);
|
||||
int lineNumber = cu.getLineNumber(quotedExpr.getExpression().getStartPosition());
|
||||
t.setGuard(Guard.of(quotedExpr.toStringWithoutQuotes(), isLambdaOrAnonymous(quotedExpr.getExpression()), internalLogic, lineNumber));
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseAction(Object arg, Transition t, CompilationUnit cu) {
|
||||
private static void parseAction(Object arg, Transition t, CompilationUnit cu, CodebaseContext context) {
|
||||
QuotedExpression quotedExpr = QuotedExpression.of(arg);
|
||||
if (quotedExpr != null) {
|
||||
String internalLogic = extractInternalLogic(quotedExpr.getExpression(), cu);
|
||||
t.getActions().add(Action.of(quotedExpr.toStringWithoutQuotes(), isLambdaOrAnonymous(quotedExpr.getExpression()), internalLogic));
|
||||
String internalLogic = extractInternalLogic(quotedExpr.getExpression(), cu, context);
|
||||
int lineNumber = cu.getLineNumber(quotedExpr.getExpression().getStartPosition());
|
||||
t.getActions().add(Action.of(quotedExpr.toStringWithoutQuotes(), isLambdaOrAnonymous(quotedExpr.getExpression()), internalLogic, lineNumber));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package click.kamil.springstatemachineexporter.model;
|
||||
|
||||
public record Action(String expression, boolean isLambda, String internalLogic) {
|
||||
public static Action of(String expression, boolean isLambda, String internalLogic) {
|
||||
return expression != null ? new Action(expression, isLambda, internalLogic) : null;
|
||||
public record Action(String expression, boolean isLambda, String internalLogic, Integer lineNumber) {
|
||||
public static Action of(String expression, boolean isLambda, String internalLogic, Integer lineNumber) {
|
||||
return expression != null ? new Action(expression, isLambda, internalLogic, lineNumber) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package click.kamil.springstatemachineexporter.model;
|
||||
|
||||
public record Guard(String expression, boolean isLambda, String internalLogic) {
|
||||
public static Guard of(String expression, boolean isLambda, String internalLogic) {
|
||||
return expression != null ? new Guard(expression, isLambda, internalLogic) : null;
|
||||
public record Guard(String expression, boolean isLambda, String internalLogic, Integer lineNumber) {
|
||||
public static Guard of(String expression, boolean isLambda, String internalLogic, Integer lineNumber) {
|
||||
return expression != null ? new Guard(expression, isLambda, internalLogic, lineNumber) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ public class ExportService {
|
||||
context.scan(inputDir);
|
||||
|
||||
CodebaseIntelligenceProvider intelligence = new JdtIntelligenceProvider(context, inputDir);
|
||||
exportAll(context, intelligence, outputDir, selectedFormats, renderChoicesAsDiamonds, flows, machineFilter);
|
||||
exportAll(context, intelligence, outputDir, selectedFormats, renderChoicesAsDiamonds, flows, machineFilter, activeProfiles != null ? activeProfiles : Collections.emptyList());
|
||||
}
|
||||
|
||||
public void runJsonExporter(Path jsonFile, Path outputDir, List<String> selectedFormats) throws IOException {
|
||||
@@ -131,7 +131,7 @@ public class ExportService {
|
||||
result.applyResolution(merged);
|
||||
}
|
||||
|
||||
private void exportAll(CodebaseContext context, CodebaseIntelligenceProvider intelligence, Path outputDir, List<String> selectedFormats, boolean renderChoicesAsDiamonds, List<BusinessFlow> flows, String machineFilter) throws IOException {
|
||||
private void exportAll(CodebaseContext context, CodebaseIntelligenceProvider intelligence, Path outputDir, List<String> selectedFormats, boolean renderChoicesAsDiamonds, List<BusinessFlow> flows, String machineFilter, List<String> activeProfiles) throws IOException {
|
||||
Set<String> processedLocations = new HashSet<>();
|
||||
|
||||
// 1. Find entry point classes (annotated or extending adapter)
|
||||
@@ -140,7 +140,7 @@ public class ExportService {
|
||||
String fqn = context.getFqn(td);
|
||||
if (machineFilter != null && !fqn.contains(machineFilter)) continue;
|
||||
if (processedLocations.add(fqn)) {
|
||||
processEntryPoint(td, outputDir, context, intelligence, selectedFormats, renderChoicesAsDiamonds, flows);
|
||||
processEntryPoint(td, outputDir, context, intelligence, selectedFormats, renderChoicesAsDiamonds, flows, activeProfiles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,12 +154,12 @@ public class ExportService {
|
||||
|
||||
if (machineFilter != null && !uniqueId.contains(machineFilter)) continue;
|
||||
if (processedLocations.add(uniqueId)) {
|
||||
processBeanMethod(m, outputDir, context, intelligence, selectedFormats, renderChoicesAsDiamonds, flows);
|
||||
processBeanMethod(m, outputDir, context, intelligence, selectedFormats, renderChoicesAsDiamonds, flows, activeProfiles);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processEntryPoint(TypeDeclaration td, Path outputDir, CodebaseContext context, CodebaseIntelligenceProvider intelligence, List<String> selectedFormats, boolean renderChoicesAsDiamonds, List<BusinessFlow> flows) throws IOException {
|
||||
private void processEntryPoint(TypeDeclaration td, Path outputDir, CodebaseContext context, CodebaseIntelligenceProvider intelligence, List<String> selectedFormats, boolean renderChoicesAsDiamonds, List<BusinessFlow> flows, List<String> activeProfiles) throws IOException {
|
||||
String className = context.getFqn(td);
|
||||
log.info("Processing state machine config: {}", className);
|
||||
|
||||
@@ -189,10 +189,12 @@ public class ExportService {
|
||||
|
||||
enrichmentService.enrich(result, context, intelligence);
|
||||
|
||||
resolveProperties(result, activeProfiles);
|
||||
|
||||
generateOutputs(outputDir, result, selectedFormats);
|
||||
}
|
||||
|
||||
private void processBeanMethod(MethodDeclaration m, Path outputDir, CodebaseContext context, CodebaseIntelligenceProvider intelligence, List<String> selectedFormats, boolean renderChoicesAsDiamonds, List<BusinessFlow> flows) throws IOException {
|
||||
private void processBeanMethod(MethodDeclaration m, Path outputDir, CodebaseContext context, CodebaseIntelligenceProvider intelligence, List<String> selectedFormats, boolean renderChoicesAsDiamonds, List<BusinessFlow> flows, List<String> activeProfiles) throws IOException {
|
||||
TypeDeclaration parentClass = (TypeDeclaration) m.getParent();
|
||||
String parentFqn = context.getFqn(parentClass);
|
||||
String methodName = m.getName().getIdentifier();
|
||||
@@ -218,6 +220,8 @@ public class ExportService {
|
||||
|
||||
enrichmentService.enrich(result, context, intelligence);
|
||||
|
||||
resolveProperties(result, activeProfiles);
|
||||
|
||||
generateOutputs(outputDir, result, selectedFormats);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user