rdx 0.9.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rdx +20 -0
- data/README +19 -0
- data/bin/rdx +7 -0
- data/examples/minimal/.rdx +8 -0
- data/examples/minimal/README +10 -0
- data/examples/minimal/lib/other_conventions.rb +64 -0
- data/examples/minimal/lib/the_basics.rb +94 -0
- data/examples/minimal/lib/using_directives.rb +66 -0
- data/examples/minimal/rakefile +27 -0
- data/examples/ruby-2.0.0-p0/README +7 -0
- data/examples/ruby-2.0.0-p0/install/core/.rdx +6 -0
- data/examples/ruby-2.0.0-p0/install/core/README +19 -0
- data/examples/ruby-2.0.0-p0/install/core/Rakefile +61 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/array.c.diff +166 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/bignum.c.diff +11 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/class.c.diff +36 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/compar.c.diff +11 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/complex.c.diff +301 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/cont.c.diff +65 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/dir.c.diff +147 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/re.rdoc.diff +328 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/security.rdoc.diff +8 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/standard_library.rdoc.diff +0 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax.rdoc.diff +0 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/assignment.rdoc.diff +160 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/calling_methods.rdoc.diff +130 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/control_expressions.rdoc.diff +254 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/exceptions.rdoc.diff +0 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/literals.rdoc.diff +54 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/methods.rdoc.diff +157 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/miscellaneous.rdoc.diff +91 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/modules_and_classes.rdoc.diff +161 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/precedence.rdoc.diff +8 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/doc/syntax/refinements.rdoc.diff +146 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/encoding.c.diff +276 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/enum.c.diff +281 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/enumerator.c.diff +479 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/error.c.diff +143 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/eval.c.diff +47 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/eval_jump.c.diff +23 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/file.c.diff +752 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/gc.c.diff +195 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/hash.c.diff +84 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/iseq.c.diff +354 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/load.c.diff +53 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/marshal.c.diff +98 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/math.c.diff +110 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/numeric.c.diff +103 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/object.c.diff +295 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/pack.c.diff +18 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/parse.y.diff +23 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/proc.c.diff +155 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/random.c.diff +126 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/range.c.diff +49 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/rational.c.diff +312 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/re.c.diff +207 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/ruby.c.diff +21 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/signal.c.diff +67 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/sprintf.c.diff +29 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/string.c.diff +73 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/struct.c.diff +20 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/time.c.diff +691 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/transcode.c.diff +435 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/variable.c.diff +62 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_backtrace.c.diff +164 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_eval.c.diff +99 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_method.c.diff +17 -0
- data/examples/ruby-2.0.0-p0/install/core/diffs/vm_trace.c.diff +393 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/.rdx +6 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/README +19 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/Rakefile +53 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/abbrev.rb.diff +77 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/base64.rb.diff +42 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/benchmark.rb.diff +144 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/cmath.rb.diff +52 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/forwardable.rb.diff +150 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/mathn.rb.diff +58 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/matrix.rb.diff +657 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/observer.rb.diff +31 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/optparse.rb.diff +147 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/ostruct.rb.diff +78 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/prime.rb.diff +52 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/pstore.rb.diff +110 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/scanf.rb.diff +100 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/securerandom.rb.diff +144 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/set.rb.diff +637 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/shellwords.rb.diff +66 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/singleton.rb.diff +37 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/tempfile.rb.diff +104 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/thread.rb.diff +38 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/time.rb.diff +140 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/tmpdir.rb.diff +52 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/uri.rb.diff +39 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/uri/common.rb.diff +237 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/weakref.rb.diff +36 -0
- data/examples/ruby-2.0.0-p0/install/stdlib/diffs/lib/yaml/store.rb.diff +27 -0
- data/examples/ruby-2.0.0-p0/rakefile +165 -0
- data/lib/rdx.rb +331 -0
- data/lib/rdx/assertions.rb +484 -0
- data/lib/rdx/binding.rb +151 -0
- data/lib/rdx/code_object.rb +598 -0
- data/lib/rdx/comment.rb +338 -0
- data/lib/rdx/convention.rb +1174 -0
- data/lib/rdx/directive.rb +1432 -0
- data/lib/rdx/example.rb +679 -0
- data/lib/rdx/generator.rb +112 -0
- data/lib/rdx/generator/rdoc.rb +1006 -0
- data/lib/rdx/options.rb +359 -0
- data/lib/rdx/plain_text.rb +65 -0
- data/lib/rdx/reporter.rb +421 -0
- data/lib/rdx/ruby_lex.rb +324 -0
- data/lib/rdx/runner.rb +309 -0
- data/lib/rdx/source_file.rb +94 -0
- data/lib/rdx/specification.rb +194 -0
- data/lib/rdx/statement.rb +248 -0
- data/lib/rdx/store.rb +119 -0
- data/lib/rdx/task.rb +361 -0
- data/lib/rdx/text.rb +688 -0
- data/lib/rdx/version.rb +15 -0
- data/rakefile +64 -0
- metadata +203 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
|
2
|
+
module RDX
|
3
|
+
|
4
|
+
#
|
5
|
+
# RDX doesn't have its own parser, formatting rules and templates for generating
|
6
|
+
# documentation from the source files. Instead, it does rely on tools already existing.
|
7
|
+
# Such tools are wrapped by subclasses of RDX::Generator, in order to provide a common
|
8
|
+
# interface to the outside world. Those need very likely to be patched
|
9
|
+
# (allowing to interact with RDX and work properly).
|
10
|
+
#
|
11
|
+
# Currently only RDoc is supported (see Generator::RDoc),
|
12
|
+
# but YARD will probably be the next one on the list.
|
13
|
+
#
|
14
|
+
class Generator
|
15
|
+
|
16
|
+
# :stopdoc:
|
17
|
+
|
18
|
+
@generators = {}
|
19
|
+
class << self
|
20
|
+
attr_reader :generators
|
21
|
+
end
|
22
|
+
def self.generator_name
|
23
|
+
name.split('::').last.downcase
|
24
|
+
end
|
25
|
+
def self.inherited child_class
|
26
|
+
Generator.generators[child_class.generator_name] = child_class
|
27
|
+
end
|
28
|
+
def self.[] name
|
29
|
+
name = name.downcase
|
30
|
+
require "rdx/generator/#{name}"
|
31
|
+
Generator.generators[name]
|
32
|
+
end
|
33
|
+
|
34
|
+
@current = nil
|
35
|
+
class << self
|
36
|
+
attr_accessor :current
|
37
|
+
end
|
38
|
+
|
39
|
+
def name
|
40
|
+
self.class.generator_name
|
41
|
+
end
|
42
|
+
|
43
|
+
attr_reader :options
|
44
|
+
|
45
|
+
def initialize
|
46
|
+
@options = {}
|
47
|
+
end
|
48
|
+
|
49
|
+
# :startdoc:
|
50
|
+
|
51
|
+
# Additional options for the generator.
|
52
|
+
def custom_options
|
53
|
+
[]
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Merges the given _argv_ and _files_ (along with #custom_options)
|
58
|
+
# into a ingle +Array+ of options.
|
59
|
+
#
|
60
|
+
def merge_argv_and_files argv, files
|
61
|
+
custom_options + argv + ['--'] + files
|
62
|
+
end
|
63
|
+
|
64
|
+
# Sets up <tt>Generator.current</tt>, and relies to #document.
|
65
|
+
def generate argv=[], files=[]
|
66
|
+
Generator.current = self
|
67
|
+
argv = merge_argv_and_files argv, files
|
68
|
+
document argv
|
69
|
+
ensure
|
70
|
+
Generator.current = nil
|
71
|
+
end
|
72
|
+
|
73
|
+
#
|
74
|
+
# The generator should implement this method in order to produce documentation output from _argv_
|
75
|
+
# (command line options).
|
76
|
+
#
|
77
|
+
def document argv=[]
|
78
|
+
end
|
79
|
+
|
80
|
+
#
|
81
|
+
# The generator should implement this method in order to recognize the directives.
|
82
|
+
# The result should be a +Regexp+ with two capturing groups: the directive name and
|
83
|
+
# its parameter.
|
84
|
+
#
|
85
|
+
def directive_rgxp
|
86
|
+
end
|
87
|
+
|
88
|
+
#
|
89
|
+
# The generator should implement this method in order to recognize the example sections
|
90
|
+
# from _text_.
|
91
|
+
# The result should be an +Array+ <tt>[ [text,line_no],... ]</tt>
|
92
|
+
#
|
93
|
+
def recognize_examples text
|
94
|
+
vbs = ::RDoc::Markup::Parser.get_verbatims(text)
|
95
|
+
vbs.map{ |vb| [vb.text,vb.line_no] }
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# The generator should implement this method in order to customize the template
|
100
|
+
# with the RDX signature.
|
101
|
+
#
|
102
|
+
def customize_template template_string
|
103
|
+
end
|
104
|
+
|
105
|
+
def RDX.customize_template template # :nodoc:
|
106
|
+
return template unless passed?
|
107
|
+
generator.customize_template template
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,1006 @@
|
|
1
|
+
|
2
|
+
require 'rdoc'
|
3
|
+
|
4
|
+
#
|
5
|
+
# :rdx: off
|
6
|
+
#
|
7
|
+
# This patch handles specific issues and comunication of RDoc with RDX, allowing it to work properly.
|
8
|
+
# There are a few important thing to notify.
|
9
|
+
#
|
10
|
+
# == Private RDX sections
|
11
|
+
#
|
12
|
+
# RDoc already allows private comments (both for C and Ruby files):
|
13
|
+
# sections between <tt>--</tt> and <tt>++</tt> (at the beginning of the line)
|
14
|
+
# are removed from documentation.
|
15
|
+
#
|
16
|
+
# If a line of comment begins with <tt>-- rdx</tt> that section is
|
17
|
+
# removed from documentation, but kept for RDX processing:
|
18
|
+
# in this way we can embed additional code, for example to hide
|
19
|
+
# additional details or to do some sort of clean-up.
|
20
|
+
#
|
21
|
+
# An example (from <tt>numeric.c</tt>):
|
22
|
+
#
|
23
|
+
# /*
|
24
|
+
# * [...]
|
25
|
+
# *-- rdx
|
26
|
+
# * It's clear from the examples that x and y are generical...
|
27
|
+
# * x = (-1)**rand(2) * (1+rand(10)*1.5)
|
28
|
+
# * y = (-1)**rand(2) * (1+rand(10)*1.5)
|
29
|
+
# *++
|
30
|
+
# * The <code>modulo</code> is defined as:
|
31
|
+
# * x.modulo(y) #=> x-y*(x/y).floor
|
32
|
+
# * [...]
|
33
|
+
# */
|
34
|
+
# static VALUE
|
35
|
+
# num_modulo(VALUE x, VALUE y)
|
36
|
+
#
|
37
|
+
# == Directives
|
38
|
+
#--
|
39
|
+
# TODO: Probably move some documentation to +Generator+.
|
40
|
+
#++
|
41
|
+
#
|
42
|
+
# RDoc directives are keywords surrounded by ":" characters,
|
43
|
+
# and what follows is its parameter:
|
44
|
+
#
|
45
|
+
# \:rdoc_directive: rdoc_parameter
|
46
|
+
#
|
47
|
+
# To insert a directive for RDX first we have to tell this to RDoc using +rdx+
|
48
|
+
# as the _rdoc_directive_.
|
49
|
+
# Then the _rdoc_parameter_ is parsed by RDX (specifically by RDX::Directive.split)
|
50
|
+
# and split into an RDX directive name and its parameter.
|
51
|
+
#
|
52
|
+
# Indeed the whole sequence in a comment looks like this:
|
53
|
+
#
|
54
|
+
# \:rdx: rdx_directive_name rdx_directive_parameter
|
55
|
+
#
|
56
|
+
# For example:
|
57
|
+
#
|
58
|
+
# # Sorts a collection in descending order.
|
59
|
+
# # :rdx: skip write an example
|
60
|
+
# def reverse_sort enum
|
61
|
+
# enum.sort.reverse
|
62
|
+
# end
|
63
|
+
#
|
64
|
+
# Here the RDX's directive name is +skip+ (which corresponds to RDX::Directive::skip)
|
65
|
+
# and its parameter is the +String+ <tt>"write an example"</tt>.
|
66
|
+
#
|
67
|
+
# To known the available directives in RDX and the parameter they support,
|
68
|
+
# consult the RDX::Directive class.
|
69
|
+
#
|
70
|
+
# This patch also removes from RDoc the <tt>:rdx:</tt> directive,
|
71
|
+
# so that they won't be shown in the documentation output
|
72
|
+
# (this happens before examples are recognized, so the indentation of directives
|
73
|
+
# has no effect on the rest of comment).
|
74
|
+
#
|
75
|
+
# == Visibility of comments
|
76
|
+
#
|
77
|
+
# While the generator scans the source files some comments are kept for the documentation
|
78
|
+
# output, others are discarded, others may even be not seen.
|
79
|
+
#
|
80
|
+
# The last type ones (_missed_ comments) don't even sprung into existence.
|
81
|
+
# Conversely the other two types can generate RDX::Comment objects.
|
82
|
+
# What discriminates them is the +documenting+ attribute:
|
83
|
+
# for this reason we refer to them with _documenting_ and _non_documenting_ comments.
|
84
|
+
#
|
85
|
+
# Since RDoc can fully tokenize Ruby files but not C ones
|
86
|
+
# it can see all Ruby comments but only "useful" C comments are recognized.
|
87
|
+
# This means that _missed_ C comments exist, while Ruby ones do not.
|
88
|
+
#
|
89
|
+
# A _non_documenting_ comment may generate warnings -
|
90
|
+
# for example if a convention is recognized inside it:
|
91
|
+
#
|
92
|
+
# # Documenting comment
|
93
|
+
# # return_one #=> 1
|
94
|
+
# def return_one
|
95
|
+
# 1
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# # :stopdoc:
|
99
|
+
#
|
100
|
+
# # ... many lines of code ...
|
101
|
+
#
|
102
|
+
# # Non-documenting comment
|
103
|
+
# # return_two #=> 2
|
104
|
+
# def return_two
|
105
|
+
# 2
|
106
|
+
# end
|
107
|
+
#
|
108
|
+
# A _missed_ one surely cannot, so be careful.
|
109
|
+
#
|
110
|
+
module RDoc; end
|
111
|
+
|
112
|
+
module RDoc # :nodoc: all
|
113
|
+
|
114
|
+
class << Encoding # :nodoc: all
|
115
|
+
|
116
|
+
alias set_encoding_consume_nl set_encoding
|
117
|
+
private :set_encoding_consume_nl
|
118
|
+
# EDIT: Don't consume the first newline character when changing the encoding.
|
119
|
+
def set_encoding string
|
120
|
+
orig_size = string.size
|
121
|
+
result = set_encoding_consume_nl(string)
|
122
|
+
return result if string.size == orig_size # No encode changing
|
123
|
+
string.sub!(/\A(#!.*\n)?/,"\\1\n") # Add the removed newline after the shebang line (if present)
|
124
|
+
result
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
module Text
|
130
|
+
|
131
|
+
require 'rdx/text'
|
132
|
+
|
133
|
+
# Remove stars only if it's a full C-commment: containing it isn't enough.
|
134
|
+
define_method :strip_stars, &RDX::Text.method(:strip_stars)
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
class Comment
|
139
|
+
|
140
|
+
# The associated comment in RDX (or +nil+ if there isn't).
|
141
|
+
attr_reader :rdx_comment
|
142
|
+
|
143
|
+
def rdx_line_no= line_no
|
144
|
+
return unless rdx_comment
|
145
|
+
rdx_comment.line_no = line_no
|
146
|
+
end
|
147
|
+
|
148
|
+
def rdx_file_name= file_name
|
149
|
+
return unless rdx_comment
|
150
|
+
rdx_comment.file_name = file_name
|
151
|
+
end
|
152
|
+
|
153
|
+
def rdx_mark_doc(parent_comment=nil)
|
154
|
+
return unless rdx_comment
|
155
|
+
rdx_comment.documenting = true
|
156
|
+
return if parent_comment.nil?
|
157
|
+
rdx_comment.enclosing_comment = parent_comment.rdx_comment
|
158
|
+
end
|
159
|
+
|
160
|
+
def absolute_location
|
161
|
+
root = RDoc.current.options.root
|
162
|
+
File.expand_path(location.absolute_name,root.dirname)
|
163
|
+
end
|
164
|
+
|
165
|
+
alias initialize_wo_rdx initialize
|
166
|
+
private :initialize_wo_rdx
|
167
|
+
# Add logging for line number and RDX lines
|
168
|
+
def initialize(*args,&blk)
|
169
|
+
result = initialize_wo_rdx(*args,&blk)
|
170
|
+
@private_removed = false
|
171
|
+
if RDX.active? && location && !text.empty?
|
172
|
+
@rdx_comment = RDX::Comment.new(text.dup,absolute_location,nil)
|
173
|
+
end
|
174
|
+
remove_rdx_directives
|
175
|
+
result
|
176
|
+
end
|
177
|
+
|
178
|
+
def remove_rdx_directives
|
179
|
+
text.gsub! %r%^
|
180
|
+
(
|
181
|
+
[^\S\n]*
|
182
|
+
(?: [#*] [^\S\n]* )?
|
183
|
+
)
|
184
|
+
:rdx: .*
|
185
|
+
%x, '\1'
|
186
|
+
end
|
187
|
+
private :remove_rdx_directives
|
188
|
+
|
189
|
+
#
|
190
|
+
# Remove private sections keeping newlines characters from +rdx_comment+.
|
191
|
+
#--
|
192
|
+
# Method adapted from RDoc::Comment#remove_private
|
193
|
+
#
|
194
|
+
def rdx_remove_private
|
195
|
+
return unless rdx_comment
|
196
|
+
|
197
|
+
# From RDoc:
|
198
|
+
# # Workaround for gsub encoding for Ruby 1.9.2 and earlier
|
199
|
+
# empty = ''
|
200
|
+
# empty.force_encoding @rdx_text.encoding if Object.const_defined? :Encoding
|
201
|
+
#
|
202
|
+
# @text = @text.gsub(%r%^\s*([#*]?)--.*?^\s*(\1)\+\+\n?%m, empty)
|
203
|
+
# @text = @text.sub(%r%^\s*[#*]?--.*%m, '')
|
204
|
+
# return self
|
205
|
+
|
206
|
+
text = rdx_comment.text
|
207
|
+
|
208
|
+
text.gsub! %r%
|
209
|
+
^ ( (?:[^\S\n]*[#*])? ) # \1: delimiter
|
210
|
+
-- (.* \n) # \2: private header
|
211
|
+
( (?> .* \n )*? ) # \3: body
|
212
|
+
\1 \+\+ \n?
|
213
|
+
%x do |txt|
|
214
|
+
delimiter,header,body = Regexp.last_match.captures
|
215
|
+
if header[/^\s*rdx\s/i]
|
216
|
+
"#{delimiter}\n" + body + "#{delimiter}\n"
|
217
|
+
else
|
218
|
+
RDX::Text.collect_newlines(txt,delimiter)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
text.sub! %r%
|
223
|
+
^ ( (?:[^\S\n]*[#*])? ) # captures as above
|
224
|
+
-- (.* \n)
|
225
|
+
( (?m:.*) )
|
226
|
+
%x do |txt|
|
227
|
+
delimiter,header,body = Regexp.last_match.captures
|
228
|
+
if header[/^\s*rdx\s/i]
|
229
|
+
"#{delimiter}\n" + body
|
230
|
+
else
|
231
|
+
RDX::Text.collect_newlines(txt,delimiter)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
return self
|
235
|
+
end
|
236
|
+
|
237
|
+
alias remove_private_wo_rdx remove_private
|
238
|
+
private :rdx_remove_private, :remove_private_wo_rdx
|
239
|
+
def remove_private(*args,&blk)
|
240
|
+
unless @private_removed
|
241
|
+
remove_private_wo_rdx(*args,&blk)
|
242
|
+
rdx_remove_private
|
243
|
+
@private_removed = true
|
244
|
+
end
|
245
|
+
return self
|
246
|
+
end
|
247
|
+
|
248
|
+
def rdx_normalize
|
249
|
+
return unless rdx_comment
|
250
|
+
rdx_comment.normalize
|
251
|
+
end
|
252
|
+
alias normalize_wo_rdx normalize
|
253
|
+
private :rdx_normalize, :normalize_wo_rdx
|
254
|
+
#
|
255
|
+
# INSERTION: Normalize also the corresponding comment in RDX.
|
256
|
+
#
|
257
|
+
def normalize(*args,&blk)
|
258
|
+
remove_private # we want to be sure that it occurs for every comment that has to be normalized
|
259
|
+
r = normalize_wo_rdx(*args,&blk)
|
260
|
+
rdx_normalize
|
261
|
+
r
|
262
|
+
end
|
263
|
+
|
264
|
+
#
|
265
|
+
# Extracts 'call-seq' directive keeping newlines characters from +rdx_comment+.
|
266
|
+
#--
|
267
|
+
# Method adapted from RDoc::Comment#extract_call_seq
|
268
|
+
#
|
269
|
+
def rdx_extract_call_seq
|
270
|
+
return unless rdx_comment
|
271
|
+
text = rdx_comment.text
|
272
|
+
# we must handle situations like the above followed by an unindented first
|
273
|
+
# comment. The difficulty is to make sure not to match lines starting
|
274
|
+
# with ARGF at the same indent, but that are after the first description
|
275
|
+
# paragraph.
|
276
|
+
if text =~ /^\s*:?call-seq:(.*?(?:\S).*?)^\s*$/m then
|
277
|
+
all_start, all_stop = $~.offset(0)
|
278
|
+
seq_start, seq_stop = $~.offset(1)
|
279
|
+
|
280
|
+
# we get the following lines that start with the leading word at the
|
281
|
+
# same indent, even if they have blank lines before
|
282
|
+
if $1 =~ /(^\s*\n)+^(\s*\w+)/m then
|
283
|
+
leading = $2 # ' * ARGF' in the example above
|
284
|
+
re = %r%
|
285
|
+
\A(
|
286
|
+
(^\s*\n)+
|
287
|
+
(^#{Regexp.escape leading}.*?\n)+
|
288
|
+
)+
|
289
|
+
^\s*$
|
290
|
+
%xm
|
291
|
+
|
292
|
+
if text[seq_stop..-1] =~ re then
|
293
|
+
all_stop = seq_stop + $~.offset(0).last
|
294
|
+
seq_stop = seq_stop + $~.offset(1).last
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
# seq = text[seq_start..seq_stop]
|
299
|
+
# seq.gsub!(/^\s*(\S|\n)/m, '\1')
|
300
|
+
# @text.slice! all_start...all_stop
|
301
|
+
text[all_start...all_stop] = RDX::Text.collect_newlines(text[all_start...all_stop])
|
302
|
+
# method.call_seq = seq.chomp
|
303
|
+
|
304
|
+
# elsif @text.sub!(/^\s*:?call-seq:(.*?)(^\s*$|\z)/m, '') then
|
305
|
+
elsif text.sub!(/^\s*:?call-seq:(.*?)(^\s*$|\z)/m){ |s| RDX::Text.collect_newlines(s) } then
|
306
|
+
# seq = $1
|
307
|
+
# seq.gsub!(/^\s*/, '')
|
308
|
+
# method.call_seq = seq
|
309
|
+
|
310
|
+
# Single line directives has alredy been removed
|
311
|
+
# #elsif @text.sub!(/\A\/\*\s*call-seq:(.*?)\*\/\Z/, '') then
|
312
|
+
# # method.call_seq = $1.strip
|
313
|
+
|
314
|
+
end
|
315
|
+
|
316
|
+
# The :call-seq: isn't part of the plain text, which is next to the left margin
|
317
|
+
text.replace RDX::Text.flush_left(text)
|
318
|
+
|
319
|
+
# method
|
320
|
+
self
|
321
|
+
end
|
322
|
+
alias extract_call_seq_wo_rdx extract_call_seq
|
323
|
+
private :rdx_extract_call_seq, :extract_call_seq_wo_rdx
|
324
|
+
#
|
325
|
+
# Remove also +call_seq+ information from RDX's comment.
|
326
|
+
#
|
327
|
+
def extract_call_seq(*args,&blk)
|
328
|
+
r = extract_call_seq_wo_rdx(*args,&blk)
|
329
|
+
rdx_extract_call_seq
|
330
|
+
r
|
331
|
+
end
|
332
|
+
|
333
|
+
end
|
334
|
+
|
335
|
+
class Store
|
336
|
+
|
337
|
+
attr_reader :rdx_code_objects
|
338
|
+
|
339
|
+
alias initialize_wo_rdx initialize
|
340
|
+
private :initialize_wo_rdx
|
341
|
+
def initialize(*args,&blk)
|
342
|
+
@rdx_code_objects = []
|
343
|
+
initialize_wo_rdx(*args,&blk)
|
344
|
+
end
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
class CodeObject
|
349
|
+
|
350
|
+
alias set_store_wo_rdx store=
|
351
|
+
private :set_store_wo_rdx
|
352
|
+
#
|
353
|
+
# This method is called for those and only objects whose will appear in documentation,
|
354
|
+
# so we can hook into and register these objects for RDX
|
355
|
+
#
|
356
|
+
def store=(*args,&blk)
|
357
|
+
rs = set_store_wo_rdx(*args,&blk)
|
358
|
+
store.rdx_code_objects << self
|
359
|
+
rs
|
360
|
+
end
|
361
|
+
|
362
|
+
def rdx_parent
|
363
|
+
parent if parent.is_a?(ClassModule) # Discard top-level (file) comments
|
364
|
+
end
|
365
|
+
|
366
|
+
#
|
367
|
+
# Shorthand used by rdx
|
368
|
+
#
|
369
|
+
def rdx_comments
|
370
|
+
result = if respond_to?(:comment_location)
|
371
|
+
comment_location.map(&:first)
|
372
|
+
else
|
373
|
+
[comment]
|
374
|
+
end
|
375
|
+
result.grep(Comment) # remove strings (empty)
|
376
|
+
end
|
377
|
+
|
378
|
+
def rdx_mark_doc
|
379
|
+
rdx_comments.each do |comment|
|
380
|
+
location = comment.location
|
381
|
+
parent_comments = rdx_parent ? rdx_parent.rdx_comments : []
|
382
|
+
parent_comment = parent_comments.find do |cmt|
|
383
|
+
cmt.location == location
|
384
|
+
end
|
385
|
+
comment.rdx_mark_doc(parent_comment)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
end
|
390
|
+
|
391
|
+
class Parser::Simple
|
392
|
+
|
393
|
+
PRV_CMT_RDX_HEADER = /[^\S\n]* rdx [^\S\n]*/i
|
394
|
+
|
395
|
+
alias scan_wo_rdx scan
|
396
|
+
private :scan_wo_rdx
|
397
|
+
def scan(*args,&blk)
|
398
|
+
result = scan_wo_rdx(*args,&blk)
|
399
|
+
# private sections removed through #remove_private_comment and #rdx_remove_private
|
400
|
+
@top_level.comment.instance_variable_set :@private_removed, true
|
401
|
+
rdx_process_comment @top_level.comment.rdx_comment
|
402
|
+
result
|
403
|
+
end
|
404
|
+
|
405
|
+
private
|
406
|
+
|
407
|
+
def remove_private_comment comment
|
408
|
+
# Workaround for gsub encoding for Ruby 1.9.2 and earlier
|
409
|
+
# empty = ''
|
410
|
+
# empty.force_encoding comment.encoding if Object.const_defined? :Encoding
|
411
|
+
comment = comment.gsub %r%^--#{PRV_CMT_RDX_HEADER}?\n.*?^\+\+\n?%mo do |txt|
|
412
|
+
RDX::Text.collect_newlines txt
|
413
|
+
end
|
414
|
+
comment.sub! %r%^--#{PRV_CMT_RDX_HEADER}?\n.*%mo do |txt|
|
415
|
+
RDX::Text.collect_newlines txt
|
416
|
+
end
|
417
|
+
comment
|
418
|
+
end
|
419
|
+
|
420
|
+
def rdx_process_comment comment
|
421
|
+
return unless comment
|
422
|
+
comment.line_no = 1
|
423
|
+
comment.documenting = true
|
424
|
+
comment.text = rdx_remove_private comment.text
|
425
|
+
end
|
426
|
+
|
427
|
+
def rdx_remove_private text
|
428
|
+
# # Workaround for gsub encoding for Ruby 1.9.2 and earlier
|
429
|
+
# empty = ''
|
430
|
+
# empty.force_encoding comment.encoding if Object.const_defined? :Encoding
|
431
|
+
# text = text.gsub(%r%^--\n.*?^\+\+\n?%im, empty)
|
432
|
+
# text.sub(%r%^--\n.*%m, empty)
|
433
|
+
|
434
|
+
text.gsub! %r%
|
435
|
+
^ ( (?:[^\S\n]*[#*])? ) # \1: comment delimiter
|
436
|
+
-- (#{PRV_CMT_RDX_HEADER})? \n # \2: rdx header - optional
|
437
|
+
( (?> .* \n )*? ) # \3: body
|
438
|
+
\1 \+\+ \n?
|
439
|
+
%xo do |txt|
|
440
|
+
delimiter,header,body = Regexp.last_match.captures
|
441
|
+
if header
|
442
|
+
"#{delimiter}\n" + body + "#{delimiter}\n"
|
443
|
+
else
|
444
|
+
RDX::Text.collect_newlines(txt,delimiter)
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
text.sub! %r%
|
449
|
+
^ ( (?:[^\S\n]*[#*])? ) # captures as above
|
450
|
+
-- (#{PRV_CMT_RDX_HEADER})? \n
|
451
|
+
( (?m:.*) )
|
452
|
+
%xo do |txt|
|
453
|
+
delimiter,header,body = Regexp.last_match.captures
|
454
|
+
if header
|
455
|
+
"#{delimiter}\n" + body
|
456
|
+
else
|
457
|
+
RDX::Text.collect_newlines(txt,delimiter)
|
458
|
+
end
|
459
|
+
end
|
460
|
+
|
461
|
+
text
|
462
|
+
end
|
463
|
+
|
464
|
+
end
|
465
|
+
|
466
|
+
#
|
467
|
+
# Some method has been rewritten in order to keep track and add line numbers for parsed comments.
|
468
|
+
#
|
469
|
+
class Parser::Ruby
|
470
|
+
|
471
|
+
alias get_tk_wo_line_no get_tk
|
472
|
+
private :get_tk_wo_line_no
|
473
|
+
#
|
474
|
+
# Keep the line number when a comment is found.
|
475
|
+
#--
|
476
|
+
# Hack RDoc::RubyLex#identify_comment instead (but allow multiline)
|
477
|
+
#
|
478
|
+
def get_tk
|
479
|
+
tk = get_tk_wo_line_no
|
480
|
+
return tk unless RDX.active?
|
481
|
+
@current_tk_comment_line_no ||= tk.line_no if tk.is_a?(TkCOMMENT)
|
482
|
+
tk
|
483
|
+
end
|
484
|
+
|
485
|
+
alias new_comment_wo_line_no new_comment
|
486
|
+
private :new_comment_wo_line_no
|
487
|
+
#
|
488
|
+
# Create the comment with the cached line number and clear cache.
|
489
|
+
#
|
490
|
+
def new_comment(*args,&blk)
|
491
|
+
cmt = new_comment_wo_line_no(*args,&blk)
|
492
|
+
if @current_tk_comment_line_no
|
493
|
+
cmt.rdx_line_no = @current_tk_comment_line_no
|
494
|
+
@current_tk_comment_line_no = nil
|
495
|
+
end
|
496
|
+
cmt
|
497
|
+
end
|
498
|
+
|
499
|
+
# Delete the cached line number for the first comment if it's an interpreter directive (#!)
|
500
|
+
# or an ERB directive (# -*-).
|
501
|
+
# In this case we are allowed to skip newlines, otherwise we cannot.
|
502
|
+
alias collect_first_comment_wo_rdx collect_first_comment
|
503
|
+
def collect_first_comment
|
504
|
+
return collect_first_comment_wo_rdx unless RDX.active?
|
505
|
+
skip_tkspace
|
506
|
+
comment = ''
|
507
|
+
comment.force_encoding @encoding if @encoding
|
508
|
+
first_line = true
|
509
|
+
|
510
|
+
tk = get_tk
|
511
|
+
|
512
|
+
while TkCOMMENT === tk
|
513
|
+
if first_line and tk.text =~ /\A#!/ then
|
514
|
+
@current_tk_comment_line_no = nil # <--- line added for RDX
|
515
|
+
skip_tkspace
|
516
|
+
tk = get_tk
|
517
|
+
elsif first_line and tk.text =~ /\A#\s*-\*-/ then
|
518
|
+
first_line = false
|
519
|
+
@current_tk_comment_line_no = nil # <--- line added for RDX
|
520
|
+
skip_tkspace
|
521
|
+
tk = get_tk
|
522
|
+
else
|
523
|
+
first_line = false
|
524
|
+
comment << tk.text << "\n"
|
525
|
+
tk = get_tk
|
526
|
+
|
527
|
+
if TkNL === tk then
|
528
|
+
skip_tkspace false
|
529
|
+
tk = get_tk
|
530
|
+
end
|
531
|
+
end
|
532
|
+
end
|
533
|
+
|
534
|
+
unget_tk tk
|
535
|
+
|
536
|
+
new_comment comment
|
537
|
+
end
|
538
|
+
|
539
|
+
end
|
540
|
+
|
541
|
+
#
|
542
|
+
class Parser::C
|
543
|
+
|
544
|
+
def find_rdx_comments
|
545
|
+
@content.scan %r%
|
546
|
+
^ \s* /\*
|
547
|
+
[^\S\n]* :rdx: .*?
|
548
|
+
\*/
|
549
|
+
%imx do |comment|
|
550
|
+
md = Regexp.last_match
|
551
|
+
cmt = Comment.new comment, @top_level
|
552
|
+
cmt.rdx_line_no = md.pre_match.count("\n") + 1
|
553
|
+
end
|
554
|
+
end
|
555
|
+
private :find_rdx_comments
|
556
|
+
|
557
|
+
alias initialize_wo_rdx initialize
|
558
|
+
private :initialize_wo_rdx
|
559
|
+
def initialize(*args,&blk)
|
560
|
+
r = initialize_wo_rdx(*args,&blk)
|
561
|
+
find_rdx_comments if RDX.active?
|
562
|
+
r
|
563
|
+
end
|
564
|
+
|
565
|
+
#
|
566
|
+
# Remove \#ifdefs but keep newlines
|
567
|
+
#
|
568
|
+
def handle_ifdefs_in(body)
|
569
|
+
body.gsub /^#ifdef HAVE_PROTOTYPES.*?#else.*?\n(.*?)#endif.*?\n/m do |text|
|
570
|
+
md = Regexp.last_match
|
571
|
+
pre_text = text[0 ... md.begin(1)-md.begin(0)]
|
572
|
+
post_text = text[md.end(1)-md.begin(0) .. -1]
|
573
|
+
pre = RDX::Text.collect_newlines( pre_text )
|
574
|
+
cnt = md[1]
|
575
|
+
post = RDX::Text.collect_newlines( post_text )
|
576
|
+
pre + cnt + post
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
def find_alias_comment class_name, new_name, old_name
|
581
|
+
content =~ %r%((?>/\*.*?\*/\s+))
|
582
|
+
rb_define_alias\(\s*#{Regexp.escape class_name}\s*,
|
583
|
+
\s*"#{Regexp.escape new_name}"\s*,
|
584
|
+
\s*"#{Regexp.escape old_name}"\s*\);%xm
|
585
|
+
|
586
|
+
cmt = Comment.new($1 || '', @top_level)
|
587
|
+
cmt.rdx_line_no = $`.count("\n") + 1 if $`
|
588
|
+
cmt
|
589
|
+
end
|
590
|
+
|
591
|
+
def find_attr_comment var_name, attr_name, read = nil, write = nil
|
592
|
+
attr_name = Regexp.escape attr_name
|
593
|
+
|
594
|
+
rw = if read and write then
|
595
|
+
/\s*#{read}\s*,\s*#{write}\s*/xm
|
596
|
+
else
|
597
|
+
/.*?/m
|
598
|
+
end
|
599
|
+
|
600
|
+
comment = if @content =~ %r%((?>/\*.*?\*/\s+))
|
601
|
+
rb_define_attr\((?:\s*#{var_name},)?\s*
|
602
|
+
"#{attr_name}"\s*,
|
603
|
+
#{rw}\)\s*;%xm then
|
604
|
+
$1
|
605
|
+
elsif @content =~ %r%((?>/\*.*?\*/\s+))
|
606
|
+
rb_attr\(\s*#{var_name}\s*,
|
607
|
+
\s*#{attr_name}\s*,
|
608
|
+
#{rw},.*?\)\s*;%xm then
|
609
|
+
$1
|
610
|
+
elsif @content =~ %r%Document-attr:\s#{attr_name}\s*?\n
|
611
|
+
((?>.*?\*/))%xm then
|
612
|
+
$1
|
613
|
+
else
|
614
|
+
''
|
615
|
+
end
|
616
|
+
|
617
|
+
cmt = Comment.new comment, @top_level
|
618
|
+
cmt.rdx_line_no = @content[0...$~.begin(1)].count("\n") + 1 unless comment.empty?
|
619
|
+
cmt
|
620
|
+
end
|
621
|
+
|
622
|
+
alias handle_method_wo_rdx handle_method
|
623
|
+
private :handle_method_wo_rdx
|
624
|
+
def handle_method(*args,&blk)
|
625
|
+
return handle_method_wo_rdx(*args,&blk) unless RDX.active?
|
626
|
+
result = comment = absolute_path = nil
|
627
|
+
RDX::Util.patch_singleton_method ::File, :read,
|
628
|
+
lambda{ |orig_method,file,*args,&blk|
|
629
|
+
f_result = orig_method.call(file,*args,&blk)
|
630
|
+
absolute_path = ::File.expand_path(file)
|
631
|
+
f_result
|
632
|
+
} do
|
633
|
+
RDX::Util.patch_singleton_method Comment, :new,
|
634
|
+
lambda{ |orig_method,*args,&blk|
|
635
|
+
comment = orig_method.call(*args,&blk)
|
636
|
+
} do
|
637
|
+
result = handle_method_wo_rdx(*args,&blk)
|
638
|
+
end
|
639
|
+
end
|
640
|
+
if comment && absolute_path
|
641
|
+
comment.rdx_file_name = absolute_path
|
642
|
+
end
|
643
|
+
result
|
644
|
+
end
|
645
|
+
|
646
|
+
def find_body class_name, meth_name, meth_obj, file_content, quiet = false
|
647
|
+
case file_content
|
648
|
+
when %r%((?>/\*.*?\*/\s*)?)
|
649
|
+
((?:(?:static|SWIGINTERN)\s+)?
|
650
|
+
(?:intern\s+)?VALUE\s+#{meth_name}
|
651
|
+
\s*(\([^)]*\))([^;]|$))%xm then
|
652
|
+
comment = Comment.new $1, @top_level
|
653
|
+
comment.rdx_line_no = $`.count("\n") + 1
|
654
|
+
body = $2
|
655
|
+
offset, = $~.offset(2)
|
656
|
+
|
657
|
+
comment.remove_private if comment
|
658
|
+
|
659
|
+
# try to find the whole body
|
660
|
+
body = $& if /#{Regexp.escape body}[^(]*?\{.*?^\}/m =~ file_content
|
661
|
+
|
662
|
+
# The comment block may have been overridden with a 'Document-method'
|
663
|
+
# block. This happens in the interpreter when multiple methods are
|
664
|
+
# vectored through to the same C method but those methods are logically
|
665
|
+
# distinct (for example Kernel.hash and Kernel.object_id share the same
|
666
|
+
# implementation
|
667
|
+
|
668
|
+
override_comment = find_override_comment class_name, meth_obj
|
669
|
+
comment = override_comment if override_comment
|
670
|
+
|
671
|
+
comment.normalize
|
672
|
+
find_modifiers comment, meth_obj if comment
|
673
|
+
|
674
|
+
#meth_obj.params = params
|
675
|
+
meth_obj.start_collecting_tokens
|
676
|
+
tk = RubyToken::Token.new nil, 1, 1
|
677
|
+
tk.set_text body
|
678
|
+
meth_obj.add_token tk
|
679
|
+
meth_obj.comment = comment
|
680
|
+
meth_obj.offset = offset
|
681
|
+
meth_obj.line = file_content[0, offset].count("\n") + 1
|
682
|
+
|
683
|
+
body
|
684
|
+
when %r%((?>/\*.*?\*/\s*))^\s*(\#\s*define\s+#{meth_name}\s+(\w+))%m then
|
685
|
+
comment = Comment.new $1, @top_level
|
686
|
+
comment.rdx_line_no = $`.count("\n") + 1
|
687
|
+
body = $2
|
688
|
+
offset = $~.offset(2).first
|
689
|
+
|
690
|
+
find_body class_name, $3, meth_obj, file_content, true
|
691
|
+
|
692
|
+
comment.normalize
|
693
|
+
find_modifiers comment, meth_obj
|
694
|
+
|
695
|
+
meth_obj.start_collecting_tokens
|
696
|
+
tk = RubyToken::Token.new nil, 1, 1
|
697
|
+
tk.set_text body
|
698
|
+
meth_obj.add_token tk
|
699
|
+
meth_obj.comment = comment
|
700
|
+
meth_obj.offset = offset
|
701
|
+
meth_obj.line = file_content[0, offset].count("\n") + 1
|
702
|
+
|
703
|
+
body
|
704
|
+
when %r%^\s*\#\s*define\s+#{meth_name}\s+(\w+)%m then
|
705
|
+
# with no comment we hope the aliased definition has it and use it's
|
706
|
+
# definition
|
707
|
+
|
708
|
+
body = find_body(class_name, $1, meth_obj, file_content, true)
|
709
|
+
|
710
|
+
return body if body
|
711
|
+
|
712
|
+
@options.warn "No definition for #{meth_name}"
|
713
|
+
false
|
714
|
+
else # No body, but might still have an override comment
|
715
|
+
comment = find_override_comment class_name, meth_obj
|
716
|
+
|
717
|
+
if comment then
|
718
|
+
comment.normalize
|
719
|
+
find_modifiers comment, meth_obj
|
720
|
+
meth_obj.comment = comment
|
721
|
+
|
722
|
+
''
|
723
|
+
else
|
724
|
+
@options.warn "No definition for #{meth_name}"
|
725
|
+
false
|
726
|
+
end
|
727
|
+
end
|
728
|
+
end
|
729
|
+
|
730
|
+
#
|
731
|
+
# Add line number tracking
|
732
|
+
#
|
733
|
+
def find_class_comment class_name, class_mod
|
734
|
+
comment = nil
|
735
|
+
|
736
|
+
if @content =~ %r%
|
737
|
+
((?>/\*.*?\*/\s+))
|
738
|
+
(static\s+)?
|
739
|
+
void\s+
|
740
|
+
Init_#{class_name}\s*(?:_\(\s*)?\(\s*(?:void\s*)?\)%xmi then
|
741
|
+
line_no = $`.count("\n") + 1
|
742
|
+
comment = $1.sub(%r%Document-(?:class|module):\s+#{class_name}%, '')
|
743
|
+
elsif @content =~ %r%Document-(?:class|module):\s+#{class_name}\s*?
|
744
|
+
(?:<\s+[:,\w]+)?\n((?>.*?\*/))%xm then
|
745
|
+
line_no = @content[0...$~.begin(1)].count("\n")
|
746
|
+
comment = "/*\n#{$1}"
|
747
|
+
elsif @content =~ %r%.*((?>/\*.*?\*/\s+))
|
748
|
+
([\w\.\s]+\s* = \s+)?rb_define_(class|module).*?"(#{class_name})"%xm then
|
749
|
+
line_no = @content[0...$~.begin(1)].count("\n") + 1
|
750
|
+
comment = $1
|
751
|
+
elsif @content =~ %r%.*((?>/\*.*?\*/\s+))
|
752
|
+
([\w\.\s]+\s* = \s+)?rb_define_(class|module)_under.*?"(#{class_name.split('::').last})"%xm then
|
753
|
+
line_no = @content[0...$~.begin(1)].count("\n") + 1
|
754
|
+
comment = $1
|
755
|
+
else
|
756
|
+
comment = ''
|
757
|
+
end
|
758
|
+
|
759
|
+
comment = Comment.new comment, @top_level
|
760
|
+
comment.rdx_line_no = line_no
|
761
|
+
comment.normalize
|
762
|
+
|
763
|
+
look_for_directives_in class_mod, comment
|
764
|
+
|
765
|
+
class_mod.add_comment comment, @top_level
|
766
|
+
end
|
767
|
+
|
768
|
+
def find_const_comment(type, const_name, class_name = nil)
|
769
|
+
comment = if @content =~ %r%^\s*((?>/\*.*?\*/))\s+
|
770
|
+
rb_define_#{type}\((?:\s*(\w+),)?\s*
|
771
|
+
"#{const_name}"\s*,
|
772
|
+
.*?\)\s*;%xmi then
|
773
|
+
line_no = @content[0...$~.begin(1)].count("\n") + 1
|
774
|
+
$1
|
775
|
+
elsif class_name and
|
776
|
+
@content =~ %r%Document-(?:const|global|variable):\s
|
777
|
+
#{class_name}::#{const_name}
|
778
|
+
\s*?\n((?>.*?\*/))%xm then
|
779
|
+
line_no = @content[0...$~.begin(1)].count("\n")
|
780
|
+
"/*\n#{$1}"
|
781
|
+
elsif @content =~ %r%Document-(?:const|global|variable):
|
782
|
+
\s#{const_name}
|
783
|
+
\s*?\n((?>.*?\*/))%xm then
|
784
|
+
line_no = @content[0...$~.begin(1)].count("\n")
|
785
|
+
"/*\n#{$1}"
|
786
|
+
else
|
787
|
+
''
|
788
|
+
end
|
789
|
+
|
790
|
+
cmt = Comment.new comment, @top_level
|
791
|
+
cmt.rdx_line_no = line_no
|
792
|
+
cmt
|
793
|
+
end
|
794
|
+
|
795
|
+
def find_override_comment class_name, meth_obj
|
796
|
+
name = Regexp.escape meth_obj.name
|
797
|
+
prefix = Regexp.escape meth_obj.name_prefix
|
798
|
+
|
799
|
+
comment = if @content =~ %r%Document-method:
|
800
|
+
\s+#{class_name}#{prefix}#{name}
|
801
|
+
\s*?\n((?>.*?\*/))%xm then
|
802
|
+
"/*\n#{$1}"
|
803
|
+
elsif @content =~ %r%Document-method:
|
804
|
+
\s#{name}\s*?\n((?>.*?\*/))%xm then
|
805
|
+
"/*\n#{$1}"
|
806
|
+
end
|
807
|
+
|
808
|
+
return unless comment
|
809
|
+
line_no = @content[0...$~.begin(1)].count("\n")
|
810
|
+
|
811
|
+
comment.gsub!(%r%Document-method:\s+[\w:.#=!?]+%){ |s| RDX::Text.collect_newlines(s) } # <-- moved from RDoc::Text
|
812
|
+
|
813
|
+
cmt = Comment.new comment, @top_level
|
814
|
+
cmt.rdx_line_no = line_no
|
815
|
+
cmt
|
816
|
+
end
|
817
|
+
|
818
|
+
end
|
819
|
+
|
820
|
+
class Markup::Verbatim
|
821
|
+
alias normalize_wo_rdx normalize
|
822
|
+
private :normalize_wo_rdx
|
823
|
+
# Newlines in some cases doesn't have to be collapsed for reason explained in RDoc::Text.
|
824
|
+
# However this isn't the default behaviour
|
825
|
+
def normalize(*args,&blk)
|
826
|
+
return parts if RDX.active?
|
827
|
+
normalize_wo_rdx(*args,&blk)
|
828
|
+
end
|
829
|
+
|
830
|
+
# relative to the comment
|
831
|
+
attr_accessor :line_no
|
832
|
+
end
|
833
|
+
|
834
|
+
class Markup::Parser
|
835
|
+
alias build_verbatim_wo_line_no build_verbatim
|
836
|
+
private :build_verbatim_wo_line_no
|
837
|
+
# Add logging of line number to verbatim sections
|
838
|
+
def build_verbatim(*args,&blk)
|
839
|
+
line_no = @current_token[3] + 1
|
840
|
+
build_verbatim_wo_line_no(*args,&blk).tap{ |vb| vb.line_no = line_no }
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
class << Markup::Parser # :nodoc: all
|
845
|
+
#
|
846
|
+
# Parses the string _str_ and returns an array of RDoc::Markup::Verbatim, representing the
|
847
|
+
# verbatim sections contained in that string.
|
848
|
+
#
|
849
|
+
def get_verbatims str
|
850
|
+
flatten_parts(parse(str).parts).grep(Markup::Verbatim)
|
851
|
+
end
|
852
|
+
private
|
853
|
+
# Flattens recursively an array of parts into each part's components
|
854
|
+
def flatten_parts(ary)
|
855
|
+
result = []
|
856
|
+
ary.each do |elm|
|
857
|
+
case elm
|
858
|
+
when Markup::List
|
859
|
+
result.concat flatten_parts(elm.items)
|
860
|
+
when Markup::ListItem
|
861
|
+
result.concat flatten_parts(elm.parts)
|
862
|
+
else
|
863
|
+
result << elm
|
864
|
+
end
|
865
|
+
end
|
866
|
+
result
|
867
|
+
end
|
868
|
+
end
|
869
|
+
|
870
|
+
class Markup::PreProcess
|
871
|
+
|
872
|
+
alias include_file_wo_rdx include_file
|
873
|
+
private :include_file_wo_rdx
|
874
|
+
def include_file(*args,&blk)
|
875
|
+
return include_file_wo_rdx(*args,&blk) unless RDX.active?
|
876
|
+
absolute_path = nil
|
877
|
+
content = ''
|
878
|
+
RDX::Util.patch_singleton_method Encoding, :read_file,
|
879
|
+
lambda{ |orig_method,file,*args,&blk|
|
880
|
+
result = orig_method.call(file,*args,&blk)
|
881
|
+
absolute_path = File.expand_path(file)
|
882
|
+
content = result.dup
|
883
|
+
result
|
884
|
+
} do
|
885
|
+
result = include_file_wo_rdx(*args,&blk)
|
886
|
+
mark_for_rdx(absolute_path,content)
|
887
|
+
result
|
888
|
+
end
|
889
|
+
end
|
890
|
+
|
891
|
+
private
|
892
|
+
|
893
|
+
def mark_for_rdx absolute_path, content
|
894
|
+
# We want to use Comments' method without knowing anything about initialization, location, etc...
|
895
|
+
Comment.allocate.instance_eval do
|
896
|
+
# Hook in RDX::Comment#initialize
|
897
|
+
@rdx_comment = RDX::Comment.new(content,absolute_path,1)
|
898
|
+
@rdx_comment.documenting = true
|
899
|
+
rdx_remove_private
|
900
|
+
@rdx_comment = nil
|
901
|
+
end
|
902
|
+
end
|
903
|
+
|
904
|
+
end
|
905
|
+
|
906
|
+
class Generator::Darkfish
|
907
|
+
|
908
|
+
alias assemble_template_wo_rdx assemble_template
|
909
|
+
private :assemble_template_wo_rdx
|
910
|
+
# Add RDX's signature
|
911
|
+
def assemble_template(*args,&blk)
|
912
|
+
RDX.customize_template assemble_template_wo_rdx(*args,&blk)
|
913
|
+
end
|
914
|
+
|
915
|
+
end
|
916
|
+
|
917
|
+
class RDoc
|
918
|
+
|
919
|
+
alias document_wo_current_hook document
|
920
|
+
def document(*args,&blk)
|
921
|
+
self.class.current = self
|
922
|
+
document_wo_current_hook(*args,&blk)
|
923
|
+
ensure
|
924
|
+
self.class.current = nil
|
925
|
+
end
|
926
|
+
|
927
|
+
alias parse_files_wo_rdx parse_files
|
928
|
+
private :parse_files_wo_rdx
|
929
|
+
# SIGNAL INSERTION: Signal RDX the parsing phase.
|
930
|
+
def parse_files(*args,&blk)
|
931
|
+
return parse_files_wo_rdx(*args,&blk) unless RDX.active?
|
932
|
+
RDX.signal_parsing do
|
933
|
+
result = parse_files_wo_rdx(*args,&blk)
|
934
|
+
store.rdx_code_objects.each(&:rdx_mark_doc).clear
|
935
|
+
result
|
936
|
+
end
|
937
|
+
end
|
938
|
+
|
939
|
+
alias parse_file_wo_rdx parse_file
|
940
|
+
private :parse_file_wo_rdx
|
941
|
+
# SIGNAL INSERTION: Signal RDX the succesful end of parsing a file.
|
942
|
+
def parse_file rel_fname
|
943
|
+
return parse_file_wo_rdx(rel_fname) unless RDX.active?
|
944
|
+
abs_fname = File.expand_path(rel_fname,options.root)
|
945
|
+
RDX.signal_start_parsing_file(abs_fname)
|
946
|
+
parse_file_wo_rdx(rel_fname).tap do |parseable|
|
947
|
+
RDX.signal_end_parsing_file(abs_fname,parseable)
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|
951
|
+
alias generate_wo_rdx generate
|
952
|
+
private :generate_wo_rdx
|
953
|
+
# SIGNAL INSERTION: Signal RDX the generating phase.
|
954
|
+
def generate(*args,&blk)
|
955
|
+
return generate_wo_rdx(*args,&blk) unless RDX.active?
|
956
|
+
RDX.signal_generating do
|
957
|
+
generate_wo_rdx(*args,&blk)
|
958
|
+
end
|
959
|
+
end
|
960
|
+
|
961
|
+
end
|
962
|
+
|
963
|
+
end
|
964
|
+
|
965
|
+
|
966
|
+
|
967
|
+
module RDX
|
968
|
+
|
969
|
+
class Generator
|
970
|
+
|
971
|
+
# Binds the documentation generator tool +RDoc+ to RDX
|
972
|
+
class RDoc < self
|
973
|
+
|
974
|
+
# :stopdoc:
|
975
|
+
|
976
|
+
def custom_options
|
977
|
+
['--force-update']
|
978
|
+
end
|
979
|
+
|
980
|
+
def document argv=[]
|
981
|
+
@rdoc = ::RDoc::RDoc.new
|
982
|
+
@rdoc.document argv
|
983
|
+
end
|
984
|
+
|
985
|
+
def directive_rgxp
|
986
|
+
/^
|
987
|
+
\s* :([-\w]+): \ * ( .* )
|
988
|
+
$/ox
|
989
|
+
end
|
990
|
+
|
991
|
+
def customize_template tmpl
|
992
|
+
# The \z exposed at the end of regexp ensure that optimizations will occurr.
|
993
|
+
# This can be very important with big html files
|
994
|
+
tmpl.sub /<\/footer>\s*\z/, '<p>' + RDX::SIGNATURE + ".\n\\&"
|
995
|
+
end
|
996
|
+
|
997
|
+
def recognize_examples text
|
998
|
+
vbs = ::RDoc::Markup::Parser.get_verbatims(text)
|
999
|
+
vbs.map{ |vb| [vb.text,vb.line_no] }
|
1000
|
+
end
|
1001
|
+
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
end
|
1005
|
+
|
1006
|
+
end
|