Skip to content

GROOVY-11998: Better support of intersection types#2518

Open
paulk-asert wants to merge 7 commits intoapache:masterfrom
paulk-asert:groovy11998
Open

GROOVY-11998: Better support of intersection types#2518
paulk-asert wants to merge 7 commits intoapache:masterfrom
paulk-asert:groovy11998

Conversation

@paulk-asert
Copy link
Copy Markdown
Contributor

No description provided.

Grammar + AST. intersectionType rule, IntersectionTypeClassNode, AstBuilder updates. Includes parser tests; no semantic impact (ResolveVisitor errors out on it).
Resolution + STC. ResolveVisitor resolves components; StaticTypeCheckingVisitor.visitCastExpression validates and propagates. LAMBDA_MARKERS metadata. Static error messages.
Bytecode for lambdas/method refs. writeFunctionalInterfaceIndy markers, altMetafactory flags. Static parity with Java's (R & S) ()->….
as coercion. Closure asType overload, ProxyGenerator plumbing, dynamic castToType(Object, Class[]).
Closure literal native intersection. StaticTypesClosureWriter generates a class implementing all components for (R & S) { -> ... }, docs.
@paulk-asert paulk-asert changed the title Groovy11998 GROOVY-11998: Better support of intersection types May 6, 2026
@paulk-asert paulk-asert requested a review from Copilot May 6, 2026 10:01
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements parser/AST, type-checking, and codegen/runtime support for intersection-type cast and as coercion (GROOVY-11998), including marker-interface threading for lambdas/method references and a runtime fallback path for non-functional sources. It also includes a related fix for proxy generation when mixing bootstrap-loaded and user-loaded interfaces (GROOVY-11999), plus extensive tests and spec documentation updates.

Changes:

  • Extend the ANTLR grammar + AST builder to parse intersection types in cast targets and as coercion targets, producing an IntersectionTypeClassNode.
  • Add resolution + STC support for intersection targets and propagate marker-interface metadata into indy lambda/method-reference generation.
  • Route non-functional intersection casts/coercions through a new runtime helper and harden proxy generation against null (bootstrap) classloaders.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/antlr/GroovyParser.g4 Grammar changes: intersection types in cast parens and coercionType for as/!instanceof.
src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java Builds IntersectionTypeClassNode, rejects duplicate intersection components, adjusts as and !instanceof handling.
src/main/java/org/codehaus/groovy/ast/IntersectionTypeClassNode.java New ClassNode representing user-written intersection cast targets with component ordering + reclassification.
src/main/java/org/codehaus/groovy/control/ResolveVisitor.java Resolves intersection components and reclassifies class-vs-interface parts post-resolution.
src/main/java/org/codehaus/groovy/transform/stc/StaticTypesMarker.java Adds markers to carry intersection functional target + marker interfaces through compilation.
src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java Validates/applies intersection-cast behavior in STC and teaches checkCast to decompose intersections.
src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java Emits indy no-op for lambda/methodref intersection casts and invokes runtime helper for other intersection casts/coercions.
src/main/java/org/codehaus/groovy/runtime/IntersectionCastSupport.java New runtime helper for intersection cast/coercion (castTo / asType).
src/main/java/org/codehaus/groovy/runtime/ProxyGeneratorAdapter.java Fixes NPE risk by avoiding storing bootstrap (null) classloaders in internal loader lists.
src/main/java/org/codehaus/groovy/classgen/asm/sc/AbstractFunctionalInterfaceWriter.java Adds marker-aware altMetafactory bootstrap argument construction for intersection targets.
src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java Collects intersection markers and passes them to indy bootstrap for lambdas.
src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java Threads intersection markers + serializable flag into method-reference indy generation.
src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesClosureWriter.java Adds marker interfaces to statically-compiled closure literal classes when safe.
src/spec/doc/core-semantics.adoc Documents intersection casts/coercion semantics and examples.
src/spec/doc/core-differences-java.adoc Documents Java-difference: intersection casts on lambdas/method refs and Groovy as form.
src/spec/test/CoercionTest.groovy Adds spec tests/examples for intersection casts/coercion.
src/test/groovy/org/apache/groovy/parser/antlr4/IntersectionCastParserTest.groovy Parser-level tests ensuring intersection targets become IntersectionTypeClassNode and invalid cases error.
src/test/groovy/groovy/transform/stc/IntersectionCastSTCTest.groovy STC tests for intersection functional target selection, metadata, and validation errors.
src/test/groovy/groovy/lang/IntersectionCastE2ETest.groovy End-to-end runtime tests for statically compiled intersection lambdas/method references (incl. serialization).
src/test/groovy/groovy/lang/IntersectionCoercionTest.groovy Runtime tests for dynamic intersection cast/coercion on non-functional sources (Closure/Map/value/null).
src/test/groovy/groovy/lang/IntersectionClosureLiteralTest.groovy Tests native marker-interface addition for statically compiled closure literals under intersection casts.
src/test/groovy/groovy/util/ProxyGeneratorAdapterTest.groovy Regression tests for mixing bootstrap + user classloaders in proxy interface lists (GROOVY-11999).

Comment thread src/main/java/org/codehaus/groovy/runtime/IntersectionCastSupport.java Outdated
Comment thread src/main/java/org/codehaus/groovy/ast/IntersectionTypeClassNode.java Outdated
Comment thread src/spec/doc/core-semantics.adoc Outdated
Comment thread src/test/groovy/org/apache/groovy/parser/antlr4/IntersectionCastParserTest.groovy Outdated
Comment thread src/test/groovy/org/apache/groovy/parser/antlr4/IntersectionCastParserTest.groovy Outdated
Comment thread src/test/groovy/groovy/transform/stc/IntersectionCastSTCTest.groovy Outdated
@testlens-app
Copy link
Copy Markdown

testlens-app Bot commented May 6, 2026

✅ All tests passed ✅

⚠️ TestLens detected flakiness ⚠️

Test Summary

Check Project/Task Test Runs
Build and test / lts (17, macos-latest) :groovy-test-junit6:test ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() ⚠️
Build and test / lts (17, macos-latest) :groovy-test-junit6:test ForkedJvmTest > failureInChildJvmPropagatesToParent() ⚠️
Build and test / lts (17, ubuntu-latest) :groovy-test-junit6:test ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() ⚠️
Build and test / lts (17, ubuntu-latest) :groovy-test-junit6:test ForkedJvmTest > failureInChildJvmPropagatesToParent() ⚠️
Build and test / lts (17, windows-latest, 1) :groovy-test-junit6:test ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() ⚠️
Build and test / lts (17, windows-latest, 1) :groovy-test-junit6:test ForkedJvmTest > failureInChildJvmPropagatesToParent() ⚠️
Build and test / lts (21, ubuntu-latest) :groovy-test-junit6:test ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() ⚠️
Build and test / lts (21, ubuntu-latest) :groovy-test-junit6:test ForkedJvmTest > failureInChildJvmPropagatesToParent() ⚠️
Build and test / lts (25, ubuntu-latest) :groovy-test-junit6:test ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() ⚠️
Build and test / lts (25, ubuntu-latest) :groovy-test-junit6:test ForkedJvmTest > failureInChildJvmPropagatesToParent() ⚠️

🏷️ Commit: b154bbc
▶️ Tests: 97921 executed
⚪️ Checks: 24/24 completed

Test Failures (first 5 of 10)

ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() (:groovy-test-junit6:test in Build and test / lts (17, macos-latest))
java.lang.AssertionError: forked failure round-trips
	at ExpectedToFailTest.outerOrdering_failurePropagatesFromForkAndIsInverted(ExpectedToFailTest.groovy:78)
ForkedJvmTest > failureInChildJvmPropagatesToParent() (:groovy-test-junit6:test in Build and test / lts (17, macos-latest))
java.lang.AssertionError: expected failure from forked child
	at ForkedJvmTest.failureInChildJvmPropagatesToParent(ForkedJvmTest.groovy:152)
ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() (:groovy-test-junit6:test in Build and test / lts (17, ubuntu-latest))
java.lang.AssertionError: forked failure round-trips
	at ExpectedToFailTest.outerOrdering_failurePropagatesFromForkAndIsInverted(ExpectedToFailTest.groovy:78)
ForkedJvmTest > failureInChildJvmPropagatesToParent() (:groovy-test-junit6:test in Build and test / lts (17, ubuntu-latest))
java.lang.AssertionError: expected failure from forked child
	at ForkedJvmTest.failureInChildJvmPropagatesToParent(ForkedJvmTest.groovy:152)
ExpectedToFailTest > outerOrdering_failurePropagatesFromForkAndIsInverted() (:groovy-test-junit6:test in Build and test / lts (17, windows-latest, 1))
java.lang.AssertionError: forked failure round-trips
	at ExpectedToFailTest.outerOrdering_failurePropagatesFromForkAndIsInverted(ExpectedToFailTest.groovy:78)

Learn more about TestLens at testlens.app.

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.87395% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.8344%. Comparing base (6fde012) to head (b154bbc).
⚠️ Report is 2 commits behind head on master.

Files with missing lines Patch % Lines
...sc/StaticTypesMethodReferenceExpressionWriter.java 47.0588% 4 Missing and 5 partials ⚠️
...roovy/transform/stc/StaticTypeCheckingVisitor.java 85.1852% 2 Missing and 6 partials ⚠️
...dehaus/groovy/runtime/IntersectionCastSupport.java 83.3333% 1 Missing and 3 partials ⚠️
...sgen/asm/sc/AbstractFunctionalInterfaceWriter.java 91.1765% 1 Missing and 2 partials ⚠️
...oovy/classgen/asm/sc/StaticTypesClosureWriter.java 80.0000% 0 Missing and 3 partials ⚠️
...roovy/classgen/asm/sc/StaticTypesLambdaWriter.java 78.5714% 0 Missing and 3 partials ⚠️
...va/org/apache/groovy/parser/antlr4/AstBuilder.java 92.3077% 2 Missing ⚠️
...codehaus/groovy/ast/IntersectionTypeClassNode.java 89.4737% 1 Missing and 1 partial ⚠️
...codehaus/groovy/runtime/ProxyGeneratorAdapter.java 60.0000% 0 Missing and 2 partials ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##               master      #2518        +/-   ##
==================================================
+ Coverage     67.8134%   67.8344%   +0.0211%     
- Complexity      32345      32427        +82     
==================================================
  Files            1493       1495         +2     
  Lines          124213     124428       +215     
  Branches        22282      22354        +72     
==================================================
+ Hits            84233      84405       +172     
- Misses          32698      32715        +17     
- Partials         7282       7308        +26     
Files with missing lines Coverage Δ
...rg/codehaus/groovy/classgen/AsmClassGenerator.java 85.1528% <100.0000%> (+0.2305%) ⬆️
...va/org/codehaus/groovy/control/ResolveVisitor.java 90.2948% <100.0000%> (+0.0600%) ⬆️
...dehaus/groovy/transform/stc/StaticTypesMarker.java 100.0000% <100.0000%> (ø)
...va/org/apache/groovy/parser/antlr4/AstBuilder.java 86.6155% <92.3077%> (-0.0454%) ⬇️
...codehaus/groovy/ast/IntersectionTypeClassNode.java 89.4737% <89.4737%> (ø)
...codehaus/groovy/runtime/ProxyGeneratorAdapter.java 89.0792% <60.0000%> (-0.1681%) ⬇️
...sgen/asm/sc/AbstractFunctionalInterfaceWriter.java 91.9708% <91.1765%> (-0.8863%) ⬇️
...oovy/classgen/asm/sc/StaticTypesClosureWriter.java 88.3333% <80.0000%> (-2.7778%) ⬇️
...roovy/classgen/asm/sc/StaticTypesLambdaWriter.java 92.6966% <78.5714%> (-1.2793%) ⬇️
...dehaus/groovy/runtime/IntersectionCastSupport.java 83.3333% <83.3333%> (ø)
... and 2 more

... and 6 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants