Repository navigation
[Java] Remove unused and duplicate imports from generated code - #25157
Draft
ondrej-simon wants to merge 2 commits into
Draft
ondrej-simon wants to merge 2 commits into
ondrej-simon wants to merge 2 commits into
Conversation
Add a CodegenConfig#postProcessTemplateOutput hook, applied to the rendered template output in TemplateManager before it is written, and use it in AbstractJavaCodegen to remove unused and duplicate imports from all generated Java files (JavaImportPruner). Adapt tests which asserted imports that are not used by the generated code. See OpenAPITools#25145
Regenerate samples: unused and duplicate imports are removed from the generated Java files.
This branch has not been deployed
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.
Proof of concept for #25145: remove unused and duplicate imports from all generated Java files.
Draft / interim PR to gather feedback on the approach before polishing it.
How it works
New hook
CodegenConfig#postProcessTemplateOutput(String content, File target)(default: returns the content unchanged), applied inTemplateManager.writeto the rendered template output before it is written. This keepsminimalUpdateandskipOverwriteworking, and it applies to models, APIs and supporting files alike, including user-provided custom templates. Other generators (e.g. Kotlin) could reuse the hook later.AbstractJavaCodegenuses it for.javafiles with a new, dependency-freeJavaImportPruner. It is applied unconditionally (no option), as unused/duplicate imports are never desired.JavaImportPruneris a lexical pruner:java.util.Locale.ROOTdoes not count as a use of an importedLocale);{@link},@see,@throws, ...) are kept;LocaleImports #22313, [BUG] [JAVA] Imports in generated models ignore annotationLibrary option #21991);Removing an import whose simple name is not used cannot change the meaning of the code, since a single-type import only introduces that simple name.
Impact
Regenerating all 826 sample configs changes only
.javafiles: 7467 files, 43188 lines removed, 0 added, across 235 sample projects (Java clients, Spring, JAX-RS, Helidon, Micronaut, Camel, ...). No other sample changes.Example (
samples/client/petstore/java/restclient-springBoot4-jackson3/.../api/PetApi.java):Tests
JavaImportPrunerTest: unit tests for the pruner (comments/literals/text blocks, static and wildcard imports, Javadoc references, qualified usages, duplicates, type name clashes, nested types, blank lines).JavaClientCodegenTest#shouldRemoveUnusedImports(restclient, webclient) andSpringCodegenTest#shouldRemoveUnusedImports.testJspecify*: now assertorg.jspecify.annotations.Nullableis imported if and only if@Nullableis used.addsImportForSetResponse(jaxrs-spec):Setwas only used in a string (responseContainer = "Set"); the test now generatesinterfaceOnlywithoutResponse, where the method returnsSet<String>.annotationLibrary*([BUG] [JAVA] Imports in generated models ignore annotationLibrary option #21991): the swagger2Schemaimport clashes with the model namedSchemaand is now removed.shouldAddValidAnnotationIntoCollectionWhenBeanValidationIsEnabled_issue17150,testJdkHttpClientWithJackson3: asserted imports which are not used.supportsJackson3WithOpenApiNullableForSpringBoot4Libraries: now assertsJsonNullableJackson3Moduleis actually registered. This uncovered a bug: withresttemplate(Spring Boot 4, Jackson 3,openApiNullable=true), the module is only imported but registered for XML only (withXml), not for JSON. The test previously passed only because of the unused import. Marked with aFIXMEfor now, to be fixed separately.Verified locally: all tests of the generator module pass (except the C++ Boost runtime tests, which need a local Boost installation), and the pruned Spring Boot 4
spring/restclient/webclient, sealed oneOf,okhttp-gson,native,jersey3,feign,microprofile,jaxrs-spec,helidonandapache-httpclientsamples compile. I also tried it in a real-world project via the Maven plugin.Open questions
CodegenConfig/TemplateManagerhook acceptable, or is there a preferred place?PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
cc @wing328, Java technical committee: @bbdouglas @sreeshas @jfiala @lukoyanov @cbornet @jeff9finger @karismann @Zomzog @lwlee2608 @martin-mfg @KannaKim, Java Spring technical committee: @cachescrubber @welshm @MelleD @atextor @manedev79 @javisst @borsch @banlevente
Summary by cubic
Removes unused and duplicate imports from all generated Java files, addressing #25145.
CodegenConfig#postProcessTemplateOutputhook applied to rendered template output inTemplateManagerbefore writing, so it works withminimalUpdate,skipOverwrite, and custom templates;AbstractJavaCodegenuses it for all.javafiles unconditionally via the newJavaImportPruner.JavaImportPruneris a dependency-free lexical pruner: it masks comments, string/char literals, and text blocks; removes imports whose simple name never appears as an unqualified identifier; keeps wildcard imports and imports referenced from Javadoc; removes imports clashing with a top-level type declared in the same file; and collapses blank lines left in the import section..javafiles: 7,467 files, 43,188 lines removed, 0 added.Bug uncovered
openApiNullable=true, and theresttemplatelibrary,JsonNullableJackson3Moduleis imported but only registered for XML, not JSON; the existing test passed only because of the unused import. Marked with aFIXME, to be fixed separately.Written for commit 3fb1678. Summary will update on new commits.