You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2021/11/18 12:39:03 UTC

[groovy] branch master updated: add check for required parameter when using NamedVariant

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

paulk 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 220f73a  add check for required parameter when using NamedVariant
220f73a is described below

commit 220f73a250a0a1f3dd14ce3bfa8a91bf51d35bab
Author: Paul King <pa...@asert.com.au>
AuthorDate: Thu Nov 18 22:38:55 2021 +1000

    add check for required parameter when using NamedVariant
---
 .../transform/NamedVariantASTTransformation.java       | 18 +++++++++++++-----
 .../transform/TupleConstructorASTTransformation.java   |  2 +-
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java
index 39c6604..7cda805 100644
--- a/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java
@@ -38,6 +38,7 @@ import org.codehaus.groovy.ast.stmt.AssertStatement;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
 import org.codehaus.groovy.ast.stmt.ForStatement;
 import org.codehaus.groovy.ast.tools.GenericsUtils;
+import org.codehaus.groovy.classgen.asm.util.TypeUtil;
 import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
 
@@ -74,6 +75,7 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.plusX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.ternaryX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 
 @GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
@@ -121,7 +123,7 @@ public class NamedVariantASTTransformation extends AbstractASTTransformation {
         } else {
             for (Parameter fromParam : fromParams) {
                 if (!annoFound) {
-                    if (!processImplicitNamedParam(this, mNode, mapParam, args, propNames, fromParam, coerce)) return;
+                    if (!processImplicitNamedParam(this, mNode, mapParam, inner, args, propNames, fromParam, coerce)) return;
                 } else if (AnnotatedNodeUtils.hasAnnotation(fromParam, NAMED_PARAM_TYPE)) {
                     if (!processExplicitNamedParam(mNode, mapParam, inner, args, propNames, fromParam, coerce)) return;
                 } else if (AnnotatedNodeUtils.hasAnnotation(fromParam, NAMED_DELEGATE_TYPE)) {
@@ -138,18 +140,24 @@ public class NamedVariantASTTransformation extends AbstractASTTransformation {
         createMapVariant(this, mNode, anno, mapParam, genParams, cNode, inner, args, propNames);
     }
 
-    static boolean processImplicitNamedParam(final ErrorCollecting xform, final MethodNode mNode, final Parameter mapParam, final ArgumentListExpression args, final List<String> propNames, final Parameter fromParam, boolean coerce) {
+    static boolean processImplicitNamedParam(final ErrorCollecting xform, final MethodNode mNode, final Parameter mapParam, final BlockStatement inner, final ArgumentListExpression args, final List<String> propNames, final Parameter fromParam, boolean coerce) {
         boolean required = !fromParam.hasInitialExpression();
         String name = fromParam.getName();
         if (hasDuplicates(xform, mNode, propNames, name)) return false;
         AnnotationNode namedParam = new AnnotationNode(NAMED_PARAM_TYPE);
+        ClassNode type = fromParam.getType();
         namedParam.addMember("value", constX(name));
-        namedParam.addMember("type", classX(fromParam.getType()));
+        namedParam.addMember("type", classX(type));
         namedParam.addMember("required", constX(required, true));
         mapParam.addAnnotation(namedParam);
         PropertyExpression arg = propX(varX(mapParam), name);
-        Expression argOrDefault = fromParam.hasInitialExpression() ? elvisX(arg, fromParam.getDefaultValue()) : arg;
-        args.addExpression(asType(argOrDefault, fromParam.getType(), coerce));
+        Expression fallback = fromParam.getDefaultValue() == null && TypeUtil.isPrimitiveType(type) ? defaultValueX(type) : fromParam.getDefaultValue();
+        Expression argOrDefault = required && !TypeUtil.isPrimitiveType(type) ? arg : ternaryX(arg, arg, fallback);
+        args.addExpression(asType(argOrDefault, type, coerce));
+        if (required) {
+            inner.addStatement(new AssertStatement(boolX(callX(varX(mapParam), "containsKey", args(constX(name)))),
+                    plusX(constX("Missing required named argument '" + name + "'. Keys found: "), callX(varX(mapParam), "keySet"))));
+        }
         return true;
     }
 
diff --git a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
index 3c6aa99..9c3c3ec 100644
--- a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
@@ -278,7 +278,7 @@ public class TupleConstructorASTTransformation extends AbstractASTTransformation
             ArgumentListExpression args = new ArgumentListExpression();
             List<String> propNames = new ArrayList<>();
             for (Parameter p : params) {
-                if (!processImplicitNamedParam(xform, consNode, mapParam, args, propNames, p,false)) return;
+                if (!processImplicitNamedParam(xform, consNode, mapParam, inner, args, propNames, p,false)) return;
             }
             NamedVariantASTTransformation.createMapVariant(xform, consNode, anno, mapParam, genParams, cNode, inner, args, propNames);
         }