def case working
This commit is contained in:
parent
876f0a613e
commit
592042601f
|
@ -29,7 +29,6 @@ import java.lang.invoke.MethodHandle;
|
|||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -321,14 +320,26 @@ public final class Def {
|
|||
String call, Class<?>... captures) throws LambdaConversionException {
|
||||
final FunctionRef ref;
|
||||
if ("this".equals(type)) {
|
||||
// user written method
|
||||
Method interfaceMethod = clazz.struct.getFunctionalMethod();
|
||||
if (interfaceMethod == null) {
|
||||
throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " +
|
||||
"to [" + clazz.name + "], not a functional interface");
|
||||
}
|
||||
int arity = interfaceMethod.arguments.size();
|
||||
// user written method
|
||||
ref = null;
|
||||
int arity = interfaceMethod.arguments.size() + captures.length;
|
||||
final MethodHandle handle;
|
||||
try {
|
||||
MethodHandle accessor = lookup.findStaticGetter(lookup.lookupClass(),
|
||||
"handle$" + call + "$" + arity,
|
||||
MethodHandle.class);
|
||||
handle = (MethodHandle) accessor.invokeExact();
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
throw new IllegalArgumentException("Unknown call [" + call + "] with [" + arity + "] arguments.");
|
||||
} catch (Throwable t) {
|
||||
rethrow(t);
|
||||
throw new AssertionError();
|
||||
}
|
||||
ref = new FunctionRef(clazz, interfaceMethod, handle, captures);
|
||||
} else {
|
||||
// whitelist lookup
|
||||
ref = new FunctionRef(clazz, type, call, captures);
|
||||
|
|
|
@ -101,6 +101,27 @@ public class FunctionRef {
|
|||
samMethodType = impl.getMethodType().dropParameterTypes(0, captures.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new FunctionRef (low level).
|
||||
* <p>
|
||||
* This will <b>not</b> set implMethodASM. It is for runtime use only.
|
||||
*/
|
||||
public FunctionRef(Definition.Type expected, Definition.Method method, MethodHandle impl, Class<?>... captures) {
|
||||
// e.g. compareTo
|
||||
invokedName = method.name;
|
||||
// e.g. (Object)Comparator
|
||||
invokedType = MethodType.methodType(expected.clazz, captures);
|
||||
// e.g. (Object,Object)int
|
||||
interfaceMethodType = method.getMethodType().dropParameterTypes(0, 1);
|
||||
|
||||
implMethod = impl;
|
||||
|
||||
implMethodASM = null;
|
||||
|
||||
// remove any prepended captured arguments for the 'natural' signature.
|
||||
samMethodType = impl.type().dropParameterTypes(0, captures.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up {@code type::call} from the whitelist, and returns a matching method.
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.objectweb.asm.Type;
|
|||
import static org.elasticsearch.painless.WriterConstants.LAMBDA_BOOTSTRAP_HANDLE;
|
||||
|
||||
import java.lang.invoke.LambdaMetafactory;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
/**
|
||||
* Represents a function reference.
|
||||
|
|
|
@ -114,7 +114,6 @@ public class FunctionRefTests extends ScriptTestCase {
|
|||
"List l = new ArrayList(); l.add(2); l.add(1); l.sort(this::mycompare); return l.get(0);"));
|
||||
}
|
||||
|
||||
@AwaitsFix(bugUrl = "working on it")
|
||||
public void testOwnStaticMethodReferenceDef() {
|
||||
assertEquals(2, exec("int mycompare(int i, int j) { j - i } " +
|
||||
"def l = new ArrayList(); l.add(2); l.add(1); l.sort(this::mycompare); return l.get(0);"));
|
||||
|
|
Loading…
Reference in New Issue