You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2020/10/03 16:25:40 UTC

[groovy] branch GROOVY-9769 created (now 1ee2ccd)

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

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


      at 1ee2ccd  GROOVY-9769: avoid unnecessary creation of UnionTypeClassNode

This branch includes the following new commits:

     new 1ee2ccd  GROOVY-9769: avoid unnecessary creation of UnionTypeClassNode

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.



[groovy] 01/01: GROOVY-9769: avoid unnecessary creation of UnionTypeClassNode

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

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

commit 1ee2ccd096f9d6fdc38f94253aef7b5f75a8887a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Oct 3 11:25:09 2020 -0500

    GROOVY-9769: avoid unnecessary creation of UnionTypeClassNode
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 27 +++++++-------
 .../classgen/asm/sc/bugs/Groovy7333Bug.groovy      | 43 +++++++++++++++++++---
 2 files changed, 51 insertions(+), 19 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index e36cf53..71dbbe1 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2265,26 +2265,27 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
         ).toArray(ClassNode[]::new);
     }
 
-    private ClassNode getInferredTypeFromTempInfo(final Expression exp, ClassNode result) {
-        if (exp instanceof VariableExpression && !typeCheckingContext.temporaryIfBranchTypeInformation.isEmpty()) {
-            List<ClassNode> classNodes = getTemporaryTypesForExpression(exp);
-            if (classNodes != null && !classNodes.isEmpty()) {
-                List<ClassNode> types = new ArrayList<>(classNodes.size() + 1);
-                if (result != null && !classNodes.contains(result)) types.add(result);
-                types.addAll(classNodes);
-                // GROOVY-7333: filter out Object
-                types.removeIf(OBJECT_TYPE::equals);
+    private ClassNode getInferredTypeFromTempInfo(final Expression expression, final ClassNode expressionType) {
+        if (expression instanceof VariableExpression && !typeCheckingContext.temporaryIfBranchTypeInformation.isEmpty()) {
+            List<ClassNode> tempTypes = getTemporaryTypesForExpression(expression);
+            if (tempTypes != null && !tempTypes.isEmpty()) {
+                List<ClassNode> types = new ArrayList<>(tempTypes.size() + 1);
+                if (expressionType != null && !expressionType.equals(ClassHelper.OBJECT_TYPE) // GROOVY-7333
+                        && tempTypes.stream().noneMatch(t -> implementsInterfaceOrIsSubclassOf(t, expressionType))) {
+                    types.add(expressionType);
+                }
+                types.addAll(tempTypes);
 
                 if (types.isEmpty()) {
-                    result = OBJECT_TYPE.getPlainNodeReference();
+                    return OBJECT_TYPE;
                 } else if (types.size() == 1) {
-                    result = types.get(0);
+                    return types.get(0);
                 } else {
-                    result = new UnionTypeClassNode(types.toArray(ClassNode.EMPTY_ARRAY));
+                    return new UnionTypeClassNode(types.toArray(ClassNode.EMPTY_ARRAY));
                 }
             }
         }
-        return result;
+        return expressionType;
     }
 
     @Override
diff --git a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333Bug.groovy b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333Bug.groovy
index ecb3c49..0916e27 100644
--- a/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333Bug.groovy
+++ b/src/test/org/codehaus/groovy/classgen/asm/sc/bugs/Groovy7333Bug.groovy
@@ -16,17 +16,15 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-
-
-
-
 package org.codehaus.groovy.classgen.asm.sc.bugs
 
 import groovy.transform.stc.StaticTypeCheckingTestCase
 import org.codehaus.groovy.classgen.asm.sc.StaticCompilationTestSupport
 
-class Groovy7333Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
-    void testIncorrectInstanceOfInference() {
+final class Groovy7333Bug extends StaticTypeCheckingTestCase implements StaticCompilationTestSupport {
+
+    // GROOVY-7333
+    void testIncorrectInstanceOfInference1() {
         assertScript '''
             int len(byte[] arr) { arr.length }
             def foo(arg) {
@@ -37,4 +35,37 @@ class Groovy7333Bug extends StaticTypeCheckingTestCase implements StaticCompilat
             assert foo(new byte[3]) == 3
         '''
     }
+
+    // GROOVY-9769
+    void testIncorrectInstanceOfInference2() {
+        assertScript '''
+            interface A {
+                def foo()
+            }
+            interface B extends A {
+                def bar()
+            }
+            @groovy.transform.CompileStatic
+            void test(A a) {
+                if (a instanceof B) {
+                    @ASTTest(phase=INSTRUCTION_SELECTION, value={
+                        def type = node.rightExpression.getNodeMetaData(INFERRED_RETURN_TYPE)
+                        assert type.text == 'B' // not '<UnionType:A+B>'
+                    })
+                    def x = a
+                    a.foo()
+                    a.bar()
+                }
+            }
+
+            def result = ''
+
+            test([
+                foo: { -> result += 'foo' },
+                bar: { -> result += 'bar' }
+            ] as B)
+
+            assert result == 'foobar'
+        '''
+    }
 }