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 2021/08/18 17:32:37 UTC

[groovy] branch GROOVY_3_0_X updated (3dca50c -> 2c43daa)

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

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


    from 3dca50c  GROOVY-10075: STC: always re-check extension method receiver/argument(s)
     new 7e46901  GROOVY-10098: STC: infer return type from Closure<T> for short-form call
     new 2c43daa  GROOVY-10102: trait SelfType: continue checking self type for self types

The 2 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:
 .../transform/stc/StaticTypeCheckingVisitor.java   | 12 ++--
 .../codehaus/groovy/transform/trait/Traits.java    | 46 ++++++++-------
 src/test/groovy/transform/stc/BugsSTCTest.groovy   | 69 ++++++++++++++++------
 .../groovy/transform/stc/GenericsSTCTest.groovy    | 15 +++++
 4 files changed, 96 insertions(+), 46 deletions(-)

[groovy] 02/02: GROOVY-10102: trait SelfType: continue checking self type for self types

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

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

commit 2c43daa690d12c1698778f72a09b66fb4eae3fb5
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed May 26 09:48:31 2021 -0500

    GROOVY-10102: trait SelfType: continue checking self type for self types
    
    Conflicts:
    	src/test/groovy/transform/stc/BugsSTCTest.groovy
---
 .../codehaus/groovy/transform/trait/Traits.java    | 46 ++++++++-------
 src/test/groovy/transform/stc/BugsSTCTest.groovy   | 69 ++++++++++++++++------
 2 files changed, 75 insertions(+), 40 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
index e051ad2..a2c5110 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
@@ -298,13 +298,12 @@ public abstract class Traits {
      * Collects all the self types that a type should extend or implement, given
      * the traits is implements. Collects from interfaces and superclasses too.
      * @param receiver a class node that may implement a trait
-     * @param selfTypes a collection where the list of self types will be written
-     * @return the selfTypes collection itself
+     * @param selfTypes a set where the self types will be put
+     * @return the {@code selfTypes} collection
+     *
      * @since 2.4.0
      */
-    public static LinkedHashSet<ClassNode> collectSelfTypes(
-            ClassNode receiver,
-            LinkedHashSet<ClassNode> selfTypes) {
+    public static LinkedHashSet<ClassNode> collectSelfTypes(final ClassNode receiver, final LinkedHashSet<ClassNode> selfTypes) {
         return collectSelfTypes(receiver, selfTypes, true, true);
     }
 
@@ -312,28 +311,30 @@ public abstract class Traits {
      * Collects all the self types that a type should extend or implement, given
      * the traits is implements.
      * @param receiver a class node that may implement a trait
-     * @param selfTypes a collection where the list of self types will be written
+     * @param selfTypes a set where the self types will be put
      * @param checkInterfaces should the interfaces that the node implements be collected too
-     * @param checkSuper should we collect from the superclass too
-     * @return the selfTypes collection itself
+     * @param checkSuperClass should we collect from the superclass too
+     * @return the {@code selfTypes} collection
+     *
      * @since 2.4.0
      */
-    public static LinkedHashSet<ClassNode> collectSelfTypes(
-            ClassNode receiver,
-            LinkedHashSet<ClassNode> selfTypes,
-            boolean checkInterfaces,
-            boolean checkSuper) {
+    public static LinkedHashSet<ClassNode> collectSelfTypes(final ClassNode receiver, final LinkedHashSet<ClassNode> selfTypes, final boolean checkInterfaces, final boolean checkSuperClass) {
         if (Traits.isTrait(receiver)) {
             List<AnnotationNode> annotations = receiver.getAnnotations(SELFTYPE_CLASSNODE);
             for (AnnotationNode annotation : annotations) {
                 Expression value = annotation.getMember("value");
                 if (value instanceof ClassExpression) {
-                    selfTypes.add(value.getType());
+                    ClassNode selfType = value.getType();
+                    if (selfTypes.add(selfType)) {
+                        collectSelfTypes(selfType, selfTypes, checkInterfaces, checkSuperClass);
+                    }
                 } else if (value instanceof ListExpression) {
-                    List<Expression> expressions = ((ListExpression) value).getExpressions();
-                    for (Expression expression : expressions) {
+                    for (Expression expression : ((ListExpression) value).getExpressions()) {
                         if (expression instanceof ClassExpression) {
-                            selfTypes.add(expression.getType());
+                            ClassNode selfType = expression.getType();
+                            if (selfTypes.add(selfType)) {
+                                collectSelfTypes(selfType, selfTypes, checkInterfaces, checkSuperClass);
+                            }
                         }
                     }
                 }
@@ -341,14 +342,15 @@ public abstract class Traits {
         }
         if (checkInterfaces) {
             ClassNode[] interfaces = receiver.getInterfaces();
-            for (ClassNode anInterface : interfaces) {
-                collectSelfTypes(anInterface, selfTypes, true, checkSuper);
+            for (ClassNode interFace : interfaces) {
+                if (!selfTypes.contains(interFace)) {
+                    collectSelfTypes(interFace, selfTypes, true, checkSuperClass);
+                }
             }
         }
-
-        if (checkSuper) {
+        if (checkSuperClass) {
             ClassNode superClass = receiver.getSuperClass();
-            if (superClass != null) {
+            if (superClass != null && !superClass.equals(ClassHelper.OBJECT_TYPE)) {
                 collectSelfTypes(superClass, selfTypes, checkInterfaces, true);
             }
         }
diff --git a/src/test/groovy/transform/stc/BugsSTCTest.groovy b/src/test/groovy/transform/stc/BugsSTCTest.groovy
index 887fc86..393845f 100644
--- a/src/test/groovy/transform/stc/BugsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/BugsSTCTest.groovy
@@ -90,34 +90,67 @@ class BugsSTCTest extends StaticTypeCheckingTestCase {
     // GROOVY-7929
     void testShouldDetectInvalidMethodUseWithinTraitWithCompileStaticAndSelfType() {
         shouldFailWithMessages '''
-            class C1 {
-                def c1() { }
+            class C {
+                def m() { }
             }
             @groovy.transform.CompileStatic
-            @groovy.transform.SelfType(C1)
-            trait TT {
-                def foo() {
-                    c2()
+            @groovy.transform.SelfType(C)
+            trait T {
+                void test() {
+                    x()
                 }
             }
-        ''', 'Cannot find matching method <UnionType:C1+TT>#c2'
+        ''', 'Cannot find matching method <UnionType:C+T>#x'
     }
 
-    void testGroovy5444() {
+    // GROOVY-10102
+    void testShouldDetectValidMethodUseWithinTraitWithCompileStaticAndSelfType() {
         assertScript '''
-                def curr = { System.currentTimeMillis() }
+            import groovy.transform.*
 
-                5.times {
-                    @ASTTest(phase=INSTRUCTION_SELECTION, value= {
-                        assert node.getNodeMetaData(INFERRED_TYPE) == Long_TYPE
-                    })
-                    def t0 = curr()
-                    100000.times {
-                        "echo"
+            trait A {
+                String foo = 'foo'
+                String m(String s, Closure x) {
+                    s + x()
+                }
+            }
+            @SelfType(A)
+            trait B {
+            }
+            @SelfType(B)
+            trait C {
+            }
+            @CompileStatic
+            @SelfType(C)
+            trait D {
+                def test() {
+                    String s = foo
+                    m(s) {
+                        s.toUpperCase()
                     }
-                    println (curr() - t0)
-                }'''
+                }
+            }
 
+            class E implements A, B, C, D { }
+            assert new E().test() == 'fooFOO'
+        '''
+    }
+
+    void testGroovy5444() {
+        assertScript '''
+            def millis = { System.currentTimeMillis() }
+
+            5.times {
+                @ASTTest(phase=INSTRUCTION_SELECTION, value= {
+                    assert node.getNodeMetaData(INFERRED_TYPE) == Long_TYPE
+                })
+                def t0 = millis()
+                1000.times {
+                    "echo"
+                }
+                def elapsed = millis() - t0
+            }
+        '''
     }
 
     void testGroovy5487ReturnNull() {

[groovy] 01/02: GROOVY-10098: STC: infer return type from Closure for short-form call

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

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

commit 7e469010c12649ae233bca543d3317f4d7b3a228
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu May 20 12:45:51 2021 -0500

    GROOVY-10098: STC: infer return type from Closure<T> for short-form call
    
    Conflicts:
    	src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
---
 .../groovy/transform/stc/StaticTypeCheckingVisitor.java   | 12 ++++++------
 src/test/groovy/transform/stc/GenericsSTCTest.groovy      | 15 +++++++++++++++
 2 files changed, 21 insertions(+), 6 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 440aebd..1c67688 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -3406,13 +3406,13 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
                             typeCheckClosureCall(callArguments, args, parameters);
                         }
                         ClassNode type = getType(((ASTNode) variable));
-                        if (type != null && type.equals(CLOSURE_TYPE)) {
+                        if (CLOSURE_TYPE.equals(type)) { // GROOVY-10098, et al.
                             GenericsType[] genericsTypes = type.getGenericsTypes();
-                            type = OBJECT_TYPE;
-                            if (genericsTypes != null) {
-                                if (!genericsTypes[0].isPlaceholder()) {
-                                    type = genericsTypes[0].getType();
-                                }
+                            if (genericsTypes != null && genericsTypes.length == 1
+                                    && genericsTypes[0].getLowerBound() == null) {
+                                type = getCombinedBoundType(genericsTypes[0]);
+                            } else {
+                                type = OBJECT_TYPE;
                             }
                         }
                         if (type != null) {
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 61de438..6631867 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -208,6 +208,21 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
         '''
     }
 
+    // GROOVY-10098
+    void testReturnTypeInferenceWithMethodGenerics16() {
+        assertScript '''
+            @groovy.transform.TupleConstructor(defaults=false)
+            class C<T extends Number> {
+              T p
+              T m() {
+                Closure<T> x = { -> p }
+                x() // Cannot return value of type Object on method returning type T
+              }
+            }
+            assert new C<>(42).m() == 42
+        '''
+    }
+
     void testDiamondInferrenceFromConstructor1() {
         assertScript '''
             Set< Long > s2 = new HashSet<>()