54 lines
2.4 KiB
Markdown
54 lines
2.4 KiB
Markdown
# Advanced String and Variable Resolution Strategy
|
|
|
|
## 1. The Problem
|
|
Annotations often use non-literal values for metadata:
|
|
- **Constants**: `@PostMapping(ApiConstants.SUBMIT_PATH)`
|
|
- **Concatenation**: `@RequestMapping(BASE + "/orders")`
|
|
- **Inherited Variables**: Use of fields defined in base classes.
|
|
|
|
Simple `StringLiteral` extraction fails in these cases. We need a recursive **Expression Evaluator**.
|
|
|
|
## 2. Evaluation Logic
|
|
|
|
### Constant Resolution
|
|
If an expression is a `SimpleName` or `QualifiedName`:
|
|
1. Use `CodebaseContext.getTypeDeclaration()` to find the class where the variable is defined.
|
|
2. Search for the `VariableDeclarationFragment`.
|
|
3. If it has an initializer that is a literal or another evaluatable expression, resolve it.
|
|
|
|
### Concatenation (Infix Expressions)
|
|
If an expression is an `InfixExpression` with the `+` operator:
|
|
1. Recursively resolve the left operand.
|
|
2. Recursively resolve the right operand.
|
|
3. Concatenate the results if both are strings.
|
|
|
|
### Spring Expression Language (SpEL) in Annotations
|
|
For values like `@Value("#{systemProperties['path.base'] + '/api'}")`:
|
|
1. Identify the SpEL string.
|
|
2. Use a "Lite" SpEL parser to extract keys.
|
|
3. Match against the `profiles` map in `CodebaseMetadata`.
|
|
|
|
## 3. Implementation: `ValueResolver`
|
|
We will introduce a central `ValueResolver` utility.
|
|
|
|
```java
|
|
public class ValueResolver {
|
|
public String resolveString(Expression expr, CodebaseContext context) {
|
|
if (expr instanceof StringLiteral sl) return sl.getLiteralValue();
|
|
if (expr instanceof InfixExpression ie) return resolveInfix(ie, context);
|
|
if (expr instanceof Name name) return resolveVariable(name, context);
|
|
// ... fallback to toString() or empty
|
|
}
|
|
}
|
|
```
|
|
|
|
## 4. Challenges
|
|
- **Circular Dependencies**: A + B, where B = A + C. We need a "visited" set to prevent infinite recursion.
|
|
- **Runtime-only values**: Some values cannot be resolved statically (e.g., values from a DB). In these cases, we should return the placeholder or a "Runtime Value" marker.
|
|
- **Method Calls**: `getPath() + "/orders"`. Resolving method return values is complex; initially, we will only support simple getters returning literals.
|
|
|
|
## 5. Integration
|
|
1. Update `AstUtils` or create `ValueResolver`.
|
|
2. Refactor `SpringMvcEnricher`, `RabbitMqEnricher`, and `JmsEnricher` to use the resolver for all path/queue/destination fields.
|
|
3. Update `integration_test_state_machine` with complex path examples.
|