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 2020/09/12 16:26:30 UTC

[groovy] 17/19: minor refactor

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

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

commit 800badd1e88a40773c92f0ef7d2e12c6b9854b3b
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Sep 1 00:42:34 2020 +0800

    minor refactor
    
    (cherry picked from commit 03c21a3190b52fe3e9c868fd93b3250eb38e875a)
---
 .../groovy/classgen/asm/UnaryExpressionHelper.java |   2 +-
 .../asm/sc/StaticTypesUnaryExpressionHelper.java   | 134 +++++-----
 .../transform/stc/UnaryOperatorSTCTest.groovy      | 278 ++++++++++++++++++---
 .../asm/sc/UnaryOperatorStaticCompileTest.groovy   |  26 +-
 4 files changed, 322 insertions(+), 118 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/UnaryExpressionHelper.java b/src/main/java/org/codehaus/groovy/classgen/asm/UnaryExpressionHelper.java
index 9ed2792..842ea6d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/UnaryExpressionHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/UnaryExpressionHelper.java
@@ -41,7 +41,7 @@ public class UnaryExpressionHelper {
     static final MethodCaller unaryMinus = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "unaryMinus");
     static final MethodCaller bitwiseNegate = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "bitwiseNegate");
 
-    private final WriterController controller;
+    protected final WriterController controller;
 
     public UnaryExpressionHelper(final WriterController controller) {
         this.controller = controller;
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesUnaryExpressionHelper.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesUnaryExpressionHelper.java
index b1986e8..a46bf94 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesUnaryExpressionHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesUnaryExpressionHelper.java
@@ -25,7 +25,6 @@ import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.NotExpression;
 import org.codehaus.groovy.ast.expr.UnaryMinusExpression;
 import org.codehaus.groovy.ast.expr.UnaryPlusExpression;
-import org.codehaus.groovy.classgen.BytecodeExpression;
 import org.codehaus.groovy.classgen.asm.TypeChooser;
 import org.codehaus.groovy.classgen.asm.UnaryExpressionHelper;
 import org.codehaus.groovy.classgen.asm.WriterController;
@@ -38,66 +37,59 @@ import static org.codehaus.groovy.ast.ClassHelper.char_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.double_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.float_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.int_TYPE;
-import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
 import static org.codehaus.groovy.ast.ClassHelper.long_TYPE;
 import static org.codehaus.groovy.ast.ClassHelper.short_TYPE;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.bytecodeX;
 
 /**
- * An unary expression helper which generates optimized bytecode depending on
- * the current type on top of the operand stack.
+ * An expression helper which generates optimized bytecode depending on the
+ * current type on top of the operand stack.
  */
 public class StaticTypesUnaryExpressionHelper extends UnaryExpressionHelper implements Opcodes {
+
+    private static final BitwiseNegationExpression EMPTY_BITWISE_NEGATE = new BitwiseNegationExpression(EmptyExpression.INSTANCE);
     private static final UnaryMinusExpression EMPTY_UNARY_MINUS = new UnaryMinusExpression(EmptyExpression.INSTANCE);
     private static final UnaryPlusExpression EMPTY_UNARY_PLUS = new UnaryPlusExpression(EmptyExpression.INSTANCE);
-    private static final BitwiseNegationExpression EMPTY_BITWISE_NEGATE = new BitwiseNegationExpression(EmptyExpression.INSTANCE);
-
-    private final WriterController controller;
 
     public StaticTypesUnaryExpressionHelper(final WriterController controller) {
         super(controller);
-        this.controller = controller;
     }
 
     @Override
     public void writeBitwiseNegate(final BitwiseNegationExpression expression) {
         expression.getExpression().visit(controller.getAcg());
-        if (isPrimitiveOnTop()) {
-            ClassNode top = getTopOperand();
-            if (top == int_TYPE || top == short_TYPE || top == byte_TYPE || top == char_TYPE || top == long_TYPE) {
-                BytecodeExpression bytecodeExpression = bytecodeX(mv -> {
-                    if (long_TYPE == top) {
-                        mv.visitLdcInsn(-1L);
-                        mv.visitInsn(LXOR);
-                    } else {
-                        mv.visitInsn(ICONST_M1);
-                        mv.visitInsn(IXOR);
-                        if (byte_TYPE == top) {
-                            mv.visitInsn(I2B);
-                        } else if (char_TYPE == top) {
-                            mv.visitInsn(I2C);
-                        } else if (short_TYPE == top) {
-                            mv.visitInsn(I2S);
-                        }
+        ClassNode top = controller.getOperandStack().getTopOperand();
+        if (top == int_TYPE || top == long_TYPE || top == short_TYPE || top == byte_TYPE || top == char_TYPE) {
+            bytecodeX(mv -> {
+                if (top == long_TYPE) {
+                    mv.visitLdcInsn(-1);
+                    mv.visitInsn(LXOR);
+                } else {
+                    mv.visitInsn(ICONST_M1);
+                    mv.visitInsn(IXOR);
+                    if (top == byte_TYPE) {
+                        mv.visitInsn(I2B);
+                    } else if (top == char_TYPE) {
+                        mv.visitInsn(I2C);
+                    } else if (top == short_TYPE) {
+                        mv.visitInsn(I2S);
                     }
-                });
-                bytecodeExpression.visit(controller.getAcg());
-                controller.getOperandStack().remove(1);
-                return;
-            }
+                }
+            }).visit(controller.getAcg());
+            controller.getOperandStack().remove(1);
+        } else {
+            super.writeBitwiseNegate(EMPTY_BITWISE_NEGATE);
         }
-        super.writeBitwiseNegate(EMPTY_BITWISE_NEGATE);
     }
 
     @Override
     public void writeNotExpression(final NotExpression expression) {
-        TypeChooser typeChooser = controller.getTypeChooser();
         Expression subExpression = expression.getExpression();
-        ClassNode classNode = controller.getClassNode();
-        if (typeChooser.resolveType(subExpression, classNode) == boolean_TYPE) {
+        TypeChooser typeChooser = controller.getTypeChooser();
+        if (typeChooser.resolveType(subExpression, controller.getClassNode()) == boolean_TYPE) {
             subExpression.visit(controller.getAcg());
             controller.getOperandStack().doGroovyCast(boolean_TYPE);
-            BytecodeExpression bytecodeExpression = bytecodeX(mv -> {
+            bytecodeX(mv -> {
                 Label ne = new Label();
                 mv.visitJumpInsn(IFNE, ne);
                 mv.visitInsn(ICONST_1);
@@ -106,62 +98,50 @@ public class StaticTypesUnaryExpressionHelper extends UnaryExpressionHelper impl
                 mv.visitLabel(ne);
                 mv.visitInsn(ICONST_0);
                 mv.visitLabel(out);
-            });
-            bytecodeExpression.visit(controller.getAcg());
+            }).visit(controller.getAcg());
             controller.getOperandStack().remove(1);
-            return;
+        } else {
+            super.writeNotExpression(expression);
         }
-        super.writeNotExpression(expression);
     }
 
     @Override
     public void writeUnaryMinus(final UnaryMinusExpression expression) {
         expression.getExpression().visit(controller.getAcg());
-        if (isPrimitiveOnTop()) {
-            ClassNode top = getTopOperand();
-            if (top != boolean_TYPE) {
-                BytecodeExpression bytecodeExpression = bytecodeX(mv -> {
-                    if (int_TYPE == top || short_TYPE == top || byte_TYPE == top || char_TYPE == top) {
-                        mv.visitInsn(INEG);
-                        if (byte_TYPE == top) {
-                            mv.visitInsn(I2B);
-                        } else if (char_TYPE == top) {
-                            mv.visitInsn(I2C);
-                        } else if (short_TYPE == top) {
-                            mv.visitInsn(I2S);
-                        }
-                    } else if (long_TYPE == top) {
-                        mv.visitInsn(LNEG);
-                    } else if (float_TYPE == top) {
-                        mv.visitInsn(FNEG);
-                    } else if (double_TYPE == top) {
-                        mv.visitInsn(DNEG);
+        ClassNode top = controller.getOperandStack().getTopOperand();
+        if (top == int_TYPE || top == long_TYPE || top == short_TYPE || top == float_TYPE || top == double_TYPE || top == byte_TYPE || top == char_TYPE) {
+            bytecodeX(mv -> {
+                if (top == int_TYPE || top == short_TYPE || top == byte_TYPE || top == char_TYPE) {
+                    mv.visitInsn(INEG);
+                    if (top == byte_TYPE) {
+                        mv.visitInsn(I2B);
+                    } else if (top == char_TYPE) {
+                        mv.visitInsn(I2C);
+                    } else if (top == short_TYPE) {
+                        mv.visitInsn(I2S);
                     }
-                });
-                bytecodeExpression.visit(controller.getAcg());
-                controller.getOperandStack().remove(1);
-                return;
-            }
+                } else if (top == long_TYPE) {
+                    mv.visitInsn(LNEG);
+                } else if (top == float_TYPE) {
+                    mv.visitInsn(FNEG);
+                } else if (top == double_TYPE) {
+                    mv.visitInsn(DNEG);
+                }
+            }).visit(controller.getAcg());
+            controller.getOperandStack().remove(1);
+        } else {
+            super.writeUnaryMinus(EMPTY_UNARY_MINUS);
         }
-        // we already visited the sub expression
-        super.writeUnaryMinus(EMPTY_UNARY_MINUS);
     }
 
     @Override
     public void writeUnaryPlus(final UnaryPlusExpression expression) {
         expression.getExpression().visit(controller.getAcg());
-        if (isPrimitiveOnTop()) {
-            // only visit the expression
-            return;
+        ClassNode top = controller.getOperandStack().getTopOperand();
+        if (top == int_TYPE || top == long_TYPE || top == short_TYPE || top == float_TYPE || top == double_TYPE || top == byte_TYPE || top == char_TYPE) {
+            // only visit the sub-expression
+        } else {
+            super.writeUnaryPlus(EMPTY_UNARY_PLUS);
         }
-        super.writeUnaryPlus(EMPTY_UNARY_PLUS);
-    }
-
-    private boolean isPrimitiveOnTop() {
-        return isPrimitiveType(getTopOperand());
-    }
-
-    private ClassNode getTopOperand() {
-        return controller.getOperandStack().getTopOperand();
     }
 }
diff --git a/src/test/groovy/transform/stc/UnaryOperatorSTCTest.groovy b/src/test/groovy/transform/stc/UnaryOperatorSTCTest.groovy
index e26dbfa..b4854c6 100644
--- a/src/test/groovy/transform/stc/UnaryOperatorSTCTest.groovy
+++ b/src/test/groovy/transform/stc/UnaryOperatorSTCTest.groovy
@@ -19,130 +19,333 @@
 package groovy.transform.stc
 
 /**
- * Unit tests for static type checking : unary operator tests.
+ * Unit tests for static type checking : unary operators.
  */
 class UnaryOperatorSTCTest extends StaticTypeCheckingTestCase {
 
+    void testUnaryPlus_int() {
+        assertScript '''
+            int x = 1
+            assert +x == 1
+        '''
+    }
+
+    void testUnaryMinus_int() {
+        assertScript '''
+            int x = 1
+            assert -x == -1
+        '''
+    }
+
+    void testBitwiseNegate_int() {
+        assertScript '''
+            int x = 1
+            assert ~x == -2
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_long() {
+        assertScript '''
+            long x = 1L
+            assert +x == 1L
+        '''
+    }
+
+    void testUnaryMinus_long() {
+        assertScript '''
+            long x = 1L
+            assert -x == -1L
+        '''
+    }
+
     // GROOVY-9704
-    void testBitwiseNegate_long() {
+    void _FIXME_testBitwiseNegate_long() {
         assertScript '''
             long x = 1L
             assert ~x == -2L
         '''
     }
 
-    void testUnaryPlusOnInt() {
+    //
+
+    void testUnaryPlus_short() {
         assertScript '''
-            int x = 1
+            short x = 1
             assert +x == 1
         '''
     }
 
-    void testUnaryPlusOnInteger() {
+    void testUnaryMinus_short() {
         assertScript '''
-            Integer x = new Integer(1)
+            short x = 1
+            assert -x == -1
+        '''
+    }
+
+    void testBitwiseNegate_short() {
+        assertScript '''
+            short x = 1
+            assert ~x == -2
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_byte() {
+        assertScript '''
+            byte x = 1
             assert +x == 1
         '''
     }
 
-    void testUnaryMinusOnInt() {
+    void testUnaryMinus_byte() {
         assertScript '''
-            int x = 1
+            byte x = 1
             assert -x == -1
         '''
     }
 
-    void testUnaryMinusOnInteger() {
+    void testBitwiseNegate_byte() {
+        assertScript '''
+            byte x = 1
+            assert ~x == -2
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_char() {
+        shouldFail MissingMethodException, '''
+            char x = 1
+            +x
+        '''
+    }
+
+    void testUnaryMinus_char() {
+        shouldFail MissingMethodException, '''
+            char x = 1
+            -x
+        '''
+    }
+
+    void testBitwiseNegate_char() {
+        shouldFail MissingMethodException, '''
+            char x = 1
+            ~x
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_float() {
+        assertScript '''
+            float x = 1f
+            assert +x == 1f
+        '''
+    }
+
+    void testUnaryMinus_float() {
+        assertScript '''
+            float x = 1f
+            assert -x == -1f
+        '''
+    }
+
+    void testBitwiseNegate_float() {
+        shouldFail UnsupportedOperationException, '''
+            float x = 1f
+            ~x
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_double() {
+        assertScript '''
+            double x = 1d
+            assert +x == 1d
+        '''
+    }
+
+    void testUnaryMinus_double() {
+        assertScript '''
+            double x = 1d
+            assert -x == -1d
+        '''
+    }
+
+    void testBitwiseNegate_double() {
+        shouldFail UnsupportedOperationException, '''
+            double x = 1d
+            ~x
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_Integer() {
+        assertScript '''
+            Integer x = new Integer(1)
+            assert +x == 1
+        '''
+    }
+
+    void testUnaryMinus_Integer() {
         assertScript '''
             Integer x = new Integer(1)
             assert -x == -1
         '''
     }
 
-    void testUnaryPlusOnShort() {
+    void testBitwiseNegate_Integer() {
         assertScript '''
-            short x = 1
-            assert +x == 1
+            Integer x = new Integer(1)
+            assert ~x == -2
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_Long() {
+        assertScript '''
+            Long x = new Long(1L)
+            assert +x == 1L
         '''
     }
 
-    void testUnaryPlusOnBoxedShort() {
+    void testUnaryMinus_Long() {
+        assertScript '''
+            Long x = new Long(1L)
+            assert -x == -1L
+        '''
+    }
+
+    void testBitwiseNegate_Long() {
+        assertScript '''
+            Long x = new Long(1L)
+            assert ~x == -2L
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_Short() {
         assertScript '''
             Short x = new Short((short)1)
             assert +x == 1
         '''
     }
 
-    void testUnaryMinusOnShort() {
+    void testUnaryMinus_Short() {
         assertScript '''
-            short x = 1
+            Short x = new Short((short)1)
             assert -x == -1
         '''
     }
 
-    void testUnaryMinusOnBoxedShort() {
+    void testBitwiseNegate_Short() {
         assertScript '''
             Short x = new Short((short)1)
-            assert -x == -1
+            assert ~x == -2
         '''
     }
 
-    void testUnaryPlusOnFloat() {
+    //
+
+    void testUnaryPlus_Byte() {
         assertScript '''
-            float x = 1f
-            assert +x == 1f
+            Byte x = new Byte((byte)1)
+            assert +x == 1
         '''
     }
 
-    void testUnaryPlusOnBoxedFloat() {
+    void testUnaryMinus_Byte() {
         assertScript '''
-            Float x = new Float(1f)
-            assert +x == 1f
+            Byte x = new Byte((byte)1)
+            assert -x == -1
         '''
     }
 
-    void testUnaryMinusOnFloat() {
+    void testBitwiseNegate_Byte() {
         assertScript '''
-            float x = 1f
-            assert -x == -1f
+            Byte x = new Byte((byte)1)
+            assert ~x == -2
+        '''
+    }
+
+    //
+
+    void testUnaryPlus_Character() {
+        shouldFail MissingMethodException, '''
+            Character x = new Character((char)1)
+            +x
+        '''
+    }
+
+    void testUnaryMinus_Character() {
+        shouldFail MissingMethodException, '''
+            Character x = new Character((char)1)
+            -x
+        '''
+    }
+
+    void testBitwiseNegate_Character() {
+        shouldFail MissingMethodException, '''
+            Character x = new Character((char)1)
+            ~x
         '''
     }
 
-    void testUnaryMinusOnBoxedFloat() {
+    //
+
+    void testUnaryPlus_Float() {
         assertScript '''
             Float x = new Float(1f)
-            assert -x == -1f
+            assert +x == 1f
         '''
     }
 
-    void testUnaryPlusOnDouble() {
+    void testUnaryMinus_Float() {
         assertScript '''
-            double x = 1d
-            assert +x == 1d
+            Float x = new Float(1f)
+            assert -x == -1f
+        '''
+    }
+
+    void testBitwiseNegate_Float() {
+        shouldFail UnsupportedOperationException, '''
+            Float x = new Float(1f)
+            ~x
         '''
     }
 
-    void testUnaryPlusOnBoxedDouble() {
+    //
+
+    void testUnaryPlus_Double() {
         assertScript '''
             Double x = new Double(1d)
             assert +x == 1d
         '''
     }
 
-    void testUnaryMinusOnDouble() {
+    void testUnaryMinus_Double() {
         assertScript '''
-            double x = 1d
+            Double x = new Double(1d)
             assert -x == -1d
         '''
     }
 
-    void testUnaryMinusOnBoxedDouble() {
-        assertScript '''
+    void testBitwiseNegate_Double() {
+        shouldFail UnsupportedOperationException, '''
             Double x = new Double(1d)
-            assert -x == -1d
+            ~x
         '''
     }
 
+    //
+
     void testIntXIntInferredType() {
         assertScript '''
             int x = 1
@@ -325,4 +528,3 @@ class UnaryOperatorSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 }
-
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/UnaryOperatorStaticCompileTest.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/UnaryOperatorStaticCompileTest.groovy
index 520325b..f330eae 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/UnaryOperatorStaticCompileTest.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/UnaryOperatorStaticCompileTest.groovy
@@ -21,9 +21,31 @@ package org.codehaus.groovy.classgen.asm.sc
 import groovy.transform.stc.UnaryOperatorSTCTest
 
 /**
- * Unit tests for static type checking : unary operator.
+ * Unit tests for static compilation : unary operators.
  */
 class UnaryOperatorStaticCompileTest extends UnaryOperatorSTCTest implements StaticCompilationTestSupport {
 
-}
+    @Override
+    void testUnaryPlus_char() {
+        assertScript '''
+            char x = 1
+            assert +x == 1
+        '''
+    }
+
+    @Override
+    void testUnaryMinus_char() {
+        assertScript '''
+            char x = 1
+            assert -x == 0xFFFF
+        '''
+    }
 
+    @Override
+    void testBitwiseNegate_char() {
+        assertScript '''
+            char x = 1
+            assert ~x == 0xFFFE
+        '''
+    }
+}