You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2016/08/29 12:59:47 UTC
groovy git commit: GROOVY-7920: Simple getAt example produces a BUG
exception (closes #399)
Repository: groovy
Updated Branches:
refs/heads/master 680bd4428 -> e0b36ebc9
GROOVY-7920: Simple getAt example produces a BUG exception (closes #399)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/e0b36ebc
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/e0b36ebc
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/e0b36ebc
Branch: refs/heads/master
Commit: e0b36ebc910cd01a05a5c9ecf5e569b26e891874
Parents: 680bd44
Author: paulk <pa...@asert.com.au>
Authored: Sat Aug 27 14:37:35 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Mon Aug 29 22:59:07 2016 +1000
----------------------------------------------------------------------
.../asm/sc/StaticTypesCallSiteWriter.java | 30 +++++++++-
src/test/groovy/bugs/Groovy7920Bug.groovy | 58 ++++++++++++++++++++
2 files changed, 85 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/e0b36ebc/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
index dd5a913..e955efc 100644
--- a/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+++ b/src/main/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
@@ -662,11 +662,20 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
ClassNode current = rType;
MethodNode getAtNode = null;
while (current!=null && getAtNode==null) {
- getAtNode = current.getMethod("getAt", new Parameter[]{new Parameter(aType, "index")});
+ getAtNode = current.getDeclaredMethod("getAt", new Parameter[]{new Parameter(aType, "index")});
+ if (getAtNode == null) {
+ getAtNode = getCompatibleMethod(current, "getAt", aType);
+ }
if (getAtNode==null && isPrimitiveType(aType)) {
- getAtNode = current.getMethod("getAt", new Parameter[]{new Parameter(getWrapper(aType), "index")});
+ getAtNode = current.getDeclaredMethod("getAt", new Parameter[]{new Parameter(getWrapper(aType), "index")});
+ if (getAtNode == null) {
+ getAtNode = getCompatibleMethod(current, "getAt", getWrapper(aType));
+ }
} else if (getAtNode==null && aType.isDerivedFrom(Number_TYPE)) {
- getAtNode = current.getMethod("getAt", new Parameter[]{new Parameter(getUnwrapper(aType), "index")});
+ getAtNode = current.getDeclaredMethod("getAt", new Parameter[]{new Parameter(getUnwrapper(aType), "index")});
+ if (getAtNode == null) {
+ getAtNode = getCompatibleMethod(current, "getAt", getUnwrapper(aType));
+ }
}
current = current.getSuperClass();
}
@@ -726,6 +735,21 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
return false;
}
+ private MethodNode getCompatibleMethod(ClassNode current, String getAt, ClassNode aType) {
+ // TODO this really should find "best" match or find all matches and complain about ambiguity if more than one
+ // TODO handle getAt with more than one parameter
+ // TODO handle default getAt methods on Java 8 interfaces
+ for (MethodNode methodNode : current.getDeclaredMethods("getAt")) {
+ if (methodNode.getParameters().length == 1) {
+ ClassNode paramType = methodNode.getParameters()[0].getType();
+ if (aType.isDerivedFrom(paramType) || aType.declaresInterface(paramType)) {
+ return methodNode;
+ }
+ }
+ }
+ return null;
+ }
+
private void writeArrayGet(final Expression receiver, final Expression arguments, final ClassNode rType, final ClassNode aType) {
OperandStack operandStack = controller.getOperandStack();
int m1 = operandStack.getStackLength();
http://git-wip-us.apache.org/repos/asf/groovy/blob/e0b36ebc/src/test/groovy/bugs/Groovy7920Bug.groovy
----------------------------------------------------------------------
diff --git a/src/test/groovy/bugs/Groovy7920Bug.groovy b/src/test/groovy/bugs/Groovy7920Bug.groovy
new file mode 100644
index 0000000..f59a63f
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy7920Bug.groovy
@@ -0,0 +1,58 @@
+/*
+ * 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 Groovy7920Bug extends GroovyTestCase {
+ void testGetAtViaInterface() {
+ assertScript '''
+ interface Foo {}
+ class Bar implements Foo {}
+ @groovy.transform.CompileStatic
+ class TestGroovy {
+ static void test() { assert new TestGroovy()[new Bar()] == 42 }
+ def getAt(Foo x) { 42 }
+ }
+ TestGroovy.test()
+ '''
+ }
+
+ void testGetAtViaSuper() {
+ assertScript '''
+ class Foo {}
+ class Bar extends Foo {}
+ @groovy.transform.CompileStatic
+ class TestGroovy {
+ static void test() { assert new TestGroovy()[new Bar()] == 42 }
+ def getAt(Foo x) { 42 }
+ }
+ TestGroovy.test()
+ '''
+ }
+
+ void testGetAtNonNumeric() {
+ assertScript '''
+ @groovy.transform.CompileStatic
+ class TestGroovy {
+ static void test() { assert new TestGroovy()[3] == 42 }
+ def getAt(def x) { 42 }
+ }
+ TestGroovy.test()
+ '''
+ }
+}