GROOVY-7879 Groovy calls wrong method if there is a static method on an interface
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/07680166 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/07680166 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/07680166 Branch: refs/heads/parrot Commit: 076801660c75a985180413d8a792bd03da386438 Parents: 17c4ac2 Author: Dmitrii Kahmitov <[email protected]> Authored: Wed Apr 5 09:49:54 2017 +0300 Committer: paulk <[email protected]> Committed: Fri Apr 21 13:14:43 2017 +1000 ---------------------------------------------------------------------- .../runtime/metaclass/MetaMethodIndex.java | 14 +++++-- .../runtime/methoddispatching/BarOne.java | 25 ++++++++++++ .../runtime/methoddispatching/BarThree.java | 25 ++++++++++++ .../runtime/methoddispatching/BarTwo.java | 25 ++++++++++++ .../runtime/methoddispatching/FooOne.java | 25 ++++++++++++ .../runtime/methoddispatching/FooThree.java | 33 +++++++++++++++ .../runtime/methoddispatching/FooTwo.java | 29 ++++++++++++++ .../StaticMethodOverloadTest.groovy | 42 ++++++++++++++++++++ 8 files changed, 214 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/main/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java b/src/main/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java index 0598f9a..c442e48 100644 --- a/src/main/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java +++ b/src/main/org/codehaus/groovy/runtime/metaclass/MetaMethodIndex.java @@ -315,7 +315,7 @@ public class MetaMethodIndex { Object oldListOrMethod = e.methodsForSuper; if (oldListOrMethod == null) return; - + if (oldListOrMethod instanceof FastArray) { FastArray oldList = (FastArray) oldListOrMethod; int len1 = oldList.size(); @@ -346,7 +346,7 @@ public class MetaMethodIndex { Object oldListOrMethod = from.methods; if (oldListOrMethod == null) return; - + if (oldListOrMethod instanceof FastArray) { FastArray oldList = (FastArray) oldListOrMethod; Entry e = null; @@ -381,7 +381,10 @@ public class MetaMethodIndex { return list; } else { if (match.isPrivate() - || (!isNonRealMethod(match) && match.getDeclaringClass().isInterface() && !method.getDeclaringClass().isInterface())) { + || (!isNonRealMethod(match) + && match.getDeclaringClass().isInterface() + && !method.getDeclaringClass().isInterface() + && !method.isStatic())) { // do not overwrite interface methods with instance methods // do not overwrite private methods // Note: private methods from parent classes are not shown here, @@ -413,7 +416,10 @@ public class MetaMethodIndex { MetaMethod match = (MetaMethod) list.get(found); if (match==method) return o; if (match.isPrivate() - || (!isNonRealMethod(match) && match.getDeclaringClass().isInterface() && !method.getDeclaringClass().isInterface())) { + || (!isNonRealMethod(match) + && match.getDeclaringClass().isInterface() + && !method.getDeclaringClass().isInterface() + && !method.isStatic())) { // do not overwrite interface methods with instance methods // do not overwrite private methods // Note: private methods from parent classes are not shown here, http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/test/org/codehaus/groovy/runtime/methoddispatching/BarOne.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/methoddispatching/BarOne.java b/src/test/org/codehaus/groovy/runtime/methoddispatching/BarOne.java new file mode 100644 index 0000000..56daeeb --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/methoddispatching/BarOne.java @@ -0,0 +1,25 @@ +/* + * 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 org.codehaus.groovy.runtime.methoddispatching; + +class BarOne implements FooOne { + static String foo() { + return "I'm Bar"; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/test/org/codehaus/groovy/runtime/methoddispatching/BarThree.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/methoddispatching/BarThree.java b/src/test/org/codehaus/groovy/runtime/methoddispatching/BarThree.java new file mode 100644 index 0000000..63686b3 --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/methoddispatching/BarThree.java @@ -0,0 +1,25 @@ +/* + * 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 org.codehaus.groovy.runtime.methoddispatching; + +class BarThree implements FooThree { + static String foo() { + return "I'm Bar"; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/test/org/codehaus/groovy/runtime/methoddispatching/BarTwo.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/methoddispatching/BarTwo.java b/src/test/org/codehaus/groovy/runtime/methoddispatching/BarTwo.java new file mode 100644 index 0000000..84a8f02 --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/methoddispatching/BarTwo.java @@ -0,0 +1,25 @@ +/* + * 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 org.codehaus.groovy.runtime.methoddispatching; + +class BarTwo implements FooTwo { + static String foo() { + return "I'm Bar"; + } +} http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/test/org/codehaus/groovy/runtime/methoddispatching/FooOne.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/methoddispatching/FooOne.java b/src/test/org/codehaus/groovy/runtime/methoddispatching/FooOne.java new file mode 100644 index 0000000..f1bac0f --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/methoddispatching/FooOne.java @@ -0,0 +1,25 @@ +/* + * 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 org.codehaus.groovy.runtime.methoddispatching; + +interface FooOne { + static String foo() { + return "I'm Foo"; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/test/org/codehaus/groovy/runtime/methoddispatching/FooThree.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/methoddispatching/FooThree.java b/src/test/org/codehaus/groovy/runtime/methoddispatching/FooThree.java new file mode 100644 index 0000000..9f897ea --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/methoddispatching/FooThree.java @@ -0,0 +1,33 @@ +/* + * 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 org.codehaus.groovy.runtime.methoddispatching; + +interface FooThree { + static String foo() { + return "I'm Foo"; + } + + static String foo(int num) { + return String.valueOf(num); + } + + static String foo(boolean bool) { + return String.valueOf(bool); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/test/org/codehaus/groovy/runtime/methoddispatching/FooTwo.java ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/methoddispatching/FooTwo.java b/src/test/org/codehaus/groovy/runtime/methoddispatching/FooTwo.java new file mode 100644 index 0000000..b7b315b --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/methoddispatching/FooTwo.java @@ -0,0 +1,29 @@ +/* + * 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 org.codehaus.groovy.runtime.methoddispatching; + +interface FooTwo { + static String foo() { + return "I'm Foo"; + } + + static String foo(int num) { + return String.valueOf(num); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/groovy/blob/07680166/src/test/org/codehaus/groovy/runtime/methoddispatching/StaticMethodOverloadTest.groovy ---------------------------------------------------------------------- diff --git a/src/test/org/codehaus/groovy/runtime/methoddispatching/StaticMethodOverloadTest.groovy b/src/test/org/codehaus/groovy/runtime/methoddispatching/StaticMethodOverloadTest.groovy new file mode 100644 index 0000000..2df115f --- /dev/null +++ b/src/test/org/codehaus/groovy/runtime/methoddispatching/StaticMethodOverloadTest.groovy @@ -0,0 +1,42 @@ +/* + * 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 org.codehaus.groovy.runtime.methoddispatching + +class StaticMethodOverloadTest extends GroovyTestCase { + void testOneStaticMethod() throws Exception { + assert FooOne.foo() == "I'm Foo" + assert BarOne.foo() == "I'm Bar" + } + + void testTwoStaticMethods() { + assert FooTwo.foo(42) == '42' + assert FooTwo.foo() == "I'm Foo" + assert BarTwo.foo(42) == '42' + assert BarTwo.foo() == "I'm Bar" + } + + void testMoreThanTwoStaticMethods() { + assert FooThree.foo(42) == '42' + assert FooThree.foo() == "I'm Foo" + assert FooThree.foo(true) == 'true' + assert BarThree.foo(42) == '42' + assert BarThree.foo() == "I'm Bar" + assert BarThree.foo(true) == 'true' + } +}
