rdoc 7.2.0 → 8.1.0
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 +4 -4
- data/CONTRIBUTING.md +4 -7
- data/LICENSE.rdoc +4 -0
- data/README.md +43 -2
- data/RI.md +75 -75
- data/doc/markup_reference/markdown.md +104 -3
- data/exe/rdoc +2 -2
- data/lib/rdoc/code_object/alias.rb +70 -74
- data/lib/rdoc/code_object/any_method.rb +305 -298
- data/lib/rdoc/code_object/attr.rb +150 -143
- data/lib/rdoc/code_object/class_module.rb +801 -765
- data/lib/rdoc/code_object/constant.rb +178 -150
- data/lib/rdoc/code_object/context/section.rb +133 -160
- data/lib/rdoc/code_object/context.rb +925 -952
- data/lib/rdoc/code_object/extend.rb +7 -5
- data/lib/rdoc/code_object/include.rb +7 -5
- data/lib/rdoc/code_object/method_attr.rb +325 -324
- data/lib/rdoc/code_object/mixin.rb +97 -95
- data/lib/rdoc/code_object/normal_class.rb +77 -78
- data/lib/rdoc/code_object/normal_module.rb +61 -59
- data/lib/rdoc/code_object/require.rb +23 -39
- data/lib/rdoc/code_object/single_class.rb +21 -19
- data/lib/rdoc/code_object/top_level.rb +212 -213
- data/lib/rdoc/code_object.rb +305 -305
- data/lib/rdoc/comment.rb +274 -337
- data/lib/rdoc/cross_reference.rb +194 -212
- data/lib/rdoc/encoding.rb +105 -103
- data/lib/rdoc/erb_partial.rb +13 -11
- data/lib/rdoc/erbio.rb +29 -27
- data/lib/rdoc/generator/aliki.rb +165 -140
- data/lib/rdoc/generator/darkfish.rb +647 -631
- data/lib/rdoc/generator/json_index.rb +233 -229
- data/lib/rdoc/generator/markup.rb +165 -122
- data/lib/rdoc/generator/pot/message_extractor.rb +57 -51
- data/lib/rdoc/generator/pot/po.rb +52 -51
- data/lib/rdoc/generator/pot/po_entry.rb +138 -132
- data/lib/rdoc/generator/pot.rb +85 -81
- data/lib/rdoc/generator/ri.rb +23 -19
- data/lib/rdoc/generator/template/aliki/DESIGN.md +538 -0
- data/lib/rdoc/generator/template/aliki/_aside_toc.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_head.rhtml +11 -11
- data/lib/rdoc/generator/template/aliki/_header.rhtml +29 -44
- data/lib/rdoc/generator/template/aliki/_sidebar_extends.rhtml +8 -6
- data/lib/rdoc/generator/template/aliki/_sidebar_includes.rhtml +8 -6
- data/lib/rdoc/generator/template/aliki/_sidebar_installed.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_sidebar_pages.rhtml +2 -2
- data/lib/rdoc/generator/template/aliki/_sidebar_search.rhtml +4 -4
- data/lib/rdoc/generator/template/aliki/_sidebar_sections.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/_sidebar_toggle.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/class.rhtml +56 -46
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +538 -283
- data/lib/rdoc/generator/template/aliki/index.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/js/aliki.js +80 -102
- data/lib/rdoc/generator/template/aliki/page.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/servlet_not_found.rhtml +1 -1
- data/lib/rdoc/generator/template/aliki/servlet_root.rhtml +2 -2
- data/lib/rdoc/generator/template/darkfish/_footer.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_extends.rhtml +8 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_includes.rhtml +8 -6
- data/lib/rdoc/generator/template/darkfish/_sidebar_installed.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_pages.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_sections.rhtml +1 -1
- data/lib/rdoc/generator/template/darkfish/_sidebar_table_of_contents.rhtml +5 -5
- data/lib/rdoc/generator/template/darkfish/class.rhtml +18 -21
- data/lib/rdoc/generator/template/darkfish/css/rdoc.css +0 -1
- data/lib/rdoc/generator/template/darkfish/table_of_contents.rhtml +3 -3
- data/lib/rdoc/generator.rb +48 -46
- data/lib/rdoc/i18n/locale.rb +99 -95
- data/lib/rdoc/i18n/text.rb +109 -105
- data/lib/rdoc/i18n.rb +7 -5
- data/lib/rdoc/markdown/byte_runtime.rb +80 -0
- data/lib/rdoc/markdown.kpeg +30 -21
- data/lib/rdoc/markdown.rb +329 -151
- data/lib/rdoc/markup/block_quote.rb +12 -8
- data/lib/rdoc/markup/document.rb +127 -123
- data/lib/rdoc/markup/formatter.rb +215 -221
- data/lib/rdoc/markup/heading.rb +1 -4
- data/lib/rdoc/markup/include.rb +33 -29
- data/lib/rdoc/markup/indented_paragraph.rb +37 -33
- data/lib/rdoc/markup/inline_parser.rb +281 -277
- data/lib/rdoc/markup/list.rb +80 -88
- data/lib/rdoc/markup/list_item.rb +73 -85
- data/lib/rdoc/markup/paragraph.rb +23 -19
- data/lib/rdoc/markup/parser.rb +501 -497
- data/lib/rdoc/markup/pre_process.rb +284 -305
- data/lib/rdoc/markup/raw.rb +2 -2
- data/lib/rdoc/markup/rule.rb +16 -12
- data/lib/rdoc/markup/to_ansi.rb +143 -139
- data/lib/rdoc/markup/to_bs.rb +72 -68
- data/lib/rdoc/markup/to_html.rb +600 -493
- data/lib/rdoc/markup/to_html_crossref.rb +221 -191
- data/lib/rdoc/markup/to_html_snippet.rb +232 -227
- data/lib/rdoc/markup/to_joined_paragraph.rb +40 -41
- data/lib/rdoc/markup/to_label.rb +63 -59
- data/lib/rdoc/markup/to_markdown.rb +212 -208
- data/lib/rdoc/markup/to_rdoc.rb +336 -332
- data/lib/rdoc/markup/to_table_of_contents.rb +66 -62
- data/lib/rdoc/markup/to_test.rb +60 -56
- data/lib/rdoc/markup/to_tt_only.rb +83 -86
- data/lib/rdoc/markup/verbatim.rb +62 -58
- data/lib/rdoc/markup.rb +198 -196
- data/lib/rdoc/options.rb +1063 -1076
- data/lib/rdoc/parser/c.rb +1039 -1036
- data/lib/rdoc/parser/changelog.rb +319 -315
- data/lib/rdoc/parser/markdown.rb +17 -13
- data/lib/rdoc/parser/rbs.rb +279 -0
- data/lib/rdoc/parser/rd.rb +17 -13
- data/lib/rdoc/parser/ruby.rb +1231 -2222
- data/lib/rdoc/parser/ruby_colorizer.rb +303 -0
- data/lib/rdoc/parser/simple.rb +31 -27
- data/lib/rdoc/parser/text.rb +12 -8
- data/lib/rdoc/parser.rb +230 -221
- data/lib/rdoc/rbs_helper.rb +186 -0
- data/lib/rdoc/rd/inline.rb +57 -53
- data/lib/rdoc/rd.rb +90 -88
- data/lib/rdoc/rdoc.rb +547 -366
- data/lib/rdoc/ri/driver.rb +1141 -1130
- data/lib/rdoc/ri/formatter.rb +7 -3
- data/lib/rdoc/ri/paths.rb +140 -136
- data/lib/rdoc/ri/servlet.rb +456 -0
- data/lib/rdoc/ri/store.rb +4 -2
- data/lib/rdoc/ri/task.rb +55 -51
- data/lib/rdoc/ri.rb +14 -11
- data/lib/rdoc/rubygems_hook.rb +194 -192
- data/lib/rdoc/server.rb +462 -0
- data/lib/rdoc/stats/normal.rb +46 -42
- data/lib/rdoc/stats/quiet.rb +39 -35
- data/lib/rdoc/stats/verbose.rb +35 -31
- data/lib/rdoc/stats.rb +363 -338
- data/lib/rdoc/store.rb +919 -725
- data/lib/rdoc/task.rb +260 -255
- data/lib/rdoc/text.rb +130 -245
- data/lib/rdoc/token_stream.rb +101 -115
- data/lib/rdoc/tom_doc.rb +203 -201
- data/lib/rdoc/version.rb +1 -1
- data/lib/rdoc.rb +35 -7
- data/lib/rubygems_plugin.rb +2 -11
- data/rdoc-logo.svg +43 -0
- data/rdoc.gemspec +6 -4
- metadata +36 -20
- data/lib/rdoc/code_object/anon_class.rb +0 -10
- data/lib/rdoc/code_object/ghost_method.rb +0 -6
- data/lib/rdoc/code_object/meta_method.rb +0 -6
- data/lib/rdoc/markdown/literals.kpeg +0 -21
- data/lib/rdoc/markdown/literals.rb +0 -454
- data/lib/rdoc/parser/prism_ruby.rb +0 -1112
- data/lib/rdoc/parser/ripper_state_lex.rb +0 -302
- data/lib/rdoc/parser/ruby_tools.rb +0 -163
- data/lib/rdoc/servlet.rb +0 -452
|
@@ -1,1233 +1,1206 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
#
|
|
5
|
-
#
|
|
2
|
+
module RDoc
|
|
3
|
+
##
|
|
4
|
+
# A Context is something that can hold modules, classes, methods, attributes,
|
|
5
|
+
# aliases, requires, and includes. Classes, modules, and files are all
|
|
6
|
+
# Contexts.
|
|
6
7
|
|
|
7
|
-
class
|
|
8
|
+
class Context < CodeObject
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
include Comparable
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
##
|
|
13
|
+
# Types of methods
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
TYPES = %w[class instance]
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
##
|
|
18
|
+
# If a context has these titles it will be sorted in this order.
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
TOMDOC_TITLES = [nil, 'Public', 'Internal', 'Deprecated'] # :nodoc:
|
|
21
|
+
TOMDOC_TITLES_SORT = TOMDOC_TITLES.sort_by { |title| title.to_s } # :nodoc:
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
##
|
|
24
|
+
# Class/module aliases
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
attr_reader :aliases
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
##
|
|
29
|
+
# All attr* methods
|
|
29
30
|
|
|
30
|
-
|
|
31
|
+
attr_reader :attributes
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
##
|
|
34
|
+
# Block params to be used in the next MethodAttr parsed under this context
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
attr_accessor :block_params
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
##
|
|
39
|
+
# Constants defined
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
attr_reader :constants
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
##
|
|
44
|
+
# Sets the current documentation section of documentation
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
attr_writer :current_section
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
##
|
|
49
|
+
# Files this context is found in
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
attr_reader :in_files
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
##
|
|
54
|
+
# Modules this context includes
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
attr_reader :includes
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
##
|
|
59
|
+
# Modules this context is extended with
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
attr_reader :extends
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
##
|
|
64
|
+
# Methods defined in this context
|
|
64
65
|
|
|
65
|
-
|
|
66
|
+
attr_reader :method_list
|
|
66
67
|
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
##
|
|
69
|
+
# Name of this class excluding namespace. See also full_name
|
|
69
70
|
|
|
70
|
-
|
|
71
|
+
attr_reader :name
|
|
71
72
|
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
##
|
|
74
|
+
# Files this context requires
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
##
|
|
78
|
-
# Use this section for the next method, attribute or constant added.
|
|
76
|
+
attr_reader :requires
|
|
79
77
|
|
|
80
|
-
|
|
78
|
+
##
|
|
79
|
+
# Use this section for the next method, attribute or constant added.
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
# Hash <tt>old_name => [aliases]</tt>, for aliases
|
|
84
|
-
# that haven't (yet) been resolved to a method/attribute.
|
|
85
|
-
# (Not to be confused with the aliases of the context.)
|
|
81
|
+
attr_accessor :temporary_section
|
|
86
82
|
|
|
87
|
-
|
|
83
|
+
##
|
|
84
|
+
# Hash <tt>old_name => [aliases]</tt>, for aliases
|
|
85
|
+
# that haven't (yet) been resolved to a method/attribute.
|
|
86
|
+
# (Not to be confused with the aliases of the context.)
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
# Aliases that could not be resolved.
|
|
88
|
+
attr_accessor :unmatched_alias_lists
|
|
91
89
|
|
|
92
|
-
|
|
90
|
+
##
|
|
91
|
+
# Aliases that could not be resolved.
|
|
93
92
|
|
|
94
|
-
|
|
95
|
-
# Current visibility of this context
|
|
93
|
+
attr_reader :external_aliases
|
|
96
94
|
|
|
97
|
-
|
|
95
|
+
##
|
|
96
|
+
# Hash of registered methods. Attributes are also registered here,
|
|
97
|
+
# twice if they are RW.
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
# Current visibility of this line
|
|
99
|
+
attr_reader :methods_hash
|
|
101
100
|
|
|
102
|
-
|
|
101
|
+
##
|
|
102
|
+
# Params to be used in the next MethodAttr parsed under this context
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
# Hash of registered methods. Attributes are also registered here,
|
|
106
|
-
# twice if they are RW.
|
|
104
|
+
attr_accessor :params
|
|
107
105
|
|
|
108
|
-
|
|
106
|
+
##
|
|
107
|
+
# Hash of registered constants.
|
|
109
108
|
|
|
110
|
-
|
|
111
|
-
# Params to be used in the next MethodAttr parsed under this context
|
|
109
|
+
attr_reader :constants_hash
|
|
112
110
|
|
|
113
|
-
|
|
111
|
+
##
|
|
112
|
+
# Creates an unnamed empty context
|
|
114
113
|
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
def initialize
|
|
115
|
+
super
|
|
117
116
|
|
|
118
|
-
|
|
117
|
+
@in_files = []
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
|
|
119
|
+
@name ||= "unknown"
|
|
120
|
+
@parent = nil
|
|
121
|
+
@current_section = Section.new self, nil, nil
|
|
122
|
+
@sections = { nil => @current_section }
|
|
123
|
+
@temporary_section = nil
|
|
122
124
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
@classes = {}
|
|
126
|
+
@modules = {}
|
|
125
127
|
|
|
126
|
-
|
|
128
|
+
initialize_methods_etc
|
|
129
|
+
end
|
|
127
130
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
@visibility = :public
|
|
131
|
+
##
|
|
132
|
+
# Sets the defaults for methods and so-forth
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
134
|
+
def initialize_methods_etc
|
|
135
|
+
@method_list = []
|
|
136
|
+
@attributes = []
|
|
137
|
+
@aliases = []
|
|
138
|
+
@requires = []
|
|
139
|
+
@includes = []
|
|
140
|
+
@extends = []
|
|
141
|
+
@constants = []
|
|
142
|
+
@external_aliases = []
|
|
143
|
+
# This Hash maps a method name to a list of unmatched aliases (aliases of
|
|
144
|
+
# a method not yet encountered).
|
|
145
|
+
@unmatched_alias_lists = {}
|
|
135
146
|
|
|
136
|
-
|
|
137
|
-
|
|
147
|
+
@methods_hash = {}
|
|
148
|
+
@constants_hash = {}
|
|
138
149
|
|
|
139
|
-
|
|
140
|
-
end
|
|
150
|
+
@params = nil
|
|
141
151
|
|
|
142
|
-
|
|
143
|
-
|
|
152
|
+
@store ||= nil
|
|
153
|
+
end
|
|
144
154
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
@attributes = []
|
|
148
|
-
@aliases = []
|
|
149
|
-
@requires = []
|
|
150
|
-
@includes = []
|
|
151
|
-
@extends = []
|
|
152
|
-
@constants = []
|
|
153
|
-
@external_aliases = []
|
|
154
|
-
@current_line_visibility = nil
|
|
155
|
+
##
|
|
156
|
+
# Contexts are sorted by full_name
|
|
155
157
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
@unmatched_alias_lists = {}
|
|
158
|
+
def <=>(other)
|
|
159
|
+
return nil unless CodeObject === other
|
|
159
160
|
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
full_name <=> other.full_name
|
|
162
|
+
end
|
|
162
163
|
|
|
163
|
-
|
|
164
|
+
##
|
|
165
|
+
# Adds an item of type +klass+ with the given +name+ and +comment+ to the
|
|
166
|
+
# context.
|
|
167
|
+
#
|
|
168
|
+
# Currently only RDoc::Extend and RDoc::Include are supported.
|
|
169
|
+
|
|
170
|
+
def add(klass, name, comment)
|
|
171
|
+
if Extend == klass
|
|
172
|
+
ext = Extend.new name, comment
|
|
173
|
+
add_extend ext
|
|
174
|
+
elsif Include == klass
|
|
175
|
+
incl = Include.new name, comment
|
|
176
|
+
add_include incl
|
|
177
|
+
else
|
|
178
|
+
raise NotImplementedError, "adding a #{klass} is not implemented"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
164
181
|
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
##
|
|
183
|
+
# Adds +an_alias+ that is automatically resolved
|
|
167
184
|
|
|
168
|
-
|
|
169
|
-
|
|
185
|
+
def add_alias(an_alias)
|
|
186
|
+
return an_alias unless @document_self
|
|
170
187
|
|
|
171
|
-
|
|
172
|
-
|
|
188
|
+
method_attr = find_method(an_alias.old_name, an_alias.singleton) ||
|
|
189
|
+
find_attribute(an_alias.old_name, an_alias.singleton)
|
|
173
190
|
|
|
174
|
-
|
|
175
|
-
|
|
191
|
+
if method_attr
|
|
192
|
+
method_attr.add_alias an_alias, self
|
|
193
|
+
else
|
|
194
|
+
add_to @external_aliases, an_alias
|
|
195
|
+
unmatched_alias_list =
|
|
196
|
+
@unmatched_alias_lists[an_alias.pretty_old_name] ||= []
|
|
197
|
+
unmatched_alias_list.push an_alias
|
|
198
|
+
end
|
|
176
199
|
|
|
177
|
-
|
|
178
|
-
# Adds an item of type +klass+ with the given +name+ and +comment+ to the
|
|
179
|
-
# context.
|
|
180
|
-
#
|
|
181
|
-
# Currently only RDoc::Extend and RDoc::Include are supported.
|
|
182
|
-
|
|
183
|
-
def add(klass, name, comment)
|
|
184
|
-
if RDoc::Extend == klass then
|
|
185
|
-
ext = RDoc::Extend.new name, comment
|
|
186
|
-
add_extend ext
|
|
187
|
-
elsif RDoc::Include == klass then
|
|
188
|
-
incl = RDoc::Include.new name, comment
|
|
189
|
-
add_include incl
|
|
190
|
-
else
|
|
191
|
-
raise NotImplementedError, "adding a #{klass} is not implemented"
|
|
200
|
+
an_alias
|
|
192
201
|
end
|
|
193
|
-
end
|
|
194
202
|
|
|
195
|
-
|
|
196
|
-
|
|
203
|
+
##
|
|
204
|
+
# Adds +attribute+ if not already there. If it is (as method(s) or attribute),
|
|
205
|
+
# updates the comment if it was empty.
|
|
206
|
+
#
|
|
207
|
+
# The attribute is registered only if it defines a new method.
|
|
208
|
+
# For instance, <tt>attr_reader :foo</tt> will not be registered
|
|
209
|
+
# if method +foo+ exists, but <tt>attr_accessor :foo</tt> will be registered
|
|
210
|
+
# if method +foo+ exists, but <tt>foo=</tt> does not.
|
|
197
211
|
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
def add_attribute(attribute)
|
|
213
|
+
return attribute unless @document_self
|
|
200
214
|
|
|
201
|
-
|
|
202
|
-
|
|
215
|
+
# mainly to check for redefinition of an attribute as a method
|
|
216
|
+
# TODO find a policy for 'attr_reader :foo' + 'def foo=()'
|
|
217
|
+
register = false
|
|
203
218
|
|
|
204
|
-
|
|
205
|
-
method_attr.add_alias an_alias, self
|
|
206
|
-
else
|
|
207
|
-
add_to @external_aliases, an_alias
|
|
208
|
-
unmatched_alias_list =
|
|
209
|
-
@unmatched_alias_lists[an_alias.pretty_old_name] ||= []
|
|
210
|
-
unmatched_alias_list.push an_alias
|
|
211
|
-
end
|
|
219
|
+
key = nil
|
|
212
220
|
|
|
213
|
-
|
|
214
|
-
|
|
221
|
+
if attribute.rw.index 'R'
|
|
222
|
+
key = attribute.pretty_name
|
|
223
|
+
known = @methods_hash[key]
|
|
215
224
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
225
|
+
if known
|
|
226
|
+
known.comment = attribute.comment if known.comment.empty?
|
|
227
|
+
elsif registered = @methods_hash[attribute.pretty_name + '='] and
|
|
228
|
+
Attr === registered
|
|
229
|
+
registered.rw = 'RW'
|
|
230
|
+
else
|
|
231
|
+
@methods_hash[key] = attribute
|
|
232
|
+
register = true
|
|
233
|
+
end
|
|
234
|
+
end
|
|
224
235
|
|
|
225
|
-
|
|
226
|
-
|
|
236
|
+
if attribute.rw.index 'W'
|
|
237
|
+
key = attribute.pretty_name + '='
|
|
238
|
+
known = @methods_hash[key]
|
|
227
239
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
240
|
+
if known
|
|
241
|
+
known.comment = attribute.comment if known.comment.empty?
|
|
242
|
+
elsif registered = @methods_hash[attribute.pretty_name] and
|
|
243
|
+
Attr === registered
|
|
244
|
+
registered.rw = 'RW'
|
|
245
|
+
else
|
|
246
|
+
@methods_hash[key] = attribute
|
|
247
|
+
register = true
|
|
248
|
+
end
|
|
249
|
+
end
|
|
231
250
|
|
|
232
|
-
|
|
251
|
+
if register
|
|
252
|
+
add_to @attributes, attribute
|
|
253
|
+
resolve_aliases attribute
|
|
254
|
+
end
|
|
233
255
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
known = @methods_hash[key]
|
|
256
|
+
attribute
|
|
257
|
+
end
|
|
237
258
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
259
|
+
##
|
|
260
|
+
# Adds a class named +given_name+ with +superclass+.
|
|
261
|
+
#
|
|
262
|
+
# Both +given_name+ and +superclass+ may contain '::', and are
|
|
263
|
+
# interpreted relative to the +self+ context. This allows handling correctly
|
|
264
|
+
# examples like these:
|
|
265
|
+
# class RDoc::Gauntlet < Gauntlet
|
|
266
|
+
# module Mod
|
|
267
|
+
# class Object # implies < ::Object
|
|
268
|
+
# class SubObject < Object # this is _not_ ::Object
|
|
269
|
+
#
|
|
270
|
+
# Given <tt>class Container::Item</tt> RDoc assumes +Container+ is a module
|
|
271
|
+
# unless it later sees <tt>class Container</tt>. +add_class+ automatically
|
|
272
|
+
# upgrades +given_name+ to a class in this case.
|
|
273
|
+
|
|
274
|
+
def add_class(class_type, given_name, superclass = '::Object')
|
|
275
|
+
# superclass +nil+ is passed by the C parser in the following cases:
|
|
276
|
+
# - registering Object in 1.8 (correct)
|
|
277
|
+
# - registering BasicObject in 1.9 (correct)
|
|
278
|
+
# - registering RubyVM in 1.9 in iseq.c (incorrect: < Object in vm.c)
|
|
279
|
+
#
|
|
280
|
+
# If we later find a superclass for a registered class with a nil
|
|
281
|
+
# superclass, we must honor it.
|
|
282
|
+
|
|
283
|
+
# find the name & enclosing context
|
|
284
|
+
if given_name =~ /^:+(\w+)$/
|
|
285
|
+
full_name = $1
|
|
286
|
+
enclosing = top_level
|
|
287
|
+
name = full_name.split(/:+/).last
|
|
243
288
|
else
|
|
244
|
-
|
|
245
|
-
|
|
289
|
+
full_name = child_name given_name
|
|
290
|
+
|
|
291
|
+
if full_name =~ /^(.+)::(\w+)$/
|
|
292
|
+
name = $2
|
|
293
|
+
ename = $1
|
|
294
|
+
enclosing = @store.classes_hash[ename] || @store.modules_hash[ename]
|
|
295
|
+
# HACK: crashes in actionpack/lib/action_view/helpers/form_helper.rb (metaprogramming)
|
|
296
|
+
unless enclosing
|
|
297
|
+
# try the given name at top level (will work for the above example)
|
|
298
|
+
enclosing = @store.classes_hash[given_name] ||
|
|
299
|
+
@store.modules_hash[given_name]
|
|
300
|
+
return enclosing if enclosing
|
|
301
|
+
# not found: create the parent(s)
|
|
302
|
+
enclosing = find_or_create_namespace_path ename
|
|
303
|
+
end
|
|
304
|
+
else
|
|
305
|
+
name = full_name
|
|
306
|
+
enclosing = self
|
|
307
|
+
end
|
|
246
308
|
end
|
|
247
|
-
end
|
|
248
309
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
310
|
+
# fix up superclass
|
|
311
|
+
if full_name == 'BasicObject'
|
|
312
|
+
superclass = nil
|
|
313
|
+
elsif full_name == 'Object'
|
|
314
|
+
superclass = '::BasicObject'
|
|
315
|
+
end
|
|
252
316
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
317
|
+
# find the superclass full name
|
|
318
|
+
if superclass
|
|
319
|
+
if superclass =~ /^:+/
|
|
320
|
+
superclass = $' #'
|
|
321
|
+
else
|
|
322
|
+
if superclass =~ /^(\w+):+(.+)$/
|
|
323
|
+
suffix = $2
|
|
324
|
+
mod = find_module_named($1)
|
|
325
|
+
superclass = mod.full_name + '::' + suffix if mod
|
|
326
|
+
else
|
|
327
|
+
mod = find_module_named(superclass)
|
|
328
|
+
superclass = mod.full_name if mod
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# did we believe it was a module?
|
|
333
|
+
mod = @store.modules_hash.delete superclass
|
|
334
|
+
|
|
335
|
+
upgrade_to_class mod, NormalClass, mod.parent if mod
|
|
336
|
+
|
|
337
|
+
# e.g., Object < Object
|
|
338
|
+
superclass = nil if superclass == full_name
|
|
261
339
|
end
|
|
262
|
-
end
|
|
263
340
|
|
|
264
|
-
|
|
265
|
-
attribute.visibility = @visibility
|
|
266
|
-
add_to @attributes, attribute
|
|
267
|
-
resolve_aliases attribute
|
|
268
|
-
end
|
|
341
|
+
klass = @store.classes_hash[full_name]
|
|
269
342
|
|
|
270
|
-
|
|
271
|
-
|
|
343
|
+
if klass
|
|
344
|
+
# if TopLevel, it may not be registered in the classes:
|
|
345
|
+
enclosing.classes_hash[name] = klass
|
|
272
346
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
# module Mod
|
|
281
|
-
# class Object # implies < ::Object
|
|
282
|
-
# class SubObject < Object # this is _not_ ::Object
|
|
283
|
-
#
|
|
284
|
-
# Given <tt>class Container::Item</tt> RDoc assumes +Container+ is a module
|
|
285
|
-
# unless it later sees <tt>class Container</tt>. +add_class+ automatically
|
|
286
|
-
# upgrades +given_name+ to a class in this case.
|
|
287
|
-
|
|
288
|
-
def add_class(class_type, given_name, superclass = '::Object')
|
|
289
|
-
# superclass +nil+ is passed by the C parser in the following cases:
|
|
290
|
-
# - registering Object in 1.8 (correct)
|
|
291
|
-
# - registering BasicObject in 1.9 (correct)
|
|
292
|
-
# - registering RubyVM in 1.9 in iseq.c (incorrect: < Object in vm.c)
|
|
293
|
-
#
|
|
294
|
-
# If we later find a superclass for a registered class with a nil
|
|
295
|
-
# superclass, we must honor it.
|
|
296
|
-
|
|
297
|
-
# find the name & enclosing context
|
|
298
|
-
if given_name =~ /^:+(\w+)$/ then
|
|
299
|
-
full_name = $1
|
|
300
|
-
enclosing = top_level
|
|
301
|
-
name = full_name.split(/:+/).last
|
|
302
|
-
else
|
|
303
|
-
full_name = child_name given_name
|
|
304
|
-
|
|
305
|
-
if full_name =~ /^(.+)::(\w+)$/ then
|
|
306
|
-
name = $2
|
|
307
|
-
ename = $1
|
|
308
|
-
enclosing = @store.classes_hash[ename] || @store.modules_hash[ename]
|
|
309
|
-
# HACK: crashes in actionpack/lib/action_view/helpers/form_helper.rb (metaprogramming)
|
|
310
|
-
unless enclosing then
|
|
311
|
-
# try the given name at top level (will work for the above example)
|
|
312
|
-
enclosing = @store.classes_hash[given_name] ||
|
|
313
|
-
@store.modules_hash[given_name]
|
|
314
|
-
return enclosing if enclosing
|
|
315
|
-
# not found: create the parent(s)
|
|
316
|
-
names = ename.split('::')
|
|
317
|
-
enclosing = self
|
|
318
|
-
names.each do |n|
|
|
319
|
-
enclosing = enclosing.classes_hash[n] ||
|
|
320
|
-
enclosing.modules_hash[n] ||
|
|
321
|
-
enclosing.add_module(RDoc::NormalModule, n)
|
|
347
|
+
# update the superclass if needed
|
|
348
|
+
if superclass
|
|
349
|
+
existing = klass.superclass
|
|
350
|
+
existing = existing.full_name unless existing.is_a?(String) if existing
|
|
351
|
+
if existing.nil? ||
|
|
352
|
+
(existing == 'Object' && superclass != 'Object')
|
|
353
|
+
klass.superclass = superclass
|
|
322
354
|
end
|
|
323
355
|
end
|
|
324
356
|
else
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
end
|
|
328
|
-
end
|
|
357
|
+
# this is a new class
|
|
358
|
+
mod = @store.modules_hash.delete full_name
|
|
329
359
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
superclass = nil
|
|
333
|
-
elsif full_name == 'Object' then
|
|
334
|
-
superclass = '::BasicObject'
|
|
335
|
-
end
|
|
360
|
+
if mod
|
|
361
|
+
klass = upgrade_to_class mod, NormalClass, enclosing
|
|
336
362
|
|
|
337
|
-
|
|
338
|
-
if superclass then
|
|
339
|
-
if superclass =~ /^:+/ then
|
|
340
|
-
superclass = $' #'
|
|
341
|
-
else
|
|
342
|
-
if superclass =~ /^(\w+):+(.+)$/ then
|
|
343
|
-
suffix = $2
|
|
344
|
-
mod = find_module_named($1)
|
|
345
|
-
superclass = mod.full_name + '::' + suffix if mod
|
|
363
|
+
klass.superclass = superclass unless superclass.nil?
|
|
346
364
|
else
|
|
347
|
-
|
|
348
|
-
|
|
365
|
+
klass = class_type.new name, superclass
|
|
366
|
+
|
|
367
|
+
enclosing.add_class_or_module(klass, enclosing.classes_hash,
|
|
368
|
+
@store.classes_hash)
|
|
349
369
|
end
|
|
350
370
|
end
|
|
351
371
|
|
|
352
|
-
|
|
353
|
-
mod = @store.modules_hash.delete superclass
|
|
372
|
+
klass.parent = self
|
|
354
373
|
|
|
355
|
-
|
|
374
|
+
klass
|
|
375
|
+
end
|
|
356
376
|
|
|
357
|
-
|
|
358
|
-
|
|
377
|
+
##
|
|
378
|
+
# Adds the class or module +mod+ to the modules or
|
|
379
|
+
# classes Hash +self_hash+, and to +all_hash+ (either
|
|
380
|
+
# <tt>TopLevel::modules_hash</tt> or <tt>TopLevel::classes_hash</tt>),
|
|
381
|
+
# unless #done_documenting is +true+. Sets the #parent of +mod+
|
|
382
|
+
# to +self+, and its #section to #current_section. Returns +mod+.
|
|
383
|
+
|
|
384
|
+
def add_class_or_module(mod, self_hash, all_hash)
|
|
385
|
+
mod.section = current_section # TODO declaring context? something is
|
|
386
|
+
# wrong here...
|
|
387
|
+
mod.parent = self
|
|
388
|
+
mod.full_name = nil
|
|
389
|
+
mod.store = @store
|
|
390
|
+
|
|
391
|
+
unless @done_documenting
|
|
392
|
+
self_hash[mod.name] = mod
|
|
393
|
+
# this must be done AFTER adding mod to its parent, so that the full
|
|
394
|
+
# name is correct:
|
|
395
|
+
all_hash[mod.full_name] = mod
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
mod
|
|
359
399
|
end
|
|
360
400
|
|
|
361
|
-
|
|
401
|
+
##
|
|
402
|
+
# Adds +constant+ if not already there. If it is, updates the comment,
|
|
403
|
+
# value and/or is_alias_for of the known constant if they were empty/nil.
|
|
362
404
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
enclosing.classes_hash[name] = klass
|
|
405
|
+
def add_constant(constant)
|
|
406
|
+
return constant unless @document_self
|
|
366
407
|
|
|
367
|
-
#
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
existing = existing.full_name unless existing.is_a?(String) if existing
|
|
371
|
-
if existing.nil? ||
|
|
372
|
-
(existing == 'Object' && superclass != 'Object') then
|
|
373
|
-
klass.superclass = superclass
|
|
374
|
-
end
|
|
375
|
-
end
|
|
376
|
-
else
|
|
377
|
-
# this is a new class
|
|
378
|
-
mod = @store.modules_hash.delete full_name
|
|
408
|
+
# HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code)
|
|
409
|
+
# (this is a #ifdef: should be handled by the C parser)
|
|
410
|
+
known = @constants_hash[constant.name]
|
|
379
411
|
|
|
380
|
-
if
|
|
381
|
-
|
|
412
|
+
if known
|
|
413
|
+
known.comment = constant.comment if known.comment.empty?
|
|
382
414
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
klass = class_type.new name, superclass
|
|
415
|
+
known.value = constant.value if
|
|
416
|
+
known.value.nil? or known.value.strip.empty?
|
|
386
417
|
|
|
387
|
-
|
|
388
|
-
|
|
418
|
+
constant.parent = self
|
|
419
|
+
known.is_alias_for ||= constant.is_alias_for
|
|
420
|
+
else
|
|
421
|
+
@constants_hash[constant.name] = constant
|
|
422
|
+
add_to @constants, constant
|
|
389
423
|
end
|
|
424
|
+
|
|
425
|
+
constant
|
|
390
426
|
end
|
|
391
427
|
|
|
392
|
-
|
|
428
|
+
##
|
|
429
|
+
# Adds included module +include+ which should be an RDoc::Include
|
|
393
430
|
|
|
394
|
-
|
|
395
|
-
|
|
431
|
+
def add_include(include)
|
|
432
|
+
add_to @includes, include
|
|
396
433
|
|
|
397
|
-
|
|
398
|
-
# Adds the class or module +mod+ to the modules or
|
|
399
|
-
# classes Hash +self_hash+, and to +all_hash+ (either
|
|
400
|
-
# <tt>TopLevel::modules_hash</tt> or <tt>TopLevel::classes_hash</tt>),
|
|
401
|
-
# unless #done_documenting is +true+. Sets the #parent of +mod+
|
|
402
|
-
# to +self+, and its #section to #current_section. Returns +mod+.
|
|
403
|
-
|
|
404
|
-
def add_class_or_module(mod, self_hash, all_hash)
|
|
405
|
-
mod.section = current_section # TODO declaring context? something is
|
|
406
|
-
# wrong here...
|
|
407
|
-
mod.parent = self
|
|
408
|
-
mod.full_name = nil
|
|
409
|
-
mod.store = @store
|
|
410
|
-
|
|
411
|
-
unless @done_documenting then
|
|
412
|
-
self_hash[mod.name] = mod
|
|
413
|
-
# this must be done AFTER adding mod to its parent, so that the full
|
|
414
|
-
# name is correct:
|
|
415
|
-
all_hash[mod.full_name] = mod
|
|
416
|
-
if @store.unmatched_constant_alias[mod.full_name] then
|
|
417
|
-
to, file = @store.unmatched_constant_alias[mod.full_name]
|
|
418
|
-
add_module_alias mod, mod.name, to, file
|
|
419
|
-
end
|
|
434
|
+
include
|
|
420
435
|
end
|
|
421
436
|
|
|
422
|
-
|
|
423
|
-
|
|
437
|
+
##
|
|
438
|
+
# Adds extension module +ext+ which should be an RDoc::Extend
|
|
424
439
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
# value and/or is_alias_for of the known constant if they were empty/nil.
|
|
440
|
+
def add_extend(ext)
|
|
441
|
+
add_to @extends, ext
|
|
428
442
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
# HACK: avoid duplicate 'PI' & 'E' in math.c (1.8.7 source code)
|
|
433
|
-
# (this is a #ifdef: should be handled by the C parser)
|
|
434
|
-
known = @constants_hash[constant.name]
|
|
443
|
+
ext
|
|
444
|
+
end
|
|
435
445
|
|
|
436
|
-
|
|
437
|
-
|
|
446
|
+
##
|
|
447
|
+
# Adds +method+ if not already there. If it is (as method or attribute),
|
|
448
|
+
# updates the comment if it was empty.
|
|
438
449
|
|
|
439
|
-
|
|
440
|
-
|
|
450
|
+
def add_method(method)
|
|
451
|
+
return method unless @document_self
|
|
441
452
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
@
|
|
445
|
-
add_to @constants, constant
|
|
446
|
-
end
|
|
453
|
+
# HACK: avoid duplicate 'new' in io.c & struct.c (1.8.7 source code)
|
|
454
|
+
key = method.pretty_name
|
|
455
|
+
known = @methods_hash[key]
|
|
447
456
|
|
|
448
|
-
|
|
449
|
-
|
|
457
|
+
if known
|
|
458
|
+
if @store # otherwise we are loading
|
|
459
|
+
known.comment = method.comment if known.comment.empty?
|
|
460
|
+
previously = ", previously in #{known.file}" unless
|
|
461
|
+
method.file == known.file
|
|
462
|
+
@store.options.warn \
|
|
463
|
+
"Duplicate method #{known.full_name} in #{method.file}#{previously}"
|
|
464
|
+
end
|
|
465
|
+
else
|
|
466
|
+
@methods_hash[key] = method
|
|
467
|
+
add_to @method_list, method
|
|
468
|
+
resolve_aliases method
|
|
469
|
+
end
|
|
450
470
|
|
|
451
|
-
|
|
452
|
-
|
|
471
|
+
method
|
|
472
|
+
end
|
|
453
473
|
|
|
454
|
-
|
|
455
|
-
|
|
474
|
+
##
|
|
475
|
+
# Returns the owner context and local name for +constant_path+, creating
|
|
476
|
+
# missing namespace modules. A leading +::+ resolves from the top-level.
|
|
477
|
+
# This only resolves explicit context-tree paths; RDoc::Parser::Ruby has
|
|
478
|
+
# parser-local lexical helpers for Ruby's nesting-dependent lookup.
|
|
456
479
|
|
|
457
|
-
|
|
458
|
-
|
|
480
|
+
def find_or_create_constant_owner_for_path(constant_path) # :nodoc:
|
|
481
|
+
constant_path = constant_path.to_s
|
|
482
|
+
owner = constant_path.start_with?('::') ? top_level : self
|
|
483
|
+
constant_path = constant_path.delete_prefix('::')
|
|
459
484
|
|
|
460
|
-
|
|
461
|
-
|
|
485
|
+
owner_path, separator, name = constant_path.rpartition('::')
|
|
486
|
+
owner = owner.find_or_create_namespace_path owner_path unless separator.empty?
|
|
462
487
|
|
|
463
|
-
|
|
464
|
-
|
|
488
|
+
[owner, name]
|
|
489
|
+
end
|
|
465
490
|
|
|
466
|
-
|
|
467
|
-
|
|
491
|
+
##
|
|
492
|
+
# Finds or creates the module namespace path under this context.
|
|
468
493
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
return method unless @document_self
|
|
475
|
-
|
|
476
|
-
# HACK: avoid duplicate 'new' in io.c & struct.c (1.8.7 source code)
|
|
477
|
-
key = method.pretty_name
|
|
478
|
-
known = @methods_hash[key]
|
|
479
|
-
|
|
480
|
-
if known then
|
|
481
|
-
if @store then # otherwise we are loading
|
|
482
|
-
known.comment = method.comment if known.comment.empty?
|
|
483
|
-
previously = ", previously in #{known.file}" unless
|
|
484
|
-
method.file == known.file
|
|
485
|
-
@store.options.warn \
|
|
486
|
-
"Duplicate method #{known.full_name} in #{method.file}#{previously}"
|
|
494
|
+
def find_or_create_namespace_path(path) # :nodoc:
|
|
495
|
+
path.to_s.split('::').inject(self) do |owner, name|
|
|
496
|
+
owner.classes_hash[name] ||
|
|
497
|
+
owner.modules_hash[name] ||
|
|
498
|
+
owner.add_module(NormalModule, name)
|
|
487
499
|
end
|
|
488
|
-
else
|
|
489
|
-
@methods_hash[key] = method
|
|
490
|
-
if @current_line_visibility
|
|
491
|
-
method.visibility, @current_line_visibility = @current_line_visibility, nil
|
|
492
|
-
else
|
|
493
|
-
method.visibility = @visibility
|
|
494
|
-
end
|
|
495
|
-
add_to @method_list, method
|
|
496
|
-
resolve_aliases method
|
|
497
500
|
end
|
|
498
501
|
|
|
499
|
-
|
|
500
|
-
|
|
502
|
+
##
|
|
503
|
+
# Adds a module named +name+. If RDoc already knows +name+ is a class then
|
|
504
|
+
# that class is returned instead. See also #add_class.
|
|
501
505
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
506
|
+
def add_module(class_type, name)
|
|
507
|
+
if name.to_s.include?('::')
|
|
508
|
+
owner, name = find_or_create_constant_owner_for_path name
|
|
509
|
+
return owner.add_module class_type, name unless owner == self
|
|
510
|
+
end
|
|
505
511
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
return mod if mod
|
|
512
|
+
mod = @classes[name] || @modules[name]
|
|
513
|
+
return mod if mod
|
|
509
514
|
|
|
510
|
-
|
|
511
|
-
|
|
515
|
+
full_name = child_name name
|
|
516
|
+
mod = @store.modules_hash[full_name] || class_type.new(name)
|
|
512
517
|
|
|
513
|
-
|
|
514
|
-
|
|
518
|
+
add_class_or_module mod, @modules, @store.modules_hash
|
|
519
|
+
end
|
|
515
520
|
|
|
516
|
-
|
|
517
|
-
|
|
521
|
+
##
|
|
522
|
+
# Adds a module by +RDoc::NormalModule+ instance. See also #add_module.
|
|
518
523
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
524
|
+
def add_module_by_normal_module(mod)
|
|
525
|
+
add_class_or_module mod, @modules, @store.modules_hash
|
|
526
|
+
end
|
|
522
527
|
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
528
|
+
##
|
|
529
|
+
# Adds an alias from +from+ (a class or module) to the constant +to+ which
|
|
530
|
+
# was defined in +file+.
|
|
526
531
|
|
|
527
|
-
|
|
528
|
-
|
|
532
|
+
def add_module_alias(from, to, file)
|
|
533
|
+
return from if @done_documenting
|
|
529
534
|
|
|
530
|
-
|
|
535
|
+
to_full_name = child_name to.name
|
|
531
536
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
+
# if we already know this name, don't register an alias:
|
|
538
|
+
# see the metaprogramming in lib/active_support/basic_object.rb,
|
|
539
|
+
# where we already know BasicObject is a class when we find
|
|
540
|
+
# BasicObject = BlankSlate
|
|
541
|
+
return from if @store.find_class_or_module to_full_name
|
|
537
542
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
543
|
+
new_to = from.dup
|
|
544
|
+
new_to.name = to.name
|
|
545
|
+
new_to.full_name = nil
|
|
546
|
+
new_to.is_alias_for = from
|
|
542
547
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
548
|
+
if new_to.module?
|
|
549
|
+
@store.modules_hash[to_full_name] = new_to
|
|
550
|
+
@modules[to.name] = new_to
|
|
551
|
+
else
|
|
552
|
+
@store.classes_hash[to_full_name] = new_to
|
|
553
|
+
@classes[to.name] = new_to
|
|
554
|
+
end
|
|
546
555
|
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
556
|
+
# Registers a constant for this alias. The constant value and comment
|
|
557
|
+
# will be updated later, when the Ruby parser adds the constant
|
|
558
|
+
const = Constant.new to.name, nil, new_to.comment
|
|
559
|
+
const.record_location file
|
|
560
|
+
const.is_alias_for = from
|
|
561
|
+
add_constant const
|
|
562
|
+
|
|
563
|
+
new_to
|
|
553
564
|
end
|
|
554
565
|
|
|
555
|
-
|
|
556
|
-
#
|
|
557
|
-
const = RDoc::Constant.new to.name, nil, new_to.comment
|
|
558
|
-
const.record_location file
|
|
559
|
-
const.is_alias_for = from
|
|
560
|
-
add_constant const
|
|
566
|
+
##
|
|
567
|
+
# Adds +require+ to this context's top level
|
|
561
568
|
|
|
562
|
-
|
|
563
|
-
|
|
569
|
+
def add_require(require)
|
|
570
|
+
return require unless @document_self
|
|
564
571
|
|
|
565
|
-
|
|
566
|
-
|
|
572
|
+
if TopLevel === self
|
|
573
|
+
add_to @requires, require
|
|
574
|
+
else
|
|
575
|
+
parent.add_require require
|
|
576
|
+
end
|
|
577
|
+
end
|
|
567
578
|
|
|
568
|
-
|
|
569
|
-
|
|
579
|
+
##
|
|
580
|
+
# Returns a section with +title+, creating it if it doesn't already exist.
|
|
581
|
+
# +comment+ will be appended to the section's comment.
|
|
582
|
+
#
|
|
583
|
+
# A section with a +title+ of +nil+ will return the default section.
|
|
584
|
+
#
|
|
585
|
+
# See also RDoc::Context::Section
|
|
570
586
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
587
|
+
def add_section(title, comment = nil)
|
|
588
|
+
if section = @sections[title]
|
|
589
|
+
section.add_comment comment if comment
|
|
590
|
+
else
|
|
591
|
+
section = Section.new self, title, comment, @store
|
|
592
|
+
@sections[title] = section
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
section
|
|
575
596
|
end
|
|
576
|
-
end
|
|
577
597
|
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
# +comment+ will be appended to the section's comment.
|
|
581
|
-
#
|
|
582
|
-
# A section with a +title+ of +nil+ will return the default section.
|
|
583
|
-
#
|
|
584
|
-
# See also RDoc::Context::Section
|
|
585
|
-
|
|
586
|
-
def add_section(title, comment = nil)
|
|
587
|
-
if section = @sections[title] then
|
|
588
|
-
section.add_comment comment if comment
|
|
589
|
-
else
|
|
590
|
-
section = Section.new self, title, comment, @store
|
|
591
|
-
@sections[title] = section
|
|
592
|
-
end
|
|
593
|
-
|
|
594
|
-
section
|
|
595
|
-
end
|
|
598
|
+
##
|
|
599
|
+
# Adds +thing+ to the collection +array+
|
|
596
600
|
|
|
597
|
-
|
|
598
|
-
|
|
601
|
+
def add_to(array, thing)
|
|
602
|
+
array << thing if @document_self
|
|
599
603
|
|
|
600
|
-
|
|
601
|
-
|
|
604
|
+
thing.parent = self
|
|
605
|
+
thing.store = @store if @store
|
|
606
|
+
thing.section = current_section
|
|
607
|
+
end
|
|
602
608
|
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
609
|
+
##
|
|
610
|
+
# Is there any content?
|
|
611
|
+
#
|
|
612
|
+
# This means any of: comment, aliases, methods, attributes, external
|
|
613
|
+
# aliases, require, constant.
|
|
614
|
+
#
|
|
615
|
+
# Includes and extends are also checked unless <tt>includes == false</tt>.
|
|
616
|
+
|
|
617
|
+
def any_content(includes = true)
|
|
618
|
+
@any_content ||= !(
|
|
619
|
+
@comment.empty? &&
|
|
620
|
+
@method_list.empty? &&
|
|
621
|
+
@attributes.empty? &&
|
|
622
|
+
@aliases.empty? &&
|
|
623
|
+
@external_aliases.empty? &&
|
|
624
|
+
@requires.empty? &&
|
|
625
|
+
@constants.empty?
|
|
626
|
+
)
|
|
627
|
+
@any_content || (includes && !(@includes + @extends).empty? )
|
|
628
|
+
end
|
|
607
629
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
#
|
|
611
|
-
# This means any of: comment, aliases, methods, attributes, external
|
|
612
|
-
# aliases, require, constant.
|
|
613
|
-
#
|
|
614
|
-
# Includes and extends are also checked unless <tt>includes == false</tt>.
|
|
615
|
-
|
|
616
|
-
def any_content(includes = true)
|
|
617
|
-
@any_content ||= !(
|
|
618
|
-
@comment.empty? &&
|
|
619
|
-
@method_list.empty? &&
|
|
620
|
-
@attributes.empty? &&
|
|
621
|
-
@aliases.empty? &&
|
|
622
|
-
@external_aliases.empty? &&
|
|
623
|
-
@requires.empty? &&
|
|
624
|
-
@constants.empty?
|
|
625
|
-
)
|
|
626
|
-
@any_content || (includes && !(@includes + @extends).empty? )
|
|
627
|
-
end
|
|
630
|
+
##
|
|
631
|
+
# Creates the full name for a child with +name+
|
|
628
632
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
else
|
|
638
|
-
"#{self.full_name}::#{name}"
|
|
633
|
+
def child_name(name)
|
|
634
|
+
if name =~ /^:+/
|
|
635
|
+
$' #'
|
|
636
|
+
elsif TopLevel === self
|
|
637
|
+
name
|
|
638
|
+
else
|
|
639
|
+
"#{self.full_name}::#{name}"
|
|
640
|
+
end
|
|
639
641
|
end
|
|
640
|
-
end
|
|
641
642
|
|
|
642
|
-
|
|
643
|
-
|
|
643
|
+
##
|
|
644
|
+
# Class methods
|
|
644
645
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
646
|
+
def class_method_list
|
|
647
|
+
method_list.select { |a| a.singleton }
|
|
648
|
+
end
|
|
648
649
|
|
|
649
|
-
|
|
650
|
-
|
|
650
|
+
##
|
|
651
|
+
# Array of classes in this context
|
|
651
652
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
653
|
+
def classes
|
|
654
|
+
@classes.values
|
|
655
|
+
end
|
|
655
656
|
|
|
656
|
-
|
|
657
|
-
|
|
657
|
+
##
|
|
658
|
+
# All classes and modules in this namespace
|
|
658
659
|
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
660
|
+
def classes_and_modules
|
|
661
|
+
classes + modules
|
|
662
|
+
end
|
|
662
663
|
|
|
663
|
-
|
|
664
|
-
|
|
664
|
+
##
|
|
665
|
+
# Hash of classes keyed by class name
|
|
665
666
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
667
|
+
def classes_hash
|
|
668
|
+
@classes
|
|
669
|
+
end
|
|
669
670
|
|
|
670
|
-
|
|
671
|
-
|
|
671
|
+
##
|
|
672
|
+
# The current documentation section that new items will be added to. If
|
|
673
|
+
# temporary_section is available it will be used.
|
|
672
674
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
675
|
+
def current_section
|
|
676
|
+
if section = @temporary_section
|
|
677
|
+
@temporary_section = nil
|
|
678
|
+
else
|
|
679
|
+
section = @current_section
|
|
680
|
+
end
|
|
676
681
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
# temporary_section is available it will be used.
|
|
682
|
+
section
|
|
683
|
+
end
|
|
680
684
|
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
685
|
+
def display(method_attr) # :nodoc:
|
|
686
|
+
if method_attr.is_a? Attr
|
|
687
|
+
"#{method_attr.definition} #{method_attr.pretty_name}"
|
|
688
|
+
else
|
|
689
|
+
"method #{method_attr.pretty_name}"
|
|
690
|
+
end
|
|
686
691
|
end
|
|
687
692
|
|
|
688
|
-
|
|
689
|
-
|
|
693
|
+
##
|
|
694
|
+
# Iterator for ancestors for duck-typing. Does nothing. See
|
|
695
|
+
# RDoc::ClassModule#each_ancestor.
|
|
696
|
+
#
|
|
697
|
+
# This method exists to make it easy to work with Context subclasses that
|
|
698
|
+
# aren't part of RDoc.
|
|
690
699
|
|
|
691
|
-
|
|
692
|
-
if method_attr.is_a? RDoc::Attr
|
|
693
|
-
"#{method_attr.definition} #{method_attr.pretty_name}"
|
|
694
|
-
else
|
|
695
|
-
"method #{method_attr.pretty_name}"
|
|
700
|
+
def each_ancestor(&_) # :nodoc:
|
|
696
701
|
end
|
|
697
|
-
end
|
|
698
702
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
# RDoc::ClassModule#each_ancestor.
|
|
702
|
-
#
|
|
703
|
-
# This method exists to make it easy to work with Context subclasses that
|
|
704
|
-
# aren't part of RDoc.
|
|
703
|
+
##
|
|
704
|
+
# Iterator for classes and modules
|
|
705
705
|
|
|
706
|
-
|
|
707
|
-
|
|
706
|
+
def each_classmodule(&block) # :yields: module
|
|
707
|
+
classes_and_modules.sort.each(&block)
|
|
708
|
+
end
|
|
708
709
|
|
|
709
|
-
|
|
710
|
-
|
|
710
|
+
##
|
|
711
|
+
# Iterator for methods
|
|
711
712
|
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
end
|
|
713
|
+
def each_method # :yields: method
|
|
714
|
+
return enum_for __method__ unless block_given?
|
|
715
715
|
|
|
716
|
-
|
|
717
|
-
|
|
716
|
+
@method_list.sort.each { |m| yield m }
|
|
717
|
+
end
|
|
718
718
|
|
|
719
|
-
|
|
720
|
-
|
|
719
|
+
##
|
|
720
|
+
# Iterator for each section's contents sorted by title. The +section+, the
|
|
721
|
+
# section's +constants+ and the sections +attributes+ are yielded. The
|
|
722
|
+
# +constants+ and +attributes+ collections are sorted.
|
|
723
|
+
#
|
|
724
|
+
# To retrieve methods in a section use #methods_by_type with the optional
|
|
725
|
+
# +section+ parameter.
|
|
726
|
+
#
|
|
727
|
+
# NOTE: Do not edit collections yielded by this method
|
|
721
728
|
|
|
722
|
-
|
|
723
|
-
|
|
729
|
+
def each_section # :yields: section, constants, attributes
|
|
730
|
+
return enum_for __method__ unless block_given?
|
|
724
731
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
# section's +constants+ and the sections +attributes+ are yielded. The
|
|
728
|
-
# +constants+ and +attributes+ collections are sorted.
|
|
729
|
-
#
|
|
730
|
-
# To retrieve methods in a section use #methods_by_type with the optional
|
|
731
|
-
# +section+ parameter.
|
|
732
|
-
#
|
|
733
|
-
# NOTE: Do not edit collections yielded by this method
|
|
732
|
+
constants = @constants.group_by do |constant| constant.section end
|
|
733
|
+
attributes = @attributes.group_by do |attribute| attribute.section end
|
|
734
734
|
|
|
735
|
-
|
|
736
|
-
|
|
735
|
+
constants.default = []
|
|
736
|
+
attributes.default = []
|
|
737
737
|
|
|
738
|
-
|
|
739
|
-
|
|
738
|
+
sort_sections.each do |section|
|
|
739
|
+
yield section, constants[section].select(&:display?).sort, attributes[section].select(&:display?).sort
|
|
740
|
+
end
|
|
741
|
+
end
|
|
740
742
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
+
##
|
|
744
|
+
# Finds an attribute +name+ with singleton value +singleton+.
|
|
743
745
|
|
|
744
|
-
|
|
745
|
-
|
|
746
|
+
def find_attribute(name, singleton)
|
|
747
|
+
name = $1 if name =~ /^(.*)=$/
|
|
748
|
+
@attributes.find { |a| a.name == name && a.singleton == singleton }
|
|
746
749
|
end
|
|
747
|
-
end
|
|
748
750
|
|
|
749
|
-
|
|
750
|
-
|
|
751
|
+
##
|
|
752
|
+
# Finds an attribute with +name+ in this context
|
|
751
753
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
754
|
+
def find_attribute_named(name)
|
|
755
|
+
case name
|
|
756
|
+
when /\A#/
|
|
757
|
+
find_attribute name[1..-1], false
|
|
758
|
+
when /\A::/
|
|
759
|
+
find_attribute name[2..-1], true
|
|
760
|
+
else
|
|
761
|
+
@attributes.find { |a| a.name == name }
|
|
762
|
+
end
|
|
763
|
+
end
|
|
756
764
|
|
|
757
|
-
|
|
758
|
-
|
|
765
|
+
##
|
|
766
|
+
# Finds a class method with +name+ in this context
|
|
759
767
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
when /\A#/ then
|
|
763
|
-
find_attribute name[1..-1], false
|
|
764
|
-
when /\A::/ then
|
|
765
|
-
find_attribute name[2..-1], true
|
|
766
|
-
else
|
|
767
|
-
@attributes.find { |a| a.name == name }
|
|
768
|
+
def find_class_method_named(name)
|
|
769
|
+
@method_list.find { |meth| meth.singleton && meth.name == name }
|
|
768
770
|
end
|
|
769
|
-
end
|
|
770
771
|
|
|
771
|
-
|
|
772
|
-
|
|
772
|
+
##
|
|
773
|
+
# Finds a constant with +name+ in this context
|
|
773
774
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
775
|
+
def find_constant_named(name)
|
|
776
|
+
@constants.find do |m|
|
|
777
|
+
m.name == name || m.full_name == name
|
|
778
|
+
end
|
|
779
|
+
end
|
|
777
780
|
|
|
778
|
-
|
|
779
|
-
|
|
781
|
+
##
|
|
782
|
+
# Tries to find a module at a higher scope.
|
|
783
|
+
# But parent is not always a higher module nesting scope, so the result is not correct.
|
|
784
|
+
# Parent chain can only represent last-opened nesting, and may be broken in some cases.
|
|
785
|
+
# The Ruby parser does not represent module nesting with the parent chain.
|
|
780
786
|
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
m.name == name || m.full_name == name
|
|
787
|
+
def find_enclosing_module_named(name)
|
|
788
|
+
parent && parent.find_module_named(name)
|
|
784
789
|
end
|
|
785
|
-
end
|
|
786
790
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
# But parent is not always a higher module nesting scope, so the result is not correct.
|
|
790
|
-
# Parent chain can only represent last-opened nesting, and may be broken in some cases.
|
|
791
|
-
# PrismRuby parser stopped representing module nesting with parent chain at all.
|
|
791
|
+
##
|
|
792
|
+
# Finds an external alias +name+ with singleton value +singleton+.
|
|
792
793
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
794
|
+
def find_external_alias(name, singleton)
|
|
795
|
+
@external_aliases.find { |m| m.name == name && m.singleton == singleton }
|
|
796
|
+
end
|
|
796
797
|
|
|
797
|
-
|
|
798
|
-
|
|
798
|
+
##
|
|
799
|
+
# Finds an external alias with +name+ in this context
|
|
799
800
|
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
801
|
+
def find_external_alias_named(name)
|
|
802
|
+
case name
|
|
803
|
+
when /\A#/
|
|
804
|
+
find_external_alias name[1..-1], false
|
|
805
|
+
when /\A::/
|
|
806
|
+
find_external_alias name[2..-1], true
|
|
807
|
+
else
|
|
808
|
+
@external_aliases.find { |a| a.name == name }
|
|
809
|
+
end
|
|
810
|
+
end
|
|
803
811
|
|
|
804
|
-
|
|
805
|
-
|
|
812
|
+
##
|
|
813
|
+
# Finds an instance method with +name+ in this context
|
|
806
814
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
when /\A#/ then
|
|
810
|
-
find_external_alias name[1..-1], false
|
|
811
|
-
when /\A::/ then
|
|
812
|
-
find_external_alias name[2..-1], true
|
|
813
|
-
else
|
|
814
|
-
@external_aliases.find { |a| a.name == name }
|
|
815
|
+
def find_instance_method_named(name)
|
|
816
|
+
@method_list.find { |meth| !meth.singleton && meth.name == name }
|
|
815
817
|
end
|
|
816
|
-
end
|
|
817
818
|
|
|
818
|
-
|
|
819
|
-
|
|
819
|
+
##
|
|
820
|
+
# Finds a method, constant, attribute, external alias, module or file
|
|
821
|
+
# named +symbol+ in this context.
|
|
822
|
+
|
|
823
|
+
def find_local_symbol(symbol)
|
|
824
|
+
find_method_named(symbol) or
|
|
825
|
+
find_constant_named(symbol) or
|
|
826
|
+
find_attribute_named(symbol) or
|
|
827
|
+
find_external_alias_named(symbol) or
|
|
828
|
+
find_module_named(symbol) or
|
|
829
|
+
@store.find_file_named(symbol)
|
|
830
|
+
end
|
|
820
831
|
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
end
|
|
832
|
+
##
|
|
833
|
+
# Finds a method named +name+ with singleton value +singleton+.
|
|
824
834
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
find_module_named(symbol) or
|
|
835
|
-
@store.find_file_named(symbol)
|
|
836
|
-
end
|
|
835
|
+
def find_method(name, singleton)
|
|
836
|
+
@method_list.find { |m|
|
|
837
|
+
if m.singleton
|
|
838
|
+
m.name == name && m.singleton == singleton
|
|
839
|
+
else
|
|
840
|
+
m.name == name && !m.singleton && !singleton
|
|
841
|
+
end
|
|
842
|
+
}
|
|
843
|
+
end
|
|
837
844
|
|
|
838
|
-
|
|
839
|
-
|
|
845
|
+
##
|
|
846
|
+
# Finds a instance or module method with +name+ in this context
|
|
840
847
|
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
848
|
+
def find_method_named(name)
|
|
849
|
+
case name
|
|
850
|
+
when /\A#/
|
|
851
|
+
find_method name[1..-1], false
|
|
852
|
+
when /\A::/
|
|
853
|
+
find_method name[2..-1], true
|
|
845
854
|
else
|
|
846
|
-
|
|
855
|
+
@method_list.find { |meth| meth.name == name }
|
|
847
856
|
end
|
|
848
|
-
|
|
849
|
-
end
|
|
857
|
+
end
|
|
850
858
|
|
|
851
|
-
|
|
852
|
-
|
|
859
|
+
##
|
|
860
|
+
# Find a module with +name+ trying to using ruby's scoping rules.
|
|
861
|
+
# find_enclosing_module_named cannot use ruby's scoping so the result is not correct.
|
|
853
862
|
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
find_method name[2..-1], true
|
|
860
|
-
else
|
|
861
|
-
@method_list.find { |meth| meth.name == name }
|
|
863
|
+
def find_module_named(name)
|
|
864
|
+
res = get_module_named(name)
|
|
865
|
+
return res if res
|
|
866
|
+
return self if self.name == name
|
|
867
|
+
find_enclosing_module_named name
|
|
862
868
|
end
|
|
863
|
-
end
|
|
864
869
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
# find_enclosing_module_named cannot use ruby's scoping so the result is not correct.
|
|
868
|
-
|
|
869
|
-
def find_module_named(name)
|
|
870
|
-
res = get_module_named(name)
|
|
871
|
-
return res if res
|
|
872
|
-
return self if self.name == name
|
|
873
|
-
find_enclosing_module_named name
|
|
874
|
-
end
|
|
870
|
+
# Get a module named +name+ in this context
|
|
871
|
+
# Don't look up for higher module nesting scopes. RDoc::Context doesn't have that information.
|
|
875
872
|
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
def get_module_named(name)
|
|
880
|
-
@modules[name] || @classes[name]
|
|
881
|
-
end
|
|
873
|
+
def get_module_named(name)
|
|
874
|
+
@modules[name] || @classes[name]
|
|
875
|
+
end
|
|
882
876
|
|
|
883
|
-
|
|
884
|
-
|
|
877
|
+
##
|
|
878
|
+
# Look up +symbol+, first as a module, then as a local symbol.
|
|
885
879
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
880
|
+
def find_symbol(symbol)
|
|
881
|
+
find_symbol_module(symbol) || find_local_symbol(symbol)
|
|
882
|
+
end
|
|
889
883
|
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
884
|
+
##
|
|
885
|
+
# Look up a module named +symbol+.
|
|
886
|
+
|
|
887
|
+
def find_symbol_module(symbol)
|
|
888
|
+
result = nil
|
|
889
|
+
|
|
890
|
+
# look for a class or module 'symbol'
|
|
891
|
+
case symbol
|
|
892
|
+
when /^::/
|
|
893
|
+
result = @store.find_class_or_module symbol
|
|
894
|
+
when /^(\w+):+(.+)$/
|
|
895
|
+
suffix = $2
|
|
896
|
+
top = $1
|
|
897
|
+
searched = self
|
|
898
|
+
while searched do
|
|
899
|
+
mod = searched.find_module_named(top)
|
|
900
|
+
break unless mod
|
|
901
|
+
result = @store.find_class_or_module "#{mod.full_name}::#{suffix}"
|
|
902
|
+
break if result || searched.is_a?(TopLevel)
|
|
903
|
+
searched = searched.parent
|
|
904
|
+
end
|
|
905
|
+
else
|
|
906
|
+
searched = self
|
|
907
|
+
while searched do
|
|
908
|
+
result = searched.find_module_named(symbol)
|
|
909
|
+
break if result || searched.is_a?(TopLevel)
|
|
910
|
+
searched = searched.parent
|
|
911
|
+
end
|
|
917
912
|
end
|
|
913
|
+
|
|
914
|
+
result
|
|
918
915
|
end
|
|
919
916
|
|
|
920
|
-
|
|
921
|
-
|
|
917
|
+
##
|
|
918
|
+
# The full name for this context. This method is overridden by subclasses.
|
|
922
919
|
|
|
923
|
-
|
|
924
|
-
|
|
920
|
+
def full_name
|
|
921
|
+
'(unknown)'
|
|
922
|
+
end
|
|
925
923
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
924
|
+
##
|
|
925
|
+
# Does this context and its methods and constants all have documentation?
|
|
926
|
+
#
|
|
927
|
+
# (Yes, fully documented doesn't mean everything.)
|
|
929
928
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
documented? and
|
|
937
|
-
attributes.all? { |a| a.documented? } and
|
|
938
|
-
method_list.all? { |m| m.documented? } and
|
|
939
|
-
constants.all? { |c| c.documented? }
|
|
940
|
-
end
|
|
929
|
+
def fully_documented?
|
|
930
|
+
documented? and
|
|
931
|
+
attributes.all? { |a| a.documented? } and
|
|
932
|
+
method_list.all? { |m| m.documented? } and
|
|
933
|
+
constants.all? { |c| c.documented? }
|
|
934
|
+
end
|
|
941
935
|
|
|
942
|
-
|
|
943
|
-
|
|
936
|
+
##
|
|
937
|
+
# URL for this with a +prefix+
|
|
944
938
|
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
939
|
+
def http_url
|
|
940
|
+
path = name_for_path
|
|
941
|
+
path = path.gsub(/<<\s*(\w*)/, 'from-\1') if path =~ /<</
|
|
942
|
+
path = path.split('::')
|
|
949
943
|
|
|
950
|
-
|
|
951
|
-
|
|
944
|
+
File.join(*path.compact) + '.html'
|
|
945
|
+
end
|
|
952
946
|
|
|
953
|
-
|
|
954
|
-
|
|
947
|
+
##
|
|
948
|
+
# Instance methods
|
|
955
949
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
950
|
+
def instance_methods
|
|
951
|
+
method_list.reject { |a| a.singleton }
|
|
952
|
+
end
|
|
959
953
|
|
|
960
|
-
|
|
961
|
-
|
|
954
|
+
##
|
|
955
|
+
# Breaks method_list into a nested hash by type (<tt>'class'</tt> or
|
|
956
|
+
# <tt>'instance'</tt>) and visibility (+:public+, +:protected+, +:private+).
|
|
957
|
+
#
|
|
958
|
+
# If +section+ is provided only methods in that RDoc::Context::Section will
|
|
959
|
+
# be returned.
|
|
962
960
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
end
|
|
961
|
+
def methods_by_type(section = nil)
|
|
962
|
+
methods = {}
|
|
966
963
|
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
964
|
+
TYPES.each do |type|
|
|
965
|
+
visibilities = {}
|
|
966
|
+
VISIBILITIES.each do |vis|
|
|
967
|
+
visibilities[vis] = []
|
|
968
|
+
end
|
|
971
969
|
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
@instance_methods ||= method_list.reject { |a| a.singleton }
|
|
975
|
-
end
|
|
970
|
+
methods[type] = visibilities
|
|
971
|
+
end
|
|
976
972
|
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
#
|
|
981
|
-
# If +section+ is provided only methods in that RDoc::Context::Section will
|
|
982
|
-
# be returned.
|
|
983
|
-
|
|
984
|
-
def methods_by_type(section = nil)
|
|
985
|
-
methods = {}
|
|
986
|
-
|
|
987
|
-
TYPES.each do |type|
|
|
988
|
-
visibilities = {}
|
|
989
|
-
RDoc::VISIBILITIES.each do |vis|
|
|
990
|
-
visibilities[vis] = []
|
|
973
|
+
each_method do |method|
|
|
974
|
+
next if section and not method.section == section
|
|
975
|
+
methods[method.type][method.visibility] << method
|
|
991
976
|
end
|
|
992
977
|
|
|
993
|
-
methods
|
|
978
|
+
methods
|
|
994
979
|
end
|
|
995
980
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
methods[method.type][method.visibility] << method
|
|
999
|
-
end
|
|
981
|
+
##
|
|
982
|
+
# Yields AnyMethod and Attr entries matching the list of names in +methods+.
|
|
1000
983
|
|
|
1001
|
-
methods
|
|
1002
|
-
|
|
984
|
+
def methods_matching(methods, singleton = false, &block)
|
|
985
|
+
(@method_list + @attributes).each do |m|
|
|
986
|
+
yield m if methods.include?(m.name) and m.singleton == singleton
|
|
987
|
+
end
|
|
1003
988
|
|
|
1004
|
-
|
|
1005
|
-
|
|
989
|
+
each_ancestor do |parent|
|
|
990
|
+
parent.methods_matching(methods, singleton, &block)
|
|
991
|
+
end
|
|
992
|
+
end
|
|
993
|
+
|
|
994
|
+
##
|
|
995
|
+
# Array of modules in this context
|
|
1006
996
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
yield m if methods.include?(m.name) and m.singleton == singleton
|
|
997
|
+
def modules
|
|
998
|
+
@modules.values
|
|
1010
999
|
end
|
|
1011
1000
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1001
|
+
##
|
|
1002
|
+
# Hash of modules keyed by module name
|
|
1003
|
+
|
|
1004
|
+
def modules_hash
|
|
1005
|
+
@modules
|
|
1014
1006
|
end
|
|
1015
|
-
end
|
|
1016
1007
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1008
|
+
##
|
|
1009
|
+
# Name to use to generate the url.
|
|
1010
|
+
# <tt>#full_name</tt> by default.
|
|
1019
1011
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1012
|
+
def name_for_path
|
|
1013
|
+
full_name
|
|
1014
|
+
end
|
|
1023
1015
|
|
|
1024
|
-
|
|
1025
|
-
|
|
1016
|
+
##
|
|
1017
|
+
# Record +top_level+ as a file +self+ is in.
|
|
1026
1018
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1019
|
+
def record_location(top_level)
|
|
1020
|
+
@in_files << top_level unless @in_files.include?(top_level)
|
|
1021
|
+
end
|
|
1030
1022
|
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1023
|
+
##
|
|
1024
|
+
# Should we remove this context from the documentation?
|
|
1025
|
+
#
|
|
1026
|
+
# The answer is yes if:
|
|
1027
|
+
# * #received_nodoc is +true+
|
|
1028
|
+
# * #any_content is +false+ (not counting includes)
|
|
1029
|
+
# * All #includes are modules (not a string), and their module has
|
|
1030
|
+
# <tt>#remove_from_documentation? == true</tt>
|
|
1031
|
+
# * All classes and modules have <tt>#remove_from_documentation? == true</tt>
|
|
1032
|
+
|
|
1033
|
+
def remove_from_documentation?
|
|
1034
|
+
# Contexts that are still ignored here were created inside a :stopdoc:
|
|
1035
|
+
# region and never received documentable contents afterwards
|
|
1036
|
+
@remove_from_documentation ||=
|
|
1037
|
+
(@received_nodoc || @ignored) &&
|
|
1038
|
+
!any_content(false) &&
|
|
1039
|
+
@includes.all? { |i| !i.module.is_a?(String) && i.module.remove_from_documentation? } &&
|
|
1040
|
+
classes_and_modules.all? { |cm| cm.remove_from_documentation? }
|
|
1041
|
+
end
|
|
1034
1042
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1043
|
+
##
|
|
1044
|
+
# Removes methods and attributes with a visibility less than +min_visibility+.
|
|
1045
|
+
#--
|
|
1046
|
+
# TODO mark the visibility of attributes in the template (if not public?)
|
|
1038
1047
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1048
|
+
def remove_invisible(min_visibility)
|
|
1049
|
+
return if [:private, :nodoc].include? min_visibility
|
|
1050
|
+
remove_invisible_in @method_list, min_visibility
|
|
1051
|
+
remove_invisible_in @attributes, min_visibility
|
|
1052
|
+
remove_invisible_in @constants, min_visibility
|
|
1053
|
+
end
|
|
1041
1054
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
end
|
|
1055
|
+
##
|
|
1056
|
+
# Only called when min_visibility == :public or :private
|
|
1045
1057
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1058
|
+
def remove_invisible_in(array, min_visibility) # :nodoc:
|
|
1059
|
+
if min_visibility == :public
|
|
1060
|
+
array.reject! { |e|
|
|
1061
|
+
e.visibility != :public and not e.force_documentation
|
|
1062
|
+
}
|
|
1063
|
+
else
|
|
1064
|
+
array.reject! { |e|
|
|
1065
|
+
e.visibility == :private and not e.force_documentation
|
|
1066
|
+
}
|
|
1067
|
+
end
|
|
1068
|
+
end
|
|
1048
1069
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1070
|
+
##
|
|
1071
|
+
# Tries to resolve unmatched aliases when a method or attribute has just
|
|
1072
|
+
# been added.
|
|
1073
|
+
|
|
1074
|
+
def resolve_aliases(added)
|
|
1075
|
+
# resolve any pending unmatched aliases
|
|
1076
|
+
key = added.pretty_name
|
|
1077
|
+
unmatched_alias_list = @unmatched_alias_lists[key]
|
|
1078
|
+
return unless unmatched_alias_list
|
|
1079
|
+
unmatched_alias_list.each do |unmatched_alias|
|
|
1080
|
+
added.add_alias unmatched_alias, self
|
|
1081
|
+
@external_aliases.delete unmatched_alias
|
|
1082
|
+
end
|
|
1083
|
+
@unmatched_alias_lists.delete key
|
|
1084
|
+
end
|
|
1052
1085
|
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
# The answer is yes if:
|
|
1057
|
-
# * #received_nodoc is +true+
|
|
1058
|
-
# * #any_content is +false+ (not counting includes)
|
|
1059
|
-
# * All #includes are modules (not a string), and their module has
|
|
1060
|
-
# <tt>#remove_from_documentation? == true</tt>
|
|
1061
|
-
# * All classes and modules have <tt>#remove_from_documentation? == true</tt>
|
|
1062
|
-
|
|
1063
|
-
def remove_from_documentation?
|
|
1064
|
-
@remove_from_documentation ||=
|
|
1065
|
-
@received_nodoc &&
|
|
1066
|
-
!any_content(false) &&
|
|
1067
|
-
@includes.all? { |i| !i.module.is_a?(String) && i.module.remove_from_documentation? } &&
|
|
1068
|
-
classes_and_modules.all? { |cm| cm.remove_from_documentation? }
|
|
1069
|
-
end
|
|
1086
|
+
##
|
|
1087
|
+
# Returns RDoc::Context::Section objects referenced in this context for use
|
|
1088
|
+
# in a table of contents.
|
|
1070
1089
|
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
#--
|
|
1074
|
-
# TODO mark the visibility of attributes in the template (if not public?)
|
|
1075
|
-
|
|
1076
|
-
def remove_invisible(min_visibility)
|
|
1077
|
-
return if [:private, :nodoc].include? min_visibility
|
|
1078
|
-
remove_invisible_in @method_list, min_visibility
|
|
1079
|
-
remove_invisible_in @attributes, min_visibility
|
|
1080
|
-
remove_invisible_in @constants, min_visibility
|
|
1081
|
-
end
|
|
1090
|
+
def section_contents
|
|
1091
|
+
used_sections = {}
|
|
1082
1092
|
|
|
1083
|
-
|
|
1084
|
-
|
|
1093
|
+
each_method do |method|
|
|
1094
|
+
next unless method.display?
|
|
1085
1095
|
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
array.reject! { |e|
|
|
1089
|
-
e.visibility != :public and not e.force_documentation
|
|
1090
|
-
}
|
|
1091
|
-
else
|
|
1092
|
-
array.reject! { |e|
|
|
1093
|
-
e.visibility == :private and not e.force_documentation
|
|
1094
|
-
}
|
|
1095
|
-
end
|
|
1096
|
-
end
|
|
1096
|
+
used_sections[method.section] = true
|
|
1097
|
+
end
|
|
1097
1098
|
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
def resolve_aliases(added)
|
|
1103
|
-
# resolve any pending unmatched aliases
|
|
1104
|
-
key = added.pretty_name
|
|
1105
|
-
unmatched_alias_list = @unmatched_alias_lists[key]
|
|
1106
|
-
return unless unmatched_alias_list
|
|
1107
|
-
unmatched_alias_list.each do |unmatched_alias|
|
|
1108
|
-
added.add_alias unmatched_alias, self
|
|
1109
|
-
@external_aliases.delete unmatched_alias
|
|
1110
|
-
end
|
|
1111
|
-
@unmatched_alias_lists.delete key
|
|
1112
|
-
end
|
|
1099
|
+
# order found sections
|
|
1100
|
+
sections = sort_sections.select do |section|
|
|
1101
|
+
used_sections[section]
|
|
1102
|
+
end
|
|
1113
1103
|
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1104
|
+
# only the default section is used
|
|
1105
|
+
return [] if
|
|
1106
|
+
sections.length == 1 and not sections.first.title
|
|
1117
1107
|
|
|
1118
|
-
|
|
1119
|
-
|
|
1108
|
+
sections
|
|
1109
|
+
end
|
|
1120
1110
|
|
|
1121
|
-
|
|
1122
|
-
|
|
1111
|
+
##
|
|
1112
|
+
# Sections in this context
|
|
1123
1113
|
|
|
1124
|
-
|
|
1114
|
+
def sections
|
|
1115
|
+
@sections.values
|
|
1125
1116
|
end
|
|
1126
1117
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
used_sections[section]
|
|
1118
|
+
def sections_hash # :nodoc:
|
|
1119
|
+
@sections
|
|
1130
1120
|
end
|
|
1131
1121
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
sections.length == 1 and not sections.first.title
|
|
1122
|
+
##
|
|
1123
|
+
# Sets the current section to a section with +title+. See also #add_section
|
|
1135
1124
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1125
|
+
def set_current_section(title, comment)
|
|
1126
|
+
@current_section = add_section title, comment
|
|
1127
|
+
end
|
|
1138
1128
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1129
|
+
##
|
|
1130
|
+
# Given an array +methods+ of method names, set the visibility of each to
|
|
1131
|
+
# +visibility+
|
|
1141
1132
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1133
|
+
def set_visibility_for(methods, visibility, singleton = false)
|
|
1134
|
+
methods_matching methods, singleton do |m|
|
|
1135
|
+
m.visibility = visibility
|
|
1136
|
+
end
|
|
1137
|
+
end
|
|
1145
1138
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1139
|
+
##
|
|
1140
|
+
# Given an array +names+ of constants, set the visibility of each constant to
|
|
1141
|
+
# +visibility+
|
|
1149
1142
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1143
|
+
def set_constant_visibility_for(names, visibility)
|
|
1144
|
+
names.each do |name|
|
|
1145
|
+
constant = @constants_hash[name] or next
|
|
1146
|
+
constant.visibility = visibility
|
|
1147
|
+
end
|
|
1148
|
+
end
|
|
1152
1149
|
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1150
|
+
##
|
|
1151
|
+
# Sorts sections alphabetically (default) or in TomDoc fashion (none,
|
|
1152
|
+
# Public, Internal, Deprecated)
|
|
1156
1153
|
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
# +visibility+
|
|
1154
|
+
def sort_sections
|
|
1155
|
+
titles = @sections.map { |title, _| title }
|
|
1160
1156
|
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1157
|
+
if titles.length > 1 and
|
|
1158
|
+
TOMDOC_TITLES_SORT ==
|
|
1159
|
+
(titles | TOMDOC_TITLES).sort_by { |title| title.to_s }
|
|
1160
|
+
@sections.values_at(*TOMDOC_TITLES).compact
|
|
1161
|
+
else
|
|
1162
|
+
@sections.sort_by { |title, _|
|
|
1163
|
+
title.to_s
|
|
1164
|
+
}.map { |_, section|
|
|
1165
|
+
section
|
|
1166
|
+
}
|
|
1167
|
+
end
|
|
1164
1168
|
end
|
|
1165
|
-
end
|
|
1166
1169
|
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
# +visibility+
|
|
1170
|
-
|
|
1171
|
-
def set_constant_visibility_for(names, visibility)
|
|
1172
|
-
names.each do |name|
|
|
1173
|
-
constant = @constants_hash[name] or next
|
|
1174
|
-
constant.visibility = visibility
|
|
1170
|
+
def to_s # :nodoc:
|
|
1171
|
+
"#{self.class.name} #{self.full_name}"
|
|
1175
1172
|
end
|
|
1176
|
-
end
|
|
1177
1173
|
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
@
|
|
1189
|
-
else
|
|
1190
|
-
@sections.sort_by { |title, _|
|
|
1191
|
-
title.to_s
|
|
1192
|
-
}.map { |_, section|
|
|
1193
|
-
section
|
|
1194
|
-
}
|
|
1174
|
+
##
|
|
1175
|
+
# Return the TopLevel that owns us
|
|
1176
|
+
#--
|
|
1177
|
+
# FIXME we can be 'owned' by several TopLevel (see #record_location &
|
|
1178
|
+
# #in_files)
|
|
1179
|
+
|
|
1180
|
+
def top_level
|
|
1181
|
+
return @top_level if defined? @top_level
|
|
1182
|
+
@top_level = self
|
|
1183
|
+
@top_level = @top_level.parent until TopLevel === @top_level
|
|
1184
|
+
@top_level
|
|
1195
1185
|
end
|
|
1196
|
-
end
|
|
1197
1186
|
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
end
|
|
1187
|
+
##
|
|
1188
|
+
# Upgrades NormalModule +mod+ in +enclosing+ to a +class_type+
|
|
1201
1189
|
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
#--
|
|
1205
|
-
# FIXME we can be 'owned' by several TopLevel (see #record_location &
|
|
1206
|
-
# #in_files)
|
|
1207
|
-
|
|
1208
|
-
def top_level
|
|
1209
|
-
return @top_level if defined? @top_level
|
|
1210
|
-
@top_level = self
|
|
1211
|
-
@top_level = @top_level.parent until RDoc::TopLevel === @top_level
|
|
1212
|
-
@top_level
|
|
1213
|
-
end
|
|
1190
|
+
def upgrade_to_class(mod, class_type, enclosing)
|
|
1191
|
+
enclosing.modules_hash.delete mod.name
|
|
1214
1192
|
|
|
1215
|
-
|
|
1216
|
-
|
|
1193
|
+
klass = ClassModule.from_module class_type, mod
|
|
1194
|
+
klass.store = @store
|
|
1217
1195
|
|
|
1218
|
-
|
|
1219
|
-
|
|
1196
|
+
# if it was there, then we keep it even if done_documenting
|
|
1197
|
+
@store.classes_hash[mod.full_name] = klass
|
|
1198
|
+
enclosing.classes_hash[mod.name] = klass
|
|
1220
1199
|
|
|
1221
|
-
|
|
1222
|
-
|
|
1200
|
+
klass
|
|
1201
|
+
end
|
|
1223
1202
|
|
|
1224
|
-
|
|
1225
|
-
@store.classes_hash[mod.full_name] = klass
|
|
1226
|
-
enclosing.classes_hash[mod.name] = klass
|
|
1203
|
+
autoload :Section, "#{__dir__}/context/section"
|
|
1227
1204
|
|
|
1228
|
-
klass
|
|
1229
1205
|
end
|
|
1230
|
-
|
|
1231
|
-
autoload :Section, "#{__dir__}/context/section"
|
|
1232
|
-
|
|
1233
1206
|
end
|