From 62cc025865759878436e487308cebe8c3c8a7d7a Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Mon, 8 Sep 2025 13:20:44 +0200 Subject: [PATCH 01/13] Have claude generate tests --- .../java/tree/ClassDeclarationTest.java | 189 ++++++++++++++++++ .../java/tree/MethodDeclarationTest.java | 128 ++++++++++++ 2 files changed, 317 insertions(+) diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java index 343a6d1972..b41aae67b3 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java @@ -22,6 +22,7 @@ import org.openrewrite.Issue; import org.openrewrite.java.JavaIsoVisitor; import org.openrewrite.java.MinimumJava17; +import org.openrewrite.java.MinimumJava25; import org.openrewrite.test.RewriteTest; import static org.assertj.core.api.Assertions.assertThat; @@ -276,4 +277,192 @@ class A { ) ); } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithMainMethod() { + rewriteRun( + java( + """ + void main() { + System.out.println("Hello from implicit class!"); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithMultipleMethods() { + rewriteRun( + java( + """ + void main() { + greet("World"); + } + + void greet(String name) { + System.out.println("Hello, " + name + "!"); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithFields() { + rewriteRun( + java( + """ + String greeting = "Hello"; + + void main() { + System.out.println(greeting + ", World!"); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithStaticFields() { + rewriteRun( + java( + """ + static int counter = 0; + + void main() { + counter++; + System.out.println("Counter: " + counter); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithImports() { + rewriteRun( + java( + """ + import java.util.List; + import java.util.ArrayList; + + void main() { + List names = new ArrayList<>(); + names.add("Alice"); + names.add("Bob"); + System.out.println(names); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithPackageStatement() { + rewriteRun( + java( + """ + package com.example; + + void main() { + System.out.println("Hello from package!"); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithStaticInitializer() { + rewriteRun( + java( + """ + static { + System.out.println("Static initializer"); + } + + void main() { + System.out.println("Main method"); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithInstanceInitializer() { + rewriteRun( + java( + """ + { + System.out.println("Instance initializer"); + } + + void main() { + System.out.println("Main method"); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithConstructor() { + rewriteRun( + java( + """ + private String name; + + Main(String name) { + this.name = name; + } + + void main() { + System.out.println("Name: " + name); + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void implicitClassWithInnerClass() { + rewriteRun( + java( + """ + void main() { + Helper helper = new Helper(); + helper.help(); + } + + class Helper { + void help() { + System.out.println("Helping!"); + } + } + """ + ) + ); + } } diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java index 02a7dd20f7..c45ba96b4a 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java @@ -16,6 +16,8 @@ package org.openrewrite.java.tree; import org.junit.jupiter.api.Test; +import org.openrewrite.Issue; +import org.openrewrite.java.MinimumJava25; import org.openrewrite.test.RewriteTest; import static org.openrewrite.java.Assertions.java; @@ -116,4 +118,130 @@ public void foo() { }/*Comments*/ ); } + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void instanceMainMethodWithNoParameters() { + rewriteRun( + java( + """ + class HelloWorld { + void main() { + System.out.println("Hello, World!"); + } + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void instanceMainMethodWithStringArrayParameter() { + rewriteRun( + java( + """ + class HelloWorld { + void main(String[] args) { + System.out.println("Hello, World!"); + } + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void publicInstanceMainMethod() { + rewriteRun( + java( + """ + public class HelloWorld { + public void main() { + System.out.println("Hello, World!"); + } + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void protectedInstanceMainMethod() { + rewriteRun( + java( + """ + class HelloWorld { + protected void main(String[] args) { + System.out.println("Hello, World!"); + } + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void instanceMainMethodWithInstanceFields() { + rewriteRun( + java( + """ + class Counter { + private int count = 0; + + void main() { + count++; + System.out.println("Count: " + count); + } + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void instanceMainMethodCallingInstanceMethods() { + rewriteRun( + java( + """ + class Greeter { + void main() { + greet("World"); + } + + void greet(String name) { + System.out.println("Hello, " + name + "!"); + } + } + """ + ) + ); + } + + @Issue("https://openjdk.org/jeps/512") + @MinimumJava25 + @Test + void staticMainMethodStillSupported() { + rewriteRun( + java( + """ + class TraditionalMain { + public static void main(String[] args) { + System.out.println("Traditional main method"); + } + } + """ + ) + ); + } + } From 07b306db0a0be9594047f4bca71386bd019e2984 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Mon, 8 Sep 2025 16:13:44 +0200 Subject: [PATCH 02/13] Nest tests and reduce annotations --- .../java/tree/ClassDeclarationTest.java | 302 ++++++++---------- .../java/tree/MethodDeclarationTest.java | 195 +++++------ 2 files changed, 206 insertions(+), 291 deletions(-) diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java index b41aae67b3..ed65246a74 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java @@ -16,6 +16,7 @@ package org.openrewrite.java.tree; import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @@ -280,189 +281,140 @@ class A { @Issue("https://openjdk.org/jeps/512") @MinimumJava25 - @Test - void implicitClassWithMainMethod() { - rewriteRun( - java( - """ - void main() { - System.out.println("Hello from implicit class!"); - } - """ - ) - ); - } + @Nested + class ImplicitClasses implements RewriteTest { - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithMultipleMethods() { - rewriteRun( - java( - """ - void main() { - greet("World"); - } - - void greet(String name) { - System.out.println("Hello, " + name + "!"); - } - """ - ) - ); - } - - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithFields() { - rewriteRun( - java( - """ - String greeting = "Hello"; - - void main() { - System.out.println(greeting + ", World!"); - } - """ - ) - ); - } + @Test + void implicitClassWithMainMethod() { + rewriteRun( + java( + """ + void main() { + System.out.println("Hello from implicit class!"); + } + """ + ) + ); + } - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithStaticFields() { - rewriteRun( - java( - """ - static int counter = 0; - - void main() { - counter++; - System.out.println("Counter: " + counter); - } - """ - ) - ); - } + @Test + void implicitClassWithMultipleMethods() { + rewriteRun( + java( + """ + void main() { + greet("World"); + } + + void greet(String name) { + System.out.println("Hello, " + name + "!"); + } + """ + ) + ); + } - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithImports() { - rewriteRun( - java( - """ - import java.util.List; - import java.util.ArrayList; - - void main() { - List names = new ArrayList<>(); - names.add("Alice"); - names.add("Bob"); - System.out.println(names); - } - """ - ) - ); - } + @Test + void implicitClassWithFields() { + rewriteRun( + java( + """ + String greeting = "Hello"; + + void main() { + System.out.println(greeting + ", World!"); + } + """ + ) + ); + } - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithPackageStatement() { - rewriteRun( - java( - """ - package com.example; - - void main() { - System.out.println("Hello from package!"); - } - """ - ) - ); - } + @Test + void implicitClassUtilizingJavaBase() { + rewriteRun( + java( + """ + void main() { + List names = new ArrayList<>(); + names.add("Alice"); + names.add("Bob"); + System.out.println(names); + } + """ + ) + ); + } - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithStaticInitializer() { - rewriteRun( - java( - """ - static { - System.out.println("Static initializer"); - } - - void main() { - System.out.println("Main method"); - } - """ - ) - ); - } + @Test + void implicitClassWithPackageStatement() { + rewriteRun( + java( + """ + package com.example; + + void main() { + System.out.println("Hello from package!"); + } + """ + ) + ); + } - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithInstanceInitializer() { - rewriteRun( - java( - """ - { - System.out.println("Instance initializer"); - } - - void main() { - System.out.println("Main method"); - } - """ - ) - ); - } + @Test + void implicitClassWithStaticInitializer() { + rewriteRun( + java( + """ + static { + System.out.println("Static initializer"); + } + + void main() { + System.out.println("Main method"); + } + """ + ) + ); + } - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithConstructor() { - rewriteRun( - java( - """ - private String name; - - Main(String name) { - this.name = name; - } - - void main() { - System.out.println("Name: " + name); - } - """ - ) - ); - } + @Test + void implicitClassWithConstructor() { + rewriteRun( + java( + """ + private String name; + + Main(String name) { + this.name = name; + } + + void main() { + System.out.println("Name: " + name); + } + """, + spec -> spec.path("com/example/Main.java") + ) + ); + } - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void implicitClassWithInnerClass() { - rewriteRun( - java( - """ - void main() { - Helper helper = new Helper(); - helper.help(); - } - - class Helper { - void help() { - System.out.println("Helping!"); + @Test + void implicitClassWithInnerClass() { + rewriteRun( + java( + """ + void main() { + Helper helper = new Helper(); + helper.help(); } - } - """ - ) - ); + + class Helper { + void help() { + System.out.println("Helping!"); + } + } + """ + ) + ); + } } } diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java index c45ba96b4a..5df13459f7 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java @@ -15,6 +15,7 @@ */ package org.openrewrite.java.tree; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.openrewrite.Issue; import org.openrewrite.java.MinimumJava25; @@ -120,128 +121,90 @@ public void foo() { }/*Comments*/ @Issue("https://openjdk.org/jeps/512") @MinimumJava25 - @Test - void instanceMainMethodWithNoParameters() { - rewriteRun( - java( - """ - class HelloWorld { - void main() { - System.out.println("Hello, World!"); - } - } - """ - ) - ); - } - - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void instanceMainMethodWithStringArrayParameter() { - rewriteRun( - java( - """ - class HelloWorld { - void main(String[] args) { - System.out.println("Hello, World!"); - } - } - """ - ) - ); - } - - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void publicInstanceMainMethod() { - rewriteRun( - java( - """ - public class HelloWorld { - public void main() { - System.out.println("Hello, World!"); + @Nested + class InstanceMainMethods implements RewriteTest { + + @Test + void instanceMainMethodWithNoParameters() { + rewriteRun( + java( + """ + class HelloWorld { + void main() { + System.out.println("Hello, World!"); + } } - } - """ - ) - ); - } - - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void protectedInstanceMainMethod() { - rewriteRun( - java( - """ - class HelloWorld { - protected void main(String[] args) { - System.out.println("Hello, World!"); + """ + ) + ); + } + + @Test + void instanceMainMethodWithStringArrayParameter() { + rewriteRun( + java( + """ + class HelloWorld { + void main(String[] args) { + System.out.println("Hello, World!"); + } } - } - """ - ) - ); - } - - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void instanceMainMethodWithInstanceFields() { - rewriteRun( - java( - """ - class Counter { - private int count = 0; + """ + ) + ); + } + + @Test + void instanceMainMethodWithInstanceFields() { + rewriteRun( + java( + """ + class Counter { + private int count = 0; - void main() { - count++; - System.out.println("Count: " + count); - } - } - """ - ) - ); - } - - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void instanceMainMethodCallingInstanceMethods() { - rewriteRun( - java( - """ - class Greeter { - void main() { - greet("World"); + void main() { + count++; + System.out.println("Count: " + count); + } } - - void greet(String name) { - System.out.println("Hello, " + name + "!"); + """ + ) + ); + } + + @Test + void instanceMainMethodCallingInstanceMethods() { + rewriteRun( + java( + """ + class Greeter { + void main() { + greet("World"); + } + + void greet(String name) { + System.out.println("Hello, " + name + "!"); + } } - } - """ - ) - ); - } - - @Issue("https://openjdk.org/jeps/512") - @MinimumJava25 - @Test - void staticMainMethodStillSupported() { - rewriteRun( - java( - """ - class TraditionalMain { - public static void main(String[] args) { - System.out.println("Traditional main method"); + """ + ) + ); + } + + @Test + void staticMainMethodStillSupported() { + rewriteRun( + java( + """ + class TraditionalMain { + public static void main(String[] args) { + System.out.println("Traditional main method"); + } } - } - """ - ) - ); + """ + ) + ); + } } } From 22e445b9190d0f96dc51ffdd51e4494745cd011c Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 9 Sep 2025 12:12:55 +0200 Subject: [PATCH 03/13] Adjust tests slightly --- .../java/tree/ClassDeclarationTest.java | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java index ed65246a74..3e1839c696 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java @@ -292,7 +292,26 @@ void implicitClassWithMainMethod() { void main() { System.out.println("Hello from implicit class!"); } - """ + """, + spec -> spec.path("com/example/Main.java") + ) + ); + } + + @Test + void implicitClassWithAbundantSpacing() { + rewriteRun( + java( + """ + + void main() { + + System.out.println("Hello from implicit class!"); + + } + + """, + spec -> spec.path("com/example/Main.java") ) ); } @@ -309,7 +328,8 @@ void main() { void greet(String name) { System.out.println("Hello, " + name + "!"); } - """ + """, + spec -> spec.path("com/example/Main.java") ) ); } @@ -324,7 +344,8 @@ void implicitClassWithFields() { void main() { System.out.println(greeting + ", World!"); } - """ + """, + spec -> spec.path("com/example/Main.java") ) ); } @@ -340,7 +361,8 @@ void main() { names.add("Bob"); System.out.println(names); } - """ + """, + spec -> spec.path("com/example/Main.java") ) ); } @@ -355,24 +377,28 @@ void implicitClassWithPackageStatement() { void main() { System.out.println("Hello from package!"); } - """ + """, + spec -> spec.path("com/example/Main.java") ) ); } @Test - void implicitClassWithStaticInitializer() { + void implicitClassWithPackageStatementWithAbundantSpacing() { rewriteRun( java( """ - static { - System.out.println("Static initializer"); - } + + package com.example; void main() { - System.out.println("Main method"); + + System.out.println("Hello from package!"); + } - """ + + """, + spec -> spec.path("com/example/Main.java") ) ); } @@ -412,7 +438,8 @@ void help() { System.out.println("Helping!"); } } - """ + """, + spec -> spec.path("com/example/Main.java") ) ); } From 3b948a3b7a26cebd93026285d6b7892907e2120e Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 9 Sep 2025 12:13:31 +0200 Subject: [PATCH 04/13] Initial attempt at solving --- .../ReloadableJava25ParserVisitor.java | 33 ++++++++++------ .../org/openrewrite/java/JavaPrinter.java | 38 +++++++++++++++++-- .../java/marker/CompactSourceFile.java | 13 +++++++ .../marker/PackageOnCompactSourceFile.java | 17 +++++++++ 4 files changed, 87 insertions(+), 14 deletions(-) create mode 100644 rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java create mode 100644 rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java diff --git a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java index 0793f5a5ef..30c7f8bfec 100644 --- a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java +++ b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java @@ -37,10 +37,9 @@ import org.openrewrite.java.JavaParsingException; import org.openrewrite.java.JavaPrinter; import org.openrewrite.java.internal.JavaTypeCache; -import org.openrewrite.java.marker.CompactConstructor; -import org.openrewrite.java.marker.OmitParentheses; -import org.openrewrite.java.marker.TrailingComma; +import org.openrewrite.java.marker.*; import org.openrewrite.java.tree.*; +import org.openrewrite.marker.Marker; import org.openrewrite.marker.Markers; import org.openrewrite.style.NamedStyles; @@ -56,6 +55,7 @@ import java.util.regex.Pattern; import java.util.stream.Stream; +import static java.lang.Math.E; import static java.lang.Math.max; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -397,9 +397,11 @@ public J visitClass(ClassTree node, Space fmt) { Map annotationPosTable = mapAnnotations(node.getModifiers().getAnnotations(), new HashMap<>(node.getModifiers().getAnnotations().size())); + int saveCursor = cursor; ReloadableJava25ModifierResults modifierResults = sortedModifiersAndAnnotations(node.getModifiers(), annotationPosTable); List kindAnnotations = collectAnnotations(annotationPosTable); + CompactSourceFile compactSourceFile = null; J.ClassDeclaration.Kind kind; if (hasFlag(node.getModifiers(), Flags.ENUM)) { @@ -412,10 +414,16 @@ public J visitClass(ClassTree node, Space fmt) { } else if (hasFlag(node.getModifiers(), Flags.RECORD)) { kind = new J.ClassDeclaration.Kind(randomId(), sourceBefore("record"), Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Record); } else { - kind = new J.ClassDeclaration.Kind(randomId(), sourceBefore("class"), Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Class); + if (source.startsWith("class", cursor)) { + kind = new J.ClassDeclaration.Kind(randomId(), sourceBefore("class"), Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Class); + } else { + kind = new J.ClassDeclaration.Kind(randomId(), whitespace(), Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Class); + compactSourceFile = new CompactSourceFile(randomId()); + cursor = saveCursor; + } } - J.Identifier name = new J.Identifier(randomId(), sourceBefore(node.getSimpleName().toString()), + J.Identifier name = new J.Identifier(randomId(), compactSourceFile != null ? EMPTY : sourceBefore(node.getSimpleName().toString()), Markers.EMPTY, emptyList(), ((JCClassDecl) node).getSimpleName().toString(), typeMapping.type(node), null); JContainer typeParams = node.getTypeParameters().isEmpty() ? null : JContainer.build( @@ -498,7 +506,7 @@ public J visitClass(ClassTree node, Space fmt) { ); } - Space bodyPrefix = sourceBefore("{"); + Space bodyPrefix = compactSourceFile != null ? whitespace() : sourceBefore("{"); // enum values are required by the grammar to occur before any ordinary field, constructor, or method members List jcEnums = new ArrayList<>(node.getMembers().size()); @@ -588,9 +596,9 @@ public J visitClass(ClassTree node, Space fmt) { addPossibleEmptyStatementsBeforeClosingBrace(members); J.Block body = new J.Block(randomId(), bodyPrefix, Markers.EMPTY, new JRightPadded<>(false, EMPTY, Markers.EMPTY), - members, sourceBefore("}")); + members, compactSourceFile != null ? whitespace() : sourceBefore("}")); - return new J.ClassDeclaration(randomId(), fmt, Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), kind, name, typeParams, + return new J.ClassDeclaration(randomId(), fmt, compactSourceFile != null ? Markers.build(List.of(compactSourceFile)) : Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), kind, name, typeParams, primaryConstructor, extendings, implementings, permitting, body, (JavaType.FullyQualified) typeMapping.type(node)); } @@ -611,17 +619,20 @@ public J visitCompilationUnit(CompilationUnitTree node, Space fmt) { Map annotationPosTable = mapAnnotations(node.getPackageAnnotations(), new HashMap<>(node.getPackageAnnotations().size())); List packageAnnotations = collectAnnotations(annotationPosTable); + List markers = new ArrayList<>(styles); J.Package packageDecl = null; if (cu.getPackageName() != null) { - Space packagePrefix = sourceBefore("package"); - packageDecl = new J.Package(randomId(), packagePrefix, Markers.EMPTY, + packageDecl = new J.Package(randomId(), sourceBefore("package"), Markers.EMPTY, convert(cu.getPackageName()), packageAnnotations); + } else if (cu.getPackageName() == null && source.startsWith("package", cursor)) { + markers.add(new PackageOnCompactSourceFile(randomId(), + sourceBefore("package"), sourceBefore(";").getWhitespace())); } return new J.CompilationUnit( randomId(), fmt, - Markers.build(styles), + Markers.build(markers), sourcePath, fileAttributes, charset.name(), diff --git a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java index c16570cec1..bdd21bdc7d 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java @@ -19,9 +19,7 @@ import org.openrewrite.Cursor; import org.openrewrite.PrintOutputCapture; import org.openrewrite.Tree; -import org.openrewrite.java.marker.CompactConstructor; -import org.openrewrite.java.marker.OmitParentheses; -import org.openrewrite.java.marker.TrailingComma; +import org.openrewrite.java.marker.*; import org.openrewrite.java.tree.*; import org.openrewrite.java.tree.J.*; import org.openrewrite.marker.Marker; @@ -29,6 +27,7 @@ import java.util.Iterator; import java.util.List; +import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.UnaryOperator; @@ -389,6 +388,22 @@ public J visitBlock(Block block, PrintOutputCapture

p) { return block; } + public J visitBlock(Block block, PrintOutputCapture

p, boolean includeBraces) { + beforeSyntax(block, Space.Location.BLOCK_PREFIX, p); + + if (block.isStatic()) { + p.append("static"); + visitRightPadded(block.getPadding().getStatic(), JRightPadded.Location.STATIC_INIT, p); + } + + if (includeBraces) p.append('{'); + visitStatements(block.getPadding().getStatements(), JRightPadded.Location.BLOCK_STATEMENT, p); + visitSpace(block.getEnd(), Space.Location.BLOCK_END, p); + if (includeBraces) p.append('}'); + afterSyntax(block, p); + return block; + } + protected void visitStatements(List> statements, JRightPadded.Location location, PrintOutputCapture

p) { for (JRightPadded paddedStat : statements) { visitStatement(paddedStat, location, p); @@ -539,6 +554,15 @@ public J visitClassDeclaration(ClassDeclaration classDecl, PrintOutputCapture

break; } + Optional compactSourceFile = classDecl.getMarkers().getMarkers().stream() + .filter(m -> m instanceof CompactSourceFile).findFirst(); + if (compactSourceFile.isPresent()) { + beforeSyntax(classDecl, Space.Location.CLASS_DECLARATION_PREFIX, p); + visitBlock(classDecl.getBody(), p, false); + afterSyntax(classDecl, p); + return classDecl; + } + beforeSyntax(classDecl, Space.Location.CLASS_DECLARATION_PREFIX, p); visitSpace(Space.EMPTY, Space.Location.ANNOTATIONS, p); visit(classDecl.getLeadingAnnotations(), p); @@ -563,6 +587,14 @@ public J visitClassDeclaration(ClassDeclaration classDecl, PrintOutputCapture

@Override public J visitCompilationUnit(J.CompilationUnit cu, PrintOutputCapture

p) { beforeSyntax(cu, Space.Location.COMPILATION_UNIT_PREFIX, p); + Optional packageOnCompactSourceFile = cu.getMarkers().getMarkers().stream().filter(m -> m instanceof PackageOnCompactSourceFile).findFirst(); + if (packageOnCompactSourceFile.isPresent()) { + PackageOnCompactSourceFile pkg = (PackageOnCompactSourceFile) packageOnCompactSourceFile.get(); + visitSpace(pkg.getPrefix(), Space.Location.PACKAGE_PREFIX, p); + p.append("package"); + p.append(pkg.getPackageDefinition()); + p.append(";"); + } visitRightPadded(cu.getPadding().getPackageDeclaration(), JRightPadded.Location.PACKAGE, ";", p); visitRightPadded(cu.getPadding().getImports(), JRightPadded.Location.IMPORT, ";", p); if (!cu.getImports().isEmpty()) { diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java new file mode 100644 index 0000000000..6d8696e025 --- /dev/null +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java @@ -0,0 +1,13 @@ +package org.openrewrite.java.marker; + +import lombok.Value; +import lombok.With; +import org.openrewrite.marker.Marker; + +import java.util.UUID; + +@Value +@With +public class CompactSourceFile implements Marker { + UUID id; +} diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java new file mode 100644 index 0000000000..099b9f391e --- /dev/null +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java @@ -0,0 +1,17 @@ +package org.openrewrite.java.marker; + +import lombok.Value; +import lombok.With; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.Space; +import org.openrewrite.marker.Marker; + +import java.util.UUID; + +@Value +@With +public class PackageOnCompactSourceFile implements Marker { + UUID id; + Space prefix; + String packageDefinition; +} From 968275e39d80b7c9e2160835d1317cbc513bba71 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 9 Sep 2025 14:16:41 +0200 Subject: [PATCH 05/13] Self review --- .../ReloadableJava25ParserVisitor.java | 22 ++++++++++++++----- .../org/openrewrite/java/JavaPrinter.java | 14 +----------- .../java/marker/CompactSourceFile.java | 15 +++++++++++++ .../marker/PackageOnCompactSourceFile.java | 15 +++++++++++++ 4 files changed, 47 insertions(+), 19 deletions(-) diff --git a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java index 30c7f8bfec..1755a3bfc3 100644 --- a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java +++ b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java @@ -21,6 +21,7 @@ import com.sun.source.util.TreePathScanner; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.tree.DocCommentTable; import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; @@ -55,7 +56,6 @@ import java.util.regex.Pattern; import java.util.stream.Stream; -import static java.lang.Math.E; import static java.lang.Math.max; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; @@ -414,13 +414,14 @@ public J visitClass(ClassTree node, Space fmt) { } else if (hasFlag(node.getModifiers(), Flags.RECORD)) { kind = new J.ClassDeclaration.Kind(randomId(), sourceBefore("record"), Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Record); } else { + Space prefix = whitespace(); if (source.startsWith("class", cursor)) { - kind = new J.ClassDeclaration.Kind(randomId(), sourceBefore("class"), Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Class); + skip("class"); } else { - kind = new J.ClassDeclaration.Kind(randomId(), whitespace(), Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Class); compactSourceFile = new CompactSourceFile(randomId()); cursor = saveCursor; } + kind = new J.ClassDeclaration.Kind(randomId(), prefix, Markers.EMPTY, kindAnnotations, J.ClassDeclaration.Kind.Type.Class); } J.Identifier name = new J.Identifier(randomId(), compactSourceFile != null ? EMPTY : sourceBefore(node.getSimpleName().toString()), @@ -625,9 +626,18 @@ public J visitCompilationUnit(CompilationUnitTree node, Space fmt) { if (cu.getPackageName() != null) { packageDecl = new J.Package(randomId(), sourceBefore("package"), Markers.EMPTY, convert(cu.getPackageName()), packageAnnotations); - } else if (cu.getPackageName() == null && source.startsWith("package", cursor)) { - markers.add(new PackageOnCompactSourceFile(randomId(), - sourceBefore("package"), sourceBefore(";").getWhitespace())); + } else if (cu.getPackageName() == null && + cu.modle.equals(Symtab.instance(context).unnamedModule) && + cu.packge.equals(Symtab.instance(context).unnamedModule.unnamedPackage)) { + int saveCursor = cursor; + Space prefix = whitespace(); + if (source.startsWith("package", cursor)) { + skip("package"); + markers.add(new PackageOnCompactSourceFile(randomId(), + prefix, sourceBefore(";").getWhitespace())); + } else { + cursor = saveCursor; + } } return new J.CompilationUnit( randomId(), diff --git a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java index bdd21bdc7d..5e91ce6ddb 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java @@ -373,19 +373,7 @@ public J visitBinary(Binary binary, PrintOutputCapture

p) { @Override public J visitBlock(Block block, PrintOutputCapture

p) { - beforeSyntax(block, Space.Location.BLOCK_PREFIX, p); - - if (block.isStatic()) { - p.append("static"); - visitRightPadded(block.getPadding().getStatic(), JRightPadded.Location.STATIC_INIT, p); - } - - p.append('{'); - visitStatements(block.getPadding().getStatements(), JRightPadded.Location.BLOCK_STATEMENT, p); - visitSpace(block.getEnd(), Space.Location.BLOCK_END, p); - p.append('}'); - afterSyntax(block, p); - return block; + return visitBlock(block, p, true); } public J visitBlock(Block block, PrintOutputCapture

p, boolean includeBraces) { diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java index 6d8696e025..35a33b9373 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/CompactSourceFile.java @@ -1,3 +1,18 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.openrewrite.java.marker; import lombok.Value; diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java index 099b9f391e..c2a38ba0a2 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java @@ -1,3 +1,18 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.openrewrite.java.marker; import lombok.Value; From 8283a5287feab83ac5bc04c4ac7de75645d62f56 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 9 Sep 2025 14:38:52 +0200 Subject: [PATCH 06/13] Force CI to use java 25 --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 92074628ae..94059fd48a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,8 +21,8 @@ jobs: uses: openrewrite/gh-automation/.github/workflows/ci-gradle.yml@main with: java_version: | - 25-ea 21 + 25-ea secrets: gradle_enterprise_access_key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} sonatype_username: ${{ secrets.SONATYPE_USERNAME }} From 9f5104bf2d79f8bf20e95797f1af735dbefd65bc Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 9 Sep 2025 14:39:42 +0200 Subject: [PATCH 07/13] Remove unused import --- .../org/openrewrite/java/marker/PackageOnCompactSourceFile.java | 1 - 1 file changed, 1 deletion(-) diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java index c2a38ba0a2..02eb9120ad 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java @@ -17,7 +17,6 @@ import lombok.Value; import lombok.With; -import org.openrewrite.java.tree.J; import org.openrewrite.java.tree.Space; import org.openrewrite.marker.Marker; From 2e9b909950d4cc5ba58d7fb2d78f9533b5a9faf1 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Tue, 9 Sep 2025 14:41:43 +0200 Subject: [PATCH 08/13] Revert CI change --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 94059fd48a..92074628ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,8 +21,8 @@ jobs: uses: openrewrite/gh-automation/.github/workflows/ci-gradle.yml@main with: java_version: | - 21 25-ea + 21 secrets: gradle_enterprise_access_key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} sonatype_username: ${{ secrets.SONATYPE_USERNAME }} From be49136b391ae2584e9d231b44f898c0042884d5 Mon Sep 17 00:00:00 2001 From: Tim te Beek Date: Tue, 9 Sep 2025 17:27:05 +0200 Subject: [PATCH 09/13] Trim empty lines --- .../java/tree/ClassDeclarationTest.java | 30 +++++++++---------- .../java/tree/MethodDeclarationTest.java | 5 ++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java index 3e1839c696..d84d5630e9 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java @@ -303,13 +303,13 @@ void implicitClassWithAbundantSpacing() { rewriteRun( java( """ - + void main() { - + System.out.println("Hello from implicit class!"); - + } - + """, spec -> spec.path("com/example/Main.java") ) @@ -324,7 +324,7 @@ void implicitClassWithMultipleMethods() { void main() { greet("World"); } - + void greet(String name) { System.out.println("Hello, " + name + "!"); } @@ -340,7 +340,7 @@ void implicitClassWithFields() { java( """ String greeting = "Hello"; - + void main() { System.out.println(greeting + ", World!"); } @@ -373,7 +373,7 @@ void implicitClassWithPackageStatement() { java( """ package com.example; - + void main() { System.out.println("Hello from package!"); } @@ -388,15 +388,15 @@ void implicitClassWithPackageStatementWithAbundantSpacing() { rewriteRun( java( """ - + package com.example; - + void main() { - + System.out.println("Hello from package!"); - + } - + """, spec -> spec.path("com/example/Main.java") ) @@ -409,11 +409,11 @@ void implicitClassWithConstructor() { java( """ private String name; - + Main(String name) { this.name = name; } - + void main() { System.out.println("Name: " + name); } @@ -432,7 +432,7 @@ void main() { Helper helper = new Helper(); helper.help(); } - + class Helper { void help() { System.out.println("Helping!"); diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java index 5df13459f7..96aff36384 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/MethodDeclarationTest.java @@ -161,7 +161,7 @@ void instanceMainMethodWithInstanceFields() { """ class Counter { private int count = 0; - + void main() { count++; System.out.println("Count: " + count); @@ -181,7 +181,7 @@ class Greeter { void main() { greet("World"); } - + void greet(String name) { System.out.println("Hello, " + name + "!"); } @@ -206,5 +206,4 @@ public static void main(String[] args) { ); } } - } From fd00a08cd34f8f8ed502b08a387b35d0d970b91e Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Wed, 10 Sep 2025 11:45:31 +0200 Subject: [PATCH 10/13] Apply review feedback --- .../ReloadableJava25ParserVisitor.java | 9 ++++--- .../org/openrewrite/java/JavaPrinter.java | 27 +++++++++---------- .../openrewrite/java/marker/OmitBraces.java | 17 ++++++++++++ .../openrewrite/kotlin/marker/OmitBraces.java | 4 +++ 4 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java diff --git a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java index 1755a3bfc3..d2af32b6ca 100644 --- a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java +++ b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java @@ -596,10 +596,13 @@ public J visitClass(ClassTree node, Space fmt) { members.addAll(convertStatements(membersMultiVariablesSeparated)); addPossibleEmptyStatementsBeforeClosingBrace(members); - J.Block body = new J.Block(randomId(), bodyPrefix, Markers.EMPTY, new JRightPadded<>(false, EMPTY, Markers.EMPTY), - members, compactSourceFile != null ? whitespace() : sourceBefore("}")); + J.Block body = new J.Block(randomId(), bodyPrefix, compactSourceFile != null ? Markers.build(List.of(new OmitBraces(randomId()))) : Markers.EMPTY, + new JRightPadded<>(false, EMPTY, Markers.EMPTY), + members, + compactSourceFile != null ? whitespace() : sourceBefore("}")); - return new J.ClassDeclaration(randomId(), fmt, compactSourceFile != null ? Markers.build(List.of(compactSourceFile)) : Markers.EMPTY, modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), kind, name, typeParams, + return new J.ClassDeclaration(randomId(), fmt, compactSourceFile != null ? Markers.build(List.of(compactSourceFile)) : Markers.EMPTY, + modifierResults.getLeadingAnnotations(), modifierResults.getModifiers(), kind, name, typeParams, primaryConstructor, extendings, implementings, permitting, body, (JavaType.FullyQualified) typeMapping.type(node)); } diff --git a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java index 5e91ce6ddb..5c5a7825bd 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java @@ -372,22 +372,23 @@ public J visitBinary(Binary binary, PrintOutputCapture

p) { } @Override - public J visitBlock(Block block, PrintOutputCapture

p) { - return visitBlock(block, p, true); - } - - public J visitBlock(Block block, PrintOutputCapture

p, boolean includeBraces) { + public J visitBlock(J.Block block, PrintOutputCapture

p) { beforeSyntax(block, Space.Location.BLOCK_PREFIX, p); if (block.isStatic()) { - p.append("static"); + p.append("init"); visitRightPadded(block.getPadding().getStatic(), JRightPadded.Location.STATIC_INIT, p); } - if (includeBraces) p.append('{'); + boolean omitBraces = block.getMarkers().findFirst(OmitBraces.class).isPresent(); + if (!omitBraces) { + p.append("{"); + } visitStatements(block.getPadding().getStatements(), JRightPadded.Location.BLOCK_STATEMENT, p); visitSpace(block.getEnd(), Space.Location.BLOCK_END, p); - if (includeBraces) p.append('}'); + if (!omitBraces) { + p.append("}"); + } afterSyntax(block, p); return block; } @@ -542,11 +543,9 @@ public J visitClassDeclaration(ClassDeclaration classDecl, PrintOutputCapture

break; } - Optional compactSourceFile = classDecl.getMarkers().getMarkers().stream() - .filter(m -> m instanceof CompactSourceFile).findFirst(); - if (compactSourceFile.isPresent()) { + if (classDecl.getMarkers().findFirst(CompactSourceFile.class).isPresent()) { beforeSyntax(classDecl, Space.Location.CLASS_DECLARATION_PREFIX, p); - visitBlock(classDecl.getBody(), p, false); + visit(classDecl.getBody(), p); afterSyntax(classDecl, p); return classDecl; } @@ -575,9 +574,9 @@ public J visitClassDeclaration(ClassDeclaration classDecl, PrintOutputCapture

@Override public J visitCompilationUnit(J.CompilationUnit cu, PrintOutputCapture

p) { beforeSyntax(cu, Space.Location.COMPILATION_UNIT_PREFIX, p); - Optional packageOnCompactSourceFile = cu.getMarkers().getMarkers().stream().filter(m -> m instanceof PackageOnCompactSourceFile).findFirst(); + Optional packageOnCompactSourceFile = cu.getMarkers().findFirst(PackageOnCompactSourceFile.class); if (packageOnCompactSourceFile.isPresent()) { - PackageOnCompactSourceFile pkg = (PackageOnCompactSourceFile) packageOnCompactSourceFile.get(); + PackageOnCompactSourceFile pkg = packageOnCompactSourceFile.get(); visitSpace(pkg.getPrefix(), Space.Location.PACKAGE_PREFIX, p); p.append("package"); p.append(pkg.getPackageDefinition()); diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java new file mode 100644 index 0000000000..daee4b0b6a --- /dev/null +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java @@ -0,0 +1,17 @@ +package org.openrewrite.java.marker; + +import lombok.Value; +import lombok.With; +import org.openrewrite.marker.Marker; + +import java.util.UUID; + +@Value +@With +public class OmitBraces implements Marker { + UUID id; + + public OmitBraces(UUID id) { + this.id = id; + } +} diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/marker/OmitBraces.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/marker/OmitBraces.java index be5effe619..bb34b52d36 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/marker/OmitBraces.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/marker/OmitBraces.java @@ -21,8 +21,12 @@ import java.util.UUID; +/** + * Use {@link org.openrewrite.java.marker.OmitBraces} instead. + */ @Value @With +@Deprecated public class OmitBraces implements Marker { UUID id; From 2b782aa95a0b6d05e434009b8ab6a98aab5b6fe1 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Wed, 10 Sep 2025 11:48:16 +0200 Subject: [PATCH 11/13] License fmt --- .../org/openrewrite/java/marker/OmitBraces.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java index daee4b0b6a..902b3dcf52 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/marker/OmitBraces.java @@ -1,3 +1,18 @@ +/* + * Copyright 2025 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.openrewrite.java.marker; import lombok.Value; From 11fdf6bf293c8159f8d9021ad2395188bbd4db2b Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Wed, 10 Sep 2025 11:51:20 +0200 Subject: [PATCH 12/13] Reduce PR noise --- .../src/main/java/org/openrewrite/java/JavaPrinter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java index 5c5a7825bd..b823b04ea4 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java @@ -372,11 +372,11 @@ public J visitBinary(Binary binary, PrintOutputCapture

p) { } @Override - public J visitBlock(J.Block block, PrintOutputCapture

p) { + public J visitBlock(Block block, PrintOutputCapture

p) { beforeSyntax(block, Space.Location.BLOCK_PREFIX, p); if (block.isStatic()) { - p.append("init"); + p.append("static"); visitRightPadded(block.getPadding().getStatic(), JRightPadded.Location.STATIC_INIT, p); } From e652cf21a75b2413c24f35430d31ea972733e3e6 Mon Sep 17 00:00:00 2001 From: Laurens Westerlaken Date: Mon, 20 Oct 2025 14:10:11 +0200 Subject: [PATCH 13/13] Remove overengineered marker and adjust kotlin parser printer and visitors to consider both java and kotlin version of `OmitBraces` --- .../ReloadableJava25ParserVisitor.java | 8 ----- .../java/tree/ClassDeclarationTest.java | 36 ------------------- .../org/openrewrite/java/JavaPrinter.java | 8 ----- .../marker/PackageOnCompactSourceFile.java | 31 ---------------- .../kotlin/format/BlankLinesVisitor.java | 5 +-- .../kotlin/format/SpacesVisitor.java | 4 ++- .../kotlin/format/TabsAndIndentsVisitor.java | 5 +-- .../format/WrappingAndBracesVisitor.java | 5 +-- .../kotlin/internal/KotlinPrinter.java | 4 ++- .../internal/KotlinTreeParserVisitor.java | 1 + 10 files changed, 16 insertions(+), 91 deletions(-) delete mode 100644 rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java diff --git a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java index d2af32b6ca..edd7994b9b 100644 --- a/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java +++ b/rewrite-java-25/src/main/java/org/openrewrite/java/isolated/ReloadableJava25ParserVisitor.java @@ -633,14 +633,6 @@ public J visitCompilationUnit(CompilationUnitTree node, Space fmt) { cu.modle.equals(Symtab.instance(context).unnamedModule) && cu.packge.equals(Symtab.instance(context).unnamedModule.unnamedPackage)) { int saveCursor = cursor; - Space prefix = whitespace(); - if (source.startsWith("package", cursor)) { - skip("package"); - markers.add(new PackageOnCompactSourceFile(randomId(), - prefix, sourceBefore(";").getWhitespace())); - } else { - cursor = saveCursor; - } } return new J.CompilationUnit( randomId(), diff --git a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java index d84d5630e9..ec851ed1c2 100644 --- a/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java +++ b/rewrite-java-tck/src/main/java/org/openrewrite/java/tree/ClassDeclarationTest.java @@ -367,42 +367,6 @@ void main() { ); } - @Test - void implicitClassWithPackageStatement() { - rewriteRun( - java( - """ - package com.example; - - void main() { - System.out.println("Hello from package!"); - } - """, - spec -> spec.path("com/example/Main.java") - ) - ); - } - - @Test - void implicitClassWithPackageStatementWithAbundantSpacing() { - rewriteRun( - java( - """ - - package com.example; - - void main() { - - System.out.println("Hello from package!"); - - } - - """, - spec -> spec.path("com/example/Main.java") - ) - ); - } - @Test void implicitClassWithConstructor() { rewriteRun( diff --git a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java index b823b04ea4..960ea28271 100644 --- a/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java +++ b/rewrite-java/src/main/java/org/openrewrite/java/JavaPrinter.java @@ -574,14 +574,6 @@ public J visitClassDeclaration(ClassDeclaration classDecl, PrintOutputCapture

@Override public J visitCompilationUnit(J.CompilationUnit cu, PrintOutputCapture

p) { beforeSyntax(cu, Space.Location.COMPILATION_UNIT_PREFIX, p); - Optional packageOnCompactSourceFile = cu.getMarkers().findFirst(PackageOnCompactSourceFile.class); - if (packageOnCompactSourceFile.isPresent()) { - PackageOnCompactSourceFile pkg = packageOnCompactSourceFile.get(); - visitSpace(pkg.getPrefix(), Space.Location.PACKAGE_PREFIX, p); - p.append("package"); - p.append(pkg.getPackageDefinition()); - p.append(";"); - } visitRightPadded(cu.getPadding().getPackageDeclaration(), JRightPadded.Location.PACKAGE, ";", p); visitRightPadded(cu.getPadding().getImports(), JRightPadded.Location.IMPORT, ";", p); if (!cu.getImports().isEmpty()) { diff --git a/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java b/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java deleted file mode 100644 index 02eb9120ad..0000000000 --- a/rewrite-java/src/main/java/org/openrewrite/java/marker/PackageOnCompactSourceFile.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2025 the original author or authors. - *

- * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - *

- * https://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.openrewrite.java.marker; - -import lombok.Value; -import lombok.With; -import org.openrewrite.java.tree.Space; -import org.openrewrite.marker.Marker; - -import java.util.UUID; - -@Value -@With -public class PackageOnCompactSourceFile implements Marker { - UUID id; - Space prefix; - String packageDefinition; -} diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/BlankLinesVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/BlankLinesVisitor.java index 773bdbf4b9..74d7736685 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/BlankLinesVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/BlankLinesVisitor.java @@ -19,9 +19,9 @@ import org.jspecify.annotations.Nullable; import org.openrewrite.Tree; import org.openrewrite.internal.ListUtils; +import org.openrewrite.java.marker.OmitBraces; import org.openrewrite.java.tree.*; import org.openrewrite.kotlin.KotlinIsoVisitor; -import org.openrewrite.kotlin.marker.OmitBraces; import org.openrewrite.kotlin.marker.PrimaryConstructor; import org.openrewrite.kotlin.marker.SingleExpressionBlock; import org.openrewrite.kotlin.style.BlankLinesStyle; @@ -338,7 +338,8 @@ public K.When visitWhen(K.When when, P p) { K.WhenBranch branch = (K.WhenBranch) s; K.WhenBranch previousBranch = (K.WhenBranch) branches.getStatements().get(index - 1); boolean isPreviousWhenBranchWithBlock = previousBranch.getBody() instanceof J.Block && - !previousBranch.getBody().getMarkers().findFirst(OmitBraces.class).isPresent(); + (!previousBranch.getBody().getMarkers().findFirst(OmitBraces.class).isPresent() || + !previousBranch.getMarkers().findFirst(org.openrewrite.kotlin.marker.OmitBraces.class).isPresent()); if (!isPreviousWhenBranchWithBlock) { return s; } diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/SpacesVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/SpacesVisitor.java index c90cd87f09..c26adb0634 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/SpacesVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/SpacesVisitor.java @@ -20,6 +20,7 @@ import org.openrewrite.Tree; import org.openrewrite.internal.ListUtils; import org.openrewrite.internal.StringUtils; +import org.openrewrite.java.marker.OmitBraces; import org.openrewrite.java.marker.OmitParentheses; import org.openrewrite.java.marker.TrailingComma; import org.openrewrite.java.tree.*; @@ -176,7 +177,8 @@ private Markers spaceBeforeColonAfterDeclarationName(Markers markers) { @Override public J.ClassDeclaration visitClassDeclaration(J.ClassDeclaration classDecl, P p) { J.ClassDeclaration c = super.visitClassDeclaration(classDecl, p); - boolean omitBraces = c.getBody().getMarkers().findFirst(OmitBraces.class).isPresent(); + boolean omitBraces = c.getBody().getMarkers().findFirst(OmitBraces.class).isPresent() || + c.getBody().getMarkers().findFirst(org.openrewrite.kotlin.marker.OmitBraces.class).isPresent(); c = c.withBody(spaceBefore(c.getBody(), beforeLeftBrace && !omitBraces)); if (c.getBody().getStatements().isEmpty()) { if (c.getKind() != J.ClassDeclaration.Kind.Type.Enum) { diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/TabsAndIndentsVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/TabsAndIndentsVisitor.java index 52cda3e929..a3a7bc7c76 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/TabsAndIndentsVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/TabsAndIndentsVisitor.java @@ -20,11 +20,11 @@ import org.openrewrite.Tree; import org.openrewrite.internal.ListUtils; import org.openrewrite.internal.StringUtils; +import org.openrewrite.java.marker.OmitBraces; import org.openrewrite.java.marker.ImplicitReturn; import org.openrewrite.java.tree.*; import org.openrewrite.kotlin.KotlinIsoVisitor; import org.openrewrite.kotlin.marker.Implicit; -import org.openrewrite.kotlin.marker.OmitBraces; import org.openrewrite.kotlin.marker.SingleExpressionBlock; import org.openrewrite.kotlin.marker.TrailingLambdaArgument; import org.openrewrite.kotlin.style.TabsAndIndentsStyle; @@ -156,7 +156,8 @@ public Space visitSpace(Space space, Space.Location loc, P p) { if (parent != null && parent.getValue() instanceof J.Annotation) { parent.getParentOrThrow().putMessage("afterAnnotation", true); } else if (loc == Space.Location.BLOCK_PREFIX && - ((J.Block) value).getMarkers().findFirst(OmitBraces.class).isPresent() && + (((J.Block) value).getMarkers().findFirst(OmitBraces.class).isPresent() || + ((J.Block) value).getMarkers().findFirst(org.openrewrite.kotlin.marker.OmitBraces.class).isPresent()) && ((J.Block) value).getStatements().isEmpty()) { return space; } else if (parent != null && !getCursor().getParentOrThrow().getPath(J.Annotation.class::isInstance).hasNext()) { diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/WrappingAndBracesVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/WrappingAndBracesVisitor.java index 7195d29624..ed093fddae 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/WrappingAndBracesVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/format/WrappingAndBracesVisitor.java @@ -20,9 +20,9 @@ import org.openrewrite.Cursor; import org.openrewrite.Tree; import org.openrewrite.internal.ListUtils; +import org.openrewrite.java.marker.OmitBraces; import org.openrewrite.java.tree.*; import org.openrewrite.kotlin.KotlinIsoVisitor; -import org.openrewrite.kotlin.marker.OmitBraces; import org.openrewrite.kotlin.marker.PrimaryConstructor; import org.openrewrite.kotlin.style.WrappingAndBracesStyle; @@ -52,7 +52,8 @@ public Statement visitStatement(Statement statement, P p) { if (parentTree instanceof J.Block && !(j instanceof J.EnumValueSet)) { J.Block parentBlock = (J.Block) parentTree; - if (parentBlock.getMarkers().findFirst(OmitBraces.class).isPresent()) { + if (parentBlock.getMarkers().findFirst(OmitBraces.class).isPresent() || + parentBlock.getMarkers().findFirst(org.openrewrite.kotlin.marker.OmitBraces.class).isPresent()) { return j; } diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinPrinter.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinPrinter.java index 904356fb63..e3c344e52d 100755 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinPrinter.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinPrinter.java @@ -21,6 +21,7 @@ import org.openrewrite.Tree; import org.openrewrite.java.JavaPrinter; import org.openrewrite.java.marker.ImplicitReturn; +import org.openrewrite.java.marker.OmitBraces; import org.openrewrite.java.marker.OmitParentheses; import org.openrewrite.java.marker.Quoted; import org.openrewrite.java.tree.*; @@ -599,7 +600,8 @@ public J visitBlock(J.Block block, PrintOutputCapture

p) { p.append("="); } - boolean omitBraces = block.getMarkers().findFirst(OmitBraces.class).isPresent(); + boolean omitBraces = block.getMarkers().findFirst(OmitBraces.class).isPresent() || + block.getMarkers().findFirst(org.openrewrite.kotlin.marker.OmitBraces.class).isPresent(); if (!omitBraces) { p.append("{"); } diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java index be8ff606d3..d29c8241bf 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java @@ -47,6 +47,7 @@ import org.openrewrite.internal.EncodingDetectingInputStream; import org.openrewrite.internal.ListUtils; import org.openrewrite.java.marker.ImplicitReturn; +import org.openrewrite.java.marker.OmitBraces; import org.openrewrite.java.marker.OmitParentheses; import org.openrewrite.java.marker.Quoted; import org.openrewrite.java.marker.TrailingComma;