Skip to content

Commit 14e858e

Browse files
committed
Fix call-seq deduplicate for name overlap in aliases
Fix call-seq deduplicate of `Hash#value?` and `Hash#has_value?`. When alias names have overlap, deduplicate didn't work correctly.
1 parent aa20ac5 commit 14e858e

File tree

2 files changed

+66
-7
lines changed

2 files changed

+66
-7
lines changed

lib/rdoc/code_object/any_method.rb

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,6 @@ def deduplicate_call_seq(call_seq)
351351
return call_seq unless is_alias_for || !aliases.empty?
352352

353353
method_name = self.name
354-
method_name = method_name[0, 1] if method_name =~ /\A\[/
355354

356355
entries = call_seq.split "\n"
357356

@@ -360,15 +359,24 @@ def deduplicate_call_seq(call_seq)
360359
ignore << is_alias_for.name
361360
ignore.concat is_alias_for.aliases.map(&:name)
362361
end
363-
ignore.map! { |n| n =~ /\A\[/ ? /\[.*\]/ : n}
362+
364363
ignore.delete(method_name)
365-
ignore = Regexp.union(ignore)
364+
ignore_bracket_methods, ignore_other_methods = ignore.partition {|i| i.start_with?('[') }
366365

367-
matching = entries.reject do |entry|
368-
entry =~ /^\w*\.?#{ignore}[$\(\s]/ or
369-
entry =~ /\s#{ignore}\s/
366+
if ignore_other_methods.any?
367+
ignore_union = Regexp.union(ignore_other_methods)
368+
entries.reject! do |entry|
369+
/\A(\w*\.)?#{ignore_union}([(\s]|\z)/.match?(entry) ||
370+
/\s#{ignore_union}\s/.match?(entry)
371+
end
372+
end
373+
if ignore_bracket_methods.any?
374+
entries.reject! do |entry|
375+
# Ignore `receiver[arg] -> return_type` `[](arg)` `[]`
376+
entry.match?(/\A\w*\[.*\]([\(\s]|\z)/)
377+
end
370378
end
371379

372-
matching.empty? ? nil : matching.join("\n")
380+
entries.empty? ? nil : entries.join("\n")
373381
end
374382
end

test/rdoc/parser/c_test.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,6 +2107,57 @@ def test_scan_method_copy
21072107
assert_match 'str === obj', equals3.call_seq
21082108
end
21092109

2110+
def test_scan_method_copy_bracket_name
2111+
parser = util_parser <<~C
2112+
/*
2113+
* call-seq:
2114+
* obj[index] -> nil
2115+
* obj.aref(index) -> nil
2116+
*/
2117+
static VALUE
2118+
rb_obj_aref(VALUE obj, VALUE index) { return Qnil; }
2119+
2120+
Init_AB(void)
2121+
{
2122+
rb_define_method(rb_cObject, "[]", rb_obj_aref, 1);
2123+
rb_define_method(rb_cObject, "aref", rb_obj_aref, 1);
2124+
}
2125+
C
2126+
2127+
parser.scan
2128+
2129+
object = @store.classes_hash['Object']
2130+
bracket_method = object.method_list.find { |m| m.name == '[]' }
2131+
non_bracket_method = object.method_list.find { |m| m.name == 'aref' }
2132+
assert_equal 'obj[index] -> nil', bracket_method.call_seq
2133+
assert_equal 'obj.aref(index) -> nil', non_bracket_method.call_seq
2134+
end
2135+
2136+
def test_scan_method_copy_name_overlap
2137+
parser = util_parser <<~C
2138+
/*
2139+
* call-seq:
2140+
* value?(value) -> true or false
2141+
* has_value?(value) -> true or false
2142+
*/
2143+
static VALUE
2144+
rb_hash_has_value(VALUE hash, VALUE val) { return Qtrue; }
2145+
Init_Hash(void)
2146+
{
2147+
rb_define_method(rb_cHash, "has_value?", rb_hash_has_value, 1);
2148+
rb_define_method(rb_cHash, "value?", rb_hash_has_value, 1);
2149+
}
2150+
C
2151+
2152+
parser.scan
2153+
2154+
hash = @store.classes_hash['Hash']
2155+
value_method = hash.method_list.find { |m| m.name == 'value?' }
2156+
has_value_method = hash.method_list.find { |m| m.name == 'has_value?' }
2157+
assert_equal 'value?(value) -> true or false', value_method.call_seq
2158+
assert_equal 'has_value?(value) -> true or false', has_value_method.call_seq
2159+
end
2160+
21102161
def test_scan_order_dependent
21112162
parser = util_parser <<-C
21122163
void a(void) {

0 commit comments

Comments
 (0)