You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2021/04/14 06:52:07 UTC

[groovy] branch GROOVY-10035 updated (2f16b6b -> 6f81677)

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

sunlan pushed a change to branch GROOVY-10035
in repository https://gitbox.apache.org/repos/asf/groovy.git.


 discard 2f16b6b  GROOVY-10035: CLONE - Compiler writes extra cast for Type[] to Object[]
     new 6f81677  GROOVY-10035: CLONE - Compiler writes extra cast for Type[] to Object[]

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (2f16b6b)
            \
             N -- N -- N   refs/heads/GROOVY-10035 (6f81677)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../java/org/apache/groovy/ast/tools/ClassNodeUtils.java  | 15 +++++++++------
 .../org/codehaus/groovy/classgen/asm/OperandStack.java    | 13 ++++++-------
 src/test/groovy/bugs/Groovy9126.groovy                    |  4 ----
 3 files changed, 15 insertions(+), 17 deletions(-)

[groovy] 01/01: GROOVY-10035: CLONE - Compiler writes extra cast for Type[] to Object[]

Posted by su...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 6f816772ea0bd1e03614c29636184ebf46a06405
Author: Daniel Sun <su...@apache.org>
AuthorDate: Wed Apr 14 14:51:37 2021 +0800

    GROOVY-10035: CLONE - Compiler writes extra cast for Type[] to Object[]
---
 .../apache/groovy/ast/tools/ClassNodeUtils.java    | 18 ++++++++
 .../codehaus/groovy/classgen/asm/OperandStack.java |  6 +--
 .../codehaus/groovy/runtime/ArrayTypeUtils.java    | 50 ++++++++++++++++++++++
 src/test/groovy/bugs/Groovy9126.groovy             |  4 --
 4 files changed, 70 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
index d7d6657..984c530 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
@@ -49,6 +49,9 @@ import java.util.function.Predicate;
 import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.isGenerated;
 import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
 import static org.codehaus.groovy.ast.ClassHelper.boolean_TYPE;
+import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
+import static org.codehaus.groovy.runtime.ArrayTypeUtils.dimension;
+import static org.codehaus.groovy.runtime.ArrayTypeUtils.elementType;
 import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
 
 /**
@@ -355,6 +358,21 @@ public class ClassNodeUtils {
         return cNode.getOuterClass() != null && !Modifier.isStatic(cNode.getModifiers());
     }
 
+    /**
+     * Check if the source ClassNode is compatible with the target ClassNode
+     */
+    public static boolean isCompatibleWith(ClassNode source, ClassNode target) {
+        if (source.equals(target)) return true;
+
+        if (source.isArray() && target.isArray() && dimension(source) == dimension(target)) {
+            source = elementType(source);
+            target = elementType(target);
+        }
+
+        return !isPrimitiveType(source) && !isPrimitiveType(target)
+                && (source.isDerivedFrom(target) || source.implementsInterface(target));
+    }
+
     public static boolean hasNoArgConstructor(final ClassNode cNode) {
         List<ConstructorNode> constructors = cNode.getDeclaredConstructors();
         for (ConstructorNode next : constructors) {
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java b/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
index ec75c58..73edd6e 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/OperandStack.java
@@ -18,6 +18,7 @@
  */
 package org.codehaus.groovy.classgen.asm;
 
+import org.apache.groovy.ast.tools.ClassNodeUtils;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
@@ -339,10 +340,7 @@ public class OperandStack {
         }
 
         // GROOVY-10034: no need to cast non-primitive array when target is "java.lang.Object[]"
-        if (targetType.isArray() && targetType.getComponentType().equals(ClassHelper.OBJECT_TYPE)
-                && top.isArray() && !ClassHelper.isPrimitiveType(top.getComponentType())) {
-            return;
-        }
+        if (ClassNodeUtils.isCompatibleWith(top, targetType)) return;
 
         boolean primTarget = ClassHelper.isPrimitiveType(targetType);
         boolean primTop = ClassHelper.isPrimitiveType(top);
diff --git a/src/main/java/org/codehaus/groovy/runtime/ArrayTypeUtils.java b/src/main/java/org/codehaus/groovy/runtime/ArrayTypeUtils.java
index 6902461..8556789 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ArrayTypeUtils.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ArrayTypeUtils.java
@@ -19,6 +19,8 @@
 
 package org.codehaus.groovy.runtime;
 
+import org.codehaus.groovy.ast.ClassNode;
+
 /**
  * Utilities for handling array types
  */
@@ -43,6 +45,24 @@ public class ArrayTypeUtils {
     }
 
     /**
+     * Calculate the dimension of array
+     *
+     * @param clazz the type of array
+     * @return the dimension of array
+     */
+    public static int dimension(ClassNode clazz) {
+        checkArrayType(clazz);
+
+        int result = 0;
+        while (clazz.isArray()) {
+            result++;
+            clazz = clazz.getComponentType();
+        }
+
+        return result;
+    }
+
+    /**
      * Get the type of array elements
      *
      * @param clazz the type of array
@@ -59,6 +79,22 @@ public class ArrayTypeUtils {
     }
 
     /**
+     * Get the type of array elements
+     *
+     * @param clazz the type of array
+     * @return the type of elements
+     */
+    public static ClassNode elementType(ClassNode clazz) {
+        checkArrayType(clazz);
+
+        while (clazz.isArray()) {
+            clazz = clazz.getComponentType();
+        }
+
+        return clazz;
+    }
+
+    /**
      * Get the type of array elements by the dimension
      *
      * @param clazz the type of array
@@ -92,4 +128,18 @@ public class ArrayTypeUtils {
             throw new IllegalArgumentException(clazz.getCanonicalName() + " is not array type");
         }
     }
+
+    /**
+     * Check whether the type passed in is array type.
+     * If the type is not array type, throw IllegalArgumentException.
+     */
+    private static void checkArrayType(ClassNode clazz) {
+        if (null == clazz) {
+            throw new IllegalArgumentException("clazz can not be null");
+        }
+
+        if (!clazz.isArray()) {
+            throw new IllegalArgumentException(clazz.getName() + " is not array type");
+        }
+    }
 }
diff --git a/src/test/groovy/bugs/Groovy9126.groovy b/src/test/groovy/bugs/Groovy9126.groovy
index fb72f9c..258e724 100644
--- a/src/test/groovy/bugs/Groovy9126.groovy
+++ b/src/test/groovy/bugs/Groovy9126.groovy
@@ -22,8 +22,6 @@ import groovy.transform.CompileStatic
 import org.codehaus.groovy.classgen.asm.AbstractBytecodeTestCase
 import org.junit.Test
 
-import static groovy.test.GroovyAssert.assertScript
-
 @CompileStatic
 final class Groovy9126 extends AbstractBytecodeTestCase {
 
@@ -64,7 +62,6 @@ final class Groovy9126 extends AbstractBytecodeTestCase {
                  'L0',
                  'LINENUMBER 4 L0',
                  'ALOAD 0',
-                 'CHECKCAST script',
                  'BIPUSH 123',
                  'INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;',
                  'INVOKEVIRTUAL script.println (Ljava/lang/Object;)V',
@@ -95,7 +92,6 @@ final class Groovy9126 extends AbstractBytecodeTestCase {
                  'L0',
                  'LINENUMBER 4 L0',
                  'ALOAD 0',
-                 'CHECKCAST script',
                  'BIPUSH 123',
                  'INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;',
                  'INVOKEVIRTUAL script.println (Ljava/lang/Object;)V',