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 2021/04/12 06:04:08 UTC
[groovy] 02/26: GROOVY-9649: Rework range creation to also allow
left- and full-open ranges
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch groovy9649
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 9b36007010305a133886c9dc9cd932985dc78b87
Author: Esko Toivonen <es...@tuni.fi>
AuthorDate: Tue Mar 30 11:12:26 2021 +0300
GROOVY-9649: Rework range creation to also allow left- and full-open ranges
This commit also adds a new parameter to MethodCaller which is used in
AsmClassGenerator to access the createRange method. This new parameter is needed
because the three-parameter version has to be left in for backwards
compatibility, and without the additional parameter in MethodCaller the wrong
method would be found.
---
.../groovy/classgen/AsmClassGenerator.java | 9 ++++---
.../codehaus/groovy/classgen/asm/MethodCaller.java | 29 ++++++++++++++++++----
.../org/codehaus/groovy/runtime/InvokerHelper.java | 9 +++++--
.../groovy/runtime/ScriptBytecodeAdapter.java | 8 +++++-
4 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index bfbd856..be5047d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -216,7 +216,9 @@ public class AsmClassGenerator extends ClassGenerator {
// type conversions
private static final MethodCaller createMapMethod = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "createMap");
private static final MethodCaller createListMethod = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "createList");
- private static final MethodCaller createRangeMethod = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "createRange");
+ // The 3-parameter version of createRange is kept in for backwards compatibility, so we need to specify the
+ // parameter count here
+ private static final MethodCaller createRangeMethod = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "createRange", 4);
private static final MethodCaller createPojoWrapperMethod = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "createPojoWrapper");
private static final MethodCaller createGroovyObjectWrapperMethod = MethodCaller.newStatic(ScriptBytecodeAdapter.class, "createGroovyObjectWrapper");
@@ -1526,10 +1528,11 @@ public class AsmClassGenerator extends ClassGenerator {
operandStack.box();
expression.getTo().visit(this);
operandStack.box();
- operandStack.pushBool(expression.isInclusive());
+ operandStack.pushBool(expression.isExclusiveLeft());
+ operandStack.pushBool(expression.isExclusiveRight());
createRangeMethod.call(controller.getMethodVisitor());
- operandStack.replace(ClassHelper.RANGE_TYPE, 3);
+ operandStack.replace(ClassHelper.RANGE_TYPE, 4);
}
@Override
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/MethodCaller.java b/src/main/java/org/codehaus/groovy/classgen/asm/MethodCaller.java
index 91a5988..faf3390 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/MethodCaller.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/MethodCaller.java
@@ -38,11 +38,17 @@ public class MethodCaller {
private String name;
private Class theClass;
private String methodDescriptor;
+ private int parameterCount;
+ private static final int ANY_PARAMETER_COUNT = -1;
public static MethodCaller newStatic(Class theClass, String name) {
return new MethodCaller(INVOKESTATIC, theClass, name);
}
+ public static MethodCaller newStatic(Class theClass, String name, int parameterCount) {
+ return new MethodCaller(INVOKESTATIC, theClass, name, parameterCount);
+ }
+
public static MethodCaller newInterface(Class theClass, String name) {
return new MethodCaller(INVOKEINTERFACE, theClass, name);
}
@@ -57,11 +63,15 @@ public class MethodCaller {
protected MethodCaller() {}
public MethodCaller(int opcode, Class theClass, String name) {
+ this(opcode, theClass, name, ANY_PARAMETER_COUNT);
+ }
+
+ public MethodCaller(int opcode, Class theClass, String name, int parameterCount) {
this.opcode = opcode;
this.internalName = Type.getInternalName(theClass);
this.theClass = theClass;
this.name = name;
-
+ this.parameterCount = parameterCount;
}
public void call(MethodVisitor methodVisitor) {
@@ -78,11 +88,20 @@ public class MethodCaller {
protected Method getMethod() {
Method[] methods = theClass.getMethods();
- for (Method method : methods) {
- if (method.getName().equals(name)) {
- return method;
+ if (parameterCount != ANY_PARAMETER_COUNT) {
+ for (Method method : methods) {
+ if (method.getName().equals(name) && method.getParameterCount() == parameterCount) {
+ return method;
+ }
+ }
+ } else {
+ for (Method method : methods) {
+ if (method.getName().equals(name)) {
+ return method;
+ }
}
}
- throw new ClassGeneratorException("Could not find method: " + name + " on class: " + theClass);
+ throw new ClassGeneratorException("Could not find method: " + name +
+ (parameterCount >= 0 ? " with parameter count " + parameterCount : "") + " on class: " + theClass);
}
}
diff --git a/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java b/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java
index 82a8868..6d64276 100644
--- a/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java
+++ b/src/main/java/org/codehaus/groovy/runtime/InvokerHelper.java
@@ -933,9 +933,9 @@ public class InvokerHelper {
return toArrayString(arguments, false, maxSize, safe);
}
- public static List createRange(Object from, Object to, boolean inclusive) {
+ public static List createRange(Object from, Object to, boolean exclusiveLeft, boolean exclusiveRight) {
try {
- return ScriptBytecodeAdapter.createRange(from, to, inclusive);
+ return ScriptBytecodeAdapter.createRange(from, to, exclusiveLeft, exclusiveRight);
} catch (RuntimeException | Error re) {
throw re;
} catch (Throwable t) {
@@ -943,6 +943,11 @@ public class InvokerHelper {
}
}
+ // Kept in for backwards compatibility
+ public static List createRange(Object from, Object to, boolean inclusive) {
+ return createRange(from, to, false, !inclusive);
+ }
+
public static Object bitwiseNegate(Object value) {
if (value instanceof Integer) {
Integer number = (Integer) value;
diff --git a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
index 69cd50f..e02bc62 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ScriptBytecodeAdapter.java
@@ -635,7 +635,8 @@ public class ScriptBytecodeAdapter {
return InvokerHelper.createMap(values);
}
- public static List createRange(Object from, Object to, boolean inclusive) throws Throwable {
+ public static List createRange(Object from, Object to, boolean exclusiveLeft, boolean exclusiveRight) throws Throwable {
+ boolean inclusive = !exclusiveRight;
if (from instanceof Integer && to instanceof Integer) {
int ifrom = (Integer) from;
int ito = (Integer) to;
@@ -660,6 +661,11 @@ public class ScriptBytecodeAdapter {
return new ObjectRange((Comparable) from, (Comparable) to);
}
+ // Kept in for backwards compatibility
+ public static List createRange(Object from, Object to, boolean inclusive) throws Throwable {
+ return createRange(from, to, false, !inclusive);
+ }
+
@SuppressWarnings("unchecked")
private static <T extends Number & Comparable> T comparableNumber(Number n) {
return (T) n;