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

not-in-ldap 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 4dd482ca1b GROOVY-5193: refactor checking
4dd482ca1b is described below

commit 4dd482ca1b369b5abd1839254bdc5b5f6cac33f6
Author: Eric Milles <[email protected]>
AuthorDate: Mon May 5 13:05:50 2025 -0500

    GROOVY-5193: refactor checking
---
 .../groovy/classgen/ClassCompletionVerifier.java   | 34 +++++++------
 src/test/groovy/bugs/Groovy5193.groovy             | 57 ++++++++++++++++++++++
 src/test/groovy/bugs/Groovy5193Bug.groovy          | 52 --------------------
 .../traitx/TraitASTTransformationTest.groovy       |  4 +-
 4 files changed, 78 insertions(+), 69 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java 
b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index 5b0e0d48f4..2414ba05f3 100644
--- a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -533,8 +533,10 @@ out:        for (ClassNode sc : superTypes) {
         inConstructor = false;
         inStaticConstructor = node.isStaticConstructor();
         checkAbstractDeclaration(node);
-        checkRepetitiveMethod(node);
-        checkOverloadingPrivateAndPublic(node);
+        if (!inStaticConstructor) {
+            checkRepetitiveMethod(node);
+            checkOverloadingPrivateAndPublic(node);
+        }
         checkMethodForIncorrectModifiers(node);
         checkGenericsUsage(node, node.getParameters());
         checkGenericsUsage(node, node.getReturnType());
@@ -586,26 +588,28 @@ out:        for (ClassNode sc : superTypes) {
     }
 
     private void checkOverloadingPrivateAndPublic(final MethodNode node) {
-        if (node.isStaticConstructor()) return;
-        boolean hasPrivate = node.isPrivate();
-        boolean hasPublic = node.isPublic();
-        for (MethodNode method : currentClass.getMethods(node.getName())) {
-            if (method == node) continue;
-            if (!method.getDeclaringClass().equals(node.getDeclaringClass())) 
continue;
-            if (method.isPublic() || method.isProtected()) {
-                hasPublic = true;
-            } else {
-                hasPrivate = true;
+        boolean mixed = false;
+        if (node.isPublic()) {
+            for (MethodNode mn : 
currentClass.getDeclaredMethods(node.getName())) {
+                if (mn != node && !(mn.isPublic() || mn.isProtected())) {
+                    mixed = true;
+                    break;
+                }
+            }
+        } else if (node.isPrivate()) {
+            for (MethodNode mn : 
currentClass.getDeclaredMethods(node.getName())) {
+                if (mn != node && (mn.isPublic() || mn.isProtected())) {
+                    mixed = true;
+                    break;
+                }
             }
-            if (hasPrivate && hasPublic) break;
         }
-        if (hasPrivate && hasPublic) {
+        if (mixed) { // GROOVY-5193
             addError("Mixing private and public/protected methods of the same 
name causes multimethods to be disabled and is forbidden to avoid surprising 
behaviour. Renaming the private methods will solve the problem.", node);
         }
     }
 
     private void checkRepetitiveMethod(final MethodNode node) {
-        if (node.isStaticConstructor()) return;
         for (MethodNode method : currentClass.getMethods(node.getName())) {
             if (method == node) continue;
             if (!method.getDeclaringClass().equals(node.getDeclaringClass())) 
continue;
diff --git a/src/test/groovy/bugs/Groovy5193.groovy 
b/src/test/groovy/bugs/Groovy5193.groovy
new file mode 100644
index 0000000000..d0284b5ae3
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy5193.groovy
@@ -0,0 +1,57 @@
+/*
+ *  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 bugs
+
+import org.codehaus.groovy.control.MultipleCompilationErrorsException
+import org.junit.jupiter.api.Test
+
+import static groovy.test.GroovyAssert.shouldFail
+
+final class Groovy5193 {
+
+    @Test
+    void testMixingMethodsWithPrivatePublicAccessInSameClass1() {
+        def err = shouldFail MultipleCompilationErrorsException, '''
+            class A5193 {
+                static main(args) {
+                }
+                public find(String id) {
+                }
+                private <T> T find(Class<T> type, String id, boolean 
suppressExceptions) {
+                }
+            }
+        '''
+        assert err.message.contains('Mixing private and public/protected 
methods of the same name causes multimethods to be disabled')
+    }
+
+    @Test
+    void testMixingMethodsWithPrivatePublicAccessInSameClass2() {
+        def err = shouldFail MultipleCompilationErrorsException, '''
+            class B5193 {
+                static main(args) {
+                }
+                public find(String id) {
+                }
+                private <T> T find(Class<T> type, String id, boolean 
suppressExceptions = true) {
+                }
+            }
+        '''
+        assert err.message.contains('Mixing private and public/protected 
methods of the same name causes multimethods to be disabled')
+    }
+}
diff --git a/src/test/groovy/bugs/Groovy5193Bug.groovy 
b/src/test/groovy/bugs/Groovy5193Bug.groovy
deleted file mode 100644
index 3dc07a3eae..0000000000
--- a/src/test/groovy/bugs/Groovy5193Bug.groovy
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  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 bugs
-
-import groovy.test.GroovyTestCase
-import org.codehaus.groovy.control.MultipleCompilationErrorsException
-
-class Groovy5193Bug extends GroovyTestCase {
-    void testMixingMethodsWithPrivatePublicAccessInSameClassV1() {
-        try{
-            assertScript """
-                class Repository5193V1 {
-                  def find(String id) {}
-                  private <T> T find(Class<T> type, String id, boolean 
suppressNotFoundExceptions) { }
-                }
-            """
-            fail("compilation should have failed saying that mixing private 
and public/protected methods of the same name causes multimethods to be 
disabled and is forbidden.")
-        } catch(MultipleCompilationErrorsException ex) {
-            assertTrue ex.message.contains("Mixing private and 
public/protected methods of the same name causes multimethods to be disabled 
and is forbidden")
-        }
-    }
-
-    void testMixingMethodsWithPrivatePublicAccessInSameClassV2() {
-        try{
-            assertScript """
-                class Repository5193V2 {
-                  def find(String id) {}
-                  private <T> T find(Class<T> type, String id, boolean 
suppressNotFoundExceptions = true) { }
-                }
-            """
-            fail("compilation should have failed saying that mixing private 
and public/protected methods of the same name causes multimethods to be 
disabled and is forbidden.")
-        } catch(MultipleCompilationErrorsException ex) {
-            assertTrue ex.message.contains("Mixing private and 
public/protected methods of the same name causes multimethods to be disabled 
and is forbidden")
-        }
-    }
-}
diff --git 
a/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
 
b/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
index d90290e21e..1f6e7b493f 100644
--- 
a/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
+++ 
b/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
@@ -1811,6 +1811,7 @@ final class TraitASTTransformationTest {
         """
     }
 
+    // GROOVY-5193
     @Test
     void testMixPrivatePublicMethodsOfSameName() {
         def err = shouldFail shell, '''
@@ -1822,8 +1823,7 @@ final class TraitASTTransformationTest {
             class C implements T {
             }
 
-            def c = new C()
-            assert c.foo() == 'SECRET'
+            assert new C().foo() == 'SECRET'
         '''
         assert err =~ 'Mixing private and public/protected methods of the same 
name causes multimethods to be disabled'
     }

Reply via email to