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/06/13 13:32:43 UTC

[groovy] branch master updated: GROOVY-8840: use inferred type for subscript if operand is placeholder

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

sunlan 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 0aafd97  GROOVY-8840: use inferred type for subscript if operand is placeholder
0aafd97 is described below

commit 0aafd9756cfd84a03fe8c1f1f79486dae73636ec
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Jun 9 14:58:50 2020 -0500

    GROOVY-8840: use inferred type for subscript if operand is placeholder
---
 .../classgen/asm/BinaryExpressionHelper.java       |  4 ++
 .../classgen/asm/sc/StaticInvocationWriter.java    |  3 --
 .../stc/DefaultGroovyMethodsSTCTest.groovy         | 51 ++++++++++++++++++++++
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
index 261fc84..02f02e9 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BinaryExpressionHelper.java
@@ -41,6 +41,7 @@ import org.codehaus.groovy.ast.expr.TernaryExpression;
 import org.codehaus.groovy.ast.expr.TupleExpression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.tools.GeneralUtils;
+import org.codehaus.groovy.ast.tools.GenericsUtils;
 import org.codehaus.groovy.ast.tools.WideningCategories;
 import org.codehaus.groovy.classgen.AsmClassGenerator;
 import org.codehaus.groovy.classgen.BytecodeExpression;
@@ -740,6 +741,9 @@ public class BinaryExpressionHelper {
                 subscript.visit(acg);
                 OperandStack operandStack = controller.getOperandStack();
                 ClassNode subscriptType = operandStack.getTopOperand();
+                if (subscriptType.isGenericsPlaceHolder() || GenericsUtils.hasPlaceHolders(subscriptType)) {
+                    subscriptType = controller.getTypeChooser().resolveType(bexp, controller.getClassNode());
+                }
                 int id = controller.getCompileStack().defineTemporaryVariable("$subscript", subscriptType, true);
                 VariableSlotLoader subscriptExpression = new VariableSlotLoader(subscriptType, id, operandStack);
                 BinaryExpression rewrite = binX(bexp.getLeftExpression(), bexp.getOperation(), subscriptExpression);
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index bb6e934..20c3b27 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -82,7 +82,6 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 import static org.codehaus.groovy.classgen.AsmClassGenerator.isNullConstant;
 import static org.codehaus.groovy.classgen.AsmClassGenerator.isSuperExpression;
 import static org.codehaus.groovy.classgen.AsmClassGenerator.isThisExpression;
-import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.missesGenericsTypes;
 import static org.objectweb.asm.Opcodes.ACONST_NULL;
 import static org.objectweb.asm.Opcodes.ALOAD;
 import static org.objectweb.asm.Opcodes.CHECKCAST;
@@ -316,8 +315,6 @@ public class StaticInvocationWriter extends InvocationWriter {
             if (ClassHelper.VOID_TYPE.equals(returnType)) {
                 returnType = ClassHelper.OBJECT_TYPE;
                 mv.visitInsn(ACONST_NULL);
-            } else if (missesGenericsTypes(returnType)) {
-                returnType = returnType.redirect();
             }
             controller.getOperandStack().push(returnType);
             return true;
diff --git a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
index bf36366..cf4c8f6 100644
--- a/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/DefaultGroovyMethodsSTCTest.groovy
@@ -202,6 +202,57 @@ class DefaultGroovyMethodsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    void testListGetAtNext() {
+        assertScript '''
+            def test() {
+                def list = [0, 1, 2, 3]
+                for (i in 1..2) {
+                    list[i-1]++
+                }
+                list
+            }
+            assert test() == [1, 2, 2, 3]
+        '''
+    }
+
+    // GROOVY-8840
+    void testListGetAtGetAtNext() {
+        assertScript '''
+            def test() {
+                def list = [0, 1, 2, 3]
+                List<Integer> other = [1]
+                list[other[0]]++
+                //   ^^^^^^^^ puts T on operand stack, not int/Integer
+                list
+            }
+            assert test() == [0, 2, 2, 3]
+        '''
+    }
+
+    void testListGetAtGetAtNext2() {
+        assertScript '''
+            def test() {
+                def list = [0, 1, 2, 3]
+                List<Integer> other = [1]
+                list[(int)other[0]]++
+                list
+            }
+            assert test() == [0, 2, 2, 3]
+        '''
+    }
+
+    void testListGetAtFirstNext() {
+        assertScript '''
+            def test() {
+                def list = [0, 1, 2, 3]
+                List<Integer> other = [1]
+                list[other.first()]++
+                list
+            }
+            assert test() == [0, 2, 2, 3]
+        '''
+    }
+
     // GROOVY-9420
     void testMapGetVsGetAt() {
         assertScript '''