[groovy] branch GROOVY-8258 updated (86516a1 -> d1f754b)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[groovy] branch GROOVY-8258 updated (86516a1 -> d1f754b)

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

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


    from 86516a1  GROOVY-8258: make fields `final`
     new d695867  GROOVY-8258: trivial refactoring
     new d1f754b  GROOVY-8258: generate unique param name for each invocation of lambda

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:
 .../linq/provider/collection/GinqAstWalker.groovy  | 23 ++++++--
 .../provider/collection/QueryableCollection.java   |  2 +-
 .../groovy/org/apache/groovy/linq/GinqTest.groovy  | 64 +++++++++++-----------
 3 files changed, 51 insertions(+), 38 deletions(-)

Apache Groovy committer & PMC member

Blog: http://blog.sunlan.me
Twitter: @daniel_sun
Reply | Threaded
Open this post in threaded view
|

[groovy] 01/02: GROOVY-8258: trivial refactoring

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

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

commit d6958676427df74cfe17f9815e655fd6a9d60ebb
Author: Daniel Sun <[hidden email]>
AuthorDate: Tue Oct 13 07:36:20 2020 +0800

    GROOVY-8258: trivial refactoring
---
 .../org/apache/groovy/linq/provider/collection/QueryableCollection.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java
index 101b1f3..476c0d3 100644
--- a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java
+++ b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/QueryableCollection.java
@@ -100,7 +100,7 @@ class QueryableCollection<T> implements Queryable<T>, Iterable<T> {
 
     @Override
     public Queryable<T> where(Predicate<? super T> filter) {
-        Stream<T> stream = this.stream().filter(filter::test);
+        Stream<T> stream = this.stream().filter(filter);
 
         return from(stream);
     }

Apache Groovy committer & PMC member

Blog: http://blog.sunlan.me
Twitter: @daniel_sun
Reply | Threaded
Open this post in threaded view
|

[groovy] 02/02: GROOVY-8258: generate unique param name for each invocation of lambda

Daniel.Sun
In reply to this post by Daniel.Sun
This is an automated email from the ASF dual-hosted git repository.

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

commit d1f754bf8315cfb598337f970d5ebfa1053d1f02
Author: Daniel Sun <[hidden email]>
AuthorDate: Tue Oct 13 08:23:22 2020 +0800

    GROOVY-8258: generate unique param name for each invocation of lambda
---
 .../linq/provider/collection/GinqAstWalker.groovy  | 23 ++++++--
 .../groovy/org/apache/groovy/linq/GinqTest.groovy  | 64 +++++++++++-----------
 2 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy
index e6c3850..db33cff 100644
--- a/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy
+++ b/subprojects/groovy-linq/src/main/groovy/org/apache/groovy/linq/provider/collection/GinqAstWalker.groovy
@@ -365,6 +365,11 @@ class GinqAstWalker implements GinqVisitor<Object>, SyntaxErrorReportable {
     private Expression correctVariablesOfGinqExpression(DataSourceExpression dataSourceExpression, Expression expr) {
         boolean isGroup = isGroupByVisited()
         boolean isJoin = dataSourceExpression instanceof JoinExpression
+        String lambdaParamName = expr.getNodeMetaData(__LAMBDA_PARAM_NAME)
+
+        if (null == lambdaParamName) {
+            throw new GroovyBugError("lambdaParamName is null. dataSourceExpression:${dataSourceExpression}, expr:${expr}")
+        }
 
         def correctVarsForJoin = { Expression expression ->
             if (!isJoin) return expression
@@ -387,7 +392,7 @@ class GinqAstWalker implements GinqVisitor<Object>, SyntaxErrorReportable {
                      *
                      * The following code shows how to construct the access path for variables
                      */
-            Expression prop = isGroup ? propX(new VariableExpression(__T), 'v1') : new VariableExpression(__T)
+            Expression prop = isGroup ? propX(new VariableExpression(lambdaParamName), 'v1') : new VariableExpression(lambdaParamName)
             for (DataSourceExpression dse = dataSourceExpression;
                  null == transformedExpression && dse instanceof JoinExpression;
                  dse = dse.getNodeMetaData(__DATA_SOURCE_EXPRESSION)) {
@@ -414,9 +419,9 @@ class GinqAstWalker implements GinqVisitor<Object>, SyntaxErrorReportable {
                 if (isGroup) { //  groupby
                     // in #1, we will correct receiver of built-in aggregate functions
                     // the correct receiver is `__t.v2`, so we should not replace `__t` here
-                    if (__T != expression.text) {
+                    if (lambdaParamName != expression.text) {
                         // replace `gk` in the groupby with `__t.v1.gk`, note: __t.v1 stores the group key
-                        transformedExpression = propX(propX(new VariableExpression(__T), 'v1'), expression.text)
+                        transformedExpression = propX(propX(new VariableExpression(lambdaParamName), 'v1'), expression.text)
                     }
                 } else if (isJoin) {
                     transformedExpression = correctVarsForJoin(expression)
@@ -427,7 +432,7 @@ class GinqAstWalker implements GinqVisitor<Object>, SyntaxErrorReportable {
                     if (expression.implicitThis) {
                         String methodName = expression.methodAsString
                         if ('count' == methodName && ((TupleExpression) expression.arguments).getExpressions().isEmpty()) {
-                            expression.objectExpression = propX(new VariableExpression(__T), 'v2')
+                            expression.objectExpression = propX(new VariableExpression(lambdaParamName), 'v2')
                             transformedExpression = expression
                         }
                     }
@@ -479,15 +484,21 @@ class GinqAstWalker implements GinqVisitor<Object>, SyntaxErrorReportable {
         )
     }
 
+    private static String generateLambdaParamName() {
+        "__t_${System.nanoTime()}_${new Random().nextInt(1000)}"
+    }
+
     private Tuple2<String, Expression> correctVariablesOfLambdaExpression(DataSourceExpression dataSourceExpression, Expression lambdaCode) {
         boolean isGroup = isGroupByVisited()
 
         String lambdaParamName
         if (dataSourceExpression instanceof JoinExpression || isGroup) {
-            lambdaParamName = __T
+            lambdaParamName = generateLambdaParamName()
+            lambdaCode.putNodeMetaData(__LAMBDA_PARAM_NAME, lambdaParamName)
             lambdaCode = correctVariablesOfGinqExpression(dataSourceExpression, lambdaCode)
         } else {
             lambdaParamName = dataSourceExpression.aliasExpr.text
+            lambdaCode.putNodeMetaData(__LAMBDA_PARAM_NAME, lambdaParamName)
         }
 
         return Tuple.tuple(lambdaParamName, lambdaCode)
@@ -516,6 +527,6 @@ class GinqAstWalker implements GinqVisitor<Object>, SyntaxErrorReportable {
 
     private static final String __DATA_SOURCE_EXPRESSION = "__dataSourceExpression"
     private static final String __METHOD_CALL_RECEIVER = "__methodCallReceiver"
-    private static final String __T = "__t"
     private static final String __GROUP_BY = "__GROUP_BY"
+    private static final String __LAMBDA_PARAM_NAME = "__LAMBDA_PARAM_NAME"
 }
diff --git a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
index 9a22d19..86a4d9c 100644
--- a/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
+++ b/subprojects/groovy-linq/src/test/groovy/org/apache/groovy/linq/GinqTest.groovy
@@ -18,7 +18,6 @@
  */
 package org.apache.groovy.linq
 
-import groovy.json.JsonSlurper
 import groovy.transform.CompileDynamic
 import groovy.transform.CompileStatic
 import org.junit.Test
@@ -1585,36 +1584,39 @@ class GinqTest {
     @CompileDynamic
     @Test
     void "testGinq - query json - 1"() {
-        def parser = new JsonSlurper()
-        def json = parser.parseText('''
-            {
-                "persons": [
-                    {"id": 1, "name": "Daniel"},
-                    {"id": 2, "name": "Paul"},
-                    {"id": 3, "name": "Eric"}
-                ],
-                "tasks": [
-                    {"id": 1, "assignee": 1, "content": "task1", "manDay": 6},
-                    {"id": 2, "assignee": 1, "content": "task2", "manDay": 1},
-                    {"id": 3, "assignee": 2, "content": "task3", "manDay": 3},
-                    {"id": 4, "assignee": 3, "content": "task4", "manDay": 5}
-                ]
-            }
-        ''')
-
-        def expected = [
-                [taskId: 1, taskContent: 'task1', assignee: 'Daniel', manDay: 6],
-                [taskId: 4, taskContent: 'task4', assignee: 'Eric', manDay: 5],
-                [taskId: 3, taskContent: 'task3', assignee: 'Paul', manDay: 3]
-        ]
-
-        assert expected == GINQ {
-            from p in json.persons
-            innerjoin t in json.tasks on t.assignee == p.id
-            where t.id in [1, 3, 4]
-            orderby t.manDay in desc
-            select (taskId: t.id, taskContent: t.content, assignee: p.name, manDay: t.manDay)
-        }.toList()
+        assertScript """
+            import groovy.json.JsonSlurper
+            def parser = new JsonSlurper()
+            def json = parser.parseText('''
+                {
+                    "persons": [
+                        {"id": 1, "name": "Daniel"},
+                        {"id": 2, "name": "Paul"},
+                        {"id": 3, "name": "Eric"}
+                    ],
+                    "tasks": [
+                        {"id": 1, "assignee": 1, "content": "task1", "manDay": 6},
+                        {"id": 2, "assignee": 1, "content": "task2", "manDay": 1},
+                        {"id": 3, "assignee": 2, "content": "task3", "manDay": 3},
+                        {"id": 4, "assignee": 3, "content": "task4", "manDay": 5}
+                    ]
+                }
+            ''')
+    
+            def expected = [
+                    [taskId: 1, taskContent: 'task1', assignee: 'Daniel', manDay: 6],
+                    [taskId: 4, taskContent: 'task4', assignee: 'Eric', manDay: 5],
+                    [taskId: 3, taskContent: 'task3', assignee: 'Paul', manDay: 3]
+            ]
+    
+            assert expected == GINQ {
+                from p in json.persons
+                innerjoin t in json.tasks on t.assignee == p.id
+                where t.id in [1, 3, 4]
+                orderby t.manDay in desc
+                select (taskId: t.id, taskContent: t.content, assignee: p.name, manDay: t.manDay)
+            }.toList()
+        """
     }
 
     @CompileDynamic

Apache Groovy committer & PMC member

Blog: http://blog.sunlan.me
Twitter: @daniel_sun