[code-reflection] RFR: Drop Quotable type
Maurizio Cimadamore
mcimadamore at openjdk.org
Wed Nov 19 13:15:31 UTC 2025
The `Quotable` type is a marker interface that is used to mark lambda expressions and method reference for which javac should produce a code model (we call them quotable lambdas), as in:
Runnable r = (Runnable & Quotable)() -> {}
Since the lambda metafactory, nor `Op::opQuotable` only rely on this type in a superficial way, this PR simplifies the programming model by removing `Quotable` and use the `@CodeReflection` annotation (now turned into a type annotation) to mark quotable lambdas, as in:
Runnable r = (@CodeReflection Runnable)() -> {}
Supporting this is relatively straightforward. The most complex part is, perhaps, to make sure that (a) the type annotation we care about is visible in the AST (javac is very lazy when it comes to fill in information on type annotations) and (b) make sure we don't end up using type annotations that appear in positions other than a cast. The latter point is important; if we have this:
void m(@CodeReflection Runnable r) { ... }
m(() -> { .. });
we don't want the lambda to magically become quotable simply because the target method parameter has been annotated.
There's also other cases like:
@CodeReflection
Runnable m() {
return () -> { .. };
}
If `@CodeReflection` is a type annotation, the above lambda has a target `@CodeReflection Runnable` and is also treated as a quotable lambda. What we want here instead is for `@CodeReflection` to just act as a regular declaration annotation on the method.
To address these issues, I've augmented both `ReflectMethods` and its associated `BodyScanner` to keep track of the prviously visited node. This is done by having both classes extend a new simple scanner `TreeScannerPrev`, which "remembers" the node visited before the current one.
Thanks to this, when we see a lambda we can see if the previous node was a cast, and if such a cast contained any type-annotated type. If so, we will treat the lambda as a quotable lambda.
This implementation tactic guarantees that type annotations will only be consulted when needed.
-------------
Commit messages:
- Simplify code
- Fix JDK tests
- Initial push
Changes: https://git.openjdk.org/babylon/pull/685/files
Webrev: https://webrevs.openjdk.org/?repo=babylon&pr=685&range=00
Stats: 314 lines in 31 files changed: 80 ins; 111 del; 123 mod
Patch: https://git.openjdk.org/babylon/pull/685.diff
Fetch: git fetch https://git.openjdk.org/babylon.git pull/685/head:pull/685
PR: https://git.openjdk.org/babylon/pull/685
More information about the babylon-dev
mailing list