You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/09/10 19:12:16 UTC

[groovy] branch master updated: GROOVY-10094: STC: check the compatibility of method default argument(s)

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

emilles 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 c4b73b1  GROOVY-10094: STC: check the compatibility of method default argument(s)
c4b73b1 is described below

commit c4b73b1a6598123f15c00d93c7a6d0d303eda09a
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Fri Sep 10 13:59:32 2021 -0500

    GROOVY-10094: STC: check the compatibility of method default argument(s)
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 15 +++++
 src/test/groovy/bugs/Groovy10094.groovy            | 67 ++++++++++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 93f148c..1f2bc54 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -2600,6 +2600,21 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
     protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
         typeCheckingContext.pushEnclosingMethod(node);
         super.visitConstructorOrMethod(node, isConstructor);
+        if (node.hasDefaultValue()) {
+            for (Parameter parameter : node.getParameters()) {
+                if (!parameter.hasInitialExpression()) continue;
+                // GROOVY-10094: visit param default argument expression
+                visitInitialExpression(parameter.getInitialExpression(), varX(parameter), parameter);
+                // GROOVY-10104: remove direct target setting to prevent errors
+                parameter.getInitialExpression().visit(new CodeVisitorSupport() {
+                    @Override
+                    public void visitMethodCallExpression(final MethodCallExpression mce) {
+                        super.visitMethodCallExpression(mce);
+                        mce.setMethodTarget(null);
+                    }
+                });
+            }
+        }
         if (!isConstructor) {
             returnAdder.visitMethod(node); // GROOVY-7753: we cannot count these auto-generated return statements, see `typeCheckingContext.pushEnclosingReturnStatement`
         }
diff --git a/src/test/groovy/bugs/Groovy10094.groovy b/src/test/groovy/bugs/Groovy10094.groovy
new file mode 100644
index 0000000..fb32df9
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy10094.groovy
@@ -0,0 +1,67 @@
+/*
+ *  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 groovy.bugs
+
+import org.junit.Test
+
+import static groovy.test.GroovyAssert.shouldFail
+
+final class Groovy10094 {
+
+    @Test
+    void testMethodDefaultArgumentSTC() {
+        def err = shouldFail '''
+            @groovy.transform.TypeChecked
+            class C {
+                int m(int i = 'error') {
+                    return i
+                }
+            }
+        '''
+
+        assert err =~ /Cannot assign value of type java.lang.String to variable of type int/
+    }
+
+    @Test
+    void testClosureDefaultArgumentSTC() {
+        def err = shouldFail '''
+            @groovy.transform.TypeChecked
+            class C {
+                def c = { int i = 'error' ->
+                    return i
+                }
+            }
+        '''
+
+        assert err =~ /Cannot assign value of type java.lang.String to variable of type int/
+    }
+
+    @Test
+    void testConstructorDefaultArgumentSTC() {
+        def err = shouldFail '''
+            @groovy.transform.TypeChecked
+            class C {
+                C(int i = 'error') {
+                }
+            }
+        '''
+
+        assert err =~ /Cannot assign value of type java.lang.String to variable of type int/
+    }
+}