You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/06/29 14:22:13 UTC

[groovy] branch master updated: GROOVY-9170: exclude non-interface methods from methods map

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

sunlan 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 3d03e2f  GROOVY-9170: exclude non-interface methods from methods map
3d03e2f is described below

commit 3d03e2f4b31d7514a76f918dc6eb3308f599a3c1
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Jun 11 10:45:18 2019 -0500

    GROOVY-9170: exclude non-interface methods from methods map
---
 .../apache/groovy/ast/tools/ClassNodeUtils.java    | 28 +++++++---------
 src/test/groovy/bugs/Groovy9170.groovy             | 37 ++++++++++++++++++++++
 2 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
index 0d61ea5..ffb6f70 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
@@ -151,39 +151,35 @@ public class ClassNodeUtils {
     }
 
     /**
-     * Add in methods from all interfaces. Existing entries in the methods map take precedence.
-     * Methods from interfaces visited early take precedence over later ones.
+     * Adds methods from all interfaces. Existing entries in the methods map
+     * take precedence. Methods from interfaces visited early take precedence
+     * over later ones.
      *
      * @param cNode The ClassNode
      * @param methodsMap A map of existing methods to alter
      */
     public static void addDeclaredMethodsFromInterfaces(ClassNode cNode, Map<String, MethodNode> methodsMap) {
-        // add in unimplemented abstract methods from the interfaces
         for (ClassNode iface : cNode.getInterfaces()) {
-            Map<String, MethodNode> ifaceMethodsMap = iface.getDeclaredMethodsMap();
-            for (Map.Entry<String, MethodNode> entry : ifaceMethodsMap.entrySet()) {
-                String methSig = entry.getKey();
-                if (!methodsMap.containsKey(methSig)) {
-                    methodsMap.put(methSig, entry.getValue());
+            Map<String, MethodNode> declaredMethods = iface.getDeclaredMethodsMap();
+            for (Map.Entry<String, MethodNode> entry : declaredMethods.entrySet()) {
+                if (entry.getValue().getDeclaringClass().isInterface()) {
+                    methodsMap.putIfAbsent(entry.getKey(), entry.getValue());
                 }
             }
         }
     }
 
     /**
-     * Get methods from all interfaces.
-     * Methods from interfaces visited early will be overwritten by later ones.
+     * Gets methods from all interfaces. Methods from interfaces visited early
+     * take precedence over later ones.
      *
      * @param cNode The ClassNode
      * @return A map of methods
      */
     public static Map<String, MethodNode> getDeclaredMethodsFromInterfaces(ClassNode cNode) {
-        Map<String, MethodNode> result = new HashMap<String, MethodNode>();
-        ClassNode[] interfaces = cNode.getInterfaces();
-        for (ClassNode iface : interfaces) {
-            result.putAll(iface.getDeclaredMethodsMap());
-        }
-        return result;
+        Map<String, MethodNode> methodsMap = new HashMap<>();
+        addDeclaredMethodsFromInterfaces(cNode, methodsMap);
+        return methodsMap;
     }
 
     /**
diff --git a/src/test/groovy/bugs/Groovy9170.groovy b/src/test/groovy/bugs/Groovy9170.groovy
new file mode 100644
index 0000000..6ee0368
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9170.groovy
@@ -0,0 +1,37 @@
+/*
+ * 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 groovy.transform.CompileStatic
+
+@CompileStatic
+final class Groovy9170 extends GroovyTestCase {
+
+    void testOverrideJavaLangObjectClone() {
+        shouldFail CloneNotSupportedException, '''
+            class C implements Cloneable, Serializable {
+                @Override
+                protected Object clone() {
+                    throw new CloneNotSupportedException()
+                }
+            }
+            new C().clone()
+        '''
+    }
+}