solargraph 0.45.0 → 0.49.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/.github/FUNDING.yml +1 -0
- data/.github/workflows/rspec.yml +1 -1
- data/CHANGELOG.md +41 -0
- data/LICENSE +1 -1
- data/README.md +8 -0
- data/SPONSORS.md +2 -4
- data/lib/solargraph/api_map/store.rb +13 -1
- data/lib/solargraph/api_map.rb +55 -32
- data/lib/solargraph/cache.rb +51 -0
- data/lib/solargraph/complex_type/type_methods.rb +10 -6
- data/lib/solargraph/complex_type/unique_type.rb +57 -0
- data/lib/solargraph/complex_type.rb +35 -2
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +16 -0
- data/lib/solargraph/diagnostics/rubocop.rb +17 -3
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
- data/lib/solargraph/language_server/host.rb +22 -18
- data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
- data/lib/solargraph/language_server/message/initialize.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/hover.rb +16 -4
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +1 -1
- data/lib/solargraph/library.rb +21 -20
- data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +12 -2
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +24 -3
- data/lib/solargraph/parser/rubyvm/class_methods.rb +7 -2
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +13 -2
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -9
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +2 -2
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +14 -3
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
- data/lib/solargraph/pin/base.rb +5 -2
- data/lib/solargraph/pin/block.rb +2 -1
- data/lib/solargraph/pin/conversions.rb +2 -6
- data/lib/solargraph/pin/method.rb +100 -10
- data/lib/solargraph/pin/namespace.rb +4 -1
- data/lib/solargraph/pin/parameter.rb +10 -7
- data/lib/solargraph/pin/search.rb +56 -0
- data/lib/solargraph/pin/signature.rb +23 -0
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/rbs_map/conversions.rb +394 -0
- data/lib/solargraph/rbs_map/core_fills.rb +61 -0
- data/lib/solargraph/rbs_map/core_map.rb +38 -0
- data/lib/solargraph/rbs_map/core_signs.rb +33 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
- data/lib/solargraph/rbs_map.rb +73 -0
- data/lib/solargraph/shell.rb +38 -30
- data/lib/solargraph/source/chain/call.rb +34 -23
- data/lib/solargraph/source/chain.rb +21 -6
- data/lib/solargraph/source.rb +1 -1
- data/lib/solargraph/source_map/clip.rb +5 -0
- data/lib/solargraph/source_map/mapper.rb +31 -2
- data/lib/solargraph/source_map.rb +1 -10
- data/lib/solargraph/type_checker/checks.rb +13 -0
- data/lib/solargraph/type_checker.rb +88 -68
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +2 -2
- data/lib/solargraph/workspace.rb +12 -14
- data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
- data/lib/solargraph/yard_map.rb +51 -195
- data/lib/solargraph.rb +2 -2
- data/solargraph.gemspec +8 -6
- metadata +44 -36
- data/lib/solargraph/compat.rb +0 -37
- data/lib/solargraph/yard_map/core_docs.rb +0 -170
- data/lib/solargraph/yard_map/core_fills.rb +0 -208
- data/lib/solargraph/yard_map/core_gen.rb +0 -76
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
- data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
- data/yardoc/2.2.2.tar.gz +0 -0
@@ -0,0 +1,394 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class RbsMap
|
5
|
+
# Functions for converting RBS declarations to Solargraph pins
|
6
|
+
#
|
7
|
+
module Conversions
|
8
|
+
# A container for tracking the current context of the RBS conversion
|
9
|
+
# process, e.g., what visibility is declared for methods in the current
|
10
|
+
# scope
|
11
|
+
#
|
12
|
+
class Context
|
13
|
+
attr_reader :visibility
|
14
|
+
|
15
|
+
# @param visibility [Symbol]
|
16
|
+
def initialize visibility = :public
|
17
|
+
@visibility = visibility
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Array<Pin::Base>]
|
22
|
+
def pins
|
23
|
+
@pins ||= []
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def type_aliases
|
29
|
+
@type_aliases ||= {}
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param decl [RBS::AST::Declarations::Base]
|
33
|
+
# @param closure [Pin::Closure]
|
34
|
+
# @return [void]
|
35
|
+
def convert_decl_to_pin decl, closure
|
36
|
+
cursor = pins.length
|
37
|
+
case decl
|
38
|
+
when RBS::AST::Declarations::Class
|
39
|
+
class_decl_to_pin decl
|
40
|
+
when RBS::AST::Declarations::Interface
|
41
|
+
# STDERR.puts "Skipping interface #{decl.name.relative!}"
|
42
|
+
interface_decl_to_pin decl
|
43
|
+
when RBS::AST::Declarations::Alias
|
44
|
+
type_aliases[decl.name.to_s] = decl
|
45
|
+
when RBS::AST::Declarations::Module
|
46
|
+
module_decl_to_pin decl
|
47
|
+
when RBS::AST::Declarations::Constant
|
48
|
+
constant_decl_to_pin decl
|
49
|
+
end
|
50
|
+
pins[cursor..-1].each do |pin|
|
51
|
+
pin.source = :rbs
|
52
|
+
next unless pin.is_a?(Pin::Namespace) && pin.type == :class
|
53
|
+
next if pins.any? { |p| p.path == "#{pin.path}.new"}
|
54
|
+
pins.push Solargraph::Pin::Method.new(
|
55
|
+
location: nil,
|
56
|
+
closure: pin.closure,
|
57
|
+
name: 'new',
|
58
|
+
comments: pin.comments,
|
59
|
+
scope: :class
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def convert_members_to_pin decl, closure
|
65
|
+
context = Context.new
|
66
|
+
decl.members.each { |m| context = convert_member_to_pin(m, closure, context) }
|
67
|
+
end
|
68
|
+
|
69
|
+
def convert_member_to_pin member, closure, context
|
70
|
+
case member
|
71
|
+
when RBS::AST::Members::MethodDefinition
|
72
|
+
method_def_to_pin(member, closure)
|
73
|
+
when RBS::AST::Members::AttrReader
|
74
|
+
attr_reader_to_pin(member, closure)
|
75
|
+
when RBS::AST::Members::AttrWriter
|
76
|
+
attr_writer_to_pin(member, closure)
|
77
|
+
when RBS::AST::Members::AttrAccessor
|
78
|
+
attr_accessor_to_pin(member, closure)
|
79
|
+
when RBS::AST::Members::Include
|
80
|
+
include_to_pin(member, closure)
|
81
|
+
when RBS::AST::Members::Prepend
|
82
|
+
prepend_to_pin(member, closure)
|
83
|
+
when RBS::AST::Members::Extend
|
84
|
+
extend_to_pin(member, closure)
|
85
|
+
when RBS::AST::Members::Alias
|
86
|
+
alias_to_pin(member, closure)
|
87
|
+
when RBS::AST::Members::InstanceVariable
|
88
|
+
ivar_to_pin(member, closure)
|
89
|
+
when RBS::AST::Members::Public
|
90
|
+
return Context.new(visibility: :public)
|
91
|
+
when RBS::AST::Members::Private
|
92
|
+
return Context.new(visibility: :private)
|
93
|
+
when RBS::AST::Declarations::Base
|
94
|
+
convert_decl_to_pin(member, closure)
|
95
|
+
else
|
96
|
+
Solargraph.logger.warn "Skipping member #{member.class}"
|
97
|
+
end
|
98
|
+
context
|
99
|
+
end
|
100
|
+
|
101
|
+
# @param decl [RBS::AST::Declarations::Class]
|
102
|
+
# @return [void]
|
103
|
+
def class_decl_to_pin decl
|
104
|
+
class_pin = Solargraph::Pin::Namespace.new(
|
105
|
+
type: :class,
|
106
|
+
name: decl.name.relative!.to_s,
|
107
|
+
closure: Solargraph::Pin::ROOT_PIN,
|
108
|
+
comments: decl.comment&.string,
|
109
|
+
parameters: decl.type_params.map(&:name).map(&:to_s)
|
110
|
+
)
|
111
|
+
pins.push class_pin
|
112
|
+
if decl.super_class
|
113
|
+
pins.push Solargraph::Pin::Reference::Superclass.new(
|
114
|
+
closure: class_pin,
|
115
|
+
name: decl.super_class.name.relative!.to_s
|
116
|
+
)
|
117
|
+
end
|
118
|
+
convert_members_to_pin decl, class_pin
|
119
|
+
end
|
120
|
+
|
121
|
+
# @param decl [RBS::AST::Declarations::Interface]
|
122
|
+
# @return [void]
|
123
|
+
def interface_decl_to_pin decl
|
124
|
+
class_pin = Solargraph::Pin::Namespace.new(
|
125
|
+
type: :module,
|
126
|
+
name: decl.name.relative!.to_s,
|
127
|
+
closure: Solargraph::Pin::ROOT_PIN,
|
128
|
+
comments: decl.comment&.string,
|
129
|
+
# HACK: Using :hidden to keep interfaces from appearing in
|
130
|
+
# autocompletion
|
131
|
+
visibility: :hidden
|
132
|
+
)
|
133
|
+
class_pin.docstring.add_tag(YARD::Tags::Tag.new(:abstract, '(RBS interface)'))
|
134
|
+
pins.push class_pin
|
135
|
+
convert_members_to_pin decl, class_pin
|
136
|
+
end
|
137
|
+
|
138
|
+
# @param decl [RBS::AST::Declarations::Module]
|
139
|
+
# @return [void]
|
140
|
+
def module_decl_to_pin decl
|
141
|
+
module_pin = Solargraph::Pin::Namespace.new(
|
142
|
+
type: :module,
|
143
|
+
name: decl.name.relative!.to_s,
|
144
|
+
closure: Solargraph::Pin::ROOT_PIN,
|
145
|
+
comments: decl.comment&.string
|
146
|
+
)
|
147
|
+
pins.push module_pin
|
148
|
+
convert_members_to_pin decl, module_pin
|
149
|
+
end
|
150
|
+
|
151
|
+
# @param decl [RBS::AST::Declarations::Constant]
|
152
|
+
# @return [void]
|
153
|
+
def constant_decl_to_pin decl
|
154
|
+
parts = decl.name.relative!.to_s.split('::')
|
155
|
+
if parts.length > 1
|
156
|
+
name = parts.last
|
157
|
+
closure = pins.select { |pin| pin && pin.path == parts[0..-2].join('::') }.first
|
158
|
+
else
|
159
|
+
name = parts.first
|
160
|
+
closure = Solargraph::Pin::ROOT_PIN
|
161
|
+
end
|
162
|
+
pin = Solargraph::Pin::Constant.new(
|
163
|
+
name: name,
|
164
|
+
closure: closure,
|
165
|
+
comments: decl.comment&.string
|
166
|
+
)
|
167
|
+
tag = other_type_to_tag(decl.type)
|
168
|
+
# @todo Class or Module?
|
169
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', "Class<#{tag}>"))
|
170
|
+
pins.push pin
|
171
|
+
end
|
172
|
+
|
173
|
+
# @param decl [RBS::AST::Members::MethodDefinition]
|
174
|
+
# @param closure [Pin::Closure]
|
175
|
+
# @return [void]
|
176
|
+
def method_def_to_pin decl, closure
|
177
|
+
if decl.instance?
|
178
|
+
pin = Solargraph::Pin::Method.new(
|
179
|
+
name: decl.name.to_s,
|
180
|
+
closure: closure,
|
181
|
+
comments: decl.comment&.string,
|
182
|
+
scope: :instance,
|
183
|
+
signatures: []
|
184
|
+
)
|
185
|
+
pin.signatures.concat method_def_to_sigs(decl, pin)
|
186
|
+
pins.push pin
|
187
|
+
if pin.name == 'initialize'
|
188
|
+
pins.push Solargraph::Pin::Method.new(
|
189
|
+
location: pin.location,
|
190
|
+
closure: pin.closure,
|
191
|
+
name: 'new',
|
192
|
+
comments: pin.comments,
|
193
|
+
scope: :class,
|
194
|
+
signatures: pin.signatures
|
195
|
+
)
|
196
|
+
pins.last.signatures.replace(
|
197
|
+
pin.signatures.map do |p|
|
198
|
+
Pin::Signature.new(
|
199
|
+
p.parameters,
|
200
|
+
ComplexType::SELF
|
201
|
+
)
|
202
|
+
end
|
203
|
+
)
|
204
|
+
# @todo Is this necessary?
|
205
|
+
# pin.instance_variable_set(:@visibility, :private)
|
206
|
+
# pin.instance_variable_set(:@return_type, ComplexType::VOID)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
if decl.singleton?
|
210
|
+
pin = Solargraph::Pin::Method.new(
|
211
|
+
name: decl.name.to_s,
|
212
|
+
closure: closure,
|
213
|
+
comments: decl.comment&.string,
|
214
|
+
scope: :class,
|
215
|
+
signatures: []
|
216
|
+
)
|
217
|
+
pin.signatures.concat method_def_to_sigs(decl, pin)
|
218
|
+
pins.push pin
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# @param decl [RBS::AST::Members::MethodDefinition]
|
223
|
+
# @param pin [Pin::Method]
|
224
|
+
def method_def_to_sigs decl, pin
|
225
|
+
decl.types.map do |type|
|
226
|
+
parameters, return_type = parts_of_function(type, pin)
|
227
|
+
block = if type.block
|
228
|
+
Pin::Signature.new(*parts_of_function(type.block, pin))
|
229
|
+
end
|
230
|
+
return_type = ComplexType.try_parse(method_type_to_tag(type))
|
231
|
+
Pin::Signature.new(parameters, return_type, block)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def parts_of_function type, pin
|
236
|
+
parameters = []
|
237
|
+
arg_num = -1
|
238
|
+
type.type.required_positionals.each do |param|
|
239
|
+
name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
|
240
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
|
241
|
+
end
|
242
|
+
type.type.optional_positionals.each do |param|
|
243
|
+
name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
|
244
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin)
|
245
|
+
end
|
246
|
+
if type.type.rest_positionals
|
247
|
+
name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg#{arg_num += 1}"
|
248
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin)
|
249
|
+
end
|
250
|
+
type.type.trailing_positionals.each do |param|
|
251
|
+
name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
|
252
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin)
|
253
|
+
end
|
254
|
+
type.type.required_keywords.each do |orig, _param|
|
255
|
+
name = orig ? orig.to_s : "arg#{arg_num += 1}"
|
256
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin)
|
257
|
+
end
|
258
|
+
type.type.optional_keywords.each do |orig, _param|
|
259
|
+
name = orig ? orig.to_s : "arg#{arg_num += 1}"
|
260
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin)
|
261
|
+
end
|
262
|
+
if type.type.rest_keywords
|
263
|
+
name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg#{arg_num += 1}"
|
264
|
+
parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg, name: type.type.rest_keywords.name.to_s, closure: pin)
|
265
|
+
end
|
266
|
+
return_type = ComplexType.try_parse(method_type_to_tag(type))
|
267
|
+
[parameters, return_type]
|
268
|
+
end
|
269
|
+
|
270
|
+
def attr_reader_to_pin(decl, closure)
|
271
|
+
pin = Solargraph::Pin::Method.new(
|
272
|
+
name: decl.name.to_s,
|
273
|
+
closure: closure,
|
274
|
+
comments: decl.comment&.string,
|
275
|
+
scope: :instance,
|
276
|
+
attribute: true
|
277
|
+
)
|
278
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', other_type_to_tag(decl.type)))
|
279
|
+
pins.push pin
|
280
|
+
end
|
281
|
+
|
282
|
+
def attr_writer_to_pin(decl, closure)
|
283
|
+
pin = Solargraph::Pin::Method.new(
|
284
|
+
name: "#{decl.name.to_s}=",
|
285
|
+
closure: closure,
|
286
|
+
comments: decl.comment&.string,
|
287
|
+
scope: :instance,
|
288
|
+
attribute: true
|
289
|
+
)
|
290
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', other_type_to_tag(decl.type)))
|
291
|
+
pins.push pin
|
292
|
+
end
|
293
|
+
|
294
|
+
def attr_accessor_to_pin(decl, closure)
|
295
|
+
attr_reader_to_pin(decl, closure)
|
296
|
+
attr_writer_to_pin(decl, closure)
|
297
|
+
end
|
298
|
+
|
299
|
+
def ivar_to_pin(decl, closure)
|
300
|
+
pin = Solargraph::Pin::InstanceVariable.new(
|
301
|
+
name: decl.name.to_s,
|
302
|
+
closure: closure,
|
303
|
+
comments: decl.comment&.string
|
304
|
+
)
|
305
|
+
pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
|
306
|
+
pins.push pin
|
307
|
+
end
|
308
|
+
|
309
|
+
def include_to_pin decl, closure
|
310
|
+
pins.push Solargraph::Pin::Reference::Include.new(
|
311
|
+
name: decl.name.relative!.to_s,
|
312
|
+
closure: closure
|
313
|
+
)
|
314
|
+
end
|
315
|
+
|
316
|
+
def prepend_to_pin decl, closure
|
317
|
+
pins.push Solargraph::Pin::Reference::Prepend.new(
|
318
|
+
name: decl.name.relative!.to_s,
|
319
|
+
closure: closure
|
320
|
+
)
|
321
|
+
end
|
322
|
+
|
323
|
+
def extend_to_pin decl, closure
|
324
|
+
pins.push Solargraph::Pin::Reference::Extend.new(
|
325
|
+
name: decl.name.relative!.to_s,
|
326
|
+
closure: closure
|
327
|
+
)
|
328
|
+
end
|
329
|
+
|
330
|
+
def alias_to_pin decl, closure
|
331
|
+
pins.push Solargraph::Pin::MethodAlias.new(
|
332
|
+
name: decl.new_name.to_s,
|
333
|
+
original: decl.old_name.to_s,
|
334
|
+
closure: closure
|
335
|
+
)
|
336
|
+
end
|
337
|
+
|
338
|
+
RBS_TO_YARD_TYPE = {
|
339
|
+
'bool' => 'Boolean',
|
340
|
+
'string' => 'String',
|
341
|
+
'int' => 'Integer',
|
342
|
+
'untyped' => '',
|
343
|
+
'NilClass' => 'nil'
|
344
|
+
}
|
345
|
+
|
346
|
+
def method_type_to_tag type
|
347
|
+
if type_aliases.key?(type.type.return_type.to_s)
|
348
|
+
other_type_to_tag(type_aliases[type.type.return_type.to_s].type)
|
349
|
+
else
|
350
|
+
other_type_to_tag type.type.return_type
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
# @return [String]
|
355
|
+
def other_type_to_tag type
|
356
|
+
if type.is_a?(RBS::Types::Optional)
|
357
|
+
"#{other_type_to_tag(type.type)}, nil"
|
358
|
+
elsif type.is_a?(RBS::Types::Bases::Any)
|
359
|
+
# @todo Not sure what to do with Any yet
|
360
|
+
'BasicObject'
|
361
|
+
elsif type.is_a?(RBS::Types::Bases::Bool)
|
362
|
+
'Boolean'
|
363
|
+
elsif type.is_a?(RBS::Types::Tuple)
|
364
|
+
"Array(#{type.types.map { |t| other_type_to_tag(t) }.join(', ')})"
|
365
|
+
elsif type.is_a?(RBS::Types::Literal)
|
366
|
+
"#{type.literal}"
|
367
|
+
elsif type.is_a?(RBS::Types::Union)
|
368
|
+
type.types.map { |t| other_type_to_tag(t) }.join(', ')
|
369
|
+
elsif type.is_a?(RBS::Types::Record)
|
370
|
+
# @todo Better record support
|
371
|
+
'Hash'
|
372
|
+
elsif type.is_a?(RBS::Types::Bases::Nil)
|
373
|
+
'nil'
|
374
|
+
elsif type.is_a?(RBS::Types::Bases::Self)
|
375
|
+
'self'
|
376
|
+
elsif type.is_a?(RBS::Types::Bases::Void)
|
377
|
+
'void'
|
378
|
+
elsif type.is_a?(RBS::Types::Variable)
|
379
|
+
"param<#{type.name}>"
|
380
|
+
elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty?
|
381
|
+
base = RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
|
382
|
+
params = type.args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' }
|
383
|
+
return base if params.empty?
|
384
|
+
"#{base}<#{params.join(', ')}>"
|
385
|
+
elsif type.respond_to?(:name) && type.name.respond_to?(:relative!)
|
386
|
+
RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
|
387
|
+
else
|
388
|
+
Solargraph.logger.warn "Unrecognized RBS type: #{type.class} #{type}"
|
389
|
+
'undefined'
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class RbsMap
|
5
|
+
# Override pins to fill gaps in RbsMap::CoreMap coverage
|
6
|
+
#
|
7
|
+
module CoreFills
|
8
|
+
Override = Pin::Reference::Override
|
9
|
+
|
10
|
+
KEYWORDS = [
|
11
|
+
'__ENCODING__', '__LINE__', '__FILE__', 'BEGIN', 'END', 'alias', 'and',
|
12
|
+
'begin', 'break', 'case', 'class', 'def', 'defined?', 'do', 'else',
|
13
|
+
'elsif', 'end', 'ensure', 'false', 'for', 'if', 'in', 'module', 'next',
|
14
|
+
'nil', 'not', 'or', 'redo', 'rescue', 'retry', 'return', 'self', 'super',
|
15
|
+
'then', 'true', 'undef', 'unless', 'until', 'when', 'while', 'yield'
|
16
|
+
].map { |k| Pin::Keyword.new(k) }
|
17
|
+
|
18
|
+
YIELDPARAMS = [
|
19
|
+
Override.from_comment('Object#tap', %(
|
20
|
+
@return [self]
|
21
|
+
@yieldparam [self]
|
22
|
+
)),
|
23
|
+
Override.from_comment('String#each_line', %(
|
24
|
+
@yieldparam [String]
|
25
|
+
)),
|
26
|
+
]
|
27
|
+
|
28
|
+
methods_with_yieldparam_subtypes = %w[
|
29
|
+
Array#each Array#map Array#map! Array#any? Array#all? Array#index
|
30
|
+
Array#keep_if Array#delete_if
|
31
|
+
Enumerable#each_entry Enumerable#map Enumerable#any? Enumerable#all?
|
32
|
+
Enumerable#select Enumerable#reject
|
33
|
+
Set#each
|
34
|
+
]
|
35
|
+
|
36
|
+
YIELDPARAM_SINGLE_PARAMETERS = methods_with_yieldparam_subtypes.map do |path|
|
37
|
+
Override.from_comment(path, %(
|
38
|
+
@yieldparam_single_parameter
|
39
|
+
))
|
40
|
+
end
|
41
|
+
|
42
|
+
CLASS_RETURN_TYPES = [
|
43
|
+
Override.method_return('Class#new', 'self'),
|
44
|
+
Override.method_return('Class.new', 'Class<BasicObject>'),
|
45
|
+
Override.method_return('Class#allocate', 'self'),
|
46
|
+
Override.method_return('Class.allocate', 'Class<BasicObject>'),
|
47
|
+
]
|
48
|
+
|
49
|
+
# HACK: Add Errno exception classes
|
50
|
+
errno = Solargraph::Pin::Namespace.new(name: 'Errno')
|
51
|
+
errnos = []
|
52
|
+
Errno.constants.each do |const|
|
53
|
+
errnos.push Solargraph::Pin::Namespace.new(type: :class, name: const.to_s, closure: errno)
|
54
|
+
errnos.push Solargraph::Pin::Reference::Superclass.new(closure: errnos.last, name: 'SystemCallError')
|
55
|
+
end
|
56
|
+
ERRNOS = errnos
|
57
|
+
|
58
|
+
ALL = KEYWORDS + YIELDPARAMS + YIELDPARAM_SINGLE_PARAMETERS + CLASS_RETURN_TYPES + ERRNOS
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
class RbsMap
|
5
|
+
# Ruby core pins
|
6
|
+
#
|
7
|
+
class CoreMap
|
8
|
+
include Conversions
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
cache = Cache.load('core.ser')
|
12
|
+
if cache
|
13
|
+
pins.replace cache
|
14
|
+
else
|
15
|
+
loader = RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: true))
|
16
|
+
environment = RBS::Environment.from_loader(loader).resolve_type_names
|
17
|
+
environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
|
18
|
+
pins.concat RbsMap::CoreFills::ALL
|
19
|
+
processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
|
20
|
+
pins.replace processed
|
21
|
+
|
22
|
+
Cache.save('core.ser', pins)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def method_def_to_sigs decl, pin
|
27
|
+
stubs = CoreSigns.sign(pin.path)
|
28
|
+
return super unless stubs
|
29
|
+
stubs.map do |stub|
|
30
|
+
Pin::Signature.new(
|
31
|
+
[],
|
32
|
+
ComplexType.try_parse(stub.return_type)
|
33
|
+
)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Solargraph
|
2
|
+
class RbsMap
|
3
|
+
module CoreSigns
|
4
|
+
Override = Pin::Reference::Override
|
5
|
+
|
6
|
+
class Stub
|
7
|
+
attr_reader :parameters
|
8
|
+
|
9
|
+
attr_reader :return_type
|
10
|
+
|
11
|
+
def initialize parameters, return_type
|
12
|
+
@parameters = parameters
|
13
|
+
@return_type = return_type
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
SIGNATURE_MAP = {
|
18
|
+
'Object#class' => [
|
19
|
+
Stub.new(
|
20
|
+
[],
|
21
|
+
'Class<self>'
|
22
|
+
)
|
23
|
+
]
|
24
|
+
}
|
25
|
+
|
26
|
+
# @param path [String]
|
27
|
+
# @return [Array<Stub>]
|
28
|
+
def self.sign path
|
29
|
+
SIGNATURE_MAP[path]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rbs'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
module Solargraph
|
7
|
+
class RbsMap
|
8
|
+
# Ruby stdlib pins
|
9
|
+
#
|
10
|
+
class StdlibMap < RbsMap
|
11
|
+
# @type [Hash{String => RbsMap}]
|
12
|
+
@stdlib_maps_hash = {}
|
13
|
+
|
14
|
+
# @param library [String]
|
15
|
+
def initialize library
|
16
|
+
cache = Cache.load('stdlib', "#{library}.ser")
|
17
|
+
if cache
|
18
|
+
pins.replace cache
|
19
|
+
else
|
20
|
+
super
|
21
|
+
Cache.save('stdlib', "#{library}.ser", pins)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param library [String]
|
26
|
+
# @return [StdlibMap]
|
27
|
+
def self.load library
|
28
|
+
@stdlib_maps_hash[library] ||= StdlibMap.new(library)
|
29
|
+
end
|
30
|
+
|
31
|
+
def repository
|
32
|
+
@repository ||= RBS::Repository.new
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rbs'
|
4
|
+
require 'set'
|
5
|
+
|
6
|
+
module Solargraph
|
7
|
+
class RbsMap
|
8
|
+
autoload :Conversions, 'solargraph/rbs_map/conversions'
|
9
|
+
autoload :CoreMap, 'solargraph/rbs_map/core_map'
|
10
|
+
autoload :CoreFills, 'solargraph/rbs_map/core_fills'
|
11
|
+
autoload :CoreSigns, 'solargraph/rbs_map/core_signs'
|
12
|
+
autoload :StdlibMap, 'solargraph/rbs_map/stdlib_map'
|
13
|
+
|
14
|
+
include Conversions
|
15
|
+
|
16
|
+
# @type [Hash{String => RbsMap}]
|
17
|
+
@@rbs_maps_hash = {}
|
18
|
+
|
19
|
+
attr_reader :library
|
20
|
+
|
21
|
+
# @param library [String]
|
22
|
+
def initialize library
|
23
|
+
@library = library
|
24
|
+
loader = RBS::EnvironmentLoader.new(core_root: nil, repository: repository)
|
25
|
+
add_library loader, library
|
26
|
+
return unless resolved?
|
27
|
+
environment = RBS::Environment.from_loader(loader).resolve_type_names
|
28
|
+
environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def path_pin path
|
32
|
+
pins.find { |p| p.path == path }
|
33
|
+
end
|
34
|
+
|
35
|
+
def path_pins path
|
36
|
+
pins.select { |p| p.path == path }
|
37
|
+
end
|
38
|
+
|
39
|
+
def resolved?
|
40
|
+
@resolved
|
41
|
+
end
|
42
|
+
|
43
|
+
# @param library [String]
|
44
|
+
# @return [RbsMap]
|
45
|
+
def self.load library
|
46
|
+
@@rbs_maps_hash[library] ||= RbsMap.new(library)
|
47
|
+
end
|
48
|
+
|
49
|
+
def repository
|
50
|
+
@repository ||= RBS::Repository.new(no_stdlib: true)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
# @param loader [RBS::EnvironmentLoader]
|
56
|
+
# @param library [String]
|
57
|
+
# @return [Boolean] true if adding the library succeeded
|
58
|
+
def add_library loader, library
|
59
|
+
@resolved = if loader.has_library?(library: library, version: nil)
|
60
|
+
loader.add library: library
|
61
|
+
Solargraph.logger.info "#{short_name} successfully loaded library #{library}"
|
62
|
+
true
|
63
|
+
else
|
64
|
+
Solargraph.logger.info "#{short_name} failed to load library #{library}"
|
65
|
+
false
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def short_name
|
70
|
+
self.class.name.split('::').last
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|