Expand star imports in ChangePackage and related recipes when they would create ambiguity#7202
Open
steve-aom-elliott wants to merge 16 commits intomainfrom
Open
Expand star imports in ChangePackage and related recipes when they would create ambiguity#7202steve-aom-elliott wants to merge 16 commits intomainfrom
steve-aom-elliott wants to merge 16 commits intomainfrom
Conversation
Closed
3 tasks
a6ee247 to
c7942f8
Compare
e50f48f to
48f89f5
Compare
sambsnyd
reviewed
Apr 7, 2026
rewrite-gradle/src/main/java/org/openrewrite/gradle/AddDependency.java
Outdated
Show resolved
Hide resolved
rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependency.java
Show resolved
Hide resolved
rewrite-gradle/src/main/java/org/openrewrite/gradle/ChangeDependency.java
Outdated
Show resolved
Hide resolved
When ChangePackage renames a star import (e.g. import origpkg.* to import newpkg.*), the new package may contain types whose simple names clash with types from other star imports in the same file. This creates ambiguous imports that fail to compile. This change converts ChangePackage to a ScanningRecipe so it can first collect which types exist in which packages across all source files, then use that information to detect ambiguity. When a changed star import would create ambiguity, it is expanded into explicit imports for only the types actually used from that package. Fixes moderneinc/customer-requests#1733
… classpath for ambiguity detection
Move annotation interface definitions out of source specs and into parser dependsOn, so the tests focus on the consumer file's import behavior rather than asserting changes to the definition files.
Replace synthetic test packages with real javax/jakarta/hibernate validation types from recipeDependencies. Use JavaSourceSet.build with classpath to populate the source set marker. Switch from typesInUse to AST identifier walking for collecting referenced types, since typesInUse does not include annotation types resolved through star imports.
- Use javax.validation:validation-api:1.1 (no NotBlank), jakarta.validation-api:2.0.2, and org.hibernate:hibernate-validator:5.4.3 (has NotBlank) so @notblank unambiguously resolves from org.hibernate.validator.constraints - Fix hasAmbiguity to also check the original (pre-rename) package on the classpath, since the classpath may not yet have types under the new package name - Regenerate type table for updated parserClasspath versions
Use classpathFromResources + srcMainJava + addTypesToSourceSet instead of manual JavaSourceSet.build and classpath. Move validation and hibernate deps to testParserClasspath since they're only needed by ChangePackageTest.
When dependency recipes (ChangeDependency, AddDependency, RemoveDependency, UpgradeDependencyVersion) modify a module's dependencies, the JavaSourceSet marker on Java source files now reflects those changes. This allows downstream recipes like ChangePackage to correctly detect ambiguous star imports that arise from classpath changes. Adds JavaSourceSetUpdater utility that downloads new dependency JARs and scans them for types, then updates the JavaSourceSet's classpath and gavToTypes map. All operations are idempotent to maintain single-cycle recipe stability.
…endency AddDependency (both Maven and Gradle) was constructing a synthetic ResolvedDependency with MavenRepository.MAVEN_CENTRAL hardcoded as the repository. This would fail to download JARs in air-gapped environments or when the dependency lives in a private repository. Changed JavaSourceSetUpdater.addDependency to accept a list of repositories and try each one until the JAR is found. The scanners now capture the project's actual repositories during version resolution.
When ChangeType moves a type into a package covered by a star import, and another star import provides a type with the same simple name, add an explicit import to disambiguate. This mirrors the ambiguity handling already present in ChangePackage.
…ntegration test Move the withSourceTypesOnClasspath test helper from private methods in ChangePackageTest and ChangeTypeTest to a public static method in Assertions.java so it can be reused across test classes. Add an end-to-end integration test in ChangeDependencyGroupIdAndArtifactIdTest that composes ChangeDependencyGroupIdAndArtifactId with ChangePackage to verify that import renaming works correctly when the JavaSourceSet is updated by the dependency change recipe.
…rce set updates - Attach Markup.warn to build files when version resolution for JavaSourceSet updates fails, so users know the classpath won't be updated - Remove counter-productive G.CompilationUnit/K.CompilationUnit exclusion in Gradle AddDependency and ChangeDependency — Groovy/Kotlin source files can have JavaSourceSet markers; Gradle build files won't have one and are already filtered by the maybeSourceSet.isPresent() check - Cache computed JavaSourceSet per source set in ChangeDependency (Gradle) and ChangeDependencyGroupIdAndArtifactId (Maven) to avoid redundant per-file recomputation when all files in a source set share identical markers
… ChangeDependency Capture Maven repositories from GradleProject in the scanner and use them when downloading JARs for JavaSourceSet updates, falling back to Maven Central only if no remote repository is available. This matches the approach already used in Maven ChangeDependencyGroupIdAndArtifactId and both AddDependency recipes.
7566269 to
7bc9f18
Compare
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.
Summary
ChangePackagerenames a star import (e.g.,import javax.validation.constraints.*→import jakarta.validation.constraints.*), it now detects if the new package contains types whose simple names clash with types from other star imports (e.g.,org.hibernate.validator.constraints.*also hasNotBlank)JavaSourceSetclasspath to enumerate types in each package, then walks AST identifiers to determine which types are actually referencedChangeTypenow also detects when its target type is covered by a star import that would become ambiguous with another star import, and inserts an explicit import to disambiguateChangeDependencyGroupIdAndArtifactId(Maven) andAddDependency(Maven and Gradle) now update theJavaSourceSetmarker when changing or adding dependencies, so downstream recipes likeChangePackageandChangeTypehave accurate classpath data for ambiguity detectionJavaSourceSetUpdater.addDependencynow tries the project's actual Maven repositories instead of hardcoding Maven Central, fixing failures in air-gapped environments or projects using private repositorieswithSourceTypesOnClasspathtest helper extracted toAssertions.javafor reuse across test classesTest plan
changePackageExpandsStarImportWhenItWouldCreateAmbiguity— uses realjavax.validation,jakarta.validation, andorg.hibernate.validatortypes; verifies star import is expanded to explicit imports when another star import contains a type with the same simple namechangePackagePreservesStarImportWhenNoAmbiguity— verifies star import is preserved when no ambiguity existschangeTypeAddsExplicitImportWhenStarImportsWouldBeAmbiguous— verifies ChangeType inserts an explicit import when two star imports would both provide the target type's simple namecomposedWithChangePackageUpdatesImports— end-to-end test composingChangeDependencyGroupIdAndArtifactId+ChangePackageto verify import renaming works when the JavaSourceSet is updated by the dependency changeChangePackageTest,ChangeTypeTest, andChangeDependencyGroupIdAndArtifactIdTestsuites pass