This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/master by this push:
     new 2cb02e9b4e GROOVY-11877: anon. inner class is never static
2cb02e9b4e is described below

commit 2cb02e9b4e76fb06cdb57521be7ccb7c7036d2f2
Author: Eric Milles <[email protected]>
AuthorDate: Sat Mar 21 15:28:16 2026 -0500

    GROOVY-11877: anon. inner class is never static
---
 .../org/codehaus/groovy/ast/InnerClassNode.java    | 26 ++++++++++++++++++--
 .../groovy/gls/innerClass/InnerClassTest.groovy    | 28 ++++++++++++++++++++++
 2 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java 
b/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java
index f8649503fc..0dbbbe1c42 100644
--- a/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java
@@ -20,6 +20,8 @@ package org.codehaus.groovy.ast;
 
 import org.objectweb.asm.Opcodes;
 
+import java.util.Collections;
+
 /**
  * Represents an inner class definition.
  */
@@ -75,11 +77,31 @@ public class InnerClassNode extends ClassNode {
         this.scope = scope;
     }
 
+    @Override
+    public boolean isSealed() {
+        return !isAnonymous() && super.isSealed(); // JLS 15.9.5
+    }
+
     public boolean isAnonymous() {
         return anonymous;
     }
 
-    public void setAnonymous(boolean anonymous) {
-        this.anonymous = anonymous;
+    public void setAnonymous(final boolean anonymous) {
+        if (this.anonymous != anonymous) {
+            if (anonymous) { // JLS 15.9.5
+                this.anonymous = true;
+
+                // GROOVY-11877
+                int modifiers = getModifiers();
+                modifiers &= ~Opcodes.ACC_STATIC;
+                modifiers &= ~Opcodes.ACC_ABSTRACT;
+                if (!isEnum()) modifiers &= ~Opcodes.ACC_FINAL;
+                setModifiers(modifiers);
+
+                setPermittedSubclasses(Collections.emptyList());
+            } else {
+                throw new IllegalArgumentException("cannot demote anon. inner 
class");
+            }
+        }
     }
 }
diff --git a/src/test/groovy/gls/innerClass/InnerClassTest.groovy 
b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
index af830965d0..e56c4f9362 100644
--- a/src/test/groovy/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/groovy/gls/innerClass/InnerClassTest.groovy
@@ -89,6 +89,34 @@ final class InnerClassTest {
         '''
     }
 
+    // GROOVY-11877
+    @Test
+    void testInnerAIC2() {
+        assertScript '''import java.lang.reflect.Modifier
+            interface I {
+                def bar = new Object[1]
+                def foo = new Runnable() {
+                    @Override
+                    void run() {
+                        bar[0] = true
+                    }
+                }
+            }
+
+            def obj = I.foo
+            assert !I.bar[0]
+            obj.run()
+            assert  I.bar[0]
+
+            def aic = obj.getClass()
+            assert aic.getName() == 'I$1'
+            assert aic.getEnclosingClass().getName() == 'I'
+            assert !Modifier.isFinal   (aic.getModifiers())
+            assert !Modifier.isStatic  (aic.getModifiers())
+            assert !Modifier.isAbstract(aic.getModifiers())
+        '''
+    }
+
     // GROOVY-11854
     @Test
     void testScriptAIC() {

Reply via email to