[groovy] branch master updated: Validate invalid options of GINQ

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: Validate invalid options of GINQ

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 74922e7  Validate invalid options of GINQ
74922e7 is described below

commit 74922e76ffd2dd85a42fe9b3a7e998962372307d
Author: Daniel Sun <[hidden email]>
AuthorDate: Sun Jan 10 15:43:24 2021 +0800

    Validate invalid options of GINQ
---
 .../apache/groovy/ginq/GinqGroovyMethods.groovy    | 24 +++++++++++++--
 .../apache/groovy/ginq/InvalidOptionException.java | 34 ++++++++++++++++++++++
 .../org/apache/groovy/ginq/GinqErrorTest.groovy    | 12 ++++++++
 3 files changed, 67 insertions(+), 3 deletions(-)

diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/GinqGroovyMethods.groovy b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/GinqGroovyMethods.groovy
index 6d0b54f..7535c37 100644
--- a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/GinqGroovyMethods.groovy
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/GinqGroovyMethods.groovy
@@ -25,6 +25,7 @@ import org.apache.groovy.ginq.dsl.GinqAstVisitor
 import org.apache.groovy.ginq.dsl.expression.GinqExpression
 import org.apache.groovy.ginq.provider.collection.GinqAstWalker
 import org.apache.groovy.lang.annotation.Incubating
+import org.codehaus.groovy.ast.ASTNode
 import org.codehaus.groovy.ast.ClassHelper
 import org.codehaus.groovy.ast.expr.ClosureExpression
 import org.codehaus.groovy.ast.expr.Expression
@@ -32,8 +33,10 @@ import org.codehaus.groovy.ast.expr.MapEntryExpression
 import org.codehaus.groovy.ast.expr.MapExpression
 import org.codehaus.groovy.ast.stmt.Statement
 import org.codehaus.groovy.control.SourceUnit
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage
 import org.codehaus.groovy.macro.runtime.Macro
 import org.codehaus.groovy.macro.runtime.MacroContext
+import org.codehaus.groovy.syntax.SyntaxException
 
 import static org.codehaus.groovy.ast.tools.GeneralUtils.asX
 
@@ -90,7 +93,7 @@ class GinqGroovyMethods {
         code.visit(ginqAstBuilder)
         GinqExpression ginqExpression = ginqAstBuilder.getGinqExpression()
 
-        Map<String, String> configuration = createConfiguration(ginqConfigurationMapExpression)
+        Map<String, String> configuration = createConfiguration(sourceUnit, ginqConfigurationMapExpression)
 
         if (TRUE_STR == configuration.get(CONF_OPTIMIZE, TRUE_STR)) {
             GinqAstOptimizer ginqAstOptimizer = new GinqAstOptimizer()
@@ -104,21 +107,36 @@ class GinqGroovyMethods {
         return (Expression) ginqAstWalker.visitGinqExpression(ginqExpression)
     }
 
-    private static Map<String, String> createConfiguration(MapExpression ginqConfigurationMapExpression) {
+    private static Map<String, String> createConfiguration(SourceUnit sourceUnit, MapExpression ginqConfigurationMapExpression) {
         Map<String, String> configuration = [:]
         if (!ginqConfigurationMapExpression) return configuration
 
         for (MapEntryExpression mapEntryExpression : ginqConfigurationMapExpression.getMapEntryExpressions()) {
-            configuration.put(mapEntryExpression.keyExpression.text, mapEntryExpression.valueExpression.text)
+            def conf = mapEntryExpression.keyExpression.text
+            if (conf !in CONF_LIST) {
+                collectErrors("Invalid option: ${conf}. (supported options: ${CONF_LIST})", mapEntryExpression.keyExpression, sourceUnit)
+            }
+            configuration.put(conf, mapEntryExpression.valueExpression.text)
         }
         return configuration
     }
 
+    private static void collectErrors(String message, ASTNode astNode, SourceUnit sourceUnit) {
+        InvalidOptionException invalidOptionException = new InvalidOptionException(message)
+        SyntaxException e = new SyntaxException(
+                invalidOptionException.getMessage(),
+                invalidOptionException,
+                astNode.lineNumber,
+                astNode.columnNumber)
+        sourceUnit.getErrorCollector().addFatalError(new SyntaxErrorMessage(e, sourceUnit))
+    }
+
     private GinqGroovyMethods() {}
 
     public static final String CONF_PARALLEL = 'parallel'
     private static final String CONF_AST_WALKER = 'astWalker'
     private static final String CONF_OPTIMIZE = 'optimize'
+    private static final List<String> CONF_LIST = [CONF_PARALLEL, CONF_AST_WALKER, CONF_OPTIMIZE]
     private static final String DEFAULT_AST_WALKER_CLASS_NAME = GinqAstWalker.class.name
     private static final String TRUE_STR = 'true'
 }
diff --git a/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/InvalidOptionException.java b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/InvalidOptionException.java
new file mode 100644
index 0000000..f25cb50
--- /dev/null
+++ b/subprojects/groovy-ginq/src/main/groovy/org/apache/groovy/ginq/InvalidOptionException.java
@@ -0,0 +1,34 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.groovy.ginq;
+
+import org.codehaus.groovy.GroovyException;
+
+/**
+ * Represents invalid options, e.g. unsupported options
+ *
+ * @since 4.0.0
+ */
+public class InvalidOptionException extends GroovyException {
+    private static final long serialVersionUID = -8644282992572200089L;
+
+    public InvalidOptionException(String message) {
+        super(message);
+    }
+}
diff --git a/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/GinqErrorTest.groovy b/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/GinqErrorTest.groovy
index 1a746d1..83037ae 100644
--- a/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/GinqErrorTest.groovy
+++ b/subprojects/groovy-ginq/src/test/groovy/org/apache/groovy/ginq/GinqErrorTest.groovy
@@ -553,4 +553,16 @@ class GinqErrorTest {
 
         assert err.toString().contains('Only `nullslast`/`nullsfirst` is expected @ line 3, column 33.')
     }
+
+    @Test
+    void "testGinq - invalid option - 1"() {
+        def err = shouldFail '''\
+            GQ(xxx:true) {
+                from n in [1, 2, 3]
+                select n
+            }
+        '''
+
+        assert err.toString().contains('Invalid option: xxx. (supported options: [parallel, astWalker, optimize]) @ line 1, column 16.')
+    }
 }

Apache Groovy committer & PMC member

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