ruby_header_parser 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.rspec +3 -0
 - data/.rubocop.yml +55 -0
 - data/.yardopts +7 -0
 - data/CHANGELOG.md +5 -0
 - data/CONFIG.md +126 -0
 - data/LICENSE.txt +21 -0
 - data/README.md +67 -0
 - data/Rakefile +30 -0
 - data/Steepfile +33 -0
 - data/config/default.yml +170 -0
 - data/lib/ruby_header_parser/argument_definition.rb +45 -0
 - data/lib/ruby_header_parser/config.rb +77 -0
 - data/lib/ruby_header_parser/enum_definition.rb +27 -0
 - data/lib/ruby_header_parser/function_definition.rb +40 -0
 - data/lib/ruby_header_parser/parser.rb +376 -0
 - data/lib/ruby_header_parser/struct_definition.rb +21 -0
 - data/lib/ruby_header_parser/type_definition.rb +21 -0
 - data/lib/ruby_header_parser/typeref_definition.rb +32 -0
 - data/lib/ruby_header_parser/util.rb +29 -0
 - data/lib/ruby_header_parser/version.rb +5 -0
 - data/lib/ruby_header_parser.rb +21 -0
 - data/rbs_collection.lock.yaml +116 -0
 - data/rbs_collection.yaml +26 -0
 - data/sig/ruby_header_parser/argument_definition.rbs +14 -0
 - data/sig/ruby_header_parser/config.rbs +19 -0
 - data/sig/ruby_header_parser/enum_definition.rbs +10 -0
 - data/sig/ruby_header_parser/function_definition.rbs +12 -0
 - data/sig/ruby_header_parser/parser.rbs +84 -0
 - data/sig/ruby_header_parser/struct_definition.rbs +9 -0
 - data/sig/ruby_header_parser/type_definition.rbs +9 -0
 - data/sig/ruby_header_parser/typeref_definition.rbs +12 -0
 - data/sig/ruby_header_parser/util.rbs +9 -0
 - data/sig/ruby_header_parser.rbs +7 -0
 - metadata +207 -0
 
| 
         @@ -0,0 +1,40 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyHeaderParser
         
     | 
| 
      
 4 
     | 
    
         
            +
              # function definition in header file
         
     | 
| 
      
 5 
     | 
    
         
            +
              class FunctionDefinition
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @!attribute name
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   @return [String]
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :name
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # @!attribute definition
         
     | 
| 
      
 11 
     | 
    
         
            +
                #   @return [String]
         
     | 
| 
      
 12 
     | 
    
         
            +
                attr_accessor :definition
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # @!attribute typeref
         
     | 
| 
      
 15 
     | 
    
         
            +
                #   @return [TyperefDefinition]
         
     | 
| 
      
 16 
     | 
    
         
            +
                attr_accessor :typeref
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                # @!attribute args
         
     | 
| 
      
 19 
     | 
    
         
            +
                #   @return [Array<ArgumentDefinition>]
         
     | 
| 
      
 20 
     | 
    
         
            +
                attr_accessor :args
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                # @param name [String]
         
     | 
| 
      
 23 
     | 
    
         
            +
                # @param definition [String]
         
     | 
| 
      
 24 
     | 
    
         
            +
                # @param typeref [TyperefDefinition]
         
     | 
| 
      
 25 
     | 
    
         
            +
                # @param args [Array<ArgumentDefinition>]
         
     | 
| 
      
 26 
     | 
    
         
            +
                def initialize(name:, definition:, typeref:, args:)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @definition = definition
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @typeref = typeref
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @args = args
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                # @param other [FunctionDefinition]
         
     | 
| 
      
 34 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 35 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  other.is_a?(FunctionDefinition) && name == other.name && definition == other.definition &&
         
     | 
| 
      
 37 
     | 
    
         
            +
                    typeref == other.typeref && args == other.args
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,376 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyHeaderParser
         
     | 
| 
      
 4 
     | 
    
         
            +
              # parse `ruby.h` using `ctags`
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Parser # rubocop:disable Metrics/ClassLength
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @!attribute [r] header_file
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   @return [String]
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :header_file
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # @!attribute [r] include_paths
         
     | 
| 
      
 11 
     | 
    
         
            +
                #   @return [Array<String>]
         
     | 
| 
      
 12 
     | 
    
         
            +
                attr_reader :include_paths
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # @!attribute [r] dist_preprocessed_header_file
         
     | 
| 
      
 15 
     | 
    
         
            +
                #   @return [String]
         
     | 
| 
      
 16 
     | 
    
         
            +
                attr_reader :dist_preprocessed_header_file
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                # @!attribute [r] data
         
     | 
| 
      
 19 
     | 
    
         
            +
                #   @return [RubyHeaderParser::Config]
         
     | 
| 
      
 20 
     | 
    
         
            +
                attr_reader :config
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                DEFAULT_HEADER_FILE = "#{RbConfig::CONFIG["rubyhdrdir"]}/ruby.h".freeze
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                DEFAULT_INCLUDE_PATHS = [
         
     | 
| 
      
 25 
     | 
    
         
            +
                  RbConfig::CONFIG["rubyarchhdrdir"],
         
     | 
| 
      
 26 
     | 
    
         
            +
                  RbConfig::CONFIG["rubyhdrdir"],
         
     | 
| 
      
 27 
     | 
    
         
            +
                ].freeze
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                # @param header_file [String] Path to `ruby.h`
         
     | 
| 
      
 30 
     | 
    
         
            +
                # @param include_paths [Array<String>]
         
     | 
| 
      
 31 
     | 
    
         
            +
                # @param dist_preprocessed_header_file [String,nil] Destination path to the output of preprocessed ruby.h.
         
     | 
| 
      
 32 
     | 
    
         
            +
                #                                      (default: `"#{Dir.tmpdir}/ruby_preprocessed.h"`)
         
     | 
| 
      
 33 
     | 
    
         
            +
                # @param config_file [String,nil] Path to config file (default: `config/default.yml`)
         
     | 
| 
      
 34 
     | 
    
         
            +
                #
         
     | 
| 
      
 35 
     | 
    
         
            +
                # @note `dist_preprocessed_header_file` is used as the output destination for temporary files when the parser
         
     | 
| 
      
 36 
     | 
    
         
            +
                #       is executed
         
     | 
| 
      
 37 
     | 
    
         
            +
                #
         
     | 
| 
      
 38 
     | 
    
         
            +
                # @note See [CONFIG.md](../file.CONFIG.html) for config file details
         
     | 
| 
      
 39 
     | 
    
         
            +
                def initialize(dist_preprocessed_header_file: nil, header_file: DEFAULT_HEADER_FILE,
         
     | 
| 
      
 40 
     | 
    
         
            +
                               include_paths: DEFAULT_INCLUDE_PATHS, config_file: nil)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  @header_file = header_file
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @include_paths = include_paths
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @dist_preprocessed_header_file = dist_preprocessed_header_file || File.join(Dir.tmpdir, "ruby_preprocessed.h")
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  config_file ||= File.expand_path("../../config/default.yml", __dir__.to_s)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  @config = Config.new(config_file)
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                # @return [Array<RubyHeaderParser::FunctionDefinition>]
         
     | 
| 
      
 50 
     | 
    
         
            +
                def extract_function_definitions
         
     | 
| 
      
 51 
     | 
    
         
            +
                  __extract_function_definitions(c_kinds: "p", kind: "p", is_parse_multiline_definition: true)
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                # @return [Array<RubyHeaderParser::FunctionDefinition>]
         
     | 
| 
      
 55 
     | 
    
         
            +
                def extract_static_inline_function_definitions
         
     | 
| 
      
 56 
     | 
    
         
            +
                  __extract_function_definitions(c_kinds: "+p-d", kind: "f", is_parse_multiline_definition: false)
         
     | 
| 
      
 57 
     | 
    
         
            +
                end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                # @return [Array<RubyHeaderParser::StructDefinition>]
         
     | 
| 
      
 60 
     | 
    
         
            +
                def extract_struct_definitions
         
     | 
| 
      
 61 
     | 
    
         
            +
                  stdout = execute_ctags("--c-kinds=s --fields=+n")
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                  stdout.each_line.with_object([]) do |line, definitions|
         
     | 
| 
      
 64 
     | 
    
         
            +
                    parts = line.split("\t")
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
                    struct_name = parts[0]
         
     | 
| 
      
 67 
     | 
    
         
            +
                    next unless config.should_generate_struct?(struct_name)
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    definitions << StructDefinition.new(
         
     | 
| 
      
 70 
     | 
    
         
            +
                      name: struct_name,
         
     | 
| 
      
 71 
     | 
    
         
            +
                    )
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
                end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
                # @return [Array<RubyHeaderParser::TyperefDefinition>]
         
     | 
| 
      
 76 
     | 
    
         
            +
                def extract_type_definitions
         
     | 
| 
      
 77 
     | 
    
         
            +
                  stdout = execute_ctags("--c-kinds=t --fields=+n")
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  stdout.each_line.with_object([]) do |line, definitions|
         
     | 
| 
      
 80 
     | 
    
         
            +
                    parts = line.split("\t")
         
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
      
 82 
     | 
    
         
            +
                    type_name = parts[0]
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                    next unless config.should_generate_type?(type_name)
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                    definitions << TypeDefinition.new(
         
     | 
| 
      
 87 
     | 
    
         
            +
                      name: type_name,
         
     | 
| 
      
 88 
     | 
    
         
            +
                    )
         
     | 
| 
      
 89 
     | 
    
         
            +
                  end.uniq(&:name)
         
     | 
| 
      
 90 
     | 
    
         
            +
                end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                # @return [Array<RubyHeaderParser::EnumDefinition>]
         
     | 
| 
      
 93 
     | 
    
         
            +
                def extract_enum_definitions
         
     | 
| 
      
 94 
     | 
    
         
            +
                  stdout = execute_ctags("--c-kinds=e --fields=+n")
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  name_to_definitions =
         
     | 
| 
      
 97 
     | 
    
         
            +
                    stdout.each_line.with_object({}) do |line, hash|
         
     | 
| 
      
 98 
     | 
    
         
            +
                      parts = line.split("\t")
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
                      enum_name = Util.find_field(parts, "enum")
         
     | 
| 
      
 101 
     | 
    
         
            +
                      next unless enum_name
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                      value = parts[0]
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
                      next unless config.should_generate_enum?(enum_name)
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                      hash[enum_name] ||= EnumDefinition.new(name: enum_name)
         
     | 
| 
      
 108 
     | 
    
         
            +
                      hash[enum_name].values << value
         
     | 
| 
      
 109 
     | 
    
         
            +
                    end
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
                  name_to_definitions.values
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                private
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
                # @param c_kinds [String]
         
     | 
| 
      
 117 
     | 
    
         
            +
                # @param kind [String]
         
     | 
| 
      
 118 
     | 
    
         
            +
                # @param is_parse_multiline_definition [Boolean]
         
     | 
| 
      
 119 
     | 
    
         
            +
                # @return [Array<RubyHeaderParser::FunctionDefinition>]
         
     | 
| 
      
 120 
     | 
    
         
            +
                def __extract_function_definitions(c_kinds:, kind:, is_parse_multiline_definition:)
         
     | 
| 
      
 121 
     | 
    
         
            +
                  stdout = execute_ctags("--c-kinds=#{c_kinds} --fields=+nS --extras=+q")
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                  stdout.each_line.map do |line|
         
     | 
| 
      
 124 
     | 
    
         
            +
                    generate_function_definition_from_line(line:, kind:, is_parse_multiline_definition:)
         
     | 
| 
      
 125 
     | 
    
         
            +
                  end.compact.uniq(&:name)
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                # @param line [String]
         
     | 
| 
      
 129 
     | 
    
         
            +
                # @param kind [String]
         
     | 
| 
      
 130 
     | 
    
         
            +
                # @param is_parse_multiline_definition [Boolean]
         
     | 
| 
      
 131 
     | 
    
         
            +
                #
         
     | 
| 
      
 132 
     | 
    
         
            +
                # @return [RubyHeaderParser::FunctionDefinition, nil]
         
     | 
| 
      
 133 
     | 
    
         
            +
                def generate_function_definition_from_line(line:, kind:, is_parse_multiline_definition:)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  parts = line.split("\t")
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                  function_name = parts[0]
         
     | 
| 
      
 137 
     | 
    
         
            +
                  filepath = parts[1]
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                  return nil unless config.should_generate_function?(function_name)
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                  return nil unless parts[3] == kind
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                  line_num = Util.find_field(parts, "line").to_i
         
     | 
| 
      
 144 
     | 
    
         
            +
                  definition = parse_function_definition(filepath:, pattern: parts[2], line_num:, is_parse_multiline_definition:)
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
                  args = parse_definition_args(function_name, Util.find_field(parts, "signature"))
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                  # Exclude functions with variable-length arguments
         
     | 
| 
      
 149 
     | 
    
         
            +
                  return nil if args&.last&.type == "..."
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                  typeref_field = Util.find_field(parts, "typeref:typename")
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
      
 153 
     | 
    
         
            +
                  FunctionDefinition.new(
         
     | 
| 
      
 154 
     | 
    
         
            +
                    definition:,
         
     | 
| 
      
 155 
     | 
    
         
            +
                    name:       function_name,
         
     | 
| 
      
 156 
     | 
    
         
            +
                    typeref:    create_typeref(definition:, function_name:, typeref_field:, filepath:, line_num:),
         
     | 
| 
      
 157 
     | 
    
         
            +
                    args:,
         
     | 
| 
      
 158 
     | 
    
         
            +
                  )
         
     | 
| 
      
 159 
     | 
    
         
            +
                end
         
     | 
| 
      
 160 
     | 
    
         
            +
             
     | 
| 
      
 161 
     | 
    
         
            +
                # @param args [String]
         
     | 
| 
      
 162 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 163 
     | 
    
         
            +
                def execute_ctags(args = "")
         
     | 
| 
      
 164 
     | 
    
         
            +
                  unless File.exist?(dist_preprocessed_header_file)
         
     | 
| 
      
 165 
     | 
    
         
            +
                    include_args = include_paths.map { |path| "-I #{path}" }.join(" ")
         
     | 
| 
      
 166 
     | 
    
         
            +
                    system("gcc -E #{include_args} #{header_file} -o #{dist_preprocessed_header_file}", exception: true)
         
     | 
| 
      
 167 
     | 
    
         
            +
                  end
         
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
      
 169 
     | 
    
         
            +
                  `ctags --languages=C --language-force=C #{args} -f - #{dist_preprocessed_header_file}`
         
     | 
| 
      
 170 
     | 
    
         
            +
                end
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
                # @param file [String]
         
     | 
| 
      
 173 
     | 
    
         
            +
                # @param line_num [Integer]
         
     | 
| 
      
 174 
     | 
    
         
            +
                def read_definition_from_header_file(file, line_num)
         
     | 
| 
      
 175 
     | 
    
         
            +
                  definition = +""
         
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
                  File.open(file, "r") do |f|
         
     | 
| 
      
 178 
     | 
    
         
            +
                    f.each_with_index do |line, index|
         
     | 
| 
      
 179 
     | 
    
         
            +
                      if index + 1 >= line_num
         
     | 
| 
      
 180 
     | 
    
         
            +
                        definition << line.strip
         
     | 
| 
      
 181 
     | 
    
         
            +
                        return definition if definition.end_with?(");")
         
     | 
| 
      
 182 
     | 
    
         
            +
                      end
         
     | 
| 
      
 183 
     | 
    
         
            +
                    end
         
     | 
| 
      
 184 
     | 
    
         
            +
                  end
         
     | 
| 
      
 185 
     | 
    
         
            +
                  ""
         
     | 
| 
      
 186 
     | 
    
         
            +
                end
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                # @param filepath [String]
         
     | 
| 
      
 189 
     | 
    
         
            +
                # @param pattern [String]
         
     | 
| 
      
 190 
     | 
    
         
            +
                # @param line_num [Integer]
         
     | 
| 
      
 191 
     | 
    
         
            +
                # @param is_parse_multiline_definition [Boolean]
         
     | 
| 
      
 192 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 193 
     | 
    
         
            +
                def parse_function_definition(filepath:, pattern:, line_num:, is_parse_multiline_definition:)
         
     | 
| 
      
 194 
     | 
    
         
            +
                  definition =
         
     | 
| 
      
 195 
     | 
    
         
            +
                    if pattern.end_with?("$/;\"")
         
     | 
| 
      
 196 
     | 
    
         
            +
                      pattern.delete_prefix("/^").delete_suffix("$/;\"")
         
     | 
| 
      
 197 
     | 
    
         
            +
                    elsif is_parse_multiline_definition
         
     | 
| 
      
 198 
     | 
    
         
            +
                      read_definition_from_header_file(filepath, line_num)
         
     | 
| 
      
 199 
     | 
    
         
            +
                    else
         
     | 
| 
      
 200 
     | 
    
         
            +
                      pattern.delete_prefix("/^")
         
     | 
| 
      
 201 
     | 
    
         
            +
                    end
         
     | 
| 
      
 202 
     | 
    
         
            +
             
     | 
| 
      
 203 
     | 
    
         
            +
                  definition.strip.delete_suffix(";")
         
     | 
| 
      
 204 
     | 
    
         
            +
                end
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                # @param function_name [String]
         
     | 
| 
      
 207 
     | 
    
         
            +
                # @param signature [String,nil]
         
     | 
| 
      
 208 
     | 
    
         
            +
                # @return [Array<RubyHeaderParser::ArgumentDefinition>]
         
     | 
| 
      
 209 
     | 
    
         
            +
                def parse_definition_args(function_name, signature)
         
     | 
| 
      
 210 
     | 
    
         
            +
                  return [] unless signature
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                  signature = signature.strip.delete_prefix("(").delete_suffix(")")
         
     | 
| 
      
 213 
     | 
    
         
            +
                  return [] if signature.match?(/^void$/i)
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                  args = Util.split_signature(signature)
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                  arg_pos = 0
         
     | 
| 
      
 218 
     | 
    
         
            +
                  args.map do |arg|
         
     | 
| 
      
 219 
     | 
    
         
            +
                    arg_pos += 1
         
     | 
| 
      
 220 
     | 
    
         
            +
                    generate_argument_definition(function_name:, arg:, arg_pos:)
         
     | 
| 
      
 221 
     | 
    
         
            +
                  end
         
     | 
| 
      
 222 
     | 
    
         
            +
                end
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                # @param definition [String]
         
     | 
| 
      
 225 
     | 
    
         
            +
                # @param function_name [String]
         
     | 
| 
      
 226 
     | 
    
         
            +
                # @param typeref_field [String,nil]
         
     | 
| 
      
 227 
     | 
    
         
            +
                # @param filepath [String]
         
     | 
| 
      
 228 
     | 
    
         
            +
                # @param line_num [Integer]
         
     | 
| 
      
 229 
     | 
    
         
            +
                # @return [RubyHeaderParser::TyperefDefinition]
         
     | 
| 
      
 230 
     | 
    
         
            +
                def create_typeref(definition:, function_name:, typeref_field:, filepath:, line_num:)
         
     | 
| 
      
 231 
     | 
    
         
            +
                  typeref_type = parse_typeref_type(definition:, function_name:, typeref_field:, filepath:, line_num:)
         
     | 
| 
      
 232 
     | 
    
         
            +
             
     | 
| 
      
 233 
     | 
    
         
            +
                  typeref_pointer = nil
         
     | 
| 
      
 234 
     | 
    
         
            +
                  if typeref_type.match?(/\*+$/)
         
     | 
| 
      
 235 
     | 
    
         
            +
                    typeref_type = typeref_type.gsub(/\*+$/, "").strip
         
     | 
| 
      
 236 
     | 
    
         
            +
                    typeref_pointer = config.function_self_pointer_hint(function_name)
         
     | 
| 
      
 237 
     | 
    
         
            +
                  end
         
     | 
| 
      
 238 
     | 
    
         
            +
             
     | 
| 
      
 239 
     | 
    
         
            +
                  TyperefDefinition.new(type: typeref_type, pointer: typeref_pointer)
         
     | 
| 
      
 240 
     | 
    
         
            +
                end
         
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                # @param definition [String]
         
     | 
| 
      
 243 
     | 
    
         
            +
                # @param function_name [String]
         
     | 
| 
      
 244 
     | 
    
         
            +
                # @param typeref_field [String,nil]
         
     | 
| 
      
 245 
     | 
    
         
            +
                # @param filepath [String]
         
     | 
| 
      
 246 
     | 
    
         
            +
                # @param line_num [Integer]
         
     | 
| 
      
 247 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 248 
     | 
    
         
            +
                def parse_typeref_type(definition:, function_name:, typeref_field:, filepath:, line_num:)
         
     | 
| 
      
 249 
     | 
    
         
            +
                  typeref_type =
         
     | 
| 
      
 250 
     | 
    
         
            +
                    if typeref_field
         
     | 
| 
      
 251 
     | 
    
         
            +
                      typeref_field.gsub(/[A-Z_]+\s*\(\(.*\)\)/, "")
         
     | 
| 
      
 252 
     | 
    
         
            +
                    else
         
     | 
| 
      
 253 
     | 
    
         
            +
                      # parse typeref in definition
         
     | 
| 
      
 254 
     | 
    
         
            +
                      type = definition[0...definition.index(function_name)] || ""
         
     | 
| 
      
 255 
     | 
    
         
            +
                      type.gsub("char *", "char*").strip
         
     | 
| 
      
 256 
     | 
    
         
            +
                    end
         
     | 
| 
      
 257 
     | 
    
         
            +
             
     | 
| 
      
 258 
     | 
    
         
            +
                  typeref_type = Util.sanitize_type(typeref_type)
         
     | 
| 
      
 259 
     | 
    
         
            +
                  return typeref_type unless typeref_type.empty?
         
     | 
| 
      
 260 
     | 
    
         
            +
             
     | 
| 
      
 261 
     | 
    
         
            +
                  # Check prev line
         
     | 
| 
      
 262 
     | 
    
         
            +
                  line = read_file_line(filepath:, line_num: line_num - 1)
         
     | 
| 
      
 263 
     | 
    
         
            +
                  return Util.sanitize_type(line) if line
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
      
 265 
     | 
    
         
            +
                  ""
         
     | 
| 
      
 266 
     | 
    
         
            +
                end
         
     | 
| 
      
 267 
     | 
    
         
            +
             
     | 
| 
      
 268 
     | 
    
         
            +
                # @param filepath [String]
         
     | 
| 
      
 269 
     | 
    
         
            +
                # @param line_num [Integer]
         
     | 
| 
      
 270 
     | 
    
         
            +
                def read_file_line(filepath:, line_num:)
         
     | 
| 
      
 271 
     | 
    
         
            +
                  return nil if line_num < 1
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
                  lines = File.open(filepath, "rb") { |f| f.readlines(chomp: true) }
         
     | 
| 
      
 274 
     | 
    
         
            +
                  lines[line_num - 1]
         
     | 
| 
      
 275 
     | 
    
         
            +
                end
         
     | 
| 
      
 276 
     | 
    
         
            +
             
     | 
| 
      
 277 
     | 
    
         
            +
                # @param function_name [String]
         
     | 
| 
      
 278 
     | 
    
         
            +
                # @param arg [String]
         
     | 
| 
      
 279 
     | 
    
         
            +
                # @param arg_pos [Integer]
         
     | 
| 
      
 280 
     | 
    
         
            +
                #
         
     | 
| 
      
 281 
     | 
    
         
            +
                # @return [ArgumentDefinition]
         
     | 
| 
      
 282 
     | 
    
         
            +
                def generate_argument_definition(function_name:, arg:, arg_pos:)
         
     | 
| 
      
 283 
     | 
    
         
            +
                  parts = arg.split
         
     | 
| 
      
 284 
     | 
    
         
            +
             
     | 
| 
      
 285 
     | 
    
         
            +
                  if parts.count < 2
         
     | 
| 
      
 286 
     | 
    
         
            +
                    return ArgumentDefinition.new(
         
     | 
| 
      
 287 
     | 
    
         
            +
                      type:    parts[0],
         
     | 
| 
      
 288 
     | 
    
         
            +
                      name:    "arg#{arg_pos}",
         
     | 
| 
      
 289 
     | 
    
         
            +
                      pointer: nil,
         
     | 
| 
      
 290 
     | 
    
         
            +
                    )
         
     | 
| 
      
 291 
     | 
    
         
            +
                  end
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
                  loop do
         
     | 
| 
      
 294 
     | 
    
         
            +
                    pointer_index = parts.index("*")
         
     | 
| 
      
 295 
     | 
    
         
            +
                    break unless pointer_index
         
     | 
| 
      
 296 
     | 
    
         
            +
             
     | 
| 
      
 297 
     | 
    
         
            +
                    parts[pointer_index - 1] << "*"
         
     | 
| 
      
 298 
     | 
    
         
            +
                    parts.delete_at(pointer_index)
         
     | 
| 
      
 299 
     | 
    
         
            +
                  end
         
     | 
| 
      
 300 
     | 
    
         
            +
             
     | 
| 
      
 301 
     | 
    
         
            +
                  type, pointer, length = analyze_argument_type(function_name:, arg_pos:, parts:)
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                  ArgumentDefinition.new(
         
     | 
| 
      
 304 
     | 
    
         
            +
                    name:    parts[-1],
         
     | 
| 
      
 305 
     | 
    
         
            +
                    type:,
         
     | 
| 
      
 306 
     | 
    
         
            +
                    pointer:,
         
     | 
| 
      
 307 
     | 
    
         
            +
                    length:,
         
     | 
| 
      
 308 
     | 
    
         
            +
                  )
         
     | 
| 
      
 309 
     | 
    
         
            +
                end
         
     | 
| 
      
 310 
     | 
    
         
            +
             
     | 
| 
      
 311 
     | 
    
         
            +
                # @param function_name [String]
         
     | 
| 
      
 312 
     | 
    
         
            +
                # @param arg_pos [Integer]
         
     | 
| 
      
 313 
     | 
    
         
            +
                # @param parts [Array<String>]
         
     | 
| 
      
 314 
     | 
    
         
            +
                #
         
     | 
| 
      
 315 
     | 
    
         
            +
                # @return [Array<String, Symbol, Integer>]
         
     | 
| 
      
 316 
     | 
    
         
            +
                #   - type [String]
         
     | 
| 
      
 317 
     | 
    
         
            +
                #   - pointer [Symbol]
         
     | 
| 
      
 318 
     | 
    
         
            +
                #   - length [Integer]
         
     | 
| 
      
 319 
     | 
    
         
            +
                def analyze_argument_type(function_name:, arg_pos:, parts:)
         
     | 
| 
      
 320 
     | 
    
         
            +
                  pointer, length = prepare_argument_parts(arg_pos:, parts:)
         
     | 
| 
      
 321 
     | 
    
         
            +
                  type = parts[0...-1] || []
         
     | 
| 
      
 322 
     | 
    
         
            +
                  original_type = Util.sanitize_type(type.join(" "))
         
     | 
| 
      
 323 
     | 
    
         
            +
             
     | 
| 
      
 324 
     | 
    
         
            +
                  case original_type
         
     | 
| 
      
 325 
     | 
    
         
            +
                  when /\*+$/
         
     | 
| 
      
 326 
     | 
    
         
            +
                    type = original_type.gsub(/\*+$/, "").strip
         
     | 
| 
      
 327 
     | 
    
         
            +
                    pointer = config.function_arg_pointer_hint(function_name:, pos: arg_pos)
         
     | 
| 
      
 328 
     | 
    
         
            +
             
     | 
| 
      
 329 
     | 
    
         
            +
                  when /^void\s*/, /\(.*\)/
         
     | 
| 
      
 330 
     | 
    
         
            +
                    # function pointer (e.g. void *(*func)(void *)) is treated as `void*`
         
     | 
| 
      
 331 
     | 
    
         
            +
                    type = "void"
         
     | 
| 
      
 332 
     | 
    
         
            +
                    pointer = config.function_arg_pointer_hint(function_name:, pos: arg_pos)
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                  else
         
     | 
| 
      
 335 
     | 
    
         
            +
                    type = original_type
         
     | 
| 
      
 336 
     | 
    
         
            +
                  end
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
      
 338 
     | 
    
         
            +
                  length = pointer_length(original_type) if pointer == :sref
         
     | 
| 
      
 339 
     | 
    
         
            +
             
     | 
| 
      
 340 
     | 
    
         
            +
                  [type, pointer, length]
         
     | 
| 
      
 341 
     | 
    
         
            +
                end
         
     | 
| 
      
 342 
     | 
    
         
            +
             
     | 
| 
      
 343 
     | 
    
         
            +
                # @param arg_pos [Integer]
         
     | 
| 
      
 344 
     | 
    
         
            +
                # @param parts [Array<String>]
         
     | 
| 
      
 345 
     | 
    
         
            +
                #
         
     | 
| 
      
 346 
     | 
    
         
            +
                # @return [Array<Symbol, Integer>]
         
     | 
| 
      
 347 
     | 
    
         
            +
                #   - pointer [Symbol,nil]
         
     | 
| 
      
 348 
     | 
    
         
            +
                #   - length [Integer]
         
     | 
| 
      
 349 
     | 
    
         
            +
                def prepare_argument_parts(parts:, arg_pos:)
         
     | 
| 
      
 350 
     | 
    
         
            +
                  if parts[-1] =~ /\[([0-9]+)?\]$/
         
     | 
| 
      
 351 
     | 
    
         
            +
                    parts[-1].gsub!(/\[([0-9]+)?\]$/, "")
         
     | 
| 
      
 352 
     | 
    
         
            +
                    length = ::Regexp.last_match(1).to_i
         
     | 
| 
      
 353 
     | 
    
         
            +
             
     | 
| 
      
 354 
     | 
    
         
            +
                    unless parts[-1] =~ /^[0-9a-zA-Z_]+$/
         
     | 
| 
      
 355 
     | 
    
         
            +
                      # last elements isn't dummy argument
         
     | 
| 
      
 356 
     | 
    
         
            +
                      parts << "arg#{arg_pos}"
         
     | 
| 
      
 357 
     | 
    
         
            +
                    end
         
     | 
| 
      
 358 
     | 
    
         
            +
             
     | 
| 
      
 359 
     | 
    
         
            +
                    return [:array, length]
         
     | 
| 
      
 360 
     | 
    
         
            +
                  end
         
     | 
| 
      
 361 
     | 
    
         
            +
             
     | 
| 
      
 362 
     | 
    
         
            +
                  unless parts[-1] =~ /^[0-9a-zA-Z_]+$/
         
     | 
| 
      
 363 
     | 
    
         
            +
                    # last elements isn't dummy argument
         
     | 
| 
      
 364 
     | 
    
         
            +
                    parts << "arg#{arg_pos}"
         
     | 
| 
      
 365 
     | 
    
         
            +
                  end
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
                  [nil, 0]
         
     | 
| 
      
 368 
     | 
    
         
            +
                end
         
     | 
| 
      
 369 
     | 
    
         
            +
             
     | 
| 
      
 370 
     | 
    
         
            +
                # @param type [String]
         
     | 
| 
      
 371 
     | 
    
         
            +
                def pointer_length(type)
         
     | 
| 
      
 372 
     | 
    
         
            +
                  type =~ /(\*+)$/
         
     | 
| 
      
 373 
     | 
    
         
            +
                  ::Regexp.last_match(1)&.length || 0
         
     | 
| 
      
 374 
     | 
    
         
            +
                end
         
     | 
| 
      
 375 
     | 
    
         
            +
              end
         
     | 
| 
      
 376 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyHeaderParser
         
     | 
| 
      
 4 
     | 
    
         
            +
              # struct definition in header file
         
     | 
| 
      
 5 
     | 
    
         
            +
              class StructDefinition
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @!attribute name
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   @return [String]
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :name
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # @param name [String]
         
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(name:)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                # @param other [StructDefinition]
         
     | 
| 
      
 16 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 17 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  other.is_a?(StructDefinition) && name == other.name
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyHeaderParser
         
     | 
| 
      
 4 
     | 
    
         
            +
              # type definition in header file
         
     | 
| 
      
 5 
     | 
    
         
            +
              class TypeDefinition
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @!attribute name
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   @return [String]
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :name
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # @param name [String]
         
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(name:)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @name = name
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                # @param other [TypeDefinition]
         
     | 
| 
      
 16 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 17 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  other.is_a?(TypeDefinition) && name == other.name
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyHeaderParser
         
     | 
| 
      
 4 
     | 
    
         
            +
              # typeref definition for {RubyHeaderParser::FunctionDefinition}
         
     | 
| 
      
 5 
     | 
    
         
            +
              class TyperefDefinition
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @!attribute type
         
     | 
| 
      
 7 
     | 
    
         
            +
                #   @return [String]
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :type
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                # @!attribute pointer
         
     | 
| 
      
 11 
     | 
    
         
            +
                #   @return [Symbol,nil] :ref, :raw
         
     | 
| 
      
 12 
     | 
    
         
            +
                attr_accessor :pointer
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                # @param type [String]
         
     | 
| 
      
 15 
     | 
    
         
            +
                # @param pointer [Symbol,nil] :ref, :raw
         
     | 
| 
      
 16 
     | 
    
         
            +
                def initialize(type:, pointer: nil)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @type = type
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @pointer = pointer
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 22 
     | 
    
         
            +
                def pointer?
         
     | 
| 
      
 23 
     | 
    
         
            +
                  !!pointer
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                # @param other [TyperefDefinition]
         
     | 
| 
      
 27 
     | 
    
         
            +
                # @return [Boolean]
         
     | 
| 
      
 28 
     | 
    
         
            +
                def ==(other)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  other.is_a?(TyperefDefinition) && type == other.type && pointer == other.pointer
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,29 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module RubyHeaderParser
         
     | 
| 
      
 4 
     | 
    
         
            +
              # util methods
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Util
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @param array [Array<String>]
         
     | 
| 
      
 7 
     | 
    
         
            +
                # @param field_name [String]
         
     | 
| 
      
 8 
     | 
    
         
            +
                # @return [String,nil]
         
     | 
| 
      
 9 
     | 
    
         
            +
                def self.find_field(array, field_name)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  array.each do |element|
         
     | 
| 
      
 11 
     | 
    
         
            +
                    return element.delete_prefix("#{field_name}:").strip if element.start_with?("#{field_name}:")
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                # @param signature [String]
         
     | 
| 
      
 18 
     | 
    
         
            +
                # @return [Array<String>]
         
     | 
| 
      
 19 
     | 
    
         
            +
                def self.split_signature(signature)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  signature.scan(/[^,]+\([^()]*\)|[^,]+/).flatten.map(&:strip)
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                # @param type [String]
         
     | 
| 
      
 24 
     | 
    
         
            +
                # @return [String]
         
     | 
| 
      
 25 
     | 
    
         
            +
                def self.sanitize_type(type)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  type.gsub(/(enum|volatile|const|struct|static\s+inline)\s+/i, "").gsub("const*", "").strip
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
              end
         
     | 
| 
      
 29 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,21 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "yaml"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "tmpdir"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative "ruby_header_parser/version"
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            # Parser for ruby.h
         
     | 
| 
      
 9 
     | 
    
         
            +
            module RubyHeaderParser
         
     | 
| 
      
 10 
     | 
    
         
            +
              class Error < StandardError; end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              autoload :ArgumentDefinition, "ruby_header_parser/argument_definition"
         
     | 
| 
      
 13 
     | 
    
         
            +
              autoload :Config,             "ruby_header_parser/config"
         
     | 
| 
      
 14 
     | 
    
         
            +
              autoload :EnumDefinition,     "ruby_header_parser/enum_definition"
         
     | 
| 
      
 15 
     | 
    
         
            +
              autoload :FunctionDefinition, "ruby_header_parser/function_definition"
         
     | 
| 
      
 16 
     | 
    
         
            +
              autoload :Parser,             "ruby_header_parser/parser"
         
     | 
| 
      
 17 
     | 
    
         
            +
              autoload :StructDefinition,   "ruby_header_parser/struct_definition"
         
     | 
| 
      
 18 
     | 
    
         
            +
              autoload :TypeDefinition,     "ruby_header_parser/type_definition"
         
     | 
| 
      
 19 
     | 
    
         
            +
              autoload :TyperefDefinition,  "ruby_header_parser/typeref_definition"
         
     | 
| 
      
 20 
     | 
    
         
            +
              autoload :Util,               "ruby_header_parser/util"
         
     | 
| 
      
 21 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,116 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            path: ".gem_rbs_collection"
         
     | 
| 
      
 3 
     | 
    
         
            +
            gems:
         
     | 
| 
      
 4 
     | 
    
         
            +
            - name: ast
         
     | 
| 
      
 5 
     | 
    
         
            +
              version: '2.4'
         
     | 
| 
      
 6 
     | 
    
         
            +
              source:
         
     | 
| 
      
 7 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 8 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 9 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 10 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 11 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 12 
     | 
    
         
            +
            - name: binding_of_caller
         
     | 
| 
      
 13 
     | 
    
         
            +
              version: '1.0'
         
     | 
| 
      
 14 
     | 
    
         
            +
              source:
         
     | 
| 
      
 15 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 16 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 17 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 18 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 19 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 20 
     | 
    
         
            +
            - name: dbm
         
     | 
| 
      
 21 
     | 
    
         
            +
              version: '0'
         
     | 
| 
      
 22 
     | 
    
         
            +
              source:
         
     | 
| 
      
 23 
     | 
    
         
            +
                type: stdlib
         
     | 
| 
      
 24 
     | 
    
         
            +
            - name: diff-lcs
         
     | 
| 
      
 25 
     | 
    
         
            +
              version: '1.5'
         
     | 
| 
      
 26 
     | 
    
         
            +
              source:
         
     | 
| 
      
 27 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 28 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 29 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 30 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 31 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 32 
     | 
    
         
            +
            - name: fileutils
         
     | 
| 
      
 33 
     | 
    
         
            +
              version: '0'
         
     | 
| 
      
 34 
     | 
    
         
            +
              source:
         
     | 
| 
      
 35 
     | 
    
         
            +
                type: stdlib
         
     | 
| 
      
 36 
     | 
    
         
            +
            - name: json
         
     | 
| 
      
 37 
     | 
    
         
            +
              version: '0'
         
     | 
| 
      
 38 
     | 
    
         
            +
              source:
         
     | 
| 
      
 39 
     | 
    
         
            +
                type: stdlib
         
     | 
| 
      
 40 
     | 
    
         
            +
            - name: parallel
         
     | 
| 
      
 41 
     | 
    
         
            +
              version: '1.20'
         
     | 
| 
      
 42 
     | 
    
         
            +
              source:
         
     | 
| 
      
 43 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 44 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 45 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 46 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 47 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 48 
     | 
    
         
            +
            - name: parser
         
     | 
| 
      
 49 
     | 
    
         
            +
              version: '3.2'
         
     | 
| 
      
 50 
     | 
    
         
            +
              source:
         
     | 
| 
      
 51 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 52 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 53 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 54 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 55 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 56 
     | 
    
         
            +
            - name: pstore
         
     | 
| 
      
 57 
     | 
    
         
            +
              version: '0'
         
     | 
| 
      
 58 
     | 
    
         
            +
              source:
         
     | 
| 
      
 59 
     | 
    
         
            +
                type: stdlib
         
     | 
| 
      
 60 
     | 
    
         
            +
            - name: psych
         
     | 
| 
      
 61 
     | 
    
         
            +
              version: '0'
         
     | 
| 
      
 62 
     | 
    
         
            +
              source:
         
     | 
| 
      
 63 
     | 
    
         
            +
                type: stdlib
         
     | 
| 
      
 64 
     | 
    
         
            +
            - name: rainbow
         
     | 
| 
      
 65 
     | 
    
         
            +
              version: '3.0'
         
     | 
| 
      
 66 
     | 
    
         
            +
              source:
         
     | 
| 
      
 67 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 68 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 69 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 70 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 71 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 72 
     | 
    
         
            +
            - name: rake
         
     | 
| 
      
 73 
     | 
    
         
            +
              version: '13.0'
         
     | 
| 
      
 74 
     | 
    
         
            +
              source:
         
     | 
| 
      
 75 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 76 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 77 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 78 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 79 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 80 
     | 
    
         
            +
            - name: regexp_parser
         
     | 
| 
      
 81 
     | 
    
         
            +
              version: '2.8'
         
     | 
| 
      
 82 
     | 
    
         
            +
              source:
         
     | 
| 
      
 83 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 84 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 85 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 86 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 87 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 88 
     | 
    
         
            +
            - name: rspec-parameterized-core
         
     | 
| 
      
 89 
     | 
    
         
            +
              version: 1.0.1
         
     | 
| 
      
 90 
     | 
    
         
            +
              source:
         
     | 
| 
      
 91 
     | 
    
         
            +
                type: rubygems
         
     | 
| 
      
 92 
     | 
    
         
            +
            - name: rspec-parameterized-table_syntax
         
     | 
| 
      
 93 
     | 
    
         
            +
              version: 1.0.1
         
     | 
| 
      
 94 
     | 
    
         
            +
              source:
         
     | 
| 
      
 95 
     | 
    
         
            +
                type: rubygems
         
     | 
| 
      
 96 
     | 
    
         
            +
            - name: rubocop
         
     | 
| 
      
 97 
     | 
    
         
            +
              version: '1.57'
         
     | 
| 
      
 98 
     | 
    
         
            +
              source:
         
     | 
| 
      
 99 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 100 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 101 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 102 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 103 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 104 
     | 
    
         
            +
            - name: rubocop-ast
         
     | 
| 
      
 105 
     | 
    
         
            +
              version: '1.30'
         
     | 
| 
      
 106 
     | 
    
         
            +
              source:
         
     | 
| 
      
 107 
     | 
    
         
            +
                type: git
         
     | 
| 
      
 108 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 109 
     | 
    
         
            +
                revision: 704f7e6b395fca717cc25c562598ca86015ed545
         
     | 
| 
      
 110 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 111 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 112 
     | 
    
         
            +
            - name: yaml
         
     | 
| 
      
 113 
     | 
    
         
            +
              version: '0'
         
     | 
| 
      
 114 
     | 
    
         
            +
              source:
         
     | 
| 
      
 115 
     | 
    
         
            +
                type: stdlib
         
     | 
| 
      
 116 
     | 
    
         
            +
            gemfile_lock_path: Gemfile.lock
         
     | 
    
        data/rbs_collection.yaml
    ADDED
    
    | 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Download sources
         
     | 
| 
      
 2 
     | 
    
         
            +
            sources:
         
     | 
| 
      
 3 
     | 
    
         
            +
              - type: git
         
     | 
| 
      
 4 
     | 
    
         
            +
                name: ruby/gem_rbs_collection
         
     | 
| 
      
 5 
     | 
    
         
            +
                remote: https://github.com/ruby/gem_rbs_collection.git
         
     | 
| 
      
 6 
     | 
    
         
            +
                revision: main
         
     | 
| 
      
 7 
     | 
    
         
            +
                repo_dir: gems
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            # You can specify local directories as sources also.
         
     | 
| 
      
 10 
     | 
    
         
            +
            # - type: local
         
     | 
| 
      
 11 
     | 
    
         
            +
            #   path: path/to/your/local/repository
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            # A directory to install the downloaded RBSs
         
     | 
| 
      
 14 
     | 
    
         
            +
            path: .gem_rbs_collection
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            gems:
         
     | 
| 
      
 17 
     | 
    
         
            +
              - name: rbs
         
     | 
| 
      
 18 
     | 
    
         
            +
                ignore: true
         
     | 
| 
      
 19 
     | 
    
         
            +
              - name: steep
         
     | 
| 
      
 20 
     | 
    
         
            +
                ignore: true
         
     | 
| 
      
 21 
     | 
    
         
            +
              - name: yard
         
     | 
| 
      
 22 
     | 
    
         
            +
                ignore: true
         
     | 
| 
      
 23 
     | 
    
         
            +
              - name: ruby_header_parser
         
     | 
| 
      
 24 
     | 
    
         
            +
                ignore: true
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              - name: yaml
         
     |