Search in sources :

Example 6 with ClassGenerator

use of org.neo4j.codegen.ClassGenerator in project neo4j by neo4j.

the class ProcedureCompilation method generateAggregator.

private static Class<?> generateAggregator(CodeGenerator codeGenerator, Method update, Method result, UserFunctionSignature signature) {
    assert update.getDeclaringClass().equals(result.getDeclaringClass());
    Class<?> userAggregatorClass = update.getDeclaringClass();
    ClassHandle handle;
    try (ClassGenerator generator = codeGenerator.generateClass(PACKAGE, "Aggregator" + userAggregatorClass.getSimpleName() + System.nanoTime(), UserAggregator.class)) {
        FieldReference aggregator = generator.field(userAggregatorClass, "aggregator");
        FieldReference context = generator.field(Context.class, "ctx");
        // constructor
        try (CodeBlock constructor = generator.generateConstructor(param(userAggregatorClass, "aggregator"), param(Context.class, "ctx"))) {
            constructor.expression(invokeSuper(OBJECT));
            constructor.put(constructor.self(), aggregator, constructor.load("aggregator"));
            constructor.put(constructor.self(), context, constructor.load("ctx"));
        }
        // update
        try (CodeBlock block = generator.generate(AGGREGATION_UPDATE)) {
            block.tryCatch(onSuccess -> onSuccess.expression(invoke(get(onSuccess.self(), aggregator), methodReference(update), parameters(onSuccess, update, get(onSuccess.self(), context)))), onError -> onError(onError, format("function `%s`", signature.name())), param(Throwable.class, "T"));
        }
        // result
        try (CodeBlock block = generator.generate(AGGREGATION_RESULT)) {
            block.tryCatch(onSuccess -> onSuccess.returns(toAnyValue(invoke(get(onSuccess.self(), aggregator), methodReference(result)), result.getReturnType(), get(onSuccess.self(), context))), onError -> onError(onError, format("function `%s`", signature.name())), param(Throwable.class, "T"));
        }
        handle = generator.handle();
    }
    try {
        return handle.loadClass();
    } catch (CompilationFailureException e) {
        // We are being called from a lambda so it'll have to do with runtime exceptions here
        throw new RuntimeException("Failed to generate iterator", e);
    }
}
Also used : Context(org.neo4j.kernel.api.procedure.Context) ClassGenerator(org.neo4j.codegen.ClassGenerator) FieldReference(org.neo4j.codegen.FieldReference) CodeBlock(org.neo4j.codegen.CodeBlock) ClassHandle(org.neo4j.codegen.ClassHandle) CompilationFailureException(org.neo4j.codegen.CompilationFailureException)

Aggregations

ClassGenerator (org.neo4j.codegen.ClassGenerator)6 ClassHandle (org.neo4j.codegen.ClassHandle)6 CodeBlock (org.neo4j.codegen.CodeBlock)6 FieldReference (org.neo4j.codegen.FieldReference)5 CodeGenerator (org.neo4j.codegen.CodeGenerator)4 CompilationFailureException (org.neo4j.codegen.CompilationFailureException)3 ProcedureException (org.neo4j.internal.kernel.api.exceptions.ProcedureException)3 ProcedureSignature (org.neo4j.internal.kernel.api.procs.ProcedureSignature)2 UserFunctionSignature (org.neo4j.internal.kernel.api.procs.UserFunctionSignature)2 Context (org.neo4j.kernel.api.procedure.Context)2 Field (java.lang.reflect.Field)1 Stream (java.util.stream.Stream)1 Test (org.junit.jupiter.api.Test)1 Expression (org.neo4j.codegen.Expression)1 Point (org.neo4j.graphdb.spatial.Point)1 ResourceTracker (org.neo4j.kernel.api.ResourceTracker)1 CallableProcedure (org.neo4j.kernel.api.procedure.CallableProcedure)1 CallableUserAggregationFunction (org.neo4j.kernel.api.procedure.CallableUserAggregationFunction)1 CallableUserFunction (org.neo4j.kernel.api.procedure.CallableUserFunction)1