Repository: groovy
Updated Branches:
  refs/heads/master 14266ad5b -> f5a161f6b


GROOVY-7937: CLONE - same linkedlist code different behavior between groovy and 
java (fix priority of DGM methods vs actual methods on an object) (closes #418)


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/f5a161f6
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/f5a161f6
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/f5a161f6

Branch: refs/heads/master
Commit: f5a161f6b0c7d55561ffb61386482d0986e72987
Parents: 14266ad
Author: paulk <pa...@asert.com.au>
Authored: Tue Sep 13 16:54:51 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Sat Sep 17 07:48:12 2016 +1000

----------------------------------------------------------------------
 src/main/groovy/lang/MetaClassImpl.java   | 23 +++++++++++++---
 src/test/groovy/bugs/Groovy7937Bug.groovy | 36 ++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/f5a161f6/src/main/groovy/lang/MetaClassImpl.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/lang/MetaClassImpl.java 
b/src/main/groovy/lang/MetaClassImpl.java
index 91ddf9a..41a91d9 100644
--- a/src/main/groovy/lang/MetaClassImpl.java
+++ b/src/main/groovy/lang/MetaClassImpl.java
@@ -94,6 +94,7 @@ import java.util.concurrent.ConcurrentMap;
 
 import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.isDefaultVisibility;
+import static org.codehaus.groovy.reflection.ReflectionCache.isAssignableFrom;
 
 /**
  * Allows methods to be dynamically added to existing classes at runtime
@@ -625,10 +626,26 @@ public class MetaClassImpl implements MetaClass, 
MutableMetaClass {
         for (CachedClass cls : interfaces) {
             MetaMethod methods[] = getNewMetaMethods(cls);
             for (MetaMethod method : methods) {
-                if (!newGroovyMethodsSet.contains(method)) {
-                    newGroovyMethodsSet.add(method);
+                boolean skip = false;
+                // skip DGM methods on an interface if the class already has 
the method
+                // but don't skip for GroovyObject-related methods as it 
breaks things :-(
+                if (method instanceof GeneratedMetaMethod && 
!isAssignableFrom(GroovyObject.class, 
method.getDeclaringClass().getTheClass())) {
+                    for (Method m : theClass.getMethods()) {
+                        if (method.getName().equals(m.getName())
+                                // below not true for DGM#push and also 
co-variant return scenarios
+                                //&& 
method.getReturnType().equals(m.getReturnType())
+                                && 
MetaMethod.equal(method.getParameterTypes(), m.getParameterTypes())) {
+                            skip = true;
+                            break;
+                        }
+                    }
+                }
+                if (!skip) {
+                    if (!newGroovyMethodsSet.contains(method)) {
+                        newGroovyMethodsSet.add(method);
+                    }
+                    addMetaMethodToIndex(method, mainClassMethodHeader);
                 }
-                addMetaMethodToIndex(method, mainClassMethodHeader);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/groovy/blob/f5a161f6/src/test/groovy/bugs/Groovy7937Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7937Bug.groovy 
b/src/test/groovy/bugs/Groovy7937Bug.groovy
new file mode 100644
index 0000000..9b2f2f4
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy7937Bug.groovy
@@ -0,0 +1,36 @@
+/*
+ *  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
+
+class Groovy7937Bug extends GroovyTestCase {
+    void 
testMethodsWithinAnInstanceShouldBeChosenAheadOfDGMMethodsOnAnInterface() {
+        assertScript """
+            class MyList extends LinkedList<String> {
+                MyList(Collection c) { super(c) }
+                String pop() {
+                    'foo'
+                }
+            }
+            MyList stack1 = new MyList(1..3)
+            assert stack1.pop() == 'foo'
+            def stack2 = 1..3 as LinkedList
+            assert stack2.pop() == 1
+        """
+    }
+}
\ No newline at end of file

Reply via email to