This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_4_0_X by this push:
new 1cd13fc14a Revert "GROOVY-10381: No compiler error for class that
implements interfaces with duplicated default methods"
1cd13fc14a is described below
commit 1cd13fc14a10ee1b4d66be21e06366932847baa6
Author: Daniel Sun <[email protected]>
AuthorDate: Tue Nov 26 22:48:45 2024 +0800
Revert "GROOVY-10381: No compiler error for class that implements
interfaces with duplicated default methods"
This reverts commit 9ce26b0eb397674f7391163794d4167254153a5b.
---
.../org/codehaus/groovy/classgen/Verifier.java | 30 ----
src/test/groovy/bugs/Groovy10381.groovy | 199 ---------------------
2 files changed, 229 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 3b9b2af50f..df5de6bb6b 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -236,7 +236,6 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
}
checkForDuplicateInterfaces(node);
- checkForDuplicateDefaultMethods(node);
if (node.isInterface() || Traits.isTrait(node)) {
// interfaces have no constructors but this expects one,
@@ -277,35 +276,6 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
checkFinalVariables(node);
}
- private static void checkForDuplicateDefaultMethods(ClassNode node) {
- if (node.getInterfaces().length < 2) return;
-
- Map<String, MethodNode> defaultMethods = new HashMap<>(8);
- node.getAllInterfaces().stream()
- .flatMap(i -> i.getAllDeclaredMethods().stream())
- .filter(MethodNode::isDefault)
- .forEach(m -> {
- String signature = methodDescriptorWithoutReturnType(m);
- MethodNode existing = defaultMethods.get(signature);
- if (existing == null) {
- defaultMethods.put(signature, m);
- return;
- }
-
- ClassNode existingDeclaringClass =
existing.getDeclaringClass();
- ClassNode currentDeclaringClass = m.getDeclaringClass();
- if (!(existingDeclaringClass.equals(currentDeclaringClass)
- ||
existingDeclaringClass.implementsInterface(currentDeclaringClass)
- ||
currentDeclaringClass.implementsInterface(existingDeclaringClass))) {
- throw new RuntimeParserException(
- (node.isInterface() ? "interface" : "class") +
" " + node.getName()
- + " inherits unrelated defaults for "
+ m.getTypeDescriptor()
- + " from types " +
existingDeclaringClass.getName()
- + " and " +
currentDeclaringClass.getName(), sourceOf(m));
- }
- });
- }
-
private static final String[] INVALID_COMPONENTS = {"clone", "finalize",
"getClass", "hashCode", "notify", "notifyAll", "toString", "wait"};
private static void detectInvalidRecordComponentNames(final ClassNode
node) {
diff --git a/src/test/groovy/bugs/Groovy10381.groovy
b/src/test/groovy/bugs/Groovy10381.groovy
deleted file mode 100644
index a49867a722..0000000000
--- a/src/test/groovy/bugs/Groovy10381.groovy
+++ /dev/null
@@ -1,199 +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 org.codehaus.groovy.control.CompilerConfiguration
-import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
-import org.junit.Test
-
-import static groovy.test.GroovyAssert.shouldFail
-
-final class Groovy10381 {
- @Test
- void testDuplicateDefaultMethodsFromGroovyClasses_implements1() {
- def err = shouldFail '''
- interface A {
- default void m(String n) {}
- }
- interface B {
- default void m(String n) {}
- }
- class C implements A, B {
- void test() {
- m('Hi')
- }
- }
- '''
- assert err =~ /class C inherits unrelated defaults for void
m\(java.lang.String\) from types A and B/
- }
-
- @Test
- void testDuplicateDefaultMethodsFromGroovyClasses_implements2() {
- def err = shouldFail '''
- interface BaseA {
- default void m(String n) {}
- }
- interface A extends BaseA {
- }
- interface BaseB {
- default void m(String n) {}
- }
- interface B extends BaseB {
- }
- class C implements A, B {
- void test() {
- m('Hi')
- }
- }
- '''
- assert err =~ /class C inherits unrelated defaults for void
m\(java.lang.String\) from types BaseA and BaseB/
- }
-
- @Test
- void testDuplicateDefaultMethodsFromGroovyClasses_override() {
- def err = shouldFail '''
- interface BaseA {
- default void m(String n) {}
- }
- interface A extends BaseA {
- @Override
- default void m(String n) {}
- }
- interface BaseB {
- default void m(String n) {}
- }
- interface B extends BaseB {
- @Override
- default void m(String n) {}
- }
- class C implements A, B {
- void test() {
- m('Hi')
- }
- }
- '''
- assert err =~ /class C inherits unrelated defaults for void
m\(java.lang.String\) from types A and B/
- }
-
- @Test
- void testDuplicateDefaultMethodsFromGroovyClasses_extends() {
- def err = shouldFail '''
- public interface A extends List {
- default void m(String n) {}
- }
- public interface B {
- default void m(String n) {}
- }
- interface C extends A, B {
- default void test() {
- m('Hi')
- }
- }
- '''
- assert err =~ /interface C inherits unrelated defaults for void
m\(java.lang.String\) from types A and B/
- }
-
- @Test
- void testDuplicateDefaultMethodsFromJavaClasses_implements() {
- def config = new CompilerConfiguration().tap {
- jointCompilationOptions = [memStub: true]
- targetDirectory = File.createTempDir()
- }
- File parentDir = File.createTempDir()
- try {
- def a = new File(parentDir, 'A.java')
- a.write '''
- public interface A {
- default void m(String n) {}
- }
- '''
-
- def b = new File(parentDir, 'B.java')
- b.write '''
- public interface B {
- default void m(String n) {}
- }
- '''
-
- def c = new File(parentDir, 'C.groovy')
- c.write '''
- class C implements A, B {
- void test() {
- m("test")
- }
- }
- '''
-
- def loader = new GroovyClassLoader(this.class.classLoader)
- def cu = new JavaAwareCompilationUnit(config, loader)
- cu.addSources(a, b, c)
- cu.compile()
- assert false
- } catch (Exception e) {
- assert e =~ /class C inherits unrelated defaults for m\(String\)
from types A and B/
- } finally {
- parentDir.deleteDir()
- config.targetDirectory.deleteDir()
- }
- }
-
- @Test
- void testDuplicateDefaultMethodsFromJavaClasses_extends() {
- def config = new CompilerConfiguration().tap {
- jointCompilationOptions = [memStub: true]
- targetDirectory = File.createTempDir()
- }
- File parentDir = File.createTempDir()
- try {
- def a = new File(parentDir, 'A.java')
- a.write '''
- public interface A extends java.util.List {
- default void m(String n) {}
- }
- '''
-
- def b = new File(parentDir, 'B.java')
- b.write '''
- public interface B {
- default void m(String n) {}
- }
- '''
-
- def c = new File(parentDir, 'C.groovy')
- c.write '''
- interface C extends A, B {
- default void test() {
- m("test")
- }
- }
- '''
-
- def loader = new GroovyClassLoader(this.class.classLoader)
- def cu = new JavaAwareCompilationUnit(config, loader)
- cu.addSources(a, b, c)
- cu.compile()
- assert false
- } catch (Exception e) {
- assert e =~ /interface C inherits unrelated defaults for
m\(String\) from types A and B/
- } finally {
- parentDir.deleteDir()
- config.targetDirectory.deleteDir()
- }
- }
-}