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

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

commit f915b7bd0e4f26f04993810f0aba5c1e0ea45c6e
Author: Eric Milles <[email protected]>
AuthorDate: Fri Apr 4 20:02:22 2025 -0500

    GROOVY-11600: inner enum, trait, record, interface or annotation: static
---
 .../apache/groovy/parser/antlr4/AstBuilder.java    | 11 ++++------
 .../java/org/codehaus/groovy/antlr/EnumHelper.java |  2 +-
 .../org/codehaus/groovy/ast/InnerClassNode.java    |  8 ++++---
 .../org/codehaus/groovy/classgen/EnumVisitor.java  |  2 --
 .../transform/trait/TraitASTTransformation.java    |  3 ++-
 src/test/gls/innerClass/InnerClassTest.groovy      | 25 ++++++++++++++++++++++
 6 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java 
b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
index 2bef2bb19e..b3065ed17c 100644
--- a/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
+++ b/src/main/java/org/apache/groovy/parser/antlr4/AstBuilder.java
@@ -1255,8 +1255,7 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> {
                     null,
                     outerClass
             );
-        } else if (asBoolean(outerClass)) {
-            if (outerClass.isInterface()) modifiers |= Opcodes.ACC_STATIC;
+        } else if (outerClass != null) {
             classNode = new InnerClassNode(
                     outerClass,
                     outerClass.getName() + "$" + className,
@@ -1317,20 +1316,18 @@ public class AstBuilder extends 
GroovyParserBaseVisitor<Object> {
             this.checkUsingGenerics(classNode);
 
         } else if (isInterface) {
-            classNode.setModifiers(classNode.getModifiers() | 
Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT);
+            classNode.setModifiers(classNode.getModifiers() | 
Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT | (outerClass != null ? 
Opcodes.ACC_STATIC : 0));
             classNode.setInterfaces(this.visitTypeList(ctx.scs));
             this.checkUsingGenerics(classNode);
             this.hackMixins(classNode);
 
         } else if (isEnum || isRecord) {
+            if (isRecord) this.transformRecordHeaderToProperties(ctx, 
classNode);
             classNode.setInterfaces(this.visitTypeList(ctx.is));
             this.checkUsingGenerics(classNode);
-            if (isRecord) {
-                this.transformRecordHeaderToProperties(ctx, classNode);
-            }
 
         } else if (isAnnotation) {
-            classNode.setModifiers(classNode.getModifiers() | 
Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT | Opcodes.ACC_ANNOTATION);
+            classNode.setModifiers(classNode.getModifiers() | 
Opcodes.ACC_ANNOTATION | Opcodes.ACC_INTERFACE | Opcodes.ACC_ABSTRACT | 
(outerClass != null ? Opcodes.ACC_STATIC : 0));
             classNode.addInterface(ClassHelper.Annotation_TYPE);
             this.hackMixins(classNode);
 
diff --git a/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java 
b/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java
index 9299a98df3..5c17078b93 100644
--- a/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java
+++ b/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java
@@ -35,7 +35,7 @@ public class EnumHelper {
         if (outerClass == null) {
             enumClass = new ClassNode(name, modifiers | Opcodes.ACC_ENUM, 
null, interfaces, MixinNode.EMPTY_ARRAY);
         } else {
-            enumClass = new InnerClassNode(outerClass, outerClass.getName() + 
"$" + name, modifiers | Opcodes.ACC_ENUM, null, interfaces, 
MixinNode.EMPTY_ARRAY);
+            enumClass = new InnerClassNode(outerClass, outerClass.getName() + 
"$" + name, modifiers | Opcodes.ACC_ENUM | Opcodes.ACC_STATIC, null, 
interfaces, MixinNode.EMPTY_ARRAY);
         }
 
         // enum E extends java.lang.Enum<E>
diff --git a/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java 
b/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java
index 8c1019cb2c..f8649503fc 100644
--- a/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/InnerClassNode.java
@@ -18,6 +18,8 @@
  */
 package org.codehaus.groovy.ast;
 
+import org.objectweb.asm.Opcodes;
+
 /**
  * Represents an inner class definition.
  */
@@ -30,7 +32,7 @@ public class InnerClassNode extends ClassNode {
     /**
      * @param name is the full name of the class
      * @param modifiers the modifiers, @see org.objectweb.asm.Opcodes
-     * @param superClass the base class name - use "java.lang.Object" if no 
direct base class
+     * @param superClass the base class name; use "java.lang.Object" if no 
direct base class
      */
     public InnerClassNode(ClassNode outerClass, String name, int modifiers, 
ClassNode superClass) {
         this(outerClass, name, modifiers, superClass, ClassNode.EMPTY_ARRAY, 
MixinNode.EMPTY_ARRAY);
@@ -39,10 +41,10 @@ public class InnerClassNode extends ClassNode {
     /**
      * @param name is the full name of the class
      * @param modifiers the modifiers, @see org.objectweb.asm.Opcodes
-     * @param superClass the base class name - use "java.lang.Object" if no 
direct base class
+     * @param superClass the base class name; use "java.lang.Object" if no 
direct base class
      */
     public InnerClassNode(ClassNode outerClass, String name, int modifiers, 
ClassNode superClass, ClassNode[] interfaces, MixinNode[] mixins) {
-        super(name, modifiers, superClass, interfaces, mixins);
+        super(name, modifiers | (outerClass != null && 
outerClass.isInterface() ? Opcodes.ACC_STATIC : 0), superClass, interfaces, 
mixins);
         if (outerClass != null) outerClass.addInnerClass(this);
         this.outerClass = outerClass;
     }
diff --git a/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java 
b/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java
index ab22c7ca25..95d82d0c7d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java
@@ -141,8 +141,6 @@ public class EnumVisitor extends ClassCodeVisitorSupport {
 
             addMethods(enumClass, values, minValue, maxValue);
 
-            // for now, inner enum is always static
-            if (isInnerClass) enumClass.setModifiers(enumClass.getModifiers() 
| ACC_STATIC);
             if (isAnyAbstract(enumClass)) 
enumClass.setModifiers(enumClass.getModifiers() | ACC_ABSTRACT);
             else if (isNotExtended(enumClass)) 
enumClass.setModifiers(enumClass.getModifiers() | ACC_FINAL);
         }
diff --git 
a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java 
b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
index dde69b9efe..addd4c5f14 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -184,7 +184,8 @@ public class TraitASTTransformation extends 
AbstractASTTransformation implements
     }
 
     private ClassNode createHelperClass(final ClassNode cNode) {
-        cNode.setModifiers(ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE);
+        cNode.setModifiers(ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE
+                | (cNode.getOuterClass() != null ? ACC_STATIC : 0)); // 
GROOVY-11600
 
         ClassNode helper = new InnerClassNode(
                 cNode,
diff --git a/src/test/gls/innerClass/InnerClassTest.groovy 
b/src/test/gls/innerClass/InnerClassTest.groovy
index e36c5f42d7..f28d8d747a 100644
--- a/src/test/gls/innerClass/InnerClassTest.groovy
+++ b/src/test/gls/innerClass/InnerClassTest.groovy
@@ -341,6 +341,31 @@ final class InnerClassTest {
         '''
     }
 
+    // GROOVY-11600
+    @Test
+    void testInnerEnumOrRecordOrInterfaceHasStaticModifier() {
+        assertScript '''
+            import static java.lang.reflect.Modifier.*
+
+            class C {
+                enum E {}
+                class C {}
+                trait T {}
+                record R() {}
+                interface I {}
+                @interface A {}
+            }
+
+            assert  isStatic(C.E.modifiers)
+            assert !isStatic(C.C.modifiers)
+            assert  isStatic(C.T.modifiers)
+            assert  isStatic(C.R.modifiers)
+            assert  isFinal (C.R.modifiers)
+            assert  isStatic(C.I.modifiers)
+            assert  isStatic(C.A.modifiers)
+        '''
+    }
+
     @Test
     void testStaticInnerClass() {
         assertScript '''

Reply via email to