<commit_before>require 'gir_ffi/builder/type'
require 'gir_ffi/builder/type/unintrospectable'
require 'gir_ffi/builder/module'
require 'gir_ffi/builder_helper'

module GirFFI
  # Builds modules and classes based on information found in the
  # introspection repository. Call its build_module and build_class methods
  # to create the modules and classes used in your program.
  module Builder
    extend BuilderHelper

    def self.build_class info
      Builder::Type.build(info)
    end

    def self.build_by_gtype gtype
      info = GObjectIntrospection::IRepository.default.find_by_gtype gtype
      if info.nil?
        Builder::Type::Unintrospectable.new(gtype).build_class
      else
        build_class info
      end
    end

    def self.build_module namespace, version=nil
      Builder::Module.new(namespace, version).generate
    end

    def self.build_module_non_recursive namespace, version=nil
      Builder::Module.new(namespace, version).build_module_non_recursive
    end

    def self.build_callback callable_info, &block
      rettype = GirFFI::Builder.itypeinfo_to_ffitype callable_info.return_type
      argtypes = GirFFI::Builder.ffi_argument_types_for_signal callable_info

      FFI::Function.new rettype, argtypes, &block
    end

    # TODO: Move elsewhere, perhaps to Builder::Function.
    def self.attach_ffi_function lib, info
      sym = info.symbol
      return if lib.method_defined? sym
      argtypes = ffi_function_argument_types info
      rt = ffi_function_return_type info

      lib.attach_function sym, argtypes, rt
    end

    def self.ffi_function_argument_types info
      types = info.args.map { |arg| iarginfo_to_ffitype arg }

      if info.info_type == :function
	types.unshift :pointer if info.method?
	types << :pointer if info.throws?
      end

      types
    end

    def self.ffi_argument_types_for_signal info
      types = info.args.map do |arg|
        itypeinfo_to_callback_ffitype arg.argument_type
      end
      types.unshift(:pointer).push(:pointer)
    end

    def self.ffi_function_return_type info
      rt = info.return_type
      # FIXME: Workaround for older gobject-introspection not identifying all
      # objects as being pointers.<commit_msg>Ensure callback return type is never a GObject<commit_after>require 'gir_ffi/builder/type'
require 'gir_ffi/builder/type/unintrospectable'
require 'gir_ffi/builder/module'
require 'gir_ffi/builder_helper'

module GirFFI
  # Builds modules and classes based on information found in the
  # introspection repository. Call its build_module and build_class methods
  # to create the modules and classes used in your program.
  module Builder
    extend BuilderHelper

    def self.build_class info
      Builder::Type.build(info)
    end

    def self.build_by_gtype gtype
      info = GObjectIntrospection::IRepository.default.find_by_gtype gtype
      if info.nil?
        Builder::Type::Unintrospectable.new(gtype).build_class
      else
        build_class info
      end
    end

    def self.build_module namespace, version=nil
      Builder::Module.new(namespace, version).generate
    end

    def self.build_module_non_recursive namespace, version=nil
      Builder::Module.new(namespace, version).build_module_non_recursive
    end

    def self.build_callback callable_info, &block
      rettype = ffi_callback_return_type callable_info
      argtypes = ffi_callback_argument_types callable_info

      FFI::Function.new rettype, argtypes, &block
    end

    # TODO: Move elsewhere, perhaps to Builder::Function.
    def self.attach_ffi_function lib, info
      sym = info.symbol
      return if lib.method_defined? sym
      argtypes = ffi_function_argument_types info
      rt = ffi_function_return_type info

      lib.attach_function sym, argtypes, rt
    end

    def self.ffi_function_argument_types info
      types = info.args.map { |arg| iarginfo_to_ffitype arg }

      if info.info_type == :function
	types.unshift :pointer if info.method?
	types << :pointer if info.throws?
      end

      types
    end

    def self.ffi_callback_argument_types info
      types = info.args.map do |arg|
        itypeinfo_to_callback_ffitype arg.argument_type
      end
      types.unshift(:pointer).push(:pointer)
    end

    def self.ffi_callback_return_type info
      ffi_function_return_type info
    end

    def self.ffi_function_return_type info
      rt = info.return_type
      # FIXME: Workaround for older gobject-introspection not identifying all
      # objects as being pointers.
{'fraction_non_alphanumeric': 0.06279018350652223, 'fraction_numerical': 0.0, 'mean_word_length': 3.3126787416587224, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5411368', 'n_tokens_mistral': 1393, 'n_tokens_neox': 1358, 'n_words': 348}