Skip to content

Use Groovy 4 parser#6228

Merged
knutwannheden merged 9 commits intomainfrom
groovy-4
Mar 5, 2026
Merged

Use Groovy 4 parser#6228
knutwannheden merged 9 commits intomainfrom
groovy-4

Conversation

@knutwannheden
Copy link
Contributor

@knutwannheden knutwannheden commented Oct 31, 2025

Summary

  • Upgrade Groovy parser from Groovy 3 to Groovy 4, using LessAstTransformationsCompilationUnit to preserve AST structure through the CANONICALIZATION phase
  • Support multi-catch (IOException | UncheckedIOException e) and try-with-resources in Groovy parser (GroovyParser support for multi-catch blocks #1944, GroovyParser support for try-with-resources  #1945)
  • Support enum constants with anonymous class bodies (e.g. A1(1) { void foo() {} }) including proper J.NewClass construction with J.Empty for empty parens
  • Support record declarations with primary constructor parameters parsed as J.VariableDeclarations
  • Support sealed class declarations with permits clause, sealed/non-sealed modifiers
  • Guard against phantom type parameterizations injected by Groovy's @Sealed AST transform

Test plan

  • EnumTest.anonymousClassInitializer — enum constants with anonymous class bodies and constructors
  • EnumTest.noArguments — enum constants with empty parentheses preserving whitespace via J.Empty
  • TryTest.multiCatch, TryTest.multiCatchThreeTypes — multi-catch blocks
  • TryTest.tryWithResource, TryTest.tryWithResources, TryTest.tryWithResourceAndFinally — try-with-resources
  • ClassDeclarationTest.recordDeclaration — record with primary constructor
  • ClassDeclarationTest.sealedClass — sealed class with permits clause and final subclasses
  • All 342 existing Groovy tests pass

timtebeek and others added 2 commits December 24, 2025 22:27
# Conflicts:
#	rewrite-groovy/src/main/java/org/openrewrite/groovy/GroovyParserVisitor.java
@knutwannheden knutwannheden marked this pull request as ready for review February 17, 2026 21:56
…1945)

Groovy 4 desugars both features at parse time, so the parser must
reconstruct them from the desugared AST and source text:
- Multi-catch: Groovy splits catch(A | B e) into separate CatchStatements
  at the same source position; detect and merge into J.MultiCatch
- Try-with-resources: Groovy nests each resource in a synthetic
  BlockStatement/TryCatchStatement structure; walk the nesting to extract
  resource declarations and the real body block
Groovy 4 represents enum anonymous bodies by appending a ClassExpression
to the ListExpression initializer. Detect this pattern, parse the body
via visitClassBlock, and populate J.NewClass.body to match Java parser
LST structure. Use J.Empty for empty parens to preserve inner whitespace.
Parse Groovy 4 records (primary constructor, components) and sealed
classes (sealed/non-sealed modifiers, permits clause) by leveraging
the CANONICALIZATION phase AST. Filter synthetic record backing fields
and guard against phantom type parameterizations from @Sealed transform.
…istic, add non-sealed test

- Use sourceBefore(")") for last record component to preserve trailing whitespace
- Tighten isDesugaredResourceBlock to also check inner block structure
- Add non-sealed modifier to sealed class test
- Split enum noArguments test to verify both A2() and A2( )
@knutwannheden knutwannheden merged commit 3e403bf into main Mar 5, 2026
1 check passed
@knutwannheden knutwannheden deleted the groovy-4 branch March 5, 2026 21:22
@github-project-automation github-project-automation bot moved this from In Progress to Done in OpenRewrite Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants