ruby-changes:61364
From: Jeremy <ko1@a...>
Date: Sun, 24 May 2020 23:53:20 +0900 (JST)
Subject: [ruby-changes:61364] 7e7981c84f (master): [ruby/rdoc] Treat multiple Ruby methods calling the same C method as aliases
https://git.ruby-lang.org/ruby.git/commit/?id=7e7981c84f From 7e7981c84f8cd3225b5e915cba2281869a08b784 Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Tue, 10 Sep 2019 16:17:09 -0700 Subject: [ruby/rdoc] 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. https://github.com/ruby/rdoc/commit/0ead78616b diff --git a/lib/rdoc/any_method.rb b/lib/rdoc/any_method.rb index 9b0d309..562e684 100644 --- a/lib/rdoc/any_method.rb +++ b/lib/rdoc/any_method.rb @@ -26,12 +26,6 @@ class RDoc::AnyMethod < RDoc::MethodAttr https://github.com/ruby/ruby/blob/trunk/lib/rdoc/any_method.rb#L26 attr_accessor :c_function - ## - # Different ways to call this method - - attr_reader :call_seq - - ## # Parameters for this method attr_accessor :params @@ -94,6 +88,19 @@ class RDoc::AnyMethod < RDoc::MethodAttr https://github.com/ruby/ruby/blob/trunk/lib/rdoc/any_method.rb#L88 end ## + # Different ways to call this method + + def call_seq + unless call_seq = _call_seq + call_seq = is_alias_for._call_seq if is_alias_for + end + + return unless call_seq + + deduplicate_call_seq(call_seq) + end + + ## # Sets the different ways you can call this method. If an empty +call_seq+ # is given nil is assumed. # @@ -312,5 +319,43 @@ class RDoc::AnyMethod < RDoc::MethodAttr https://github.com/ruby/ruby/blob/trunk/lib/rdoc/any_method.rb#L319 @superclass_method end -end + protected + + ## + # call_seq without deduplication and alias lookup. + + def _call_seq + @call_seq if defined?(@call_seq) && @call_seq + end + + private + + ## + # call_seq with alias examples information removed, if this + # method is an alias method. + + def deduplicate_call_seq(call_seq) + return call_seq unless is_alias_for || !aliases.empty? + + method_name = self.name + method_name = method_name[0, 1] if method_name =~ /\A\[/ + entries = call_seq.split "\n" + + ignore = aliases.map(&:name) + if is_alias_for + ignore << is_alias_for.name + ignore.concat is_alias_for.aliases.map(&:name) + end + ignore.map! { |n| n =~ /\A\[/ ? n[0, 1] : n} + ignore.delete(method_name) + ignore = Regexp.union(ignore) + + matching = entries.reject do |entry| + entry =~ /^\w*\.?#{ignore}/ or + entry =~ /\s#{ignore}\s/ + end + + matching.join "\n" + end +end diff --git a/lib/rdoc/generator/template/darkfish/class.rhtml b/lib/rdoc/generator/template/darkfish/class.rhtml index 7733095..596764d 100644 --- a/lib/rdoc/generator/template/darkfish/class.rhtml +++ b/lib/rdoc/generator/template/darkfish/class.rhtml @@ -98,8 +98,8 @@ https://github.com/ruby/ruby/blob/trunk/lib/rdoc/generator/template/darkfish/class.rhtml#L98 <% methods.each do |method| %> <div id="<%= method.aref %>" class="method-detail <%= method.is_alias_for ? "method-alias" : '' %>"> - <% if method.call_seq then %> - <% method.call_seq.strip.split("\n").each_with_index do |call_seq, i| %> + <% if (call_seq = method.call_seq) then %> + <% call_seq.strip.split("\n").each_with_index do |call_seq, i| %> <div class="method-heading"> <span class="method-callseq"> <%= h(call_seq.strip. diff --git a/lib/rdoc/parser/c.rb b/lib/rdoc/parser/c.rb index 8265712..707a898 100644 --- a/lib/rdoc/parser/c.rb +++ b/lib/rdoc/parser/c.rb @@ -210,48 +210,6 @@ class RDoc::Parser::C < RDoc::Parser https://github.com/ruby/ruby/blob/trunk/lib/rdoc/parser/c.rb#L210 end ## - # Removes duplicate call-seq entries for methods using the same - # implementation. - - def deduplicate_call_seq - @methods.each do |var_name, functions| - class_name = @known_classes[var_name] - next unless class_name - class_obj = find_class var_name, class_name - - functions.each_value do |method_names| - next if method_names.length == 1 - - method_names.each do |method_name| - deduplicate_method_name class_obj, method_name - end - end - end - end - - ## - # If two ruby methods share a C implementation (and comment) this - # deduplicates the examples in the call_seq for the method to reduce - # confusion in the output. - - def deduplicate_method_name class_obj, method_name # :nodoc: - return unless - method = class_obj.method_list.find { |m| m.name == method_name } - return unless call_seq = method.call_seq - - method_name = method_name[0, 1] if method_name =~ /\A\[/ - - entries = call_seq.split "\n" - - matching = entries.select do |entry| - entry =~ /^\w*\.?#{Regexp.escape method_name}/ or - entry =~ /\s#{Regexp.escape method_name}\s/ - end - - method.call_seq = matching.join "\n" - end - - ## # Scans #content for rb_define_alias def do_aliases @@ -269,24 +227,30 @@ class RDoc::Parser::C < RDoc::Parser https://github.com/ruby/ruby/blob/trunk/lib/rdoc/parser/c.rb#L227 end class_obj = find_class var_name, class_name - - al = RDoc::Alias.new '', old_name, new_name, '' - al.singleton = @singleton_classes.key? var_name - comment = find_alias_comment var_name, new_name, old_name - comment.normalize - - al.comment = comment - - al.record_location @top_level - - class_obj.add_alias al - @stats.add_alias al + if comment.to_s.empty? and existing_method = class_obj.method_list.find { |m| m.name == old_name} + comment = existing_method.comment + end + add_alias(var_name, class_obj, old_name, new_name, comment) end end ## + # Add alias, either from a direct alias definition, or from two + # method that reference the same function. + + def add_alias(var_name, class_obj, old_name, new_name, comment) + al = RDoc::Alias.new '', old_name, new_name, '' + al.singleton = @singleton_classes.key? var_name + al.comment = comment + al.record_location @top_level + class_obj.add_alias al + @stats.add_alias al + al + end + + ## # Scans #content for rb_attr and rb_define_attr def do_attrs @@ -1021,6 +985,10 @@ class RDoc::Parser::C < RDoc::Parser https://github.com/ruby/ruby/blob/trunk/lib/rdoc/parser/c.rb#L985 class_obj = find_class var_name, class_name + if existing_method = class_obj.method_list.find { |m| m.c_function == function } + add_alias(var_name, class_obj, existing_method.name, meth_name, existing_method.comment) + end + if class_obj then if meth_name == 'initialize' then meth_name = 'new' @@ -1249,8 +1217,6 @@ class RDoc::Parser::C < RDoc::Parser https://github.com/ruby/ruby/blob/trunk/lib/rdoc/parser/c.rb#L1217 do_aliases do_attrs - deduplicate_call_seq - @store.add_c_variables self @top_level -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/