Skip to content

Commit 0ead786

Browse files
committed
Treat multiple Ruby methods calling the same C method as aliases
Previously, only calls to rb_define_alias were treated as aliases. This treats calls to rb_define_method with the same C function as aliases, with the first function defined being the primary method. This move the dedup code from the C parser to AnyMethod, and has AnyMethod look in its aliases to find the call_seq. Switch the deduplication code to remove lines matching one of the other aliases, instead of only keeping lines matching the current alias. The previous approach could eliminate all call_seq lines in cases where no line matched. This was necessary to pass tests when call_seq does deduplication by default. The only change to the darkfish template is to not perform unnecessary work by deduplicating twice.
1 parent 5782377 commit 0ead786

File tree

3 files changed

+76
-65
lines changed

3 files changed

+76
-65
lines changed

lib/rdoc/any_method.rb

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,6 @@ class RDoc::AnyMethod < RDoc::MethodAttr
2626

2727
attr_accessor :c_function
2828

29-
##
30-
# Different ways to call this method
31-
32-
attr_reader :call_seq
33-
34-
##
3529
# Parameters for this method
3630

3731
attr_accessor :params
@@ -93,6 +87,19 @@ def arglists
9387
end
9488
end
9589

90+
##
91+
# Different ways to call this method
92+
93+
def call_seq
94+
unless call_seq = _call_seq
95+
call_seq = is_alias_for._call_seq if is_alias_for
96+
end
97+
98+
return unless call_seq
99+
100+
deduplicate_call_seq(call_seq)
101+
end
102+
96103
##
97104
# Sets the different ways you can call this method. If an empty +call_seq+
98105
# is given nil is assumed.
@@ -312,5 +319,43 @@ def superclass_method
312319
@superclass_method
313320
end
314321

315-
end
322+
protected
323+
324+
##
325+
# call_seq without deduplication and alias lookup.
326+
327+
def _call_seq
328+
@call_seq if defined?(@call_seq) && @call_seq
329+
end
330+
331+
private
332+
333+
##
334+
# call_seq with alias examples information removed, if this
335+
# method is an alias method.
336+
337+
def deduplicate_call_seq(call_seq)
338+
return call_seq unless is_alias_for || !aliases.empty?
339+
340+
method_name = self.name
341+
method_name = method_name[0, 1] if method_name =~ /\A\[/
316342

343+
entries = call_seq.split "\n"
344+
345+
ignore = aliases.map(&:name)
346+
if is_alias_for
347+
ignore << is_alias_for.name
348+
ignore.concat is_alias_for.aliases.map(&:name)
349+
end
350+
ignore.map! { |n| n =~ /\A\[/ ? n[0, 1] : n}
351+
ignore.delete(method_name)
352+
ignore = Regexp.union(ignore)
353+
354+
matching = entries.reject do |entry|
355+
entry =~ /^\w*\.?#{ignore}/ or
356+
entry =~ /\s#{ignore}\s/
357+
end
358+
359+
matching.join "\n"
360+
end
361+
end

lib/rdoc/generator/template/darkfish/class.rhtml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@
9898

9999
<% methods.each do |method| %>
100100
<div id="<%= method.aref %>" class="method-detail <%= method.is_alias_for ? "method-alias" : '' %>">
101-
<% if method.call_seq then %>
102-
<% method.call_seq.strip.split("\n").each_with_index do |call_seq, i| %>
101+
<% if (call_seq = method.call_seq) then %>
102+
<% call_seq.strip.split("\n").each_with_index do |call_seq, i| %>
103103
<div class="method-heading">
104104
<span class="method-callseq">
105105
<%= h(call_seq.strip.

lib/rdoc/parser/c.rb

Lines changed: 22 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -209,48 +209,6 @@ def @enclosure_dependencies.tsort_each_child node, &block
209209
end
210210
end
211211

212-
##
213-
# Removes duplicate call-seq entries for methods using the same
214-
# implementation.
215-
216-
def deduplicate_call_seq
217-
@methods.each do |var_name, functions|
218-
class_name = @known_classes[var_name]
219-
next unless class_name
220-
class_obj = find_class var_name, class_name
221-
222-
functions.each_value do |method_names|
223-
next if method_names.length == 1
224-
225-
method_names.each do |method_name|
226-
deduplicate_method_name class_obj, method_name
227-
end
228-
end
229-
end
230-
end
231-
232-
##
233-
# If two ruby methods share a C implementation (and comment) this
234-
# deduplicates the examples in the call_seq for the method to reduce
235-
# confusion in the output.
236-
237-
def deduplicate_method_name class_obj, method_name # :nodoc:
238-
return unless
239-
method = class_obj.method_list.find { |m| m.name == method_name }
240-
return unless call_seq = method.call_seq
241-
242-
method_name = method_name[0, 1] if method_name =~ /\A\[/
243-
244-
entries = call_seq.split "\n"
245-
246-
matching = entries.select do |entry|
247-
entry =~ /^\w*\.?#{Regexp.escape method_name}/ or
248-
entry =~ /\s#{Regexp.escape method_name}\s/
249-
end
250-
251-
method.call_seq = matching.join "\n"
252-
end
253-
254212
##
255213
# Scans #content for rb_define_alias
256214

@@ -269,23 +227,29 @@ def do_aliases
269227
end
270228

271229
class_obj = find_class var_name, class_name
272-
273-
al = RDoc::Alias.new '', old_name, new_name, ''
274-
al.singleton = @singleton_classes.key? var_name
275-
276230
comment = find_alias_comment var_name, new_name, old_name
277-
278231
comment.normalize
279-
280-
al.comment = comment
281-
282-
al.record_location @top_level
283-
284-
class_obj.add_alias al
285-
@stats.add_alias al
232+
if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name}
233+
comment = existing_method.comment
234+
end
235+
add_alias(var_name, class_obj, old_name, new_name, comment)
286236
end
287237
end
288238

239+
##
240+
# Add alias, either from a direct alias definition, or from two
241+
# method that reference the same function.
242+
243+
def add_alias(var_name, class_obj, old_name, new_name, comment)
244+
al = RDoc::Alias.new '', old_name, new_name, ''
245+
al.singleton = @singleton_classes.key? var_name
246+
al.comment = comment
247+
al.record_location @top_level
248+
class_obj.add_alias al
249+
@stats.add_alias al
250+
al
251+
end
252+
289253
##
290254
# Scans #content for rb_attr and rb_define_attr
291255

@@ -1021,6 +985,10 @@ def handle_method(type, var_name, meth_name, function, param_count,
1021985

1022986
class_obj = find_class var_name, class_name
1023987

988+
if existing_method = class_obj.method_list.find { |m| m.c_function == function }
989+
add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment)
990+
end
991+
1024992
if class_obj then
1025993
if meth_name == 'initialize' then
1026994
meth_name = 'new'
@@ -1249,8 +1217,6 @@ def scan
12491217
do_aliases
12501218
do_attrs
12511219

1252-
deduplicate_call_seq
1253-
12541220
@store.add_c_variables self
12551221

12561222
@top_level

0 commit comments

Comments
 (0)