Copilot commented on code in PR #2887:
URL: https://github.com/apache/groovy/pull/2887#discussion_r3943607395
##########
src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java:
##########
@@ -268,14 +268,27 @@ public void visitMethodCallExpression(final
MethodCallExpression call) {
*/
@Override
public void visitConstructorCallExpression(final ConstructorCallExpression
call) {
- super.visitConstructorCallExpression(call);
-
- if (call.isUsingAnonymousInnerClass() &&
call.getType().getNodeMetaData(StaticTypeCheckingVisitor.class) != null) {
+ if (call.isUsingAnonymousInnerClass()) {
ClassNode anonType = call.getType();
- anonType.putNodeMetaData(STATIC_COMPILE_NODE,
anonType.getEnclosingMethod().getNodeMetaData(STATIC_COMPILE_NODE));
- anonType.putNodeMetaData(WriterControllerFactory.class,
anonType.getOuterClass().getNodeMetaData(WriterControllerFactory.class));
+ if (anonType.getNodeMetaData(STATIC_COMPILE_NODE) == null) {
+ // GROOVY-6925: an anonymous inner class follows its enclosing
method
+ // (visitClass has already decided for the inner classes of an
annotated
+ // class). GROOVY-12363: decide before the type checker visits
the body
+ // below, otherwise its methods are checked while still
counting as
+ // dynamic (no direct call targets, no
SUPER_MOP_METHOD_REQUIRED) and yet
+ // the class is generated as statically compiled, which omits
the super$
+ // MOP bridges a dynamic super call needs.
+ MethodNode enclosingMethod = anonType.getEnclosingMethod();
+ boolean isSC = enclosingMethod != null
+ ? isStaticallyCompiled(enclosingMethod)
+ : isStaticallyCompiled(getEnclosingDeclaration());
+ anonType.putNodeMetaData(STATIC_COMPILE_NODE, isSC);
+ anonType.putNodeMetaData(WriterControllerFactory.class,
anonType.getOuterClass().getNodeMetaData(WriterControllerFactory.class));
+ }
Review Comment:
This null guard can preserve an earlier `false` class-level decision even
when the anonymous class is inside a more-specific `@CompileStatic` method. For
example, `@CompileDynamic class C { @CompileStatic Runnable m() { new
Runnable() { void run() { ... } } } }` is supported (the most-specific
annotation wins), but the outer-class visit records
`STATIC_COMPILE_NODE=false`; this method-level visit then refuses to change it
before checking the body, recreating the dynamic-body/static-writer mismatch.
Recompute the value from the enclosing method whenever this constructor is
actually visited; skipped methods do not reach this hook.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]