Skip to content

Preserve comments before unwrapped else blocks - #992

Open
martinfrancois wants to merge 1 commit into
openrewrite:mainfrom
martinfrancois:repro/unwrap-else-comment-before-else
Open

Preserve comments before unwrapped else blocks#992
martinfrancois wants to merge 1 commit into
openrewrite:mainfrom
martinfrancois:repro/unwrap-else-comment-before-else

Conversation

@martinfrancois

@martinfrancois martinfrancois commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Suggested review order: 4 of 52 (Score: 9)
Review first: openrewrite/rewrite-migrate-java#1192

What's changed?

Preserves comments stored before an else keyword when UnwrapElseAfterReturn removes that else. The comment is attached to the first unwrapped statement together with its original leading whitespace. Two regressions cover both multiline and inline starts of the former else block.

What's your motivation?

Recipe: org.openrewrite.staticanalysis.UnwrapElseAfterReturn.

UnwrapElseAfterReturn removes an else after a return and moves the else body up one level. When the developer wrote a comment right before the else keyword, that comment disappears.

Before

class Test {
    int foo(boolean condition) {
        if (condition) {
            return 1;
        }
        // Handle false condition
        else {
            return 2;
        }
    }
}

Actual after the recipe

Using current main before this change.

class Test {
    int foo(boolean condition) {
        if (condition) {
            return 1;
        }
        return 2;
    }
}

The output still compiles, but the comment // Handle false condition is gone.

Expected after the recipe

The output MUST keep // Handle false condition immediately before the unwrapped return 2; statement, as the second text block in the test expects.

The mechanism, read from UnwrapElseAfterReturn.java: the flatten helper carries over comments from the else block's prefix (between else and {) and from the first statement inside the block. Both of those positions are already covered by the existing tests commentsEverywhere and commentsOnlyInBlocks, added with #654 and #655. Comments in the else part's own prefix, between the then block's closing brace and the else keyword, are never copied, and ifStatement.withElsePart(null) discards them. This assumes the standard recipe run; the new test uses plain rewriteRun like its neighbors.

I found this while preparing #979, which fixes a related defect in this recipe. The defect here reproduces on current main on its own, independent of #979.

Affected code in real projects

  • elastic/elasticsearch IndexResolver.java: the then branch ends with return new InvalidMappedField(...), and the comment // type is okay, check aggregation sits between the closing brace and the else keyword. The recipe from main unwraps the else and deletes that comment.
  • spring-projects/spring-framework WhatWgUrlParser.java: this parser annotates each branch with the corresponding step quoted from the WHATWG URL spec. The if (endsInNumber(asciiDomain)) branch ends with a return, so the recipe from main unwraps the else and drops the // Return asciiDomain. spec-step comment that documents it.

Anything in particular you'd like reviewers to focus on?

Please review the ordering of comments from the else part, the else block, and its first statement. Also review the conditional whitespace transfer: whitespace from the else part is used only when that part owns comments, so comments already inside the block retain their existing line placement.

Any additional context

Pre-existing tests changed: None.

Related PR #979 touches the same recipe but does not fix this comment position. The earlier #654 and #655 handle comments inside the else block; this change handles comments stored before the else keyword.

  • Focused verification: ./gradlew test --tests org.openrewrite.staticanalysis.UnwrapElseAfterReturnTest passes all 22 tests.
  • Repository build: compilation, assembly, licensing, recipe CSV validation, and Java tests reach the full suite; eight unrelated Python tests stop because /usr/bin/python3 on this machine has no pip.

This change was prepared with AI assistance. I reviewed the implementation, regression tests, generated output, and description.

Checklist

@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Aug 11, 2026
@martinfrancois martinfrancois changed the title UnwrapElseAfterReturn: add failing test for comment dropped before else keyword Preserve comments before unwrapped else blocks Aug 15, 2026
@martinfrancois
martinfrancois force-pushed the repro/unwrap-else-comment-before-else branch from 9ae338e to c3a9e27 Compare August 15, 2026 20:01
@martinfrancois
martinfrancois force-pushed the repro/unwrap-else-comment-before-else branch from c3a9e27 to 2cb3713 Compare August 16, 2026 02:53
@martinfrancois
martinfrancois marked this pull request as ready for review August 17, 2026 08:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

1 participant