Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix comment directive parsing problem
Problem of comment parsing
The main problem is that
@preprocess.handle
parses comment, removes directive, and process code_object at the same time.This pull request change RDoc to parse comment and extract directives first, and then apply directives to code object.
Flow of legacy RDoc parsing method
For example parsing this code
Step 1
RDoc performs
@preprocess.hanlde
to RDoc::NormalClass.:category:
is applied to klass and replaced with blank line:not-new:
and:yields:
are replaced with blank line. maybe bug.:args: a, b
is replaced with:args: a, b
Step 2
RDoc performs
@preprocess.hanlde
to RDoc::AnyMethod.:args: a, b
is applied tometh.params
.Step 3
RDoc removes private section that starts with
#--
and ends with#++
.Step 4
RDoc normalizes comment by removing
#
and indentation.Step 5
RDoc extracts
":call-seq:\n initialize(x, y, z)
from comment and apply to method object.Problems
RDoc removes directives and expand
:include:
twice in some case, and once in other case.To avoid all directives removed in the first
@preprocess.handle
, preprocess needs directive-replace mechanizm which is making things complex.Private section and call-seq are processed later. This is making RDoc accept weird comment like directive inside private section and private section inside call-seq.
Handling meta programming method is also hard.
@preprocess.handle(comment, code_object)
requires code object already created.We need to parse the comment to know the code object type (method or attribute). After that, we can finally parse the comment with the code object.
C comments are also complicated. :include: can include text containing
*/
.Removing directive line and private section from the comment might remove
/*
and*/
which makes normalize_comment fail.The original implementation was avoiding this by using different processing order than ruby parser. This is not consistent.
Solution
We need to parse comment first and only once to extract directives.
Expand
:include:
, read directives (including:call-seq:
), remove private section at the same time.Comment parser should return normalized comment text and directives as an attribute hash. Directive should also contain line number.
Changed things
:call-seq:
New type of directive called "multiline directive" is introduced to make
:call-seq:
also a directive.Multiline directive ends with blank line. This restriction is for compatibility with old RDoc.
Some invalid multiline directive (unindented, ends with other directive) is also accepted with warning.
The resuld of parsing this call-seq is changed. I think it get better.
Private section
#----foobar
was accepted as private section start.#++++foobar
was decomposed to#++
(private end) and++foobar
(normal comment).Start is now
/^#-{2,}$/
(two or more -), end is now/^#\+{2}$/
(exactly two +).Unhandled directives
In old RDoc, unhandled directive
# :unknown: foo
remain in normal comment.Now it is removed just like other directives. Unhandled directive is appended to code object's metadata. It does not make sence to leave metadata in the comment. I think this was just a side effect of avoiding double parsing problem.
Normalize and remove private section
Everything is done in parse phase
C and Simple parser
C used to accept
/*\n# :directive:\n*/
but now only accepts* :directive:
.Changes for call-seq, private section and unhandled directive described above are also applied to C and Simple parser.
Old comment parsing
RDoc::Markup::PreProcess#handle
RDoc::Comment#extract_call_seq
RDoc::Comment#remove_private
is only used fromRDoc::Parser::Ruby
. We can remove them in the future.Diff
I compared generated html files of rdoc itself and c files in
ruby/ruby/*.c
.Diff are in
File/Stat.html
,Thread.html
andRDoc/Parser/Ruby.html
which I think acceptable.File/Stat.html
Parsing this
call-seq:
is improvedThread.html
Parsing this
call-seq:
began to fail but I think indentation of this comment is wrong.RDoc/Parser/Ruby.html
This is a metaprogramming comment that stars with
##
and contains:call-seq:
directive. It should be escaped like