diff --git a/lib/rdoc/code_object/class_module.rb b/lib/rdoc/code_object/class_module.rb index 76ded527a1..0a5647b51f 100644 --- a/lib/rdoc/code_object/class_module.rb +++ b/lib/rdoc/code_object/class_module.rb @@ -39,7 +39,7 @@ class RDoc::ClassModule < RDoc::Context # # Before marshalling: # - +location+ is an RDoc::TopLevel - # - +comments+ are Strings + # - +comments+ are Strings or RDoc::Comment objects # # After unmarshalling: # - +location+ is a filename String @@ -364,7 +364,7 @@ def marshal_dump # :nodoc: @name, full_name, @superclass, - parse(@comment_location), + parse_comment_locations(@comment_location), attrs, constants.select { |constant| constant.display? }, includes.map do |incl| @@ -479,10 +479,15 @@ def merge(class_module) @parent = class_module.parent @parent_name = class_module.parent_name - other_document = parse class_module.comment_location + other_comment_location = class_module.comment_location + other_document = if Hash === other_comment_location + class_module.parse_comment_locations(other_comment_location) + else + parse(other_comment_location) + end if other_document then - document = parse @comment_location + document = parse_comment_locations(@comment_location) document = document.merge other_document @@ -630,32 +635,19 @@ def name=(new_name) end ## - # Parses +comment_location+ into an RDoc::Markup::Document composed of + # Parses +comment_locations+ into an RDoc::Markup::Document composed of # multiple RDoc::Markup::Documents with their file set. - def parse(comment_location) - case comment_location - when String then - super - when Hash then - docs = comment_location.flat_map do |location, comments| - comments.map do |comment| - doc = super comment - doc.file = location - doc - end + def parse_comment_locations(comment_locations) + docs = comment_locations.flat_map do |location, comments| + comments.map do |comment| + document = parse(comment) + document.file = location unless RDoc::Comment === comment + document end - - RDoc::Markup::Document.new(*docs) - when RDoc::Comment then - doc = super comment_location.text, comment_location.format - doc.file = comment_location.location - doc - when RDoc::Markup::Document then - return comment_location - else - raise ArgumentError, "unknown comment class #{comment_location.class}" end + + RDoc::Markup::Document.new(*docs) end ## @@ -733,7 +725,7 @@ def search_record '', path, '', - snippet(@comment_location), + snippet(parse_comment_locations(@comment_location)), ] end @@ -756,7 +748,7 @@ def rebuild_comment_from_location comments.filter_map { |c| c.to_s unless c.empty? } } merged = texts.join("\n---\n") - @comment = merged.empty? ? '' : RDoc::Comment.new(merged) + @comment = merged end ## diff --git a/lib/rdoc/comment.rb b/lib/rdoc/comment.rb index b50193d56c..abe9919856 100644 --- a/lib/rdoc/comment.rb +++ b/lib/rdoc/comment.rb @@ -19,9 +19,11 @@ class RDoc::Comment attr_reader :format ## - # The RDoc::TopLevel this comment was found in + # The source this comment was read from. This is usually an + # RDoc::TopLevel. A comment loaded from a generated document without a file + # uses that RDoc::Markup::Document as its source. - attr_accessor :location + attr_reader :markup_source ## # Line where this Comment was written @@ -29,38 +31,28 @@ class RDoc::Comment attr_accessor :line ## - # For duck-typing when merging classes at load time - - alias file location # :nodoc: - - ## - # The text for this comment + # The text for this comment. attr_reader :text ## - # Alias for text + # Alias for text. alias to_s text ## - # Overrides the content returned by #parse. Use when there is no #text - # source for this comment + # Creates a new comment with +text+ from +markup_source+. - attr_writer :document + def initialize(text = nil, markup_source:, language: nil, format: 'rdoc', normalized: false) + raise ArgumentError, 'markup_source is required' unless markup_source - ## - # Creates a new comment with +text+ that is found in the RDoc::TopLevel - # +location+. - - def initialize(text = nil, location = nil, language = nil) - @location = location - @text = text.nil? ? nil : text.dup - @language = language + @markup_source = markup_source + @text = text.nil? ? nil : text.dup + @language = language @document = nil - @format = 'rdoc' - @normalized = false + @format = format + @normalized = normalized end ## @@ -68,19 +60,19 @@ def initialize(text = nil, location = nil, language = nil) # TODO deep copy @document def initialize_copy(copy) # :nodoc: - @text = copy.text.dup + @text = copy.text&.dup end def ==(other) # :nodoc: self.class === other and - other.text == @text and other.location == @location + other.text == @text and other.location == location end ## # A comment is empty if its text String is empty. def empty? - @text.empty? && (@document.nil? || @document.empty?) + @text.to_s.empty? && (@document.nil? || @document.empty?) end ## @@ -92,17 +84,42 @@ def encode!(encoding) end ## - # Sets the format of this comment and resets any parsed document + # Sets the format of this comment and resets its parsed document. def format=(format) @format = format @document = nil end + ## + # Sets the language of this comment and resets its parsed document. + + def language=(language) + @language = language + @document = nil + end + + ## + # The RDoc::TopLevel this comment was found in. + + def location + return @markup_source if RDoc::TopLevel === @markup_source + return @location if defined?(@location) + + file = @markup_source.file if @markup_source.respond_to?(:file) + @location = RDoc::TopLevel.new(file) if file + end + + ## + # For duck-typing when merging classes at load time. + + alias file location # :nodoc: + def inspect # :nodoc: - location = @location ? @location.relative_name : '(unknown)' + location = self.location + relative_name = location ? location.relative_name : '(unknown)' - "#<%s:%x %s %p>" % [self.class, object_id, location, @text] + "#<%s:%x %s %p>" % [self.class, object_id, relative_name, @text] end ## @@ -112,7 +129,9 @@ def normalize return self unless @text return self if @normalized # TODO eliminate duplicate normalization - @text = normalize_comment @text + text = normalize_comment @text + @document = nil if text != @text + @text = text @normalized = true @@ -134,13 +153,13 @@ def normalized? # :nodoc: ## # Parses the comment into an RDoc::Markup::Document. The parsed document is - # cached until the text is changed. + # cached until the text, format, or language changes. def parse return @document if @document @document = super @text, @format - @document.file = @location + @document.file = location if location @document end @@ -154,6 +173,7 @@ def text=(text) @text.nil? and @document @document = nil + @normalized = false @text = text.nil? ? nil : text.dup end @@ -176,12 +196,24 @@ def tomdoc? class << self ## - # Create a new parsed comment from a document - - def from_document(document) # :nodoc: - comment = RDoc::Comment.new('') - comment.document = document - comment.location = RDoc::TopLevel.new(document.file) if document.file + # Creates a comment from an already parsed +document+. + + def from_document(document, text: '', markup_source: nil, language: nil, format: 'rdoc', normalized: false) # :nodoc: + markup_source ||= if document.file + RDoc::TopLevel.new document.file + else + document + end + + comment = new( + text, + markup_source: markup_source, + language: language, + format: format, + normalized: normalized + ) + comment.normalize + comment.instance_variable_set :@document, document comment end diff --git a/lib/rdoc/generator/markup.rb b/lib/rdoc/generator/markup.rb index d6a56adf97..fd10190328 100644 --- a/lib/rdoc/generator/markup.rb +++ b/lib/rdoc/generator/markup.rb @@ -166,7 +166,9 @@ class RDoc::ClassModule # Handy wrapper for marking up this class or module's comment def description - markup @comment_location + return markup(@comment_location) if @store.options&.locale + + parse_comment_locations(@comment_location).accept(formatter) end end diff --git a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml b/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml index a08a1eb3a2..1828c94e04 100644 --- a/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +++ b/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml @@ -1,9 +1,14 @@ <%- comment = if current.respond_to? :comment_location - current.comment_location - else - current.comment - end - table = current.parse(comment).table_of_contents.dup + current.comment_location + else + current.comment + end + document = if Hash === comment + current.parse_comment_locations(comment) + else + current.parse(comment) + end + table = document.table_of_contents.dup if table.length > 1 %>