FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Honor JSpecify nullability of reused mapping methods by kush2439p · Pull Request #4110 · mapstruct/mapstruct · GitHub

Honor JSpecify nullability of reused mapping methods - #4110

Open
kush2439p wants to merge 5 commits into
mapstruct:mainfrom
kush2439p:codex/fix-jspecify-assignment-contracts
Open

Honor JSpecify nullability of reused mapping methods#4110
kush2439p wants to merge 5 commits into
mapstruct:mainfrom
kush2439p:codex/fix-jspecify-assignment-contracts

Conversation

kush2439p commented Aug 10, 2026
edited
Loading

Copy link
Copy Markdown

Summary

Fixes #4106 by carrying the JSpecify input and output contracts of reused mapping methods through generated assignments.

MapStruct previously based null guards primarily on source/target nullability and null-value-check strategy. It did not retain whether a selected helper method required a non-null argument or guaranteed a non-null result, which could generate unsafe calls or reject safe constructor mappings.

Implementation

  • Add internal assignment contracts for the innermost reused-method input and outermost reused-method result.
  • Resolve explicit and scoped JSpecify nullability from selected mapping methods, including methods from uses types.
  • Propagate contracts through method chains and conversion wrappers.
  • Generate a source guard when a nullable value is passed to a non-null helper parameter.
  • Invoke nullable-input helpers directly when their result is not explicitly @Nullable, preserving legacy behavior for unannotated return types.
  • Validate constructor parameters against the effective assignment result.
  • Preserve legacy behavior for built-ins, forged methods, assignments without method contracts, and -Amapstruct.disableJSpecify=true.
  • Add a verbose diagnostic for guards introduced by reused-method input contracts.
  • Document null propagation and clarify that JSpecify annotations do not participate in overload selection.

This also covers the related scenarios described in #4077, #4081, and #4086 without adding public API.

Verification

  • Exact JSpecify: False positive error for nullable source with nullable-param non-null-return method #4086 reproducer: compiled and executed successfully; generated code invokes mapValue(source.getValue()) directly.
  • Explicit-@Nullable return negative case: still produces the expected non-null-constructor diagnostic.
  • Full JSpecify*Test suite: 111 tests passed.
  • Focused reused-method, disabled-option, and verbose-diagnostic tests: 13 passed.
  • Constructor contract regression tests: 2 passed.
  • Full processor Surefire results: 3,561 tests, 0 failures, 0 errors.
  • Processor Checkstyle: passed with 0 violations.
  • Targeted MavenIntegrationTest#fullFeatureTest: passed.

The full reactor clean install -DskipDistribution=true exceeded the local 15-minute command limit after the processor suite completed; the affected integration path and Checkstyle were rerun successfully afterward.

kush2439p marked this pull request as ready for review August 10, 2026 12:44

aegliv commented Aug 19, 2026
edited
Loading

Copy link
Copy Markdown

Issue #4086 is only partially fixed by PR #4110. The reused method's result nullability is honoured when it is provable - either an explicit @NonNull return type or a @NullMarked scope - but this reproducer (the verbatim snippet from the issue) leaves the return type unannotated and outside any @NullMarked scope, so it stays UNKNOWN and PROPERTYMAPPING_NULLABLE_SOURCE_TO_NON_NULL_CONSTRUCTOR_PARAM is still raised.

@kush2439p plz verify using the verbatim snippet from #4086

Copy link
Copy Markdown
Author

Verified and fixed using the verbatim #4086 shape.

The new Issue4086Mapper leaves mapValue's return type unannotated and outside any @NullMarked scope. The generated implementation now invokes it directly:

payload = mapValue( source.getValue() );
Target target = new Target( payload );

The compatibility rule is intentionally narrow: a helper that accepts @Nullable input is invoked directly when its result is not explicitly @Nullable; an explicit @Nullable return still produces PROPERTYMAPPING_NULLABLE_SOURCE_TO_NON_NULL_CONSTRUCTOR_PARAM.

Verification:

The PR is ready for review.

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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.

Be able to generate the nullable mapping from the NotNull mapping

2 participants


Back | FazBrowse Home | New Git URL