Skip to content

chore: shorten fully-qualified type names via OpenRewrite - #2673

Open
maxandersen wants to merge 2 commits into
jbangdev:mainfrom
maxandersen:build/openrewrite-shorten-fqn
Open

maxandersen wants to merge 2 commits into
jbangdev:mainfrom
maxandersen:build/openrewrite-shorten-fqn

Conversation

@maxandersen

@maxandersen maxandersen commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

I tried making spotless do removal of Fully qualified names that LLM's has an annoying tendency to include - but spotless does not use a type aware formatter so it misses too much. this pr uses openrewrite to properly check for it.

Also introduces a dedicated format and formatCheck gradle task - does make formatting slightly slower but its "just" compile which you need to do 99% of the time anyway.

Summary

Introduce OpenRewrite with the ShortenFullyQualifiedTypeReferences recipe to replace inline fully-qualified type names with simple names + imports, and apply it (25 files).

 plugins {
   id "com.diffplug.spotless" version "8.6.0"
+  id "org.openrewrite.rewrite" version "7.39.0"
 }
+rewrite {
+  activeRecipe('org.openrewrite.java.ShortenFullyQualifiedTypeReferences')
+  activeStyle('dev.jbang.ImportStyle')          // rewrite.yml: no wildcard imports
+  exclusion('*.gradle', 'settings.gradle', '**/*.gradle', '**/*.gradle.kts')
+}

Example of what it does:

-		java.util.List<String> cmd = prefixShellArgs(java.util.Arrays.asList(command));
+import java.util.Arrays;
+import java.util.List;
 		List<String> cmd = prefixShellArgs(Arrays.asList(command));

Why OpenRewrite and not a formatter step? Unlike Spotless/CleanThat (which run without a classpath and must guess with heuristics), OpenRewrite builds a type-attributed model from the compile classpath, so it shortens safely across the whole module — including cases a classpath-free tool must leave alone (types in classes with an external superclass, method references on fields like catalog.aliases::get, etc.).

Evidence

./gradlew rewriteRun        # applies the recipe -> 25 files
./gradlew compileJava compileTestJava spotlessCheck   # all green
./gradlew test --tests TestExport --tests TestJarMainDetection --tests TestJdk   # PASS
  • 25 files shortened, 0 wildcard imports (no-star ImportLayoutStyle), compiles clean, spotless-clean.
  • catalog.aliases::get (a method reference on a field) correctly left untouched — OpenRewrite knows catalog is a local variable.

Merge Danger

Door: two-way. Pure type-preserving rewrite (FQN → simple name + import); trivially revertible, and re-runnable via ./gradlew rewriteRun.

Blast Radius: wide but shallow — 25 source files touched, imports-only + name-only edits, no behavior change (compile + tests + spotless all green).

Notes:

  • *.gradle is excluded on purpose: OpenRewrite's Groovy support shortens stdlib types (e.g. groovy.json.JsonOutput) without adding the import, which breaks the Gradle script.
  • Plugin pinned to 7.39.0: 7.40.0/7.41.0 currently fail to resolve (they depend on rewrite-bom:8.91.0, not yet on Maven Central). Bump once it syncs.
  • CI could gate drift with ./gradlew rewriteDryRun (not added here).

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • ai-review

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b638d75c-06d7-40f8-b61d-865603ae6648

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@maxandersen
maxandersen force-pushed the build/openrewrite-shorten-fqn branch 2 times, most recently from 42609a5 to 21773a7 Compare October 7, 2026 07:45
Comment thread src/main/java/dev/jbang/cli/BaseCommand.java Dismissed
@maxandersen
maxandersen force-pushed the build/openrewrite-shorten-fqn branch 3 times, most recently from ab60c11 to 40e7580 Compare October 7, 2026 09:28
@maxandersen
maxandersen marked this pull request as ready for review October 7, 2026 09:29
@maxandersen
maxandersen force-pushed the build/openrewrite-shorten-fqn branch 2 times, most recently from e52ecb5 to 0a9be76 Compare October 7, 2026 09:38
…ng gate

Add the org.openrewrite.rewrite plugin wired to the
ShortenFullyQualifiedTypeReferences recipe (shortens inline fully-qualified
type names to simple names + imports, resolved from the compile classpath).

- rewrite.yml: no-star ImportLayoutStyle (jbang forbids wildcard imports)
- exclude *.gradle (OpenRewrite's Groovy shortening drops needed imports)
- failOnDryRunResults = true so rewriteDryRun fails on FQN drift
- 'format'/'formatCheck' run OpenRewrite + Spotless together (Spotless after)
- check depends on formatCheck; build/release jobs use '-x check'
- docs/tooling: CONTRIBUTING.adoc, AGENTS.md and the justfile 'format' recipe
  now use 'gradle format'/'formatCheck'

Apply with './gradlew format'.
Output of './gradlew rewriteRun' - shorten fully-qualified type names to
simple names + imports across the module. Pure type-preserving rewrite.
@maxandersen
maxandersen force-pushed the build/openrewrite-shorten-fqn branch from 0a9be76 to c4071a4 Compare October 7, 2026 09:39

This branch has not been deployed

No deployments
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.

2 participants