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/09/26 09:59:59 UTC

[groovy] branch master updated: GROOVY-10261: @NamedVariant: Default parameters on ctor/method are ignored when passing some named parameters

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 dc3fe27  GROOVY-10261: @NamedVariant: Default parameters on ctor/method are ignored when passing some named parameters
     new 0521482  Merge pull request #1625 from paulk-asert/groovy10261
dc3fe27 is described below

commit dc3fe275626fb29ffdf8dc22b8f41ceabbc5ac32
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sun Sep 26 17:10:24 2021 +1000

    GROOVY-10261: @NamedVariant: Default parameters on ctor/method are ignored when passing some named parameters
---
 .../org/codehaus/groovy/ast/tools/GeneralUtils.java    |  5 +++++
 .../transform/NamedVariantASTTransformation.java       | 15 ++++++++++++---
 .../groovy/transform/NamedVariantTransformTest.groovy  | 18 ++++++++++++++++++
 3 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
index e09e281..3713e0e 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -41,6 +41,7 @@ import org.codehaus.groovy.ast.expr.ClosureExpression;
 import org.codehaus.groovy.ast.expr.ConstantExpression;
 import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
 import org.codehaus.groovy.ast.expr.DeclarationExpression;
+import org.codehaus.groovy.ast.expr.ElvisOperatorExpression;
 import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.FieldExpression;
 import org.codehaus.groovy.ast.expr.LambdaExpression;
@@ -354,6 +355,10 @@ public class GeneralUtils {
         return Optional.ofNullable((ConstantExpression) getDefaultValueForPrimitive(type)).orElse(nullX());
     }
 
+    public static ElvisOperatorExpression elvisX(final Expression base, final Expression otherwise) {
+        return new ElvisOperatorExpression(base, otherwise);
+    }
+
     public static MapEntryExpression entryX(final Expression key, final Expression value) {
         return new MapEntryExpression(key, value);
     }
diff --git a/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java
index 87f8836..f13fca7 100644
--- a/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/NamedVariantASTTransformation.java
@@ -32,6 +32,8 @@ import org.codehaus.groovy.ast.PropertyNode;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.MapEntryExpression;
+import org.codehaus.groovy.ast.expr.PropertyExpression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.AssertStatement;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
 import org.codehaus.groovy.ast.stmt.ForStatement;
@@ -63,6 +65,7 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.defaultValueX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.elvisX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.entryX;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.getAllProperties;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.list2args;
@@ -124,7 +127,9 @@ public class NamedVariantASTTransformation extends AbstractASTTransformation {
                 } else if (AnnotatedNodeUtils.hasAnnotation(fromParam, NAMED_DELEGATE_TYPE)) {
                     if (!processDelegateParam(mNode, mapParam, args, propNames, fromParam, coerce)) return;
                 } else {
-                    args.addExpression(asType(varX(fromParam), fromParam.getType(), coerce));
+                    VariableExpression arg = varX(fromParam);
+                    Expression argOrDefault = fromParam.hasInitialExpression() ? elvisX(arg, fromParam.getDefaultValue()) : arg;
+                    args.addExpression(asType(argOrDefault, fromParam.getType(), coerce));
                     if (hasDuplicates(mNode, propNames, fromParam.getName())) return;
                     genParams.add(fromParam);
                 }
@@ -142,7 +147,9 @@ public class NamedVariantASTTransformation extends AbstractASTTransformation {
         namedParam.addMember("type", classX(fromParam.getType()));
         namedParam.addMember("required", constX(required, true));
         mapParam.addAnnotation(namedParam);
-        args.addExpression(asType(propX(varX(mapParam), name), fromParam.getType(), coerce));
+        PropertyExpression arg = propX(varX(mapParam), name);
+        Expression argOrDefault = fromParam.hasInitialExpression() ? elvisX(arg, fromParam.getDefaultValue()) : arg;
+        args.addExpression(asType(argOrDefault, fromParam.getType(), coerce));
         return true;
     }
 
@@ -167,7 +174,9 @@ public class NamedVariantASTTransformation extends AbstractASTTransformation {
             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"))));
         }
-        args.addExpression(asType(propX(varX(mapParam), name), fromParam.getType(), coerce));
+        PropertyExpression arg = propX(varX(mapParam), name);
+        Expression argOrDefault = fromParam.hasInitialExpression() ? elvisX(arg, fromParam.getDefaultValue()) : arg;
+        args.addExpression(asType(argOrDefault, fromParam.getType(), coerce));
         mapParam.addAnnotation(namedParam);
         fromParam.getAnnotations().remove(namedParam);
         return true;
diff --git a/src/test/org/codehaus/groovy/transform/NamedVariantTransformTest.groovy b/src/test/org/codehaus/groovy/transform/NamedVariantTransformTest.groovy
index 198f951..edb22d6 100644
--- a/src/test/org/codehaus/groovy/transform/NamedVariantTransformTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/NamedVariantTransformTest.groovy
@@ -187,6 +187,24 @@ final class NamedVariantTransformTest {
         '''
     }
 
+    @Test // GROOVY-GROOVY-10261
+    void testNamedDelegateWithDefaultValues() {
+        assertScript '''
+            import groovy.transform.*
+            import java.awt.Color
+
+            @NamedVariant
+            Color makeColor(int r=10, int g=20, int b=30) {
+                new Color(r, g, b)
+            }
+
+            assert makeColor(r: 128, g: 128, b: 5).toString() == 'java.awt.Color[r=128,g=128,b=5]'
+            assert makeColor(r: 128, g: 128).toString() == 'java.awt.Color[r=128,g=128,b=30]'
+            assert makeColor(r: 128).toString() == 'java.awt.Color[r=128,g=20,b=30]'
+            assert makeColor().toString() == 'java.awt.Color[r=10,g=20,b=30]'
+        '''
+    }
+
     @Test // GROOVY-9183
     void testNamedDelegateWithPropertyDefaults() {
         assertScript '''