initial messy impl of painless method references
This commit is contained in:
parent
ad118eb1e5
commit
6dbf7ab1ea
|
@ -73,7 +73,7 @@ decltype
|
|||
;
|
||||
|
||||
funcref
|
||||
: TYPE REF ID
|
||||
: TYPE REF ( ID | NEW )
|
||||
;
|
||||
|
||||
declvar
|
||||
|
|
|
@ -22,6 +22,9 @@ package org.elasticsearch.painless;
|
|||
import org.elasticsearch.painless.Definition.Method;
|
||||
import org.elasticsearch.painless.Definition.RuntimeClass;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.LambdaConversionException;
|
||||
import java.lang.invoke.LambdaMetafactory;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup;
|
||||
|
@ -123,7 +126,52 @@ public final class Def {
|
|||
}
|
||||
|
||||
/**
|
||||
* Looks up handle for a dynamic method call.
|
||||
* Looks up method entry for a dynamic method call.
|
||||
* <p>
|
||||
* A dynamic method call for variable {@code x} of type {@code def} looks like:
|
||||
* {@code x.method(args...)}
|
||||
* <p>
|
||||
* This method traverses {@code recieverClass}'s class hierarchy (including interfaces)
|
||||
* until it finds a matching whitelisted method. If one is not found, it throws an exception.
|
||||
* Otherwise it returns the matching method.
|
||||
* <p>
|
||||
* @param receiverClass Class of the object to invoke the method on.
|
||||
* @param name Name of the method.
|
||||
* @param arity arity of method
|
||||
* @return matching method to invoke. never returns null.
|
||||
* @throws IllegalArgumentException if no matching whitelisted method was found.
|
||||
*/
|
||||
static Method lookupMethodInternal(Class<?> receiverClass, String name, int arity) {
|
||||
Definition.MethodKey key = new Definition.MethodKey(name, arity);
|
||||
// check whitelist for matching method
|
||||
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
|
||||
RuntimeClass struct = Definition.getRuntimeClass(clazz);
|
||||
|
||||
if (struct != null) {
|
||||
Method method = struct.methods.get(key);
|
||||
if (method != null) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
||||
for (Class<?> iface : clazz.getInterfaces()) {
|
||||
struct = Definition.getRuntimeClass(iface);
|
||||
|
||||
if (struct != null) {
|
||||
Method method = struct.methods.get(key);
|
||||
if (method != null) {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unable to find dynamic method [" + name + "] with [" + arity + "] arguments " +
|
||||
"for class [" + receiverClass.getCanonicalName() + "].");
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up handle for a dynamic method call, with lambda replacement
|
||||
* <p>
|
||||
* A dynamic method call for variable {@code x} of type {@code def} looks like:
|
||||
* {@code x.method(args...)}
|
||||
|
@ -134,41 +182,72 @@ public final class Def {
|
|||
* <p>
|
||||
* @param receiverClass Class of the object to invoke the method on.
|
||||
* @param name Name of the method.
|
||||
* @param type Callsite signature. Need not match exactly, except the number of parameters.
|
||||
* @param args args passed to callsite
|
||||
* @param recipe bitset marking functional parameters
|
||||
* @return pointer to matching method to invoke. never returns null.
|
||||
* @throws IllegalArgumentException if no matching whitelisted method was found.
|
||||
*/
|
||||
static MethodHandle lookupMethod(Class<?> receiverClass, String name, MethodType type) {
|
||||
// we don't consider receiver an argument/counting towards arity
|
||||
type = type.dropParameterTypes(0, 1);
|
||||
Definition.MethodKey key = new Definition.MethodKey(name, type.parameterCount());
|
||||
// check whitelist for matching method
|
||||
for (Class<?> clazz = receiverClass; clazz != null; clazz = clazz.getSuperclass()) {
|
||||
RuntimeClass struct = Definition.getRuntimeClass(clazz);
|
||||
static MethodHandle lookupMethod(Class<?> receiverClass, String name, Object args[], long recipe) {
|
||||
Method method = lookupMethodInternal(receiverClass, name, args.length - 1);
|
||||
MethodHandle handle = method.handle;
|
||||
MethodHandle filters[] = new MethodHandle[args.length];
|
||||
|
||||
if (struct != null) {
|
||||
Method method = struct.methods.get(key);
|
||||
if (method != null) {
|
||||
return method.handle;
|
||||
}
|
||||
}
|
||||
|
||||
for (final Class<?> iface : clazz.getInterfaces()) {
|
||||
struct = Definition.getRuntimeClass(iface);
|
||||
|
||||
if (struct != null) {
|
||||
Method method = struct.methods.get(key);
|
||||
if (method != null) {
|
||||
return method.handle;
|
||||
}
|
||||
if (recipe != 0) {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
// its a functional reference, replace the argument with an impl
|
||||
if ((recipe & (1L << (i - 1))) != 0) {
|
||||
filters[i] = lookupReference(method.arguments.get(i - 1).clazz, (String) args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no matching methods in whitelist found
|
||||
throw new IllegalArgumentException("Unable to find dynamic method [" + name + "] with signature [" + type + "] " +
|
||||
"for class [" + receiverClass.getCanonicalName() + "].");
|
||||
}
|
||||
handle = MethodHandles.filterArguments(handle, 0, filters);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
/** Returns a method handle to an implementation of clazz, given method reference signature */
|
||||
private static MethodHandle lookupReference(Class<?> clazz, String signature) {
|
||||
int separator = signature.indexOf('.');
|
||||
FunctionRef ref = new FunctionRef(clazz, signature.substring(0, separator), signature.substring(separator+1));
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup(); // XXX: no lookuping needed, we should pass this from DefBootstrap!
|
||||
final CallSite callSite;
|
||||
// XXX: clean all this up to use handles in FunctionRef, deal with ASM in EFunctionRef differently
|
||||
MethodType invokedType = MethodType.fromMethodDescriptorString(ref.invokedType.getDescriptor(), Def.class.getClassLoader());
|
||||
MethodType samMethodType = MethodType.fromMethodDescriptorString(ref.samMethodType.getDescriptor(), Def.class.getClassLoader());
|
||||
MethodType interfaceType = MethodType.fromMethodDescriptorString(ref.interfaceType.getDescriptor(), Def.class.getClassLoader());
|
||||
try {
|
||||
if (ref.interfaceType.equals(ref.samMethodType)) {
|
||||
callSite = LambdaMetafactory.altMetafactory(lookup,
|
||||
ref.invokedName,
|
||||
invokedType,
|
||||
samMethodType,
|
||||
ref.implMethodHandle,
|
||||
samMethodType,
|
||||
0);
|
||||
} else {
|
||||
callSite = LambdaMetafactory.altMetafactory(lookup,
|
||||
ref.invokedName,
|
||||
invokedType,
|
||||
samMethodType,
|
||||
ref.implMethodHandle,
|
||||
samMethodType,
|
||||
LambdaMetafactory.FLAG_BRIDGES,
|
||||
1,
|
||||
interfaceType);
|
||||
}
|
||||
} catch (LambdaConversionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
// create an implementation of the interface (instance)
|
||||
Object instance = callSite.dynamicInvoker().asType(MethodType.methodType(clazz)).invoke();
|
||||
// bind this instance as a constant replacement for the parameter
|
||||
return MethodHandles.dropArguments(MethodHandles.constant(clazz, instance), 0, Object.class);
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Looks up handle for a dynamic field getter (field load)
|
||||
|
|
|
@ -66,12 +66,16 @@ public final class DefBootstrap {
|
|||
|
||||
private final String name;
|
||||
private final int flavor;
|
||||
private final long recipe;
|
||||
int depth; // pkg-protected for testing
|
||||
|
||||
PIC(String name, MethodType type, int flavor) {
|
||||
PIC(String name, MethodType type, int flavor, long recipe) {
|
||||
super(type);
|
||||
this.name = name;
|
||||
this.flavor = flavor;
|
||||
this.recipe = recipe;
|
||||
assert recipe == 0 || flavor == METHOD_CALL;
|
||||
assert Long.bitCount(flavor) <= type.parameterCount();
|
||||
|
||||
final MethodHandle fallback = FALLBACK.bindTo(this)
|
||||
.asCollector(Object[].class, type.parameterCount())
|
||||
|
@ -91,10 +95,10 @@ public final class DefBootstrap {
|
|||
/**
|
||||
* Does a slow lookup against the whitelist.
|
||||
*/
|
||||
private static MethodHandle lookup(int flavor, Class<?> clazz, String name, MethodType type) {
|
||||
private static MethodHandle lookup(int flavor, Class<?> clazz, String name, Object[] args, long recipe) {
|
||||
switch(flavor) {
|
||||
case METHOD_CALL:
|
||||
return Def.lookupMethod(clazz, name, type);
|
||||
return Def.lookupMethod(clazz, name, args, recipe);
|
||||
case LOAD:
|
||||
return Def.lookupGetter(clazz, name);
|
||||
case STORE:
|
||||
|
@ -115,7 +119,7 @@ public final class DefBootstrap {
|
|||
final MethodType type = type();
|
||||
final Object receiver = args[0];
|
||||
final Class<?> receiverClass = receiver.getClass();
|
||||
final MethodHandle target = lookup(flavor, receiverClass, name, type).asType(type);
|
||||
final MethodHandle target = lookup(flavor, receiverClass, name, args, recipe).asType(type);
|
||||
|
||||
if (depth >= MAX_DEPTH) {
|
||||
// revert to a vtable call
|
||||
|
@ -157,8 +161,8 @@ public final class DefBootstrap {
|
|||
* <p>
|
||||
* see https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokedynamic
|
||||
*/
|
||||
public static CallSite bootstrap(Lookup lookup, String name, MethodType type, int flavor) {
|
||||
return new PIC(name, type, flavor);
|
||||
public static CallSite bootstrap(Lookup lookup, String name, MethodType type, int flavor, long recipe) {
|
||||
return new PIC(name, type, flavor, recipe);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.io.InputStreamReader;
|
|||
import java.io.LineNumberReader;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
@ -31,6 +32,8 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.PrimitiveIterator;
|
||||
import java.util.Spliterator;
|
||||
|
||||
/**
|
||||
* The entire API for Painless. Also used as a whitelist for checking for legal
|
||||
|
@ -171,21 +174,6 @@ public final class Definition {
|
|||
}
|
||||
}
|
||||
|
||||
public static final class Constructor {
|
||||
public final String name;
|
||||
public final Struct owner;
|
||||
public final List<Type> arguments;
|
||||
public final org.objectweb.asm.commons.Method method;
|
||||
|
||||
private Constructor(String name, Struct owner, List<Type> arguments,
|
||||
org.objectweb.asm.commons.Method method) {
|
||||
this.name = name;
|
||||
this.owner = owner;
|
||||
this.arguments = Collections.unmodifiableList(arguments);
|
||||
this.method = method;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Method {
|
||||
public final String name;
|
||||
public final Struct owner;
|
||||
|
@ -287,7 +275,7 @@ public final class Definition {
|
|||
public final Class<?> clazz;
|
||||
public final org.objectweb.asm.Type type;
|
||||
|
||||
public final Map<MethodKey, Constructor> constructors;
|
||||
public final Map<MethodKey, Method> constructors;
|
||||
public final Map<MethodKey, Method> staticMethods;
|
||||
public final Map<MethodKey, Method> methods;
|
||||
|
||||
|
@ -439,6 +427,18 @@ public final class Definition {
|
|||
for (Map.Entry<String,List<String>> clazz : hierarchy.entrySet()) {
|
||||
copyStruct(clazz.getKey(), clazz.getValue());
|
||||
}
|
||||
// if someone declares an interface type, its still an Object
|
||||
for (Map.Entry<String,Struct> clazz : structsMap.entrySet()) {
|
||||
String name = clazz.getKey();
|
||||
Class<?> javaPeer = clazz.getValue().clazz;
|
||||
if (javaPeer.isInterface()) {
|
||||
copyStruct(name, Collections.singletonList("Object"));
|
||||
} else if (name.equals("def") == false && name.equals("Object") == false && javaPeer.isPrimitive() == false) {
|
||||
// but otherwise, unless its a primitive type, it really should
|
||||
assert hierarchy.get(name) != null : "class '" + name + "' does not extend Object!";
|
||||
assert hierarchy.get(name).contains("Object") : "class '" + name + "' does not extend Object!";
|
||||
}
|
||||
}
|
||||
// precompute runtime classes
|
||||
for (Struct struct : structsMap.values()) {
|
||||
addRuntimeClass(struct);
|
||||
|
@ -573,7 +573,7 @@ public final class Definition {
|
|||
"Owner struct [" + struct + "] not defined for constructor [" + name + "].");
|
||||
}
|
||||
|
||||
if (!name.matches("^[_a-zA-Z][_a-zA-Z0-9]*$")) {
|
||||
if (!name.matches("<init>")) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid constructor name [" + name + "] with the struct [" + owner.name + "].");
|
||||
}
|
||||
|
@ -611,7 +611,18 @@ public final class Definition {
|
|||
}
|
||||
|
||||
final org.objectweb.asm.commons.Method asm = org.objectweb.asm.commons.Method.getMethod(reflect);
|
||||
final Constructor constructor = new Constructor(name, owner, Arrays.asList(args), asm);
|
||||
final Type returnType = getTypeInternal("void");
|
||||
final MethodHandle handle;
|
||||
|
||||
try {
|
||||
handle = MethodHandles.publicLookup().in(owner.clazz).unreflectConstructor(reflect);
|
||||
} catch (final IllegalAccessException exception) {
|
||||
throw new IllegalArgumentException("Constructor " +
|
||||
" not found for class [" + owner.clazz.getName() + "]" +
|
||||
" with arguments " + Arrays.toString(classes) + ".");
|
||||
}
|
||||
|
||||
final Method constructor = new Method(name, owner, returnType, Arrays.asList(args), asm, reflect.getModifiers(), handle);
|
||||
|
||||
owner.constructors.put(methodKey, constructor);
|
||||
}
|
||||
|
@ -653,7 +664,7 @@ public final class Definition {
|
|||
if (!elements[0].equals(className)) {
|
||||
throw new IllegalArgumentException("Constructors must return their own type");
|
||||
}
|
||||
addConstructorInternal(className, "new", args);
|
||||
addConstructorInternal(className, "<init>", args);
|
||||
} else {
|
||||
if (methodName.indexOf('/') >= 0) {
|
||||
String nameAndAlias[] = methodName.split("/");
|
||||
|
@ -720,7 +731,7 @@ public final class Definition {
|
|||
" method [" + name + "]" +
|
||||
" within the struct [" + owner.name + "].");
|
||||
}
|
||||
|
||||
|
||||
final org.objectweb.asm.commons.Method asm = org.objectweb.asm.commons.Method.getMethod(reflect);
|
||||
|
||||
MethodHandle handle;
|
||||
|
@ -821,11 +832,37 @@ public final class Definition {
|
|||
throw new ClassCastException("Child struct [" + child.name + "]" +
|
||||
" is not a super type of owner struct [" + owner.name + "] in copy.");
|
||||
}
|
||||
|
||||
|
||||
for (Map.Entry<MethodKey,Method> kvPair : child.methods.entrySet()) {
|
||||
MethodKey methodKey = kvPair.getKey();
|
||||
Method method = kvPair.getValue();
|
||||
if (owner.methods.get(methodKey) == null) {
|
||||
// sanity check, look for missing covariant/generic override
|
||||
if (owner.clazz.isInterface() && child.clazz == Object.class) {
|
||||
// ok
|
||||
} else if (child.clazz == Spliterator.OfPrimitive.class || child.clazz == PrimitiveIterator.class) {
|
||||
// ok, we rely on generics erasure for these (its guaranteed in the javadocs though!!!!)
|
||||
} else {
|
||||
try {
|
||||
Class<?> arguments[] = new Class<?>[method.arguments.size()];
|
||||
for (int i = 0; i < method.arguments.size(); i++) {
|
||||
arguments[i] = method.arguments.get(i).clazz;
|
||||
}
|
||||
java.lang.reflect.Method m = owner.clazz.getMethod(method.method.getName(), arguments);
|
||||
if (m.getReturnType() != method.rtn.clazz) {
|
||||
throw new IllegalStateException("missing covariant override for: " + m + " in " + owner.name);
|
||||
}
|
||||
if (m.isBridge() && !Modifier.isVolatile(method.modifiers)) {
|
||||
// its a bridge in the destination, but not in the source, but it might still be ok, check generics:
|
||||
java.lang.reflect.Method source = child.clazz.getMethod(method.method.getName(), arguments);
|
||||
if (!Arrays.equals(source.getGenericParameterTypes(), source.getParameterTypes())) {
|
||||
throw new IllegalStateException("missing generic override for: " + m + " in " + owner.name);
|
||||
}
|
||||
}
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new AssertionError(e);
|
||||
}
|
||||
}
|
||||
owner.methods.put(methodKey,
|
||||
new Method(method.name, owner, method.rtn, method.arguments, method.method, method.modifiers, method.handle));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch 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.elasticsearch.painless;
|
||||
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* computes "everything you need" to call LambdaMetaFactory, given an expected interface,
|
||||
* and reference class + method name
|
||||
*/
|
||||
public class FunctionRef {
|
||||
// XXX: this is a mess, because of ASM versus MethodHandle types
|
||||
// clean all this up, move reflection out of here into definition, etc etc
|
||||
public final String invokedName;
|
||||
public final Type invokedType;
|
||||
public final Handle implMethod;
|
||||
public final Type samMethodType;
|
||||
public final Type interfaceType;
|
||||
|
||||
public final MethodHandle implMethodHandle;
|
||||
|
||||
public FunctionRef(Class<?> expected, String type, String call) {
|
||||
boolean isCtorReference = "new".equals(call);
|
||||
// check its really a functional interface
|
||||
// for e.g. Comparable
|
||||
java.lang.reflect.Method method = getFunctionalMethod(type, call, expected);
|
||||
// e.g. compareTo
|
||||
invokedName = method.getName();
|
||||
// e.g. (Object)Comparator
|
||||
invokedType = Type.getMethodType(Type.getType(expected));
|
||||
// e.g. (Object,Object)int
|
||||
interfaceType = Type.getMethodType(Type.getMethodDescriptor(method));
|
||||
// lookup requested method
|
||||
Definition.Struct struct = Definition.getType(type).struct;
|
||||
final Definition.Method impl;
|
||||
// ctor ref
|
||||
if (isCtorReference) {
|
||||
impl = struct.constructors.get(new Definition.MethodKey("<init>", method.getParameterCount()));
|
||||
} else {
|
||||
// look for a static impl first
|
||||
Definition.Method staticImpl = struct.staticMethods.get(new Definition.MethodKey(call, method.getParameterCount()));
|
||||
if (staticImpl == null) {
|
||||
// otherwise a virtual impl
|
||||
impl = struct.methods.get(new Definition.MethodKey(call, method.getParameterCount()-1));
|
||||
} else {
|
||||
impl = staticImpl;
|
||||
}
|
||||
}
|
||||
if (impl == null) {
|
||||
throw new IllegalArgumentException("Unknown reference [" + type + "::" + call + "] matching " +
|
||||
"[" + expected + "]");
|
||||
}
|
||||
|
||||
final int tag;
|
||||
if (isCtorReference) {
|
||||
tag = Opcodes.H_NEWINVOKESPECIAL;
|
||||
} else if (Modifier.isStatic(impl.modifiers)) {
|
||||
tag = Opcodes.H_INVOKESTATIC;
|
||||
} else {
|
||||
tag = Opcodes.H_INVOKEVIRTUAL;
|
||||
}
|
||||
implMethod = new Handle(tag, struct.type.getInternalName(), impl.name, impl.method.getDescriptor());
|
||||
implMethodHandle = impl.handle;
|
||||
if (isCtorReference) {
|
||||
samMethodType = Type.getMethodType(interfaceType.getReturnType(), impl.method.getArgumentTypes());
|
||||
} else if (Modifier.isStatic(impl.modifiers)) {
|
||||
samMethodType = Type.getMethodType(impl.method.getReturnType(), impl.method.getArgumentTypes());
|
||||
} else {
|
||||
Type[] argTypes = impl.method.getArgumentTypes();
|
||||
Type[] params = new Type[argTypes.length + 1];
|
||||
System.arraycopy(argTypes, 0, params, 1, argTypes.length);
|
||||
params[0] = struct.type;
|
||||
samMethodType = Type.getMethodType(impl.method.getReturnType(), params);
|
||||
}
|
||||
}
|
||||
|
||||
static final Set<Definition.MethodKey> OBJECT_METHODS = new HashSet<>();
|
||||
static {
|
||||
for (java.lang.reflect.Method m : Object.class.getMethods()) {
|
||||
OBJECT_METHODS.add(new Definition.MethodKey(m.getName(), m.getParameterCount()));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move all this crap out, to Definition to compute up front
|
||||
java.lang.reflect.Method getFunctionalMethod(String type, String call, Class<?> clazz) {
|
||||
if (!clazz.isInterface()) {
|
||||
throw new IllegalArgumentException("Cannot convert function reference ["
|
||||
+ type + "::" + call + "] to [" + clazz + "]");
|
||||
}
|
||||
for (java.lang.reflect.Method m : clazz.getMethods()) {
|
||||
if (m.isDefault()) {
|
||||
continue;
|
||||
}
|
||||
if (OBJECT_METHODS.contains(new Definition.MethodKey(m.getName(), m.getParameterCount()))) {
|
||||
continue;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
throw new IllegalArgumentException("Cannot convert function reference ["
|
||||
+ type + "::" + call + "] to [" + clazz + "]");
|
||||
}
|
||||
}
|
|
@ -40,7 +40,6 @@ import java.security.Permissions;
|
|||
import java.security.PrivilegedAction;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
|
@ -119,7 +119,7 @@ final class ScriptImpl implements ExecutableScript, LeafSearchScript {
|
|||
public Object run() {
|
||||
try {
|
||||
return executable.execute(variables, scorer, doc, aggregationValue);
|
||||
} catch (PainlessError | Exception t) {
|
||||
} catch (PainlessError | BootstrapMethodError | Exception t) {
|
||||
throw convertToScriptException(t);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import org.objectweb.asm.Type;
|
|||
import org.objectweb.asm.commons.Method;
|
||||
|
||||
import java.lang.invoke.CallSite;
|
||||
import java.lang.invoke.LambdaMetafactory;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.BitSet;
|
||||
|
@ -62,7 +64,7 @@ public final class WriterConstants {
|
|||
|
||||
/** dynamic callsite bootstrap signature */
|
||||
public final static MethodType DEF_BOOTSTRAP_TYPE =
|
||||
MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class);
|
||||
MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int.class, long.class);
|
||||
public final static Handle DEF_BOOTSTRAP_HANDLE =
|
||||
new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(DefBootstrap.class),
|
||||
"bootstrap", DEF_BOOTSTRAP_TYPE.toMethodDescriptorString());
|
||||
|
@ -101,7 +103,15 @@ public final class WriterConstants {
|
|||
public final static Method DEF_LTE_CALL = getAsmMethod(boolean.class, "lte", Object.class, Object.class);
|
||||
public final static Method DEF_GT_CALL = getAsmMethod(boolean.class, "gt" , Object.class, Object.class);
|
||||
public final static Method DEF_GTE_CALL = getAsmMethod(boolean.class, "gte", Object.class, Object.class);
|
||||
|
||||
|
||||
/** invokedynamic bootstrap for lambda expression/method references */
|
||||
public final static MethodType LAMBDA_BOOTSTRAP_TYPE =
|
||||
MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
||||
MethodType.class, Object[].class);
|
||||
public final static Handle LAMBDA_BOOTSTRAP_HANDLE =
|
||||
new Handle(Opcodes.H_INVOKESTATIC, Type.getInternalName(LambdaMetafactory.class),
|
||||
"altMetafactory", LAMBDA_BOOTSTRAP_TYPE.toMethodDescriptorString());
|
||||
|
||||
/** dynamic invokedynamic bootstrap for indy string concats (Java 9+) */
|
||||
public final static Handle INDY_STRING_CONCAT_BOOTSTRAP_HANDLE;
|
||||
static {
|
||||
|
|
|
@ -986,6 +986,7 @@ class PainlessParser extends Parser {
|
|||
public TerminalNode TYPE() { return getToken(PainlessParser.TYPE, 0); }
|
||||
public TerminalNode REF() { return getToken(PainlessParser.REF, 0); }
|
||||
public TerminalNode ID() { return getToken(PainlessParser.ID, 0); }
|
||||
public TerminalNode NEW() { return getToken(PainlessParser.NEW, 0); }
|
||||
public FuncrefContext(ParserRuleContext parent, int invokingState) {
|
||||
super(parent, invokingState);
|
||||
}
|
||||
|
@ -1000,6 +1001,7 @@ class PainlessParser extends Parser {
|
|||
public final FuncrefContext funcref() throws RecognitionException {
|
||||
FuncrefContext _localctx = new FuncrefContext(_ctx, getState());
|
||||
enterRule(_localctx, 18, RULE_funcref);
|
||||
int _la;
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
|
@ -1008,7 +1010,12 @@ class PainlessParser extends Parser {
|
|||
setState(162);
|
||||
match(REF);
|
||||
setState(163);
|
||||
match(ID);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==NEW || _la==ID) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
} else {
|
||||
consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (RecognitionException re) {
|
||||
|
@ -2623,112 +2630,112 @@ class PainlessParser extends Parser {
|
|||
"\24\3\24\3\24\3\24\3\24\5\24\u015f\n\24\3\25\3\25\3\25\3\25\3\26\3\26"+
|
||||
"\3\26\3\26\7\26\u0169\n\26\f\26\16\26\u016c\13\26\5\26\u016e\n\26\3\26"+
|
||||
"\3\26\3\27\3\27\5\27\u0174\n\27\3\27\2\3\34\30\2\4\6\b\n\f\16\20\22\24"+
|
||||
"\26\30\32\34\36 \"$&(*,\2\r\3\3\r\r\3\2\66A\3\2\34\36\3\2\37 \3\2!#\3"+
|
||||
"\2$\'\3\2(+\3\2\64\65\3\2BE\4\2\32\33\37 \3\2LM\u019b\2\61\3\2\2\2\4{"+
|
||||
"\3\2\2\2\6\177\3\2\2\2\b\u0081\3\2\2\2\n\u008a\3\2\2\2\f\u008e\3\2\2\2"+
|
||||
"\16\u0090\3\2\2\2\20\u0092\3\2\2\2\22\u009b\3\2\2\2\24\u00a3\3\2\2\2\26"+
|
||||
"\u00a7\3\2\2\2\30\u00ac\3\2\2\2\32\u00b3\3\2\2\2\34\u00be\3\2\2\2\36\u011b"+
|
||||
"\3\2\2\2 \u013f\3\2\2\2\"\u0151\3\2\2\2$\u0157\3\2\2\2&\u015e\3\2\2\2"+
|
||||
"(\u0160\3\2\2\2*\u0164\3\2\2\2,\u0173\3\2\2\2.\60\5\4\3\2/.\3\2\2\2\60"+
|
||||
"\63\3\2\2\2\61/\3\2\2\2\61\62\3\2\2\2\62\64\3\2\2\2\63\61\3\2\2\2\64\65"+
|
||||
"\7\2\2\3\65\3\3\2\2\2\66\67\7\16\2\2\678\7\t\2\289\5\34\17\29:\7\n\2\2"+
|
||||
":>\5\6\4\2;<\7\17\2\2<?\5\6\4\2=?\6\3\2\2>;\3\2\2\2>=\3\2\2\2?|\3\2\2"+
|
||||
"\2@A\7\20\2\2AB\7\t\2\2BC\5\34\17\2CF\7\n\2\2DG\5\6\4\2EG\5\n\6\2FD\3"+
|
||||
"\2\2\2FE\3\2\2\2G|\3\2\2\2HI\7\21\2\2IJ\5\b\5\2JK\7\20\2\2KL\7\t\2\2L"+
|
||||
"M\5\34\17\2MN\7\n\2\2NO\5\32\16\2O|\3\2\2\2PQ\7\22\2\2QS\7\t\2\2RT\5\f"+
|
||||
"\7\2SR\3\2\2\2ST\3\2\2\2TU\3\2\2\2UW\7\r\2\2VX\5\34\17\2WV\3\2\2\2WX\3"+
|
||||
"\2\2\2XY\3\2\2\2Y[\7\r\2\2Z\\\5\16\b\2[Z\3\2\2\2[\\\3\2\2\2\\]\3\2\2\2"+
|
||||
"]`\7\n\2\2^a\5\6\4\2_a\5\n\6\2`^\3\2\2\2`_\3\2\2\2a|\3\2\2\2bc\5\20\t"+
|
||||
"\2cd\5\32\16\2d|\3\2\2\2ef\7\23\2\2f|\5\32\16\2gh\7\24\2\2h|\5\32\16\2"+
|
||||
"ij\7\25\2\2jk\5\34\17\2kl\5\32\16\2l|\3\2\2\2mn\7\27\2\2np\5\b\5\2oq\5"+
|
||||
"\30\r\2po\3\2\2\2qr\3\2\2\2rp\3\2\2\2rs\3\2\2\2s|\3\2\2\2tu\7\31\2\2u"+
|
||||
"v\5\34\17\2vw\5\32\16\2w|\3\2\2\2xy\5\34\17\2yz\5\32\16\2z|\3\2\2\2{\66"+
|
||||
"\3\2\2\2{@\3\2\2\2{H\3\2\2\2{P\3\2\2\2{b\3\2\2\2{e\3\2\2\2{g\3\2\2\2{"+
|
||||
"i\3\2\2\2{m\3\2\2\2{t\3\2\2\2{x\3\2\2\2|\5\3\2\2\2}\u0080\5\b\5\2~\u0080"+
|
||||
"\5\4\3\2\177}\3\2\2\2\177~\3\2\2\2\u0080\7\3\2\2\2\u0081\u0085\7\5\2\2"+
|
||||
"\u0082\u0084\5\4\3\2\u0083\u0082\3\2\2\2\u0084\u0087\3\2\2\2\u0085\u0083"+
|
||||
"\3\2\2\2\u0085\u0086\3\2\2\2\u0086\u0088\3\2\2\2\u0087\u0085\3\2\2\2\u0088"+
|
||||
"\u0089\7\6\2\2\u0089\t\3\2\2\2\u008a\u008b\7\r\2\2\u008b\13\3\2\2\2\u008c"+
|
||||
"\u008f\5\20\t\2\u008d\u008f\5\34\17\2\u008e\u008c\3\2\2\2\u008e\u008d"+
|
||||
"\3\2\2\2\u008f\r\3\2\2\2\u0090\u0091\5\34\17\2\u0091\17\3\2\2\2\u0092"+
|
||||
"\u0093\5\22\n\2\u0093\u0098\5\26\f\2\u0094\u0095\7\f\2\2\u0095\u0097\5"+
|
||||
"\26\f\2\u0096\u0094\3\2\2\2\u0097\u009a\3\2\2\2\u0098\u0096\3\2\2\2\u0098"+
|
||||
"\u0099\3\2\2\2\u0099\21\3\2\2\2\u009a\u0098\3\2\2\2\u009b\u00a0\7J\2\2"+
|
||||
"\u009c\u009d\7\7\2\2\u009d\u009f\7\b\2\2\u009e\u009c\3\2\2\2\u009f\u00a2"+
|
||||
"\3\2\2\2\u00a0\u009e\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1\23\3\2\2\2\u00a2"+
|
||||
"\u00a0\3\2\2\2\u00a3\u00a4\7J\2\2\u00a4\u00a5\7\63\2\2\u00a5\u00a6\7K"+
|
||||
"\2\2\u00a6\25\3\2\2\2\u00a7\u00aa\7K\2\2\u00a8\u00a9\7\66\2\2\u00a9\u00ab"+
|
||||
"\5\34\17\2\u00aa\u00a8\3\2\2\2\u00aa\u00ab\3\2\2\2\u00ab\27\3\2\2\2\u00ac"+
|
||||
"\u00ad\7\30\2\2\u00ad\u00ae\7\t\2\2\u00ae\u00af\7J\2\2\u00af\u00b0\7K"+
|
||||
"\2\2\u00b0\u00b1\7\n\2\2\u00b1\u00b2\5\b\5\2\u00b2\31\3\2\2\2\u00b3\u00b4"+
|
||||
"\t\2\2\2\u00b4\33\3\2\2\2\u00b5\u00b6\b\17\1\2\u00b6\u00b7\5 \21\2\u00b7"+
|
||||
"\u00b8\t\3\2\2\u00b8\u00b9\5\34\17\3\u00b9\u00ba\b\17\1\2\u00ba\u00bf"+
|
||||
"\3\2\2\2\u00bb\u00bc\5\36\20\2\u00bc\u00bd\b\17\1\2\u00bd\u00bf\3\2\2"+
|
||||
"\2\u00be\u00b5\3\2\2\2\u00be\u00bb\3\2\2\2\u00bf\u00fb\3\2\2\2\u00c0\u00c1"+
|
||||
"\f\16\2\2\u00c1\u00c2\t\4\2\2\u00c2\u00c3\5\34\17\17\u00c3\u00c4\b\17"+
|
||||
"\1\2\u00c4\u00fa\3\2\2\2\u00c5\u00c6\f\r\2\2\u00c6\u00c7\t\5\2\2\u00c7"+
|
||||
"\u00c8\5\34\17\16\u00c8\u00c9\b\17\1\2\u00c9\u00fa\3\2\2\2\u00ca\u00cb"+
|
||||
"\f\f\2\2\u00cb\u00cc\t\6\2\2\u00cc\u00cd\5\34\17\r\u00cd\u00ce\b\17\1"+
|
||||
"\2\u00ce\u00fa\3\2\2\2\u00cf\u00d0\f\13\2\2\u00d0\u00d1\t\7\2\2\u00d1"+
|
||||
"\u00d2\5\34\17\f\u00d2\u00d3\b\17\1\2\u00d3\u00fa\3\2\2\2\u00d4\u00d5"+
|
||||
"\f\n\2\2\u00d5\u00d6\t\b\2\2\u00d6\u00d7\5\34\17\13\u00d7\u00d8\b\17\1"+
|
||||
"\2\u00d8\u00fa\3\2\2\2\u00d9\u00da\f\t\2\2\u00da\u00db\7,\2\2\u00db\u00dc"+
|
||||
"\5\34\17\n\u00dc\u00dd\b\17\1\2\u00dd\u00fa\3\2\2\2\u00de\u00df\f\b\2"+
|
||||
"\2\u00df\u00e0\7-\2\2\u00e0\u00e1\5\34\17\t\u00e1\u00e2\b\17\1\2\u00e2"+
|
||||
"\u00fa\3\2\2\2\u00e3\u00e4\f\7\2\2\u00e4\u00e5\7.\2\2\u00e5\u00e6\5\34"+
|
||||
"\17\b\u00e6\u00e7\b\17\1\2\u00e7\u00fa\3\2\2\2\u00e8\u00e9\f\6\2\2\u00e9"+
|
||||
"\u00ea\7/\2\2\u00ea\u00eb\5\34\17\7\u00eb\u00ec\b\17\1\2\u00ec\u00fa\3"+
|
||||
"\2\2\2\u00ed\u00ee\f\5\2\2\u00ee\u00ef\7\60\2\2\u00ef\u00f0\5\34\17\6"+
|
||||
"\u00f0\u00f1\b\17\1\2\u00f1\u00fa\3\2\2\2\u00f2\u00f3\f\4\2\2\u00f3\u00f4"+
|
||||
"\7\61\2\2\u00f4\u00f5\5\34\17\2\u00f5\u00f6\7\62\2\2\u00f6\u00f7\5\34"+
|
||||
"\17\4\u00f7\u00f8\b\17\1\2\u00f8\u00fa\3\2\2\2\u00f9\u00c0\3\2\2\2\u00f9"+
|
||||
"\u00c5\3\2\2\2\u00f9\u00ca\3\2\2\2\u00f9\u00cf\3\2\2\2\u00f9\u00d4\3\2"+
|
||||
"\2\2\u00f9\u00d9\3\2\2\2\u00f9\u00de\3\2\2\2\u00f9\u00e3\3\2\2\2\u00f9"+
|
||||
"\u00e8\3\2\2\2\u00f9\u00ed\3\2\2\2\u00f9\u00f2\3\2\2\2\u00fa\u00fd\3\2"+
|
||||
"\2\2\u00fb\u00f9\3\2\2\2\u00fb\u00fc\3\2\2\2\u00fc\35\3\2\2\2\u00fd\u00fb"+
|
||||
"\3\2\2\2\u00fe\u00ff\6\20\16\3\u00ff\u0100\t\t\2\2\u0100\u011c\5 \21\2"+
|
||||
"\u0101\u0102\6\20\17\3\u0102\u0103\5 \21\2\u0103\u0104\t\t\2\2\u0104\u011c"+
|
||||
"\3\2\2\2\u0105\u0106\6\20\20\3\u0106\u011c\5 \21\2\u0107\u0108\6\20\21"+
|
||||
"\3\u0108\u0109\t\n\2\2\u0109\u011c\b\20\1\2\u010a\u010b\6\20\22\3\u010b"+
|
||||
"\u010c\7G\2\2\u010c\u011c\b\20\1\2\u010d\u010e\6\20\23\3\u010e\u010f\7"+
|
||||
"H\2\2\u010f\u011c\b\20\1\2\u0110\u0111\6\20\24\3\u0111\u0112\7I\2\2\u0112"+
|
||||
"\u011c\b\20\1\2\u0113\u0114\6\20\25\3\u0114\u0115\t\13\2\2\u0115\u011c"+
|
||||
"\5\36\20\2\u0116\u0117\7\t\2\2\u0117\u0118\5\22\n\2\u0118\u0119\7\n\2"+
|
||||
"\2\u0119\u011a\5\36\20\2\u011a\u011c\3\2\2\2\u011b\u00fe\3\2\2\2\u011b"+
|
||||
"\u0101\3\2\2\2\u011b\u0105\3\2\2\2\u011b\u0107\3\2\2\2\u011b\u010a\3\2"+
|
||||
"\2\2\u011b\u010d\3\2\2\2\u011b\u0110\3\2\2\2\u011b\u0113\3\2\2\2\u011b"+
|
||||
"\u0116\3\2\2\2\u011c\37\3\2\2\2\u011d\u0121\5\"\22\2\u011e\u0120\5$\23"+
|
||||
"\2\u011f\u011e\3\2\2\2\u0120\u0123\3\2\2\2\u0121\u011f\3\2\2\2\u0121\u0122"+
|
||||
"\3\2\2\2\u0122\u0140\3\2\2\2\u0123\u0121\3\2\2\2\u0124\u0125\5\22\n\2"+
|
||||
"\u0125\u0129\5&\24\2\u0126\u0128\5$\23\2\u0127\u0126\3\2\2\2\u0128\u012b"+
|
||||
"\3\2\2\2\u0129\u0127\3\2\2\2\u0129\u012a\3\2\2\2\u012a\u0140\3\2\2\2\u012b"+
|
||||
"\u0129\3\2\2\2\u012c\u012d\7\26\2\2\u012d\u0132\7J\2\2\u012e\u012f\7\7"+
|
||||
"\2\2\u012f\u0130\5\34\17\2\u0130\u0131\7\b\2\2\u0131\u0133\3\2\2\2\u0132"+
|
||||
"\u012e\3\2\2\2\u0133\u0134\3\2\2\2\u0134\u0132\3\2\2\2\u0134\u0135\3\2"+
|
||||
"\2\2\u0135\u013d\3\2\2\2\u0136\u013a\5&\24\2\u0137\u0139\5$\23\2\u0138"+
|
||||
"\u0137\3\2\2\2\u0139\u013c\3\2\2\2\u013a\u0138\3\2\2\2\u013a\u013b\3\2"+
|
||||
"\2\2\u013b\u013e\3\2\2\2\u013c\u013a\3\2\2\2\u013d\u0136\3\2\2\2\u013d"+
|
||||
"\u013e\3\2\2\2\u013e\u0140\3\2\2\2\u013f\u011d\3\2\2\2\u013f\u0124\3\2"+
|
||||
"\2\2\u013f\u012c\3\2\2\2\u0140!\3\2\2\2\u0141\u0142\6\22\26\3\u0142\u0143"+
|
||||
"\7\t\2\2\u0143\u0144\5\34\17\2\u0144\u0145\7\n\2\2\u0145\u0146\b\22\1"+
|
||||
"\2\u0146\u0152\3\2\2\2\u0147\u0148\6\22\27\3\u0148\u0149\7\t\2\2\u0149"+
|
||||
"\u014a\5\36\20\2\u014a\u014b\7\n\2\2\u014b\u0152\3\2\2\2\u014c\u0152\7"+
|
||||
"F\2\2\u014d\u0152\7K\2\2\u014e\u014f\7\26\2\2\u014f\u0150\7J\2\2\u0150"+
|
||||
"\u0152\5*\26\2\u0151\u0141\3\2\2\2\u0151\u0147\3\2\2\2\u0151\u014c\3\2"+
|
||||
"\2\2\u0151\u014d\3\2\2\2\u0151\u014e\3\2\2\2\u0152#\3\2\2\2\u0153\u0154"+
|
||||
"\6\23\30\3\u0154\u0158\5&\24\2\u0155\u0156\6\23\31\3\u0156\u0158\5(\25"+
|
||||
"\2\u0157\u0153\3\2\2\2\u0157\u0155\3\2\2\2\u0158%\3\2\2\2\u0159\u015a"+
|
||||
"\7\13\2\2\u015a\u015b\7M\2\2\u015b\u015f\5*\26\2\u015c\u015d\7\13\2\2"+
|
||||
"\u015d\u015f\t\f\2\2\u015e\u0159\3\2\2\2\u015e\u015c\3\2\2\2\u015f\'\3"+
|
||||
"\2\2\2\u0160\u0161\7\7\2\2\u0161\u0162\5\34\17\2\u0162\u0163\7\b\2\2\u0163"+
|
||||
")\3\2\2\2\u0164\u016d\7\t\2\2\u0165\u016a\5,\27\2\u0166\u0167\7\f\2\2"+
|
||||
"\u0167\u0169\5,\27\2\u0168\u0166\3\2\2\2\u0169\u016c\3\2\2\2\u016a\u0168"+
|
||||
"\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u016e\3\2\2\2\u016c\u016a\3\2\2\2\u016d"+
|
||||
"\u0165\3\2\2\2\u016d\u016e\3\2\2\2\u016e\u016f\3\2\2\2\u016f\u0170\7\n"+
|
||||
"\2\2\u0170+\3\2\2\2\u0171\u0174\5\34\17\2\u0172\u0174\5\24\13\2\u0173"+
|
||||
"\u0171\3\2\2\2\u0173\u0172\3\2\2\2\u0174-\3\2\2\2!\61>FSW[`r{\177\u0085"+
|
||||
"\u008e\u0098\u00a0\u00aa\u00be\u00f9\u00fb\u011b\u0121\u0129\u0134\u013a"+
|
||||
"\u013d\u013f\u0151\u0157\u015e\u016a\u016d\u0173";
|
||||
"\26\30\32\34\36 \"$&(*,\2\16\4\2\26\26KK\3\3\r\r\3\2\66A\3\2\34\36\3\2"+
|
||||
"\37 \3\2!#\3\2$\'\3\2(+\3\2\64\65\3\2BE\4\2\32\33\37 \3\2LM\u019b\2\61"+
|
||||
"\3\2\2\2\4{\3\2\2\2\6\177\3\2\2\2\b\u0081\3\2\2\2\n\u008a\3\2\2\2\f\u008e"+
|
||||
"\3\2\2\2\16\u0090\3\2\2\2\20\u0092\3\2\2\2\22\u009b\3\2\2\2\24\u00a3\3"+
|
||||
"\2\2\2\26\u00a7\3\2\2\2\30\u00ac\3\2\2\2\32\u00b3\3\2\2\2\34\u00be\3\2"+
|
||||
"\2\2\36\u011b\3\2\2\2 \u013f\3\2\2\2\"\u0151\3\2\2\2$\u0157\3\2\2\2&\u015e"+
|
||||
"\3\2\2\2(\u0160\3\2\2\2*\u0164\3\2\2\2,\u0173\3\2\2\2.\60\5\4\3\2/.\3"+
|
||||
"\2\2\2\60\63\3\2\2\2\61/\3\2\2\2\61\62\3\2\2\2\62\64\3\2\2\2\63\61\3\2"+
|
||||
"\2\2\64\65\7\2\2\3\65\3\3\2\2\2\66\67\7\16\2\2\678\7\t\2\289\5\34\17\2"+
|
||||
"9:\7\n\2\2:>\5\6\4\2;<\7\17\2\2<?\5\6\4\2=?\6\3\2\2>;\3\2\2\2>=\3\2\2"+
|
||||
"\2?|\3\2\2\2@A\7\20\2\2AB\7\t\2\2BC\5\34\17\2CF\7\n\2\2DG\5\6\4\2EG\5"+
|
||||
"\n\6\2FD\3\2\2\2FE\3\2\2\2G|\3\2\2\2HI\7\21\2\2IJ\5\b\5\2JK\7\20\2\2K"+
|
||||
"L\7\t\2\2LM\5\34\17\2MN\7\n\2\2NO\5\32\16\2O|\3\2\2\2PQ\7\22\2\2QS\7\t"+
|
||||
"\2\2RT\5\f\7\2SR\3\2\2\2ST\3\2\2\2TU\3\2\2\2UW\7\r\2\2VX\5\34\17\2WV\3"+
|
||||
"\2\2\2WX\3\2\2\2XY\3\2\2\2Y[\7\r\2\2Z\\\5\16\b\2[Z\3\2\2\2[\\\3\2\2\2"+
|
||||
"\\]\3\2\2\2]`\7\n\2\2^a\5\6\4\2_a\5\n\6\2`^\3\2\2\2`_\3\2\2\2a|\3\2\2"+
|
||||
"\2bc\5\20\t\2cd\5\32\16\2d|\3\2\2\2ef\7\23\2\2f|\5\32\16\2gh\7\24\2\2"+
|
||||
"h|\5\32\16\2ij\7\25\2\2jk\5\34\17\2kl\5\32\16\2l|\3\2\2\2mn\7\27\2\2n"+
|
||||
"p\5\b\5\2oq\5\30\r\2po\3\2\2\2qr\3\2\2\2rp\3\2\2\2rs\3\2\2\2s|\3\2\2\2"+
|
||||
"tu\7\31\2\2uv\5\34\17\2vw\5\32\16\2w|\3\2\2\2xy\5\34\17\2yz\5\32\16\2"+
|
||||
"z|\3\2\2\2{\66\3\2\2\2{@\3\2\2\2{H\3\2\2\2{P\3\2\2\2{b\3\2\2\2{e\3\2\2"+
|
||||
"\2{g\3\2\2\2{i\3\2\2\2{m\3\2\2\2{t\3\2\2\2{x\3\2\2\2|\5\3\2\2\2}\u0080"+
|
||||
"\5\b\5\2~\u0080\5\4\3\2\177}\3\2\2\2\177~\3\2\2\2\u0080\7\3\2\2\2\u0081"+
|
||||
"\u0085\7\5\2\2\u0082\u0084\5\4\3\2\u0083\u0082\3\2\2\2\u0084\u0087\3\2"+
|
||||
"\2\2\u0085\u0083\3\2\2\2\u0085\u0086\3\2\2\2\u0086\u0088\3\2\2\2\u0087"+
|
||||
"\u0085\3\2\2\2\u0088\u0089\7\6\2\2\u0089\t\3\2\2\2\u008a\u008b\7\r\2\2"+
|
||||
"\u008b\13\3\2\2\2\u008c\u008f\5\20\t\2\u008d\u008f\5\34\17\2\u008e\u008c"+
|
||||
"\3\2\2\2\u008e\u008d\3\2\2\2\u008f\r\3\2\2\2\u0090\u0091\5\34\17\2\u0091"+
|
||||
"\17\3\2\2\2\u0092\u0093\5\22\n\2\u0093\u0098\5\26\f\2\u0094\u0095\7\f"+
|
||||
"\2\2\u0095\u0097\5\26\f\2\u0096\u0094\3\2\2\2\u0097\u009a\3\2\2\2\u0098"+
|
||||
"\u0096\3\2\2\2\u0098\u0099\3\2\2\2\u0099\21\3\2\2\2\u009a\u0098\3\2\2"+
|
||||
"\2\u009b\u00a0\7J\2\2\u009c\u009d\7\7\2\2\u009d\u009f\7\b\2\2\u009e\u009c"+
|
||||
"\3\2\2\2\u009f\u00a2\3\2\2\2\u00a0\u009e\3\2\2\2\u00a0\u00a1\3\2\2\2\u00a1"+
|
||||
"\23\3\2\2\2\u00a2\u00a0\3\2\2\2\u00a3\u00a4\7J\2\2\u00a4\u00a5\7\63\2"+
|
||||
"\2\u00a5\u00a6\t\2\2\2\u00a6\25\3\2\2\2\u00a7\u00aa\7K\2\2\u00a8\u00a9"+
|
||||
"\7\66\2\2\u00a9\u00ab\5\34\17\2\u00aa\u00a8\3\2\2\2\u00aa\u00ab\3\2\2"+
|
||||
"\2\u00ab\27\3\2\2\2\u00ac\u00ad\7\30\2\2\u00ad\u00ae\7\t\2\2\u00ae\u00af"+
|
||||
"\7J\2\2\u00af\u00b0\7K\2\2\u00b0\u00b1\7\n\2\2\u00b1\u00b2\5\b\5\2\u00b2"+
|
||||
"\31\3\2\2\2\u00b3\u00b4\t\3\2\2\u00b4\33\3\2\2\2\u00b5\u00b6\b\17\1\2"+
|
||||
"\u00b6\u00b7\5 \21\2\u00b7\u00b8\t\4\2\2\u00b8\u00b9\5\34\17\3\u00b9\u00ba"+
|
||||
"\b\17\1\2\u00ba\u00bf\3\2\2\2\u00bb\u00bc\5\36\20\2\u00bc\u00bd\b\17\1"+
|
||||
"\2\u00bd\u00bf\3\2\2\2\u00be\u00b5\3\2\2\2\u00be\u00bb\3\2\2\2\u00bf\u00fb"+
|
||||
"\3\2\2\2\u00c0\u00c1\f\16\2\2\u00c1\u00c2\t\5\2\2\u00c2\u00c3\5\34\17"+
|
||||
"\17\u00c3\u00c4\b\17\1\2\u00c4\u00fa\3\2\2\2\u00c5\u00c6\f\r\2\2\u00c6"+
|
||||
"\u00c7\t\6\2\2\u00c7\u00c8\5\34\17\16\u00c8\u00c9\b\17\1\2\u00c9\u00fa"+
|
||||
"\3\2\2\2\u00ca\u00cb\f\f\2\2\u00cb\u00cc\t\7\2\2\u00cc\u00cd\5\34\17\r"+
|
||||
"\u00cd\u00ce\b\17\1\2\u00ce\u00fa\3\2\2\2\u00cf\u00d0\f\13\2\2\u00d0\u00d1"+
|
||||
"\t\b\2\2\u00d1\u00d2\5\34\17\f\u00d2\u00d3\b\17\1\2\u00d3\u00fa\3\2\2"+
|
||||
"\2\u00d4\u00d5\f\n\2\2\u00d5\u00d6\t\t\2\2\u00d6\u00d7\5\34\17\13\u00d7"+
|
||||
"\u00d8\b\17\1\2\u00d8\u00fa\3\2\2\2\u00d9\u00da\f\t\2\2\u00da\u00db\7"+
|
||||
",\2\2\u00db\u00dc\5\34\17\n\u00dc\u00dd\b\17\1\2\u00dd\u00fa\3\2\2\2\u00de"+
|
||||
"\u00df\f\b\2\2\u00df\u00e0\7-\2\2\u00e0\u00e1\5\34\17\t\u00e1\u00e2\b"+
|
||||
"\17\1\2\u00e2\u00fa\3\2\2\2\u00e3\u00e4\f\7\2\2\u00e4\u00e5\7.\2\2\u00e5"+
|
||||
"\u00e6\5\34\17\b\u00e6\u00e7\b\17\1\2\u00e7\u00fa\3\2\2\2\u00e8\u00e9"+
|
||||
"\f\6\2\2\u00e9\u00ea\7/\2\2\u00ea\u00eb\5\34\17\7\u00eb\u00ec\b\17\1\2"+
|
||||
"\u00ec\u00fa\3\2\2\2\u00ed\u00ee\f\5\2\2\u00ee\u00ef\7\60\2\2\u00ef\u00f0"+
|
||||
"\5\34\17\6\u00f0\u00f1\b\17\1\2\u00f1\u00fa\3\2\2\2\u00f2\u00f3\f\4\2"+
|
||||
"\2\u00f3\u00f4\7\61\2\2\u00f4\u00f5\5\34\17\2\u00f5\u00f6\7\62\2\2\u00f6"+
|
||||
"\u00f7\5\34\17\4\u00f7\u00f8\b\17\1\2\u00f8\u00fa\3\2\2\2\u00f9\u00c0"+
|
||||
"\3\2\2\2\u00f9\u00c5\3\2\2\2\u00f9\u00ca\3\2\2\2\u00f9\u00cf\3\2\2\2\u00f9"+
|
||||
"\u00d4\3\2\2\2\u00f9\u00d9\3\2\2\2\u00f9\u00de\3\2\2\2\u00f9\u00e3\3\2"+
|
||||
"\2\2\u00f9\u00e8\3\2\2\2\u00f9\u00ed\3\2\2\2\u00f9\u00f2\3\2\2\2\u00fa"+
|
||||
"\u00fd\3\2\2\2\u00fb\u00f9\3\2\2\2\u00fb\u00fc\3\2\2\2\u00fc\35\3\2\2"+
|
||||
"\2\u00fd\u00fb\3\2\2\2\u00fe\u00ff\6\20\16\3\u00ff\u0100\t\n\2\2\u0100"+
|
||||
"\u011c\5 \21\2\u0101\u0102\6\20\17\3\u0102\u0103\5 \21\2\u0103\u0104\t"+
|
||||
"\n\2\2\u0104\u011c\3\2\2\2\u0105\u0106\6\20\20\3\u0106\u011c\5 \21\2\u0107"+
|
||||
"\u0108\6\20\21\3\u0108\u0109\t\13\2\2\u0109\u011c\b\20\1\2\u010a\u010b"+
|
||||
"\6\20\22\3\u010b\u010c\7G\2\2\u010c\u011c\b\20\1\2\u010d\u010e\6\20\23"+
|
||||
"\3\u010e\u010f\7H\2\2\u010f\u011c\b\20\1\2\u0110\u0111\6\20\24\3\u0111"+
|
||||
"\u0112\7I\2\2\u0112\u011c\b\20\1\2\u0113\u0114\6\20\25\3\u0114\u0115\t"+
|
||||
"\f\2\2\u0115\u011c\5\36\20\2\u0116\u0117\7\t\2\2\u0117\u0118\5\22\n\2"+
|
||||
"\u0118\u0119\7\n\2\2\u0119\u011a\5\36\20\2\u011a\u011c\3\2\2\2\u011b\u00fe"+
|
||||
"\3\2\2\2\u011b\u0101\3\2\2\2\u011b\u0105\3\2\2\2\u011b\u0107\3\2\2\2\u011b"+
|
||||
"\u010a\3\2\2\2\u011b\u010d\3\2\2\2\u011b\u0110\3\2\2\2\u011b\u0113\3\2"+
|
||||
"\2\2\u011b\u0116\3\2\2\2\u011c\37\3\2\2\2\u011d\u0121\5\"\22\2\u011e\u0120"+
|
||||
"\5$\23\2\u011f\u011e\3\2\2\2\u0120\u0123\3\2\2\2\u0121\u011f\3\2\2\2\u0121"+
|
||||
"\u0122\3\2\2\2\u0122\u0140\3\2\2\2\u0123\u0121\3\2\2\2\u0124\u0125\5\22"+
|
||||
"\n\2\u0125\u0129\5&\24\2\u0126\u0128\5$\23\2\u0127\u0126\3\2\2\2\u0128"+
|
||||
"\u012b\3\2\2\2\u0129\u0127\3\2\2\2\u0129\u012a\3\2\2\2\u012a\u0140\3\2"+
|
||||
"\2\2\u012b\u0129\3\2\2\2\u012c\u012d\7\26\2\2\u012d\u0132\7J\2\2\u012e"+
|
||||
"\u012f\7\7\2\2\u012f\u0130\5\34\17\2\u0130\u0131\7\b\2\2\u0131\u0133\3"+
|
||||
"\2\2\2\u0132\u012e\3\2\2\2\u0133\u0134\3\2\2\2\u0134\u0132\3\2\2\2\u0134"+
|
||||
"\u0135\3\2\2\2\u0135\u013d\3\2\2\2\u0136\u013a\5&\24\2\u0137\u0139\5$"+
|
||||
"\23\2\u0138\u0137\3\2\2\2\u0139\u013c\3\2\2\2\u013a\u0138\3\2\2\2\u013a"+
|
||||
"\u013b\3\2\2\2\u013b\u013e\3\2\2\2\u013c\u013a\3\2\2\2\u013d\u0136\3\2"+
|
||||
"\2\2\u013d\u013e\3\2\2\2\u013e\u0140\3\2\2\2\u013f\u011d\3\2\2\2\u013f"+
|
||||
"\u0124\3\2\2\2\u013f\u012c\3\2\2\2\u0140!\3\2\2\2\u0141\u0142\6\22\26"+
|
||||
"\3\u0142\u0143\7\t\2\2\u0143\u0144\5\34\17\2\u0144\u0145\7\n\2\2\u0145"+
|
||||
"\u0146\b\22\1\2\u0146\u0152\3\2\2\2\u0147\u0148\6\22\27\3\u0148\u0149"+
|
||||
"\7\t\2\2\u0149\u014a\5\36\20\2\u014a\u014b\7\n\2\2\u014b\u0152\3\2\2\2"+
|
||||
"\u014c\u0152\7F\2\2\u014d\u0152\7K\2\2\u014e\u014f\7\26\2\2\u014f\u0150"+
|
||||
"\7J\2\2\u0150\u0152\5*\26\2\u0151\u0141\3\2\2\2\u0151\u0147\3\2\2\2\u0151"+
|
||||
"\u014c\3\2\2\2\u0151\u014d\3\2\2\2\u0151\u014e\3\2\2\2\u0152#\3\2\2\2"+
|
||||
"\u0153\u0154\6\23\30\3\u0154\u0158\5&\24\2\u0155\u0156\6\23\31\3\u0156"+
|
||||
"\u0158\5(\25\2\u0157\u0153\3\2\2\2\u0157\u0155\3\2\2\2\u0158%\3\2\2\2"+
|
||||
"\u0159\u015a\7\13\2\2\u015a\u015b\7M\2\2\u015b\u015f\5*\26\2\u015c\u015d"+
|
||||
"\7\13\2\2\u015d\u015f\t\r\2\2\u015e\u0159\3\2\2\2\u015e\u015c\3\2\2\2"+
|
||||
"\u015f\'\3\2\2\2\u0160\u0161\7\7\2\2\u0161\u0162\5\34\17\2\u0162\u0163"+
|
||||
"\7\b\2\2\u0163)\3\2\2\2\u0164\u016d\7\t\2\2\u0165\u016a\5,\27\2\u0166"+
|
||||
"\u0167\7\f\2\2\u0167\u0169\5,\27\2\u0168\u0166\3\2\2\2\u0169\u016c\3\2"+
|
||||
"\2\2\u016a\u0168\3\2\2\2\u016a\u016b\3\2\2\2\u016b\u016e\3\2\2\2\u016c"+
|
||||
"\u016a\3\2\2\2\u016d\u0165\3\2\2\2\u016d\u016e\3\2\2\2\u016e\u016f\3\2"+
|
||||
"\2\2\u016f\u0170\7\n\2\2\u0170+\3\2\2\2\u0171\u0174\5\34\17\2\u0172\u0174"+
|
||||
"\5\24\13\2\u0173\u0171\3\2\2\2\u0173\u0172\3\2\2\2\u0174-\3\2\2\2!\61"+
|
||||
">FSW[`r{\177\u0085\u008e\u0098\u00a0\u00aa\u00be\u00f9\u00fb\u011b\u0121"+
|
||||
"\u0129\u0134\u013a\u013d\u013f\u0151\u0157\u015e\u016a\u016d\u0173";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
|
|
@ -391,7 +391,15 @@ public final class Walker extends PainlessParserBaseVisitor<Object> {
|
|||
|
||||
@Override
|
||||
public Object visitFuncref(FuncrefContext ctx) {
|
||||
return new EFunctionRef(location(ctx), ctx.TYPE().getText(), ctx.ID().getText());
|
||||
final String methodText;
|
||||
if (ctx.ID() != null) {
|
||||
methodText = ctx.ID().getText();
|
||||
} else if (ctx.NEW() != null ){
|
||||
methodText = ctx.NEW().getText();
|
||||
} else {
|
||||
throw location(ctx).createError(new IllegalStateException("Illegal tree structure."));
|
||||
}
|
||||
return new EFunctionRef(location(ctx), ctx.TYPE().getText(), methodText);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,16 +19,24 @@
|
|||
|
||||
package org.elasticsearch.painless.node;
|
||||
|
||||
import org.elasticsearch.painless.Definition;
|
||||
import org.elasticsearch.painless.FunctionRef;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.MethodWriter;
|
||||
import org.elasticsearch.painless.Variables;
|
||||
|
||||
import static org.elasticsearch.painless.WriterConstants.LAMBDA_BOOTSTRAP_HANDLE;
|
||||
|
||||
import java.lang.invoke.LambdaMetafactory;
|
||||
|
||||
/**
|
||||
* Represents a function reference.
|
||||
*/
|
||||
public class EFunctionRef extends AExpression {
|
||||
public String type;
|
||||
public String call;
|
||||
public final String type;
|
||||
public final String call;
|
||||
|
||||
private FunctionRef ref;
|
||||
|
||||
public EFunctionRef(Location location, String type, String call) {
|
||||
super(location);
|
||||
|
@ -39,12 +47,35 @@ public class EFunctionRef extends AExpression {
|
|||
|
||||
@Override
|
||||
void analyze(Variables variables) {
|
||||
throw createError(new UnsupportedOperationException("Function references [" + type + "::" + call +
|
||||
"] are not currently supported."));
|
||||
if (expected == null) {
|
||||
ref = null;
|
||||
actual = Definition.getType("String");
|
||||
} else {
|
||||
try {
|
||||
ref = new FunctionRef(expected.clazz, type, call);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw createError(e);
|
||||
}
|
||||
actual = expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void write(MethodWriter writer) {
|
||||
throw createError(new IllegalStateException("Illegal tree structure."));
|
||||
if (ref == null) {
|
||||
writer.push(type + "." + call);
|
||||
} else {
|
||||
writer.writeDebugInfo(location);
|
||||
// currently if the interface differs, we ask for a bridge, but maybe we should do smarter checking?
|
||||
// either way, stuff will fail if its wrong :)
|
||||
if (ref.interfaceType.equals(ref.samMethodType)) {
|
||||
writer.invokeDynamic(ref.invokedName, ref.invokedType.getDescriptor(), LAMBDA_BOOTSTRAP_HANDLE,
|
||||
ref.samMethodType, ref.implMethod, ref.samMethodType, 0);
|
||||
} else {
|
||||
writer.invokeDynamic(ref.invokedName, ref.invokedType.getDescriptor(), LAMBDA_BOOTSTRAP_HANDLE,
|
||||
ref.samMethodType, ref.implMethod, ref.samMethodType,
|
||||
LambdaMetafactory.FLAG_BRIDGES, 1, ref.interfaceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,7 +82,7 @@ public final class LCall extends ALink {
|
|||
}
|
||||
|
||||
throw createError(new IllegalArgumentException("Unknown call [" + name + "] with [" + arguments.size() +
|
||||
"] arguments on type [" + struct.name + "]."));
|
||||
"] arguments on type [" + struct.name + "]."));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -61,13 +61,13 @@ final class LDefArray extends ALink implements IDefLink {
|
|||
void load(MethodWriter writer) {
|
||||
writer.writeDebugInfo(location);
|
||||
String desc = Type.getMethodDescriptor(after.type, Definition.DEF_TYPE.type, index.actual.type);
|
||||
writer.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.ARRAY_LOAD);
|
||||
writer.invokeDynamic("arrayLoad", desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.ARRAY_LOAD, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
void store(MethodWriter writer) {
|
||||
writer.writeDebugInfo(location);
|
||||
String desc = Type.getMethodDescriptor(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, index.actual.type, after.type);
|
||||
writer.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.ARRAY_STORE);
|
||||
writer.invokeDynamic("arrayStore", desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.ARRAY_STORE, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ final class LDefCall extends ALink implements IDefLink {
|
|||
|
||||
final String name;
|
||||
final List<AExpression> arguments;
|
||||
long recipe;
|
||||
|
||||
LDefCall(Location location, String name, List<AExpression> arguments) {
|
||||
super(location, -1);
|
||||
|
@ -46,9 +47,20 @@ final class LDefCall extends ALink implements IDefLink {
|
|||
|
||||
@Override
|
||||
ALink analyze(Variables variables) {
|
||||
if (arguments.size() > 63) {
|
||||
// technically, the limitation is just methods with > 63 params, containing method references.
|
||||
// this is because we are lazy and use a long as a bitset. we can always change to a "string" if need be.
|
||||
// but NEED NOT BE. nothing with this many parameters is in the whitelist and we do not support varargs.
|
||||
throw new UnsupportedOperationException("methods with > 63 arguments are currently not supported");
|
||||
}
|
||||
|
||||
recipe = 0;
|
||||
for (int argument = 0; argument < arguments.size(); ++argument) {
|
||||
AExpression expression = arguments.get(argument);
|
||||
|
||||
if (expression instanceof EFunctionRef) {
|
||||
recipe |= (1L << argument); // mark argument as deferred reference
|
||||
}
|
||||
expression.internal = true;
|
||||
expression.analyze(variables);
|
||||
expression.expected = expression.actual;
|
||||
|
@ -84,7 +96,7 @@ final class LDefCall extends ALink implements IDefLink {
|
|||
// return value
|
||||
signature.append(after.type.getDescriptor());
|
||||
|
||||
writer.invokeDynamic(name, signature.toString(), DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.METHOD_CALL);
|
||||
writer.invokeDynamic(name, signature.toString(), DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.METHOD_CALL, recipe);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -58,13 +58,13 @@ final class LDefField extends ALink implements IDefLink {
|
|||
void load(MethodWriter writer) {
|
||||
writer.writeDebugInfo(location);
|
||||
String desc = Type.getMethodDescriptor(after.type, Definition.DEF_TYPE.type);
|
||||
writer.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.LOAD);
|
||||
writer.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.LOAD, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
void store(MethodWriter writer) {
|
||||
writer.writeDebugInfo(location);
|
||||
String desc = Type.getMethodDescriptor(Definition.VOID_TYPE.type, Definition.DEF_TYPE.type, after.type);
|
||||
writer.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.STORE);
|
||||
writer.invokeDynamic(value, desc, DEF_BOOTSTRAP_HANDLE, (Object)DefBootstrap.STORE, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ package org.elasticsearch.painless.node;
|
|||
|
||||
import org.elasticsearch.painless.Definition;
|
||||
import org.elasticsearch.painless.Location;
|
||||
import org.elasticsearch.painless.Definition.Constructor;
|
||||
import org.elasticsearch.painless.Definition.Method;
|
||||
import org.elasticsearch.painless.Definition.Struct;
|
||||
import org.elasticsearch.painless.Definition.Type;
|
||||
import org.elasticsearch.painless.Variables;
|
||||
|
@ -37,7 +37,7 @@ public final class LNewObj extends ALink {
|
|||
final String type;
|
||||
final List<AExpression> arguments;
|
||||
|
||||
Constructor constructor;
|
||||
Method constructor;
|
||||
|
||||
public LNewObj(Location location, String type, List<AExpression> arguments) {
|
||||
super(location, -1);
|
||||
|
@ -63,7 +63,7 @@ public final class LNewObj extends ALink {
|
|||
}
|
||||
|
||||
Struct struct = type.struct;
|
||||
constructor = struct.constructors.get(new Definition.MethodKey("new", arguments.size()));
|
||||
constructor = struct.constructors.get(new Definition.MethodKey("<init>", arguments.size()));
|
||||
|
||||
if (constructor != null) {
|
||||
Type[] types = new Type[constructor.arguments.size()];
|
||||
|
|
|
@ -63,6 +63,7 @@ class Boolean -> java.lang.Boolean extends Comparable,Object {
|
|||
Boolean FALSE
|
||||
boolean booleanValue()
|
||||
int compare(boolean,boolean)
|
||||
int compareTo(Boolean)
|
||||
int hashCode(boolean)
|
||||
boolean logicalAnd(boolean,boolean)
|
||||
boolean logicalOr(boolean,boolean)
|
||||
|
@ -78,6 +79,7 @@ class Byte -> java.lang.Byte extends Number,Comparable,Object {
|
|||
byte MIN_VALUE
|
||||
int SIZE
|
||||
int compare(byte,byte)
|
||||
int compareTo(Byte)
|
||||
Byte decode(String)
|
||||
int hashCode(byte)
|
||||
byte parseByte(String)
|
||||
|
@ -163,6 +165,7 @@ class Character -> java.lang.Character extends Comparable,Object {
|
|||
int codePointBefore(CharSequence,int)
|
||||
int codePointCount(CharSequence,int,int)
|
||||
int compare(char,char)
|
||||
int compareTo(Character)
|
||||
int digit(int,int)
|
||||
char forDigit(int,int)
|
||||
byte getDirectionality(int)
|
||||
|
@ -454,6 +457,7 @@ class Double -> java.lang.Double extends Number,Comparable,Object {
|
|||
double POSITIVE_INFINITY
|
||||
int SIZE
|
||||
int compare(double,double)
|
||||
int compareTo(Double)
|
||||
long doubleToLongBits(double)
|
||||
long doubleToRawLongBits(double)
|
||||
int hashCode(double)
|
||||
|
@ -473,6 +477,7 @@ class Double -> java.lang.Double extends Number,Comparable,Object {
|
|||
}
|
||||
|
||||
class Enum -> java.lang.Enum extends Comparable,Object {
|
||||
int compareTo(Enum)
|
||||
String name();
|
||||
int ordinal();
|
||||
}
|
||||
|
@ -489,6 +494,7 @@ class Float -> java.lang.Float extends Number,Comparable,Object {
|
|||
float POSITIVE_INFINITY
|
||||
int SIZE
|
||||
int compare(float,float)
|
||||
int compareTo(Float)
|
||||
int floatToIntBits(float)
|
||||
int floatToRawIntBits(float)
|
||||
int hashCode(float)
|
||||
|
@ -516,6 +522,7 @@ class Integer -> java.lang.Integer extends Number,Comparable,Object {
|
|||
int SIZE
|
||||
int bitCount(int)
|
||||
int compare(int,int)
|
||||
int compareTo(Integer)
|
||||
int compareUnsigned(int,int)
|
||||
Integer decode(String)
|
||||
int divideUnsigned(int,int)
|
||||
|
@ -555,6 +562,7 @@ class Long -> java.lang.Long extends Number,Comparable,Object {
|
|||
int SIZE
|
||||
int bitCount(long)
|
||||
int compare(long,long)
|
||||
int compareTo(Long)
|
||||
int compareUnsigned(long,long)
|
||||
Long decode(String)
|
||||
long divideUnsigned(long,long)
|
||||
|
@ -587,7 +595,7 @@ class Long -> java.lang.Long extends Number,Comparable,Object {
|
|||
Long valueOf(String,int)
|
||||
}
|
||||
|
||||
class Math -> java.lang.Math {
|
||||
class Math -> java.lang.Math extends Object {
|
||||
double E
|
||||
double PI
|
||||
double abs(double)
|
||||
|
@ -658,6 +666,7 @@ class Short -> java.lang.Short extends Number,Comparable,Object {
|
|||
short MIN_VALUE
|
||||
int SIZE
|
||||
int compare(short,short)
|
||||
int compareTo(Short)
|
||||
Short decode(String)
|
||||
int hashCode(short)
|
||||
short parseShort(String)
|
||||
|
@ -679,7 +688,7 @@ class StackTraceElement -> java.lang.StackTraceElement extends Object {
|
|||
boolean isNativeMethod()
|
||||
}
|
||||
|
||||
class StrictMath -> java.lang.StrictMath {
|
||||
class StrictMath -> java.lang.StrictMath extends Object {
|
||||
double E
|
||||
double PI
|
||||
double abs(double)
|
||||
|
@ -726,6 +735,7 @@ class String -> java.lang.String extends CharSequence,Comparable,Object {
|
|||
int codePointAt(int)
|
||||
int codePointBefore(int)
|
||||
int codePointCount(int,int)
|
||||
int compareTo(String)
|
||||
int compareToIgnoreCase(String)
|
||||
String concat(String)
|
||||
boolean contains(CharSequence)
|
||||
|
|
|
@ -35,6 +35,7 @@ class BigDecimal -> java.math.BigDecimal extends Number,Comparable,Object {
|
|||
BigDecimal add(BigDecimal)
|
||||
BigDecimal add(BigDecimal,MathContext)
|
||||
byte byteValueExact()
|
||||
int compareTo(BigDecimal)
|
||||
BigDecimal divide(BigDecimal)
|
||||
BigDecimal divide(BigDecimal,MathContext)
|
||||
BigDecimal[] divideAndRemainder(BigDecimal)
|
||||
|
@ -90,6 +91,7 @@ class BigInteger -> java.math.BigInteger extends Number,Comparable,Object {
|
|||
int bitLength()
|
||||
byte byteValueExact()
|
||||
BigInteger clearBit(int)
|
||||
int compareTo(BigInteger)
|
||||
BigInteger divide(BigInteger)
|
||||
BigInteger[] divideAndRemainder(BigInteger)
|
||||
BigInteger flipBit(int)
|
||||
|
|
|
@ -149,6 +149,7 @@ class CollationElementIterator -> java.text.CollationElementIterator extends Obj
|
|||
}
|
||||
|
||||
class CollationKey -> java.text.CollationKey extends Comparable,Object {
|
||||
int compareTo(CollationKey)
|
||||
String getSourceString()
|
||||
byte[] toByteArray()
|
||||
}
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
#### Interfaces
|
||||
|
||||
class ChronoLocalDate -> java.time.chrono.ChronoLocalDate extends Comparable,Temporal,TemporalAccessor,TemporalAdjuster {
|
||||
class ChronoLocalDate -> java.time.chrono.ChronoLocalDate extends Temporal,TemporalAccessor,TemporalAdjuster,Comparable {
|
||||
ChronoLocalDateTime atTime(LocalTime)
|
||||
int compareTo(ChronoLocalDate)
|
||||
boolean equals(Object)
|
||||
String format(DateTimeFormatter)
|
||||
ChronoLocalDate from(TemporalAccessor)
|
||||
|
@ -50,8 +51,9 @@ class ChronoLocalDate -> java.time.chrono.ChronoLocalDate extends Comparable,Tem
|
|||
ChronoLocalDate with(TemporalField,long)
|
||||
}
|
||||
|
||||
class ChronoLocalDateTime -> java.time.chrono.ChronoLocalDateTime extends Comparable,Temporal,TemporalAccessor,TemporalAdjuster {
|
||||
class ChronoLocalDateTime -> java.time.chrono.ChronoLocalDateTime extends Temporal,TemporalAccessor,TemporalAdjuster,Comparable {
|
||||
ChronoZonedDateTime atZone(ZoneId)
|
||||
int compareTo(ChronoLocalDateTime)
|
||||
boolean equals(Object)
|
||||
String format(DateTimeFormatter)
|
||||
ChronoLocalDateTime from(TemporalAccessor)
|
||||
|
@ -75,6 +77,7 @@ class ChronoLocalDateTime -> java.time.chrono.ChronoLocalDateTime extends Compar
|
|||
}
|
||||
|
||||
class Chronology -> java.time.chrono.Chronology extends Comparable {
|
||||
int compareTo(Chronology)
|
||||
ChronoLocalDate date(TemporalAccessor)
|
||||
ChronoLocalDate date(Era,int,int,int)
|
||||
ChronoLocalDate date(int,int,int)
|
||||
|
@ -121,7 +124,8 @@ class ChronoPeriod -> java.time.chrono.ChronoPeriod extends TemporalAmount {
|
|||
String toString()
|
||||
}
|
||||
|
||||
class ChronoZonedDateTime -> java.time.chrono.ChronoZonedDateTime extends Comparable,Temporal,TemporalAccessor {
|
||||
class ChronoZonedDateTime -> java.time.chrono.ChronoZonedDateTime extends Temporal,TemporalAccessor,Comparable {
|
||||
int compareTo(ChronoZonedDateTime)
|
||||
boolean equals(Object)
|
||||
String format(DateTimeFormatter)
|
||||
ChronoZonedDateTime from(TemporalAccessor)
|
||||
|
@ -158,10 +162,10 @@ class Era -> java.time.chrono.Era extends TemporalAccessor,TemporalAdjuster {
|
|||
|
||||
#### Classes
|
||||
|
||||
class AbstractChronology -> java.time.chrono.Chronology extends Comparable,Chronology,Object {
|
||||
class AbstractChronology -> java.time.chrono.Chronology extends Chronology,Comparable,Object {
|
||||
}
|
||||
|
||||
class HijrahChronology -> java.time.chrono.HijrahChronology extends AbstractChronology,Comparable,Chronology,Object {
|
||||
class HijrahChronology -> java.time.chrono.HijrahChronology extends AbstractChronology,Chronology,Comparable,Object {
|
||||
HijrahChronology INSTANCE
|
||||
HijrahDate date(TemporalAccessor)
|
||||
HijrahDate date(int,int,int)
|
||||
|
@ -172,25 +176,26 @@ class HijrahChronology -> java.time.chrono.HijrahChronology extends AbstractChro
|
|||
HijrahDate dateYearDay(int,int)
|
||||
HijrahDate dateYearDay(Era,int,int)
|
||||
HijrahEra eraOf(int)
|
||||
HijrahDate resolveDate(Map,ResolverStyle)
|
||||
}
|
||||
|
||||
class HijrahDate -> java.time.chrono.HijrahDate extends Comparable,ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
HijrahDate now()
|
||||
HijrahDate now(ZoneId)
|
||||
HijrahDate of(int,int,int)
|
||||
class HijrahDate -> java.time.chrono.HijrahDate extends ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
HijrahDate from(TemporalAccessor)
|
||||
HijrahChronology getChronology()
|
||||
HijrahEra getEra()
|
||||
HijrahDate minus(TemporalAmount)
|
||||
HijrahDate minus(long,TemporalUnit)
|
||||
HijrahDate now()
|
||||
HijrahDate now(ZoneId)
|
||||
HijrahDate of(int,int,int)
|
||||
HijrahDate plus(TemporalAmount)
|
||||
HijrahDate plus(long,TemporalUnit)
|
||||
HijrahDate with(TemporalField,long)
|
||||
HijrahDate with(TemporalAdjuster)
|
||||
HijrahDate withVariant(HijrahChronology)
|
||||
HijrahDate plus(TemporalAmount)
|
||||
HijrahDate minus(TemporalAmount)
|
||||
HijrahDate plus(long,TemporalUnit)
|
||||
HijrahDate minus(long,TemporalUnit)
|
||||
}
|
||||
|
||||
class IsoChronology -> java.time.chrono.IsoChronology extends AbstractChronology,Comparable,Chronology,Object {
|
||||
class IsoChronology -> java.time.chrono.IsoChronology extends AbstractChronology,Chronology,Comparable,Object {
|
||||
IsoChronology INSTANCE
|
||||
LocalDate date(TemporalAccessor)
|
||||
LocalDate date(int,int,int)
|
||||
|
@ -201,9 +206,14 @@ class IsoChronology -> java.time.chrono.IsoChronology extends AbstractChronology
|
|||
LocalDate dateYearDay(int,int)
|
||||
LocalDate dateYearDay(Era,int,int)
|
||||
IsoEra eraOf(int)
|
||||
LocalDateTime localDateTime(TemporalAccessor)
|
||||
Period period(int,int,int)
|
||||
LocalDate resolveDate(Map,ResolverStyle)
|
||||
ZonedDateTime zonedDateTime(TemporalAccessor)
|
||||
ZonedDateTime zonedDateTime(Instant,ZoneId)
|
||||
}
|
||||
|
||||
class JapaneseChronology -> java.time.chrono.JapaneseChronology extends AbstractChronology,Comparable,Chronology,Object {
|
||||
class JapaneseChronology -> java.time.chrono.JapaneseChronology extends AbstractChronology,Chronology,Comparable,Object {
|
||||
JapaneseChronology INSTANCE
|
||||
JapaneseDate date(TemporalAccessor)
|
||||
JapaneseDate date(int,int,int)
|
||||
|
@ -214,9 +224,10 @@ class JapaneseChronology -> java.time.chrono.JapaneseChronology extends Abstract
|
|||
JapaneseDate dateYearDay(int,int)
|
||||
JapaneseDate dateYearDay(Era,int,int)
|
||||
JapaneseEra eraOf(int)
|
||||
JapaneseDate resolveDate(Map,ResolverStyle)
|
||||
}
|
||||
|
||||
class JapaneseDate -> java.time.chrono.JapaneseDate extends Comparable,ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class JapaneseDate -> java.time.chrono.JapaneseDate extends ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
JapaneseDate now()
|
||||
JapaneseDate now(ZoneId)
|
||||
JapaneseDate of(int,int,int)
|
||||
|
@ -242,7 +253,7 @@ class JapaneseEra -> java.time.chrono.JapaneseEra extends Era,TemporalAccessor,T
|
|||
JapaneseEra[] values()
|
||||
}
|
||||
|
||||
class MinguoChronology -> java.time.chrono.MinguoChronology extends AbstractChronology,Comparable,Chronology,Object {
|
||||
class MinguoChronology -> java.time.chrono.MinguoChronology extends AbstractChronology,Chronology,Comparable,Object {
|
||||
MinguoChronology INSTANCE
|
||||
MinguoDate date(TemporalAccessor)
|
||||
MinguoDate date(int,int,int)
|
||||
|
@ -253,9 +264,10 @@ class MinguoChronology -> java.time.chrono.MinguoChronology extends AbstractChro
|
|||
MinguoDate dateYearDay(int,int)
|
||||
MinguoDate dateYearDay(Era,int,int)
|
||||
MinguoEra eraOf(int)
|
||||
MinguoDate resolveDate(Map,ResolverStyle)
|
||||
}
|
||||
|
||||
class MinguoDate -> java.time.chrono.MinguoDate extends Comparable,ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class MinguoDate -> java.time.chrono.MinguoDate extends ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
MinguoDate now()
|
||||
MinguoDate now(ZoneId)
|
||||
MinguoDate of(int,int,int)
|
||||
|
@ -270,7 +282,7 @@ class MinguoDate -> java.time.chrono.MinguoDate extends Comparable,ChronoLocalDa
|
|||
MinguoDate minus(long,TemporalUnit)
|
||||
}
|
||||
|
||||
class ThaiBuddhistChronology -> java.time.chrono.ThaiBuddhistChronology extends AbstractChronology,Comparable,Chronology,Object {
|
||||
class ThaiBuddhistChronology -> java.time.chrono.ThaiBuddhistChronology extends AbstractChronology,Chronology,Comparable,Object {
|
||||
ThaiBuddhistChronology INSTANCE
|
||||
ThaiBuddhistDate date(TemporalAccessor)
|
||||
ThaiBuddhistDate date(int,int,int)
|
||||
|
@ -281,9 +293,10 @@ class ThaiBuddhistChronology -> java.time.chrono.ThaiBuddhistChronology extends
|
|||
ThaiBuddhistDate dateYearDay(int,int)
|
||||
ThaiBuddhistDate dateYearDay(Era,int,int)
|
||||
ThaiBuddhistEra eraOf(int)
|
||||
ThaiBuddhistDate resolveDate(Map,ResolverStyle)
|
||||
}
|
||||
|
||||
class ThaiBuddhistDate -> java.time.chrono.ThaiBuddhistDate extends Comparable,ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class ThaiBuddhistDate -> java.time.chrono.ThaiBuddhistDate extends ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
ThaiBuddhistDate now()
|
||||
ThaiBuddhistDate now(ZoneId)
|
||||
ThaiBuddhistDate of(int,int,int)
|
||||
|
|
|
@ -43,6 +43,7 @@ class Duration -> java.time.Duration extends Comparable,TemporalAmount,Object {
|
|||
Duration ZERO
|
||||
Duration abs()
|
||||
Duration between(Temporal,Temporal)
|
||||
int compareTo(Duration)
|
||||
Duration dividedBy(long)
|
||||
Duration from(TemporalAmount)
|
||||
int getNano()
|
||||
|
@ -91,6 +92,7 @@ class Instant -> java.time.Instant extends Comparable,Temporal,TemporalAccessor,
|
|||
Instant MIN
|
||||
OffsetDateTime atOffset(ZoneOffset)
|
||||
ZonedDateTime atZone(ZoneId)
|
||||
int compareTo(Instant)
|
||||
Instant from(TemporalAccessor)
|
||||
long getEpochSecond()
|
||||
int getNano()
|
||||
|
@ -118,7 +120,7 @@ class Instant -> java.time.Instant extends Comparable,Temporal,TemporalAccessor,
|
|||
Instant with(TemporalField,long)
|
||||
}
|
||||
|
||||
class LocalDate -> java.time.LocalDate extends Comparable,ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class LocalDate -> java.time.LocalDate extends ChronoLocalDate,Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
LocalDate MAX
|
||||
LocalDate MIN
|
||||
LocalDateTime atStartOfDay()
|
||||
|
@ -154,6 +156,7 @@ class LocalDate -> java.time.LocalDate extends Comparable,ChronoLocalDate,Tempor
|
|||
LocalDate plusMonths(long)
|
||||
LocalDate plusWeeks(long)
|
||||
LocalDate plusDays(long)
|
||||
Period until(ChronoLocalDate)
|
||||
LocalDate with(TemporalAdjuster)
|
||||
LocalDate with(TemporalField,long)
|
||||
LocalDate withDayOfMonth(int)
|
||||
|
@ -162,7 +165,7 @@ class LocalDate -> java.time.LocalDate extends Comparable,ChronoLocalDate,Tempor
|
|||
LocalDate withYear(int)
|
||||
}
|
||||
|
||||
class LocalDateTime -> java.time.LocalDateTime extends Comparable,ChronoLocalDateTime,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class LocalDateTime -> java.time.LocalDateTime extends ChronoLocalDateTime,Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
LocalDateTime MIN
|
||||
LocalDateTime MAX
|
||||
OffsetDateTime atOffset(ZoneOffset)
|
||||
|
@ -208,6 +211,7 @@ class LocalDateTime -> java.time.LocalDateTime extends Comparable,ChronoLocalDat
|
|||
LocalDateTime plusSeconds(long)
|
||||
LocalDateTime plusWeeks(long)
|
||||
LocalDateTime plusYears(long)
|
||||
LocalDate toLocalDate()
|
||||
LocalDateTime truncatedTo(TemporalUnit)
|
||||
LocalDateTime with(TemporalAdjuster)
|
||||
LocalDateTime with(TemporalField,long)
|
||||
|
@ -220,13 +224,14 @@ class LocalDateTime -> java.time.LocalDateTime extends Comparable,ChronoLocalDat
|
|||
LocalDateTime withYear(int)
|
||||
}
|
||||
|
||||
class LocalTime -> java.time.LocalTime extends Comparable,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class LocalTime -> java.time.LocalTime extends Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
LocalTime MAX
|
||||
LocalTime MIDNIGHT
|
||||
LocalTime MIN
|
||||
LocalTime NOON
|
||||
LocalDateTime atDate(LocalDate)
|
||||
OffsetTime atOffset(ZoneOffset)
|
||||
int compareTo(LocalTime)
|
||||
String format(DateTimeFormatter)
|
||||
LocalTime from(TemporalAccessor)
|
||||
int getHour()
|
||||
|
@ -267,8 +272,9 @@ class LocalTime -> java.time.LocalTime extends Comparable,Temporal,TemporalAcces
|
|||
LocalTime withSecond(int)
|
||||
}
|
||||
|
||||
class MonthDay -> java.time.MonthDay extends Comparable,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class MonthDay -> java.time.MonthDay extends TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
LocalDate atYear(int)
|
||||
int compareTo(MonthDay)
|
||||
String format(DateTimeFormatter)
|
||||
MonthDay from(TemporalAccessor)
|
||||
int getMonthValue()
|
||||
|
@ -287,11 +293,12 @@ class MonthDay -> java.time.MonthDay extends Comparable,TemporalAccessor,Tempora
|
|||
MonthDay withMonth(int)
|
||||
}
|
||||
|
||||
class OffsetDateTime -> java.time.OffsetDateTime extends Comparable,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class OffsetDateTime -> java.time.OffsetDateTime extends Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
OffsetDateTime MAX
|
||||
OffsetDateTime MIN
|
||||
ZonedDateTime atZoneSameInstant(ZoneId)
|
||||
ZonedDateTime atZoneSimilarLocal(ZoneId)
|
||||
int compareTo(OffsetDateTime)
|
||||
String format(DateTimeFormatter)
|
||||
OffsetDateTime from(TemporalAccessor)
|
||||
int getDayOfMonth()
|
||||
|
@ -359,9 +366,10 @@ class OffsetDateTime -> java.time.OffsetDateTime extends Comparable,Temporal,Tem
|
|||
OffsetDateTime withOffsetSameInstant(ZoneOffset)
|
||||
}
|
||||
|
||||
class OffsetTime -> java.time.OffsetTime extends Comparable,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class OffsetTime -> java.time.OffsetTime extends Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
OffsetTime MAX
|
||||
OffsetTime MIN
|
||||
int compareTo(OffsetTime)
|
||||
String format(DateTimeFormatter)
|
||||
OffsetTime from(TemporalAccessor)
|
||||
int getHour()
|
||||
|
@ -434,12 +442,13 @@ class Period -> java.time.Period extends ChronoPeriod,TemporalAmount,Object {
|
|||
Period withYears(int)
|
||||
}
|
||||
|
||||
class Year -> java.time.Year extends Comparable,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class Year -> java.time.Year extends Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
int MAX_VALUE
|
||||
int MIN_VALUE
|
||||
LocalDate atDay(int)
|
||||
YearMonth atMonth(int)
|
||||
LocalDate atMonthDay(MonthDay)
|
||||
int compareTo(Year)
|
||||
String format(DateTimeFormatter)
|
||||
Year from(TemporalAccessor)
|
||||
int getValue()
|
||||
|
@ -463,9 +472,10 @@ class Year -> java.time.Year extends Comparable,Temporal,TemporalAccessor,Tempor
|
|||
Year with(TemporalField,long)
|
||||
}
|
||||
|
||||
class YearMonth -> java.time.YearMonth extends Comparable,Temporal,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class YearMonth -> java.time.YearMonth extends Temporal,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
LocalDate atDay(int)
|
||||
LocalDate atEndOfMonth()
|
||||
int compareTo(YearMonth)
|
||||
String format(DateTimeFormatter)
|
||||
YearMonth from(TemporalAccessor)
|
||||
Month getMonth()
|
||||
|
@ -496,7 +506,7 @@ class YearMonth -> java.time.YearMonth extends Comparable,Temporal,TemporalAcces
|
|||
YearMonth withMonth(int)
|
||||
}
|
||||
|
||||
class ZonedDateTime -> java.time.ZonedDateTime extends Comparable,ChronoZonedDateTime,Temporal,TemporalAccessor,Object {
|
||||
class ZonedDateTime -> java.time.ZonedDateTime extends ChronoZonedDateTime,Temporal,TemporalAccessor,Comparable,Object {
|
||||
int getDayOfMonth()
|
||||
DayOfWeek getDayOfWeek()
|
||||
int getDayOfYear()
|
||||
|
@ -589,7 +599,7 @@ class ZoneOffset -> java.time.ZoneOffset extends ZoneId,Object {
|
|||
|
||||
#### Enums
|
||||
|
||||
class DayOfWeek -> java.time.DayOfWeek extends Enum,Comparable,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class DayOfWeek -> java.time.DayOfWeek extends Enum,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
DayOfWeek FRIDAY
|
||||
DayOfWeek MONDAY
|
||||
DayOfWeek SATURDAY
|
||||
|
@ -607,7 +617,7 @@ class DayOfWeek -> java.time.DayOfWeek extends Enum,Comparable,TemporalAccessor,
|
|||
DayOfWeek[] values()
|
||||
}
|
||||
|
||||
class Month -> java.time.Month extends Enum,Comparable,TemporalAccessor,TemporalAdjuster,Object {
|
||||
class Month -> java.time.Month extends Enum,TemporalAccessor,TemporalAdjuster,Comparable,Object {
|
||||
Month APRIL
|
||||
Month AUGUST
|
||||
Month DECEMBER
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#### Classes
|
||||
|
||||
class ZoneOffsetTransition -> java.time.zone.ZoneOffsetTransition extends Comparable,Object {
|
||||
int compareTo(ZoneOffsetTransition)
|
||||
LocalDateTime getDateTimeAfter()
|
||||
LocalDateTime getDateTimeBefore()
|
||||
Duration getDuration()
|
||||
|
|
|
@ -454,6 +454,7 @@ class Calendar -> java.util.Calendar extends Comparable,Object {
|
|||
void clear()
|
||||
void clear(int)
|
||||
def clone()
|
||||
int compareTo(Calendar)
|
||||
int get(int)
|
||||
int getActualMaximum(int)
|
||||
int getActualMinimum(int)
|
||||
|
@ -584,6 +585,7 @@ class Date -> java.util.Date extends Comparable,Object {
|
|||
boolean after(Date)
|
||||
boolean before(Date)
|
||||
def clone()
|
||||
int compareTo(Date)
|
||||
Date from(Instant)
|
||||
long getTime()
|
||||
void setTime(long)
|
||||
|
@ -999,6 +1001,7 @@ class TreeSet -> java.util.TreeSet extends AbstractSet,NavigableSet,SortedSet,Se
|
|||
|
||||
class UUID -> java.util.UUID extends Comparable,Object {
|
||||
UUID <init>(long,long)
|
||||
int compareTo(UUID)
|
||||
int clockSequence()
|
||||
UUID fromString(String)
|
||||
long getLeastSignificantBits()
|
||||
|
@ -1054,101 +1057,101 @@ class Locale.FilteringMode -> java.util.Locale$FilteringMode extends Enum,Compar
|
|||
|
||||
#### Exceptions
|
||||
|
||||
class ConcurrentModificationException -> java.util.ConcurrentModificationException extends RuntimeException,Exception {
|
||||
class ConcurrentModificationException -> java.util.ConcurrentModificationException extends RuntimeException,Exception,Object {
|
||||
ConcurrentModificationException <init>()
|
||||
ConcurrentModificationException <init>(String)
|
||||
}
|
||||
|
||||
class DuplicateFormatFlagsException -> java.util.DuplicateFormatFlagsException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class DuplicateFormatFlagsException -> java.util.DuplicateFormatFlagsException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
DuplicateFormatFlagsException <init>(String)
|
||||
String getFlags()
|
||||
}
|
||||
|
||||
class EmptyStackException -> java.util.EmptyStackException extends RuntimeException,Exception {
|
||||
class EmptyStackException -> java.util.EmptyStackException extends RuntimeException,Exception,Object {
|
||||
EmptyStackException <init>()
|
||||
}
|
||||
|
||||
class FormatFlagsConversionMismatchException -> java.util.FormatFlagsConversionMismatchException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class FormatFlagsConversionMismatchException -> java.util.FormatFlagsConversionMismatchException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
FormatFlagsConversionMismatchException <init>(String,char)
|
||||
char getConversion()
|
||||
String getFlags()
|
||||
}
|
||||
|
||||
class FormatterClosedException -> java.util.FormatterClosedException extends IllegalStateException,RuntimeException,Exception {
|
||||
class FormatterClosedException -> java.util.FormatterClosedException extends IllegalStateException,RuntimeException,Exception,Object {
|
||||
FormatterClosedException <init>()
|
||||
}
|
||||
|
||||
class IllegalFormatCodePointException -> java.util.IllegalFormatCodePointException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class IllegalFormatCodePointException -> java.util.IllegalFormatCodePointException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
IllegalFormatCodePointException <init>(int)
|
||||
int getCodePoint()
|
||||
}
|
||||
|
||||
class IllegalFormatConversionException -> java.util.IllegalFormatConversionException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class IllegalFormatConversionException -> java.util.IllegalFormatConversionException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
char getConversion()
|
||||
}
|
||||
|
||||
class IllegalFormatException -> java.util.IllegalFormatException extends IllegalArgumentException,RuntimeException,Exception {
|
||||
class IllegalFormatException -> java.util.IllegalFormatException extends IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
}
|
||||
|
||||
class IllegalFormatFlagsException -> java.util.IllegalFormatFlagsException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class IllegalFormatFlagsException -> java.util.IllegalFormatFlagsException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
IllegalFormatFlagsException <init>(String)
|
||||
String getFlags()
|
||||
}
|
||||
|
||||
class IllegalFormatPrecisionException -> java.util.IllegalFormatPrecisionException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class IllegalFormatPrecisionException -> java.util.IllegalFormatPrecisionException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
IllegalFormatPrecisionException <init>(int)
|
||||
int getPrecision()
|
||||
}
|
||||
|
||||
class IllegalFormatWidthException -> java.util.IllegalFormatWidthException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class IllegalFormatWidthException -> java.util.IllegalFormatWidthException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
IllegalFormatWidthException <init>(int)
|
||||
int getWidth()
|
||||
}
|
||||
|
||||
class IllformedLocaleException -> java.util.IllformedLocaleException extends RuntimeException,Exception {
|
||||
class IllformedLocaleException -> java.util.IllformedLocaleException extends RuntimeException,Exception,Object {
|
||||
IllformedLocaleException <init>()
|
||||
IllformedLocaleException <init>(String)
|
||||
IllformedLocaleException <init>(String,int)
|
||||
int getErrorIndex()
|
||||
}
|
||||
|
||||
class InputMismatchException -> java.util.InputMismatchException extends NoSuchElementException,RuntimeException,Exception {
|
||||
class InputMismatchException -> java.util.InputMismatchException extends NoSuchElementException,RuntimeException,Exception,Object {
|
||||
InputMismatchException <init>()
|
||||
InputMismatchException <init>(String)
|
||||
}
|
||||
|
||||
class MissingFormatArgumentException -> java.util.MissingFormatArgumentException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class MissingFormatArgumentException -> java.util.MissingFormatArgumentException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
MissingFormatArgumentException <init>(String)
|
||||
String getFormatSpecifier()
|
||||
}
|
||||
|
||||
class MissingFormatWidthException -> java.util.MissingFormatWidthException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class MissingFormatWidthException -> java.util.MissingFormatWidthException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
MissingFormatWidthException <init>(String)
|
||||
String getFormatSpecifier()
|
||||
}
|
||||
|
||||
class MissingResourceException -> java.util.MissingResourceException extends RuntimeException,Exception {
|
||||
class MissingResourceException -> java.util.MissingResourceException extends RuntimeException,Exception,Object {
|
||||
MissingResourceException <init>(String,String,String)
|
||||
String getClassName()
|
||||
String getKey()
|
||||
}
|
||||
|
||||
class NoSuchElementException -> java.util.NoSuchElementException extends RuntimeException,Exception {
|
||||
class NoSuchElementException -> java.util.NoSuchElementException extends RuntimeException,Exception,Object {
|
||||
NoSuchElementException <init>()
|
||||
NoSuchElementException <init>(String)
|
||||
}
|
||||
|
||||
class TooManyListenersException -> java.util.TooManyListenersException extends Exception {
|
||||
class TooManyListenersException -> java.util.TooManyListenersException extends Exception,Object {
|
||||
TooManyListenersException <init>()
|
||||
TooManyListenersException <init>(String)
|
||||
}
|
||||
|
||||
class UnknownFormatConversionException -> java.util.UnknownFormatConversionException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class UnknownFormatConversionException -> java.util.UnknownFormatConversionException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
UnknownFormatConversionException <init>(String)
|
||||
String getConversion()
|
||||
}
|
||||
|
||||
class UnknownFormatFlagsException -> java.util.UnknownFormatFlagsException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception {
|
||||
class UnknownFormatFlagsException -> java.util.UnknownFormatFlagsException extends IllegalFormatException,IllegalArgumentException,RuntimeException,Exception,Object {
|
||||
UnknownFormatFlagsException <init>(String)
|
||||
String getFlags()
|
||||
}
|
||||
|
|
|
@ -65,22 +65,26 @@ class org.elasticsearch.common.geo.GeoPoint -> org.elasticsearch.common.geo.GeoP
|
|||
}
|
||||
|
||||
class org.elasticsearch.index.fielddata.ScriptDocValues.Strings -> org.elasticsearch.index.fielddata.ScriptDocValues$Strings extends List,Collection,Iterable,Object {
|
||||
String get(int)
|
||||
String getValue()
|
||||
List getValues()
|
||||
}
|
||||
|
||||
class org.elasticsearch.index.fielddata.ScriptDocValues.Longs -> org.elasticsearch.index.fielddata.ScriptDocValues$Longs extends List,Collection,Iterable,Object {
|
||||
Long get(int)
|
||||
long getValue()
|
||||
List getValues()
|
||||
org.joda.time.ReadableDateTime getDate()
|
||||
}
|
||||
|
||||
class org.elasticsearch.index.fielddata.ScriptDocValues.Doubles -> org.elasticsearch.index.fielddata.ScriptDocValues$Doubles extends List,Collection,Iterable,Object {
|
||||
Double get(int)
|
||||
double getValue()
|
||||
List getValues()
|
||||
}
|
||||
|
||||
class org.elasticsearch.index.fielddata.ScriptDocValues.GeoPoints -> org.elasticsearch.index.fielddata.ScriptDocValues$GeoPoints extends List,Collection,Iterable,Object {
|
||||
org.elasticsearch.common.geo.GeoPoint get(int)
|
||||
org.elasticsearch.common.geo.GeoPoint getValue()
|
||||
List getValues()
|
||||
double getLat()
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.painless;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -111,7 +110,13 @@ public class BasicAPITests extends ScriptTestCase {
|
|||
assertBytecodeExists("def x = 1D", "INVOKESTATIC java/lang/Double.valueOf (D)Ljava/lang/Double;");
|
||||
}
|
||||
|
||||
void testStream() {
|
||||
assertEquals(11, exec("params.list.stream().sum()", Collections.singletonMap("list", Arrays.asList(1,2,3,5))));
|
||||
public void testInterfaceDefaultMethods() {
|
||||
assertEquals(1, exec("Map map = new HashMap(); return map.getOrDefault(5,1);"));
|
||||
assertEquals(1, exec("def map = new HashMap(); return map.getOrDefault(5,1);"));
|
||||
}
|
||||
|
||||
public void testInterfacesHaveObject() {
|
||||
assertEquals("{}", exec("Map map = new HashMap(); return map.toString();"));
|
||||
assertEquals("{}", exec("def map = new HashMap(); return map.toString();"));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class DefBootstrapTests extends ESTestCase {
|
|||
CallSite site = DefBootstrap.bootstrap(MethodHandles.publicLookup(),
|
||||
"toString",
|
||||
MethodType.methodType(String.class, Object.class),
|
||||
DefBootstrap.METHOD_CALL);
|
||||
DefBootstrap.METHOD_CALL, 0);
|
||||
MethodHandle handle = site.dynamicInvoker();
|
||||
assertDepthEquals(site, 0);
|
||||
|
||||
|
@ -50,7 +50,7 @@ public class DefBootstrapTests extends ESTestCase {
|
|||
CallSite site = DefBootstrap.bootstrap(MethodHandles.publicLookup(),
|
||||
"toString",
|
||||
MethodType.methodType(String.class, Object.class),
|
||||
DefBootstrap.METHOD_CALL);
|
||||
DefBootstrap.METHOD_CALL, 0);
|
||||
MethodHandle handle = site.dynamicInvoker();
|
||||
assertDepthEquals(site, 0);
|
||||
|
||||
|
@ -72,7 +72,7 @@ public class DefBootstrapTests extends ESTestCase {
|
|||
CallSite site = DefBootstrap.bootstrap(MethodHandles.publicLookup(),
|
||||
"toString",
|
||||
MethodType.methodType(String.class, Object.class),
|
||||
DefBootstrap.METHOD_CALL);
|
||||
DefBootstrap.METHOD_CALL, 0);
|
||||
MethodHandle handle = site.dynamicInvoker();
|
||||
assertDepthEquals(site, 0);
|
||||
|
||||
|
|
|
@ -20,11 +20,60 @@
|
|||
package org.elasticsearch.painless;
|
||||
|
||||
public class FunctionRefTests extends ScriptTestCase {
|
||||
public void testUnsupported() {
|
||||
expectScriptThrows(UnsupportedOperationException.class, () -> {
|
||||
exec("DoubleStream.Builder builder = DoubleStream.builder();" +
|
||||
"builder.add(2.0); builder.add(1.0); builder.add(3.0);" +
|
||||
"builder.build().reduce(Double::unsupported);");
|
||||
|
||||
public void testStaticMethodReference() {
|
||||
assertEquals(1, exec("List l = new ArrayList(); l.add(2); l.add(1); l.sort(Integer::compare); return l.get(0);"));
|
||||
}
|
||||
|
||||
public void testStaticMethodReferenceDef() {
|
||||
assertEquals(1, exec("def l = new ArrayList(); l.add(2); l.add(1); l.sort(Integer::compare); return l.get(0);"));
|
||||
}
|
||||
|
||||
public void testVirtualMethodReference() {
|
||||
assertEquals(2, exec("List l = new ArrayList(); l.add(1); l.add(1); return l.stream().mapToInt(Integer::intValue).sum();"));
|
||||
}
|
||||
|
||||
public void testVirtualMethodReferenceDef() {
|
||||
assertEquals(2, exec("def l = new ArrayList(); l.add(1); l.add(1); return l.stream().mapToInt(Integer::intValue).sum();"));
|
||||
}
|
||||
|
||||
public void testCtorMethodReference() {
|
||||
assertEquals(3.0D,
|
||||
exec("List l = new ArrayList(); l.add(1.0); l.add(2.0); " +
|
||||
"DoubleStream doubleStream = l.stream().mapToDouble(Double::doubleValue);" +
|
||||
"DoubleSummaryStatistics stats = doubleStream.collect(DoubleSummaryStatistics::new, " +
|
||||
"DoubleSummaryStatistics::accept, " +
|
||||
"DoubleSummaryStatistics::combine); " +
|
||||
"return stats.getSum()"));
|
||||
}
|
||||
|
||||
public void testCtorMethodReferenceDef() {
|
||||
assertEquals(3.0D,
|
||||
exec("def l = new ArrayList(); l.add(1.0); l.add(2.0); " +
|
||||
"def doubleStream = l.stream().mapToDouble(Double::doubleValue);" +
|
||||
"def stats = doubleStream.collect(DoubleSummaryStatistics::new, " +
|
||||
"DoubleSummaryStatistics::accept, " +
|
||||
"DoubleSummaryStatistics::combine); " +
|
||||
"return stats.getSum()"));
|
||||
}
|
||||
|
||||
public void testMethodMissing() {
|
||||
IllegalArgumentException expected = expectScriptThrows(IllegalArgumentException.class, () -> {
|
||||
exec("List l = new ArrayList(); l.add(2); l.add(1); l.sort(Integer::bogus); return l.get(0);");
|
||||
});
|
||||
assertTrue(expected.getMessage().contains("Unknown reference"));
|
||||
}
|
||||
|
||||
public void testNotFunctionalInterface() {
|
||||
IllegalArgumentException expected = expectScriptThrows(IllegalArgumentException.class, () -> {
|
||||
exec("List l = new ArrayList(); l.add(2); l.add(1); l.add(Integer::bogus); return l.get(0);");
|
||||
});
|
||||
assertTrue(expected.getMessage().contains("Cannot convert function reference"));
|
||||
}
|
||||
|
||||
public void testIncompatible() {
|
||||
expectScriptThrows(BootstrapMethodError.class, () -> {
|
||||
exec("List l = new ArrayList(); l.add(2); l.add(1); l.sort(String::startsWith); return l.get(0);");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public class OverloadTests extends ScriptTestCase {
|
|||
IllegalArgumentException expected = expectScriptThrows(IllegalArgumentException.class, () -> {
|
||||
exec("def x = 'abc123abc'; return x.indexOf('c', 3, 'bogus');");
|
||||
});
|
||||
assertTrue(expected.getMessage().contains("dynamic method [indexOf] with signature [(String,int,String)"));
|
||||
assertTrue(expected.getMessage().contains("dynamic method [indexOf]"));
|
||||
}
|
||||
|
||||
public void testConstructor() {
|
||||
|
|
Loading…
Reference in New Issue