bitclust-core 1.3.0 → 1.6.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.
Files changed (152) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +65 -0
  4. data/Rakefile +32 -0
  5. data/data/bitclust/catalog/ja_JP.UTF-8 +19 -1
  6. data/data/bitclust/searchpage/index.html +90 -0
  7. data/data/bitclust/template/class +69 -8
  8. data/data/bitclust/template/function +2 -2
  9. data/data/bitclust/template/layout +11 -3
  10. data/data/bitclust/template/method +2 -2
  11. data/data/bitclust/template/search +1 -1
  12. data/data/bitclust/template.epub/class +22 -1
  13. data/data/bitclust/template.epub/function +2 -2
  14. data/data/bitclust/template.epub/layout +1 -3
  15. data/data/bitclust/template.epub/method +2 -2
  16. data/data/bitclust/template.lillia/class +26 -5
  17. data/data/bitclust/template.lillia/layout +1 -3
  18. data/data/bitclust/template.lillia/method +2 -2
  19. data/data/bitclust/template.offline/class +48 -4
  20. data/data/bitclust/template.offline/function +2 -2
  21. data/data/bitclust/template.offline/layout +27 -3
  22. data/data/bitclust/template.offline/method +2 -2
  23. data/lib/bitclust/app.rb +16 -17
  24. data/lib/bitclust/capi_converter.rb +20 -0
  25. data/lib/bitclust/classentry.rb +67 -17
  26. data/lib/bitclust/compat.rb +2 -2
  27. data/lib/bitclust/completion.rb +58 -27
  28. data/lib/bitclust/crossrubyutils.rb +8 -5
  29. data/lib/bitclust/database.rb +28 -8
  30. data/lib/bitclust/doc_converter.rb +63 -0
  31. data/lib/bitclust/docentry.rb +1 -1
  32. data/lib/bitclust/entity_splitter.rb +221 -0
  33. data/lib/bitclust/entry.rb +47 -7
  34. data/lib/bitclust/functiondatabase.rb +13 -1
  35. data/lib/bitclust/functionentry.rb +5 -1
  36. data/lib/bitclust/functionreferenceparser.rb +4 -4
  37. data/lib/bitclust/generators/epub.rb +10 -3
  38. data/lib/bitclust/htmlutils.rb +1 -1
  39. data/lib/bitclust/include_graph.rb +375 -0
  40. data/lib/bitclust/include_pruner.rb +144 -0
  41. data/lib/bitclust/interface.rb +1 -1
  42. data/lib/bitclust/libraryentry.rb +8 -7
  43. data/lib/bitclust/lineinput.rb +7 -5
  44. data/lib/bitclust/link_checker.rb +179 -0
  45. data/lib/bitclust/markdown_bridge.rb +186 -0
  46. data/lib/bitclust/markdown_orchestrator.rb +267 -0
  47. data/lib/bitclust/markdown_to_rrd.rb +824 -0
  48. data/lib/bitclust/markdown_tree.rb +217 -0
  49. data/lib/bitclust/mdcompiler.rb +883 -0
  50. data/lib/bitclust/mdparser.rb +347 -0
  51. data/lib/bitclust/messagecatalog.rb +3 -3
  52. data/lib/bitclust/method_since_calculator.rb +117 -0
  53. data/lib/bitclust/methoddatabase.rb +124 -14
  54. data/lib/bitclust/methodentry.rb +125 -7
  55. data/lib/bitclust/methodid.rb +12 -11
  56. data/lib/bitclust/methodsignature.rb +10 -4
  57. data/lib/bitclust/nameutils.rb +41 -22
  58. data/lib/bitclust/preprocessor.rb +66 -29
  59. data/lib/bitclust/rdcompiler.rb +195 -95
  60. data/lib/bitclust/refsdatabase.rb +23 -8
  61. data/lib/bitclust/reloadable_request_handler.rb +72 -0
  62. data/lib/bitclust/requesthandler.rb +21 -16
  63. data/lib/bitclust/ridatabase.rb +10 -4
  64. data/lib/bitclust/rrd_to_markdown.rb +925 -0
  65. data/lib/bitclust/rrdparser.rb +196 -30
  66. data/lib/bitclust/runner.rb +17 -2
  67. data/lib/bitclust/screen.rb +80 -11
  68. data/lib/bitclust/search_index_generator.rb +288 -0
  69. data/lib/bitclust/searcher.rb +69 -20
  70. data/lib/bitclust/simplesearcher.rb +24 -12
  71. data/lib/bitclust/subcommand.rb +7 -1
  72. data/lib/bitclust/subcommands/ancestors_command.rb +9 -2
  73. data/lib/bitclust/subcommands/checklink_command.rb +54 -0
  74. data/lib/bitclust/subcommands/chm_command.rb +15 -7
  75. data/lib/bitclust/subcommands/classes_command.rb +5 -0
  76. data/lib/bitclust/subcommands/extract_command.rb +5 -0
  77. data/lib/bitclust/subcommands/htmlfile_command.rb +21 -7
  78. data/lib/bitclust/subcommands/init_command.rb +4 -1
  79. data/lib/bitclust/subcommands/list_command.rb +12 -4
  80. data/lib/bitclust/subcommands/lookup_command.rb +28 -9
  81. data/lib/bitclust/subcommands/methods_command.rb +10 -2
  82. data/lib/bitclust/subcommands/methodsince_command.rb +80 -0
  83. data/lib/bitclust/subcommands/preproc_command.rb +5 -0
  84. data/lib/bitclust/subcommands/property_command.rb +2 -1
  85. data/lib/bitclust/subcommands/searchpage_command.rb +102 -0
  86. data/lib/bitclust/subcommands/server_command.rb +10 -8
  87. data/lib/bitclust/subcommands/setup_command.rb +24 -10
  88. data/lib/bitclust/subcommands/statichtml_command.rb +129 -6
  89. data/lib/bitclust/subcommands/update_command.rb +110 -2
  90. data/lib/bitclust/syntax_highlighter.rb +48 -4
  91. data/lib/bitclust/textutils.rb +3 -3
  92. data/lib/bitclust/version.rb +1 -1
  93. data/lib/bitclust/version_badges.rb +90 -0
  94. data/lib/bitclust/whole_file_gate.rb +137 -0
  95. data/test/test_app.rb +269 -0
  96. data/test/test_bitclust.rb +2 -0
  97. data/test/test_capi_converter.rb +91 -0
  98. data/test/test_class_screen.rb +413 -0
  99. data/test/test_copy_doc_md.rb +53 -0
  100. data/test/test_doc_converter.rb +78 -0
  101. data/test/test_entity_splitter.rb +231 -0
  102. data/test/test_entry.rb +207 -2
  103. data/test/test_eol_warning.rb +43 -0
  104. data/test/test_functionreferenceparser.rb +11 -0
  105. data/test/test_include_graph.rb +640 -0
  106. data/test/test_include_pruner.rb +133 -0
  107. data/test/test_link_checker.rb +114 -0
  108. data/test/test_lookup_command.rb +135 -0
  109. data/test/test_markdown_bridge.rb +217 -0
  110. data/test/test_markdown_orchestrator.rb +478 -0
  111. data/test/test_markdown_to_rrd.rb +757 -0
  112. data/test/test_markdown_tree.rb +369 -0
  113. data/test/test_mdcompiler.rb +1276 -0
  114. data/test/test_mdparser.rb +538 -0
  115. data/test/test_method_screen.rb +166 -0
  116. data/test/test_method_since_calculator.rb +290 -0
  117. data/test/test_methoddatabase.rb +16 -0
  118. data/test/test_methodentry.rb +328 -0
  119. data/test/test_methodsignature.rb +3 -1
  120. data/test/test_methodsince_command.rb +168 -0
  121. data/test/test_nameutils.rb +22 -0
  122. data/test/test_preprocessor.rb +215 -0
  123. data/test/test_rdcompiler.rb +401 -30
  124. data/test/test_refsdatabase.rb +32 -0
  125. data/test/test_rrd_to_markdown.rb +968 -0
  126. data/test/test_rrdparser.rb +295 -2
  127. data/test/test_run_ruby_wasm.rb +54 -0
  128. data/test/test_run_worker_prelude.rb +83 -0
  129. data/test/test_runner.rb +51 -0
  130. data/test/test_search_index_generator.rb +513 -0
  131. data/test/test_search_screen.rb +48 -0
  132. data/test/test_searcher.rb +132 -0
  133. data/test/test_searchpage_command.rb +167 -0
  134. data/test/test_simplesearcher.rb +28 -0
  135. data/test/test_statichtml_command.rb +204 -0
  136. data/test/test_syntax_highlighter.rb +60 -0
  137. data/test/test_whole_file_gate.rb +175 -0
  138. data/theme/default/js/NOTICE +42 -0
  139. data/theme/default/js/run-worker.js +111 -0
  140. data/theme/default/js/run.js +350 -0
  141. data/theme/default/js/search_controller.js +134 -0
  142. data/theme/default/js/search_init.js +176 -0
  143. data/theme/default/js/search_navigation.js +110 -0
  144. data/theme/default/js/search_page.js +202 -0
  145. data/theme/default/js/search_ranker.js +244 -0
  146. data/theme/default/script.js +91 -18
  147. data/theme/default/search.css +149 -0
  148. data/theme/default/style.css +193 -21
  149. data/theme/default/syntax-highlight.css +8 -0
  150. data/theme/lillia/style.css +45 -1
  151. metadata +161 -20
  152. data/README +0 -32
@@ -120,7 +120,11 @@
120
120
  [_('Instance Methods'), ents.instance_methods ],
121
121
  [_('Private Singleton Methods'), ents.private_singleton_methods ],
122
122
  [_('Private Instance Methods'), ents.private_instance_methods ],
123
+ [_('Protected Instance Methods'),ents.protected_instance_methods ],
123
124
  [_('Module Functions'), ents.module_functions ],
125
+ [_('Added Methods'), ents.added ],
126
+ [_('Redefined Methods'), ents.redefined ],
127
+ [_('Undefined Methods for Explanation'), ents.nomethod ],
124
128
  [_('Constants'), ents.constants ],
125
129
  [_('Special Variables'), ents.special_variables ,'$']] %>
126
130
  <%= headline(_("Index")) %>
@@ -146,17 +150,38 @@
146
150
 
147
151
  <%
148
152
  _myself, *ancestors = @entry.ancestors.reject { |c| %w[Object Kernel BasicObject].include?(c.name) }
149
- displayed_methods = Set.new(ents.instance_methods.flat_map(&:names))
153
+ displayed_instance_methods = Set.new((ents.instance_methods + ents.redefined.select(&:instance_method?)).flat_map(&:names))
154
+ displayed_singleton_methods = Set.new((ents.singleton_methods + ents.redefined.select(&:singleton_method?)).flat_map(&:names))
155
+ undefined_methods = @entry.partitioned_entries.undefined
156
+ undefined_instance_methods = undefined_methods.select(&:instance_method?)
157
+ undefined_singleton_methods = undefined_methods.select(&:singleton_method?)
150
158
  %>
151
159
 
152
160
  <% unless ancestors.empty? %>
153
161
  <%= headline(_("Ancestor Methods")) %>
154
162
  <dl>
163
+ <%# Singleton methods are inherited only through the superclass chain, not from included modules. %>
164
+ <% ancestors.select(&:class?).each do |c|
165
+ methods = c.partitioned_entries(@alevel).singleton_methods
166
+ .flat_map { |m| m.names.map { |n| [n, m] } }
167
+ .reject { |name,| displayed_singleton_methods.include?(name) }
168
+ .reject { |name,| undefined_singleton_methods.any? { |m| m.names.include?(name) } }
169
+ .sort
170
+ next if methods.empty? %>
171
+ <dt><%= _('Ancestor Singleton Methods %s', c.name) %></dt>
172
+ <dd>
173
+ <ul class="class-toc">
174
+ <% methods.each do |name, m| %>
175
+ <li><%= method_link(m.spec_string, name) %></li>
176
+ <% displayed_singleton_methods << name %>
177
+ <% end %>
178
+ </ul>
179
+ </dd>
180
+ <% end %>
155
181
  <% ancestors.each do |c|
156
- undefined_instance_methods = @entry.partitioned_entries.undefined.select(&:instance_method?)
157
182
  methods = c.partitioned_entries(@alevel).instance_methods
158
183
  .flat_map { |m| m.names.map { |n| [n, m] } }
159
- .reject { |name,| displayed_methods.include?(name) }
184
+ .reject { |name,| displayed_instance_methods.include?(name) }
160
185
  .reject { |name,| undefined_instance_methods.any? { |m| m.names.include?(name) } }
161
186
  .sort
162
187
  next if methods.empty? %>
@@ -165,7 +190,7 @@ displayed_methods = Set.new(ents.instance_methods.flat_map(&:names))
165
190
  <ul class="class-toc">
166
191
  <% methods.each do |name, m| %>
167
192
  <li><%= method_link(m.spec_string, name) %></li>
168
- <% displayed_methods << name %>
193
+ <% displayed_instance_methods << name %>
169
194
  <% end %>
170
195
  </ul>
171
196
  </dd>
@@ -174,6 +199,25 @@ displayed_methods = Set.new(ents.instance_methods.flat_map(&:names))
174
199
  end %>
175
200
  </dl>
176
201
 
202
+ <%
203
+ dyninc_groups = @entry.dynamically_included_entries.group_by(&:klass)
204
+ %>
205
+ <% unless dyninc_groups.empty? %>
206
+ <%= headline(_("Methods Added by Dynamic Include")) %>
207
+ <dl>
208
+ <% dyninc_groups.each do |mod, mod_entries| %>
209
+ <dt><%= mod.name %> (by <%= mod.library.name %>)</dt>
210
+ <dd>
211
+ <ul class="class-toc">
212
+ <% mod_entries.each do |m| %>
213
+ <li><%= method_link(m.spec_string, m.name) %></li>
214
+ <% end %>
215
+ </ul>
216
+ </dd>
217
+ <% end %>
218
+ </dl>
219
+ <% end %>
220
+
177
221
  <%
178
222
  items.each do |label, entries|
179
223
  unless entries.empty? %>
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  entry = @entry
3
- @title = "#{entry.type_label} #{entry.label}"
3
+ @title = "#{entry.type_label} #{entry.display_label}"
4
4
  @description = @entry.description
5
5
  @edit_url = edit_url(@entry.source_location) if @conf[:edit_base_url] && @entry.source_location
6
6
  %>
@@ -41,7 +41,7 @@
41
41
  </ol>
42
42
  </nav>
43
43
  <% headline_init %>
44
- <%= headline("#{entry.type_label} #{entry.label}", edit_url: @edit_url) %>
44
+ <%= headline("#{entry.type_label} #{entry.display_label}", edit_url: @edit_url) %>
45
45
  </header>
46
46
 
47
47
  <main>
@@ -7,6 +7,7 @@
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1">
8
8
  <link rel="stylesheet" href="<%=h css_url() %>">
9
9
  <link rel="stylesheet" href="<%=h custom_css_url("syntax-highlight.css") %>">
10
+ <link rel="stylesheet" href="<%=h custom_css_url("search.css") %>">
10
11
  <link rel="icon" type="image/png" href="<%=h favicon_url() %>">
11
12
  <% if @conf[:canonical_base_url] %>
12
13
  <link rel="canonical" href="<%= canonical_url() %>">
@@ -14,13 +15,36 @@
14
15
  <title><%=h @title %> (Ruby <%=h ruby_version %> リファレンスマニュアル)</title>
15
16
  <meta name="description" content="<%=h @description %>">
16
17
  <script src="<%=h custom_js_url('script.js') %>"></script>
18
+ <script>var index_rel_prefix = "<%=h html_base() %>/";</script>
19
+ <script src="<%=h custom_js_url('js/search_data.js') %>"></script>
20
+ <script src="<%=h custom_js_url('js/search_navigation.js') %>"></script>
21
+ <script src="<%=h custom_js_url('js/search_ranker.js') %>"></script>
22
+ <script src="<%=h custom_js_url('js/search_controller.js') %>"></script>
23
+ <script src="<%=h custom_js_url('js/search_init.js') %>"></script>
24
+ <% if run_ruby_wasm_url %>
25
+ <meta name="rurema-run-ruby-wasm" content="<%=h run_ruby_wasm_url %>">
26
+ <script type="module" src="<%=h custom_js_url('js/run.js') %>"></script>
27
+ <% end %>
17
28
  </head>
18
29
  <body>
30
+ <% if eol_warning?() %>
31
+ <p class="eol-warning">
32
+ <%= _('This reference manual is for a version of Ruby that is no longer maintained.') %>
33
+ <a href="https://docs.ruby-lang.org/ja/latest/"><%= _('Latest version') %></a>
34
+ </p>
35
+ <% end %>
36
+ <div id="rurema-topbar">
37
+ <div id="rurema-brand"><%= manual_home_link %></div>
38
+ <div id="search-section" role="search">
39
+ <input id="search-field" type="text" autocomplete="off" spellcheck="false"
40
+ placeholder="クラス・メソッドを検索 (/)"
41
+ aria-label="検索" aria-autocomplete="list" aria-controls="search-results">
42
+ <ul id="search-results" class="search-results" aria-expanded="false"></ul>
43
+ </div>
44
+ </div>
19
45
  <%= yield %>
20
46
  <footer id="footer">
21
- <a rel="license" href="https://creativecommons.org/licenses/by/3.0/">
22
- <img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/3.0/88x31.png" />
23
- </a>
47
+ <a rel="license" href="https://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/3.0/88x31.png" /></a>
24
48
 
25
49
  <a href="https://github.com/rurema/doctree/issues/new" id="feedback-link">フィードバックを送る</a>
26
50
  <% if defined?(@edit_url) && @edit_url %>
@@ -1,6 +1,6 @@
1
1
  <%
2
2
  entry = @entries.sort.first
3
- @title = entry.label
3
+ @title = entry.display_title_labels.join(', ')
4
4
  @description = entry.description
5
5
  @edit_url = edit_url(entry.source_location) if @conf[:edit_base_url] && entry.source_location
6
6
  %>
@@ -55,7 +55,7 @@
55
55
  </ol>
56
56
  </nav>
57
57
  <% headline_init %>
58
- <%= headline("#{entry.type_label} #{entry.label}") %>
58
+ <%= headline("#{entry.type_label} #{entry.display_label}") %>
59
59
  </header>
60
60
 
61
61
  <main>
data/lib/bitclust/app.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
  require 'bitclust'
3
3
  require 'bitclust/interface'
4
+ require 'bitclust/reloadable_request_handler'
4
5
 
5
6
  module BitClust
6
7
 
7
8
  # Main class of BitClust server application.
8
- # Actual actions are implemneted by RequestHandler.
9
+ # Actual actions are implemented by RequestHandler.
9
10
  #
10
11
  # Supports Rack and WEBrick.
11
12
  class App
@@ -26,11 +27,8 @@ module BitClust
26
27
  @interfaces = {}
27
28
  case dbpath
28
29
  when String
30
+ # @type var viewpath: String
29
31
  dbpath = File.expand_path(dbpath)
30
- db = BitClust::MethodDatabase.new(dbpath)
31
- if capi
32
- db = [db, BitClust::FunctionDatabase.new(dbpath)]
33
- end
34
32
  manager = BitClust::ScreenManager.new(
35
33
  :base_url => baseurl,
36
34
  :cgi_url => File.join(baseurl, viewpath),
@@ -39,25 +37,22 @@ module BitClust
39
37
  :theme => options[:theme],
40
38
  :encoding => encoding
41
39
  )
42
- handler = request_handler_class.new(db, manager)
40
+ handler = BitClust::ReloadableRequestHandler.new(dbpath, capi, manager, request_handler_class)
43
41
  @interfaces[viewpath] = BitClust::Interface.new { handler }
44
42
  when Array
43
+ # @type var viewpath: String?
45
44
  dbpaths = dbpath
46
45
  @versions = []
47
46
  dbpaths.each do |dbpath|
48
47
  next unless /db-([\d_\.]+)/ =~ dbpath
49
48
  dbpath = File.expand_path(dbpath)
50
- version = $1.tr("_", ".")
49
+ version = ($1 || raise).tr("_", ".")
51
50
  @versions << version
52
51
  if viewpath
53
52
  version_viewpath = File.join(version, viewpath)
54
53
  else
55
54
  version_viewpath = version
56
55
  end
57
- db = BitClust::MethodDatabase.new(dbpath)
58
- if capi
59
- db = [db, BitClust::FunctionDatabase.new(dbpath)]
60
- end
61
56
  manager = BitClust::ScreenManager.new(
62
57
  :base_url => baseurl,
63
58
  :cgi_url => File.join(baseurl, version_viewpath),
@@ -66,7 +61,7 @@ module BitClust
66
61
  :theme => options[:theme],
67
62
  :encoding => encoding
68
63
  )
69
- handler = request_handler_class.new(db, manager)
64
+ handler = BitClust::ReloadableRequestHandler.new(dbpath, capi, manager, request_handler_class)
70
65
  @interfaces[version_viewpath] = BitClust::Interface.new { handler }
71
66
  $bitclust_context_cache = nil # clear cache
72
67
  end
@@ -88,13 +83,15 @@ module BitClust
88
83
  req.path_info
89
84
  end
90
85
  if @versions.any?{|version| %r|\A/?#{version}/?\z| =~ request_path }
91
- viewpath = File.join(request_path, @options[:viewpath])
86
+ viewpath = @options[:viewpath]
87
+ raise unless viewpath.is_a?(String)
88
+ viewpath = File.join(request_path || raise, viewpath)
92
89
  @index = "<html><head><meta http-equiv='Refresh' content='0;URL=#{viewpath}'></head></html>"
93
90
  else
94
91
  links = "<ul>"
95
92
  @interfaces.keys.sort.each do |v|
96
- if @options[:viewpath]
97
- version = v.sub(@options[:viewpath], '')
93
+ if (viewpath = @options[:viewpath]).is_a?(String)
94
+ version = v.sub(viewpath, '')
98
95
  else
99
96
  version = v
100
97
  end
@@ -108,15 +105,17 @@ module BitClust
108
105
  @index = "<html><head><title>bitclust</title></head><body>#{links}</body></html>"
109
106
  end
110
107
  end
108
+ else
109
+ raise '[BUG]'
111
110
  end
112
111
  end
113
112
 
114
- def get_instance(server)
113
+ def get_instance(_server, *_)
115
114
  self
116
115
  end
117
116
 
118
117
  def service(req, res)
119
- unless %r|/#{File.basename(@options[:baseurl])}/?\z| =~ req.path
118
+ unless %r|/#{File.basename(@options[:baseurl] || raise)}/?\z| =~ req.path
120
119
  raise WEBrick::HTTPStatus::NotFound
121
120
  end
122
121
  res.body = index(req)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bitclust/rrd_to_markdown'
4
+
5
+ module BitClust
6
+ # refm/capi(C API リファレンス)の Markdown 変換。
7
+ #
8
+ # capi の構造は「--- シグネチャ + 本文」の列のみで、見出し・include・
9
+ # ライブラリ等のクロスファイル情報が無い(FunctionReferenceParser 参照)。
10
+ # front matter は使わず、シグネチャは capi モードの変換
11
+ # 「--- <C sig>」↔「### <C sig>」(def 等のキーワード無し。C の
12
+ # シグネチャは型から始まるため自己記述的)で表す。本文の記法は api と共通。
13
+ module CapiConverter
14
+ module_function
15
+
16
+ def convert(rrd)
17
+ RRDToMarkdown.convert(rrd, capi: true)
18
+ end
19
+ end
20
+ end
@@ -79,7 +79,7 @@ module BitClust
79
79
  end
80
80
 
81
81
  persistent_properties {
82
- property :type, 'Symbol' # :class | :module | :object
82
+ property :type, 'Symbol' ## :class | :module | :object
83
83
  property :superclass, 'ClassEntry'
84
84
  property :included, '[ClassEntry]'
85
85
  property :extended, '[ClassEntry]'
@@ -217,8 +217,10 @@ module BitClust
217
217
  [ myself, included().map {|m| m.ancestors },
218
218
  ancestors ].flatten
219
219
  else
220
+ # steep:ignore:start
220
221
  [ self, included().map {|m| m.ancestors },
221
222
  superclass() ? superclass().ancestors : [] ].flatten
223
+ # steep:ignore:end
222
224
  end
223
225
  end
224
226
 
@@ -228,6 +230,24 @@ module BitClust
228
230
  list
229
231
  end
230
232
 
233
+ # Public instance methods contributed by modules that are dynamically
234
+ # included into this class (via `# reopen` + `include:`/`include`).
235
+ #
236
+ # Unlike +included+, +dynamically_included+ does not affect +ancestors+
237
+ # or the method resolution order, so these methods are never returned by
238
+ # +entries+/+partitioned_entries+. This method exists so that screens and
239
+ # templates can list them separately, attributed to the module (and its
240
+ # library) that defines them, without disturbing the MRO.
241
+ #
242
+ # Only each module's own public instance methods are returned (i.e. its
243
+ # +entries(0)+ filtered like +public_instance_methods+); methods that the
244
+ # dynamically included module itself inherits are not followed. If no
245
+ # module has been dynamically included, this returns an empty array, so
246
+ # output for classes without dynamic include is unaffected.
247
+ def dynamically_included_entries
248
+ dynamically_included().flat_map {|m| m.public_instance_methods(0) }
249
+ end
250
+
231
251
  def extended_modules
232
252
  ancestors().select(&:class?).map(&:extended).flatten
233
253
  end
@@ -235,8 +255,8 @@ module BitClust
235
255
  def entries(level = 0)
236
256
  @entries ||= @db.entries("method/#{@id}")\
237
257
  .map {|ent| MethodEntry.new(@db, "#{@id}/#{ent}") }
238
- ret = @entries
239
- ancestors[1..level].each{|c| ret += c.entries }
258
+ ret = @entries || raise
259
+ (ancestors[1..level] || raise).each{|c| ret += c.entries }
240
260
  ret
241
261
  end
242
262
 
@@ -252,26 +272,43 @@ module BitClust
252
272
  end
253
273
 
254
274
  Parts = Struct.new(:singleton_methods, :private_singleton_methods,
255
- :instance_methods, :private_instance_methods,
275
+ :instance_methods, :private_instance_methods, :protected_instance_methods,
256
276
  :module_functions,
257
277
  :constants, :special_variables,
258
- :added, :undefined)
278
+ :redefined,
279
+ :added, :undefined, :nomethod)
259
280
 
260
281
  def partitioned_entries(level = 0)
282
+ # @type var s: Array[MethodEntry]
283
+ # @type var spv: Array[MethodEntry]
284
+ # @type var i: Array[MethodEntry]
285
+ # @type var ipv: Array[MethodEntry]
286
+ # @type var ipt: Array[MethodEntry]
287
+ # @type var mf: Array[MethodEntry]
288
+ # @type var c: Array[MethodEntry]
289
+ # @type var v: Array[MethodEntry]
290
+ # @type var redefined: Array[MethodEntry]
291
+ # @type var added: Array[MethodEntry]
292
+ # @type var undefined: Array[MethodEntry]
293
+ # @type var nomethod: Array[MethodEntry]
261
294
  s = []; spv = []
262
- i = []; ipv = []
295
+ i = []; ipv = []; ipt = []
263
296
  mf = []
264
297
  c = []; v = []
298
+ redefined = []
265
299
  added = []
266
300
  undefined = []
301
+ nomethod = []
267
302
  entries(level).sort_by(&:name).each do |m|
268
303
  case m.kind
269
- when :defined, :redefined
304
+ when :defined
270
305
  case m.type
271
306
  when :singleton_method
272
307
  (m.public? ? s : spv).push m
273
308
  when :instance_method
274
- (m.public? ? i : ipv).push m
309
+ tmp = m.public? ? i : ipv
310
+ tmp = ipt if m.protected?
311
+ tmp.push m
275
312
  when :module_function
276
313
  mf.push m
277
314
  when :constant
@@ -281,13 +318,19 @@ module BitClust
281
318
  else
282
319
  raise "must not happen: m.type=#{m.type.inspect} (#{m.inspect})"
283
320
  end
321
+ when :redefined
322
+ redefined.push m
284
323
  when :added
285
324
  added.push m
286
325
  when :undefined
287
326
  undefined.push m
327
+ when :nomethod
328
+ nomethod.push m
288
329
  end
289
330
  end
290
- Parts.new(s,spv, i,ipv, mf, c, v, added, undefined)
331
+ # steep:ignore:start
332
+ Parts.new(s,spv, i,ipv,ipt, mf, c, v, redefined, added, undefined, nomethod)
333
+ # steep:ignore:end
291
334
  end
292
335
 
293
336
  def singleton_methods(level = 0)
@@ -322,6 +365,10 @@ module BitClust
322
365
 
323
366
  alias private_methods private_instance_methods
324
367
 
368
+ def protected_instance_methods(level = 0)
369
+ entries(level).select(&:protected_instance_method?).sort_by(&:sort_key)
370
+ end
371
+
325
372
  def constants(level = 0)
326
373
  entries(level).select(&:constant?).sort_by(&:sort_key)
327
374
  end
@@ -334,7 +381,7 @@ module BitClust
334
381
  if inherit
335
382
  _smap().key?(name)
336
383
  else
337
- singleton_methods(false).detect {|m| m.name?(name) }
384
+ singleton_methods(0).detect {|m| m.name?(name) }
338
385
  end
339
386
  end
340
387
 
@@ -342,7 +389,7 @@ module BitClust
342
389
  if inherit
343
390
  _imap().key?(name)
344
391
  else
345
- instance_methods(false).detect {|m| m.name?(name) }
392
+ instance_methods(0).detect {|m| m.name?(name) }
346
393
  end
347
394
  end
348
395
 
@@ -350,7 +397,7 @@ module BitClust
350
397
  if inherit
351
398
  ancestors().any? {|c| c.constant?(name, false) }
352
399
  else
353
- constants(false).detect {|m| m.name?(name) }
400
+ constants(0).detect {|m| m.name?(name) }
354
401
  end
355
402
  end
356
403
 
@@ -383,15 +430,15 @@ module BitClust
383
430
 
384
431
  def singleton_method_names
385
432
  # should remove module functions?
386
- _index().keys.select {|name| /\A\./ =~ name }.map {|name| name[1..-1] }
433
+ _index().keys.select {|name| /\A\./ =~ name }.filter_map {|name| name[1..-1] }
387
434
  end
388
435
 
389
436
  def instance_method_names
390
- _index().keys.select {|name| /\A\#/ =~ name }.map {|name| name[1..-1] }
437
+ _index().keys.select {|name| /\A\#/ =~ name }.filter_map {|name| name[1..-1] }
391
438
  end
392
439
 
393
440
  def constant_names
394
- _index().keys.select {|name| /\A\:/ =~ name }.map {|name| name[1..-1] }
441
+ _index().keys.select {|name| /\A\:/ =~ name }.filter_map {|name| name[1..-1] }
395
442
  end
396
443
 
397
444
  def special_variable_names
@@ -405,7 +452,7 @@ module BitClust
405
452
  end
406
453
 
407
454
  def description
408
- source.split(/\n\n+/, 2)[0].strip
455
+ description_text(source.split(/\n\n+/, 2)[0].strip)
409
456
  end
410
457
 
411
458
  def clear_cache
@@ -434,11 +481,12 @@ module BitClust
434
481
  return aliasof().__send__("_#{typechar}map").dup
435
482
  end
436
483
  s = superclass()
484
+ # @type var map: Hash[String, String]
437
485
  map = s ? s.__send__("_#{typechar}map").dup : {}
438
486
  inherited_modules.each do |mod|
439
487
  map.update mod.__send__("_#{typechar == 'c' ? 'c' : 'i'}map")
440
488
  end
441
- defined, undefined = *ents.partition {|m| m.defined? }
489
+ defined, undefined = ents.partition {|m| m.defined? }
442
490
  (undefined + defined).each do |m|
443
491
  m.names.each do |name|
444
492
  map[name] = m.spec_string
@@ -465,9 +513,11 @@ module BitClust
465
513
  def _index
466
514
  @_index ||=
467
515
  begin
516
+ # @type var h: Hash[String, String]
468
517
  h = {}
469
518
  @db.foreach_line("method/#{@id}/=index") do |line|
470
519
  name, spec = line.split
520
+ name || raise; spec || raise
471
521
  h[name] = spec
472
522
  end
473
523
  h
@@ -38,7 +38,7 @@ end
38
38
  def fopen(*args, &block)
39
39
  option = args[1]
40
40
  if option and !Object.const_defined?(:Encoding)
41
- args[1] = option.sub(/:.*\z/, '')
41
+ args[1] = option.sub(/:.*\z/, '') # steep:ignore
42
42
  end
43
- File.open(*args, &block)
43
+ File.open(*args, &block) # steep:ignore
44
44
  end