Skip to content

fix(java): correct Lombok @RequiredArgsConstructor/@AllArgsConstructor DI semantics#589

Open
YutenC wants to merge 1 commit into
tirth8205:mainfrom
YutenC:feat/lombok-nonnull-allargs-fix
Open

fix(java): correct Lombok @RequiredArgsConstructor/@AllArgsConstructor DI semantics#589
YutenC wants to merge 1 commit into
tirth8205:mainfrom
YutenC:feat/lombok-nonnull-allargs-fix

Conversation

@YutenC

@YutenC YutenC commented Jun 30, 2026

Copy link
Copy Markdown

Problem

v2.3.3 introduced Spring DI resolution via _emit_spring_field_injection(), but the Lombok constructor annotation handling has two semantic bugs:

1. @RequiredArgsConstructor misses @NonNull fields

Lombok's @RequiredArgsConstructor generates a constructor for final fields and @NonNull-annotated non-final fields. The current implementation only checks has_final, so @NonNull fields silently produce no INJECTS edge.

2. @AllArgsConstructor behaves like @RequiredArgsConstructor

@AllArgsConstructor generates a constructor for all non-static fields regardless of final or @NonNull. The current code shares the same has_lombok_constructor and has_final guard, so non-final fields in an @AllArgsConstructor class are never resolved.

Fix

Split has_lombok_constructor: bool into two flags and apply the correct Lombok field-selection rule for each annotation:

Annotation Fields included in generated constructor
@RequiredArgsConstructor final or @NonNull (non-static)
@AllArgsConstructor All non-static fields

A new injection_type value "constructor_lombok_all" is introduced for @AllArgsConstructor edges. The existing "constructor_lombok" value is preserved for @RequiredArgsConstructor — no breaking change to existing graphs.

Changes

  • code_review_graph/parser.py_emit_spring_injections() and _emit_spring_field_injection()
  • tests/fixtures/SpringDI.java — add PaymentService (@RequiredArgsConstructor + @NonNull non-final field) and ReportService (@AllArgsConstructor with non-final fields)
  • tests/test_multilang.py — three new tests, updated edge count assertion

Tests

…DI semantics

@requiredargsconstructor previously only detected final fields, missing
@NonNull-annotated non-final fields which Lombok also includes in the
generated constructor.

@AllArgsConstructor was treated identically to @requiredargsconstructor
(only final fields), but its correct semantics is all non-static fields
regardless of final or @nonnull.

Changes:
- Split has_lombok_constructor into has_required_args / has_all_args so
  each annotation applies its own field-selection rule
- @requiredargsconstructor: final || @nonnull (non-static)
- @AllArgsConstructor: every non-static field
- New injection_type value 'constructor_lombok_all' for @AllArgsConstructor
  edges; existing 'constructor_lombok' preserved for @requiredargsconstructor

Tests:
- Add PaymentService fixture (RequiredArgsConstructor + @nonnull non-final field)
- Add ReportService fixture (AllArgsConstructor with non-final fields)
- test_required_args_nonnull_field_injected
- test_required_args_plain_field_not_injected
- test_all_args_injects_all_non_static_fields
- Update test_total_injects_edge_count (4 → 8 minimum edges)
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