Skip to content

Prevent marker-only changes from producing phantom diffs#7358

Merged
steve-aom-elliott merged 1 commit intomainfrom
fix/marker-only-phantom-diffs
Apr 13, 2026
Merged

Prevent marker-only changes from producing phantom diffs#7358
steve-aom-elliott merged 1 commit intomainfrom
fix/marker-only-phantom-diffs

Conversation

@steve-aom-elliott
Copy link
Copy Markdown
Contributor

@steve-aom-elliott steve-aom-elliott commented Apr 13, 2026

Summary

  • Dependency-modifying recipes now update JavaSourceSet markers (Expand star imports in ChangePackage and related recipes when they would create ambiguity #7202), which can produce Result objects with identical before/after printed text. This caused "An empty diff was generated" test failures in downstream repos:

  • moderneinc/rewrite-dropwizard — addsSpringStarterJdbcWhenDropwizardDbIsUsed

  • openrewrite/rewrite-hibernate — groupIdHibernateOrmRenamed

  • openrewrite/rewrite-migrate-java — changeAndUpgradeDependencyIfAnnotationJsr250Present

  • openrewrite/rewrite-spring — flywayStarterOmitsVersionWhenManagedByParent

Three fixes, each addressing a different layer:

  1. JavaSourceSet.addTypesForGav idempotency — returns this when the gavKey already exists with the same types, preventing unnecessary object allocation (especially for LSTs with empty gavToTypes maps where the existing guard in changeDependency doesn't fire).

  2. JavaSourceSet.updateOnSourceFile (cached overload) — checks whether the source file's current marker is already the cached instance before calling withMarkers, preventing O(n) new tree references across all files in a source set when only the first file truly changed.

  3. RewriteTest safety net — accepts marker-only changes (identical before/after text) instead of failing, since these represent legitimate internal state updates. Calls afterRecipe so marker assertions still work.

All four downstream test failures were verified to pass with these changes.

Dependency-modifying recipes now update JavaSourceSet markers (added in
#7202), which can produce Results with identical before/after text. This
caused downstream test failures in rewrite-dropwizard, rewrite-hibernate,
rewrite-migrate-java, and rewrite-spring.

Three fixes:

1. JavaSourceSet.addTypesForGav returns `this` when the gavKey already
   exists with the same types, preventing unnecessary allocations for
   LSTs with empty gavToTypes maps.

2. The cached overload of JavaSourceSet.updateOnSourceFile now checks
   whether the source file's current marker is already the cached
   instance before replacing it, preventing O(n) phantom diffs across
   files in the same source set.

3. RewriteTest accepts marker-only changes (identical printed text)
   instead of failing with "An empty diff was generated", since these
   represent legitimate internal state updates.

Closes #7349
@github-project-automation github-project-automation bot moved this to In Progress in OpenRewrite Apr 13, 2026
@steve-aom-elliott steve-aom-elliott added bug Something isn't working enhancement New feature or request labels Apr 13, 2026
@steve-aom-elliott steve-aom-elliott moved this from In Progress to Ready to Review in OpenRewrite Apr 13, 2026
*/
public JavaSourceSet addTypesForGav(String gavKey, List<JavaType.FullyQualified> types) {
List<JavaType.FullyQualified> existing = gavToTypes.get(gavKey);
if (existing != null && existing.equals(types)) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose there's no way to prevent the deep equality comparison here? Are there any shortcuts like comparing the sizes? Or is that already built into equals?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the size check is one of the first things it does, thankfully. Then this is less of a concern.

@steve-aom-elliott steve-aom-elliott merged commit 6d85e4a into main Apr 13, 2026
1 check passed
@steve-aom-elliott steve-aom-elliott deleted the fix/marker-only-phantom-diffs branch April 13, 2026 12:12
@github-project-automation github-project-automation bot moved this from Ready to Review to Done in OpenRewrite Apr 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

ChangeDependencyGroupIdAndArtifactId generates empty diffs on Java files after #7202

2 participants