Skip to content

Commit 56627dd

Browse files
authored
Merge pull request #172 from sue445/feature/remove_AbcSize
Remove Metrics/AbcSize in .rubocop_todo.yml
2 parents 6f4eb5b + f0e9e14 commit 56627dd

File tree

4 files changed

+134
-70
lines changed

4 files changed

+134
-70
lines changed

.rubocop.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ Lint/BinaryOperatorWithIdenticalOperands:
3434
Exclude:
3535
- "**/*_spec.rb" # for rspec-parameterized
3636

37+
Metrics/AbcSize:
38+
Max: 20
39+
3740
Metrics/BlockLength:
3841
Exclude:
3942
- "*.gemspec"

.rubocop_todo.yml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@
66
# Note that changes in the inspected code, or installation of new
77
# versions of RuboCop, may require this file to be generated again.
88

9-
# Offense count: 8
10-
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
11-
Metrics/AbcSize:
12-
Max: 46
13-
149
# Offense count: 17
1510
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
1611
Metrics/MethodLength:

_tools/ruby_h_to_go/lib/ruby_h_to_go/function_definition.rb

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,24 +36,46 @@ def write_go_file(dist_dir)
3636

3737
# @return [String]
3838
def generate_go_content
39-
go_function_args = args.map(&:go_function_arg)
39+
go_function_lines = generate_function_header_lines
4040

41-
go_function_typeref = typeref.go_function_typeref
41+
casted_go_args, before_call_function_lines, after_call_function_lines = analyze_args
4242

43-
go_function_lines = [
43+
call_c_method = "C.#{name}(#{casted_go_args.join(", ")})"
44+
45+
append_function_body(call_c_method:, go_function_lines:, before_call_function_lines:, after_call_function_lines:)
46+
47+
go_function_lines.append("}", "", "")
48+
49+
go_function_lines.join("\n")
50+
end
51+
52+
# @return [String]
53+
def go_function_name
54+
return name if name.match?(/^[A-Z0-9_]+$/)
55+
56+
GoUtil.snake_to_camel(name)
57+
end
58+
59+
private
60+
61+
# @return [Array<String>]
62+
def generate_function_header_lines
63+
[
4464
"// #{go_function_name} calls `#{name}` in C",
4565
"//",
4666
"// Original definition is following",
4767
"//",
4868
"//\t#{definition}",
69+
"func #{go_function_name}(#{args.map(&:go_function_arg).join(", ")}) #{typeref.go_function_typeref} {",
4970
]
71+
end
5072

51-
go_function_lines << "func #{go_function_name}(#{go_function_args.join(", ")}) #{go_function_typeref} {"
52-
73+
# @return [Array<Array<String>, Array<String>, Array<String>>]
74+
# - casted_go_args [Array<String>]
75+
# - before_call_function_lines [Array<String>]
76+
# - after_call_function_lines [Array<String>]
77+
def analyze_args
5378
casted_go_args = []
54-
char_var_count = args.count { |c_arg| c_arg.type == "char" && c_arg.pointer == :ref }
55-
chars_var_count = args.count { |c_arg| c_arg.type == "char" && c_arg.pointer == :str_array }
56-
5779
before_call_function_lines = []
5880
after_call_function_lines = []
5981

@@ -65,9 +87,27 @@ def generate_go_content
6587
after_call_function_lines.push(*after_lines)
6688
end
6789

68-
call_c_method = "C.#{name}(#{casted_go_args.join(", ")})"
90+
[casted_go_args, before_call_function_lines, after_call_function_lines]
91+
end
6992

93+
# @return [Integer]
94+
def char_var_count
95+
args.count { |c_arg| c_arg.type == "char" && c_arg.pointer == :ref }
96+
end
97+
98+
# @return [Integer]
99+
def chars_var_count
100+
args.count { |c_arg| c_arg.type == "char" && c_arg.pointer == :str_array }
101+
end
102+
103+
# @param go_function_lines [Array<String>]
104+
# @param call_c_method [String]
105+
# @param before_call_function_lines [Array<String>]
106+
# @param after_call_function_lines [Array<String>]
107+
def append_function_body(go_function_lines:, call_c_method:, before_call_function_lines:,
108+
after_call_function_lines:)
70109
go_function_lines.push(*before_call_function_lines)
110+
71111
cast_func = typeref.cast_func_for_function_return
72112
if cast_func == ""
73113
go_function_lines << call_c_method
@@ -79,19 +119,6 @@ def generate_go_content
79119
go_function_lines.push(*after_call_function_lines)
80120
go_function_lines << "return ret"
81121
end
82-
83-
go_function_lines << "}"
84-
go_function_lines << ""
85-
go_function_lines << ""
86-
87-
go_function_lines.join("\n")
88-
end
89-
90-
# @return [String]
91-
def go_function_name
92-
return name if name.match?(/^[A-Z0-9_]+$/)
93-
94-
GoUtil.snake_to_camel(name)
95122
end
96123
end
97124
end

_tools/ruby_h_to_go/lib/ruby_header_parser/parser.rb

Lines changed: 82 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -104,33 +104,42 @@ def extract_enum_definitions
104104
def __extract_function_definitions(c_kinds:, kind:, is_parse_multiline_definition:)
105105
stdout = execute_ctags("--c-kinds=#{c_kinds} --fields=+nS --extras=+q")
106106

107-
stdout.each_line.with_object([]) do |line, definitions|
108-
parts = line.split("\t")
107+
stdout.each_line.map do |line|
108+
generate_function_definition_from_line(line:, kind:, is_parse_multiline_definition:)
109+
end.compact.uniq(&:name)
110+
end
109111

110-
function_name = parts[0]
111-
filepath = parts[1]
112+
# @param line [String]
113+
# @param kind [String]
114+
# @param is_parse_multiline_definition [Boolean]
115+
#
116+
# @param [Array<RubyHeaderParser::FunctionDefinition>, nil]
117+
def generate_function_definition_from_line(line:, kind:, is_parse_multiline_definition:)
118+
parts = line.split("\t")
112119

113-
next unless data.should_generate_function?(function_name)
120+
function_name = parts[0]
121+
filepath = parts[1]
114122

115-
next unless parts[3] == kind
123+
return nil unless data.should_generate_function?(function_name)
116124

117-
line_num = Util.find_field(parts, "line").to_i
118-
definition = parse_function_definition(filepath:, pattern: parts[2], line_num:, is_parse_multiline_definition:)
125+
return nil unless parts[3] == kind
119126

120-
args = parse_definition_args(function_name, Util.find_field(parts, "signature"))
127+
line_num = Util.find_field(parts, "line").to_i
128+
definition = parse_function_definition(filepath:, pattern: parts[2], line_num:, is_parse_multiline_definition:)
121129

122-
# Exclude functions with variable-length arguments
123-
next if args&.last&.type == "..."
130+
args = parse_definition_args(function_name, Util.find_field(parts, "signature"))
124131

125-
typeref_field = Util.find_field(parts, "typeref:typename")
132+
# Exclude functions with variable-length arguments
133+
return nil if args&.last&.type == "..."
126134

127-
definitions << FunctionDefinition.new(
128-
definition:,
129-
name: function_name,
130-
typeref: create_typeref(definition:, function_name:, typeref_field:, filepath:, line_num:),
131-
args:,
132-
)
133-
end.uniq(&:name)
135+
typeref_field = Util.find_field(parts, "typeref:typename")
136+
137+
FunctionDefinition.new(
138+
definition:,
139+
name: function_name,
140+
typeref: create_typeref(definition:, function_name:, typeref_field:, filepath:, line_num:),
141+
args:,
142+
)
134143
end
135144

136145
# @param args [String]
@@ -272,45 +281,75 @@ def generate_argument_definition(function_name:, arg:, arg_pos:)
272281
parts.delete_at(pointer_index)
273282
end
274283

275-
pointer = nil
276-
length = 0
284+
type, pointer, length = analyze_argument_type(function_name:, arg_pos:, parts:)
277285

278-
if parts[-1] =~ /\[([0-9]+)?\]$/
279-
parts[-1].gsub!(/\[([0-9]+)?\]$/, "")
280-
length = ::Regexp.last_match(1).to_i
281-
pointer = :array
282-
end
283-
284-
unless parts[-1] =~ /^[0-9a-zA-Z_]+$/
285-
# last elements isn't dummy argument
286-
parts << "arg#{arg_pos}"
287-
end
286+
ArgumentDefinition.new(
287+
name: parts[-1],
288+
type:,
289+
pointer:,
290+
length:,
291+
)
292+
end
288293

294+
# @param function_name [String]
295+
# @param arg_pos [Integer]
296+
# @param parts [Array<String>]
297+
#
298+
# @return [Array<String, Symbol, Integer>]
299+
# - type [String]
300+
# - pointer [Symbol]
301+
# - length [Integer]
302+
def analyze_argument_type(function_name:, arg_pos:, parts:)
303+
pointer, length = prepare_argument_parts(arg_pos:, parts:)
289304
original_type = Util.sanitize_type(parts[0...-1].join(" "))
290-
name = parts[-1]
291305

292-
if original_type.match?(/\*+$/)
306+
case original_type
307+
when /\*+$/
293308
type = original_type.gsub(/\*+$/, "").strip
294309
pointer = data.function_arg_pointer_hint(function_name:, pos: arg_pos)
295-
elsif /^void\s*\s/.match?(original_type) || /\(.*\)/.match?(original_type)
310+
311+
when /^void\s*/, /\(.*\)/
296312
# function pointer (e.g. void *(*func)(void *)) is treated as `void*`
297313
type = "void"
298314
pointer = data.function_arg_pointer_hint(function_name:, pos: arg_pos)
315+
299316
else
300317
type = original_type
301318
end
302319

303-
if pointer == :sref
304-
original_type =~ /(\*+)$/
305-
length = ::Regexp.last_match(1).length
320+
length = pointer_length(original_type) if pointer == :sref
321+
322+
[type, pointer, length]
323+
end
324+
325+
# @param arg_pos [Integer]
326+
# @param parts [Array<String>]
327+
#
328+
# @return [Array<Symbol, Integer>]
329+
# - pointer [Symbol,nil]
330+
# - length [Integer]
331+
def prepare_argument_parts(parts:, arg_pos:)
332+
pointer = nil
333+
length = 0
334+
335+
if parts[-1] =~ /\[([0-9]+)?\]$/
336+
parts[-1].gsub!(/\[([0-9]+)?\]$/, "")
337+
length = ::Regexp.last_match(1).to_i
338+
pointer = :array
339+
end
340+
341+
unless parts[-1] =~ /^[0-9a-zA-Z_]+$/
342+
# last elements isn't dummy argument
343+
parts << "arg#{arg_pos}"
306344
end
307345

308-
ArgumentDefinition.new(
309-
type:,
310-
name:,
311-
pointer:,
312-
length:,
313-
)
346+
[pointer, length]
347+
end
348+
349+
# @param type [String]
350+
def pointer_length(type)
351+
type =~ /(\*+)$/
352+
::Regexp.last_match(1).length
314353
end
315354
end
316355
end

0 commit comments

Comments
 (0)