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
|
@@ -14,18 +14,19 @@ module Docscribe
|
|
|
14
14
|
# The provider returns Docscribe's normalized signature model so the rest of
|
|
15
15
|
# the pipeline can stay independent of the underlying signature source.
|
|
16
16
|
class Provider
|
|
17
|
+
# Initialize
|
|
18
|
+
#
|
|
17
19
|
# @param [Array<String>] sig_dirs directories containing `.rbs` files
|
|
18
20
|
# @param [Array<String>] collection_dirs RBS collection directories
|
|
19
|
-
# (loaded separately; on error they are silently dropped and only
|
|
20
|
-
# user sig_dirs are used)
|
|
21
21
|
# @param [Boolean] collapse_generics whether generic container types
|
|
22
|
-
#
|
|
23
|
-
# @return [
|
|
24
|
-
def initialize(sig_dirs:, collection_dirs: [], collapse_generics: false)
|
|
22
|
+
# @param [Boolean] collapse_object_generics collapse Object generics flag
|
|
23
|
+
# @return [void]
|
|
24
|
+
def initialize(sig_dirs:, collection_dirs: [], collapse_generics: false, collapse_object_generics: false)
|
|
25
25
|
require 'rbs'
|
|
26
26
|
@sig_dirs = Array(sig_dirs).map(&:to_s)
|
|
27
27
|
@collection_dirs = Array(collection_dirs).map(&:to_s)
|
|
28
28
|
@collapse_generics = !!collapse_generics
|
|
29
|
+
@collapse_object_generics = !!collapse_object_generics
|
|
29
30
|
@env = nil
|
|
30
31
|
@builder = nil
|
|
31
32
|
@warned = false
|
|
@@ -41,7 +42,9 @@ module Docscribe
|
|
|
41
42
|
# @param [Symbol, String] name method name
|
|
42
43
|
# @raise [::RBS::BaseError]
|
|
43
44
|
# @raise [StandardError]
|
|
44
|
-
# @return [Docscribe::Types::MethodSignature, nil]
|
|
45
|
+
# @return [Docscribe::Types::MethodSignature, nil] if StandardError
|
|
46
|
+
# @return [nil] if ::RBS::BaseError
|
|
47
|
+
# @return [nil] if StandardError
|
|
45
48
|
def signature_for(container:, scope:, name:)
|
|
46
49
|
load_env!
|
|
47
50
|
lookup_signature(container, scope, name)
|
|
@@ -63,8 +66,6 @@ module Docscribe
|
|
|
63
66
|
# dirs are dropped and only user sig_dirs are used.
|
|
64
67
|
#
|
|
65
68
|
# @private
|
|
66
|
-
# @raise [::RBS::BaseError]
|
|
67
|
-
# @raise [StandardError]
|
|
68
69
|
# @return [void]
|
|
69
70
|
def load_env!
|
|
70
71
|
return if @env && @builder
|
|
@@ -84,13 +85,16 @@ module Docscribe
|
|
|
84
85
|
# @return [Docscribe::Types::MethodSignature, nil]
|
|
85
86
|
def lookup_signature(container, scope, name)
|
|
86
87
|
definition = definition_for(container: container, scope: scope)
|
|
88
|
+
return nil unless definition
|
|
89
|
+
|
|
87
90
|
method_def = definition.methods[name.to_sym]
|
|
88
91
|
return nil unless method_def
|
|
89
92
|
|
|
90
93
|
method_type = method_def.method_types.first
|
|
91
94
|
return nil unless method_type
|
|
92
95
|
|
|
93
|
-
|
|
96
|
+
func = method_type.type #: ::RBS::Types::Function
|
|
97
|
+
build_signature(func)
|
|
94
98
|
end
|
|
95
99
|
|
|
96
100
|
# Try building an environment from combined dirs, falling back to
|
|
@@ -98,10 +102,11 @@ module Docscribe
|
|
|
98
102
|
#
|
|
99
103
|
# @private
|
|
100
104
|
# @param [Array<String>] all_dirs combined sig and collection dirs
|
|
101
|
-
# @param [Array<String>] collection_dirs
|
|
105
|
+
# @param [Array<String>] collection_dirs RBS collection directories
|
|
102
106
|
# @raise [::RBS::BaseError]
|
|
103
107
|
# @raise [StandardError]
|
|
104
|
-
# @return [
|
|
108
|
+
# @return [RBS::Environment] if ::RBS::BaseError
|
|
109
|
+
# @return [Object] if ::RBS::BaseError
|
|
105
110
|
def try_with_fallback_build_env(all_dirs, collection_dirs)
|
|
106
111
|
build_env(all_dirs)
|
|
107
112
|
rescue ::RBS::BaseError => e
|
|
@@ -118,12 +123,12 @@ module Docscribe
|
|
|
118
123
|
# Build an RBS environment from the given directories.
|
|
119
124
|
#
|
|
120
125
|
# @private
|
|
121
|
-
# @param [Array<String>] dirs
|
|
122
|
-
# @return [
|
|
126
|
+
# @param [Array<String>] dirs directories to load RBS from
|
|
127
|
+
# @return [RBS::Environment]
|
|
123
128
|
def build_env(dirs)
|
|
124
129
|
loader = ::RBS::EnvironmentLoader.new
|
|
125
130
|
# Load core types transitively
|
|
126
|
-
loader.add(library: 'rbs')
|
|
131
|
+
loader.add(library: 'rbs') # steep:ignore
|
|
127
132
|
|
|
128
133
|
dirs.each do |dir|
|
|
129
134
|
path = Pathname(dir)
|
|
@@ -138,9 +143,9 @@ module Docscribe
|
|
|
138
143
|
# Build the appropriate instance or singleton definition for a container.
|
|
139
144
|
#
|
|
140
145
|
# @private
|
|
141
|
-
# @param [String] container
|
|
142
|
-
# @param [Symbol] scope
|
|
143
|
-
# @return [
|
|
146
|
+
# @param [String] container fully qualified class/module name
|
|
147
|
+
# @param [Symbol] scope :instance or :class
|
|
148
|
+
# @return [RBS::Definition, nil]
|
|
144
149
|
def definition_for(container:, scope:)
|
|
145
150
|
type_name = parse_type_name(absolute_const(container))
|
|
146
151
|
scope == :class ? @builder&.build_singleton(type_name) : @builder&.build_instance(type_name)
|
|
@@ -153,7 +158,7 @@ module Docscribe
|
|
|
153
158
|
#
|
|
154
159
|
# @private
|
|
155
160
|
# @param [String] string e.g. "::Irb::Autosuggestions"
|
|
156
|
-
# @return [
|
|
161
|
+
# @return [RBS::TypeName]
|
|
157
162
|
def parse_type_name(string)
|
|
158
163
|
absolute = string.start_with?('::')
|
|
159
164
|
*path, name = string.delete_prefix('::').split('::').map(&:to_sym)
|
|
@@ -167,7 +172,7 @@ module Docscribe
|
|
|
167
172
|
# Normalize a container name into an absolute constant path.
|
|
168
173
|
#
|
|
169
174
|
# @private
|
|
170
|
-
# @param [String] container
|
|
175
|
+
# @param [String] container fully qualified class/module name
|
|
171
176
|
# @return [String]
|
|
172
177
|
def absolute_const(container)
|
|
173
178
|
s = container.to_s
|
|
@@ -178,40 +183,49 @@ module Docscribe
|
|
|
178
183
|
# model.
|
|
179
184
|
#
|
|
180
185
|
# @private
|
|
181
|
-
# @param [
|
|
186
|
+
# @param [RBS::Types::Function] func RBS function type to convert
|
|
182
187
|
# @return [Docscribe::Types::MethodSignature]
|
|
183
188
|
def build_signature(func)
|
|
189
|
+
param_types, positional_types = build_param_types(func)
|
|
184
190
|
MethodSignature.new(
|
|
185
191
|
return_type: format_type(func.return_type),
|
|
186
|
-
param_types:
|
|
192
|
+
param_types: param_types,
|
|
193
|
+
positional_types: positional_types,
|
|
187
194
|
rest_positional: build_rest_positional(func),
|
|
188
195
|
rest_keywords: build_rest_keywords(func)
|
|
189
196
|
)
|
|
190
197
|
end
|
|
191
198
|
|
|
192
|
-
# Build a name => type map
|
|
199
|
+
# Build a name => type map and positional type list for all
|
|
200
|
+
# positional and keyword parameters.
|
|
201
|
+
#
|
|
202
|
+
# Returns [param_types (Hash), positional_types (Array)].
|
|
203
|
+
# positional_types includes ALL positional params in order (named
|
|
204
|
+
# and unnamed) so callers can fall back to positional matching when
|
|
205
|
+
# the RBS signature omits parameter names.
|
|
193
206
|
#
|
|
194
207
|
# @private
|
|
195
|
-
# @param [
|
|
196
|
-
# @return [Hash
|
|
208
|
+
# @param [RBS::Types::Function] func RBS function to extract params
|
|
209
|
+
# @return [(Hash<String, String>, Array<String>)]
|
|
197
210
|
def build_param_types(func)
|
|
198
211
|
param_types = {} #: Hash[String, String]
|
|
212
|
+
positional_types = [] #: Array[String]
|
|
199
213
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
214
|
+
collect_positionals!(param_types, positional_types, func.required_positionals)
|
|
215
|
+
collect_positionals!(param_types, positional_types, func.optional_positionals)
|
|
216
|
+
collect_positionals!(param_types, positional_types, func.trailing_positionals)
|
|
203
217
|
|
|
204
218
|
add_keywords!(param_types, func.required_keywords)
|
|
205
219
|
add_keywords!(param_types, func.optional_keywords)
|
|
206
220
|
|
|
207
|
-
param_types
|
|
221
|
+
[param_types, positional_types]
|
|
208
222
|
end
|
|
209
223
|
|
|
210
224
|
# Add keyword parameters to the normalized parameter map.
|
|
211
225
|
#
|
|
212
226
|
# @private
|
|
213
|
-
# @param [Hash
|
|
214
|
-
# @param [Hash
|
|
227
|
+
# @param [Hash<String, String>] param_types normalized param type map
|
|
228
|
+
# @param [Hash<Symbol, RBS::Types::Function::Param>] keywords keyword parameter entries
|
|
215
229
|
# @return [void]
|
|
216
230
|
def add_keywords!(param_types, keywords)
|
|
217
231
|
keywords.each do |kw, p|
|
|
@@ -219,24 +233,26 @@ module Docscribe
|
|
|
219
233
|
end
|
|
220
234
|
end
|
|
221
235
|
|
|
222
|
-
#
|
|
236
|
+
# Collect positional parameter types into both the name-keyed hash
|
|
237
|
+
# (when a name is available) and the ordered-position list (always).
|
|
223
238
|
#
|
|
224
239
|
# @private
|
|
225
|
-
# @param [Hash
|
|
226
|
-
# @param [Array<
|
|
240
|
+
# @param [Hash<String, String>] param_types normalized param type map
|
|
241
|
+
# @param [Array<String>] positional_types ordered type list
|
|
242
|
+
# @param [Array<RBS::Types::Function::Param>] list positional parameter objects
|
|
227
243
|
# @return [void]
|
|
228
|
-
def
|
|
244
|
+
def collect_positionals!(param_types, positional_types, list)
|
|
229
245
|
list.each do |p|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
param_types[p.name.to_s] =
|
|
246
|
+
type_str = format_type(p.type)
|
|
247
|
+
positional_types << type_str
|
|
248
|
+
param_types[p.name.to_s] = type_str if p.name
|
|
233
249
|
end
|
|
234
250
|
end
|
|
235
251
|
|
|
236
252
|
# Build normalized `*args` metadata.
|
|
237
253
|
#
|
|
238
254
|
# @private
|
|
239
|
-
# @param [
|
|
255
|
+
# @param [RBS::Types::Function] func RBS function for rest params
|
|
240
256
|
# @return [Docscribe::Types::RestPositional, nil]
|
|
241
257
|
def build_rest_positional(func)
|
|
242
258
|
rp = func.rest_positionals
|
|
@@ -251,7 +267,7 @@ module Docscribe
|
|
|
251
267
|
# Build normalized `**kwargs` metadata.
|
|
252
268
|
#
|
|
253
269
|
# @private
|
|
254
|
-
# @param [
|
|
270
|
+
# @param [RBS::Types::Function] func RBS function for rest keywords
|
|
255
271
|
# @return [Docscribe::Types::RestKeywords, nil]
|
|
256
272
|
def build_rest_keywords(func)
|
|
257
273
|
rk = func.rest_keywords
|
|
@@ -267,21 +283,21 @@ module Docscribe
|
|
|
267
283
|
# generated comments.
|
|
268
284
|
#
|
|
269
285
|
# @private
|
|
270
|
-
# @param [
|
|
286
|
+
# @param [Docscribe::Types::RBS::TypeFormatter::rbs_type] type RBS type object to format
|
|
271
287
|
# @return [String]
|
|
272
288
|
def format_type(type)
|
|
273
289
|
Docscribe::Types::RBS::TypeFormatter.to_yard(
|
|
274
290
|
type,
|
|
275
|
-
collapse_generics: @collapse_generics
|
|
291
|
+
collapse_generics: @collapse_generics,
|
|
292
|
+
collapse_object_generics: @collapse_object_generics
|
|
276
293
|
)
|
|
277
294
|
end
|
|
278
295
|
|
|
279
296
|
# Emit a formatted RBS error warning with context-specific messaging.
|
|
280
297
|
#
|
|
281
298
|
# @private
|
|
282
|
-
# @param [StandardError]
|
|
299
|
+
# @param [RBS::BaseError, StandardError] error the raised exception
|
|
283
300
|
# @param [String] context human-readable context label
|
|
284
|
-
# @param [StandardError] error the raised exception
|
|
285
301
|
# @return [void]
|
|
286
302
|
def handle_rbs_error(error, context)
|
|
287
303
|
case error
|
|
@@ -298,7 +314,7 @@ module Docscribe
|
|
|
298
314
|
# Print one debug warning per provider instance when debugging is enabled.
|
|
299
315
|
#
|
|
300
316
|
# @private
|
|
301
|
-
# @param [String] msg
|
|
317
|
+
# @param [String] msg warning message text
|
|
302
318
|
# @return [void]
|
|
303
319
|
def warn_once(msg)
|
|
304
320
|
return unless ENV['DOCSCRIBE_RBS_DEBUG'] == '1'
|
|
@@ -10,28 +10,107 @@ module Docscribe
|
|
|
10
10
|
module TypeFormatter
|
|
11
11
|
module_function
|
|
12
12
|
|
|
13
|
-
#
|
|
13
|
+
# Dispatch an RBS type object to the appropriate YARD formatter.
|
|
14
|
+
#
|
|
15
|
+
# @note module_function: defines #to_yard (visibility: private)
|
|
16
|
+
# @param [Docscribe::Types::RBS::TypeFormatter::rbs_type, nil] type the RBS type object to convert
|
|
17
|
+
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
18
|
+
# @param [Boolean] collapse_object_generics whether to collapse generics when all inner types are Object
|
|
19
|
+
# @return [String]
|
|
20
|
+
def to_yard(type, collapse_generics: false, collapse_object_generics: false)
|
|
21
|
+
return 'Object' unless type
|
|
22
|
+
|
|
23
|
+
handler = to_yard_formatters.find { |klass, _| type.is_a?(klass) }
|
|
24
|
+
return handler.last.call(type, cg: collapse_generics, cog: collapse_object_generics) if handler
|
|
25
|
+
|
|
26
|
+
if named_type?(type)
|
|
27
|
+
return format_named(type, # steep:ignore
|
|
28
|
+
collapse_generics: collapse_generics,
|
|
29
|
+
collapse_object_generics: collapse_object_generics)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
fallback_string(type)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Check if the given type object is a named RBS type (class, singleton, interface, or alias).
|
|
36
|
+
#
|
|
37
|
+
# @note module_function: defines #named_type? (visibility: private)
|
|
38
|
+
# @param [Docscribe::Types::RBS::TypeFormatter::rbs_type] type the RBS type object to check
|
|
39
|
+
# @return [Boolean]
|
|
40
|
+
def named_type?(type)
|
|
41
|
+
named_type_classes.any? { |klass| type.is_a?(klass) }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Return or memoize the list of RBS type classes considered named types.
|
|
45
|
+
#
|
|
46
|
+
# @note module_function: defines #named_type_classes (visibility: private)
|
|
47
|
+
# @return [Array<Class>]
|
|
48
|
+
def named_type_classes
|
|
49
|
+
@named_type_classes ||= [
|
|
50
|
+
::RBS::Types::ClassInstance,
|
|
51
|
+
::RBS::Types::ClassSingleton,
|
|
52
|
+
::RBS::Types::Interface,
|
|
53
|
+
::RBS::Types::Alias
|
|
54
|
+
].freeze
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Fallback conversion of an unrecognized RBS type to a cleaned string representation.
|
|
58
|
+
#
|
|
59
|
+
# @note module_function: defines #fallback_string (visibility: private)
|
|
60
|
+
# @param [Docscribe::Types::RBS::TypeFormatter::rbs_type] type the unrecognized RBS type object
|
|
61
|
+
# @return [String]
|
|
62
|
+
def fallback_string(type)
|
|
63
|
+
type.to_s
|
|
64
|
+
.gsub(/\A::/, '')
|
|
65
|
+
.gsub(/\bbool\b/, 'Boolean')
|
|
66
|
+
.gsub(/\buntyped\b/, 'Object')
|
|
67
|
+
end
|
|
68
|
+
|
|
14
69
|
# Return or memoize the dispatch hash mapping RBS type classes to formatter lambdas.
|
|
15
70
|
#
|
|
16
|
-
# @note module_function:
|
|
17
|
-
# @return [Hash
|
|
71
|
+
# @note module_function: defines #to_yard_formatters (visibility: private)
|
|
72
|
+
# @return [Hash<Class, Docscribe::Types::RBS::TypeFormatter::formatter_fn>]
|
|
18
73
|
def to_yard_formatters
|
|
19
|
-
@to_yard_formatters ||=
|
|
74
|
+
@to_yard_formatters ||= formatter_pairs.to_h.freeze
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Hash of RBS type classes and their YARD formatter lambdas.
|
|
78
|
+
#
|
|
79
|
+
# @note module_function: defines #formatter_pairs (visibility: private)
|
|
80
|
+
# @return [Hash<Class, Docscribe::Types::RBS::TypeFormatter::formatter_fn>]
|
|
81
|
+
def formatter_pairs # steep:ignore # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
82
|
+
@formatter_pairs ||= {
|
|
20
83
|
::RBS::Types::Bases::Any => ->(_, **) { format_any },
|
|
21
84
|
::RBS::Types::Bases::Bool => ->(_, **) { format_bool },
|
|
22
85
|
::RBS::Types::Bases::Void => ->(_, **) { format_void },
|
|
23
86
|
::RBS::Types::Bases::Nil => ->(_, **) { format_nil },
|
|
24
|
-
::RBS::Types::Optional =>
|
|
25
|
-
|
|
87
|
+
::RBS::Types::Optional => lambda { |t, cg:, cog:|
|
|
88
|
+
format_optional(t, collapse_generics: cg, collapse_object_generics: cog)
|
|
89
|
+
},
|
|
90
|
+
::RBS::Types::Union => lambda { |t, cg:, cog:|
|
|
91
|
+
format_union(t, collapse_generics: cg, collapse_object_generics: cog)
|
|
92
|
+
},
|
|
26
93
|
::RBS::Types::Literal => ->(t, **) { format_literal(t.literal) },
|
|
27
|
-
::RBS::Types::Proc => ->(_, **) { format_proc }
|
|
94
|
+
::RBS::Types::Proc => ->(_, **) { format_proc },
|
|
95
|
+
::RBS::Types::Tuple => lambda { |t, cg:, cog:|
|
|
96
|
+
format_tuple(t, collapse_generics: cg, collapse_object_generics: cog)
|
|
97
|
+
},
|
|
98
|
+
::RBS::Types::Bases::Top => ->(_, **) { format_top },
|
|
99
|
+
::RBS::Types::Bases::Bottom => ->(_, **) { format_bottom },
|
|
100
|
+
::RBS::Types::Bases::Self => ->(_, **) { format_self },
|
|
101
|
+
::RBS::Types::Bases::Instance => ->(_, **) { format_instance },
|
|
102
|
+
::RBS::Types::Bases::Class => ->(_, **) { format_class_type },
|
|
103
|
+
::RBS::Types::Variable => ->(t, **) { format_variable(t) },
|
|
104
|
+
::RBS::Types::Record => lambda { |t, cg:, cog:|
|
|
105
|
+
format_record(t, collapse_generics: cg, collapse_object_generics: cog)
|
|
106
|
+
},
|
|
107
|
+
::RBS::Types::Intersection => ->(t, cg:, cog:) { format_intersection(t, collapse_generics: cg, collapse_object_generics: cog) }
|
|
28
108
|
}.freeze
|
|
29
109
|
end
|
|
30
|
-
# rubocop:enable Metrics/AbcSize, Layout/LineLength
|
|
31
110
|
|
|
32
111
|
# Format RBS `any` type as the YARD-equivalent `Object`.
|
|
33
112
|
#
|
|
34
|
-
# @note module_function:
|
|
113
|
+
# @note module_function: defines #format_any (visibility: private)
|
|
35
114
|
# @return [String]
|
|
36
115
|
def format_any
|
|
37
116
|
'Object'
|
|
@@ -39,7 +118,7 @@ module Docscribe
|
|
|
39
118
|
|
|
40
119
|
# Format RBS `bool` type as the YARD `Boolean`.
|
|
41
120
|
#
|
|
42
|
-
# @note module_function:
|
|
121
|
+
# @note module_function: defines #format_bool (visibility: private)
|
|
43
122
|
# @return [String]
|
|
44
123
|
def format_bool
|
|
45
124
|
'Boolean'
|
|
@@ -47,7 +126,7 @@ module Docscribe
|
|
|
47
126
|
|
|
48
127
|
# Format RBS `void` type as the YARD `void`.
|
|
49
128
|
#
|
|
50
|
-
# @note module_function:
|
|
129
|
+
# @note module_function: defines #format_void (visibility: private)
|
|
51
130
|
# @return [String]
|
|
52
131
|
def format_void
|
|
53
132
|
'void'
|
|
@@ -55,7 +134,7 @@ module Docscribe
|
|
|
55
134
|
|
|
56
135
|
# Format RBS `nil` type as the YARD `nil`.
|
|
57
136
|
#
|
|
58
|
-
# @note module_function:
|
|
137
|
+
# @note module_function: defines #format_nil (visibility: private)
|
|
59
138
|
# @return [String]
|
|
60
139
|
def format_nil
|
|
61
140
|
'nil'
|
|
@@ -63,18 +142,20 @@ module Docscribe
|
|
|
63
142
|
|
|
64
143
|
# Format an RBS Optional type as a YARD optional type with `?` suffix.
|
|
65
144
|
#
|
|
66
|
-
# @note module_function:
|
|
67
|
-
# @param [
|
|
145
|
+
# @note module_function: defines #format_optional (visibility: private)
|
|
146
|
+
# @param [RBS::Types::Optional] type the optional type to format
|
|
68
147
|
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
148
|
+
# @param [Boolean] collapse_object_generics collapse Object generics flag
|
|
69
149
|
# @return [String]
|
|
70
|
-
def format_optional(type, collapse_generics:)
|
|
71
|
-
"#{to_yard(type.type, collapse_generics: collapse_generics
|
|
150
|
+
def format_optional(type, collapse_generics:, collapse_object_generics:)
|
|
151
|
+
"#{to_yard(type.type, collapse_generics: collapse_generics,
|
|
152
|
+
collapse_object_generics: collapse_object_generics)}?"
|
|
72
153
|
end
|
|
73
154
|
|
|
74
155
|
# Map a Ruby literal value to its corresponding YARD type name.
|
|
75
156
|
#
|
|
76
|
-
# @note module_function:
|
|
77
|
-
# @param [
|
|
157
|
+
# @note module_function: defines #format_literal (visibility: private)
|
|
158
|
+
# @param [RBS::Types::Literal] lit a Ruby literal value
|
|
78
159
|
# @return [String]
|
|
79
160
|
def format_literal(lit)
|
|
80
161
|
case lit
|
|
@@ -90,46 +171,157 @@ module Docscribe
|
|
|
90
171
|
|
|
91
172
|
# Format RBS Proc type as the YARD `Proc`.
|
|
92
173
|
#
|
|
93
|
-
# @note module_function:
|
|
174
|
+
# @note module_function: defines #format_proc (visibility: private)
|
|
94
175
|
# @return [String]
|
|
95
176
|
def format_proc
|
|
96
177
|
'Proc'
|
|
97
178
|
end
|
|
98
179
|
|
|
180
|
+
# Format an RBS Tuple type as a parenthesized list of YARD types.
|
|
181
|
+
#
|
|
182
|
+
# @note module_function: defines #format_tuple (visibility: private)
|
|
183
|
+
# @param [RBS::Types::Tuple] type the tuple type to format
|
|
184
|
+
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
185
|
+
# @param [Boolean] collapse_object_generics collapse Object generics flag
|
|
186
|
+
# @return [String]
|
|
187
|
+
def format_tuple(type, collapse_generics:, collapse_object_generics:)
|
|
188
|
+
"(#{type.types.map do |t|
|
|
189
|
+
to_yard(t, collapse_generics: collapse_generics, collapse_object_generics: collapse_object_generics)
|
|
190
|
+
end.join(', ')})"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# Format RBS top type as YARD `Object`.
|
|
194
|
+
#
|
|
195
|
+
# @note module_function: defines #format_top (visibility: private)
|
|
196
|
+
# @return [String]
|
|
197
|
+
def format_top
|
|
198
|
+
'Object'
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Format RBS bottom type as YARD `Object`.
|
|
202
|
+
#
|
|
203
|
+
# @note module_function: defines #format_bottom (visibility: private)
|
|
204
|
+
# @return [String]
|
|
205
|
+
def format_bottom
|
|
206
|
+
'Object'
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Format RBS self type as YARD `self`.
|
|
210
|
+
#
|
|
211
|
+
# @note module_function: defines #format_self (visibility: private)
|
|
212
|
+
# @return [String]
|
|
213
|
+
def format_self
|
|
214
|
+
'self'
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
# Format RBS instance type as YARD `Object`.
|
|
218
|
+
#
|
|
219
|
+
# @note module_function: defines #format_instance (visibility: private)
|
|
220
|
+
# @return [String]
|
|
221
|
+
def format_instance
|
|
222
|
+
'Object'
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Format RBS class type as YARD `Class`.
|
|
226
|
+
#
|
|
227
|
+
# @note module_function: defines #format_class_type (visibility: private)
|
|
228
|
+
# @return [String]
|
|
229
|
+
def format_class_type
|
|
230
|
+
'Class'
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Format an RBS type variable as its name string.
|
|
234
|
+
#
|
|
235
|
+
# @note module_function: defines #format_variable (visibility: private)
|
|
236
|
+
# @param [RBS::Types::Variable] type the variable type
|
|
237
|
+
# @return [String]
|
|
238
|
+
def format_variable(type)
|
|
239
|
+
type.name.to_s
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
# Format an RBS Record type as a YARD `Hash<Symbol, ValueType>`.
|
|
243
|
+
#
|
|
244
|
+
# @note module_function: defines #format_record (visibility: private)
|
|
245
|
+
# @param [RBS::Types::Record] type the record type
|
|
246
|
+
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
247
|
+
# @param [Boolean] collapse_object_generics collapse Object generics flag
|
|
248
|
+
# @return [String]
|
|
249
|
+
def format_record(type, collapse_generics:, collapse_object_generics:)
|
|
250
|
+
value_types = type.all_fields.values.map do |(ty, _)|
|
|
251
|
+
to_yard(ty, collapse_generics: collapse_generics, collapse_object_generics: collapse_object_generics)
|
|
252
|
+
end.uniq
|
|
253
|
+
"Hash<Symbol, #{value_types.join(', ')}>"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Format an RBS Intersection type as `Type & Type` list.
|
|
257
|
+
#
|
|
258
|
+
# @note module_function: defines #format_intersection (visibility: private)
|
|
259
|
+
# @param [RBS::Types::Intersection] type the intersection type
|
|
260
|
+
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
261
|
+
# @param [Boolean] collapse_object_generics collapse Object generics flag
|
|
262
|
+
# @return [String]
|
|
263
|
+
def format_intersection(type, collapse_generics:, collapse_object_generics:)
|
|
264
|
+
type.types.map do |t|
|
|
265
|
+
to_yard(t, collapse_generics: collapse_generics, collapse_object_generics: collapse_object_generics)
|
|
266
|
+
end.join(' & ')
|
|
267
|
+
end
|
|
268
|
+
|
|
99
269
|
# Format an RBS Union type as a comma-separated list of YARD types.
|
|
100
270
|
#
|
|
101
|
-
# @note module_function:
|
|
102
|
-
# @param [
|
|
271
|
+
# @note module_function: defines #format_union (visibility: private)
|
|
272
|
+
# @param [RBS::Types::Union] type the union type to format
|
|
103
273
|
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
274
|
+
# @param [Boolean] collapse_object_generics collapse Object generics flag
|
|
104
275
|
# @return [String]
|
|
105
|
-
def format_union(type, collapse_generics:)
|
|
106
|
-
type.types.map
|
|
107
|
-
|
|
108
|
-
|
|
276
|
+
def format_union(type, collapse_generics:, collapse_object_generics:)
|
|
277
|
+
type.types.map do |t|
|
|
278
|
+
to_yard(t, collapse_generics: collapse_generics, collapse_object_generics: collapse_object_generics)
|
|
279
|
+
end
|
|
280
|
+
.uniq
|
|
281
|
+
.join(', ')
|
|
109
282
|
end
|
|
110
283
|
|
|
111
284
|
# Format an RBS named type (class, interface, alias) with optional generic arguments.
|
|
112
285
|
#
|
|
113
|
-
# @note module_function:
|
|
114
|
-
# @param [::
|
|
286
|
+
# @note module_function: defines #format_named (visibility: private)
|
|
287
|
+
# @param [Docscribe::Types::RBS::TypeFormatter::named_rbs_type] type the unrecognized RBS type object
|
|
115
288
|
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
289
|
+
# @param [Boolean] collapse_object_generics whether to collapse generics when all inner types are Object
|
|
116
290
|
# @return [String]
|
|
117
|
-
def format_named(type, collapse_generics:)
|
|
291
|
+
def format_named(type, collapse_generics:, collapse_object_generics:)
|
|
118
292
|
name = type.name.to_s.delete_prefix('::')
|
|
119
293
|
args = type.respond_to?(:args) ? type.args : [] #: Array[untyped]
|
|
120
294
|
|
|
121
295
|
if args && !args.empty?
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
"#{name}<#{args.map { |a| to_yard(a, collapse_generics: collapse_generics) }.join(', ')}>"
|
|
296
|
+
format_generic_args(name, args, collapse_generics: collapse_generics,
|
|
297
|
+
collapse_object_generics: collapse_object_generics)
|
|
125
298
|
else
|
|
126
299
|
name
|
|
127
300
|
end
|
|
128
301
|
end
|
|
129
302
|
|
|
303
|
+
# Format generic type arguments for a named type.
|
|
304
|
+
#
|
|
305
|
+
# @note module_function: defines #format_generic_args (visibility: private)
|
|
306
|
+
# @param [String] name the type name
|
|
307
|
+
# @param [Array<Docscribe::Types::RBS::TypeFormatter::rbs_type>] args the generic type arguments
|
|
308
|
+
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
309
|
+
# @param [Boolean] collapse_object_generics whether to collapse generics when all inner types are Object
|
|
310
|
+
# @return [String]
|
|
311
|
+
def format_generic_args(name, args, collapse_generics:, collapse_object_generics:)
|
|
312
|
+
return name if collapse_generics
|
|
313
|
+
|
|
314
|
+
formatted = args.map do |a|
|
|
315
|
+
to_yard(a, collapse_generics: collapse_generics, collapse_object_generics: collapse_object_generics)
|
|
316
|
+
end
|
|
317
|
+
return name if collapse_object_generics && formatted.all? { |s| s == 'Object' }
|
|
318
|
+
|
|
319
|
+
"#{name}<#{formatted.join(', ')}>"
|
|
320
|
+
end
|
|
321
|
+
|
|
130
322
|
# Convert a Ruby literal value to its YARD type name string.
|
|
131
323
|
#
|
|
132
|
-
# @note module_function:
|
|
324
|
+
# @note module_function: defines #literal_to_yard (visibility: private)
|
|
133
325
|
# @param [Object] lit a Ruby literal value
|
|
134
326
|
# @return [String]
|
|
135
327
|
def literal_to_yard(lit)
|
|
@@ -143,57 +335,6 @@ module Docscribe
|
|
|
143
335
|
else 'Object'
|
|
144
336
|
end
|
|
145
337
|
end
|
|
146
|
-
|
|
147
|
-
# Dispatch an RBS type object to the appropriate YARD formatter.
|
|
148
|
-
#
|
|
149
|
-
# @note module_function: when included, also defines #to_yard (instance visibility: private)
|
|
150
|
-
# @param [::RBS::Type] type the RBS type object to convert
|
|
151
|
-
# @param [Boolean] collapse_generics whether to omit generic type arguments
|
|
152
|
-
# @return [String]
|
|
153
|
-
def to_yard(type, collapse_generics: false)
|
|
154
|
-
return 'Object' unless type
|
|
155
|
-
|
|
156
|
-
handler = to_yard_formatters.find { |klass, _| type.is_a?(klass) }
|
|
157
|
-
return handler.last.call(type, collapse_generics: collapse_generics) if handler
|
|
158
|
-
|
|
159
|
-
return format_named(type, collapse_generics: collapse_generics) if named_type?(type)
|
|
160
|
-
|
|
161
|
-
fallback_string(type)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
# Check if the given type object is a named RBS type (class, singleton, interface, or alias).
|
|
165
|
-
#
|
|
166
|
-
# @note module_function: when included, also defines #named_type? (instance visibility: private)
|
|
167
|
-
# @param [::RBS::Type] type the RBS type object to check
|
|
168
|
-
# @return [Boolean]
|
|
169
|
-
def named_type?(type)
|
|
170
|
-
named_type_classes.any? { |klass| type.is_a?(klass) }
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Return or memoize the list of RBS type classes considered named types.
|
|
174
|
-
#
|
|
175
|
-
# @note module_function: when included, also defines #named_type_classes (instance visibility: private)
|
|
176
|
-
# @return [Array<Class>]
|
|
177
|
-
def named_type_classes
|
|
178
|
-
@named_type_classes ||= [
|
|
179
|
-
::RBS::Types::ClassInstance,
|
|
180
|
-
::RBS::Types::ClassSingleton,
|
|
181
|
-
::RBS::Types::Interface,
|
|
182
|
-
::RBS::Types::Alias
|
|
183
|
-
].freeze
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
# Fallback conversion of an unrecognized RBS type to a cleaned string representation.
|
|
187
|
-
#
|
|
188
|
-
# @note module_function: when included, also defines #fallback_string (instance visibility: private)
|
|
189
|
-
# @param [::RBS::Type] type the unrecognized RBS type object
|
|
190
|
-
# @return [String]
|
|
191
|
-
def fallback_string(type)
|
|
192
|
-
type.to_s
|
|
193
|
-
.gsub(/\A::/, '')
|
|
194
|
-
.gsub(/\bbool\b/, 'Boolean')
|
|
195
|
-
.gsub(/\buntyped\b/, 'Object')
|
|
196
|
-
end
|
|
197
338
|
end
|
|
198
339
|
end
|
|
199
340
|
end
|