Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 20 additions & 28 deletions lib/rdoc/code_object/class_module.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reflects existing behaviour. It's not introduced in this PR

#
# After unmarshalling:
# - +location+ is a filename String
Expand Down Expand Up @@ -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|
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

##
Expand Down Expand Up @@ -733,7 +725,7 @@ def search_record
'',
path,
'',
snippet(@comment_location),
snippet(parse_comment_locations(@comment_location)),
]
end

Expand All @@ -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

##
Expand Down
106 changes: 69 additions & 37 deletions lib/rdoc/comment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,68 +19,60 @@ 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

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

##
#--
# 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

##
Expand All @@ -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

##
Expand All @@ -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

Expand All @@ -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

Expand All @@ -154,6 +173,7 @@ def text=(text)
@text.nil? and @document

@document = nil
@normalized = false
@text = text.nil? ? nil : text.dup
end

Expand All @@ -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

Expand Down
4 changes: 3 additions & 1 deletion lib/rdoc/generator/markup.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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 %>
<div class="nav-section">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<li class="<%= klass.type %>">
<a href="<%= klass.path %>"><%= klass.full_name %></a>
<%- table = []
table.concat klass.parse(klass.comment_location).table_of_contents
table.concat klass.parse_comment_locations(klass.comment_location).table_of_contents
table.concat klass.section_contents

unless table.empty? %>
Expand Down
9 changes: 6 additions & 3 deletions lib/rdoc/parser/c.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1219,8 +1219,11 @@ def scan
# 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
RDoc::Comment.new(
text,
markup_source: location || @top_level,
language: language,
format: @markup
)
end
end
8 changes: 6 additions & 2 deletions lib/rdoc/parser/changelog.rb
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,12 @@ def scan
grouped_entries = group_entries entries

doc = create_document grouped_entries
comment = RDoc::Comment.new(@content)
comment.document = doc
doc.file = @top_level
comment = RDoc::Comment.from_document(
doc,
text: @content,
markup_source: @top_level
)
@top_level.comment = comment

@top_level
Expand Down
7 changes: 5 additions & 2 deletions lib/rdoc/parser/markdown.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ class RDoc::Parser::Markdown < RDoc::Parser
# Creates an Markdown-format TopLevel for the given file.

def scan
comment = RDoc::Comment.new @content, @top_level
comment.format = 'markdown'
comment = RDoc::Comment.new(
@content,
markup_source: @top_level,
format: 'markdown'
)

@top_level.comment = comment
end
Expand Down
Loading