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 0e33c73ee4 GROOVY-11413: interfaces and modifiers of array class
0e33c73ee4 is described below

commit 0e33c73ee40d5672efad6d2fd27cd0700a337278
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Thu Jun 20 16:18:36 2024 -0500

    GROOVY-11413: interfaces and modifiers of array class
---
 .../options/ImmutablePropertyHandler.java          | 46 ++++++++++------------
 .../groovy/ast/tools/ImmutablePropertyUtils.java   |  9 ++---
 .../java/org/codehaus/groovy/ast/ClassHelper.java  |  1 +
 .../java/org/codehaus/groovy/ast/ClassNode.java    |  4 +-
 .../transform/AutoCloneASTTransformation.java      |  4 +-
 .../org/codehaus/groovy/ast/ClassNodeTest.java     | 17 ++++++++
 6 files changed, 46 insertions(+), 35 deletions(-)

diff --git 
a/src/main/java/groovy/transform/options/ImmutablePropertyHandler.java 
b/src/main/java/groovy/transform/options/ImmutablePropertyHandler.java
index 935eaf6f4a..726b09c354 100644
--- a/src/main/java/groovy/transform/options/ImmutablePropertyHandler.java
+++ b/src/main/java/groovy/transform/options/ImmutablePropertyHandler.java
@@ -22,7 +22,6 @@ import groovy.lang.ReadOnlyPropertyException;
 import groovy.transform.stc.POJO;
 import org.apache.groovy.ast.tools.ImmutablePropertyUtils;
 import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.FieldNode;
 import org.codehaus.groovy.ast.Parameter;
@@ -42,10 +41,7 @@ import 
org.codehaus.groovy.transform.ImmutableASTTransformation;
 import org.codehaus.groovy.transform.MapConstructorASTTransformation;
 import org.codehaus.groovy.transform.NullCheckASTTransformation;
 
-import java.util.Collection;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
 
@@ -54,8 +50,13 @@ import static 
org.apache.groovy.ast.tools.ImmutablePropertyUtils.cloneArrayOrClo
 import static org.apache.groovy.ast.tools.ImmutablePropertyUtils.cloneDateExpr;
 import static 
org.apache.groovy.ast.tools.ImmutablePropertyUtils.derivesFromDate;
 import static 
org.apache.groovy.ast.tools.ImmutablePropertyUtils.implementsCloneable;
+import static org.codehaus.groovy.ast.ClassHelper.CLONEABLE_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.COLLECTION_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.LIST_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.MAP_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.SET_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
 import static org.codehaus.groovy.ast.ClassHelper.make;
-import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignNullS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
@@ -81,17 +82,12 @@ import static 
org.codehaus.groovy.ast.tools.GeneralUtils.throwS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 
 public class ImmutablePropertyHandler extends PropertyHandler {
-    private static final ClassNode CLONEABLE_TYPE = make(Cloneable.class);
-    private static final ClassNode COLLECTION_TYPE = 
makeWithoutCaching(Collection.class, false);
+    private static final ClassNode POJO_TYPE = make(POJO.class);
+    private static final ClassNode SORTEDMAP_TYPE = make(SortedMap.class);
+    private static final ClassNode SORTEDSET_TYPE = make(SortedSet.class);
     private static final ClassNode DGM_TYPE = make(DefaultGroovyMethods.class);
-    private static final ClassNode SELF_TYPE = 
make(ImmutableASTTransformation.class);
-    private static final ClassNode MAP_TYPE = makeWithoutCaching(Map.class, 
false);
-    private static final ClassNode SORTEDSET_CLASSNODE = make(SortedSet.class);
-    private static final ClassNode SORTEDMAP_CLASSNODE = make(SortedMap.class);
-    private static final ClassNode SET_CLASSNODE = make(Set.class);
-    private static final ClassNode MAP_CLASSNODE = make(Map.class);
+    private static final ClassNode XFORM_TYPE = 
make(ImmutableASTTransformation.class);
     private static final ClassNode READONLYEXCEPTION_TYPE = 
make(ReadOnlyPropertyException.class);
-    private static final ClassNode POJO_TYPE = make(POJO.class);
 
     @Override
     public Statement createPropGetter(final PropertyNode pNode) {
@@ -159,16 +155,14 @@ public class ImmutablePropertyHandler extends 
PropertyHandler {
     }
 
     protected Expression cloneCollectionExpr(final Expression fieldExpr, final 
ClassNode type) {
-        return castX(type, createIfInstanceOfAsImmutableS(fieldExpr, 
SORTEDSET_CLASSNODE,
-                createIfInstanceOfAsImmutableS(fieldExpr, SORTEDMAP_CLASSNODE,
-                        createIfInstanceOfAsImmutableS(fieldExpr, 
SET_CLASSNODE,
-                                createIfInstanceOfAsImmutableS(fieldExpr, 
MAP_CLASSNODE,
-                                        
createIfInstanceOfAsImmutableS(fieldExpr, ClassHelper.LIST_TYPE,
-                                                createAsImmutableX(fieldExpr, 
COLLECTION_TYPE))
-                                )
-                        )
-                )
-        ));
+        // priority is low to high -- SortedSet comes first and Collection is 
last
+        Expression  asImmutableX = createAsImmutableX(fieldExpr, 
COLLECTION_TYPE);
+        asImmutableX = createIfInstanceOfAsImmutableS(fieldExpr, LIST_TYPE, 
asImmutableX);
+        asImmutableX = createIfInstanceOfAsImmutableS(fieldExpr, MAP_TYPE , 
asImmutableX);
+        asImmutableX = createIfInstanceOfAsImmutableS(fieldExpr, SET_TYPE , 
asImmutableX);
+        asImmutableX = createIfInstanceOfAsImmutableS(fieldExpr, 
SORTEDMAP_TYPE, asImmutableX);
+        asImmutableX = createIfInstanceOfAsImmutableS(fieldExpr, 
SORTEDSET_TYPE, asImmutableX);
+        return castX(type, asImmutableX);
     }
 
     private Expression createIfInstanceOfAsImmutableS(final Expression expr, 
final ClassNode type, final Expression elseStatement) {
@@ -214,7 +208,7 @@ public class ImmutablePropertyHandler extends 
PropertyHandler {
         Expression initExpr = fNode.getInitialValueExpression();
         Statement assignInit;
         if (initExpr == null || (initExpr instanceof ConstantExpression && 
((ConstantExpression) initExpr).isNullExpression())) {
-            if (ClassHelper.isPrimitiveType(fType)) {
+            if (isPrimitiveType(fType)) {
                 assignInit = EmptyStatement.INSTANCE;
             } else {
                 assignInit = shouldNullCheck ? 
NullCheckASTTransformation.makeThrowStmt(fNode.getName()) : 
assignNullS(fieldExpr);
@@ -262,7 +256,7 @@ public class ImmutablePropertyHandler extends 
PropertyHandler {
     // check at runtime since classes might not be resolved
     private static Expression createCheckImmutable(final FieldNode fNode, 
final Expression value, final List<String> knownImmutables, final List<String> 
knownImmutableClasses) {
         Expression args = args(callThisX("getClass"), constX(fNode.getName()), 
value, list2args(knownImmutables), classList2args(knownImmutableClasses));
-        return callX(SELF_TYPE, "checkImmutable", args);
+        return callX(XFORM_TYPE, "checkImmutable", args);
     }
 
     private Statement createConstructorStatementCollection(final FieldNode 
fNode, final Parameter namedArgsMap, final boolean shouldNullCheck) {
diff --git 
a/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java 
b/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java
index 182508780c..f5e140e238 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ImmutablePropertyUtils.java
@@ -48,8 +48,6 @@ import java.util.Date;
 import java.util.List;
 import java.util.Set;
 
-import static org.codehaus.groovy.ast.ClassHelper.make;
-import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.castX;
@@ -58,9 +56,8 @@ import static 
org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.isOrImplements;
 
 public class ImmutablePropertyUtils {
-    private static final ClassNode DATE_TYPE = make(Date.class);
-    private static final ClassNode CLONEABLE_TYPE = make(Cloneable.class);
-    public  static final ClassNode IMMUTABLE_OPTIONS_TYPE = 
makeWithoutCaching(ImmutableOptions.class, false);
+    private static final ClassNode DATE_TYPE = ClassHelper.make(Date.class);
+    public  static final ClassNode IMMUTABLE_OPTIONS_TYPE = 
ClassHelper.makeWithoutCaching(ImmutableOptions.class, false);
 
     private static final String MEMBER_KNOWN_IMMUTABLE_CLASSES = 
"knownImmutableClasses";
     private static final String MEMBER_KNOWN_IMMUTABLES = "knownImmutables";
@@ -185,7 +182,7 @@ public class ImmutablePropertyUtils {
     }
 
     public static boolean implementsCloneable(final ClassNode fieldType) {
-        return isOrImplements(fieldType, CLONEABLE_TYPE);
+        return isOrImplements(fieldType, ClassHelper.CLONEABLE_TYPE);
     }
 
     public static Expression cloneDateExpr(final Expression origDate) {
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java 
b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index c6cb4cfd16..b79a07ec51 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -142,6 +142,7 @@ public class ClassHelper {
             Annotation_TYPE = makeCached(Annotation.class),
             ELEMENT_TYPE_TYPE = makeCached(ElementType.class),
             AUTOCLOSEABLE_TYPE = makeCached(AutoCloseable.class),
+            CLONEABLE_TYPE = makeCached(Cloneable.class),
             SERIALIZABLE_TYPE = makeCached(Serializable.class),
             SERIALIZEDLAMBDA_TYPE = makeCached(SerializedLambda.class),
             SEALED_TYPE = makeCached(Sealed.class),
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java 
b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 2d2ec5b86a..c211c0f6d9 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -59,6 +59,7 @@ import static 
org.codehaus.groovy.transform.trait.Traits.isTrait;
 import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
 import static org.objectweb.asm.Opcodes.ACC_ANNOTATION;
 import static org.objectweb.asm.Opcodes.ACC_ENUM;
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
 import static org.objectweb.asm.Opcodes.ACC_INTERFACE;
 import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
 import static org.objectweb.asm.Opcodes.ACC_STATIC;
@@ -239,7 +240,8 @@ public class ClassNode extends AnnotatedNode {
      * Constructor used by {@code makeArray()} if no real class is available.
      */
     private ClassNode(final ClassNode componentType) {
-        this(componentType.getName() + "[]", ACC_PUBLIC, 
ClassHelper.OBJECT_TYPE);
+        this(componentType.getName() + "[]", ACC_ABSTRACT | ACC_FINAL | 
ACC_PUBLIC, ClassHelper.OBJECT_TYPE,
+          new ClassNode[]{ClassHelper.CLONEABLE_TYPE, 
ClassHelper.SERIALIZABLE_TYPE}, MixinNode.EMPTY_ARRAY);
         this.componentType = componentType.redirect();
         this.isPrimaryNode = false;
     }
diff --git 
a/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java 
b/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java
index fe318a0912..0916d79dcc 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/AutoCloneASTTransformation.java
@@ -54,6 +54,8 @@ import java.util.List;
 
 import static 
org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedConstructor;
 import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
+import static org.codehaus.groovy.ast.ClassHelper.CLONEABLE_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.isObjectType;
 import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
 import static org.codehaus.groovy.ast.ClassHelper.make;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
@@ -83,7 +85,6 @@ import static 
org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ternaryX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
-import static org.codehaus.groovy.ast.ClassHelper.isObjectType;
 import static 
org.codehaus.groovy.transform.sc.StaticCompilationVisitor.COMPILESTATIC_CLASSNODE;
 import static 
org.codehaus.groovy.transform.stc.StaticTypesMarker.DIRECT_METHOD_CALL_TARGET;
 import static org.objectweb.asm.Opcodes.ACC_FINAL;
@@ -98,7 +99,6 @@ public class AutoCloneASTTransformation extends 
AbstractASTTransformation {
     static final Class MY_CLASS = AutoClone.class;
     static final ClassNode MY_TYPE = make(MY_CLASS);
     static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage();
-    private static final ClassNode CLONEABLE_TYPE = make(Cloneable.class);
     private static final ClassNode BAOS_TYPE = 
make(ByteArrayOutputStream.class);
     private static final ClassNode BAIS_TYPE = 
make(ByteArrayInputStream.class);
     private static final ClassNode OOS_TYPE = make(ObjectOutputStream.class);
diff --git a/src/test/org/codehaus/groovy/ast/ClassNodeTest.java 
b/src/test/org/codehaus/groovy/ast/ClassNodeTest.java
index 3759da76ed..f42934aad1 100644
--- a/src/test/org/codehaus/groovy/ast/ClassNodeTest.java
+++ b/src/test/org/codehaus/groovy/ast/ClassNodeTest.java
@@ -23,6 +23,7 @@ import org.codehaus.groovy.ast.tools.GenericsUtils;
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -42,6 +43,22 @@ public final class ClassNodeTest {
         classNode.addField("field", ACC_PUBLIC, ClassHelper.STRING_TYPE, null);
     }
 
+    @Test // GROOVY-11413
+    public void testArrayClass() {
+        ClassNode array1 = ClassHelper.make(Integer[].class);
+        ClassNode array2 = classNode.makeArray();
+
+        assertEquals(array1.getModifiers(), array2.getModifiers());
+        assertEquals(array1.getSuperClass(), array2.getSuperClass());
+        assertArrayEquals(array1.getInterfaces(), array2.getInterfaces());
+
+        // members; TODO: "length" and "clone()"
+        assertTrue(array1.getFields().isEmpty());
+        assertTrue(array2.getFields().isEmpty());
+        assertTrue(array1.getMethods().isEmpty());
+        assertTrue(array2.getMethods().isEmpty());
+    }
+
     @Test
     public void testOuterClass() {
         assertNull(classNode.getOuterClass());

Reply via email to