Repository navigation
Detect build method by signature in builder contract check - #320
Merged
AndreasIgel merged 7 commits intoOct 3, 2026
Merged
AndreasIgel merged 7 commits into
AndreasIgel merged 7 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Generated code emits a literal call to the builder's terminal method, so the contract resolution must remember which method matched. When several parameterless methods return the referenced type, 'build' is preferred and the alphabetically first name is chosen otherwise - matching the create()/of() preference used for static factories. Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
The contract-specific selection (build-name preference, non-static and Object-method filtering) belongs to the resolver's contract check; JavaLangAnalyser keeps only the generic findMethods lookup, which already restricts candidates to members accessible from the generated builder's package. Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
Like the instantiationCode/methodReference renderers on BuilderInstantiation, the record now renders its own terminal call via buildCall(builderExpression); MethodGeneratorUtil's private calculateBuildExpression helper is no longer needed. Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
Renamed to isMethodOfObjectClass alongside isNoMethodOfObjectClass: the existing check filters by declaring type and misses overrides like StringBuilder.toString, while the signature comparison catches them. Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
…overage The existing check filtered by declaring type and missed overrides like StringBuilder.toString; now signature-based and shared between setter detection and the contract's build-method selection. New tests: StringBuilder rejected for String (Object-signature guard), inherited build method selected, package-private build method rejected when inaccessible. Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
Fold the new rejection cases into rejectedContractVariants and point the resolve-side tests at the equivalent usageWithoutAnnotation probe instead of a duplicated contractResult field (Sonar java:S5976). Co-Authored-By: Andreas Igel <andreas.igel@computacenter.com>
|
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
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes #319
Sub-task of #301.
Summary
The builder-contract check in
BuilderScopeResolverrequired the build method to be literally namedbuild. This drops the name check so any accessible, non-static, parameterless method returning the referenced type satisfies the contract — matchingSimpleBuildersBuilderProvider.findBuildMethods, which already detects build methods by signature.BuilderScopeResolver.findBuildMethodselects the terminal method by signature: parameterless + return-type match + accessible from the generated builder's package (the last via the genericfindMethods), excluding static methods andjava.lang.Objectsignatures. When several candidates exist,buildis preferred, then the alphabetically first name — the same conventioncreate()/of()already use for static factories.JavaLangAnalyser.isNoMethodOfObjectClassis now signature-based (was declaration-site), so overrides likeStringBuilder.toStringare also excluded — otherwiseStringBuilder.toString()+StringBuilder(String)would falsely satisfy the contract forString. The shared check is used by setter detection and the contract alike.ResolvedBuildercarries the selectedbuildMethodNameand renders the terminal call itself (buildCall), consistent withBuilderInstantiation.instantiationCode/methodReference; generated code emitsbuilder.<name>()instead of a hard-codedbuild().Tests
buildname (toTarget()) resolves and the picked name is recorded; inherited build methods count;buildis preferred over other candidates; alphabetical fallback withoutbuild.void/parameterised/static/non-public returning methods, package-private methods inaccessible from the generated package, andStringBuilderforString(Object-signature guard).mvn -pl processor test: 496 tests, 0 failures. Generated example builders unchanged.