presto-main/src/main/java/io/prestosql/operator/scalar/annotations/ParametricScalarImplementation.java/ParametricScalarImplementation/javaMethodType
class ParametricScalarImplementation:    private static MethodType javaMethodType(ParametricScalarImplementationChoice choice, Signature signature, Metadata metadata)
    {
        // This method accomplishes two purposes:
        // * Assert that the method signature is as expected.
        //   This catches errors that would otherwise surface during bytecode generation and class loading.
        // * Adapt the method signature when necessary (for example, when the parameter type or return type is declared as Object).
        ImmutableList.Builder<Class<?>> methodHandleParameterTypes = ImmutableList.builder();
        if (choice.getConstructor().isPresent()) {
            methodHandleParameterTypes.add(Object.class);
        }
        if (choice.hasConnectorSession()) {
            methodHandleParameterTypes.add(ConnectorSession.class);
        }

        List<ArgumentProperty> argumentProperties = choice.getArgumentProperties();
        for (int i = 0; i < argumentProperties.size(); i++) {
            ArgumentProperty argumentProperty = argumentProperties.get(i);
            switch (argumentProperty.getArgumentType()) {
                case VALUE_TYPE:
                    Type signatureType = metadata.getType(signature.getArgumentTypes().get(i));
                    switch (argumentProperty.getNullConvention()) {
                        case RETURN_NULL_ON_NULL:
                            methodHandleParameterTypes.add(signatureType.getJavaType());
                            break;
                        case USE_NULL_FLAG:
                            methodHandleParameterTypes.add(signatureType.getJavaType());
                            methodHandleParameterTypes.add(boolean.class);
                            break;
                        case USE_BOXED_TYPE:
                            methodHandleParameterTypes.add(Primitives.wrap(signatureType.getJavaType()));
                            break;
                        case BLOCK_AND_POSITION:
                            methodHandleParameterTypes.add(Block.class);
                            methodHandleParameterTypes.add(int.class);
                            break;
                        default:
                            throw new UnsupportedOperationException("unknown NullConvention");
                    }
                    break;
                case FUNCTION_TYPE:
                    methodHandleParameterTypes.add(argumentProperty.getLambdaInterface());
                    break;
                default:
                    throw new UnsupportedOperationException("unknown ArgumentType");
            }
        }

        Class<?> methodHandleReturnType = metadata.getType(signature.getReturnType()).getJavaType();
        if (choice.isNullable()) {
            methodHandleReturnType = Primitives.wrap(methodHandleReturnType);
        }

        return MethodType.methodType(methodHandleReturnType, methodHandleParameterTypes.build());
    }