Skip to content

Preserve generic type parameters in AutowiredFieldIntoConstructorParameterVisitor#1037

Merged
MBoegers merged 1 commit into
mainfrom
MBoegers/issue-1005-autowired-generic-types
Jun 15, 2026
Merged

Preserve generic type parameters in AutowiredFieldIntoConstructorParameterVisitor#1037
MBoegers merged 1 commit into
mainfrom
MBoegers/issue-1005-autowired-generic-types

Conversation

@MBoegers

@MBoegers MBoegers commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

What's changed?

AutowiredFieldIntoConstructorParameterVisitor rendered the generated constructor parameter type with TypeUtils.asFullyQualified(type).getClassName(), which drops type arguments — so an @Autowired List<String> field became a raw List parameter (and array fields were skipped entirely).

  • New-constructor path (AddConstructorVisitor): render the field's TypeTree source text directly in the template. Because the template is contextSensitive() and the field stays in the class, its imports are already present — no import registration needed.
  • Existing-constructor path (AddConstructorParameterAndAssignment): the replaceParameters() template is parsed without the file's imports, so the parameter is rendered fully qualified via TypeUtils.toString(..) and then simplified with service(ImportService.class).shortenFullyQualifiedTypeReferencesIn(..) — the same idiom ChangeMethodParameter already uses in this repo. This also fixes array fields into an existing constructor, which previously threw.
  • The type guard now skips only null/primitive types instead of everything without a FullyQualified, letting arrays and type variables through.

Why this shape

The fix itself is just rendering the type from the LST instead of getClassName(). No recursive FQN-collection helper is needed: imports are already in scope on the new-constructor path, and ImportService handles them on the existing-constructor path. Net production change is ~23 lines.

Tests

Covers generics into new/existing/parameterized constructors, nested generics (incl. into an existing constructor, under full type validation), bounded wildcards, user-defined generic types across packages, and arrays. Two tests relax TypeValidation to document current JavaTemplate limitations (the template parser can't resolve sibling in-run sources; array assignments are mis-attributed upstream) — each annotated with the precise reason.

…onstructor parameters

`AutowiredFieldIntoConstructorParameterVisitor` rendered the generated
constructor parameter with `FullyQualified.getClassName()`, which strips
type arguments, so `List<String>` became a raw `List`. Render the field's
source-level type instead (`TypeTree` text for the new-constructor path,
`TypeUtils.toString(..)` plus `ImportService` shortening for the
existing-constructor path) and let array-typed fields through the guard.

Co-authored-by: dim-kod <278075964+dim-kod@users.noreply.github.com>

@timtebeek timtebeek left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice to see this minimal fix, thanks!

@github-project-automation github-project-automation Bot moved this from In Progress to Ready to Review in OpenRewrite Jun 15, 2026
@dim-kod

dim-kod commented Jun 15, 2026

Copy link
Copy Markdown

Hello @MBoegers, I am satisfied with the result. It is always better to have simpler fixes! Thank you once again, closing the other PR.

@MBoegers MBoegers merged commit 44a9fba into main Jun 15, 2026
1 check passed
@MBoegers MBoegers deleted the MBoegers/issue-1005-autowired-generic-types branch June 15, 2026 09:44
@github-project-automation github-project-automation Bot moved this from Ready to Review to Done in OpenRewrite Jun 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

AutowiredFieldIntoConstructorParameterVisitor loses generic type parameters

3 participants