solargraph 0.48.0 → 0.49.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +1 -0
  3. data/.github/workflows/rspec.yml +1 -1
  4. data/CHANGELOG.md +9 -0
  5. data/LICENSE +1 -1
  6. data/SPONSORS.md +2 -4
  7. data/lib/solargraph/api_map/store.rb +13 -1
  8. data/lib/solargraph/api_map.rb +30 -12
  9. data/lib/solargraph/cache.rb +51 -0
  10. data/lib/solargraph/complex_type/type_methods.rb +3 -6
  11. data/lib/solargraph/complex_type/unique_type.rb +57 -0
  12. data/lib/solargraph/complex_type.rb +20 -1
  13. data/lib/solargraph/convention/rakefile.rb +17 -0
  14. data/lib/solargraph/convention.rb +2 -0
  15. data/lib/solargraph/diagnostics/rubocop.rb +15 -2
  16. data/lib/solargraph/diagnostics/rubocop_helpers.rb +3 -1
  17. data/lib/solargraph/language_server/host.rb +22 -18
  18. data/lib/solargraph/language_server/message/extended/download_core.rb +1 -5
  19. data/lib/solargraph/language_server/message/initialize.rb +2 -0
  20. data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -1
  21. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
  22. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
  23. data/lib/solargraph/library.rb +21 -20
  24. data/lib/solargraph/parser/rubyvm/class_methods.rb +6 -1
  25. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +20 -8
  26. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +14 -3
  27. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +4 -2
  28. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +47 -0
  29. data/lib/solargraph/pin/base.rb +5 -2
  30. data/lib/solargraph/pin/conversions.rb +2 -6
  31. data/lib/solargraph/pin/method.rb +84 -10
  32. data/lib/solargraph/pin/namespace.rb +4 -1
  33. data/lib/solargraph/pin/parameter.rb +8 -3
  34. data/lib/solargraph/pin/signature.rb +23 -0
  35. data/lib/solargraph/pin.rb +1 -0
  36. data/lib/solargraph/rbs_map/conversions.rb +394 -0
  37. data/lib/solargraph/rbs_map/core_fills.rb +61 -0
  38. data/lib/solargraph/rbs_map/core_map.rb +38 -0
  39. data/lib/solargraph/rbs_map/core_signs.rb +33 -0
  40. data/lib/solargraph/rbs_map/stdlib_map.rb +36 -0
  41. data/lib/solargraph/rbs_map.rb +73 -0
  42. data/lib/solargraph/shell.rb +38 -30
  43. data/lib/solargraph/source/chain/call.rb +30 -22
  44. data/lib/solargraph/source/chain.rb +21 -6
  45. data/lib/solargraph/source_map/clip.rb +5 -0
  46. data/lib/solargraph/source_map/mapper.rb +2 -0
  47. data/lib/solargraph/type_checker.rb +71 -65
  48. data/lib/solargraph/version.rb +1 -1
  49. data/lib/solargraph/views/environment.erb +2 -2
  50. data/lib/solargraph/workspace.rb +11 -14
  51. data/lib/solargraph/yard_map/mapper/to_method.rb +7 -4
  52. data/lib/solargraph/yard_map.rb +7 -148
  53. data/lib/solargraph.rb +2 -2
  54. data/solargraph.gemspec +8 -6
  55. metadata +43 -36
  56. data/lib/solargraph/compat.rb +0 -37
  57. data/lib/solargraph/yard_map/core_docs.rb +0 -170
  58. data/lib/solargraph/yard_map/core_fills.rb +0 -208
  59. data/lib/solargraph/yard_map/core_gen.rb +0 -76
  60. data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -143
  61. data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
  62. 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