Skip to content

Conversation

dsgrieve
Copy link

@dsgrieve dsgrieve commented Sep 9, 2025

What's changed?

Added MoveFieldsToTopOfClass recipe and tests. This recipe reorders class members so that all field declarations appear before any method declarations constructors, or other class members. This improves code organization and readability by grouping field declarations together at the top of the class. Comments associated with fields are preserved during the reordering.

What's your motivation?

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

Anyone you would like to review specifically?

Have you considered any alternatives or workarounds?

Any additional context

This PR adds the recipe to static-analysis.yml. I'm not sure if that should be done in a separate PR, or not done at all.

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 9, 2025
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

@greg-at-moderne greg-at-moderne left a comment

Choose a reason for hiding this comment

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

Other than Tim's comments, approving.

@github-project-automation github-project-automation bot moved this from In Progress to Ready to Review in OpenRewrite Sep 10, 2025
dsgrieve and others added 2 commits September 11, 2025 17:35
* Implemented Comparator-based sorting
  - public static final > protected static final > private static final
  - > public final > protected final > private final
  - > public > protected > private
* Preserved comments and spacing - Proper formatting maintained
Fix sort order of fields by modifier

Co-authored-by: Jenson3210 <[email protected]>
dsgrieve and others added 2 commits September 12, 2025 15:56
…Class.java

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
dsgrieve and others added 2 commits September 16, 2025 16:00
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
…Class.java

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@dsgrieve
Copy link
Author

The current issue is keeping a static intializer with the variable it's initializing. For instance, this simple test case will fail.

    @Test
    void staticInitializerStaysWithDeclaration() {
        rewriteRun(
          //language=java
          java(
            """
              class WithStaticInitializer {
                  public void method() {
                      System.out.println("method");
                  }

                  private static final String field1;
                  static {
                      field1 = "value1";
                  }

                  public WithStaticInitializer() {
                      // constructor
                  }
              }
              """,
            """
              class WithStaticInitializer {

                  private static final String field1;
                  static {
                      field1 = "value1";
                  }
                  public void method() {
                      System.out.println("method");
                  }

                  public WithStaticInitializer() {
                      // constructor
                  }
              }
              """
          )
        );
    }

In addition, I would expect a static initializer block that initializes more than one variable to appear after the last variable declared (of those being initialized). I would also expect that other static blocks that aren't initializing a variable (doing something you want done when the class is first loaded) to come after all the variable declarations. None of these are being handled.

Also, as @Jenson3210 points out, this could be a reorder statements recipe - which it is tending toward anyway. I'll add that how the statements are ordered should be a Style (even for the field decls, the ordering for which follows Oracle code conventions

Lastly, this recipe in its current state messes up the formatting. But, as discussed with @sambsnyd, trying to maintain spacing seems overreach for this recipe.

I feel, however, that without handling statement reordering and formatting this recipe in its current incantation just makes a mess of things. In short, moving the fields to the top is fairly trivial. Doing it correctly, however, is a bit tricky.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Ready to Review
Development

Successfully merging this pull request may close these issues.

Recipe to move fields to the top of class definition
4 participants