Skip to content

Mergeable if statements should be combined - RSPEC-S1066#734

Open
olwispe wants to merge 20 commits intoopenrewrite:mainfrom
olwispe:combine-mergeable-if-statements-rspec-s1066
Open

Mergeable if statements should be combined - RSPEC-S1066#734
olwispe wants to merge 20 commits intoopenrewrite:mainfrom
olwispe:combine-mergeable-if-statements-rspec-s1066

Conversation

@olwispe
Copy link
Copy Markdown
Contributor

@olwispe olwispe commented Sep 8, 2025

What's changed?

This PR implements RSPEC-S1066 which was requested in :

What's your motivation?

Among others, help migrate to pattern matching for instanceof when combined with org.openrewrite.staticanalysis.InstanceOfPatternMatch :

if (o instanceof String) {
  String s = (String) o;
  if (s.isEmpty()) {
     System.out.println("OK");
  }
}
if (o instanceof String s && s.isEmpty()) {
  System.out.println("OK");
}

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

Anyone you would like to review specifically?

@timtebeek

Have you considered any alternatives or workarounds?

Any additional context

Checklist

  • I've added unit tests to cover both positive and negative cases
  • I've read and applied the recipe conventions and best practices
  • I've used the IntelliJ IDEA auto-formatter on affected files

@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Sep 8, 2025
Copy link
Copy Markdown
Member

@timtebeek timtebeek left a comment

Choose a reason for hiding this comment

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

Great to see @olwispe ! Added some light polish and I've been looking at the changes at scale.

Looking at these two examples I wonder if perhaps we should move the inner if conditional to a new line, and keep the comments in more of their original position.

image image image

I've pushed a quick test update that shows a comment lost. What are your thoughts to the above proposal?

@olwispe
Copy link
Copy Markdown
Contributor Author

olwispe commented Sep 8, 2025

Thanks for your comments.
I tend to prefer to have each merged conditional on a new line as you suggest and therefore keep the comments in their original position.

Comment thread src/main/java/org/openrewrite/staticanalysis/CombineMergeableIfStatements.java Outdated
@github-actions
Copy link
Copy Markdown
Contributor

This PR is stale because it has been open for 90 days with no activity. Remove stale label or comment or this will be closed in two weeks. PRs may be reopened when there is renewed interest.

@github-actions github-actions Bot added the Stale label Jan 26, 2026
@timtebeek timtebeek removed the Stale label Jan 27, 2026
Comment thread src/main/java/org/openrewrite/staticanalysis/CombineMergeableIfStatements.java Outdated
Comment thread src/main/java/org/openrewrite/staticanalysis/CombineMergeableIfStatements.java Outdated
Comment thread src/main/java/org/openrewrite/staticanalysis/CombineMergeableIfStatements.java Outdated
@olwispe
Copy link
Copy Markdown
Contributor Author

olwispe commented Jan 29, 2026

Hi @timtebeek!
I've implemented your earlier suggestions which were quite tricky to implement given my knowledge of OpenRewrite.
Anyway, could you review these changes?

@olwispe olwispe force-pushed the combine-mergeable-if-statements-rspec-s1066 branch from 2018f25 to f0c659e Compare February 3, 2026 18:32
Comment thread src/main/java/org/openrewrite/staticanalysis/CombineMergeableIfStatements.java Outdated
@timtebeek
Copy link
Copy Markdown
Member

Moderne Validation Summary — Apache Organization

Ran CombineMergeableIfStatements against the Apache Maven organization (87 repos, 81 succeeded, 6 skipped due to missing LSTs).

Results

  • 36 out of 81 repositories produced changes
  • ~127 files modified across those 36 repos
  • Top repos by changes: maven-2 (14 files), maven-scm (10 files), maven-doxia (10 files), maven-indexer (8 files), maven-wagon (6 files)

Additionally tested individually against apache/accumulo (30 files changed).

Correctness

Repos with standard 4-space indentation: All patches look correct. Conditions are properly merged with &&, comments are preserved, and the then body is correctly dedented by one level.

Repos with 2-space indentation (e.g., apache/accumulo): The recipe produces incorrect indentation in the merged if body. The indent(innerIf.getThenPart(), getCursor(), -1) call on line 107 dedents by 4 spaces (default IntelliJ style) instead of 2 spaces (the actual indent used in the file). This causes the body to shift left by too much, breaking compilation.

Example (accumulo, 2-space indent):

// Before (correct):
      if (!extentsToHost.isEmpty()) {
        if (...) {
          requestTabletHosting(context, extentsToHost.values());
        }
      }

// After (incorrect — body shifted too far left):
      if (!extentsToHost.isEmpty() &&
              (...)) {
      requestTabletHosting(context, extentsToHost.values());  // should be 8 spaces, got 6
    }

Root Cause

ShiftFormat.indent() uses the file's TabsAndIndentsStyle (defaulting to IntelliJ's 4-space indent), but repos like accumulo use 2-space indentation without an explicit style marker. The -1 level shift therefore removes 4 spaces instead of 2.

Replace ShiftFormat.indent(-1) with a custom shiftLeft that computes
the actual indent difference between the inner and outer if statements.
indent(-1) always used the default 4-space indent size, causing broken
indentation in repos using 2-space indent (e.g., Apache Accumulo).

Add test case for 2-space indentation.
@timtebeek
Copy link
Copy Markdown
Member

Fix Applied: Indentation bug with non-4-space indent

Pushed commit 488123b1 to fix the indentation issue found during validation.

Problem

ShiftFormat.indent(-1) always dedented by 4 spaces (IntelliJ default), breaking repos that use 2-space indentation (like Apache Accumulo). The body of the merged if statement would shift too far left, producing malformed code.

Fix

Replaced indent(-1) with a custom shiftLeft() method that computes the actual indent difference between the inner and outer if statements by measuring their whitespace. This works correctly regardless of indent style (2-space, 4-space, tabs, etc.).

Test

Added combineMergeableIfStatementsWithTwoSpaceIndent test case that verifies the recipe produces correct indentation with 2-space indent style.

Comment thread src/main/java/org/openrewrite/staticanalysis/CombineMergeableIfStatements.java Outdated
timtebeek and others added 3 commits March 30, 2026 14:08
Co-authored-by: Tim te Beek <timtebeek@gmail.com>
Replace hand-rolled indentation shifting with the existing
ShiftFormat.indent() utility from rewrite-java, which properly
handles tabs vs spaces based on TabsAndIndentsStyle.
Replace ShiftFormat.indent() with autoFormat(merged, ctx) which
delegates indentation correction to the standard formatting pipeline.
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.

2 participants