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]

Reply via email to