[code-reflection] RFR: Issue errors when quotable constructs are found inside inner classes
Maurizio Cimadamore
mcimadamore at openjdk.org
Tue Jul 8 16:40:57 UTC 2025
On Mon, 7 Jul 2025 15:01:34 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:
> This PR adds check in `ReflectMethods` to issue errors when quotable methods, lambdas, method references are found inside an inner class. This includes member inner classes, local and anonymous inner classes, but static inner classes (sometimes referred to as *nested classes*) are ok.
>
> The issue is that if we allowed code reflection in these places, we would need to come up with uniform treatment for compiler-generated captured symbols.
> Currently `ReflectMethods` just allows method in an inner class to refer to a variable or a method in the enclosing class freely. While this is correct from a source code perspective, by the time we translate to bytecode, such references are no longer possible, and are typically mediated by compiler-generated symbols such as `this$0`.
>
> So, instead of generating a code model that might be unreliable, it is better, for now, to just disallow such cases.
>
> In principle, we should just "skip over" code elements we cannot support, and generate bytecode as usual. Indeed this is where I started, but then I realized that the support for lambda conversion into `Quoted` does not make sense unless we enable code reflection (as there's no real functional interface target we can use there). For this reason, an error is generated instead.
Let me approach it from a completely different angle (for the sake of argument)
Another possible answer could be to stick with the source code, rather than trying to play the "codegen" game. E.g. if the source code says we're accessing a member from an enclosing class, then the model should say we're accessing a member from an enclosing class. If the model is then used to generate the bytecode, at least it will be "trivial" to detect which parts of the model contain an enclosing instance access that needs to be patched.
While correct in principle, this approach turns out to be problematic in practice. How exactly do we determine when enclosing instance access is required? We can (and we do) have complex cases where the same member is available both in the current class and the enclosing class. But maybe the one in the superclass is not accessible, so we prefer the enclosing class path. But the code model, most surely, doesn't have the level of finesse required to answer such questions -- and even if it did, I wonder if we would want code model processors to basically reimplement a biggie portion of the javac compiler in their own 3rd party logic.
So, I think this means that the decision of "where did x comes from" (where x can be a member of an enclosing class, or some captured value) need to be made explicit in the model, otherwise processors will have an hard time figuring out which is which.
-------------
PR Comment: https://git.openjdk.org/babylon/pull/486#issuecomment-3049613181
More information about the babylon-dev
mailing list