Search in sources :

Example 6 with Method

use of org.elasticsearch.painless.Definition.Method in project elasticsearch by elastic.

the class NodeToStringTests method testPSubCallInvoke.

public void testPSubCallInvoke() {
    Location l = new Location(getTestName(), 0);
    RuntimeClass c = Definition.getRuntimeClass(Integer.class);
    Method m = c.methods.get(new MethodKey("toString", 0));
    PSubCallInvoke node = new PSubCallInvoke(l, m, null, emptyList());
    node.prefix = new EVariable(l, "a");
    assertEquals("(PSubCallInvoke (EVariable a) toString)", node.toString());
    assertEquals("(PSubNullSafeCallInvoke (PSubCallInvoke (EVariable a) toString))", new PSubNullSafeCallInvoke(l, node).toString());
    l = new Location(getTestName(), 1);
    m = c.methods.get(new MethodKey("equals", 1));
    node = new PSubCallInvoke(l, m, null, singletonList(new EVariable(l, "b")));
    node.prefix = new EVariable(l, "a");
    assertEquals("(PSubCallInvoke (EVariable a) equals (Args (EVariable b)))", node.toString());
    assertEquals("(PSubNullSafeCallInvoke (PSubCallInvoke (EVariable a) equals (Args (EVariable b))))", new PSubNullSafeCallInvoke(l, node).toString());
}
Also used : Method(org.elasticsearch.painless.Definition.Method) RuntimeClass(org.elasticsearch.painless.Definition.RuntimeClass) Location(org.elasticsearch.painless.Location) MethodKey(org.elasticsearch.painless.Definition.MethodKey)

Example 7 with Method

use of org.elasticsearch.painless.Definition.Method in project elasticsearch by elastic.

the class SFunction method generateSignature.

void generateSignature() {
    try {
        rtnType = Definition.getType(rtnTypeStr);
    } catch (IllegalArgumentException exception) {
        throw createError(new IllegalArgumentException("Illegal return type [" + rtnTypeStr + "] for function [" + name + "]."));
    }
    if (paramTypeStrs.size() != paramNameStrs.size()) {
        throw createError(new IllegalStateException("Illegal tree structure."));
    }
    Class<?>[] paramClasses = new Class<?>[this.paramTypeStrs.size()];
    List<Type> paramTypes = new ArrayList<>();
    for (int param = 0; param < this.paramTypeStrs.size(); ++param) {
        try {
            Type paramType = Definition.getType(this.paramTypeStrs.get(param));
            paramClasses[param] = paramType.clazz;
            paramTypes.add(paramType);
            parameters.add(new Parameter(location, paramNameStrs.get(param), paramType));
        } catch (IllegalArgumentException exception) {
            throw createError(new IllegalArgumentException("Illegal parameter type [" + this.paramTypeStrs.get(param) + "] for function [" + name + "]."));
        }
    }
    org.objectweb.asm.commons.Method method = new org.objectweb.asm.commons.Method(name, MethodType.methodType(rtnType.clazz, paramClasses).toMethodDescriptorString());
    this.method = new Method(name, null, false, rtnType, paramTypes, method, Modifier.STATIC | Modifier.PRIVATE, null);
}
Also used : ArrayList(java.util.ArrayList) Method(org.elasticsearch.painless.Definition.Method) Type(org.elasticsearch.painless.Definition.Type) MethodType(java.lang.invoke.MethodType) Parameter(org.elasticsearch.painless.Locals.Parameter)

Example 8 with Method

use of org.elasticsearch.painless.Definition.Method in project elasticsearch by elastic.

the class EFunctionRef method analyze.

@Override
void analyze(Locals locals) {
    if (expected == null) {
        ref = null;
        actual = Definition.getType("String");
        defPointer = "S" + type + "." + call + ",0";
    } else {
        defPointer = null;
        try {
            if ("this".equals(type)) {
                // user's own function
                Method interfaceMethod = expected.struct.getFunctionalMethod();
                if (interfaceMethod == null) {
                    throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + "to [" + expected.name + "], not a functional interface");
                }
                Method implMethod = locals.getMethod(new MethodKey(call, interfaceMethod.arguments.size()));
                if (implMethod == null) {
                    throw new IllegalArgumentException("Cannot convert function reference [" + type + "::" + call + "] " + "to [" + expected.name + "], function not found");
                }
                ref = new FunctionRef(expected, interfaceMethod, implMethod, 0);
            } else {
                // whitelist lookup
                ref = new FunctionRef(expected, type, call, 0);
            }
        } catch (IllegalArgumentException e) {
            throw createError(e);
        }
        actual = expected;
    }
}
Also used : Method(org.elasticsearch.painless.Definition.Method) MethodKey(org.elasticsearch.painless.Definition.MethodKey) FunctionRef(org.elasticsearch.painless.FunctionRef)

Example 9 with Method

use of org.elasticsearch.painless.Definition.Method in project elasticsearch by elastic.

the class PainlessDocGenerator method main.

public static void main(String[] args) throws IOException {
    Path apiRootPath = PathUtils.get(args[0]);
    // Blow away the last execution and recreate it from scratch
    IOUtils.rm(apiRootPath);
    Files.createDirectories(apiRootPath);
    Path indexPath = apiRootPath.resolve("index.asciidoc");
    logger.info("Starting to write [index.asciidoc]");
    try (PrintStream indexStream = new PrintStream(Files.newOutputStream(indexPath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE), false, StandardCharsets.UTF_8.name())) {
        emitGeneratedWarning(indexStream);
        List<Type> types = Definition.allSimpleTypes().stream().sorted(comparing(t -> t.name)).collect(toList());
        for (Type type : types) {
            if (type.sort.primitive) {
                // Primitives don't have methods to reference
                continue;
            }
            if ("def".equals(type.name)) {
                // def is special but doesn't have any methods all of its own.
                continue;
            }
            indexStream.print("include::");
            indexStream.print(type.struct.name);
            indexStream.println(".asciidoc[]");
            Path typePath = apiRootPath.resolve(type.struct.name + ".asciidoc");
            logger.info("Writing [{}.asciidoc]", type.name);
            try (PrintStream typeStream = new PrintStream(Files.newOutputStream(typePath, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE), false, StandardCharsets.UTF_8.name())) {
                emitGeneratedWarning(typeStream);
                typeStream.print("[[");
                emitAnchor(typeStream, type.struct);
                typeStream.print("]]++");
                typeStream.print(type.name);
                typeStream.println("++::");
                Consumer<Field> documentField = field -> PainlessDocGenerator.documentField(typeStream, field);
                Consumer<Method> documentMethod = method -> PainlessDocGenerator.documentMethod(typeStream, method);
                type.struct.staticMembers.values().stream().sorted(FIELD_NAME).forEach(documentField);
                type.struct.members.values().stream().sorted(FIELD_NAME).forEach(documentField);
                type.struct.staticMethods.values().stream().sorted(METHOD_NAME.thenComparing(NUMBER_OF_ARGS)).forEach(documentMethod);
                type.struct.constructors.values().stream().sorted(NUMBER_OF_ARGS).forEach(documentMethod);
                Map<String, Struct> inherited = new TreeMap<>();
                type.struct.methods.values().stream().sorted(METHOD_NAME.thenComparing(NUMBER_OF_ARGS)).forEach(method -> {
                    if (method.owner == type.struct) {
                        documentMethod(typeStream, method);
                    } else {
                        inherited.put(method.owner.name, method.owner);
                    }
                });
                if (false == inherited.isEmpty()) {
                    typeStream.print("* Inherits methods from ");
                    boolean first = true;
                    for (Struct inheritsFrom : inherited.values()) {
                        if (first) {
                            first = false;
                        } else {
                            typeStream.print(", ");
                        }
                        typeStream.print("++");
                        emitStruct(typeStream, inheritsFrom);
                        typeStream.print("++");
                    }
                    typeStream.println();
                }
            }
        }
    }
    logger.info("Done writing [index.asciidoc]");
}
Also used : Path(java.nio.file.Path) PrintStream(java.io.PrintStream) Field(org.elasticsearch.painless.Definition.Field) Augmentation(org.elasticsearch.painless.api.Augmentation) Files(java.nio.file.Files) StandardOpenOption(java.nio.file.StandardOpenOption) IOUtils(org.apache.lucene.util.IOUtils) IOException(java.io.IOException) Type(org.elasticsearch.painless.Definition.Type) StandardCharsets(java.nio.charset.StandardCharsets) Struct(org.elasticsearch.painless.Definition.Struct) Consumer(java.util.function.Consumer) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) Logger(org.apache.logging.log4j.Logger) Method(org.elasticsearch.painless.Definition.Method) TreeMap(java.util.TreeMap) ESLoggerFactory(org.elasticsearch.common.logging.ESLoggerFactory) Modifier(java.lang.reflect.Modifier) Map(java.util.Map) Comparator.comparing(java.util.Comparator.comparing) Comparator(java.util.Comparator) Path(java.nio.file.Path) PathUtils(org.elasticsearch.common.io.PathUtils) PrintStream(java.io.PrintStream) Method(org.elasticsearch.painless.Definition.Method) TreeMap(java.util.TreeMap) Struct(org.elasticsearch.painless.Definition.Struct) Field(org.elasticsearch.painless.Definition.Field) Type(org.elasticsearch.painless.Definition.Type)

Example 10 with Method

use of org.elasticsearch.painless.Definition.Method in project elasticsearch by elastic.

the class PCallInvoke method analyze.

@Override
void analyze(Locals locals) {
    prefix.analyze(locals);
    prefix.expected = prefix.actual;
    prefix = prefix.cast(locals);
    if (prefix.actual.sort == Sort.ARRAY) {
        throw createError(new IllegalArgumentException("Illegal call [" + name + "] on array type."));
    }
    Struct struct = prefix.actual.struct;
    if (prefix.actual.sort.primitive) {
        struct = Definition.getType(prefix.actual.sort.boxed.getSimpleName()).struct;
    }
    MethodKey methodKey = new MethodKey(name, arguments.size());
    Method method = prefix instanceof EStatic ? struct.staticMethods.get(methodKey) : struct.methods.get(methodKey);
    if (method != null) {
        sub = new PSubCallInvoke(location, method, prefix.actual, arguments);
    } else if (prefix.actual.sort == Sort.DEF) {
        sub = new PSubDefCall(location, name, arguments);
    } else {
        throw createError(new IllegalArgumentException("Unknown call [" + name + "] with [" + arguments.size() + "] arguments on type [" + struct.name + "]."));
    }
    if (nullSafe) {
        sub = new PSubNullSafeCallInvoke(location, sub);
    }
    sub.expected = expected;
    sub.explicit = explicit;
    sub.analyze(locals);
    actual = sub.actual;
    statement = true;
}
Also used : Method(org.elasticsearch.painless.Definition.Method) Struct(org.elasticsearch.painless.Definition.Struct) MethodKey(org.elasticsearch.painless.Definition.MethodKey)

Aggregations

Method (org.elasticsearch.painless.Definition.Method)13 MethodKey (org.elasticsearch.painless.Definition.MethodKey)5 Struct (org.elasticsearch.painless.Definition.Struct)4 Type (org.elasticsearch.painless.Definition.Type)3 CallSite (java.lang.invoke.CallSite)2 MethodHandle (java.lang.invoke.MethodHandle)2 MethodType (java.lang.invoke.MethodType)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Map (java.util.Map)2 Field (org.elasticsearch.painless.Definition.Field)2 RuntimeClass (org.elasticsearch.painless.Definition.RuntimeClass)2 FunctionRef (org.elasticsearch.painless.FunctionRef)2 Location (org.elasticsearch.painless.Location)2 IOException (java.io.IOException)1 PrintStream (java.io.PrintStream)1 Modifier (java.lang.reflect.Modifier)1 StandardCharsets (java.nio.charset.StandardCharsets)1 Files (java.nio.file.Files)1 Path (java.nio.file.Path)1