docscribe 1.2.0 → 1.3.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 +296 -2
- data/lib/docscribe/cli/config_builder.rb +17 -5
- data/lib/docscribe/cli/generate.rb +309 -0
- data/lib/docscribe/cli/options.rb +8 -1
- data/lib/docscribe/cli/run.rb +52 -51
- data/lib/docscribe/cli.rb +8 -2
- data/lib/docscribe/config/defaults.rb +3 -0
- data/lib/docscribe/config/emit.rb +16 -0
- data/lib/docscribe/config/filtering.rb +2 -2
- data/lib/docscribe/config/plugin.rb +29 -0
- data/lib/docscribe/config/template.rb +26 -1
- data/lib/docscribe/config.rb +1 -0
- data/lib/docscribe/infer/returns.rb +71 -10
- data/lib/docscribe/infer.rb +7 -2
- data/lib/docscribe/inline_rewriter/collector.rb +144 -97
- data/lib/docscribe/inline_rewriter/doc_builder.rb +197 -50
- data/lib/docscribe/inline_rewriter.rb +215 -56
- data/lib/docscribe/plugin/base/collector_plugin.rb +55 -0
- data/lib/docscribe/plugin/base/tag_plugin.rb +38 -0
- data/lib/docscribe/plugin/context.rb +38 -0
- data/lib/docscribe/plugin/registry.rb +69 -0
- data/lib/docscribe/plugin/tag.rb +23 -0
- data/lib/docscribe/plugin.rb +58 -0
- data/lib/docscribe/types/rbs/collection_loader.rb +50 -0
- data/lib/docscribe/types/rbs/provider.rb +3 -0
- data/lib/docscribe/version.rb +1 -1
- metadata +13 -5
|
@@ -28,7 +28,15 @@ module Docscribe
|
|
|
28
28
|
# Emit the header line:
|
|
29
29
|
#
|
|
30
30
|
# +MyClass#my_method+ -> ReturnType
|
|
31
|
-
header:
|
|
31
|
+
header: false
|
|
32
|
+
|
|
33
|
+
# Whether to include the default placeholder line:
|
|
34
|
+
# # Method documentation.
|
|
35
|
+
include_default_message: true
|
|
36
|
+
|
|
37
|
+
# Whether to append placeholder text to generated @param tags:
|
|
38
|
+
# # @param [String] name Param documentation.
|
|
39
|
+
include_param_documentation: true
|
|
32
40
|
|
|
33
41
|
# Emit @param tags.
|
|
34
42
|
param_tags: true
|
|
@@ -129,6 +137,18 @@ module Docscribe
|
|
|
129
137
|
include: []
|
|
130
138
|
exclude: ["spec"]
|
|
131
139
|
|
|
140
|
+
plugins:
|
|
141
|
+
# Load custom plugins by path or gem name.
|
|
142
|
+
#
|
|
143
|
+
# Each entry is passed to `require`. Registration happens inside
|
|
144
|
+
# the required file via Docscribe::Plugin::Registry.register.
|
|
145
|
+
#
|
|
146
|
+
# Example:
|
|
147
|
+
# require:
|
|
148
|
+
# - ./docscribe_plugins
|
|
149
|
+
# - docscribe-rails-associations
|
|
150
|
+
require: []
|
|
151
|
+
|
|
132
152
|
rbs:
|
|
133
153
|
# Optional: use RBS signatures to improve @param / @return types.
|
|
134
154
|
#
|
|
@@ -147,6 +167,11 @@ module Docscribe
|
|
|
147
167
|
# - Hash<Symbol, String> => Hash
|
|
148
168
|
# - Array<Integer> => Array
|
|
149
169
|
collapse_generics: false
|
|
170
|
+
# Auto-discover RBS collection from rbs_collection.lock.yaml.
|
|
171
|
+
# Equivalent to --rbs-collection CLI flag.
|
|
172
|
+
# Requires `bundle exec rbs collection install` to have been run.
|
|
173
|
+
#
|
|
174
|
+
collection: false
|
|
150
175
|
|
|
151
176
|
sorbet:
|
|
152
177
|
# Optional: use Sorbet signatures from inline `sig` declarations and
|
data/lib/docscribe/config.rb
CHANGED
|
@@ -56,8 +56,11 @@ module Docscribe
|
|
|
56
56
|
# @param [Parser::AST::Node] node `:def` or `:defs` node
|
|
57
57
|
# @param [String] fallback_type type used when inference is uncertain
|
|
58
58
|
# @param [Boolean] nil_as_optional whether `nil` unions should be rendered as optional types
|
|
59
|
+
# @param [nil] core_rbs_provider Param documentation.
|
|
60
|
+
# @param [nil] param_types Param documentation.
|
|
59
61
|
# @return [Hash]
|
|
60
|
-
def returns_spec_from_node(node, fallback_type: FALLBACK_TYPE, nil_as_optional: true
|
|
62
|
+
def returns_spec_from_node(node, fallback_type: FALLBACK_TYPE, nil_as_optional: true, core_rbs_provider: nil,
|
|
63
|
+
param_types: nil)
|
|
61
64
|
body =
|
|
62
65
|
case node.type
|
|
63
66
|
when :def then node.children[2]
|
|
@@ -70,7 +73,8 @@ module Docscribe
|
|
|
70
73
|
if body.type == :rescue
|
|
71
74
|
main_body = body.children[0]
|
|
72
75
|
spec[:normal] =
|
|
73
|
-
last_expr_type(main_body, fallback_type: fallback_type, nil_as_optional: nil_as_optional
|
|
76
|
+
last_expr_type(main_body, fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
77
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types) || FALLBACK_TYPE
|
|
74
78
|
|
|
75
79
|
body.children.each do |ch|
|
|
76
80
|
next unless ch.is_a?(Parser::AST::Node) && ch.type == :resbody
|
|
@@ -78,13 +82,15 @@ module Docscribe
|
|
|
78
82
|
exc_list, _asgn, rescue_body = *ch
|
|
79
83
|
exc_names = Raises.exception_names_from_rescue_list(exc_list)
|
|
80
84
|
rtype =
|
|
81
|
-
last_expr_type(rescue_body, fallback_type: fallback_type, nil_as_optional: nil_as_optional
|
|
85
|
+
last_expr_type(rescue_body, fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
86
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types) ||
|
|
82
87
|
fallback_type
|
|
83
88
|
spec[:rescues] << [exc_names, rtype]
|
|
84
89
|
end
|
|
85
90
|
else
|
|
86
91
|
spec[:normal] =
|
|
87
|
-
last_expr_type(body, fallback_type: fallback_type, nil_as_optional: nil_as_optional
|
|
92
|
+
last_expr_type(body, fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
93
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types) || FALLBACK_TYPE
|
|
88
94
|
end
|
|
89
95
|
|
|
90
96
|
spec
|
|
@@ -98,30 +104,38 @@ module Docscribe
|
|
|
98
104
|
# - `case` expressions
|
|
99
105
|
# - explicit `return`
|
|
100
106
|
# - literal-like expressions via {Literals.type_from_literal}
|
|
107
|
+
# - method calls with RBS core type lookup
|
|
101
108
|
#
|
|
102
109
|
# @note module_function: when included, also defines #last_expr_type (instance visibility: private)
|
|
103
110
|
# @param [Parser::AST::Node, nil] node expression node
|
|
104
111
|
# @param [String] fallback_type type used when inference is uncertain
|
|
105
112
|
# @param [Boolean] nil_as_optional whether `nil` unions should be rendered as optional types
|
|
113
|
+
# @param [Object, nil] core_rbs_provider optional RBS provider for core type lookup
|
|
114
|
+
# @param [Hash, nil] param_types parameter name -> type map for lvar resolution
|
|
106
115
|
# @return [String, nil]
|
|
107
|
-
def last_expr_type(node, fallback_type:, nil_as_optional:)
|
|
116
|
+
def last_expr_type(node, fallback_type:, nil_as_optional:, core_rbs_provider: nil, param_types: nil)
|
|
108
117
|
return nil unless node
|
|
109
118
|
|
|
110
119
|
case node.type
|
|
111
120
|
when :begin
|
|
112
|
-
last_expr_type(node.children.last, fallback_type: fallback_type, nil_as_optional: nil_as_optional
|
|
121
|
+
last_expr_type(node.children.last, fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
122
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types)
|
|
113
123
|
|
|
114
124
|
when :if
|
|
115
|
-
t = last_expr_type(node.children[1], fallback_type: fallback_type, nil_as_optional: nil_as_optional
|
|
116
|
-
|
|
125
|
+
t = last_expr_type(node.children[1], fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
126
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types)
|
|
127
|
+
e = last_expr_type(node.children[2], fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
128
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types)
|
|
117
129
|
unify_types(t, e, fallback_type: fallback_type, nil_as_optional: nil_as_optional)
|
|
118
130
|
|
|
119
131
|
when :case
|
|
120
132
|
branches = node.children[1..].compact.flat_map do |child|
|
|
121
133
|
if child.type == :when
|
|
122
|
-
last_expr_type(child.children.last, fallback_type: fallback_type, nil_as_optional: nil_as_optional
|
|
134
|
+
last_expr_type(child.children.last, fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
135
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types)
|
|
123
136
|
else
|
|
124
|
-
last_expr_type(child, fallback_type: fallback_type, nil_as_optional: nil_as_optional
|
|
137
|
+
last_expr_type(child, fallback_type: fallback_type, nil_as_optional: nil_as_optional,
|
|
138
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types)
|
|
125
139
|
end
|
|
126
140
|
end.compact
|
|
127
141
|
|
|
@@ -136,11 +150,58 @@ module Docscribe
|
|
|
136
150
|
when :return
|
|
137
151
|
Literals.type_from_literal(node.children.first, fallback_type: fallback_type)
|
|
138
152
|
|
|
153
|
+
when :send
|
|
154
|
+
recv = node.children[0]
|
|
155
|
+
meth = node.children[1]
|
|
156
|
+
|
|
157
|
+
# Try to resolve return type from RBS core for method calls
|
|
158
|
+
if core_rbs_provider && recv&.type == :send
|
|
159
|
+
# Chained call: arg.to_i.positive?
|
|
160
|
+
inner_type = last_expr_type(recv, fallback_type: nil, nil_as_optional: false,
|
|
161
|
+
core_rbs_provider: core_rbs_provider, param_types: param_types)
|
|
162
|
+
if inner_type
|
|
163
|
+
rbs_type = resolve_rbs_return_type(inner_type, meth, core_rbs_provider)
|
|
164
|
+
return rbs_type unless rbs_type == FALLBACK_TYPE
|
|
165
|
+
end
|
|
166
|
+
elsif core_rbs_provider && recv&.type == :lvar
|
|
167
|
+
# Direct call: arg.positive?
|
|
168
|
+
lvar_name = recv.children.first
|
|
169
|
+
if lvar_name && param_types
|
|
170
|
+
recv_type = param_types[lvar_name.to_s]
|
|
171
|
+
if recv_type
|
|
172
|
+
rbs_type = resolve_rbs_return_type(recv_type, meth, core_rbs_provider)
|
|
173
|
+
return rbs_type unless rbs_type == FALLBACK_TYPE
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
Literals.type_from_literal(node, fallback_type: fallback_type)
|
|
179
|
+
|
|
139
180
|
else
|
|
140
181
|
Literals.type_from_literal(node, fallback_type: fallback_type)
|
|
141
182
|
end
|
|
142
183
|
end
|
|
143
184
|
|
|
185
|
+
# Resolve a return type from core RBS for a method call.
|
|
186
|
+
#
|
|
187
|
+
# @note module_function: when included, also defines #resolve_rbs_return_type (instance visibility: private)
|
|
188
|
+
# @private
|
|
189
|
+
# @param [String] container_type e.g. "Numeric", "String"
|
|
190
|
+
# @param [Symbol] method_name e.g. :positive?
|
|
191
|
+
# @param [Object, nil] core_rbs_provider RBS provider
|
|
192
|
+
# @return [String] FALLBACK_TYPE if lookup fails
|
|
193
|
+
def resolve_rbs_return_type(container_type, method_name, core_rbs_provider)
|
|
194
|
+
return FALLBACK_TYPE unless core_rbs_provider
|
|
195
|
+
|
|
196
|
+
sig = core_rbs_provider.signature_for(
|
|
197
|
+
container: container_type,
|
|
198
|
+
scope: :instance,
|
|
199
|
+
name: method_name
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
sig&.return_type || FALLBACK_TYPE
|
|
203
|
+
end
|
|
204
|
+
|
|
144
205
|
# Unify two inferred types into a single type string.
|
|
145
206
|
#
|
|
146
207
|
# Rules:
|
data/lib/docscribe/infer.rb
CHANGED
|
@@ -93,12 +93,17 @@ module Docscribe
|
|
|
93
93
|
# @param [Parser::AST::Node] node
|
|
94
94
|
# @param [String] fallback_type
|
|
95
95
|
# @param [Boolean] nil_as_optional
|
|
96
|
+
# @param [nil] core_rbs_provider Param documentation.
|
|
97
|
+
# @param [nil] param_types Param documentation.
|
|
96
98
|
# @return [Hash]
|
|
97
|
-
def returns_spec_from_node(node, fallback_type: FALLBACK_TYPE, nil_as_optional: true
|
|
99
|
+
def returns_spec_from_node(node, fallback_type: FALLBACK_TYPE, nil_as_optional: true, core_rbs_provider: nil,
|
|
100
|
+
param_types: nil)
|
|
98
101
|
Returns.returns_spec_from_node(
|
|
99
102
|
node,
|
|
100
103
|
fallback_type: fallback_type,
|
|
101
|
-
nil_as_optional: nil_as_optional
|
|
104
|
+
nil_as_optional: nil_as_optional,
|
|
105
|
+
core_rbs_provider: core_rbs_provider,
|
|
106
|
+
param_types: param_types
|
|
102
107
|
)
|
|
103
108
|
end
|
|
104
109
|
|