diff options
Diffstat (limited to 'lib/rdoc/parser')
-rw-r--r-- | lib/rdoc/parser/c.rb | 275 | ||||
-rw-r--r-- | lib/rdoc/parser/changelog.rb | 16 | ||||
-rw-r--r-- | lib/rdoc/parser/markdown.rb | 2 | ||||
-rw-r--r-- | lib/rdoc/parser/rd.rb | 1 | ||||
-rw-r--r-- | lib/rdoc/parser/ripper_state_lex.rb | 12 | ||||
-rw-r--r-- | lib/rdoc/parser/ruby.rb | 59 | ||||
-rw-r--r-- | lib/rdoc/parser/ruby_tools.rb | 2 | ||||
-rw-r--r-- | lib/rdoc/parser/text.rb | 1 |
8 files changed, 212 insertions, 156 deletions
diff --git a/lib/rdoc/parser/c.rb b/lib/rdoc/parser/c.rb index 9d8db6cdee..f8f238fd74 100644 --- a/lib/rdoc/parser/c.rb +++ b/lib/rdoc/parser/c.rb @@ -122,6 +122,11 @@ class RDoc::Parser::C < RDoc::Parser include RDoc::Text + # :stopdoc: + BOOL_ARG_PATTERN = /\s*+\b([01]|Q?(?:true|false)|TRUE|FALSE)\b\s*/ + TRUE_VALUES = ['1', 'TRUE', 'true', 'Qtrue'].freeze + # :startdoc: + ## # Maps C variable names to names of Ruby classes or modules @@ -173,6 +178,8 @@ class RDoc::Parser::C < RDoc::Parser @classes = load_variable_map :c_class_variables @singleton_classes = load_variable_map :c_singleton_class_variables + @markup = @options.markup + # class_variable => { function => [method, ...] } @methods = Hash.new { |h, f| h[f] = Hash.new { |i, m| i[m] = [] } } @@ -257,18 +264,18 @@ class RDoc::Parser::C < RDoc::Parser @content.scan(/rb_attr\s*\( \s*(\w+), \s*([\w"()]+), - \s*([01]), - \s*([01]), - \s*\w+\);/xm) do |var_name, attr_name, read, write| + #{BOOL_ARG_PATTERN}, + #{BOOL_ARG_PATTERN}, + \s*\w+\);/xmo) do |var_name, attr_name, read, write| handle_attr var_name, attr_name, read, write end @content.scan(%r%rb_define_attr\( \s*([\w\.]+), \s*"([^"]+)", - \s*(\d+), - \s*(\d+)\s*\); - %xm) do |var_name, attr_name, read, write| + #{BOOL_ARG_PATTERN}, + #{BOOL_ARG_PATTERN}\); + %xmo) do |var_name, attr_name, read, write| handle_attr var_name, attr_name, read, write end end @@ -293,94 +300,92 @@ class RDoc::Parser::C < RDoc::Parser @content.scan( %r( + (?<open>\s*\(\s*) {0} + (?<close>\s*\)\s*) {0} + (?<name>\s*"(?<class_name>\w+)") {0} + (?<parent>\s*(?: + (?<parent_name>[\w\*\s\(\)\.\->]+) | + rb_path2class\s*\(\s*"(?<path>[\w:]+)"\s*\) + )) {0} + (?<under>\w+) {0} + (?<var_name>[\w\.]+)\s* = \s*rb_(?: define_(?: - class(?: # rb_define_class(class_name_1, parent_name_1) - \s*\( - \s*"(?<class_name_1>\w+)", - \s*(?<parent_name_1>\w+)\s* - \) - | - _under\s*\( # rb_define_class_under(class_under, class_name2, parent_name2...) - \s* (?<class_under>\w+), - \s* "(?<class_name_2>\w+)", - \s* - (?: - (?<parent_name_2>[\w\*\s\(\)\.\->]+) | - rb_path2class\("(?<path>[\w:]+)"\) - ) + class(?: # rb_define_class(name, parent_name) + \(\s* + \g<name>, + \g<parent> \s*\) + | + _under\g<open> # rb_define_class_under(under, name, parent_name...) + \g<under>, + \g<name>, + \g<parent> + \g<close> ) | - module(?: # rb_define_module(module_name_1) - \s*\( - \s*"(?<module_name_1>\w+)"\s* - \) + (?<module>) + module(?: # rb_define_module(name) + \g<open> + \g<name> + \g<close> | - _under\s*\( # rb_define_module_under(module_under, module_name_2) - \s*(?<module_under>\w+), - \s*"(?<module_name_2>\w+)" - \s*\) + _under\g<open> # rb_define_module_under(under, name) + \g<under>, + \g<name> + \g<close> ) ) | - struct_define_without_accessor\s*\( # rb_struct_define_without_accessor(class_name_3, parent_name_3, ...) - \s*"(?<class_name_3>\w+)", - \s*(?<parent_name_3>\w+), - \s*\w+, # Allocation function - (?:\s*"\w+",)* # Attributes - \s*NULL - \) + (?<attributes>(?:\s*"\w+",)*\s*NULL\s*) {0} + struct_define(?: + \g<open> # rb_struct_define(name, ...) + \g<name>, + | + _under\g<open> # rb_struct_define_under(under, name, ...) + \g<under>, + \g<name>, + | + _without_accessor(?: + \g<open> # rb_struct_define_without_accessor(name, parent_name, ...) + | + _under\g<open> # rb_struct_define_without_accessor_under(under, name, parent_name, ...) + \g<under>, + ) + \g<name>, + \g<parent>, + \s*\w+, # Allocation function + ) + \g<attributes> + \g<close> | - singleton_class\s*\( # rb_singleton_class(target_class_name) - \s*(?<target_class_name>\w+) - \) + singleton_class\g<open> # rb_singleton_class(target_class_name) + (?<target_class_name>\w+) + \g<close> ) )mx ) do - class_name = $~[:class_name_1] - type = :class - if class_name - # rb_define_class(class_name_1, parent_name_1) - parent_name = $~[:parent_name_1] - #under = nil - else - class_name = $~[:class_name_2] - if class_name - # rb_define_class_under(class_under, class_name2, parent_name2...) - parent_name = $~[:parent_name_2] || $~[:path] - under = $~[:class_under] - else - class_name = $~[:class_name_3] - if class_name - # rb_struct_define_without_accessor(class_name_3, parent_name_3, ...) - parent_name = $~[:parent_name_3] - #under = nil - else - type = :module - class_name = $~[:module_name_1] - #parent_name = nil - if class_name - # rb_define_module(module_name_1) - #under = nil - else - class_name = $~[:module_name_2] - if class_name - # rb_define_module_under(module_under, module_name_1) - under = $~[:module_under] - else - # rb_singleton_class(target_class_name) - target_class_name = $~[:target_class_name] - handle_singleton $~[:var_name], target_class_name - next - end - end - end - end + if target_class_name = $~[:target_class_name] + # rb_singleton_class(target_class_name) + handle_singleton $~[:var_name], target_class_name + next end - handle_class_module($~[:var_name], type, class_name, parent_name, under) + var_name = $~[:var_name] + type = $~[:module] ? :module : :class + class_name = $~[:class_name] + parent_name = $~[:parent_name] || $~[:path] + under = $~[:under] + attributes = $~[:attributes] + + handle_class_module(var_name, type, class_name, parent_name, under) + if attributes and !parent_name # rb_struct_define *not* without_accessor + true_flag = 'Qtrue' + attributes.scan(/"\K\w+(?=")/) do |attr_name| + handle_attr var_name, attr_name, true_flag, true_flag + end + end end end @@ -439,7 +444,7 @@ class RDoc::Parser::C < RDoc::Parser next unless cls = @classes[c] m = @known_classes[m] || m - comment = RDoc::Comment.new '', @top_level, :c + comment = new_comment '', @top_level, :c incl = cls.add_include RDoc::Include.new(m, comment) incl.record_location @top_level end @@ -521,7 +526,7 @@ class RDoc::Parser::C < RDoc::Parser \s*"#{Regexp.escape new_name}"\s*, \s*"#{Regexp.escape old_name}"\s*\);%xm - RDoc::Comment.new($1 || '', @top_level, :c) + new_comment($1 || '', @top_level, :c) end ## @@ -560,7 +565,7 @@ class RDoc::Parser::C < RDoc::Parser '' end - RDoc::Comment.new comment, @top_level, :c + new_comment comment, @top_level, :c end ## @@ -570,19 +575,18 @@ class RDoc::Parser::C < RDoc::Parser table = {} file_content.scan(%r{ ((?>/\*.*?\*/\s*)?) - ((?:(?:\w+)\s+)? - (?:intern\s+)?VALUE\s+(\w+) - \s*(?:\([^)]*\))(?:[^\);]|$)) + ((?:\w+\s+){0,2} VALUE\s+(\w+) + \s*(?:\([^\)]*\))(?:[^\);]|$)) | ((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+(\w+)\s+(\w+)) | ^\s*\#\s*define\s+(\w+)\s+(\w+) }xm) do case - when $1 - table[$3] = [:func_def, $1, $2, $~.offset(2)] if !table[$3] || table[$3][0] != :func_def - when $4 - table[$6] = [:macro_def, $4, $5, $~.offset(5), $7] if !table[$6] || table[$6][0] == :macro_alias - when $8 - table[$8] ||= [:macro_alias, $9] + when name = $3 + table[name] = [:func_def, $1, $2, $~.offset(2)] if !(t = table[name]) || t[0] != :func_def + when name = $6 + table[name] = [:macro_def, $4, $5, $~.offset(5), $7] if !(t = table[name]) || t[0] == :macro_alias + when name = $8 + table[name] ||= [:macro_alias, $9] end end table @@ -600,7 +604,7 @@ class RDoc::Parser::C < RDoc::Parser case type when :func_def - comment = RDoc::Comment.new args[0], @top_level, :c + comment = new_comment args[0], @top_level, :c body = args[1] offset, = args[2] @@ -630,7 +634,7 @@ class RDoc::Parser::C < RDoc::Parser body when :macro_def - comment = RDoc::Comment.new args[0], @top_level, :c + comment = new_comment args[0], @top_level, :c body = args[1] offset, = args[2] @@ -675,13 +679,14 @@ class RDoc::Parser::C < RDoc::Parser ## # Finds a RDoc::NormalClass or RDoc::NormalModule for +raw_name+ - def find_class(raw_name, name) + def find_class(raw_name, name, base_name = nil) unless @classes[raw_name] if raw_name =~ /^rb_m/ container = @top_level.add_module RDoc::NormalModule, name else container = @top_level.add_class RDoc::NormalClass, name end + container.name = base_name if base_name container.record_location @top_level @classes[raw_name] = container @@ -722,7 +727,7 @@ class RDoc::Parser::C < RDoc::Parser ((?>/\*.*?\*/\s+)) (static\s+)? void\s+ - Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xmi then + Init(?:VM)?_(?i:#{class_name})\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xm then comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '') elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*? (?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then @@ -737,7 +742,7 @@ class RDoc::Parser::C < RDoc::Parser comment = '' end - comment = RDoc::Comment.new comment, @top_level, :c + comment = new_comment comment, @top_level, :c comment.normalize look_for_directives_in class_mod, comment @@ -751,17 +756,27 @@ class RDoc::Parser::C < RDoc::Parser def gen_const_table file_content table = {} @content.scan(%r{ - ((?>^\s*/\*.*?\*/\s+)) - rb_define_(\w+)\((?:\s*(?:\w+),)?\s* - "(\w+)"\s*, + (?<doc>(?>^\s*/\*.*?\*/\s+)) + rb_define_(?<type>\w+)\(\s*(?:\w+),\s* + "(?<name>\w+)"\s*, .*?\)\s*; + | (?<doc>(?>^\s*/\*.*?\*/\s+)) + rb_file_(?<type>const)\(\s* + "(?<name>\w+)"\s*, + .*?\)\s*; + | (?<doc>(?>^\s*/\*.*?\*/\s+)) + rb_curses_define_(?<type>const)\(\s* + (?<name>\w+) + \s*\)\s*; | Document-(?:const|global|variable):\s - ((?:\w+::)*\w+) - \s*?\n((?>.*?\*/)) + (?<name>(?:\w+::)*\w+) + \s*?\n(?<doc>(?>.*?\*/)) }mxi) do - case - when $1 then table[[$2, $3]] = $1 - when $4 then table[$4] = "/*\n" + $5 + name, doc, type = $~.values_at(:name, :doc, :type) + if type + table[[type, name]] = doc + else + table[name] = "/*\n" + doc end end table @@ -782,7 +797,7 @@ class RDoc::Parser::C < RDoc::Parser table[const_name] || '' - RDoc::Comment.new comment, @top_level, :c + new_comment comment, @top_level, :c end ## @@ -813,7 +828,7 @@ class RDoc::Parser::C < RDoc::Parser return unless comment - RDoc::Comment.new comment, @top_level, :c + new_comment comment, @top_level, :c end ## @@ -822,8 +837,8 @@ class RDoc::Parser::C < RDoc::Parser def handle_attr(var_name, attr_name, read, write) rw = '' - rw += 'R' if '1' == read - rw += 'W' if '1' == write + rw += 'R' if TRUE_VALUES.include?(read) + rw += 'W' if TRUE_VALUES.include?(write) class_name = @known_classes[var_name] @@ -919,7 +934,7 @@ class RDoc::Parser::C < RDoc::Parser return unless class_name - class_obj = find_class var_name, class_name + class_obj = find_class var_name, class_name, class_name[/::\K[^:]+\z/] unless class_obj then @options.warn 'Enclosing class or module %p is not known' % [const_name] @@ -933,21 +948,20 @@ class RDoc::Parser::C < RDoc::Parser # "/* definition: comment */" form. The literal ':' and '\' characters # can be escaped with a backslash. if type.downcase == 'const' then - no_match, new_definition, new_comment = comment.text.split(/(\A.*):/) + if /\A(.+?)?:(?!\S)/ =~ comment.text + new_definition, new_comment = $1, $' - if no_match and no_match.empty? then - if new_definition.empty? then # Default to literal C definition + if !new_definition # Default to literal C definition new_definition = definition else - new_definition = new_definition.gsub("\:", ":") - new_definition = new_definition.gsub("\\", '\\') + new_definition = new_definition.gsub(/\\([\\:])/, '\1') end new_definition.sub!(/\A(\s+)/, '') new_comment = "#{$1}#{new_comment.lstrip}" - new_comment = RDoc::Comment.new new_comment, @top_level, :c + new_comment = self.new_comment(new_comment, @top_level, :c) con = RDoc::Constant.new const_name, new_definition, new_comment else @@ -1023,12 +1037,18 @@ class RDoc::Parser::C < RDoc::Parser elsif p_count == -1 then # argc, argv rb_scan_args body else - "(#{(1..p_count).map { |i| "p#{i}" }.join ', '})" + args = (1..p_count).map { |i| "p#{i}" } + "(#{args.join ', '})" end meth_obj.record_location @top_level + + if meth_obj.section_title + class_obj.temporary_section = class_obj.add_section(meth_obj.section_title) + end class_obj.add_method meth_obj + @stats.add_method meth_obj meth_obj.visibility = :private if 'private_method' == type end @@ -1046,23 +1066,6 @@ class RDoc::Parser::C < RDoc::Parser end ## - # Normalizes tabs in +body+ - - def handle_tab_width(body) - if /\t/ =~ body - tab_width = @options.tab_width - body.split(/\n/).map do |line| - 1 while line.gsub!(/\t+/) do - ' ' * (tab_width * $&.length - $`.length % tab_width) - end && $~ - line - end.join "\n" - else - body - end - end - - ## # Loads the variable map with the given +name+ from the RDoc::Store, if # present. @@ -1222,4 +1225,12 @@ class RDoc::Parser::C < RDoc::Parser @top_level end + ## + # Creates a RDoc::Comment instance. + + def new_comment text = nil, location = nil, language = nil + RDoc::Comment.new(text, location, language).tap do |comment| + comment.format = @markup + end + end end diff --git a/lib/rdoc/parser/changelog.rb b/lib/rdoc/parser/changelog.rb index 9245d49376..a046241870 100644 --- a/lib/rdoc/parser/changelog.rb +++ b/lib/rdoc/parser/changelog.rb @@ -216,12 +216,22 @@ class RDoc::Parser::ChangeLog < RDoc::Parser @top_level end + ## + # The extension for Git commit log + module Git + ## + # Parses auxiliary info. Currentry `base-url` to expand + # references is effective. + def parse_info(info) /^\s*base-url\s*=\s*(.*\S)/ =~ info @base_url = $1 end + ## + # Parses the entries in the Git commit logs + def parse_entries entries = [] @@ -244,6 +254,11 @@ class RDoc::Parser::ChangeLog < RDoc::Parser entries end + ## + # Returns a list of ChangeLog entries as + # RDoc::Parser::ChangeLog::Git::LogEntry list for the given + # +entries+. + def create_entries entries # git log entries have no strictly itemized style like the old # style, just assume Markdown. @@ -332,4 +347,3 @@ class RDoc::Parser::ChangeLog < RDoc::Parser end end end - diff --git a/lib/rdoc/parser/markdown.rb b/lib/rdoc/parser/markdown.rb index 9ff478f872..3c316227b9 100644 --- a/lib/rdoc/parser/markdown.rb +++ b/lib/rdoc/parser/markdown.rb @@ -20,5 +20,3 @@ class RDoc::Parser::Markdown < RDoc::Parser end end - - diff --git a/lib/rdoc/parser/rd.rb b/lib/rdoc/parser/rd.rb index 25f5711731..19e47e549d 100644 --- a/lib/rdoc/parser/rd.rb +++ b/lib/rdoc/parser/rd.rb @@ -20,4 +20,3 @@ class RDoc::Parser::RD < RDoc::Parser end end - diff --git a/lib/rdoc/parser/ripper_state_lex.rb b/lib/rdoc/parser/ripper_state_lex.rb index 5492f08726..f6cefd0305 100644 --- a/lib/rdoc/parser/ripper_state_lex.rb +++ b/lib/rdoc/parser/ripper_state_lex.rb @@ -1,7 +1,12 @@ # frozen_string_literal: true require 'ripper' +## +# Wrapper for Ripper lex states + class RDoc::Parser::RipperStateLex + # :stopdoc: + # TODO: Remove this constants after Ruby 2.4 EOL RIPPER_HAS_LEX_STATE = Ripper::Filter.method_defined?(:state) @@ -368,7 +373,7 @@ class RDoc::Parser::RipperStateLex private def get_symbol_tk(tk) is_symbol = true symbol_tk = Token.new(tk.line_no, tk.char_no, :on_symbol) - if ":'" == tk[:text] or ':"' == tk[:text] + if ":'" == tk[:text] or ':"' == tk[:text] or tk[:text].start_with?('%s') tk1 = get_string_tk(tk) symbol_tk[:text] = tk1[:text] symbol_tk[:state] = tk1[:state] @@ -565,6 +570,9 @@ class RDoc::Parser::RipperStateLex tk end + # :startdoc: + + # New lexer for +code+. def initialize(code) @buf = [] @heredoc_queue = [] @@ -572,6 +580,7 @@ class RDoc::Parser::RipperStateLex @tokens = @inner_lex.parse([]) end + # Returns tokens parsed from +code+. def self.parse(code) lex = self.new(code) tokens = [] @@ -584,6 +593,7 @@ class RDoc::Parser::RipperStateLex tokens end + # Returns +true+ if lex state will be +END+ after +token+. def self.end?(token) (token[:state] & EXPR_END) end diff --git a/lib/rdoc/parser/ruby.rb b/lib/rdoc/parser/ruby.rb index e546fe2141..85f1cd0391 100644 --- a/lib/rdoc/parser/ruby.rb +++ b/lib/rdoc/parser/ruby.rb @@ -8,6 +8,9 @@ # by Keiju ISHITSUKA (Nippon Rational Inc.) # +require 'ripper' +require_relative 'ripper_state_lex' + ## # Extracts code elements from a source file returning a TopLevel object # containing the constituent file elements. @@ -138,9 +141,6 @@ # Note that by default, the :method: directive will be ignored if there is a # standard rdocable item following it. -require 'ripper' -require_relative 'ripper_state_lex' - class RDoc::Parser::Ruby < RDoc::Parser parse_files_matching(/\.rbw?$/) @@ -164,15 +164,7 @@ class RDoc::Parser::Ruby < RDoc::Parser def initialize(top_level, file_name, content, options, stats) super - if /\t/ =~ content then - tab_width = @options.tab_width - content = content.split(/\n/).map do |line| - 1 while line.gsub!(/\t+/) { - ' ' * (tab_width*$&.length - $`.length % tab_width) - } && $~ - line - end.join("\n") - end + content = handle_tab_width(content) @size = 0 @token_listeners = nil @@ -188,6 +180,9 @@ class RDoc::Parser::Ruby < RDoc::Parser reset end + ## + # Return +true+ if +tk+ is a newline. + def tk_nl?(tk) :on_nl == tk[:kind] or :on_ignored_nl == tk[:kind] end @@ -400,6 +395,29 @@ class RDoc::Parser::Ruby < RDoc::Parser end ## + # Skip opening parentheses and yield the block. + # Skip closing parentheses too when exists. + + def skip_parentheses(&block) + left_tk = peek_tk + + if :on_lparen == left_tk[:kind] + get_tk + + ret = skip_parentheses(&block) + + right_tk = peek_tk + if :on_rparen == right_tk[:kind] + get_tk + end + + ret + else + yield + end + end + + ## # Return a superclass, which can be either a constant of an expression def get_class_specification @@ -771,8 +789,10 @@ class RDoc::Parser::Ruby < RDoc::Parser al.line = line_no read_documentation_modifiers al, RDoc::ATTR_MODIFIERS - context.add_alias al - @stats.add_alias al + if al.document_self or not @track_visibility + context.add_alias al + @stats.add_alias al + end al end @@ -833,7 +853,7 @@ class RDoc::Parser::Ruby < RDoc::Parser cls = parse_class_regular container, declaration_context, single, name_t, given_name, comment elsif name_t[:kind] == :on_op && name_t[:text] == '<<' - case name = get_class_specification + case name = skip_parentheses { get_class_specification } when 'self', container.name read_documentation_modifiers cls, RDoc::CLASS_MODIFIERS parse_statements container, SINGLE @@ -1435,6 +1455,12 @@ class RDoc::Parser::Ruby < RDoc::Parser meth = RDoc::AnyMethod.new get_tkread, name look_for_directives_in meth, comment meth.singleton = single == SINGLE ? true : singleton + if singleton + # `current_line_visibility' is useless because it works against + # the normal method named as same as the singleton method, after + # the latter was defined. Of course these are different things. + container.current_line_visibility = :public + end record_location meth meth.line = line_no @@ -1758,6 +1784,7 @@ class RDoc::Parser::Ruby < RDoc::Parser nest = 1 save_visibility = container.visibility + container.visibility = :public unless current_method non_comment_seen = true @@ -2119,7 +2146,7 @@ class RDoc::Parser::Ruby < RDoc::Parser if :on_nl == tk[:kind] or (:on_kw == tk[:kind] && 'def' == tk[:text]) then return elsif :on_comment == tk[:kind] or :on_embdoc == tk[:kind] then - return unless tk[:text] =~ /\s*:?([\w-]+):\s*(.*)/ + return unless tk[:text] =~ /:?\b([\w-]+):\s*(.*)/ directive = $1.downcase diff --git a/lib/rdoc/parser/ruby_tools.rb b/lib/rdoc/parser/ruby_tools.rb index 681d7166ce..40ea517c4d 100644 --- a/lib/rdoc/parser/ruby_tools.rb +++ b/lib/rdoc/parser/ruby_tools.rb @@ -163,5 +163,3 @@ module RDoc::Parser::RubyTools end end - - diff --git a/lib/rdoc/parser/text.rb b/lib/rdoc/parser/text.rb index 01de0cc595..5095d8cc64 100644 --- a/lib/rdoc/parser/text.rb +++ b/lib/rdoc/parser/text.rb @@ -9,4 +9,3 @@ module RDoc::Parser::Text end - |