docscribe 1.4.2 → 1.5.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/README.md +465 -130
- data/lib/docscribe/cli/check_for_comments.rb +183 -0
- data/lib/docscribe/cli/config_builder.rb +107 -53
- data/lib/docscribe/cli/formatters/json.rb +294 -0
- data/lib/docscribe/cli/formatters/sarif.rb +235 -0
- data/lib/docscribe/cli/formatters/text.rb +208 -0
- data/lib/docscribe/cli/formatters.rb +26 -0
- data/lib/docscribe/cli/generate.rb +45 -45
- data/lib/docscribe/cli/init.rb +14 -6
- data/lib/docscribe/cli/options.rb +190 -88
- data/lib/docscribe/cli/rbs_gen.rb +529 -0
- data/lib/docscribe/cli/run.rb +210 -152
- data/lib/docscribe/cli/sigs.rb +366 -0
- data/lib/docscribe/cli/update_types.rb +103 -0
- data/lib/docscribe/cli.rb +21 -13
- data/lib/docscribe/config/defaults.rb +5 -1
- data/lib/docscribe/config/emit.rb +17 -0
- data/lib/docscribe/config/filtering.rb +18 -25
- data/lib/docscribe/config/loader.rb +15 -11
- data/lib/docscribe/config/plugin.rb +1 -1
- data/lib/docscribe/config/rbs.rb +41 -9
- data/lib/docscribe/config/sorbet.rb +9 -12
- data/lib/docscribe/config/sorting.rb +1 -1
- data/lib/docscribe/config/template.rb +9 -1
- data/lib/docscribe/config/utils.rb +11 -9
- data/lib/docscribe/config.rb +2 -4
- data/lib/docscribe/infer/ast_walk.rb +1 -1
- data/lib/docscribe/infer/literals.rb +6 -11
- data/lib/docscribe/infer/names.rb +2 -3
- data/lib/docscribe/infer/params.rb +15 -17
- data/lib/docscribe/infer/raises.rb +3 -5
- data/lib/docscribe/infer/returns.rb +542 -140
- data/lib/docscribe/infer.rb +22 -23
- data/lib/docscribe/inline_rewriter/collector.rb +159 -164
- data/lib/docscribe/inline_rewriter/doc_block.rb +145 -115
- data/lib/docscribe/inline_rewriter/doc_builder.rb +1026 -723
- data/lib/docscribe/inline_rewriter/source_helpers.rb +49 -49
- data/lib/docscribe/inline_rewriter/tag_sorter.rb +82 -85
- data/lib/docscribe/inline_rewriter.rb +495 -492
- data/lib/docscribe/parsing.rb +29 -10
- data/lib/docscribe/plugin/base/collector_plugin.rb +2 -1
- data/lib/docscribe/plugin/base/tag_plugin.rb +0 -1
- data/lib/docscribe/plugin/context.rb +28 -18
- data/lib/docscribe/plugin/registry.rb +26 -27
- data/lib/docscribe/plugin/tag.rb +9 -14
- data/lib/docscribe/plugin.rb +17 -16
- data/lib/docscribe/types/provider_chain.rb +4 -2
- data/lib/docscribe/types/rbs/collection_loader.rb +2 -2
- data/lib/docscribe/types/rbs/provider.rb +60 -44
- data/lib/docscribe/types/rbs/type_formatter.rb +224 -83
- data/lib/docscribe/types/signature.rb +22 -42
- data/lib/docscribe/types/sorbet/base_provider.rb +24 -19
- data/lib/docscribe/types/sorbet/rbi_provider.rb +3 -3
- data/lib/docscribe/types/sorbet/source_provider.rb +3 -2
- data/lib/docscribe/types/yard/formatter.rb +100 -0
- data/lib/docscribe/types/yard/parser.rb +240 -0
- data/lib/docscribe/types/yard/types.rb +52 -0
- data/lib/docscribe/version.rb +1 -1
- metadata +33 -1
|
@@ -34,15 +34,13 @@ module Docscribe
|
|
|
34
34
|
# - `rewrite: true` maps to `strategy: :aggressive`
|
|
35
35
|
module InlineRewriter
|
|
36
36
|
class << self
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
# This is the main convenience entry point for library usage.
|
|
37
|
+
# Insert comments
|
|
40
38
|
#
|
|
41
39
|
# @param [String] code Ruby source
|
|
42
|
-
# @param [Symbol
|
|
43
|
-
# @param [Boolean
|
|
44
|
-
# @param [Boolean
|
|
45
|
-
# @param [
|
|
40
|
+
# @param [Symbol?] strategy :safe or :aggressive
|
|
41
|
+
# @param [Boolean?] rewrite compatibility alias for aggressive strategy
|
|
42
|
+
# @param [Boolean?] merge compatibility alias for safe strategy
|
|
43
|
+
# @param [Object] options additional keyword arguments forwarded to rewrite_with_report
|
|
46
44
|
# @return [String]
|
|
47
45
|
def insert_comments(code, strategy: nil, rewrite: nil, merge: nil, **options)
|
|
48
46
|
strategy = normalize_strategy(strategy: strategy, rewrite: rewrite, merge: merge)
|
|
@@ -50,17 +48,14 @@ module Docscribe
|
|
|
50
48
|
rewrite_with_report(code, strategy: strategy, **options)[:output]
|
|
51
49
|
end
|
|
52
50
|
|
|
53
|
-
# Rewrite
|
|
51
|
+
# Rewrite with report
|
|
54
52
|
#
|
|
55
53
|
# @param [String] code Ruby source
|
|
56
|
-
# @param [Symbol
|
|
57
|
-
# @param [Boolean
|
|
58
|
-
# @param [Boolean
|
|
59
|
-
# @param [
|
|
60
|
-
# @
|
|
61
|
-
# @raise [Docscribe::ParseError]
|
|
62
|
-
# @raise [StandardError]
|
|
63
|
-
# @return [Hash]
|
|
54
|
+
# @param [Symbol?] strategy :safe or :aggressive
|
|
55
|
+
# @param [Boolean?] rewrite compatibility alias for aggressive strategy
|
|
56
|
+
# @param [Boolean?] merge compatibility alias for safe strategy
|
|
57
|
+
# @param [Object] options additional keyword arguments forwarded to downstream helpers
|
|
58
|
+
# @return [Hash<Symbol, String, Array<Hash<Symbol, Object>>>]
|
|
64
59
|
def rewrite_with_report(code, strategy: nil, rewrite: nil, merge: nil, **options)
|
|
65
60
|
strategy = normalize_strategy(strategy: strategy, rewrite: rewrite, merge: merge)
|
|
66
61
|
validate_strategy!(strategy)
|
|
@@ -73,16 +68,16 @@ module Docscribe
|
|
|
73
68
|
{ output: pipeline[:rewriter].process, changes: pipeline[:changes] }
|
|
74
69
|
end
|
|
75
70
|
|
|
76
|
-
# Build
|
|
71
|
+
# Build rewrite pipeline
|
|
77
72
|
#
|
|
78
|
-
# @param [
|
|
79
|
-
# @param [
|
|
80
|
-
# @return [Hash]
|
|
73
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
74
|
+
# @param [Parser::AST::Node] ast the parsed AST of the source code
|
|
75
|
+
# @return [Hash<Symbol, Object>]
|
|
81
76
|
def build_rewrite_pipeline(buffer, ast)
|
|
82
77
|
all = collect_insertions(buffer, ast)
|
|
83
78
|
method_overrides_by_pos = {} #: Hash[Integer, untyped]
|
|
84
79
|
all = deduplicate_insertions(all, method_overrides_by_pos: method_overrides_by_pos)
|
|
85
|
-
rewriter = Parser::Source::TreeRewriter.new(buffer)
|
|
80
|
+
rewriter = Parser::Source::TreeRewriter.new(buffer) # steep:ignore
|
|
86
81
|
merge_inserts = Hash.new { |h, k| h[k] = [] } #: Hash[Integer, untyped]
|
|
87
82
|
changes = [] #: Array[untyped]
|
|
88
83
|
|
|
@@ -90,32 +85,28 @@ module Docscribe
|
|
|
90
85
|
merge_inserts: merge_inserts, changes: changes }
|
|
91
86
|
end
|
|
92
87
|
|
|
93
|
-
# Dispatch
|
|
88
|
+
# Dispatch rewrite insertions
|
|
94
89
|
#
|
|
95
|
-
# @param [Object] pipeline the pipeline hash with rewriter, insertions, and tracking state
|
|
96
|
-
# @param [
|
|
97
|
-
# @param [
|
|
98
|
-
# @return [
|
|
90
|
+
# @param [Hash<Symbol, Object>] pipeline the pipeline hash with rewriter, insertions, and tracking state
|
|
91
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
92
|
+
# @param [Object] options additional kwargs (config, signature_provider, core_rbs_provider, strategy, file)
|
|
93
|
+
# @return [void]
|
|
99
94
|
def dispatch_rewrite_insertions(pipeline, buffer, **options)
|
|
100
95
|
pipeline[:all].sort_by { |(kind, ins)| plugin_insertion_pos(kind, ins) }
|
|
101
96
|
.reverse_each do |kind, ins|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
when :attr then dispatch_attr_insertion(ins, pipeline, buffer, **options)
|
|
105
|
-
when :plugin then dispatch_plugin_insertion(ins, pipeline, buffer, **options)
|
|
106
|
-
end
|
|
97
|
+
method_name = :"dispatch_#{kind}_insertion"
|
|
98
|
+
send(method_name, ins, pipeline, buffer, **options) if respond_to?(method_name, true)
|
|
107
99
|
end
|
|
108
100
|
|
|
109
101
|
apply_merge_inserts!(rewriter: pipeline[:rewriter], buffer: buffer, merge_inserts: pipeline[:merge_inserts])
|
|
110
102
|
end
|
|
111
103
|
|
|
112
|
-
# Dispatch
|
|
104
|
+
# Dispatch method insertion
|
|
113
105
|
#
|
|
114
|
-
# @
|
|
115
|
-
# @param [Object]
|
|
116
|
-
# @param [
|
|
117
|
-
# @param [Object]
|
|
118
|
-
# @param [Hash] options
|
|
106
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] ins the attribute insertion object
|
|
107
|
+
# @param [Hash<Symbol, Object>] pipeline the pipeline hash with rewriter, insertions, and tracking state
|
|
108
|
+
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
109
|
+
# @param [Object] options the full keyword options hash
|
|
119
110
|
# @return [void]
|
|
120
111
|
def dispatch_method_insertion(ins, pipeline, buffer, **options)
|
|
121
112
|
pos = plugin_insertion_pos(:method, ins)
|
|
@@ -130,13 +121,12 @@ module Docscribe
|
|
|
130
121
|
)
|
|
131
122
|
end
|
|
132
123
|
|
|
133
|
-
# Dispatch
|
|
124
|
+
# Dispatch attr insertion
|
|
134
125
|
#
|
|
135
|
-
# @
|
|
136
|
-
# @param [Object]
|
|
137
|
-
# @param [
|
|
138
|
-
# @param [Object]
|
|
139
|
-
# @param [Hash] options
|
|
126
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
127
|
+
# @param [Hash<Symbol, Object>] pipeline the pipeline hash with rewriter, insertions, and tracking state
|
|
128
|
+
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
129
|
+
# @param [Object] options the full keyword options hash
|
|
140
130
|
# @return [void]
|
|
141
131
|
def dispatch_attr_insertion(ins, pipeline, buffer, **options)
|
|
142
132
|
apply_attr_insertion!(
|
|
@@ -146,13 +136,12 @@ module Docscribe
|
|
|
146
136
|
)
|
|
147
137
|
end
|
|
148
138
|
|
|
149
|
-
# Dispatch
|
|
139
|
+
# Dispatch plugin insertion
|
|
150
140
|
#
|
|
151
|
-
# @
|
|
152
|
-
# @param [Object]
|
|
153
|
-
# @param [
|
|
154
|
-
# @param [Object]
|
|
155
|
-
# @param [Hash] options
|
|
141
|
+
# @param [Hash<Symbol, Object>] ins the attribute insertion object
|
|
142
|
+
# @param [Hash<Symbol, Object>] pipeline the pipeline hash with rewriter, insertions, and tracking state
|
|
143
|
+
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
144
|
+
# @param [Object] options the full keyword options hash
|
|
156
145
|
# @return [void]
|
|
157
146
|
def dispatch_plugin_insertion(ins, pipeline, buffer, **options)
|
|
158
147
|
apply_plugin_insertion!(
|
|
@@ -163,12 +152,13 @@ module Docscribe
|
|
|
163
152
|
|
|
164
153
|
private
|
|
165
154
|
|
|
166
|
-
# Setup
|
|
155
|
+
# Setup rewrite env
|
|
156
|
+
#
|
|
167
157
|
# @private
|
|
168
|
-
# @param [
|
|
169
|
-
# @param [Object] options hash containing :config, :file, and :core_rbs_provider
|
|
158
|
+
# @param [String] code the Ruby source code string to parse and rewrite
|
|
159
|
+
# @param [Hash<Symbol, Object>] options hash containing :config, :file, and :core_rbs_provider
|
|
170
160
|
# @raise [Docscribe::ParseError]
|
|
171
|
-
# @return [Hash]
|
|
161
|
+
# @return [Hash<Symbol, Docscribe::Config, String, Parser::Source::Buffer, Parser::AST::Node, Docscribe::Types::ProviderChain, nil, Object, nil>]
|
|
172
162
|
def setup_rewrite_env(code, options)
|
|
173
163
|
config = options[:config] || Docscribe::Config.load
|
|
174
164
|
file = (options[:file] || '(inline)').to_s
|
|
@@ -182,13 +172,13 @@ module Docscribe
|
|
|
182
172
|
core_rbs_provider: load_core_rbs_provider(config, core_rbs_provider) }
|
|
183
173
|
end
|
|
184
174
|
|
|
185
|
-
# Load core
|
|
175
|
+
# Load core rbs provider
|
|
186
176
|
#
|
|
187
177
|
# @private
|
|
188
|
-
# @param [
|
|
189
|
-
# @param [Object] core_rbs_provider optional externally-provided core RBS provider
|
|
178
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
179
|
+
# @param [Object, nil] core_rbs_provider optional externally-provided core RBS provider
|
|
190
180
|
# @raise [StandardError]
|
|
191
|
-
# @return [Object]
|
|
181
|
+
# @return [Object, nil] if StandardError
|
|
192
182
|
# @return [nil] if StandardError
|
|
193
183
|
def load_core_rbs_provider(config, core_rbs_provider)
|
|
194
184
|
core_rbs_provider || (config.respond_to?(:core_rbs_provider) ? config.core_rbs_provider : nil)
|
|
@@ -197,11 +187,12 @@ module Docscribe
|
|
|
197
187
|
nil
|
|
198
188
|
end
|
|
199
189
|
|
|
200
|
-
# Collect insertions
|
|
190
|
+
# Collect insertions
|
|
191
|
+
#
|
|
201
192
|
# @private
|
|
202
|
-
# @param [
|
|
203
|
-
# @param [
|
|
204
|
-
# @return [Object]
|
|
193
|
+
# @param [Parser::Source::Buffer] buffer the source buffer to collect insertions from
|
|
194
|
+
# @param [Parser::AST::Node] ast the parsed AST to traverse for collection
|
|
195
|
+
# @return [Array<Object>]
|
|
205
196
|
def collect_insertions(buffer, ast)
|
|
206
197
|
collector = Docscribe::InlineRewriter::Collector.new(buffer)
|
|
207
198
|
collector.process(ast)
|
|
@@ -213,33 +204,28 @@ module Docscribe
|
|
|
213
204
|
plugin_insertions.map { |i| [:plugin, i] }
|
|
214
205
|
end
|
|
215
206
|
|
|
216
|
-
# Deduplicate insertions
|
|
217
|
-
#
|
|
218
|
-
# Rules:
|
|
219
|
-
# 1. Plugin insertions override method insertions at the same position
|
|
220
|
-
# (CollectorPlugin knows more than the standard collector for that node).
|
|
221
|
-
# 2. If multiple CollectorPlugins target the same position, only insertions
|
|
222
|
-
# from the highest priority plugin(s) are kept (ties are kept).
|
|
223
|
-
# 3. Multiple plugin insertions at the same position are allowed
|
|
224
|
-
# (a single plugin may generate multiple doc blocks, e.g. one per column).
|
|
207
|
+
# Deduplicate insertions
|
|
225
208
|
#
|
|
226
209
|
# @private
|
|
227
|
-
# @param [Array<
|
|
228
|
-
# @param [nil] method_overrides_by_pos method-level overrides keyed
|
|
229
|
-
#
|
|
210
|
+
# @param [Array<(Symbol, Object)>] insertions insertions to deduplicate
|
|
211
|
+
# @param [Hash<Integer, Hash<Symbol, Object>>, nil?] method_overrides_by_pos method-level overrides keyed
|
|
212
|
+
# by insertion position
|
|
213
|
+
# @return [Array<(Symbol, Object)>]
|
|
230
214
|
def deduplicate_insertions(insertions, method_overrides_by_pos: nil)
|
|
231
215
|
group_by_position(insertions).each_with_object([]) do |(pos, items), result|
|
|
232
216
|
process_dedup_group(pos, items, result, method_overrides_by_pos)
|
|
233
217
|
end
|
|
234
218
|
end
|
|
235
219
|
|
|
236
|
-
# Process
|
|
220
|
+
# Process dedup group
|
|
221
|
+
#
|
|
237
222
|
# @private
|
|
238
|
-
# @param [
|
|
239
|
-
# @param [Object] items
|
|
240
|
-
# @param [Object] result
|
|
241
|
-
# @param [Object] method_overrides_by_pos hash mapping position to method
|
|
242
|
-
#
|
|
223
|
+
# @param [Integer] pos the source begin_pos for the group
|
|
224
|
+
# @param [Array<(Symbol, Object)>] items grouped items to process
|
|
225
|
+
# @param [Array<(Symbol, Object)>] result accumulated result array
|
|
226
|
+
# @param [Hash<Integer, Hash<Symbol, Object>>, nil] method_overrides_by_pos hash mapping position to method
|
|
227
|
+
# override data
|
|
228
|
+
# @return [void]
|
|
243
229
|
def process_dedup_group(pos, items, result, method_overrides_by_pos)
|
|
244
230
|
plugin_items = items.select { |pair| pair.first == :plugin }
|
|
245
231
|
return result.concat(items) if plugin_items.empty?
|
|
@@ -253,11 +239,11 @@ module Docscribe
|
|
|
253
239
|
end
|
|
254
240
|
end
|
|
255
241
|
|
|
256
|
-
# Group
|
|
242
|
+
# Group by position
|
|
257
243
|
#
|
|
258
244
|
# @private
|
|
259
|
-
# @param [Array<
|
|
260
|
-
# @return [Hash
|
|
245
|
+
# @param [Array<(Symbol, Object)>] insertions insertions to group
|
|
246
|
+
# @return [Hash<Integer, Array<(Symbol, Object)>>]
|
|
261
247
|
def group_by_position(insertions)
|
|
262
248
|
groups = {} #: Hash[Integer, untyped]
|
|
263
249
|
insertions.each do |kind, ins|
|
|
@@ -267,26 +253,27 @@ module Docscribe
|
|
|
267
253
|
groups
|
|
268
254
|
end
|
|
269
255
|
|
|
270
|
-
# Find
|
|
256
|
+
# Find override items
|
|
271
257
|
#
|
|
272
258
|
# @private
|
|
273
|
-
# @param [Array<
|
|
274
|
-
# @return [Array<
|
|
259
|
+
# @param [Array<(Symbol, Object)>] plugin_items plugin items to check
|
|
260
|
+
# @return [Array<(Symbol, Object)>]
|
|
275
261
|
def find_override_items(plugin_items)
|
|
276
262
|
plugin_items.select do |_k, ins|
|
|
277
263
|
ins.is_a?(Hash) && ins[:method_override].is_a?(Hash)
|
|
278
264
|
end
|
|
279
265
|
end
|
|
280
266
|
|
|
281
|
-
# Handle
|
|
267
|
+
# Handle override case
|
|
282
268
|
#
|
|
283
269
|
# @private
|
|
284
|
-
# @param [Array<
|
|
285
|
-
# @param [Array<
|
|
286
|
-
# @param [Array<
|
|
287
|
-
# @param [Hash, nil] method_overrides_by_pos
|
|
288
|
-
#
|
|
289
|
-
# @
|
|
270
|
+
# @param [Array<(Symbol, Object)>] result accumulated result array
|
|
271
|
+
# @param [Array<(Symbol, Object)>] items all items in group
|
|
272
|
+
# @param [Array<(Symbol, Object)>] override_items override plugin items
|
|
273
|
+
# @param [Hash<Integer, Hash<Symbol, Object>>, nil] method_overrides_by_pos hash mapping position to
|
|
274
|
+
# method override data
|
|
275
|
+
# @param [Integer] pos the source position of the conflict
|
|
276
|
+
# @return [void]
|
|
290
277
|
def handle_override_case(result, items, override_items, method_overrides_by_pos, pos)
|
|
291
278
|
if method_overrides_by_pos
|
|
292
279
|
winning_ins = pick_highest_priority_override_insertion(override_items, pos: pos)
|
|
@@ -297,14 +284,14 @@ module Docscribe
|
|
|
297
284
|
result.concat(items)
|
|
298
285
|
end
|
|
299
286
|
|
|
300
|
-
#
|
|
287
|
+
# Deduplicate items
|
|
301
288
|
#
|
|
302
289
|
# @private
|
|
303
|
-
# @param [Array<
|
|
304
|
-
# @param [Array<
|
|
305
|
-
# @param [Integer] pos
|
|
306
|
-
# @param [Object] _method_items method
|
|
307
|
-
# @return [Array<
|
|
290
|
+
# @param [Array<(Symbol, Object)>] items all items in group
|
|
291
|
+
# @param [Array<(Symbol, Object)>] plugin_items plugin items in group
|
|
292
|
+
# @param [Integer] pos the source position of the conflict
|
|
293
|
+
# @param [Array<(Symbol, Object)>] _method_items method items in group
|
|
294
|
+
# @return [Array<(Symbol, Object)>]
|
|
308
295
|
def deduplicate_items(items, plugin_items, pos, _method_items)
|
|
309
296
|
plugin_doc_items = plugin_items.select { |pair| plugin_doc_item?(pair) }
|
|
310
297
|
|
|
@@ -315,22 +302,23 @@ module Docscribe
|
|
|
315
302
|
end
|
|
316
303
|
end
|
|
317
304
|
|
|
318
|
-
#
|
|
305
|
+
# Plugin doc item
|
|
306
|
+
#
|
|
319
307
|
# @private
|
|
320
|
-
# @param [Object] pair
|
|
321
|
-
# @return [
|
|
308
|
+
# @param [(Symbol, Object)] pair insertion pair to check
|
|
309
|
+
# @return [Boolean]
|
|
322
310
|
def plugin_doc_item?(pair)
|
|
323
311
|
_k, ins = pair
|
|
324
312
|
ins.is_a?(Hash) && ins[:doc] && !ins[:doc].empty?
|
|
325
313
|
end
|
|
326
314
|
|
|
327
|
-
# Deduplicate plugin doc
|
|
315
|
+
# Deduplicate plugin doc case
|
|
328
316
|
#
|
|
329
317
|
# @private
|
|
330
|
-
# @param [Array<
|
|
331
|
-
# @param [Array<
|
|
332
|
-
# @param [Integer] pos
|
|
333
|
-
# @return [Array<
|
|
318
|
+
# @param [Array<(Symbol, Object)>] items all items in group
|
|
319
|
+
# @param [Array<(Symbol, Object)>] plugin_doc_items plugin doc items
|
|
320
|
+
# @param [Integer] pos the source position of the conflict
|
|
321
|
+
# @return [Array<(Symbol, Object)>]
|
|
334
322
|
def deduplicate_plugin_doc_case(items, plugin_doc_items, pos)
|
|
335
323
|
items = items.reject { |k, _| k == :method }
|
|
336
324
|
items = items.reject { |pair| override_or_plugin_method?(pair) }
|
|
@@ -344,44 +332,45 @@ module Docscribe
|
|
|
344
332
|
items
|
|
345
333
|
end
|
|
346
334
|
|
|
347
|
-
#
|
|
335
|
+
# Override or plugin method
|
|
336
|
+
#
|
|
348
337
|
# @private
|
|
349
|
-
# @param [Object] pair
|
|
350
|
-
# @return [
|
|
338
|
+
# @param [(Symbol, Object)] pair insertion pair to check
|
|
339
|
+
# @return [Boolean]
|
|
351
340
|
def override_or_plugin_method?(pair)
|
|
352
341
|
k, ins = pair
|
|
353
342
|
k == :plugin && ins.is_a?(Hash) && ins.key?(:method_override)
|
|
354
343
|
end
|
|
355
344
|
|
|
356
|
-
#
|
|
345
|
+
# Max plugin priority
|
|
357
346
|
#
|
|
358
347
|
# @private
|
|
359
|
-
# @param [Array<
|
|
348
|
+
# @param [Array<(Symbol, Object)>] plugin_items plugin items to scan
|
|
360
349
|
# @return [Integer]
|
|
361
350
|
def max_plugin_priority(plugin_items)
|
|
362
351
|
plugin_items.map { |_k, ins| plugin_insertion_priority(ins) }.max || 0
|
|
363
352
|
end
|
|
364
353
|
|
|
365
|
-
# Filter
|
|
354
|
+
# Filter lower priority plugins
|
|
366
355
|
#
|
|
367
356
|
# @private
|
|
368
|
-
# @param [Array<
|
|
369
|
-
# @param [Integer] threshold
|
|
370
|
-
# @return [Array<
|
|
357
|
+
# @param [Array<(Symbol, Object)>] items items to filter
|
|
358
|
+
# @param [Integer] threshold minimum priority threshold
|
|
359
|
+
# @return [Array<(Symbol, Object)>]
|
|
371
360
|
def filter_lower_priority_plugins(items, threshold)
|
|
372
361
|
items.select do |k, ins|
|
|
373
362
|
k == :plugin && ins.is_a?(Hash) && ins[:doc] && plugin_insertion_priority(ins) < threshold
|
|
374
363
|
end
|
|
375
364
|
end
|
|
376
365
|
|
|
377
|
-
# Warn
|
|
366
|
+
# Warn plugin conflict
|
|
378
367
|
#
|
|
379
368
|
# @private
|
|
380
|
-
# @param [Array<
|
|
381
|
-
# @param [Array<
|
|
382
|
-
# @param [Integer] max_prio
|
|
383
|
-
# @param [Integer] pos
|
|
384
|
-
# @return [
|
|
369
|
+
# @param [Array<(Symbol, Object)>] dropped dropped plugin items
|
|
370
|
+
# @param [Array<(Symbol, Object)>] plugin_items kept plugin items
|
|
371
|
+
# @param [Integer] max_prio the maximum priority value
|
|
372
|
+
# @param [Integer] pos the source position of the conflict
|
|
373
|
+
# @return [void]
|
|
385
374
|
def warn_plugin_conflict!(dropped, plugin_items, max_prio, pos)
|
|
386
375
|
kept_labels = plugin_items.map { |_k, ins| plugin_insertion_label(ins) }.uniq
|
|
387
376
|
dropped_labels = dropped.map { |_k, ins| plugin_insertion_label(ins) }.uniq
|
|
@@ -392,23 +381,23 @@ module Docscribe
|
|
|
392
381
|
'Set explicit priority or adjust anchor_node to avoid collision.'
|
|
393
382
|
end
|
|
394
383
|
|
|
395
|
-
#
|
|
384
|
+
# Conflict location str
|
|
385
|
+
#
|
|
396
386
|
# @private
|
|
397
|
-
# @param [
|
|
398
|
-
# @param [Object] plugin_items
|
|
399
|
-
# @return [
|
|
387
|
+
# @param [Integer] pos the source position of the conflict
|
|
388
|
+
# @param [Array<(Symbol, Object)>] plugin_items plugin items for location
|
|
389
|
+
# @return [String]
|
|
400
390
|
def conflict_location_str(pos, plugin_items)
|
|
401
391
|
line = plugin_insertion_line(plugin_items.first[1])
|
|
402
|
-
|
|
403
|
-
loc << " line=#{line}" if line
|
|
404
|
-
loc
|
|
392
|
+
"pos=#{pos}#{" line=#{line}" if line}"
|
|
405
393
|
end
|
|
406
394
|
|
|
395
|
+
# Pick highest priority override insertion
|
|
396
|
+
#
|
|
407
397
|
# @private
|
|
408
|
-
# @param
|
|
409
|
-
#
|
|
410
|
-
# @
|
|
411
|
-
# @return [Hash, nil] winning insertion hash (the one whose override will be applied)
|
|
398
|
+
# @param [Array<(Symbol, Object)>] override_items override items to prioritize
|
|
399
|
+
# @param [Integer] pos begin_pos (used only for debug output)
|
|
400
|
+
# @return [Hash<Symbol, Object>, nil] winning insertion hash (the one whose override will be applied)
|
|
412
401
|
def pick_highest_priority_override_insertion(override_items, pos:)
|
|
413
402
|
return nil if override_items.empty?
|
|
414
403
|
|
|
@@ -421,18 +410,20 @@ module Docscribe
|
|
|
421
410
|
winners_sorted.first[1]
|
|
422
411
|
end
|
|
423
412
|
|
|
424
|
-
#
|
|
413
|
+
# Max plugin priority for
|
|
414
|
+
#
|
|
425
415
|
# @private
|
|
426
|
-
# @param [Object] override_items
|
|
427
|
-
# @return [
|
|
416
|
+
# @param [Array<(Symbol, Object)>] override_items override items to evaluate
|
|
417
|
+
# @return [Integer]
|
|
428
418
|
def max_plugin_priority_for(override_items)
|
|
429
419
|
override_items.map { |_k, ins| plugin_insertion_priority(ins) }.max || 0
|
|
430
420
|
end
|
|
431
421
|
|
|
432
|
-
# Sort
|
|
422
|
+
# Sort winners by order
|
|
423
|
+
#
|
|
433
424
|
# @private
|
|
434
|
-
# @param [Object] winners
|
|
435
|
-
# @return [Object]
|
|
425
|
+
# @param [Array<(Symbol, Object)>] winners winning items to sort
|
|
426
|
+
# @return [Array<(Symbol, Object)>]
|
|
436
427
|
def sort_winners_by_order(winners)
|
|
437
428
|
winners.sort_by do |_k, ins|
|
|
438
429
|
order = ins.is_a?(Hash) ? ins[:__docscribe_plugin_order] : nil
|
|
@@ -440,12 +431,13 @@ module Docscribe
|
|
|
440
431
|
end
|
|
441
432
|
end
|
|
442
433
|
|
|
443
|
-
# Warn
|
|
434
|
+
# Warn override conflict
|
|
435
|
+
#
|
|
444
436
|
# @private
|
|
445
|
-
# @param [Object] winners_sorted sorted
|
|
446
|
-
# @param [
|
|
447
|
-
# @param [
|
|
448
|
-
# @return [
|
|
437
|
+
# @param [Array<(Symbol, Object)>] winners_sorted sorted winning items
|
|
438
|
+
# @param [Integer] max_prio the maximum priority value
|
|
439
|
+
# @param [Integer] pos the source position of the conflict
|
|
440
|
+
# @return [void]
|
|
449
441
|
def warn_override_conflict!(winners_sorted, max_prio, pos)
|
|
450
442
|
return unless Docscribe::Plugin.debug?
|
|
451
443
|
|
|
@@ -459,10 +451,13 @@ module Docscribe
|
|
|
459
451
|
"#{labels.join(', ')} — using first by registration order."
|
|
460
452
|
end
|
|
461
453
|
|
|
454
|
+
# Plugin insertion priority
|
|
455
|
+
#
|
|
462
456
|
# @private
|
|
463
|
-
# @param [Hash] insertion
|
|
457
|
+
# @param [Hash<Symbol, Object>, Docscribe::InlineRewriter::Collector::Insertion, Docscribe::InlineRewriter::Collector::AttrInsertion] insertion the collected method insertion
|
|
464
458
|
# @raise [StandardError]
|
|
465
|
-
# @return [Integer]
|
|
459
|
+
# @return [Integer] if StandardError
|
|
460
|
+
# @return [Integer] if StandardError
|
|
466
461
|
def plugin_insertion_priority(insertion)
|
|
467
462
|
return 0 unless insertion.is_a?(Hash)
|
|
468
463
|
|
|
@@ -471,10 +466,13 @@ module Docscribe
|
|
|
471
466
|
0
|
|
472
467
|
end
|
|
473
468
|
|
|
469
|
+
# Plugin insertion label
|
|
470
|
+
#
|
|
474
471
|
# @private
|
|
475
|
-
# @param [Hash] insertion
|
|
472
|
+
# @param [Hash<Symbol, Object>, Docscribe::InlineRewriter::Collector::Insertion, Docscribe::InlineRewriter::Collector::AttrInsertion] insertion the collected method insertion
|
|
476
473
|
# @raise [StandardError]
|
|
477
|
-
# @return [String]
|
|
474
|
+
# @return [String] if StandardError
|
|
475
|
+
# @return [String] if StandardError
|
|
478
476
|
def plugin_insertion_label(insertion)
|
|
479
477
|
return 'unknown' unless insertion.is_a?(Hash)
|
|
480
478
|
|
|
@@ -484,10 +482,13 @@ module Docscribe
|
|
|
484
482
|
'unknown'
|
|
485
483
|
end
|
|
486
484
|
|
|
485
|
+
# Plugin insertion line
|
|
486
|
+
#
|
|
487
487
|
# @private
|
|
488
|
-
# @param [Hash] insertion
|
|
488
|
+
# @param [Hash<Symbol, Object>, Docscribe::InlineRewriter::Collector::Insertion, Docscribe::InlineRewriter::Collector::AttrInsertion] insertion the collected method insertion
|
|
489
489
|
# @raise [StandardError]
|
|
490
|
-
# @return [Integer, nil]
|
|
490
|
+
# @return [Integer, nil] if StandardError
|
|
491
|
+
# @return [nil] if StandardError
|
|
491
492
|
def plugin_insertion_line(insertion)
|
|
492
493
|
return nil unless insertion.is_a?(Hash)
|
|
493
494
|
|
|
@@ -498,33 +499,31 @@ module Docscribe
|
|
|
498
499
|
nil
|
|
499
500
|
end
|
|
500
501
|
|
|
501
|
-
#
|
|
502
|
-
# insertions (method/attr) and Hash-based insertions (plugin).
|
|
502
|
+
# Plugin insertion pos
|
|
503
503
|
#
|
|
504
504
|
# @private
|
|
505
505
|
# @param [Symbol] kind :method, :attr, or :plugin
|
|
506
|
-
# @param [Object] ins insertion
|
|
506
|
+
# @param [Hash<Symbol, Object>] ins insertion to locate
|
|
507
507
|
# @return [Integer]
|
|
508
508
|
def plugin_insertion_pos(kind, ins)
|
|
509
509
|
case kind
|
|
510
510
|
when :plugin
|
|
511
|
-
ins[
|
|
511
|
+
plugin_ins = ins #: Hash[Symbol, untyped]
|
|
512
|
+
plugin_ins[:anchor_node].loc.expression.begin_pos
|
|
512
513
|
else
|
|
513
|
-
ins
|
|
514
|
+
method_ins = ins #: Collector::Insertion | Collector::AttrInsertion
|
|
515
|
+
method_ins.node.loc.expression.begin_pos
|
|
514
516
|
end
|
|
515
517
|
end
|
|
516
518
|
|
|
517
|
-
# Apply
|
|
518
|
-
#
|
|
519
|
-
# :safe — skip if a doc-like block already exists above anchor_node
|
|
520
|
-
# :aggressive — remove existing doc block, insert fresh
|
|
519
|
+
# Apply plugin insertion
|
|
521
520
|
#
|
|
522
521
|
# @private
|
|
523
|
-
# @param [Parser::Source::TreeRewriter] rewriter
|
|
524
|
-
# @param [Parser::Source::Buffer] buffer
|
|
525
|
-
# @param [Hash] insertion { anchor_node:, doc: }
|
|
526
|
-
# @param [Symbol] strategy
|
|
527
|
-
# @param [Docscribe::Config] config
|
|
522
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
523
|
+
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
524
|
+
# @param [Hash<Symbol, Object>] insertion { anchor_node:, doc: }
|
|
525
|
+
# @param [Symbol] strategy :safe or :aggressive rewrite mode
|
|
526
|
+
# @param [Docscribe::Config] config the active configuration
|
|
528
527
|
# @return [void]
|
|
529
528
|
def apply_plugin_insertion!(rewriter:, buffer:, insertion:, strategy:, config:)
|
|
530
529
|
anchor_node, doc = insertion.values_at(:anchor_node, :doc)
|
|
@@ -536,14 +535,15 @@ module Docscribe
|
|
|
536
535
|
insert_plugin_doc(rewriter, buffer, bol_range, doc, strategy)
|
|
537
536
|
end
|
|
538
537
|
|
|
539
|
-
# Insert plugin doc
|
|
538
|
+
# Insert plugin doc
|
|
539
|
+
#
|
|
540
540
|
# @private
|
|
541
|
-
# @param [
|
|
542
|
-
# @param [
|
|
543
|
-
# @param [
|
|
544
|
-
# @param [
|
|
545
|
-
# @param [
|
|
546
|
-
# @return [
|
|
541
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
542
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
543
|
+
# @param [Parser::Source::Range] bol_range the beginning-of-line range for the anchor node
|
|
544
|
+
# @param [String] doc the normalized documentation string to insert
|
|
545
|
+
# @param [Symbol] strategy :safe or :aggressive rewrite mode
|
|
546
|
+
# @return [void]
|
|
547
547
|
def insert_plugin_doc(rewriter, buffer, bol_range, doc, strategy)
|
|
548
548
|
case strategy
|
|
549
549
|
when :aggressive
|
|
@@ -557,14 +557,10 @@ module Docscribe
|
|
|
557
557
|
end
|
|
558
558
|
end
|
|
559
559
|
|
|
560
|
-
#
|
|
561
|
-
# regardless of whether it looks like documentation.
|
|
562
|
-
#
|
|
563
|
-
# Used by CollectorPlugin in aggressive mode where the plugin itself
|
|
564
|
-
# is responsible for deciding what to replace.
|
|
560
|
+
# Any comment block removal range
|
|
565
561
|
#
|
|
566
562
|
# @private
|
|
567
|
-
# @param [Parser::Source::Buffer] buffer
|
|
563
|
+
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
568
564
|
# @param [Integer] bol_pos beginning-of-line position of anchor_node
|
|
569
565
|
# @return [Parser::Source::Range, nil]
|
|
570
566
|
def any_comment_block_removal_range(buffer, bol_pos)
|
|
@@ -582,12 +578,13 @@ module Docscribe
|
|
|
582
578
|
Parser::Source::Range.new(buffer, start_pos, bol_pos)
|
|
583
579
|
end
|
|
584
580
|
|
|
585
|
-
#
|
|
581
|
+
# Nearest comment line index
|
|
582
|
+
#
|
|
586
583
|
# @private
|
|
587
|
-
# @param [
|
|
588
|
-
# @param [
|
|
589
|
-
# @param [
|
|
590
|
-
# @return [
|
|
584
|
+
# @param [String] src the full source string of the buffer
|
|
585
|
+
# @param [Array<String>] lines array of source code lines
|
|
586
|
+
# @param [Integer] bol_pos character position of the beginning of the anchor line
|
|
587
|
+
# @return [Integer, nil]
|
|
591
588
|
def nearest_comment_line_index(src, lines, bol_pos)
|
|
592
589
|
def_line_idx = (src[0...bol_pos] || '').count("\n")
|
|
593
590
|
i = def_line_idx - 1
|
|
@@ -597,60 +594,53 @@ module Docscribe
|
|
|
597
594
|
i
|
|
598
595
|
end
|
|
599
596
|
|
|
600
|
-
#
|
|
597
|
+
# Comment block start index
|
|
598
|
+
#
|
|
601
599
|
# @private
|
|
602
|
-
# @param [
|
|
603
|
-
# @param [
|
|
604
|
-
# @
|
|
605
|
-
# @return [Object]
|
|
600
|
+
# @param [Array<String>] lines array of source code lines
|
|
601
|
+
# @param [Integer] def_line_idx the index in lines of the method definition (anchor) line
|
|
602
|
+
# @return [Integer]
|
|
606
603
|
def comment_block_start_index(lines, def_line_idx)
|
|
607
604
|
start_idx = def_line_idx
|
|
608
605
|
start_idx -= 1 while start_idx >= 0 && lines[start_idx] =~ /^\s*#/
|
|
609
606
|
start_idx + 1
|
|
610
607
|
end
|
|
611
608
|
|
|
612
|
-
# Skip preserved
|
|
609
|
+
# Skip preserved lines
|
|
610
|
+
#
|
|
613
611
|
# @private
|
|
614
|
-
# @param [
|
|
615
|
-
# @param [
|
|
616
|
-
# @param [
|
|
617
|
-
# @
|
|
618
|
-
# @return [Object]
|
|
612
|
+
# @param [Array<String>] lines array of source code lines
|
|
613
|
+
# @param [Integer] start_idx index of the first line of the comment block
|
|
614
|
+
# @param [Integer] def_line_idx the index in lines of the method definition (anchor) line
|
|
615
|
+
# @return [Integer]
|
|
619
616
|
def skip_preserved_lines(lines, start_idx, def_line_idx)
|
|
620
617
|
idx = start_idx
|
|
621
618
|
idx += 1 while idx <= def_line_idx && SourceHelpers.preserved_comment_line?(lines[idx])
|
|
622
619
|
idx
|
|
623
620
|
end
|
|
624
621
|
|
|
625
|
-
# Normalize
|
|
626
|
-
#
|
|
627
|
-
# Responsibilities:
|
|
628
|
-
# - apply indentation based on the anchor node
|
|
629
|
-
# - trim trailing whitespace-only lines
|
|
630
|
-
# - (optionally) prepend the configured default message for `def/defs` anchors
|
|
631
|
-
# when the plugin output contains only tags (no prose)
|
|
622
|
+
# Normalize plugin doc
|
|
632
623
|
#
|
|
633
624
|
# @private
|
|
634
|
-
# @param
|
|
635
|
-
# @param
|
|
636
|
-
# @param
|
|
637
|
-
# @param
|
|
625
|
+
# @param [String] doc Raw doc string returned by a CollectorPlugin insertion (`:doc`)
|
|
626
|
+
# @param [String] indent Indentation to apply to every doc line
|
|
627
|
+
# @param [Docscribe::Config] config Effective Docscribe config for this run
|
|
628
|
+
# @param [Parser::AST::Node, nil] anchor_node AST node used as insertion anchor
|
|
638
629
|
# @return [String] Normalized doc string ready to be inserted
|
|
639
630
|
def normalize_plugin_doc(doc, indent, config:, anchor_node:)
|
|
640
631
|
doc = normalize_plugin_doc_indent(doc, indent)
|
|
641
632
|
doc = trim_trailing_blank_lines(doc)
|
|
642
|
-
|
|
643
633
|
if anchor_node && %i[def defs].include?(anchor_node.type) && config.include_default_message?
|
|
644
634
|
doc = prepend_default_message_if_no_prose(doc, anchor_node, indent, config)
|
|
645
635
|
end
|
|
646
|
-
|
|
647
636
|
doc
|
|
648
637
|
end
|
|
649
638
|
|
|
650
|
-
# Trim trailing blank lines
|
|
639
|
+
# Trim trailing blank lines
|
|
640
|
+
#
|
|
651
641
|
# @private
|
|
652
|
-
# @param [
|
|
653
|
-
# @return [
|
|
642
|
+
# @param [String] doc the documentation string to trim
|
|
643
|
+
# @return [String]
|
|
654
644
|
def trim_trailing_blank_lines(doc)
|
|
655
645
|
lines = doc.lines
|
|
656
646
|
lines.pop while lines.any? && lines.last.strip.empty?
|
|
@@ -658,13 +648,14 @@ module Docscribe
|
|
|
658
648
|
result.end_with?("\n") ? result : "#{result}\n"
|
|
659
649
|
end
|
|
660
650
|
|
|
661
|
-
# Prepend default message if
|
|
651
|
+
# Prepend default message if no prose
|
|
652
|
+
#
|
|
662
653
|
# @private
|
|
663
|
-
# @param [
|
|
664
|
-
# @param [
|
|
665
|
-
# @param [
|
|
666
|
-
# @param [
|
|
667
|
-
# @return [
|
|
654
|
+
# @param [String] doc the plugin-generated documentation string
|
|
655
|
+
# @param [Parser::AST::Node] anchor_node the AST node used as the insertion anchor
|
|
656
|
+
# @param [String] indent whitespace indentation prefix derived from the anchor node
|
|
657
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
658
|
+
# @return [String]
|
|
668
659
|
def prepend_default_message_if_no_prose(doc, anchor_node, indent, config)
|
|
669
660
|
return doc if doc_has_prose?(doc)
|
|
670
661
|
|
|
@@ -673,9 +664,10 @@ module Docscribe
|
|
|
673
664
|
"#{indent}# #{msg}\n#{indent}#\n" + doc
|
|
674
665
|
end
|
|
675
666
|
|
|
676
|
-
#
|
|
667
|
+
# Doc has prose
|
|
668
|
+
#
|
|
677
669
|
# @private
|
|
678
|
-
# @param [
|
|
670
|
+
# @param [String] doc the documentation string to inspect
|
|
679
671
|
# @return [Boolean]
|
|
680
672
|
def doc_has_prose?(doc)
|
|
681
673
|
doc.lines.any? do |l|
|
|
@@ -688,11 +680,7 @@ module Docscribe
|
|
|
688
680
|
end
|
|
689
681
|
end
|
|
690
682
|
|
|
691
|
-
# Normalize
|
|
692
|
-
#
|
|
693
|
-
# Plugins produce doc strings without knowledge of the surrounding
|
|
694
|
-
# indentation. We strip leading whitespace from each non-empty line
|
|
695
|
-
# and re-prefix it with the indent derived from anchor_node.
|
|
683
|
+
# Normalize plugin doc indent
|
|
696
684
|
#
|
|
697
685
|
# @private
|
|
698
686
|
# @param [String] doc raw doc string from plugin
|
|
@@ -705,18 +693,12 @@ module Docscribe
|
|
|
705
693
|
end.join
|
|
706
694
|
end
|
|
707
695
|
|
|
708
|
-
# Normalize strategy
|
|
709
|
-
#
|
|
710
|
-
# Precedence:
|
|
711
|
-
# - explicit `strategy`
|
|
712
|
-
# - `rewrite: true` => `:aggressive`
|
|
713
|
-
# - `merge: true` => `:safe`
|
|
714
|
-
# - default => `:safe`
|
|
696
|
+
# Normalize strategy
|
|
715
697
|
#
|
|
716
698
|
# @private
|
|
717
|
-
# @param [Symbol, nil] strategy
|
|
718
|
-
# @param [Boolean, nil] rewrite
|
|
719
|
-
# @param [Boolean, nil] merge
|
|
699
|
+
# @param [Symbol, nil] strategy :safe or :aggressive rewrite mode
|
|
700
|
+
# @param [Boolean, nil] rewrite compatibility alias for aggressive strategy
|
|
701
|
+
# @param [Boolean, nil] merge compatibility alias for safe strategy
|
|
720
702
|
# @return [Symbol]
|
|
721
703
|
def normalize_strategy(strategy:, rewrite:, merge:)
|
|
722
704
|
return strategy if strategy
|
|
@@ -726,10 +708,10 @@ module Docscribe
|
|
|
726
708
|
:safe
|
|
727
709
|
end
|
|
728
710
|
|
|
729
|
-
# Validate
|
|
711
|
+
# Validate strategy
|
|
730
712
|
#
|
|
731
713
|
# @private
|
|
732
|
-
# @param [Symbol] strategy
|
|
714
|
+
# @param [Symbol] strategy :safe or :aggressive rewrite mode
|
|
733
715
|
# @raise [ArgumentError]
|
|
734
716
|
# @return [void]
|
|
735
717
|
def validate_strategy!(strategy)
|
|
@@ -738,18 +720,10 @@ module Docscribe
|
|
|
738
720
|
raise ArgumentError, "Unknown strategy: #{strategy.inspect}"
|
|
739
721
|
end
|
|
740
722
|
|
|
741
|
-
# Apply
|
|
742
|
-
#
|
|
743
|
-
# Safe strategy:
|
|
744
|
-
# - merge into existing doc-like blocks when present
|
|
745
|
-
# - otherwise insert a full doc block non-destructively
|
|
746
|
-
#
|
|
747
|
-
# Aggressive strategy:
|
|
748
|
-
# - remove the existing doc block (if any)
|
|
749
|
-
# - insert a fresh regenerated block
|
|
723
|
+
# Apply method insertion
|
|
750
724
|
#
|
|
751
725
|
# @private
|
|
752
|
-
# @param [
|
|
726
|
+
# @param [Object] options kwargs with insertion, config, rewriter, buffer, strategy, changes, file, doc params
|
|
753
727
|
# @return [void]
|
|
754
728
|
def apply_method_insertion!(**options)
|
|
755
729
|
insertion = options[:insertion]
|
|
@@ -759,17 +733,19 @@ module Docscribe
|
|
|
759
733
|
anchor_bol_range, = method_bol_ranges(options[:buffer], insertion)
|
|
760
734
|
params = build_method_insertion_params(insertion, config, options[:signature_provider],
|
|
761
735
|
options[:core_rbs_provider], options[:method_override])
|
|
762
|
-
|
|
736
|
+
extract_existing_descriptions!(options[:buffer], insertion, params, options[:strategy], config)
|
|
737
|
+
doc = DocBuilder.build(insertion, **params) # steep:ignore
|
|
763
738
|
dispatch_method_insertion_by_strategy!(anchor_bol_range, options, params, doc)
|
|
764
739
|
end
|
|
765
740
|
|
|
766
|
-
# Dispatch method insertion
|
|
741
|
+
# Dispatch method insertion by strategy
|
|
742
|
+
#
|
|
767
743
|
# @private
|
|
768
|
-
# @param [
|
|
769
|
-
# @param [Object] options the full keyword options hash passed to apply_method_insertion!
|
|
770
|
-
# @param [Object] params precomputed insertion parameters (types, overrides, config)
|
|
771
|
-
# @param [
|
|
772
|
-
# @return [
|
|
744
|
+
# @param [Parser::Source::Range] anchor_bol_range the beginning-of-line range for the anchor node
|
|
745
|
+
# @param [Hash<Symbol, Object>] options the full keyword options hash passed to apply_method_insertion!
|
|
746
|
+
# @param [Hash<Symbol, Object>] params precomputed insertion parameters (types, overrides, config)
|
|
747
|
+
# @param [String, nil] doc the generated documentation block string
|
|
748
|
+
# @return [void]
|
|
773
749
|
def dispatch_method_insertion_by_strategy!(anchor_bol_range, options, params, doc)
|
|
774
750
|
base = { anchor_bol_range: anchor_bol_range, insertion: options[:insertion],
|
|
775
751
|
rewriter: options[:rewriter], buffer: options[:buffer],
|
|
@@ -780,27 +756,57 @@ module Docscribe
|
|
|
780
756
|
end
|
|
781
757
|
end
|
|
782
758
|
|
|
783
|
-
#
|
|
759
|
+
# Method insertion allowed
|
|
784
760
|
#
|
|
785
761
|
# @private
|
|
786
|
-
# @param [Collector::Insertion] insertion
|
|
787
|
-
# @param [Docscribe::Config] config
|
|
762
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
763
|
+
# @param [Docscribe::Config] config the active configuration
|
|
788
764
|
# @return [Boolean] true if insertion should proceed
|
|
789
765
|
def method_insertion_allowed?(insertion, config)
|
|
790
|
-
name = SourceHelpers.node_name(insertion.node)
|
|
766
|
+
name = SourceHelpers.node_name(insertion.node) #: Symbol
|
|
791
767
|
config.process_method?(container: insertion.container, scope: insertion.scope,
|
|
792
768
|
visibility: insertion.visibility || :public, name: name)
|
|
793
769
|
end
|
|
794
770
|
|
|
795
|
-
#
|
|
771
|
+
# Extract existing descriptions
|
|
796
772
|
#
|
|
797
773
|
# @private
|
|
798
|
-
# @param [
|
|
799
|
-
# @param [Docscribe::
|
|
800
|
-
# @param [
|
|
801
|
-
# @param [
|
|
802
|
-
# @param [
|
|
803
|
-
# @return [
|
|
774
|
+
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
775
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
776
|
+
# @param [Hash<Symbol, Object>] params precomputed attribute insertion parameters
|
|
777
|
+
# @param [Symbol] strategy :safe or :aggressive rewrite mode
|
|
778
|
+
# @param [Docscribe::Config] config the active configuration
|
|
779
|
+
# @return [void]
|
|
780
|
+
def extract_existing_descriptions!(buffer, insertion, params, strategy, config)
|
|
781
|
+
return unless strategy == :aggressive && config.keep_descriptions?
|
|
782
|
+
|
|
783
|
+
parsed = DocBuilder.parse_existing_doc_tags(
|
|
784
|
+
method_doc_comment_info(buffer, insertion)&.dig(:doc_lines) || []
|
|
785
|
+
)
|
|
786
|
+
merge_existing_descriptions!(params, parsed)
|
|
787
|
+
end
|
|
788
|
+
|
|
789
|
+
# Merge parsed descriptions into insertion params
|
|
790
|
+
#
|
|
791
|
+
# @private
|
|
792
|
+
# @param [Hash<Symbol, Object>] params insertion params
|
|
793
|
+
# @param [Hash<Symbol, Object>] parsed parsed tag info
|
|
794
|
+
# @return [void]
|
|
795
|
+
def merge_existing_descriptions!(params, parsed)
|
|
796
|
+
params[:param_descriptions] = parsed[:param_descriptions] if parsed[:param_descriptions].any?
|
|
797
|
+
params[:return_description] = parsed[:return_description] if parsed[:return_description]
|
|
798
|
+
params[:description] = parsed[:description] if parsed[:description].any?
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
# Build method insertion params
|
|
802
|
+
#
|
|
803
|
+
# @private
|
|
804
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
805
|
+
# @param [Docscribe::Config] config the active configuration
|
|
806
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider RBS signature provider
|
|
807
|
+
# @param [Object, nil] core_rbs_provider optional externally-provided core RBS provider
|
|
808
|
+
# @param [Hash<Symbol, Object>, nil] method_override the raw override data
|
|
809
|
+
# @return [Hash<Symbol, Object>]
|
|
804
810
|
def build_method_insertion_params(insertion, config, signature_provider, core_rbs_provider, method_override)
|
|
805
811
|
override = extract_method_override!(method_override)
|
|
806
812
|
effective = build_effective_params(insertion, config: config, signature_provider: signature_provider,
|
|
@@ -809,12 +815,12 @@ module Docscribe
|
|
|
809
815
|
core_rbs_provider: core_rbs_provider }
|
|
810
816
|
end
|
|
811
817
|
|
|
812
|
-
# Build effective
|
|
818
|
+
# Build effective params
|
|
813
819
|
#
|
|
814
820
|
# @private
|
|
815
|
-
# @param [Collector::Insertion] insertion
|
|
816
|
-
# @param [
|
|
817
|
-
# @return [Hash
|
|
821
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
822
|
+
# @param [Object] options keyword options
|
|
823
|
+
# @return [Hash<Symbol, Hash<String, String>, nil, String, nil, Array<Docscribe::Plugin::Tag>>]
|
|
818
824
|
def build_effective_params(insertion, **options)
|
|
819
825
|
external_sig = resolve_external_signature(insertion, options[:signature_provider])
|
|
820
826
|
param_types = resolve_param_types(insertion, external_sig, options[:config])
|
|
@@ -825,35 +831,44 @@ module Docscribe
|
|
|
825
831
|
{ param_types: param_types, return_type_override: override[:return_type], override_tags: override[:tags] }
|
|
826
832
|
end
|
|
827
833
|
|
|
828
|
-
# Resolve external signature
|
|
834
|
+
# Resolve external signature
|
|
835
|
+
#
|
|
829
836
|
# @private
|
|
830
|
-
# @param [
|
|
831
|
-
# @param [
|
|
832
|
-
# @return [
|
|
837
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
838
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider external RBS signature provider
|
|
839
|
+
# @return [Docscribe::Types::MethodSignature, nil]
|
|
833
840
|
def resolve_external_signature(insertion, signature_provider)
|
|
841
|
+
node_name = SourceHelpers.node_name(insertion.node) #: Symbol
|
|
834
842
|
signature_provider&.signature_for(
|
|
835
843
|
container: insertion.container,
|
|
836
844
|
scope: insertion.scope,
|
|
837
|
-
name:
|
|
845
|
+
name: node_name
|
|
838
846
|
)
|
|
839
847
|
end
|
|
840
848
|
|
|
841
|
-
# Resolve param types
|
|
849
|
+
# Resolve param types
|
|
850
|
+
#
|
|
842
851
|
# @private
|
|
843
|
-
# @param [
|
|
844
|
-
# @param [
|
|
845
|
-
# @param [
|
|
846
|
-
# @return [
|
|
852
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
853
|
+
# @param [Docscribe::Types::MethodSignature, nil] external_sig the resolved signature from the signature provider
|
|
854
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
855
|
+
# @return [Hash<String, String>, nil]
|
|
847
856
|
def resolve_param_types(insertion, external_sig, config)
|
|
848
|
-
external_sig
|
|
849
|
-
|
|
850
|
-
|
|
857
|
+
if external_sig
|
|
858
|
+
DocBuilder.build_param_types_from_node(
|
|
859
|
+
insertion.node, external_sig: external_sig, config: config
|
|
860
|
+
)
|
|
861
|
+
else
|
|
862
|
+
DocBuilder.build_param_types_from_node(
|
|
863
|
+
insertion.node, external_sig: nil, config: config
|
|
864
|
+
)
|
|
865
|
+
end
|
|
851
866
|
end
|
|
852
867
|
|
|
853
|
-
# Apply method insertion
|
|
868
|
+
# Apply method insertion aggressive
|
|
854
869
|
#
|
|
855
870
|
# @private
|
|
856
|
-
# @param [
|
|
871
|
+
# @param [Object] options keyword options
|
|
857
872
|
# @return [void]
|
|
858
873
|
def apply_method_insertion_aggressive!(**options)
|
|
859
874
|
rewriter = options[:rewriter]
|
|
@@ -869,21 +884,22 @@ module Docscribe
|
|
|
869
884
|
insertion: insertion, file: options[:file], message: 'missing docs')
|
|
870
885
|
end
|
|
871
886
|
|
|
872
|
-
# Remove
|
|
887
|
+
# Remove method comment block
|
|
888
|
+
#
|
|
873
889
|
# @private
|
|
874
|
-
# @param [
|
|
875
|
-
# @param [
|
|
876
|
-
# @param [
|
|
877
|
-
# @return [
|
|
890
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
891
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
892
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
893
|
+
# @return [void]
|
|
878
894
|
def remove_method_comment_block(rewriter, buffer, insertion)
|
|
879
895
|
range = method_comment_block_removal_range(buffer, insertion)
|
|
880
896
|
rewriter.remove(range) if range
|
|
881
897
|
end
|
|
882
898
|
|
|
883
|
-
# Apply method insertion
|
|
899
|
+
# Apply method insertion safe
|
|
884
900
|
#
|
|
885
901
|
# @private
|
|
886
|
-
# @param [
|
|
902
|
+
# @param [Object] options keyword options
|
|
887
903
|
# @return [void]
|
|
888
904
|
def apply_method_insertion_safe!(**options)
|
|
889
905
|
info = method_doc_comment_info(options[:buffer], options[:insertion])
|
|
@@ -895,32 +911,32 @@ module Docscribe
|
|
|
895
911
|
end
|
|
896
912
|
end
|
|
897
913
|
|
|
898
|
-
# Apply method insertion
|
|
914
|
+
# Apply method insertion safe with info
|
|
899
915
|
#
|
|
900
916
|
# @private
|
|
901
|
-
# @param [
|
|
917
|
+
# @param [Object] options keyword options
|
|
902
918
|
# @return [void]
|
|
903
919
|
def apply_method_insertion_safe_with_info!(**options)
|
|
904
920
|
i = options[:info]
|
|
905
921
|
dp = filter_doc_params(options)
|
|
906
|
-
mr =
|
|
907
|
-
|
|
922
|
+
mr = DocBuilder.build_missing_merge_result( # steep:ignore
|
|
923
|
+
options[:insertion], existing_lines: i[:doc_lines], strategy: options[:strategy], **dp
|
|
924
|
+
)
|
|
908
925
|
changed, n, ob = compute_doc_replacement(i, mr[:lines], strategy: options[:strategy], **dp)
|
|
909
926
|
commit_safe_doc_outcome(options[:rewriter], options[:buffer], i, n,
|
|
910
|
-
old_block: ob, merge_result: mr,
|
|
911
|
-
|
|
912
|
-
insertion: options[:insertion], changes: options[:changes],
|
|
913
|
-
file: options[:file])
|
|
927
|
+
old_block: ob, merge_result: mr, existing_order_changed: changed,
|
|
928
|
+
insertion: options[:insertion], changes: options[:changes], file: options[:file])
|
|
914
929
|
end
|
|
915
930
|
|
|
916
|
-
# Commit doc
|
|
931
|
+
# Commit safe doc outcome
|
|
932
|
+
#
|
|
917
933
|
# @private
|
|
918
|
-
# @param [
|
|
919
|
-
# @param [
|
|
920
|
-
# @param [Object] info hash containing existing doc comment block data
|
|
921
|
-
# @param [
|
|
922
|
-
# @param [
|
|
923
|
-
# @return [
|
|
934
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
935
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
936
|
+
# @param [Hash<Symbol, Object>] info hash containing existing doc comment block data
|
|
937
|
+
# @param [String] new_block the newly constructed replacement doc block string
|
|
938
|
+
# @param [Object] rest additional kwargs (old_block, merge_result,
|
|
939
|
+
# @return [void]
|
|
924
940
|
def commit_safe_doc_outcome(rewriter, buffer, info, new_block, **rest)
|
|
925
941
|
handle_doc_replacement(rewriter, buffer, info, new_block,
|
|
926
942
|
insertion: rest[:insertion], changes: rest[:changes],
|
|
@@ -931,26 +947,24 @@ module Docscribe
|
|
|
931
947
|
changes: rest[:changes], file: rest[:file])
|
|
932
948
|
end
|
|
933
949
|
|
|
934
|
-
# Filter doc params
|
|
950
|
+
# Filter doc params
|
|
951
|
+
#
|
|
935
952
|
# @private
|
|
936
|
-
# @param [Object] options the full options hash to filter
|
|
937
|
-
# @return [Object]
|
|
953
|
+
# @param [Hash<Symbol, Object>] options the full options hash to filter
|
|
954
|
+
# @return [Hash<Symbol, Object>]
|
|
938
955
|
def filter_doc_params(options)
|
|
939
956
|
options.reject { |k, _| %i[rewriter buffer insertion anchor_bol_range info changes file strategy].include?(k) }
|
|
940
957
|
end
|
|
941
958
|
|
|
942
|
-
# Handle
|
|
959
|
+
# Handle doc replacement
|
|
960
|
+
#
|
|
943
961
|
# @private
|
|
944
|
-
# @param [
|
|
945
|
-
# @param [
|
|
946
|
-
# @param [Object] info hash containing existing doc comment block data (start_pos, end_pos, lines)
|
|
947
|
-
# @param [
|
|
948
|
-
# @param [Object]
|
|
949
|
-
# @
|
|
950
|
-
# @param [Object] changes array of structured change records for reporting
|
|
951
|
-
# @param [Object] file the source file path string
|
|
952
|
-
# @param [Hash] log_opts additional keyword arguments for logging and recording changes
|
|
953
|
-
# @return [Object]
|
|
962
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
963
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
964
|
+
# @param [Hash<Symbol, Object>] info hash containing existing doc comment block data (start_pos, end_pos, lines)
|
|
965
|
+
# @param [String] new_block the newly constructed replacement doc block string
|
|
966
|
+
# @param [Object] log_opts additional keyword arguments for logging and recording changes
|
|
967
|
+
# @return [void]
|
|
954
968
|
def handle_doc_replacement(rewriter, buffer, info, new_block, **log_opts)
|
|
955
969
|
range = Parser::Source::Range.new(buffer, info[:start_pos], info[:end_pos])
|
|
956
970
|
rewriter.replace(range, new_block)
|
|
@@ -962,13 +976,13 @@ module Docscribe
|
|
|
962
976
|
message: 'unsorted tags')
|
|
963
977
|
end
|
|
964
978
|
|
|
965
|
-
# Compute
|
|
979
|
+
# Compute doc replacement
|
|
966
980
|
#
|
|
967
981
|
# @private
|
|
968
|
-
# @param [Hash] info existing doc info
|
|
969
|
-
# @param [Array<String>] missing_lines
|
|
970
|
-
# @param [
|
|
971
|
-
# @return [
|
|
982
|
+
# @param [Hash<Symbol, Object>] info existing doc info
|
|
983
|
+
# @param [Array<String>] missing_lines new doc lines to add
|
|
984
|
+
# @param [Object] options keyword options
|
|
985
|
+
# @return [(Boolean, String, String)]
|
|
972
986
|
def compute_doc_replacement(info, missing_lines, **options)
|
|
973
987
|
dc = options[:config]
|
|
974
988
|
sorted = Docscribe::InlineRewriter::DocBlock.merge(
|
|
@@ -980,17 +994,13 @@ module Docscribe
|
|
|
980
994
|
[sorted != info[:doc_lines], (info[:preserved_lines] + merged).join, info[:lines].join]
|
|
981
995
|
end
|
|
982
996
|
|
|
983
|
-
# Log
|
|
997
|
+
# Log method doc changes
|
|
984
998
|
#
|
|
985
999
|
# @private
|
|
986
|
-
# @param [Collector::Insertion] insertion
|
|
987
|
-
# @param [Hash] merge_result
|
|
988
|
-
# @param [
|
|
989
|
-
# @
|
|
990
|
-
# @param [Array<Hash>] changes
|
|
991
|
-
# @param [String] file
|
|
992
|
-
# @param [Hash] rest additional keyword arguments forwarded to add_change
|
|
993
|
-
# @return [Object]
|
|
1000
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
1001
|
+
# @param [Hash<Symbol, Object>] merge_result merge operation result
|
|
1002
|
+
# @param [Object] rest additional keyword arguments forwarded to add_change
|
|
1003
|
+
# @return [void]
|
|
994
1004
|
def log_method_doc_changes!(insertion:, merge_result:, **rest)
|
|
995
1005
|
reason_specs = merge_result[:reasons] || []
|
|
996
1006
|
type_mismatch_reasons = reason_specs.select { |r| %i[updated_param updated_return].include?(r[:type]) }
|
|
@@ -1003,16 +1013,18 @@ module Docscribe
|
|
|
1003
1013
|
end
|
|
1004
1014
|
end
|
|
1005
1015
|
|
|
1006
|
-
# Apply method insertion
|
|
1016
|
+
# Apply method insertion safe without info
|
|
1007
1017
|
#
|
|
1008
1018
|
# @private
|
|
1009
|
-
# @param [
|
|
1019
|
+
# @param [Object] options keyword options
|
|
1010
1020
|
# @return [void]
|
|
1011
1021
|
def apply_method_insertion_safe_without_info!(**options)
|
|
1012
1022
|
rewriter = options[:rewriter]
|
|
1013
1023
|
insertion = options[:insertion]
|
|
1014
1024
|
anchor_bol_range = options[:anchor_bol_range]
|
|
1015
|
-
doc =
|
|
1025
|
+
doc = DocBuilder.build(insertion, **options.reject do |k, _|
|
|
1026
|
+
%i[rewriter buffer insertion anchor_bol_range changes file strategy].include?(k)
|
|
1027
|
+
end) # steep:ignore
|
|
1016
1028
|
return if doc.nil? || doc.empty?
|
|
1017
1029
|
|
|
1018
1030
|
rewriter.insert_before(anchor_bol_range, doc)
|
|
@@ -1024,14 +1036,11 @@ module Docscribe
|
|
|
1024
1036
|
# @private
|
|
1025
1037
|
# @param [Object] options the full options hash to filter
|
|
1026
1038
|
# @return [Object]
|
|
1027
|
-
def filter_method_doc_params(options)
|
|
1028
|
-
options.reject { |k, _| %i[rewriter buffer insertion anchor_bol_range changes file strategy].include?(k) }
|
|
1029
|
-
end
|
|
1030
1039
|
|
|
1031
|
-
#
|
|
1040
|
+
# Add change
|
|
1032
1041
|
#
|
|
1033
1042
|
# @private
|
|
1034
|
-
# @param [
|
|
1043
|
+
# @param [Object] options kwargs for change record (type, file, line, method, message, insertion, changes, extra)
|
|
1035
1044
|
# @return [void]
|
|
1036
1045
|
def add_change(**options)
|
|
1037
1046
|
changes = options[:changes]
|
|
@@ -1044,20 +1053,20 @@ module Docscribe
|
|
|
1044
1053
|
}.merge(options[:extra] || {})
|
|
1045
1054
|
end
|
|
1046
1055
|
|
|
1047
|
-
#
|
|
1056
|
+
# Method id for
|
|
1048
1057
|
#
|
|
1049
1058
|
# @private
|
|
1050
|
-
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion
|
|
1059
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
1051
1060
|
# @return [String]
|
|
1052
1061
|
def method_id_for(insertion)
|
|
1053
1062
|
name = SourceHelpers.node_name(insertion.node)
|
|
1054
1063
|
"#{insertion.container}#{insertion.scope == :instance ? '#' : '.'}#{name}"
|
|
1055
1064
|
end
|
|
1056
1065
|
|
|
1057
|
-
# Apply
|
|
1066
|
+
# Apply attr insertion
|
|
1058
1067
|
#
|
|
1059
1068
|
# @private
|
|
1060
|
-
# @param [
|
|
1069
|
+
# @param [Object] options kwargs (insertion, config, rewriter, buffer, strategy,
|
|
1061
1070
|
# @return [void]
|
|
1062
1071
|
def apply_attr_insertion!(**options)
|
|
1063
1072
|
config = options[:config]
|
|
@@ -1069,13 +1078,14 @@ module Docscribe
|
|
|
1069
1078
|
dispatch_attr_strategy(params, options)
|
|
1070
1079
|
end
|
|
1071
1080
|
|
|
1081
|
+
# Attr insertion params
|
|
1072
1082
|
#
|
|
1073
1083
|
# @private
|
|
1074
|
-
# @param [
|
|
1075
|
-
# @param [
|
|
1076
|
-
# @param [
|
|
1077
|
-
# @param [
|
|
1078
|
-
# @return [Hash]
|
|
1084
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] insertion the collected attribute insertion
|
|
1085
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
1086
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider external RBS signature provider
|
|
1087
|
+
# @param [Parser::Source::Range] bol_range the beginning-of-line range for the attribute node
|
|
1088
|
+
# @return [Hash<Symbol, Docscribe::InlineRewriter::Collector::AttrInsertion, Docscribe::Config, Docscribe::Types::ProviderChain, nil, Parser::Source::Range>]
|
|
1079
1089
|
def attr_insertion_params(insertion, config, signature_provider, bol_range)
|
|
1080
1090
|
{
|
|
1081
1091
|
insertion: insertion, config: config,
|
|
@@ -1083,25 +1093,28 @@ module Docscribe
|
|
|
1083
1093
|
}
|
|
1084
1094
|
end
|
|
1085
1095
|
|
|
1086
|
-
# Dispatch attr
|
|
1096
|
+
# Dispatch attr strategy
|
|
1097
|
+
#
|
|
1087
1098
|
# @private
|
|
1088
|
-
# @param [Object] params precomputed attribute insertion parameters
|
|
1089
|
-
# @param [Object] options the full keyword options hash
|
|
1090
|
-
# @return [
|
|
1099
|
+
# @param [Hash<Symbol, Object>] params precomputed attribute insertion parameters
|
|
1100
|
+
# @param [Hash<Symbol, Object>] options the full keyword options hash
|
|
1101
|
+
# @return [void]
|
|
1091
1102
|
def dispatch_attr_strategy(params, options)
|
|
1092
1103
|
case options[:strategy]
|
|
1093
|
-
when :aggressive then apply_attr_aggressive!(params, options[:rewriter])
|
|
1104
|
+
when :aggressive then apply_attr_aggressive!(params, options[:rewriter], options[:buffer])
|
|
1094
1105
|
when :safe then apply_attr_safe!(params, options[:merge_inserts], options[:rewriter], options[:buffer])
|
|
1095
1106
|
end
|
|
1096
1107
|
end
|
|
1097
1108
|
|
|
1109
|
+
# Apply attr aggressive
|
|
1098
1110
|
#
|
|
1099
1111
|
# @private
|
|
1100
|
-
# @param [Object] params precomputed attribute insertion parameters
|
|
1101
|
-
# @param [
|
|
1102
|
-
# @
|
|
1103
|
-
|
|
1104
|
-
|
|
1112
|
+
# @param [Hash<Symbol, Object>] params precomputed attribute insertion parameters
|
|
1113
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
1114
|
+
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
1115
|
+
# @return [void]
|
|
1116
|
+
def apply_attr_aggressive!(params, rewriter, buffer)
|
|
1117
|
+
if (range = SourceHelpers.comment_block_removal_range(buffer, params[:bol_range].begin_pos))
|
|
1105
1118
|
rewriter.remove(range)
|
|
1106
1119
|
end
|
|
1107
1120
|
|
|
@@ -1112,13 +1125,14 @@ module Docscribe
|
|
|
1112
1125
|
rewriter.insert_before(params[:bol_range], doc)
|
|
1113
1126
|
end
|
|
1114
1127
|
|
|
1128
|
+
# Apply attr safe
|
|
1115
1129
|
#
|
|
1116
1130
|
# @private
|
|
1117
|
-
# @param [Object] params precomputed attribute insertion parameters
|
|
1118
|
-
# @param [
|
|
1119
|
-
# @param [
|
|
1120
|
-
# @param [
|
|
1121
|
-
# @return [
|
|
1131
|
+
# @param [Hash<Symbol, Object>] params precomputed attribute insertion parameters
|
|
1132
|
+
# @param [Hash<Integer, Array<(Integer, String)>>] merge_inserts deferred merge inserts
|
|
1133
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
1134
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
1135
|
+
# @return [void]
|
|
1122
1136
|
def apply_attr_safe!(params, merge_inserts, rewriter, buffer)
|
|
1123
1137
|
info = SourceHelpers.doc_comment_block_info(buffer, params[:bol_range].begin_pos)
|
|
1124
1138
|
|
|
@@ -1135,14 +1149,15 @@ module Docscribe
|
|
|
1135
1149
|
rewriter.insert_before(params[:bol_range], doc)
|
|
1136
1150
|
end
|
|
1137
1151
|
|
|
1152
|
+
# Merge attr additions
|
|
1138
1153
|
#
|
|
1139
1154
|
# @private
|
|
1140
|
-
# @param [
|
|
1141
|
-
# @param [Object] info hash containing existing doc comment block data
|
|
1142
|
-
# @param [
|
|
1143
|
-
# @param [
|
|
1144
|
-
# @param [
|
|
1145
|
-
# @return [
|
|
1155
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] insertion the collected attribute insertion
|
|
1156
|
+
# @param [Hash<Symbol, Object>] info hash containing existing doc comment block data
|
|
1157
|
+
# @param [Hash<Integer, Array<(Integer, String)>>] merge_inserts deferred merge inserts
|
|
1158
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
1159
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider external RBS signature provider
|
|
1160
|
+
# @return [void]
|
|
1146
1161
|
def merge_attr_additions!(insertion:, info:, merge_inserts:, config:, signature_provider:)
|
|
1147
1162
|
additions = build_attr_merge_additions(ins: insertion, existing_lines: info[:lines],
|
|
1148
1163
|
config: config, signature_provider: signature_provider)
|
|
@@ -1151,12 +1166,13 @@ module Docscribe
|
|
|
1151
1166
|
merge_inserts[info[:end_pos]] << [insertion.node.loc.expression.begin_pos, additions]
|
|
1152
1167
|
end
|
|
1153
1168
|
|
|
1169
|
+
# Apply merge inserts
|
|
1154
1170
|
#
|
|
1155
1171
|
# @private
|
|
1156
|
-
# @param [
|
|
1157
|
-
# @param [
|
|
1158
|
-
# @param [
|
|
1159
|
-
# @return [
|
|
1172
|
+
# @param [Parser::Source::TreeRewriter] rewriter the TreeRewriter accumulating source transformations
|
|
1173
|
+
# @param [Parser::Source::Buffer] buffer the source buffer being rewritten
|
|
1174
|
+
# @param [Hash<Integer, Array<(Integer, String)>>] merge_inserts deferred merge inserts
|
|
1175
|
+
# @return [void]
|
|
1160
1176
|
def apply_merge_inserts!(rewriter:, buffer:, merge_inserts:)
|
|
1161
1177
|
merge_inserts.keys.sort.reverse_each do |end_pos|
|
|
1162
1178
|
text = merge_text_for_pos(merge_inserts[end_pos])
|
|
@@ -1167,10 +1183,11 @@ module Docscribe
|
|
|
1167
1183
|
end
|
|
1168
1184
|
end
|
|
1169
1185
|
|
|
1186
|
+
# Merge text for pos
|
|
1170
1187
|
#
|
|
1171
1188
|
# @private
|
|
1172
|
-
# @param [
|
|
1173
|
-
# @return [
|
|
1189
|
+
# @param [Array<(Integer, String)>] chunks merge chunks at position
|
|
1190
|
+
# @return [String, nil]
|
|
1174
1191
|
def merge_text_for_pos(chunks)
|
|
1175
1192
|
return nil if chunks.empty?
|
|
1176
1193
|
|
|
@@ -1188,12 +1205,13 @@ module Docscribe
|
|
|
1188
1205
|
text.empty? ? nil : text
|
|
1189
1206
|
end
|
|
1190
1207
|
|
|
1191
|
-
# Merge
|
|
1208
|
+
# Merge chunk into out
|
|
1209
|
+
#
|
|
1192
1210
|
# @private
|
|
1193
|
-
# @param [
|
|
1194
|
-
# @param [
|
|
1195
|
-
# @param [
|
|
1196
|
-
# @return [
|
|
1211
|
+
# @param [String] chunk the doc text string to merge
|
|
1212
|
+
# @param [Array<String>] out_lines the accumulated output lines array
|
|
1213
|
+
# @param [Regexp] sep_re regex matching separator comment lines (# followed by newline)
|
|
1214
|
+
# @return [void]
|
|
1197
1215
|
def merge_chunk_into_out(chunk, out_lines, sep_re)
|
|
1198
1216
|
lines = chunk.lines
|
|
1199
1217
|
seps = extract_separators(lines, sep_re)
|
|
@@ -1202,25 +1220,27 @@ module Docscribe
|
|
|
1202
1220
|
out_lines.concat(lines)
|
|
1203
1221
|
end
|
|
1204
1222
|
|
|
1205
|
-
# Extract
|
|
1223
|
+
# Extract separators
|
|
1224
|
+
#
|
|
1206
1225
|
# @private
|
|
1207
|
-
# @param [
|
|
1208
|
-
# @param [
|
|
1209
|
-
# @return [
|
|
1226
|
+
# @param [Array<String>] lines array of lines from the chunk
|
|
1227
|
+
# @param [Regexp] sep_re regex matching separator comment lines
|
|
1228
|
+
# @return [Array<String>]
|
|
1210
1229
|
def extract_separators(lines, sep_re)
|
|
1211
1230
|
seps = [] #: Array[String]
|
|
1212
1231
|
seps << lines.shift while !lines.empty? && lines.first.match?(sep_re)
|
|
1213
1232
|
seps
|
|
1214
1233
|
end
|
|
1215
1234
|
|
|
1235
|
+
# Build attr merge additions
|
|
1216
1236
|
#
|
|
1217
1237
|
# @private
|
|
1218
|
-
# @param [
|
|
1219
|
-
# @param [
|
|
1220
|
-
# @param [
|
|
1221
|
-
# @param [
|
|
1238
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1239
|
+
# @param [Array<String>] existing_lines array of existing doc comment lines
|
|
1240
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
1241
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider external RBS signature provider
|
|
1222
1242
|
# @raise [StandardError]
|
|
1223
|
-
# @return [
|
|
1243
|
+
# @return [String, nil] if StandardError
|
|
1224
1244
|
# @return [nil] if StandardError
|
|
1225
1245
|
def build_attr_merge_additions(ins:, existing_lines:, config:, signature_provider:)
|
|
1226
1246
|
missing = missing_attr_names(ins, existing_lines)
|
|
@@ -1236,37 +1256,39 @@ module Docscribe
|
|
|
1236
1256
|
nil
|
|
1237
1257
|
end
|
|
1238
1258
|
|
|
1259
|
+
# Missing attr names
|
|
1239
1260
|
#
|
|
1240
1261
|
# @private
|
|
1241
|
-
# @param [
|
|
1242
|
-
# @param [
|
|
1243
|
-
# @return [
|
|
1262
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1263
|
+
# @param [Array<String>] existing_lines array of existing doc comment lines
|
|
1264
|
+
# @return [Array<Symbol>]
|
|
1244
1265
|
def missing_attr_names(ins, existing_lines)
|
|
1245
1266
|
existing = existing_attr_names(existing_lines)
|
|
1246
1267
|
ins.names.reject { |name_sym| existing[name_sym.to_s] }
|
|
1247
1268
|
end
|
|
1248
1269
|
|
|
1270
|
+
# Existing attr names
|
|
1249
1271
|
#
|
|
1250
1272
|
# @private
|
|
1251
|
-
# @param [
|
|
1252
|
-
# @return [
|
|
1273
|
+
# @param [Array<String>] lines array of existing doc comment lines
|
|
1274
|
+
# @return [Hash<String, nil, Boolean>]
|
|
1253
1275
|
def existing_attr_names(lines)
|
|
1254
1276
|
names = {} #: Hash[String, bool]
|
|
1255
1277
|
|
|
1256
1278
|
Array(lines).each do |line|
|
|
1257
1279
|
if (m = line.match(/^\s*#\s*@!attribute\b(?:\s+\[[^\]]+\])?\s+(\S+)/))
|
|
1258
|
-
names[m[1]] = true
|
|
1280
|
+
names[m[1].to_s] = true
|
|
1259
1281
|
end
|
|
1260
1282
|
end
|
|
1261
1283
|
|
|
1262
1284
|
names
|
|
1263
1285
|
end
|
|
1264
1286
|
|
|
1265
|
-
#
|
|
1287
|
+
# Attribute allowed
|
|
1266
1288
|
#
|
|
1267
1289
|
# @private
|
|
1268
|
-
# @param [Docscribe::Config] config
|
|
1269
|
-
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins
|
|
1290
|
+
# @param [Docscribe::Config] config the active configuration
|
|
1291
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1270
1292
|
# @return [Boolean]
|
|
1271
1293
|
def attribute_allowed?(config, ins)
|
|
1272
1294
|
ins.names.any? do |name_sym|
|
|
@@ -1274,12 +1296,13 @@ module Docscribe
|
|
|
1274
1296
|
end
|
|
1275
1297
|
end
|
|
1276
1298
|
|
|
1299
|
+
# Allowed for access
|
|
1277
1300
|
#
|
|
1278
1301
|
# @private
|
|
1279
|
-
# @param [
|
|
1280
|
-
# @param [
|
|
1281
|
-
# @param [
|
|
1282
|
-
# @return [
|
|
1302
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
1303
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1304
|
+
# @param [Symbol] name_sym the attribute name as a Symbol
|
|
1305
|
+
# @return [Boolean]
|
|
1283
1306
|
def allowed_for_access?(config, ins, name_sym)
|
|
1284
1307
|
ok = false
|
|
1285
1308
|
|
|
@@ -1296,13 +1319,14 @@ module Docscribe
|
|
|
1296
1319
|
ok
|
|
1297
1320
|
end
|
|
1298
1321
|
|
|
1322
|
+
# Build attr doc for node
|
|
1299
1323
|
#
|
|
1300
1324
|
# @private
|
|
1301
|
-
# @param [
|
|
1302
|
-
# @param [
|
|
1303
|
-
# @param [
|
|
1325
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1326
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
1327
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider external RBS signature provider
|
|
1304
1328
|
# @raise [StandardError]
|
|
1305
|
-
# @return [
|
|
1329
|
+
# @return [String, nil] if StandardError
|
|
1306
1330
|
# @return [nil] if StandardError
|
|
1307
1331
|
def build_attr_doc_for_node(ins, config:, signature_provider:)
|
|
1308
1332
|
indent = SourceHelpers.line_indent(ins.node)
|
|
@@ -1312,14 +1336,15 @@ module Docscribe
|
|
|
1312
1336
|
nil
|
|
1313
1337
|
end
|
|
1314
1338
|
|
|
1339
|
+
# Build attr doc lines
|
|
1315
1340
|
#
|
|
1316
1341
|
# @private
|
|
1317
|
-
# @param [
|
|
1318
|
-
# @param [
|
|
1319
|
-
# @param [
|
|
1320
|
-
# @param [
|
|
1321
|
-
# @param [nil] names optional subset of attribute names to document (defaults to all names)
|
|
1322
|
-
# @return [
|
|
1342
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1343
|
+
# @param [String] indent whitespace indentation prefix derived from the attribute node
|
|
1344
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
1345
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider external RBS signature provider
|
|
1346
|
+
# @param [Array<Symbol>, nil?] names optional subset of attribute names to document (defaults to all names)
|
|
1347
|
+
# @return [Array<String>]
|
|
1323
1348
|
def build_attr_doc_lines(ins, indent:, config:, signature_provider:, names: nil)
|
|
1324
1349
|
names ||= ins.names
|
|
1325
1350
|
lines = [] #: Array[untyped]
|
|
@@ -1333,17 +1358,14 @@ module Docscribe
|
|
|
1333
1358
|
lines
|
|
1334
1359
|
end
|
|
1335
1360
|
|
|
1336
|
-
# Build
|
|
1361
|
+
# Build single attr lines
|
|
1362
|
+
#
|
|
1337
1363
|
# @private
|
|
1338
|
-
# @param [
|
|
1339
|
-
# @param [
|
|
1340
|
-
# @param [
|
|
1341
|
-
# @param [Object]
|
|
1342
|
-
# @
|
|
1343
|
-
# @param [Object] config the active Docscribe::Config
|
|
1344
|
-
# @param [Object] signature_provider external RBS signature provider
|
|
1345
|
-
# @param [Hash] opts additional keyword arguments forwarded from build_attr_doc_lines
|
|
1346
|
-
# @return [Object]
|
|
1364
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1365
|
+
# @param [Symbol] name_sym the attribute name as a Symbol
|
|
1366
|
+
# @param [String] indent whitespace indentation prefix
|
|
1367
|
+
# @param [Object] opts additional keyword arguments forwarded from build_attr_doc_lines
|
|
1368
|
+
# @return [Array<String>]
|
|
1347
1369
|
def build_single_attr_lines(ins, name_sym, indent:, **opts)
|
|
1348
1370
|
cfg = opts[:config]
|
|
1349
1371
|
attr_type = attribute_type(ins, name_sym, cfg, signature_provider: opts[:signature_provider])
|
|
@@ -1355,37 +1377,40 @@ module Docscribe
|
|
|
1355
1377
|
lines
|
|
1356
1378
|
end
|
|
1357
1379
|
|
|
1358
|
-
# Append
|
|
1380
|
+
# Append attr return tag
|
|
1381
|
+
#
|
|
1359
1382
|
# @private
|
|
1360
|
-
# @param [
|
|
1361
|
-
# @param [
|
|
1362
|
-
# @param [
|
|
1363
|
-
# @param [
|
|
1364
|
-
# @return [
|
|
1383
|
+
# @param [Array<String>] lines the doc lines array being built
|
|
1384
|
+
# @param [String] indent whitespace indentation prefix
|
|
1385
|
+
# @param [String] attr_type the resolved type string for the attribute
|
|
1386
|
+
# @param [Symbol] access the access level (:r, :w, or :rw)
|
|
1387
|
+
# @return [void]
|
|
1365
1388
|
def append_attr_return_tag(lines, indent, attr_type, access)
|
|
1366
1389
|
lines << "#{indent}# @return [#{attr_type}]" if %i[r rw].include?(access)
|
|
1367
1390
|
end
|
|
1368
1391
|
|
|
1369
|
-
# Append
|
|
1392
|
+
# Append attr param tag
|
|
1393
|
+
#
|
|
1370
1394
|
# @private
|
|
1371
|
-
# @param [
|
|
1372
|
-
# @param [
|
|
1373
|
-
# @param [
|
|
1374
|
-
# @param [
|
|
1375
|
-
# @param [
|
|
1376
|
-
# @return [
|
|
1395
|
+
# @param [Array<String>] lines the doc lines array being built
|
|
1396
|
+
# @param [String] indent whitespace indentation prefix
|
|
1397
|
+
# @param [String] attr_type the resolved type string for the attribute
|
|
1398
|
+
# @param [Symbol] access the access level (:r, :w, or :rw)
|
|
1399
|
+
# @param [Docscribe::Config] cfg the active Docscribe::Config
|
|
1400
|
+
# @return [void]
|
|
1377
1401
|
def append_attr_param_tag(lines, indent, attr_type, access, cfg)
|
|
1378
1402
|
return unless %i[w rw].include?(access)
|
|
1379
1403
|
|
|
1380
1404
|
lines << format_attribute_param_tag(indent, 'value', attr_type, style: cfg.param_tag_style)
|
|
1381
1405
|
end
|
|
1382
1406
|
|
|
1383
|
-
#
|
|
1407
|
+
# Attr visibility lines
|
|
1408
|
+
#
|
|
1384
1409
|
# @private
|
|
1385
|
-
# @param [
|
|
1386
|
-
# @param [
|
|
1387
|
-
# @param [
|
|
1388
|
-
# @return [
|
|
1410
|
+
# @param [String] indent whitespace indentation prefix
|
|
1411
|
+
# @param [Docscribe::Config] config the active Docscribe::Config
|
|
1412
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1413
|
+
# @return [Array<String>]
|
|
1389
1414
|
def attr_visibility_lines(indent, config, ins)
|
|
1390
1415
|
return [] unless config.emit_visibility_tags?
|
|
1391
1416
|
|
|
@@ -1395,11 +1420,11 @@ module Docscribe
|
|
|
1395
1420
|
lines
|
|
1396
1421
|
end
|
|
1397
1422
|
|
|
1398
|
-
# Format
|
|
1423
|
+
# Format attribute param tag
|
|
1399
1424
|
#
|
|
1400
1425
|
# @private
|
|
1401
1426
|
# @param [String] indent leading whitespace
|
|
1402
|
-
# @param [
|
|
1427
|
+
# @param [String] name attribute name
|
|
1403
1428
|
# @param [String] type attribute type
|
|
1404
1429
|
# @param [String, Symbol] style param tag style (`"name_type"` or `"type_name"`)
|
|
1405
1430
|
# @return [String] formatted doc line
|
|
@@ -1414,17 +1439,16 @@ module Docscribe
|
|
|
1414
1439
|
end
|
|
1415
1440
|
end
|
|
1416
1441
|
|
|
1417
|
-
#
|
|
1418
|
-
#
|
|
1419
|
-
# Prefers the RBS reader signature when available; otherwise falls back to the config fallback type.
|
|
1442
|
+
# Attribute type
|
|
1420
1443
|
#
|
|
1421
1444
|
# @private
|
|
1422
|
-
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins
|
|
1423
|
-
# @param [Symbol] name_sym
|
|
1424
|
-
# @param [Docscribe::Config] config
|
|
1425
|
-
# @param [
|
|
1445
|
+
# @param [Docscribe::InlineRewriter::Collector::AttrInsertion] ins the attribute insertion object
|
|
1446
|
+
# @param [Symbol] name_sym the attribute name as a Symbol
|
|
1447
|
+
# @param [Docscribe::Config] config the active configuration
|
|
1448
|
+
# @param [Docscribe::Types::ProviderChain, nil] signature_provider RBS signature provider
|
|
1426
1449
|
# @raise [StandardError]
|
|
1427
|
-
# @return [String]
|
|
1450
|
+
# @return [String] if StandardError
|
|
1451
|
+
# @return [Object] if StandardError
|
|
1428
1452
|
def attribute_type(ins, name_sym, config, signature_provider:)
|
|
1429
1453
|
ty = config.fallback_type
|
|
1430
1454
|
return ty unless signature_provider
|
|
@@ -1435,21 +1459,20 @@ module Docscribe
|
|
|
1435
1459
|
config.fallback_type
|
|
1436
1460
|
end
|
|
1437
1461
|
|
|
1438
|
-
# Build
|
|
1439
|
-
#
|
|
1440
|
-
# Checks config methods in order: `signature_provider_for`, `signature_provider`, `rbs_provider`.
|
|
1462
|
+
# Build signature provider
|
|
1441
1463
|
#
|
|
1442
1464
|
# @private
|
|
1443
1465
|
# @param [Docscribe::Config] config the active configuration
|
|
1444
1466
|
# @param [String] code the source code being processed
|
|
1445
1467
|
# @param [String] file the file name
|
|
1446
1468
|
# @raise [StandardError]
|
|
1447
|
-
# @return [Object, nil]
|
|
1469
|
+
# @return [Object, nil] if StandardError
|
|
1470
|
+
# @return [Object?] if StandardError
|
|
1448
1471
|
def build_signature_provider(config, code, file)
|
|
1449
1472
|
if config.respond_to?(:signature_provider_for)
|
|
1450
1473
|
config.signature_provider_for(source: code, file: file)
|
|
1451
1474
|
elsif config.respond_to?(:signature_provider)
|
|
1452
|
-
config.signature_provider
|
|
1475
|
+
config.signature_provider # steep:ignore
|
|
1453
1476
|
elsif config.respond_to?(:rbs_provider)
|
|
1454
1477
|
config.rbs_provider
|
|
1455
1478
|
end
|
|
@@ -1457,33 +1480,12 @@ module Docscribe
|
|
|
1457
1480
|
config.respond_to?(:rbs_provider) ? config.rbs_provider : nil
|
|
1458
1481
|
end
|
|
1459
1482
|
|
|
1460
|
-
#
|
|
1461
|
-
#
|
|
1462
|
-
# @private
|
|
1463
|
-
# @param [Collector::Insertion] insertion the collected method insertion
|
|
1464
|
-
# @param [Hash] options kwargs for DocBuilder.build (param_types, return_type_override, override_tags, config)
|
|
1465
|
-
# @return [String, nil] generated doc block or nil
|
|
1466
|
-
def build_method_doc(insertion, **options)
|
|
1467
|
-
DocBuilder.build(insertion, **options)
|
|
1468
|
-
end
|
|
1469
|
-
|
|
1470
|
-
# Delegate to DocBuilder.build_missing_merge_result for generating missing doc lines only.
|
|
1471
|
-
#
|
|
1472
|
-
# @private
|
|
1473
|
-
# @param [Collector::Insertion] insertion the collected method insertion
|
|
1474
|
-
# @param [Array<String>] existing_lines existing doc-like lines
|
|
1475
|
-
# @param [Hash] options keyword arguments forwarded to DocBuilder.build_missing_merge_result
|
|
1476
|
-
# @return [Hash] result with `:lines` and `:reasons` keys
|
|
1477
|
-
def build_missing_method_merge_result(insertion, existing_lines:, **options)
|
|
1478
|
-
DocBuilder.build_missing_merge_result(insertion, existing_lines: existing_lines, **options)
|
|
1479
|
-
end
|
|
1480
|
-
|
|
1481
|
-
# Get doc comment block info (preceding comments) for a method insertion.
|
|
1483
|
+
# Method doc comment info
|
|
1482
1484
|
#
|
|
1483
1485
|
# @private
|
|
1484
1486
|
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
1485
|
-
# @param [Collector::Insertion] insertion the collected method insertion
|
|
1486
|
-
# @return [Hash, nil] doc comment block info or nil
|
|
1487
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
1488
|
+
# @return [Hash<Symbol, Object>, nil] doc comment block info or nil
|
|
1487
1489
|
def method_doc_comment_info(buffer, insertion)
|
|
1488
1490
|
anchor_bol_range, def_bol_range = method_bol_ranges(buffer, insertion)
|
|
1489
1491
|
|
|
@@ -1491,11 +1493,11 @@ module Docscribe
|
|
|
1491
1493
|
SourceHelpers.doc_comment_block_info(buffer, def_bol_range.begin_pos)
|
|
1492
1494
|
end
|
|
1493
1495
|
|
|
1494
|
-
#
|
|
1496
|
+
# Method comment block removal range
|
|
1495
1497
|
#
|
|
1496
1498
|
# @private
|
|
1497
1499
|
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
1498
|
-
# @param [Collector::Insertion] insertion the collected method insertion
|
|
1500
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
1499
1501
|
# @return [Parser::Source::Range, nil]
|
|
1500
1502
|
def method_comment_block_removal_range(buffer, insertion)
|
|
1501
1503
|
anchor_bol_range, def_bol_range = method_bol_ranges(buffer, insertion)
|
|
@@ -1504,12 +1506,12 @@ module Docscribe
|
|
|
1504
1506
|
SourceHelpers.comment_block_removal_range(buffer, def_bol_range.begin_pos)
|
|
1505
1507
|
end
|
|
1506
1508
|
|
|
1507
|
-
#
|
|
1509
|
+
# Method bol ranges
|
|
1508
1510
|
#
|
|
1509
1511
|
# @private
|
|
1510
1512
|
# @param [Parser::Source::Buffer] buffer the source buffer
|
|
1511
|
-
# @param [Collector::Insertion] insertion the collected method insertion
|
|
1512
|
-
# @return [
|
|
1513
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
1514
|
+
# @return [(Parser::Source::Range, Parser::Source::Range)]
|
|
1513
1515
|
def method_bol_ranges(buffer, insertion)
|
|
1514
1516
|
anchor_node = anchor_node_for(insertion)
|
|
1515
1517
|
[
|
|
@@ -1518,22 +1520,23 @@ module Docscribe
|
|
|
1518
1520
|
]
|
|
1519
1521
|
end
|
|
1520
1522
|
|
|
1521
|
-
#
|
|
1523
|
+
# Method line for
|
|
1522
1524
|
#
|
|
1523
1525
|
# @private
|
|
1524
|
-
# @param [Collector::Insertion] insertion the collected method insertion
|
|
1526
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
1525
1527
|
# @raise [StandardError]
|
|
1526
|
-
# @return [Integer]
|
|
1528
|
+
# @return [Integer] if StandardError
|
|
1529
|
+
# @return [Object] if StandardError
|
|
1527
1530
|
def method_line_for(insertion)
|
|
1528
1531
|
anchor_node_for(insertion).loc.expression.line
|
|
1529
1532
|
rescue StandardError
|
|
1530
1533
|
insertion.node.loc.expression.line
|
|
1531
1534
|
end
|
|
1532
1535
|
|
|
1533
|
-
#
|
|
1536
|
+
# Anchor node for
|
|
1534
1537
|
#
|
|
1535
1538
|
# @private
|
|
1536
|
-
# @param [Collector::Insertion] insertion the collected method insertion
|
|
1539
|
+
# @param [Docscribe::InlineRewriter::Collector::Insertion] insertion the collected method insertion
|
|
1537
1540
|
# @return [Parser::AST::Node]
|
|
1538
1541
|
def anchor_node_for(insertion)
|
|
1539
1542
|
if insertion.respond_to?(:anchor_node) && insertion.anchor_node
|
|
@@ -1543,11 +1546,11 @@ module Docscribe
|
|
|
1543
1546
|
end
|
|
1544
1547
|
end
|
|
1545
1548
|
|
|
1546
|
-
# Extract method override
|
|
1549
|
+
# Extract method override
|
|
1547
1550
|
#
|
|
1548
1551
|
# @private
|
|
1549
|
-
# @param [Object] method_override the raw override data
|
|
1550
|
-
# @return [Hash
|
|
1552
|
+
# @param [Hash<Symbol, Object>, nil] method_override the raw override data
|
|
1553
|
+
# @return [Hash<Symbol, Object>] normalized override hash
|
|
1551
1554
|
def extract_method_override!(method_override)
|
|
1552
1555
|
return {} unless method_override.is_a?(Hash)
|
|
1553
1556
|
|
|
@@ -1558,7 +1561,7 @@ module Docscribe
|
|
|
1558
1561
|
}
|
|
1559
1562
|
end
|
|
1560
1563
|
|
|
1561
|
-
# Normalize override tags
|
|
1564
|
+
# Normalize override tags
|
|
1562
1565
|
#
|
|
1563
1566
|
# @private
|
|
1564
1567
|
# @param [Array<Object>] tags raw tag values
|