solargraph 0.58.1 → 0.59.0.dev.1
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/.envrc +3 -0
- data/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +40 -36
- data/.github/workflows/rspec.yml +45 -13
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop_todo.yml +27 -49
- data/README.md +3 -3
- data/Rakefile +1 -0
- data/lib/solargraph/api_map/cache.rb +110 -110
- data/lib/solargraph/api_map/constants.rb +289 -279
- data/lib/solargraph/api_map/index.rb +204 -193
- data/lib/solargraph/api_map/source_to_yard.rb +109 -97
- data/lib/solargraph/api_map/store.rb +387 -384
- data/lib/solargraph/api_map.rb +1000 -945
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +242 -228
- data/lib/solargraph/complex_type/unique_type.rb +632 -482
- data/lib/solargraph/complex_type.rb +549 -444
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
- data/lib/solargraph/convention/data_definition.rb +108 -105
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
- data/lib/solargraph/convention/struct_definition.rb +168 -164
- data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
- data/lib/solargraph/diagnostics/rubocop.rb +119 -118
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
- data/lib/solargraph/diagnostics/type_check.rb +56 -55
- data/lib/solargraph/doc_map.rb +200 -439
- data/lib/solargraph/equality.rb +34 -34
- data/lib/solargraph/gem_pins.rb +97 -98
- data/lib/solargraph/language_server/host/dispatch.rb +131 -130
- data/lib/solargraph/language_server/host/message_worker.rb +113 -112
- data/lib/solargraph/language_server/host/sources.rb +100 -99
- data/lib/solargraph/language_server/host.rb +883 -878
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
- data/lib/solargraph/language_server/message/extended/document.rb +24 -23
- data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
- data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
- data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
- data/lib/solargraph/library.rb +729 -683
- data/lib/solargraph/location.rb +87 -82
- data/lib/solargraph/logging.rb +57 -37
- data/lib/solargraph/parser/comment_ripper.rb +76 -69
- data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
- data/lib/solargraph/parser/node_processor/base.rb +122 -92
- data/lib/solargraph/parser/node_processor.rb +63 -62
- data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
- data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
- data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
- data/lib/solargraph/parser/region.rb +75 -69
- data/lib/solargraph/parser/snippet.rb +17 -17
- data/lib/solargraph/pin/base.rb +761 -729
- data/lib/solargraph/pin/base_variable.rb +418 -126
- data/lib/solargraph/pin/block.rb +126 -104
- data/lib/solargraph/pin/breakable.rb +13 -9
- data/lib/solargraph/pin/callable.rb +278 -231
- data/lib/solargraph/pin/closure.rb +68 -72
- data/lib/solargraph/pin/common.rb +94 -79
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/conversions.rb +124 -123
- data/lib/solargraph/pin/delegated_method.rb +131 -120
- data/lib/solargraph/pin/documenting.rb +115 -114
- data/lib/solargraph/pin/instance_variable.rb +38 -34
- data/lib/solargraph/pin/keyword.rb +16 -20
- data/lib/solargraph/pin/local_variable.rb +31 -75
- data/lib/solargraph/pin/method.rb +720 -672
- data/lib/solargraph/pin/method_alias.rb +42 -34
- data/lib/solargraph/pin/namespace.rb +121 -115
- data/lib/solargraph/pin/parameter.rb +338 -275
- data/lib/solargraph/pin/proxy_type.rb +40 -39
- data/lib/solargraph/pin/reference/override.rb +47 -47
- data/lib/solargraph/pin/reference/superclass.rb +17 -15
- data/lib/solargraph/pin/reference.rb +41 -39
- data/lib/solargraph/pin/search.rb +62 -61
- data/lib/solargraph/pin/signature.rb +69 -61
- data/lib/solargraph/pin/symbol.rb +53 -53
- data/lib/solargraph/pin/until.rb +18 -18
- data/lib/solargraph/pin/while.rb +18 -18
- data/lib/solargraph/pin.rb +46 -44
- data/lib/solargraph/pin_cache.rb +665 -245
- data/lib/solargraph/position.rb +118 -119
- data/lib/solargraph/range.rb +112 -112
- data/lib/solargraph/rbs_map/conversions.rb +846 -823
- data/lib/solargraph/rbs_map/core_map.rb +65 -58
- data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
- data/lib/solargraph/rbs_map.rb +217 -163
- data/lib/solargraph/shell.rb +397 -352
- data/lib/solargraph/source/chain/call.rb +372 -337
- data/lib/solargraph/source/chain/constant.rb +28 -26
- data/lib/solargraph/source/chain/hash.rb +35 -34
- data/lib/solargraph/source/chain/if.rb +29 -28
- data/lib/solargraph/source/chain/instance_variable.rb +34 -13
- data/lib/solargraph/source/chain/literal.rb +53 -48
- data/lib/solargraph/source/chain/or.rb +31 -23
- data/lib/solargraph/source/chain.rb +294 -291
- data/lib/solargraph/source/change.rb +89 -82
- data/lib/solargraph/source/cursor.rb +172 -166
- data/lib/solargraph/source/source_chainer.rb +204 -194
- data/lib/solargraph/source/updater.rb +59 -55
- data/lib/solargraph/source.rb +524 -498
- data/lib/solargraph/source_map/clip.rb +237 -226
- data/lib/solargraph/source_map/data.rb +37 -34
- data/lib/solargraph/source_map/mapper.rb +282 -259
- data/lib/solargraph/source_map.rb +220 -212
- data/lib/solargraph/type_checker/problem.rb +34 -32
- data/lib/solargraph/type_checker/rules.rb +157 -84
- data/lib/solargraph/type_checker.rb +895 -814
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +257 -255
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +98 -97
- data/lib/solargraph/workspace.rb +362 -220
- data/lib/solargraph/yard_map/helpers.rb +45 -44
- data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
- data/lib/solargraph/yard_map/mapper.rb +84 -79
- data/lib/solargraph/yardoc.rb +97 -87
- data/lib/solargraph.rb +126 -105
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +5 -0
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/rbs_collection.yaml +1 -1
- data/solargraph.gemspec +2 -1
- metadata +22 -17
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
- data/sig/shims/ast/0/node.rbs +0 -5
- /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
|
@@ -1,823 +1,846 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'rbs'
|
|
4
|
-
|
|
5
|
-
module Solargraph
|
|
6
|
-
class RbsMap
|
|
7
|
-
# Functions for converting RBS declarations to Solargraph pins
|
|
8
|
-
#
|
|
9
|
-
class Conversions
|
|
10
|
-
include Logging
|
|
11
|
-
|
|
12
|
-
# A container for tracking the current context of the RBS conversion
|
|
13
|
-
# process, e.g., what visibility is declared for methods in the current
|
|
14
|
-
# scope
|
|
15
|
-
#
|
|
16
|
-
class Context
|
|
17
|
-
attr_reader :visibility
|
|
18
|
-
|
|
19
|
-
# @param visibility [Symbol]
|
|
20
|
-
def initialize visibility = :public
|
|
21
|
-
@visibility = visibility
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# @param loader [RBS::EnvironmentLoader]
|
|
26
|
-
def initialize(loader:)
|
|
27
|
-
@loader = loader
|
|
28
|
-
@pins = []
|
|
29
|
-
load_environment_to_pins(loader)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# @return [RBS::EnvironmentLoader]
|
|
33
|
-
attr_reader :loader
|
|
34
|
-
|
|
35
|
-
# @return [Array<Pin::Base>]
|
|
36
|
-
attr_reader :pins
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
# @return [Hash{String => RBS::AST::Declarations::TypeAlias}]
|
|
41
|
-
def type_aliases
|
|
42
|
-
@type_aliases ||= {}
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# @param loader [RBS::EnvironmentLoader]
|
|
46
|
-
# @return [void]
|
|
47
|
-
def load_environment_to_pins(loader)
|
|
48
|
-
environment = RBS::Environment.from_loader(loader).resolve_type_names
|
|
49
|
-
cursor = pins.length
|
|
50
|
-
if environment.declarations.empty?
|
|
51
|
-
Solargraph.logger.info "No RBS declarations found in environment for core_root #{loader.core_root.inspect}, libraries #{loader.libs} and directories #{loader.dirs}"
|
|
52
|
-
return
|
|
53
|
-
end
|
|
54
|
-
environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# @param decl [RBS::AST::Declarations::Base]
|
|
58
|
-
# @param closure [Pin::Closure]
|
|
59
|
-
# @return [void]
|
|
60
|
-
def convert_decl_to_pin decl, closure
|
|
61
|
-
case decl
|
|
62
|
-
when RBS::AST::Declarations::Class
|
|
63
|
-
class_decl_to_pin decl
|
|
64
|
-
when RBS::AST::Declarations::Interface
|
|
65
|
-
# STDERR.puts "Skipping interface #{decl.name.relative!}"
|
|
66
|
-
interface_decl_to_pin decl, closure
|
|
67
|
-
when RBS::AST::Declarations::TypeAlias
|
|
68
|
-
# @sg-ignore
|
|
69
|
-
type_aliases[decl.name.to_s] = decl
|
|
70
|
-
when RBS::AST::Declarations::Module
|
|
71
|
-
module_decl_to_pin decl
|
|
72
|
-
when RBS::AST::Declarations::Constant
|
|
73
|
-
constant_decl_to_pin decl
|
|
74
|
-
when RBS::AST::Declarations::ClassAlias
|
|
75
|
-
class_alias_decl_to_pin decl
|
|
76
|
-
when RBS::AST::Declarations::ModuleAlias
|
|
77
|
-
module_alias_decl_to_pin decl
|
|
78
|
-
when RBS::AST::Declarations::Global
|
|
79
|
-
global_decl_to_pin decl
|
|
80
|
-
else
|
|
81
|
-
Solargraph.logger.warn "Skipping declaration #{decl.class}"
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
# @param decl [RBS::AST::Declarations::Module]
|
|
86
|
-
# @param module_pin [Pin::Namespace]
|
|
87
|
-
# @return [void]
|
|
88
|
-
def convert_self_types_to_pins decl, module_pin
|
|
89
|
-
decl.self_types.each { |self_type| context = convert_self_type_to_pins(self_type, module_pin) }
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# @param decl [RBS::AST::Declarations::Module::Self]
|
|
93
|
-
# @param closure [Pin::Namespace]
|
|
94
|
-
# @return [void]
|
|
95
|
-
def convert_self_type_to_pins decl, closure
|
|
96
|
-
type = build_type(decl.name, decl.args)
|
|
97
|
-
generic_values = type.all_params.map(&:to_s)
|
|
98
|
-
include_pin = Solargraph::Pin::Reference::Include.new(
|
|
99
|
-
name:
|
|
100
|
-
type_location: location_decl_to_pin_location(decl.location),
|
|
101
|
-
generic_values: generic_values,
|
|
102
|
-
closure: closure,
|
|
103
|
-
source: :rbs
|
|
104
|
-
)
|
|
105
|
-
pins.push include_pin
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
# @param decl [RBS::AST::Declarations::Module,RBS::AST::Declarations::Class,RBS::AST::Declarations::Interface]
|
|
109
|
-
# @param closure [Pin::Namespace]
|
|
110
|
-
# @return [void]
|
|
111
|
-
def convert_members_to_pins decl, closure
|
|
112
|
-
context = Conversions::Context.new
|
|
113
|
-
decl.members.each { |m| context = convert_member_to_pin(m, closure, context) }
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# @param member [RBS::AST::Members::Base,RBS::AST::Declarations::Base]
|
|
117
|
-
# @param closure [Pin::Namespace]
|
|
118
|
-
# @param context [Context]
|
|
119
|
-
# @return [Context]
|
|
120
|
-
def convert_member_to_pin member, closure, context
|
|
121
|
-
case member
|
|
122
|
-
when RBS::AST::Members::MethodDefinition
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
when RBS::AST::Members::
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
when RBS::AST::Members::
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
when RBS::AST::Members::
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
when RBS::AST::Members::
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
class_pin
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
)
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
["
|
|
343
|
-
|
|
344
|
-
["
|
|
345
|
-
|
|
346
|
-
["
|
|
347
|
-
["
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
end
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
name =
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
name: name,
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
# @
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
type_location: location_decl_to_pin_location(decl.location),
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
# @param
|
|
631
|
-
# @
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
# @param
|
|
648
|
-
# @
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
name:
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
source: :rbs
|
|
658
|
-
)
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
end
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
elsif type.is_a?(RBS::Types::
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
#
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
'
|
|
780
|
-
elsif type.is_a?(RBS::Types::
|
|
781
|
-
|
|
782
|
-
elsif type.is_a?(RBS::Types::
|
|
783
|
-
'
|
|
784
|
-
elsif type.is_a?(RBS::Types::
|
|
785
|
-
#
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
#
|
|
792
|
-
|
|
793
|
-
elsif type.is_a?(RBS::Types::
|
|
794
|
-
#
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rbs'
|
|
4
|
+
|
|
5
|
+
module Solargraph
|
|
6
|
+
class RbsMap
|
|
7
|
+
# Functions for converting RBS declarations to Solargraph pins
|
|
8
|
+
#
|
|
9
|
+
class Conversions
|
|
10
|
+
include Logging
|
|
11
|
+
|
|
12
|
+
# A container for tracking the current context of the RBS conversion
|
|
13
|
+
# process, e.g., what visibility is declared for methods in the current
|
|
14
|
+
# scope
|
|
15
|
+
#
|
|
16
|
+
class Context
|
|
17
|
+
attr_reader :visibility
|
|
18
|
+
|
|
19
|
+
# @param visibility [Symbol]
|
|
20
|
+
def initialize visibility = :public
|
|
21
|
+
@visibility = visibility
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param loader [RBS::EnvironmentLoader]
|
|
26
|
+
def initialize(loader:)
|
|
27
|
+
@loader = loader
|
|
28
|
+
@pins = []
|
|
29
|
+
load_environment_to_pins(loader)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @return [RBS::EnvironmentLoader]
|
|
33
|
+
attr_reader :loader
|
|
34
|
+
|
|
35
|
+
# @return [Array<Pin::Base>]
|
|
36
|
+
attr_reader :pins
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
# @return [Hash{String => RBS::AST::Declarations::TypeAlias}]
|
|
41
|
+
def type_aliases
|
|
42
|
+
@type_aliases ||= {}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @param loader [RBS::EnvironmentLoader]
|
|
46
|
+
# @return [void]
|
|
47
|
+
def load_environment_to_pins(loader)
|
|
48
|
+
environment = RBS::Environment.from_loader(loader).resolve_type_names
|
|
49
|
+
cursor = pins.length
|
|
50
|
+
if environment.declarations.empty?
|
|
51
|
+
Solargraph.logger.info "No RBS declarations found in environment for core_root #{loader.core_root.inspect}, libraries #{loader.libs} and directories #{loader.dirs}"
|
|
52
|
+
return
|
|
53
|
+
end
|
|
54
|
+
environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @param decl [RBS::AST::Declarations::Base]
|
|
58
|
+
# @param closure [Pin::Closure]
|
|
59
|
+
# @return [void]
|
|
60
|
+
def convert_decl_to_pin decl, closure
|
|
61
|
+
case decl
|
|
62
|
+
when RBS::AST::Declarations::Class
|
|
63
|
+
class_decl_to_pin decl
|
|
64
|
+
when RBS::AST::Declarations::Interface
|
|
65
|
+
# STDERR.puts "Skipping interface #{decl.name.relative!}"
|
|
66
|
+
interface_decl_to_pin decl, closure
|
|
67
|
+
when RBS::AST::Declarations::TypeAlias
|
|
68
|
+
# @sg-ignore flow sensitive typing should support case/when
|
|
69
|
+
type_aliases[decl.name.to_s] = decl
|
|
70
|
+
when RBS::AST::Declarations::Module
|
|
71
|
+
module_decl_to_pin decl
|
|
72
|
+
when RBS::AST::Declarations::Constant
|
|
73
|
+
constant_decl_to_pin decl
|
|
74
|
+
when RBS::AST::Declarations::ClassAlias
|
|
75
|
+
class_alias_decl_to_pin decl
|
|
76
|
+
when RBS::AST::Declarations::ModuleAlias
|
|
77
|
+
module_alias_decl_to_pin decl
|
|
78
|
+
when RBS::AST::Declarations::Global
|
|
79
|
+
global_decl_to_pin decl
|
|
80
|
+
else
|
|
81
|
+
Solargraph.logger.warn "Skipping declaration #{decl.class}"
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# @param decl [RBS::AST::Declarations::Module]
|
|
86
|
+
# @param module_pin [Pin::Namespace]
|
|
87
|
+
# @return [void]
|
|
88
|
+
def convert_self_types_to_pins decl, module_pin
|
|
89
|
+
decl.self_types.each { |self_type| context = convert_self_type_to_pins(self_type, module_pin) }
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @param decl [RBS::AST::Declarations::Module::Self]
|
|
93
|
+
# @param closure [Pin::Namespace]
|
|
94
|
+
# @return [void]
|
|
95
|
+
def convert_self_type_to_pins decl, closure
|
|
96
|
+
type = build_type(decl.name, decl.args)
|
|
97
|
+
generic_values = type.all_params.map(&:to_s)
|
|
98
|
+
include_pin = Solargraph::Pin::Reference::Include.new(
|
|
99
|
+
name: type.rooted_name,
|
|
100
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
101
|
+
generic_values: generic_values,
|
|
102
|
+
closure: closure,
|
|
103
|
+
source: :rbs
|
|
104
|
+
)
|
|
105
|
+
pins.push include_pin
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# @param decl [RBS::AST::Declarations::Module,RBS::AST::Declarations::Class,RBS::AST::Declarations::Interface]
|
|
109
|
+
# @param closure [Pin::Namespace]
|
|
110
|
+
# @return [void]
|
|
111
|
+
def convert_members_to_pins decl, closure
|
|
112
|
+
context = Conversions::Context.new
|
|
113
|
+
decl.members.each { |m| context = convert_member_to_pin(m, closure, context) }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @param member [RBS::AST::Members::Base,RBS::AST::Declarations::Base]
|
|
117
|
+
# @param closure [Pin::Namespace]
|
|
118
|
+
# @param context [Context]
|
|
119
|
+
# @return [Context]
|
|
120
|
+
def convert_member_to_pin member, closure, context
|
|
121
|
+
case member
|
|
122
|
+
when RBS::AST::Members::MethodDefinition
|
|
123
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
124
|
+
method_def_to_pin(member, closure, context)
|
|
125
|
+
when RBS::AST::Members::AttrReader
|
|
126
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
127
|
+
attr_reader_to_pin(member, closure, context)
|
|
128
|
+
when RBS::AST::Members::AttrWriter
|
|
129
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
130
|
+
attr_writer_to_pin(member, closure, context)
|
|
131
|
+
when RBS::AST::Members::AttrAccessor
|
|
132
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
133
|
+
attr_accessor_to_pin(member, closure, context)
|
|
134
|
+
when RBS::AST::Members::Include
|
|
135
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
136
|
+
include_to_pin(member, closure)
|
|
137
|
+
when RBS::AST::Members::Prepend
|
|
138
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
139
|
+
prepend_to_pin(member, closure)
|
|
140
|
+
when RBS::AST::Members::Extend
|
|
141
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
142
|
+
extend_to_pin(member, closure)
|
|
143
|
+
when RBS::AST::Members::Alias
|
|
144
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
145
|
+
alias_to_pin(member, closure)
|
|
146
|
+
when RBS::AST::Members::ClassInstanceVariable
|
|
147
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
148
|
+
civar_to_pin(member, closure)
|
|
149
|
+
when RBS::AST::Members::ClassVariable
|
|
150
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
151
|
+
cvar_to_pin(member, closure)
|
|
152
|
+
when RBS::AST::Members::InstanceVariable
|
|
153
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
154
|
+
ivar_to_pin(member, closure)
|
|
155
|
+
when RBS::AST::Members::Public
|
|
156
|
+
return Context.new(:public)
|
|
157
|
+
when RBS::AST::Members::Private
|
|
158
|
+
return Context.new(:private)
|
|
159
|
+
when RBS::AST::Declarations::Base
|
|
160
|
+
# @sg-ignore flow based typing needs to understand case when class pattern
|
|
161
|
+
convert_decl_to_pin(member, closure)
|
|
162
|
+
else
|
|
163
|
+
Solargraph.logger.warn "Skipping member type #{member.class}"
|
|
164
|
+
end
|
|
165
|
+
context
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# @param decl [RBS::AST::Declarations::Class]
|
|
169
|
+
# @return [void]
|
|
170
|
+
def class_decl_to_pin decl
|
|
171
|
+
generics = decl.type_params.map(&:name).map(&:to_s)
|
|
172
|
+
generic_defaults = {}
|
|
173
|
+
decl.type_params.each do |param|
|
|
174
|
+
if param.default_type
|
|
175
|
+
tag = other_type_to_tag param.default_type
|
|
176
|
+
generic_defaults[param.name.to_s] = ComplexType.parse(tag).force_rooted
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
class_name = decl.name.relative!.to_s
|
|
180
|
+
class_pin = Solargraph::Pin::Namespace.new(
|
|
181
|
+
type: :class,
|
|
182
|
+
name: class_name,
|
|
183
|
+
closure: Solargraph::Pin::ROOT_PIN,
|
|
184
|
+
comments: decl.comment&.string,
|
|
185
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
186
|
+
# @todo some type parameters in core/stdlib have default
|
|
187
|
+
# values; Solargraph doesn't support that yet as so these
|
|
188
|
+
# get treated as undefined if not specified
|
|
189
|
+
generics: generics,
|
|
190
|
+
generic_defaults: generic_defaults,
|
|
191
|
+
source: :rbs
|
|
192
|
+
)
|
|
193
|
+
pins.push class_pin
|
|
194
|
+
if decl.super_class
|
|
195
|
+
type = build_type(decl.super_class.name, decl.super_class.args)
|
|
196
|
+
generic_values = type.all_params.map(&:to_s)
|
|
197
|
+
superclass_name = decl.super_class.name.to_s
|
|
198
|
+
pins.push Solargraph::Pin::Reference::Superclass.new(
|
|
199
|
+
type_location: location_decl_to_pin_location(decl.super_class.location),
|
|
200
|
+
closure: class_pin,
|
|
201
|
+
generic_values: generic_values,
|
|
202
|
+
name: superclass_name,
|
|
203
|
+
source: :rbs
|
|
204
|
+
)
|
|
205
|
+
end
|
|
206
|
+
add_mixins decl, class_pin
|
|
207
|
+
convert_members_to_pins decl, class_pin
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# @param decl [RBS::AST::Declarations::Interface]
|
|
211
|
+
# @param closure [Pin::Closure]
|
|
212
|
+
# @return [void]
|
|
213
|
+
def interface_decl_to_pin decl, closure
|
|
214
|
+
class_pin = Solargraph::Pin::Namespace.new(
|
|
215
|
+
type: :module,
|
|
216
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
217
|
+
name: decl.name.relative!.to_s,
|
|
218
|
+
closure: Solargraph::Pin::ROOT_PIN,
|
|
219
|
+
comments: decl.comment&.string,
|
|
220
|
+
generics: decl.type_params.map(&:name).map(&:to_s),
|
|
221
|
+
# HACK: Using :hidden to keep interfaces from appearing in
|
|
222
|
+
# autocompletion
|
|
223
|
+
visibility: :hidden,
|
|
224
|
+
source: :rbs
|
|
225
|
+
)
|
|
226
|
+
class_pin.docstring.add_tag(YARD::Tags::Tag.new(:abstract, '(RBS interface)'))
|
|
227
|
+
pins.push class_pin
|
|
228
|
+
convert_members_to_pins decl, class_pin
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# @param decl [RBS::AST::Declarations::Module]
|
|
232
|
+
# @return [void]
|
|
233
|
+
def module_decl_to_pin decl
|
|
234
|
+
module_pin = Solargraph::Pin::Namespace.new(
|
|
235
|
+
type: :module,
|
|
236
|
+
name: decl.name.relative!.to_s,
|
|
237
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
238
|
+
closure: Solargraph::Pin::ROOT_PIN,
|
|
239
|
+
comments: decl.comment&.string,
|
|
240
|
+
generics: decl.type_params.map(&:name).map(&:to_s),
|
|
241
|
+
source: :rbs
|
|
242
|
+
)
|
|
243
|
+
pins.push module_pin
|
|
244
|
+
convert_self_types_to_pins decl, module_pin
|
|
245
|
+
convert_members_to_pins decl, module_pin
|
|
246
|
+
|
|
247
|
+
raise "Invalid type for module declaration: #{module_pin.class}" unless module_pin.is_a?(Pin::Namespace)
|
|
248
|
+
|
|
249
|
+
add_mixins decl, module_pin.closure
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
# @param name [String]
|
|
253
|
+
# @param tag [String]
|
|
254
|
+
# @param comments [String, nil]
|
|
255
|
+
# @param decl [RBS::AST::Declarations::ClassAlias, RBS::AST::Declarations::Constant, RBS::AST::Declarations::ModuleAlias]
|
|
256
|
+
# @param base [String, nil] Optional conversion of tag to base<tag>
|
|
257
|
+
#
|
|
258
|
+
# @return [Solargraph::Pin::Constant]
|
|
259
|
+
def create_constant(name, tag, comments, decl, base = nil)
|
|
260
|
+
parts = name.split('::')
|
|
261
|
+
if parts.length > 1
|
|
262
|
+
name = parts.last
|
|
263
|
+
# @sg-ignore Need to add nil check here
|
|
264
|
+
closure = pins.select { |pin| pin && pin.path == parts[0..-2].join('::') }.first
|
|
265
|
+
else
|
|
266
|
+
name = parts.first
|
|
267
|
+
closure = Solargraph::Pin::ROOT_PIN
|
|
268
|
+
end
|
|
269
|
+
constant_pin = Solargraph::Pin::Constant.new(
|
|
270
|
+
name: name,
|
|
271
|
+
closure: closure,
|
|
272
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
273
|
+
comments: comments,
|
|
274
|
+
source: :rbs
|
|
275
|
+
)
|
|
276
|
+
tag = "#{base}<#{tag}>" if base
|
|
277
|
+
rooted_tag = ComplexType.parse(tag).force_rooted.rooted_tags
|
|
278
|
+
constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
|
|
279
|
+
constant_pin
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# @param decl [RBS::AST::Declarations::ClassAlias]
|
|
283
|
+
# @return [void]
|
|
284
|
+
def class_alias_decl_to_pin decl
|
|
285
|
+
# See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ClassAlias
|
|
286
|
+
new_name = decl.new_name.relative!.to_s
|
|
287
|
+
old_name = decl.old_name.relative!.to_s
|
|
288
|
+
|
|
289
|
+
pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Class')
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
# @param decl [RBS::AST::Declarations::ModuleAlias]
|
|
293
|
+
# @return [void]
|
|
294
|
+
def module_alias_decl_to_pin decl
|
|
295
|
+
# See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ModuleAlias
|
|
296
|
+
new_name = decl.new_name.relative!.to_s
|
|
297
|
+
old_name = decl.old_name.relative!.to_s
|
|
298
|
+
|
|
299
|
+
pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Module')
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
# @param decl [RBS::AST::Declarations::Constant]
|
|
303
|
+
# @return [void]
|
|
304
|
+
def constant_decl_to_pin decl
|
|
305
|
+
tag = other_type_to_tag(decl.type)
|
|
306
|
+
pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string, decl)
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# @param decl [RBS::AST::Declarations::Global]
|
|
310
|
+
# @return [void]
|
|
311
|
+
def global_decl_to_pin decl
|
|
312
|
+
closure = Solargraph::Pin::ROOT_PIN
|
|
313
|
+
name = decl.name.to_s
|
|
314
|
+
pin = Solargraph::Pin::GlobalVariable.new(
|
|
315
|
+
name: name,
|
|
316
|
+
closure: closure,
|
|
317
|
+
comments: decl.comment&.string,
|
|
318
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
319
|
+
source: :rbs
|
|
320
|
+
)
|
|
321
|
+
rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
|
|
322
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
323
|
+
pins.push pin
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
# Visibility overrides that will allow the Solargraph project
|
|
328
|
+
# and plugins to pass typechecking using SOLARGRAPH_ASSERTS=on,
|
|
329
|
+
# so that we can detect any regressions/issues elsewhere in the
|
|
330
|
+
# visibility logic.
|
|
331
|
+
#
|
|
332
|
+
# These should either reflect a bug upstream in the RBS
|
|
333
|
+
# definitions, or include a @todo indicating what needs to be
|
|
334
|
+
# fixed in Solargraph to properly understand it.
|
|
335
|
+
#
|
|
336
|
+
# @todo PR these fixes upstream and list open PRs here above
|
|
337
|
+
# related overrides
|
|
338
|
+
# @todo externalize remaining overrides into yaml file, then
|
|
339
|
+
# allow that to be extended via .solargraph.yml
|
|
340
|
+
# @type [Hash{Array(String, Symbol, String) => Symbol}
|
|
341
|
+
VISIBILITY_OVERRIDE = {
|
|
342
|
+
["Rails::Engine", :instance, "run_tasks_blocks"] => :protected,
|
|
343
|
+
# Should have been marked as both instance and class method in module -e.g., 'module_function'
|
|
344
|
+
["Kernel", :instance, "pretty_inspect"] => :private,
|
|
345
|
+
# marked incorrectly in RBS
|
|
346
|
+
["WEBrick::HTTPUtils::FormData", :instance, "next_data"] => :protected,
|
|
347
|
+
["Rails::Command", :class, "command_type"] => :private,
|
|
348
|
+
["Rails::Command", :class, "lookup_paths"] => :private,
|
|
349
|
+
["Rails::Command", :class, "file_lookup_paths"] => :private,
|
|
350
|
+
["Rails::Railtie", :instance, "run_console_blocks"] => :protected,
|
|
351
|
+
["Rails::Railtie", :instance, "run_generators_blocks"] => :protected,
|
|
352
|
+
["Rails::Railtie", :instance, "run_runner_blocks"] => :protected,
|
|
353
|
+
["Rails::Railtie", :instance, "run_tasks_blocks"] => :protected,
|
|
354
|
+
["ActionController::Base", :instance, "_protected_ivars"] => :private,
|
|
355
|
+
["ActionView::Template", :instance, "method_name"] => :public,
|
|
356
|
+
["Module", :instance, "ruby2_keywords"] => :private,
|
|
357
|
+
["Nokogiri::XML::Node", :instance, "coerce"] => :protected,
|
|
358
|
+
["Nokogiri::XML::Document", :class, "empty_doc?"] => :private,
|
|
359
|
+
["Nokogiri::Decorators::Slop", :instance, "respond_to_missing?"] => :public,
|
|
360
|
+
["RuboCop::Cop::RangeHelp", :instance, "source_range"] => :private,
|
|
361
|
+
["AST::Node", :instance, "original_dup"] => :private,
|
|
362
|
+
["Rainbow::Presenter", :instance, "wrap_with_sgr"] => :private,
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
# @param decl [RBS::AST::Members::MethodDefinition, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor]
|
|
366
|
+
# @param closure [Pin::Closure]
|
|
367
|
+
# @param context [Context]
|
|
368
|
+
# @param scope [Symbol] :instance or :class
|
|
369
|
+
# @param name [String] The name of the method
|
|
370
|
+
# @return [Symbol]
|
|
371
|
+
def calculate_method_visibility(decl, context, closure, scope, name)
|
|
372
|
+
override_key = [closure.path, scope, name]
|
|
373
|
+
visibility = VISIBILITY_OVERRIDE[override_key]
|
|
374
|
+
simple_override_key = [closure.path, scope]
|
|
375
|
+
visibility ||= VISIBILITY_OVERRIDE[simple_override_key]
|
|
376
|
+
visibility ||= :private if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(decl.name)
|
|
377
|
+
if decl.kind == :singleton_instance
|
|
378
|
+
# this is a 'module function'
|
|
379
|
+
visibility ||= :private
|
|
380
|
+
end
|
|
381
|
+
visibility ||= decl.visibility
|
|
382
|
+
visibility ||= context.visibility
|
|
383
|
+
visibility ||= :public
|
|
384
|
+
visibility
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# @param decl [RBS::AST::Members::MethodDefinition]
|
|
388
|
+
# @param closure [Pin::Closure]
|
|
389
|
+
# @param context [Context]
|
|
390
|
+
# @return [void]
|
|
391
|
+
def method_def_to_pin decl, closure, context
|
|
392
|
+
# there may be edge cases here around different signatures
|
|
393
|
+
# having different type params / orders - we may need to match
|
|
394
|
+
# this data model and have generics live in signatures to
|
|
395
|
+
# handle those correctly
|
|
396
|
+
generics = decl.overloads.map(&:method_type).flat_map(&:type_params).map(&:name).map(&:to_s).uniq
|
|
397
|
+
|
|
398
|
+
if decl.instance?
|
|
399
|
+
name = decl.name.to_s
|
|
400
|
+
final_scope = :instance
|
|
401
|
+
visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
|
|
402
|
+
pin = Solargraph::Pin::Method.new(
|
|
403
|
+
name: name,
|
|
404
|
+
closure: closure,
|
|
405
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
406
|
+
comments: decl.comment&.string,
|
|
407
|
+
scope: final_scope,
|
|
408
|
+
signatures: [],
|
|
409
|
+
generics: generics,
|
|
410
|
+
visibility: visibility,
|
|
411
|
+
source: :rbs
|
|
412
|
+
)
|
|
413
|
+
pin.signatures.concat method_def_to_sigs(decl, pin)
|
|
414
|
+
pins.push pin
|
|
415
|
+
if pin.name == 'initialize'
|
|
416
|
+
pin.instance_variable_set(:@visibility, :private)
|
|
417
|
+
pin.instance_variable_set(:@return_type, ComplexType::VOID)
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
if decl.singleton?
|
|
421
|
+
final_scope = :class
|
|
422
|
+
name = decl.name.to_s
|
|
423
|
+
visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
|
|
424
|
+
pin = Solargraph::Pin::Method.new(
|
|
425
|
+
name: name,
|
|
426
|
+
closure: closure,
|
|
427
|
+
comments: decl.comment&.string,
|
|
428
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
429
|
+
visibility: visibility,
|
|
430
|
+
scope: final_scope,
|
|
431
|
+
signatures: [],
|
|
432
|
+
generics: generics,
|
|
433
|
+
source: :rbs
|
|
434
|
+
)
|
|
435
|
+
pin.signatures.concat method_def_to_sigs(decl, pin)
|
|
436
|
+
pins.push pin
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
# @param decl [RBS::AST::Members::MethodDefinition]
|
|
441
|
+
# @param pin [Pin::Method]
|
|
442
|
+
# @return [void]
|
|
443
|
+
def method_def_to_sigs decl, pin
|
|
444
|
+
# @param overload [RBS::AST::Members::MethodDefinition::Overload]
|
|
445
|
+
decl.overloads.map do |overload|
|
|
446
|
+
type_location = location_decl_to_pin_location(overload.method_type.location)
|
|
447
|
+
generics = overload.method_type.type_params.map(&:name).map(&:to_s)
|
|
448
|
+
signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin)
|
|
449
|
+
rbs_block = overload.method_type.block
|
|
450
|
+
block = if rbs_block
|
|
451
|
+
block_parameters, block_return_type = parts_of_function(rbs_block, pin)
|
|
452
|
+
Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type, source: :rbs,
|
|
453
|
+
type_location: type_location, closure: pin)
|
|
454
|
+
end
|
|
455
|
+
Pin::Signature.new(generics: generics, parameters: signature_parameters, return_type: signature_return_type, block: block, source: :rbs,
|
|
456
|
+
type_location: type_location, closure: pin)
|
|
457
|
+
end
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
# @param location [RBS::Location, nil]
|
|
461
|
+
# @return [Solargraph::Location, nil]
|
|
462
|
+
def location_decl_to_pin_location(location)
|
|
463
|
+
return nil if location&.name.nil?
|
|
464
|
+
|
|
465
|
+
# @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
|
|
466
|
+
start_pos = Position.new(location.start_line - 1, location.start_column)
|
|
467
|
+
# @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
|
|
468
|
+
end_pos = Position.new(location.end_line - 1, location.end_column)
|
|
469
|
+
range = Range.new(start_pos, end_pos)
|
|
470
|
+
# @sg-ignore flow sensitve typing should handle return nil if location&.name.nil?
|
|
471
|
+
Location.new(location.name.to_s, range)
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
# @param type [RBS::MethodType,RBS::Types::Block]
|
|
475
|
+
# @param pin [Pin::Method]
|
|
476
|
+
# @return [Array(Array<Pin::Parameter>, ComplexType)]
|
|
477
|
+
def parts_of_function type, pin
|
|
478
|
+
type_location = pin.type_location
|
|
479
|
+
if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
|
|
480
|
+
return [
|
|
481
|
+
[Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs, type_location: type_location)],
|
|
482
|
+
ComplexType.try_parse(method_type_to_tag(type)).force_rooted
|
|
483
|
+
]
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
parameters = []
|
|
487
|
+
arg_num = -1
|
|
488
|
+
type.type.required_positionals.each do |param|
|
|
489
|
+
# @sg-ignore RBS generic type understanding issue
|
|
490
|
+
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
491
|
+
# @sg-ignore RBS generic type understanding issue
|
|
492
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted, source: :rbs, type_location: type_location)
|
|
493
|
+
end
|
|
494
|
+
type.type.optional_positionals.each do |param|
|
|
495
|
+
# @sg-ignore RBS generic type understanding issue
|
|
496
|
+
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
497
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
|
|
498
|
+
# @sg-ignore RBS generic type understanding issue
|
|
499
|
+
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
|
|
500
|
+
type_location: type_location,
|
|
501
|
+
source: :rbs)
|
|
502
|
+
end
|
|
503
|
+
if type.type.rest_positionals
|
|
504
|
+
name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg_#{arg_num += 1}"
|
|
505
|
+
inner_rest_positional_type =
|
|
506
|
+
ComplexType.try_parse(other_type_to_tag(type.type.rest_positionals.type))
|
|
507
|
+
rest_positional_type = ComplexType::UniqueType.new('Array',
|
|
508
|
+
[],
|
|
509
|
+
[inner_rest_positional_type],
|
|
510
|
+
rooted: true, parameters_type: :list)
|
|
511
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin,
|
|
512
|
+
source: :rbs, type_location: type_location,
|
|
513
|
+
return_type: rest_positional_type,)
|
|
514
|
+
end
|
|
515
|
+
type.type.trailing_positionals.each do |param|
|
|
516
|
+
# @sg-ignore RBS generic type understanding issue
|
|
517
|
+
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
518
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs, type_location: type_location)
|
|
519
|
+
end
|
|
520
|
+
type.type.required_keywords.each do |orig, param|
|
|
521
|
+
# @sg-ignore RBS generic type understanding issue
|
|
522
|
+
name = orig ? orig.to_s : "arg_#{arg_num += 1}"
|
|
523
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
|
|
524
|
+
# @sg-ignore RBS generic type understanding issue
|
|
525
|
+
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
|
|
526
|
+
source: :rbs, type_location: type_location)
|
|
527
|
+
end
|
|
528
|
+
type.type.optional_keywords.each do |orig, param|
|
|
529
|
+
# @sg-ignore RBS generic type understanding issue
|
|
530
|
+
name = orig ? orig.to_s : "arg_#{arg_num += 1}"
|
|
531
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
|
|
532
|
+
# @sg-ignore RBS generic type understanding issue
|
|
533
|
+
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
|
|
534
|
+
type_location: type_location,
|
|
535
|
+
source: :rbs)
|
|
536
|
+
end
|
|
537
|
+
if type.type.rest_keywords
|
|
538
|
+
name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg_#{arg_num += 1}"
|
|
539
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg, name: type.type.rest_keywords.name.to_s, closure: pin,
|
|
540
|
+
source: :rbs, type_location: type_location)
|
|
541
|
+
end
|
|
542
|
+
|
|
543
|
+
rooted_tag = method_type_to_tag(type)
|
|
544
|
+
return_type = ComplexType.try_parse(rooted_tag).force_rooted
|
|
545
|
+
[parameters, return_type]
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
# @param decl [RBS::AST::Members::AttrReader,RBS::AST::Members::AttrAccessor]
|
|
549
|
+
# @param closure [Pin::Namespace]
|
|
550
|
+
# @param context [Context]
|
|
551
|
+
# @return [void]
|
|
552
|
+
def attr_reader_to_pin(decl, closure, context)
|
|
553
|
+
name = decl.name.to_s
|
|
554
|
+
final_scope = decl.kind == :instance ? :instance : :class
|
|
555
|
+
visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
|
|
556
|
+
pin = Solargraph::Pin::Method.new(
|
|
557
|
+
name: name,
|
|
558
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
559
|
+
closure: closure,
|
|
560
|
+
comments: decl.comment&.string,
|
|
561
|
+
scope: final_scope,
|
|
562
|
+
attribute: true,
|
|
563
|
+
visibility: visibility,
|
|
564
|
+
source: :rbs
|
|
565
|
+
)
|
|
566
|
+
rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
|
|
567
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
|
|
568
|
+
logger.debug { "Conversions#attr_reader_to_pin(name=#{name.inspect}, visibility=#{visibility.inspect}) => #{pin.inspect}" }
|
|
569
|
+
pins.push pin
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
# @param decl [RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor]
|
|
573
|
+
# @param closure [Pin::Namespace]
|
|
574
|
+
# @param context [Context]
|
|
575
|
+
# @return [void]
|
|
576
|
+
def attr_writer_to_pin(decl, closure, context)
|
|
577
|
+
final_scope = decl.kind == :instance ? :instance : :class
|
|
578
|
+
name = "#{decl.name.to_s}="
|
|
579
|
+
visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
|
|
580
|
+
type_location = location_decl_to_pin_location(decl.location)
|
|
581
|
+
pin = Solargraph::Pin::Method.new(
|
|
582
|
+
name: name,
|
|
583
|
+
type_location: type_location,
|
|
584
|
+
closure: closure,
|
|
585
|
+
parameters: [],
|
|
586
|
+
comments: decl.comment&.string,
|
|
587
|
+
scope: final_scope,
|
|
588
|
+
attribute: true,
|
|
589
|
+
visibility: visibility,
|
|
590
|
+
source: :rbs
|
|
591
|
+
)
|
|
592
|
+
pin.parameters <<
|
|
593
|
+
Solargraph::Pin::Parameter.new(
|
|
594
|
+
name: 'value',
|
|
595
|
+
return_type: ComplexType.try_parse(other_type_to_tag(decl.type)).force_rooted,
|
|
596
|
+
source: :rbs,
|
|
597
|
+
closure: pin,
|
|
598
|
+
type_location: type_location
|
|
599
|
+
)
|
|
600
|
+
rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
|
|
601
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
|
|
602
|
+
pins.push pin
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
# @param decl [RBS::AST::Members::AttrAccessor]
|
|
606
|
+
# @param closure [Pin::Namespace]
|
|
607
|
+
# @param context [Context]
|
|
608
|
+
# @return [void]
|
|
609
|
+
def attr_accessor_to_pin(decl, closure, context)
|
|
610
|
+
attr_reader_to_pin(decl, closure, context)
|
|
611
|
+
attr_writer_to_pin(decl, closure, context)
|
|
612
|
+
end
|
|
613
|
+
|
|
614
|
+
# @param decl [RBS::AST::Members::InstanceVariable]
|
|
615
|
+
# @param closure [Pin::Namespace]
|
|
616
|
+
# @return [void]
|
|
617
|
+
def ivar_to_pin(decl, closure)
|
|
618
|
+
pin = Solargraph::Pin::InstanceVariable.new(
|
|
619
|
+
name: decl.name.to_s,
|
|
620
|
+
closure: closure,
|
|
621
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
622
|
+
comments: decl.comment&.string,
|
|
623
|
+
source: :rbs
|
|
624
|
+
)
|
|
625
|
+
rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
|
|
626
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
627
|
+
pins.push pin
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
# @param decl [RBS::AST::Members::ClassVariable]
|
|
631
|
+
# @param closure [Pin::Namespace]
|
|
632
|
+
# @return [void]
|
|
633
|
+
def cvar_to_pin(decl, closure)
|
|
634
|
+
name = decl.name.to_s
|
|
635
|
+
pin = Solargraph::Pin::ClassVariable.new(
|
|
636
|
+
name: name,
|
|
637
|
+
closure: closure,
|
|
638
|
+
comments: decl.comment&.string,
|
|
639
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
640
|
+
source: :rbs
|
|
641
|
+
)
|
|
642
|
+
rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
|
|
643
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
644
|
+
pins.push pin
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
# @param decl [RBS::AST::Members::ClassInstanceVariable]
|
|
648
|
+
# @param closure [Pin::Namespace]
|
|
649
|
+
# @return [void]
|
|
650
|
+
def civar_to_pin(decl, closure)
|
|
651
|
+
name = decl.name.to_s
|
|
652
|
+
pin = Solargraph::Pin::InstanceVariable.new(
|
|
653
|
+
name: name,
|
|
654
|
+
closure: closure,
|
|
655
|
+
comments: decl.comment&.string,
|
|
656
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
657
|
+
source: :rbs
|
|
658
|
+
)
|
|
659
|
+
rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
|
|
660
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
|
|
661
|
+
pins.push pin
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
# @param decl [RBS::AST::Members::Include]
|
|
665
|
+
# @param closure [Pin::Namespace]
|
|
666
|
+
# @return [void]
|
|
667
|
+
def include_to_pin decl, closure
|
|
668
|
+
type = build_type(decl.name, decl.args)
|
|
669
|
+
generic_values = type.all_params.map(&:to_s)
|
|
670
|
+
pins.push Solargraph::Pin::Reference::Include.new(
|
|
671
|
+
name: decl.name.relative!.to_s,
|
|
672
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
673
|
+
generic_values: generic_values,
|
|
674
|
+
closure: closure,
|
|
675
|
+
source: :rbs
|
|
676
|
+
)
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
# @param decl [RBS::AST::Members::Prepend]
|
|
680
|
+
# @param closure [Pin::Namespace]
|
|
681
|
+
# @return [void]
|
|
682
|
+
def prepend_to_pin decl, closure
|
|
683
|
+
pins.push Solargraph::Pin::Reference::Prepend.new(
|
|
684
|
+
name: decl.name.relative!.to_s,
|
|
685
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
686
|
+
closure: closure,
|
|
687
|
+
source: :rbs
|
|
688
|
+
)
|
|
689
|
+
end
|
|
690
|
+
|
|
691
|
+
# @param decl [RBS::AST::Members::Extend]
|
|
692
|
+
# @param closure [Pin::Namespace]
|
|
693
|
+
# @return [void]
|
|
694
|
+
def extend_to_pin decl, closure
|
|
695
|
+
pins.push Solargraph::Pin::Reference::Extend.new(
|
|
696
|
+
name: decl.name.relative!.to_s,
|
|
697
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
698
|
+
closure: closure,
|
|
699
|
+
source: :rbs
|
|
700
|
+
)
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
# @param decl [RBS::AST::Members::Alias]
|
|
704
|
+
# @param closure [Pin::Namespace]
|
|
705
|
+
# @return [void]
|
|
706
|
+
def alias_to_pin decl, closure
|
|
707
|
+
final_scope = decl.singleton? ? :class : :instance
|
|
708
|
+
pins.push Solargraph::Pin::MethodAlias.new(
|
|
709
|
+
name: decl.new_name.to_s,
|
|
710
|
+
type_location: location_decl_to_pin_location(decl.location),
|
|
711
|
+
original: decl.old_name.to_s,
|
|
712
|
+
closure: closure,
|
|
713
|
+
scope: final_scope,
|
|
714
|
+
source: :rbs,
|
|
715
|
+
)
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
RBS_TO_YARD_TYPE = {
|
|
719
|
+
'bool' => 'Boolean',
|
|
720
|
+
'string' => 'String',
|
|
721
|
+
'int' => 'Integer',
|
|
722
|
+
'untyped' => '',
|
|
723
|
+
'NilClass' => 'nil'
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
# @param type [RBS::MethodType, RBS::Types::Block]
|
|
727
|
+
# @return [String]
|
|
728
|
+
def method_type_to_tag type
|
|
729
|
+
if type_aliases.key?(type.type.return_type.to_s)
|
|
730
|
+
other_type_to_tag(type_aliases[type.type.return_type.to_s].type)
|
|
731
|
+
else
|
|
732
|
+
other_type_to_tag type.type.return_type
|
|
733
|
+
end
|
|
734
|
+
end
|
|
735
|
+
|
|
736
|
+
# @param type_name [RBS::TypeName]
|
|
737
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
738
|
+
# @return [ComplexType::UniqueType]
|
|
739
|
+
def build_type(type_name, type_args = [])
|
|
740
|
+
base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
|
|
741
|
+
params = type_args.map { |a| other_type_to_tag(a) }.map do |t|
|
|
742
|
+
ComplexType.try_parse(t).force_rooted
|
|
743
|
+
end
|
|
744
|
+
if base == 'Hash' && params.length == 2
|
|
745
|
+
ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
|
|
746
|
+
else
|
|
747
|
+
ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
|
|
748
|
+
end
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
# @param type_name [RBS::TypeName]
|
|
752
|
+
# @param type_args [Enumerable<RBS::Types::Bases::Base>]
|
|
753
|
+
# @return [String]
|
|
754
|
+
def type_tag(type_name, type_args = [])
|
|
755
|
+
build_type(type_name, type_args).tags
|
|
756
|
+
end
|
|
757
|
+
|
|
758
|
+
# @param type [RBS::Types::Bases::Base,Object] RBS type object.
|
|
759
|
+
# Note: Generally these extend from RBS::Types::Bases::Base,
|
|
760
|
+
# but not all.
|
|
761
|
+
# @return [String]
|
|
762
|
+
def other_type_to_tag type
|
|
763
|
+
if type.is_a?(RBS::Types::Optional)
|
|
764
|
+
"#{other_type_to_tag(type.type)}, nil"
|
|
765
|
+
elsif type.is_a?(RBS::Types::Bases::Any)
|
|
766
|
+
'undefined'
|
|
767
|
+
elsif type.is_a?(RBS::Types::Bases::Bool)
|
|
768
|
+
'Boolean'
|
|
769
|
+
elsif type.is_a?(RBS::Types::Tuple)
|
|
770
|
+
"Array(#{type.types.map { |t| other_type_to_tag(t) }.join(', ')})"
|
|
771
|
+
elsif type.is_a?(RBS::Types::Literal)
|
|
772
|
+
type.literal.inspect
|
|
773
|
+
elsif type.is_a?(RBS::Types::Union)
|
|
774
|
+
type.types.map { |t| other_type_to_tag(t) }.join(', ')
|
|
775
|
+
elsif type.is_a?(RBS::Types::Record)
|
|
776
|
+
# @todo Better record support
|
|
777
|
+
'Hash'
|
|
778
|
+
elsif type.is_a?(RBS::Types::Bases::Nil)
|
|
779
|
+
'nil'
|
|
780
|
+
elsif type.is_a?(RBS::Types::Bases::Self)
|
|
781
|
+
'self'
|
|
782
|
+
elsif type.is_a?(RBS::Types::Bases::Void)
|
|
783
|
+
'void'
|
|
784
|
+
elsif type.is_a?(RBS::Types::Variable)
|
|
785
|
+
"#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
|
|
786
|
+
elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty?
|
|
787
|
+
type_tag(type.name, type.args)
|
|
788
|
+
elsif type.is_a?(RBS::Types::Bases::Instance)
|
|
789
|
+
'self'
|
|
790
|
+
elsif type.is_a?(RBS::Types::Bases::Top)
|
|
791
|
+
# top is the most super superclass
|
|
792
|
+
'BasicObject'
|
|
793
|
+
elsif type.is_a?(RBS::Types::Bases::Bottom)
|
|
794
|
+
# bottom is used in contexts where nothing will ever return
|
|
795
|
+
# - e.g., it could be the return type of 'exit()' or 'raise'
|
|
796
|
+
#
|
|
797
|
+
# @todo define a specific bottom type and use it to
|
|
798
|
+
# determine dead code
|
|
799
|
+
'undefined'
|
|
800
|
+
elsif type.is_a?(RBS::Types::Intersection)
|
|
801
|
+
type.types.map { |member| other_type_to_tag(member) }.join(', ')
|
|
802
|
+
elsif type.is_a?(RBS::Types::Proc)
|
|
803
|
+
'Proc'
|
|
804
|
+
elsif type.is_a?(RBS::Types::Alias)
|
|
805
|
+
# type-level alias use - e.g., 'bool' in "type bool = true | false"
|
|
806
|
+
# @todo ensure these get resolved after processing all aliases
|
|
807
|
+
# @todo handle recursive aliases
|
|
808
|
+
type_tag(type.name, type.args)
|
|
809
|
+
elsif type.is_a?(RBS::Types::Interface)
|
|
810
|
+
# represents a mix-in module which can be considered a
|
|
811
|
+
# subtype of a consumer of it
|
|
812
|
+
type_tag(type.name, type.args)
|
|
813
|
+
elsif type.is_a?(RBS::Types::ClassSingleton)
|
|
814
|
+
# e.g., singleton(String)
|
|
815
|
+
type_tag(type.name)
|
|
816
|
+
else
|
|
817
|
+
# RBS doesn't provide a common base class for its type AST nodes
|
|
818
|
+
#
|
|
819
|
+
# @sg-ignore all types should include location
|
|
820
|
+
Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
|
|
821
|
+
'undefined'
|
|
822
|
+
end
|
|
823
|
+
end
|
|
824
|
+
|
|
825
|
+
# @param decl [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
|
|
826
|
+
# @param namespace [Pin::Namespace, nil]
|
|
827
|
+
# @return [void]
|
|
828
|
+
def add_mixins decl, namespace
|
|
829
|
+
# @param mixin [RBS::AST::Members::Include, RBS::AST::Members::Members::Extend, RBS::AST::Members::Members::Prepend]
|
|
830
|
+
decl.each_mixin do |mixin|
|
|
831
|
+
# @todo are we handling prepend correctly?
|
|
832
|
+
klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
|
|
833
|
+
type = build_type(mixin.name, mixin.args)
|
|
834
|
+
generic_values = type.all_params.map(&:to_s)
|
|
835
|
+
pins.push klass.new(
|
|
836
|
+
name: mixin.name.relative!.to_s,
|
|
837
|
+
type_location: location_decl_to_pin_location(mixin.location),
|
|
838
|
+
generic_values: generic_values,
|
|
839
|
+
closure: namespace,
|
|
840
|
+
source: :rbs
|
|
841
|
+
)
|
|
842
|
+
end
|
|
843
|
+
end
|
|
844
|
+
end
|
|
845
|
+
end
|
|
846
|
+
end
|