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
+ '''
+ }
+}