Skip to content

Feature/spring di call resolution#413

Open
jaissebastian wants to merge 5 commits intotirth8205:mainfrom
jaissebastian:feature/spring-di-call-resolution
Open

Feature/spring di call resolution#413
jaissebastian wants to merge 5 commits intotirth8205:mainfrom
jaissebastian:feature/spring-di-call-resolution

Conversation

@jaissebastian
Copy link
Copy Markdown

No description provided.

jaissebastian and others added 3 commits May 1, 2026 18:16
…tadata

Detects Spring-managed beans and their injection points in Java:

- @Component/@Service/@Repository/@Controller/@configuration on classes
  → stored as extra["spring_stereotype"] and extra["spring_annotations"]
- @Autowired / @Inject / @resource field injection → INJECTS edge with
  injection_type="field"
- Lombok @requiredargsconstructor / @AllArgsConstructor with final fields
  → INJECTS edge with injection_type="constructor_lombok"
- Explicit @Autowired constructor injection → INJECTS edge per parameter
  with injection_type="constructor"

Validated against ~/oh/kronos/kronos-dnd-calculation: 69 Spring beans and
164 INJECTS edges detected (154 lombok-constructor, 7 explicit-constructor,
3 field). Static final fields (e.g. TAG = "...") are correctly excluded.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…edType.method()

Parser fix:
- Java method_invocation now emits CALLS with the method name as target
  (not the receiver), and stores the receiver in extra["receiver"]
- When a receiver is present, skip scope-based resolution so same-name
  methods in the current class don't produce false qualifications
- INJECTS edges now carry extra["field_name"] for field/constructor params

New post-build resolver (spring_resolver.py):
- Joins INJECTS.extra.field_name → CALLS.extra.receiver to map each
  injected field variable to its declared type
- Rewrites CALLS target from bare method name to "InjectedType.method"
- Runs after full_build and incremental_update (Java files only)
- Marks resolved edges with extra.spring_resolved + extra.injected_type

Validated on kronos-dnd-calculation (347 files):
- 216 CALLS edges resolved through Spring DI injection chain
- InvoiceCalculationHandler.invoice → InvoiceCalculationService.invoice ✓
  (was incorrectly resolving to InvoiceCalculationHandler.invoice)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ers_of compatibility

The resolver was writing bare "ClassName.method" as target_qualified, but
callers_of queries for exact match against node.qualified_name which is
"file_path::ClassName.method". Added method_to_qual dict indexed by
(parent_name, method_name) to look up the full qualified_name, with fallback
to the previous format for external classes not in the graph.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jaissebastian jaissebastian force-pushed the feature/spring-di-call-resolution branch from 581e119 to 43d2875 Compare May 1, 2026 12:49
jaissebastian and others added 2 commits May 1, 2026 23:44
Parser (parser.py):
- @WorkflowInterface / @ActivityInterface on interfaces → temporal_role in
  node extra ("workflow_interface" / "activity_interface")
- @WorkflowMethod / @ActivityMethod / @SignalMethod / @QueryMethod on methods
  → temporal_role in method node extra (lowercase annotation name)
- New _emit_temporal_stub_fields(): emits TEMPORAL_STUB edges for class fields
  typed as *Activity or *Workflow — the universal Temporal naming convention
- Fix _get_name() for Java: method_declaration previously returned the return
  type_identifier instead of the method identifier; now correctly returns the
  method name (also fixes test_method_names_not_return_types)

New temporal_resolver.py (post-build pass):
- Validates TEMPORAL_STUB targets against known @ActivityInterface /
  @WorkflowInterface nodes (filters out false positives from naming convention)
- Joins TEMPORAL_STUB.field_name → CALLS.receiver to map stub fields to
  their declared Temporal interface type
- Resolves through INHERITS to the concrete implementation when unique
- Writes fully-qualified file_path::ClassName.method as target_qualified
  so callers_of() finds Temporal activity invocations correctly

Validated on kronos-dnd-calculation:
- 45 Temporal interface/method nodes detected
- 19 TEMPORAL_STUB edges (activity fields in workflow impl classes)
- 21 CALLS edges resolved: DnDCalculationWorkflowImpl.execute →
  InitializeCalculationActivity.initializeCalculation (and 20 more)

Tests: 13 new Temporal tests (parsing + resolver integration)
Fixture: tests/fixtures/TemporalWorkflow.java

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- @KafkaListener(topics="...") and topics={...} → CONSUMES edge with kafka:<topic> target
- KafkaReceiver / ReactiveKafkaConsumerTemplate fields → CONSUMES edge with kafka:config target
- KafkaTemplate / KafkaOperations / ReactiveKafkaProducerTemplate fields → PRODUCES edge
- Generic value type extracted as extra.message_type (e.g. EquipmentMove)
- Config-driven topics stored as kafka:config target
- Fixes deco_list annotation-name check: split("(")[0] before matching annotation names
- Adds fixture KafkaPatterns.java and 9 TestKafkaParsing tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant