[groovy] branch master updated: Minor tweak: support nested several GINQ in the same nested level

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

[groovy] branch master updated: Minor tweak: support nested several GINQ in the same nested level

Daniel.Sun
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 792270f  Minor tweak: support nested several GINQ in the same nested level
792270f is described below

commit 792270f2b1b570b2aea09287acc62e1a9abd6adf
Author: Daniel Sun <[hidden email]>
AuthorDate: Sat Nov 21 17:32:10 2020 +0800

    Minor tweak: support nested several GINQ in the same nested level
---
 .../org/apache/groovy/ginq/dsl/GinqAstBuilder.java | 53 +++++++---------------
 .../test/org/apache/groovy/ginq/GinqTest.groovy    | 19 ++++++++
 2 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstBuilder.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstBuilder.java
index 0cbcc31..8125f3a 100644
--- a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstBuilder.java
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/dsl/GinqAstBuilder.java
@@ -36,15 +36,12 @@ import org.codehaus.groovy.ast.CodeVisitorSupport;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.BinaryExpression;
 import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.ExpressionTransformer;
-import org.codehaus.groovy.ast.expr.ListExpression;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.syntax.Types;
 
 import java.util.ArrayDeque;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Deque;
 import java.util.HashSet;
 import java.util.Set;
@@ -80,7 +77,7 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
         return ginqExpression.getNodeMetaData(__LATEST_GINQ_EXPRESSION_CLAUSE);
     }
 
-    private static final Set<String> KEY_WORD_SET = new HashSet<>(Arrays.asList(
+    private static final Set<String> KEYWORD_SET = new HashSet<>(Arrays.asList(
             "from", "innerjoin", "leftjoin", "rightjoin", "fulljoin", "crossjoin",
             "where", "on", "having", "groupby", "orderby", "limit", "select"));
 
@@ -89,7 +86,7 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
         super.visitMethodCallExpression(call);
         final String methodName = call.getMethodAsString();
 
-        if (!KEY_WORD_SET.contains(methodName)) return;
+        if (!KEYWORD_SET.contains(methodName)) return;
 
         if ("from".equals(methodName)) {
             ginqExpressionStack.push(new GinqExpression()); // store the result
@@ -120,14 +117,7 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
             }
             BinaryExpression binaryExpression = (BinaryExpression) expression;
             Expression aliasExpr = binaryExpression.getLeftExpression();
-            Expression dataSourceExpr;
-            if (null == latestGinqExpression) {
-                dataSourceExpr = binaryExpression.getRightExpression();
-            } else {
-                // use the nested ginq expresion and clear it
-                dataSourceExpr = latestGinqExpression;
-                latestGinqExpression = null;
-            }
+            Expression dataSourceExpr = binaryExpression.getRightExpression();
 
             DataSourceExpression dataSourceExpression;
             if ("from".equals(methodName)) {
@@ -146,30 +136,6 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
         if ("where".equals(methodName) || "on".equals(methodName) || "having".equals(methodName)) {
             Expression filterExpr = ((ArgumentListExpression) call.getArguments()).getExpression(0);
 
-            // construct `ListExpression` instance to visit `filterExpr` as well
-            new ListExpression(Collections.singletonList(filterExpr)).transformExpression(new ExpressionTransformer() {
-                @Override
-                public Expression transform(Expression expression) {
-                    if (isSelectMethodCallExpression(expression)) {
-                        return expression;
-                    }
-
-                    if (expression instanceof BinaryExpression) {
-                        final BinaryExpression binaryExpression = (BinaryExpression) expression;
-                        if (binaryExpression.getOperation().getType() == Types.KEYWORD_IN) {
-                            if (null != latestGinqExpression && isSelectMethodCallExpression(binaryExpression.getRightExpression())) {
-                                // use the nested ginq and clear it
-                                binaryExpression.setRightExpression(latestGinqExpression);
-                                latestGinqExpression = null;
-                                return binaryExpression;
-                            }
-                        }
-                    }
-
-                    return expression.transformExpression(this);
-                }
-            });
-
             FilterExpression filterExpression;
             if ("where".equals(methodName)) {
                 filterExpression = new WhereExpression(filterExpr);
@@ -291,6 +257,19 @@ public class GinqAstBuilder extends CodeVisitorSupport implements SyntaxErrorRep
         }
     }
 
+    @Override
+    public void visitBinaryExpression(BinaryExpression expression) {
+        super.visitBinaryExpression(expression);
+
+        if (expression.getOperation().getType() == Types.KEYWORD_IN) {
+            if (null != latestGinqExpression && isSelectMethodCallExpression(expression.getRightExpression())) {
+                // use the nested ginq and clear it
+                expression.setRightExpression(latestGinqExpression);
+                latestGinqExpression = null;
+            }
+        }
+    }
+
     private static boolean isSelectMethodCallExpression(Expression expression) {
         return expression instanceof MethodCallExpression && "select".equals(((MethodCallExpression) expression).getMethodAsString());
     }
diff --git a/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy b/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
index 5666541..b60f7be 100644
--- a/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
+++ b/subprojects/groovy-ginq/src/spec/test/org/apache/groovy/ginq/GinqTest.groovy
@@ -938,6 +938,25 @@ class GinqTest {
     }
 
     @Test
+    void "testGinq - nested from - 24"() {
+        assertScript '''
+            assert ['ab', 'bck'] == GQ {
+                from s in ['a', 'ab', 'bck']
+                where s.size() in (
+                    from x in ['ak', 'bg']
+                    where x[0] == s[0]
+                    select x.size()
+                ) || s.length() in (
+                    from y in ['abj', 'bpt']
+                    where y[0] == s[0]
+                    select y.length()
+                )
+                select s
+            }.toList()
+        '''
+    }
+
+    @Test
     void "testGinq - from leftjoin select - 1"() {
         assertScript '''
             def nums1 = [1, 2, 3]

Apache Groovy committer & PMC member

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