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'
}