solargraph 0.51.2 → 0.53.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.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/plugins.yml +40 -0
  3. data/.github/workflows/rspec.yml +1 -3
  4. data/.github/workflows/typecheck.yml +34 -0
  5. data/.yardopts +2 -2
  6. data/CHANGELOG.md +55 -5
  7. data/README.md +13 -16
  8. data/SPONSORS.md +1 -7
  9. data/lib/solargraph/api_map/cache.rb +60 -20
  10. data/lib/solargraph/api_map/store.rb +47 -11
  11. data/lib/solargraph/api_map.rb +161 -95
  12. data/lib/solargraph/bench.rb +2 -2
  13. data/lib/solargraph/cache.rb +29 -5
  14. data/lib/solargraph/complex_type/type_methods.rb +54 -9
  15. data/lib/solargraph/complex_type/unique_type.rb +155 -58
  16. data/lib/solargraph/complex_type.rb +73 -16
  17. data/lib/solargraph/convention.rb +0 -1
  18. data/lib/solargraph/converters/dd.rb +5 -0
  19. data/lib/solargraph/converters/dl.rb +3 -0
  20. data/lib/solargraph/converters/dt.rb +3 -0
  21. data/lib/solargraph/diagnostics/rubocop.rb +8 -7
  22. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
  23. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  24. data/lib/solargraph/diagnostics.rb +2 -2
  25. data/lib/solargraph/doc_map.rb +146 -0
  26. data/lib/solargraph/gem_pins.rb +64 -0
  27. data/lib/solargraph/language_server/host/cataloger.rb +1 -0
  28. data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
  29. data/lib/solargraph/language_server/host/dispatch.rb +10 -4
  30. data/lib/solargraph/language_server/host/message_worker.rb +4 -0
  31. data/lib/solargraph/language_server/host/sources.rb +7 -4
  32. data/lib/solargraph/language_server/host.rb +15 -6
  33. data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
  34. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
  35. data/lib/solargraph/language_server/message/initialize.rb +5 -2
  36. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  37. data/lib/solargraph/language_server/message/text_document.rb +0 -1
  38. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
  39. data/lib/solargraph/language_server/transport/adapter.rb +16 -1
  40. data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
  41. data/lib/solargraph/library.rb +70 -16
  42. data/lib/solargraph/location.rb +1 -0
  43. data/lib/solargraph/parser/comment_ripper.rb +4 -0
  44. data/lib/solargraph/parser/node_methods.rb +47 -7
  45. data/lib/solargraph/parser/node_processor/base.rb +9 -0
  46. data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -5
  47. data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
  48. data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +49 -36
  49. data/lib/solargraph/parser/parser_gem/node_methods.rb +499 -0
  50. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
  51. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/args_node.rb +4 -1
  52. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
  53. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
  54. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
  55. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
  56. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
  57. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
  58. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
  59. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
  60. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +2 -2
  61. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
  62. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
  63. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
  64. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
  65. data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +2 -2
  66. data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
  67. data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -0
  68. data/lib/solargraph/parser/parser_gem.rb +12 -0
  69. data/lib/solargraph/parser/region.rb +1 -1
  70. data/lib/solargraph/parser/snippet.rb +2 -0
  71. data/lib/solargraph/parser.rb +8 -9
  72. data/lib/solargraph/pin/base.rb +64 -9
  73. data/lib/solargraph/pin/base_variable.rb +6 -2
  74. data/lib/solargraph/pin/block.rb +13 -8
  75. data/lib/solargraph/pin/closure.rb +17 -2
  76. data/lib/solargraph/pin/common.rb +7 -3
  77. data/lib/solargraph/pin/conversions.rb +33 -3
  78. data/lib/solargraph/pin/delegated_method.rb +1 -1
  79. data/lib/solargraph/pin/documenting.rb +25 -34
  80. data/lib/solargraph/pin/instance_variable.rb +4 -0
  81. data/lib/solargraph/pin/local_variable.rb +13 -1
  82. data/lib/solargraph/pin/method.rb +169 -18
  83. data/lib/solargraph/pin/namespace.rb +18 -5
  84. data/lib/solargraph/pin/parameter.rb +44 -14
  85. data/lib/solargraph/pin/reference/override.rb +2 -2
  86. data/lib/solargraph/pin/reference.rb +8 -0
  87. data/lib/solargraph/pin/search.rb +3 -3
  88. data/lib/solargraph/pin/signature.rb +123 -3
  89. data/lib/solargraph/pin.rb +0 -1
  90. data/lib/solargraph/range.rb +2 -2
  91. data/lib/solargraph/rbs_map/conversions.rb +287 -45
  92. data/lib/solargraph/rbs_map/core_fills.rb +6 -29
  93. data/lib/solargraph/rbs_map/core_map.rb +2 -1
  94. data/lib/solargraph/rbs_map/core_signs.rb +2 -0
  95. data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
  96. data/lib/solargraph/rbs_map.rb +20 -11
  97. data/lib/solargraph/shell.rb +62 -59
  98. data/lib/solargraph/source/chain/array.rb +32 -0
  99. data/lib/solargraph/source/chain/block_symbol.rb +13 -0
  100. data/lib/solargraph/source/chain/call.rb +99 -46
  101. data/lib/solargraph/source/chain/constant.rb +15 -1
  102. data/lib/solargraph/source/chain/if.rb +23 -0
  103. data/lib/solargraph/source/chain/link.rb +8 -2
  104. data/lib/solargraph/source/chain/or.rb +1 -1
  105. data/lib/solargraph/source/chain/z_super.rb +3 -3
  106. data/lib/solargraph/source/chain.rb +29 -14
  107. data/lib/solargraph/source/change.rb +3 -0
  108. data/lib/solargraph/source/cursor.rb +2 -0
  109. data/lib/solargraph/source/source_chainer.rb +8 -5
  110. data/lib/solargraph/source.rb +18 -19
  111. data/lib/solargraph/source_map/clip.rb +11 -23
  112. data/lib/solargraph/source_map/mapper.rb +12 -1
  113. data/lib/solargraph/source_map.rb +15 -5
  114. data/lib/solargraph/type_checker/checks.rb +10 -2
  115. data/lib/solargraph/type_checker.rb +92 -26
  116. data/lib/solargraph/version.rb +1 -1
  117. data/lib/solargraph/workspace/config.rb +8 -6
  118. data/lib/solargraph/workspace.rb +3 -2
  119. data/lib/solargraph/yard_map/cache.rb +6 -0
  120. data/lib/solargraph/yard_map/helpers.rb +1 -1
  121. data/lib/solargraph/yard_map/mapper/to_method.rb +11 -1
  122. data/lib/solargraph/yard_map/mapper.rb +1 -1
  123. data/lib/solargraph/yard_map/to_method.rb +11 -4
  124. data/lib/solargraph/yard_map.rb +1 -292
  125. data/lib/solargraph/yard_tags.rb +20 -0
  126. data/lib/solargraph/yardoc.rb +52 -0
  127. data/lib/solargraph.rb +6 -4
  128. data/solargraph.gemspec +3 -2
  129. metadata +51 -58
  130. data/lib/solargraph/api_map/bundler_methods.rb +0 -22
  131. data/lib/solargraph/documentor.rb +0 -76
  132. data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
  133. data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
  134. data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
  135. data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
  136. data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
  137. data/lib/solargraph/parser/legacy.rb +0 -12
  138. data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -153
  139. data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
  140. data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
  141. data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
  142. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
  143. data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
  144. data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
  145. data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
  146. data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
  147. data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
  148. data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
  149. data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
  150. data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
  151. data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
  152. data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
  153. data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
  154. data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
  155. data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
  156. data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
  157. data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
  158. data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
  159. data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
  160. data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
  161. data/lib/solargraph/parser/rubyvm.rb +0 -40
  162. data/lib/yard-solargraph.rb +0 -33
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'rbs'
4
+
3
5
  module Solargraph
4
6
  class RbsMap
5
7
  # Functions for converting RBS declarations to Solargraph pins
@@ -25,47 +27,96 @@ module Solargraph
25
27
 
26
28
  private
27
29
 
30
+ # @return [Hash{String => RBS::AST::Declarations::TypeAlias}]
28
31
  def type_aliases
29
32
  @type_aliases ||= {}
30
33
  end
31
34
 
35
+ # @param loader [RBS::EnvironmentLoader]
36
+ # @return [void]
37
+ def load_environment_to_pins(loader)
38
+ environment = RBS::Environment.from_loader(loader).resolve_type_names
39
+ cursor = pins.length
40
+ environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
41
+ added_pins = pins[cursor..-1]
42
+ add_back_implicit_pins(added_pins)
43
+ end
44
+
45
+ # @param added_pins [::Enumerable<Pin>]
46
+ # @return [void]
47
+ def add_back_implicit_pins(added_pins)
48
+ added_pins.each do |pin|
49
+ pin.source = :rbs
50
+ next unless pin.is_a?(Pin::Namespace) && pin.type == :class
51
+ next if pins.any? { |p| p.path == "#{pin.path}.new"}
52
+ pins.push Solargraph::Pin::Method.new(
53
+ location: nil,
54
+ closure: pin,
55
+ name: 'new',
56
+ comments: pin.comments,
57
+ scope: :class
58
+ )
59
+ end
60
+ end
61
+
32
62
  # @param decl [RBS::AST::Declarations::Base]
33
63
  # @param closure [Pin::Closure]
34
64
  # @return [void]
35
65
  def convert_decl_to_pin decl, closure
36
- cursor = pins.length
37
66
  case decl
38
67
  when RBS::AST::Declarations::Class
39
68
  class_decl_to_pin decl
40
69
  when RBS::AST::Declarations::Interface
41
70
  # STDERR.puts "Skipping interface #{decl.name.relative!}"
42
- interface_decl_to_pin decl
71
+ interface_decl_to_pin decl, closure
43
72
  when RBS::AST::Declarations::TypeAlias
44
73
  type_aliases[decl.name.to_s] = decl
45
74
  when RBS::AST::Declarations::Module
46
75
  module_decl_to_pin decl
47
76
  when RBS::AST::Declarations::Constant
48
77
  constant_decl_to_pin decl
78
+ when RBS::AST::Declarations::ClassAlias
79
+ class_alias_decl_to_pin decl
80
+ when RBS::AST::Declarations::ModuleAlias
81
+ module_alias_decl_to_pin decl
82
+ when RBS::AST::Declarations::Global
83
+ global_decl_to_pin decl
84
+ else
85
+ Solargraph.logger.warn "Skipping declaration #{decl.class}"
49
86
  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
87
  end
63
88
 
64
- def convert_members_to_pin decl, closure
89
+ # @param decl [RBS::AST::Declarations::Module]
90
+ # @param module_pin [Pin::Namespace]
91
+ # @return [void]
92
+ def convert_self_types_to_pins decl, module_pin
93
+ decl.self_types.each { |self_type| context = convert_self_type_to_pins(self_type, module_pin) }
94
+ end
95
+
96
+ # @param decl [RBS::AST::Declarations::Module::Self]
97
+ # @param closure [Pin::Namespace]
98
+ # @return [void]
99
+ def convert_self_type_to_pins decl, closure
100
+ include_pin = Solargraph::Pin::Reference::Include.new(
101
+ name: decl.name.relative!.to_s,
102
+ location: rbs_location_to_location(decl.location),
103
+ closure: closure
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
65
112
  context = Context.new
66
113
  decl.members.each { |m| context = convert_member_to_pin(m, closure, context) }
67
114
  end
68
115
 
116
+ # @param member [RBS::AST::Members::Base,RBS::AST::Declarations::Base]
117
+ # @param closure [Pin::Namespace]
118
+ # @param context [Context]
119
+ # @return [void]
69
120
  def convert_member_to_pin member, closure, context
70
121
  case member
71
122
  when RBS::AST::Members::MethodDefinition
@@ -84,6 +135,10 @@ module Solargraph
84
135
  extend_to_pin(member, closure)
85
136
  when RBS::AST::Members::Alias
86
137
  alias_to_pin(member, closure)
138
+ when RBS::AST::Members::ClassInstanceVariable
139
+ civar_to_pin(member, closure)
140
+ when RBS::AST::Members::ClassVariable
141
+ cvar_to_pin(member, closure)
87
142
  when RBS::AST::Members::InstanceVariable
88
143
  ivar_to_pin(member, closure)
89
144
  when RBS::AST::Members::Public
@@ -93,7 +148,7 @@ module Solargraph
93
148
  when RBS::AST::Declarations::Base
94
149
  convert_decl_to_pin(member, closure)
95
150
  else
96
- Solargraph.logger.warn "Skipping member #{member.class}"
151
+ Solargraph.logger.warn "Skipping member type #{member.class}"
97
152
  end
98
153
  context
99
154
  end
@@ -106,7 +161,10 @@ module Solargraph
106
161
  name: decl.name.relative!.to_s,
107
162
  closure: Solargraph::Pin::ROOT_PIN,
108
163
  comments: decl.comment&.string,
109
- parameters: decl.type_params.map(&:name).map(&:to_s)
164
+ # @todo some type parameters in core/stdlib have default
165
+ # values; Solargraph doesn't support that yet as so these
166
+ # get treated as undefined if not specified
167
+ generics: decl.type_params.map(&:name).map(&:to_s)
110
168
  )
111
169
  pins.push class_pin
112
170
  if decl.super_class
@@ -115,24 +173,27 @@ module Solargraph
115
173
  name: decl.super_class.name.relative!.to_s
116
174
  )
117
175
  end
118
- convert_members_to_pin decl, class_pin
176
+ add_mixins decl, class_pin.closure
177
+ convert_members_to_pins decl, class_pin
119
178
  end
120
179
 
121
180
  # @param decl [RBS::AST::Declarations::Interface]
181
+ # @param closure [Pin::Closure]
122
182
  # @return [void]
123
- def interface_decl_to_pin decl
183
+ def interface_decl_to_pin decl, closure
124
184
  class_pin = Solargraph::Pin::Namespace.new(
125
185
  type: :module,
126
186
  name: decl.name.relative!.to_s,
127
187
  closure: Solargraph::Pin::ROOT_PIN,
128
188
  comments: decl.comment&.string,
189
+ generics: decl.type_params.map(&:name).map(&:to_s),
129
190
  # HACK: Using :hidden to keep interfaces from appearing in
130
191
  # autocompletion
131
192
  visibility: :hidden
132
193
  )
133
194
  class_pin.docstring.add_tag(YARD::Tags::Tag.new(:abstract, '(RBS interface)'))
134
195
  pins.push class_pin
135
- convert_members_to_pin decl, class_pin
196
+ convert_members_to_pins decl, class_pin
136
197
  end
137
198
 
138
199
  # @param decl [RBS::AST::Declarations::Module]
@@ -142,16 +203,24 @@ module Solargraph
142
203
  type: :module,
143
204
  name: decl.name.relative!.to_s,
144
205
  closure: Solargraph::Pin::ROOT_PIN,
145
- comments: decl.comment&.string
206
+ comments: decl.comment&.string,
207
+ generics: decl.type_params.map(&:name).map(&:to_s),
146
208
  )
147
209
  pins.push module_pin
148
- convert_members_to_pin decl, module_pin
210
+ convert_self_types_to_pins decl, module_pin
211
+ convert_members_to_pins decl, module_pin
212
+
213
+ add_mixins decl, module_pin.closure
149
214
  end
150
215
 
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('::')
216
+ # @param name [String]
217
+ # @param tag [String]
218
+ # @param comments [String]
219
+ # @param base [String, nil] Optional conversion of tag to base<tag>
220
+ #
221
+ # @return [Solargraph::Pin::Constant]
222
+ def create_constant(name, tag, comments, base = nil)
223
+ parts = name.split('::')
155
224
  if parts.length > 1
156
225
  name = parts.last
157
226
  closure = pins.select { |pin| pin && pin.path == parts[0..-2].join('::') }.first
@@ -159,14 +228,55 @@ module Solargraph
159
228
  name = parts.first
160
229
  closure = Solargraph::Pin::ROOT_PIN
161
230
  end
162
- pin = Solargraph::Pin::Constant.new(
231
+ constant_pin = Solargraph::Pin::Constant.new(
163
232
  name: name,
164
233
  closure: closure,
165
- comments: decl.comment&.string
234
+ comments: comments
166
235
  )
236
+ tag = "#{base}<#{tag}>" if base
237
+ constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', tag))
238
+ constant_pin
239
+ end
240
+
241
+ # @param decl [RBS::AST::Declarations::ClassAlias]
242
+ # @return [void]
243
+ def class_alias_decl_to_pin decl
244
+ # See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ClassAlias
245
+ new_name = decl.new_name.relative!.to_s
246
+ old_name = decl.old_name.relative!.to_s
247
+
248
+ pins.push create_constant(new_name, old_name, decl.comment&.string, 'Class')
249
+ end
250
+
251
+ # @param decl [RBS::AST::Declarations::ModuleAlias]
252
+ # @return [void]
253
+ def module_alias_decl_to_pin decl
254
+ # See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ModuleAlias
255
+ new_name = decl.new_name.relative!.to_s
256
+ old_name = decl.old_name.relative!.to_s
257
+
258
+ pins.push create_constant(new_name, old_name, decl.comment&.string, 'Module')
259
+ end
260
+
261
+ # @param decl [RBS::AST::Declarations::Constant]
262
+ # @return [void]
263
+ def constant_decl_to_pin decl
167
264
  tag = other_type_to_tag(decl.type)
168
- # @todo Class or Module?
169
- pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', "Class<#{tag}>"))
265
+ pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string)
266
+ end
267
+
268
+ # @param decl [RBS::AST::Declarations::Global]
269
+ # @return [void]
270
+ def global_decl_to_pin decl
271
+ closure = Solargraph::Pin::ROOT_PIN
272
+ name = decl.name.to_s
273
+ tag = other_type_to_tag(decl.type)
274
+ pin = Solargraph::Pin::GlobalVariable.new(
275
+ name: name,
276
+ closure: closure,
277
+ comments: decl.comment&.string,
278
+ )
279
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', tag))
170
280
  pins.push pin
171
281
  end
172
282
 
@@ -174,13 +284,21 @@ module Solargraph
174
284
  # @param closure [Pin::Closure]
175
285
  # @return [void]
176
286
  def method_def_to_pin decl, closure
287
+ # there may be edge cases here around different signatures
288
+ # having different type params / orders - we may need to match
289
+ # this data model and have generics live in signatures to
290
+ # handle those correctly
291
+ generics = decl.overloads.map(&:method_type).flat_map(&:type_params).map(&:name).map(&:to_s).uniq
177
292
  if decl.instance?
178
293
  pin = Solargraph::Pin::Method.new(
179
294
  name: decl.name.to_s,
180
295
  closure: closure,
181
296
  comments: decl.comment&.string,
182
297
  scope: :instance,
183
- signatures: []
298
+ signatures: [],
299
+ generics: generics,
300
+ # @todo RBS core has unreliable visibility definitions
301
+ visibility: closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(decl.name) ? :private : :public
184
302
  )
185
303
  pin.signatures.concat method_def_to_sigs(decl, pin)
186
304
  pins.push pin
@@ -196,6 +314,7 @@ module Solargraph
196
314
  pins.last.signatures.replace(
197
315
  pin.signatures.map do |p|
198
316
  Pin::Signature.new(
317
+ p.generics,
199
318
  p.parameters,
200
319
  ComplexType::SELF
201
320
  )
@@ -212,7 +331,8 @@ module Solargraph
212
331
  closure: closure,
213
332
  comments: decl.comment&.string,
214
333
  scope: :class,
215
- signatures: []
334
+ signatures: [],
335
+ generics: generics
216
336
  )
217
337
  pin.signatures.concat method_def_to_sigs(decl, pin)
218
338
  pins.push pin
@@ -221,17 +341,33 @@ module Solargraph
221
341
 
222
342
  # @param decl [RBS::AST::Members::MethodDefinition]
223
343
  # @param pin [Pin::Method]
344
+ # @return [void]
224
345
  def method_def_to_sigs decl, pin
225
346
  decl.overloads.map do |overload|
347
+ generics = overload.method_type.type_params.map(&:to_s)
226
348
  parameters, return_type = parts_of_function(overload.method_type, pin)
227
349
  block = if overload.method_type.block
228
- Pin::Signature.new(*parts_of_function(overload.method_type.block, pin))
350
+ Pin::Signature.new(generics, *parts_of_function(overload.method_type.block, pin))
229
351
  end
230
352
  return_type = ComplexType.try_parse(method_type_to_tag(overload.method_type))
231
- Pin::Signature.new(parameters, return_type, block)
353
+ Pin::Signature.new(generics, parameters, return_type, block)
232
354
  end
233
355
  end
234
356
 
357
+ # @param location [RBS::Location, nil]
358
+ # @return [Solargraph::Location, nil]
359
+ def rbs_location_to_location(location)
360
+ return nil if location&.name.nil?
361
+
362
+ start_pos = Position.new(location.start_line - 1, location.start_column)
363
+ end_pos = Position.new(location.end_line - 1, location.end_column)
364
+ range = Range.new(start_pos, end_pos)
365
+ Location.new(location.name, range)
366
+ end
367
+
368
+ # @param type [RBS::MethodType,RBS::Types::Block]
369
+ # @param pin [Pin::Method]
370
+ # @return [Array<Array<Pin::Parameter>, ComplexType>]
235
371
  def parts_of_function type, pin
236
372
  return [[Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin)], ComplexType.try_parse(method_type_to_tag(type))] if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
237
373
 
@@ -243,7 +379,8 @@ module Solargraph
243
379
  end
244
380
  type.type.optional_positionals.each do |param|
245
381
  name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
246
- parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin)
382
+ parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
383
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
247
384
  end
248
385
  if type.type.rest_positionals
249
386
  name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg#{arg_num += 1}"
@@ -253,13 +390,15 @@ module Solargraph
253
390
  name = param.name ? param.name.to_s : "arg#{arg_num += 1}"
254
391
  parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin)
255
392
  end
256
- type.type.required_keywords.each do |orig, _param|
393
+ type.type.required_keywords.each do |orig, param|
257
394
  name = orig ? orig.to_s : "arg#{arg_num += 1}"
258
- parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin)
395
+ parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
396
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
259
397
  end
260
- type.type.optional_keywords.each do |orig, _param|
398
+ type.type.optional_keywords.each do |orig, param|
261
399
  name = orig ? orig.to_s : "arg#{arg_num += 1}"
262
- parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin)
400
+ parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
401
+ return_type: ComplexType.try_parse(other_type_to_tag(param.type)))
263
402
  end
264
403
  if type.type.rest_keywords
265
404
  name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg#{arg_num += 1}"
@@ -269,6 +408,9 @@ module Solargraph
269
408
  [parameters, return_type]
270
409
  end
271
410
 
411
+ # @param decl [RBS::AST::Members::AttrReader,RBS::AST::Members::AttrAccessor]
412
+ # @param closure [Pin::Namespace]
413
+ # @return [void]
272
414
  def attr_reader_to_pin(decl, closure)
273
415
  pin = Solargraph::Pin::Method.new(
274
416
  name: decl.name.to_s,
@@ -281,6 +423,9 @@ module Solargraph
281
423
  pins.push pin
282
424
  end
283
425
 
426
+ # @param decl [RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor]
427
+ # @param closure [Pin::Namespace]
428
+ # @return [void]
284
429
  def attr_writer_to_pin(decl, closure)
285
430
  pin = Solargraph::Pin::Method.new(
286
431
  name: "#{decl.name.to_s}=",
@@ -293,11 +438,17 @@ module Solargraph
293
438
  pins.push pin
294
439
  end
295
440
 
441
+ # @param decl [RBS::AST::Members::AttrAccessor]
442
+ # @param closure [Pin::Namespace]
443
+ # @return [void]
296
444
  def attr_accessor_to_pin(decl, closure)
297
445
  attr_reader_to_pin(decl, closure)
298
446
  attr_writer_to_pin(decl, closure)
299
447
  end
300
448
 
449
+ # @param decl [RBS::AST::Members::InstanceVariable]
450
+ # @param closure [Pin::Namespace]
451
+ # @return [void]
301
452
  def ivar_to_pin(decl, closure)
302
453
  pin = Solargraph::Pin::InstanceVariable.new(
303
454
  name: decl.name.to_s,
@@ -308,13 +459,50 @@ module Solargraph
308
459
  pins.push pin
309
460
  end
310
461
 
462
+ # @param decl [RBS::AST::Members::ClassVariable]
463
+ # @param closure [Pin::Namespace]
464
+ # @return [void]
465
+ def cvar_to_pin(decl, closure)
466
+ name = decl.name.to_s
467
+ pin = Solargraph::Pin::ClassVariable.new(
468
+ name: name,
469
+ closure: closure,
470
+ comments: decl.comment&.string
471
+ )
472
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
473
+ pins.push pin
474
+ end
475
+
476
+ # @param decl [RBS::AST::Members::ClassInstanceVariable]
477
+ # @param closure [Pin::Namespace]
478
+ # @return [void]
479
+ def civar_to_pin(decl, closure)
480
+ name = decl.name.to_s
481
+ pin = Solargraph::Pin::InstanceVariable.new(
482
+ name: name,
483
+ closure: closure,
484
+ comments: decl.comment&.string
485
+ )
486
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', other_type_to_tag(decl.type)))
487
+ pins.push pin
488
+ end
489
+
490
+ # @param decl [RBS::AST::Members::Include]
491
+ # @param closure [Pin::Namespace]
492
+ # @return [void]
311
493
  def include_to_pin decl, closure
494
+ type = generic_type(decl.name, decl.args)
495
+ generic_values = type.all_params.map(&:to_s)
312
496
  pins.push Solargraph::Pin::Reference::Include.new(
313
497
  name: decl.name.relative!.to_s,
498
+ generic_values: generic_values,
314
499
  closure: closure
315
500
  )
316
501
  end
317
502
 
503
+ # @param decl [RBS::AST::Members::Prepend]
504
+ # @param closure [Pin::Namespace]
505
+ # @return [void]
318
506
  def prepend_to_pin decl, closure
319
507
  pins.push Solargraph::Pin::Reference::Prepend.new(
320
508
  name: decl.name.relative!.to_s,
@@ -322,6 +510,9 @@ module Solargraph
322
510
  )
323
511
  end
324
512
 
513
+ # @param decl [RBS::AST::Members::Extend]
514
+ # @param closure [Pin::Namespace]
515
+ # @return [void]
325
516
  def extend_to_pin decl, closure
326
517
  pins.push Solargraph::Pin::Reference::Extend.new(
327
518
  name: decl.name.relative!.to_s,
@@ -329,6 +520,9 @@ module Solargraph
329
520
  )
330
521
  end
331
522
 
523
+ # @param decl [RBS::AST::Members::Alias]
524
+ # @param closure [Pin::Namespace]
525
+ # @return [void]
332
526
  def alias_to_pin decl, closure
333
527
  pins.push Solargraph::Pin::MethodAlias.new(
334
528
  name: decl.new_name.to_s,
@@ -345,6 +539,8 @@ module Solargraph
345
539
  'NilClass' => 'nil'
346
540
  }
347
541
 
542
+ # @param type [RBS::MethodType]
543
+ # @return [String]
348
544
  def method_type_to_tag type
349
545
  if type_aliases.key?(type.type.return_type.to_s)
350
546
  other_type_to_tag(type_aliases[type.type.return_type.to_s].type)
@@ -353,6 +549,25 @@ module Solargraph
353
549
  end
354
550
  end
355
551
 
552
+ # @param type_name [RBS::TypeName]
553
+ # @param type_args [Enumerable<RBS::Types::Bases::Base>]
554
+ # @return [ComplexType]
555
+ def generic_type(type_name, type_args)
556
+ base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
557
+ params = type_args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' }
558
+ params_str = params.empty? ? '' : "<#{params.join(', ')}>"
559
+ type_string = "#{base}#{params_str}"
560
+ ComplexType.parse(type_string)
561
+ end
562
+
563
+ # @param type_name [RBS::TypeName]
564
+ # @param type_args [Enumerable<RBS::Types::Bases::Base>]
565
+ # @return [String]
566
+ def generic_type_tag(type_name, type_args)
567
+ generic_type(type_name, type_args).tag
568
+ end
569
+
570
+ # @param type [RBS::Types::Bases::Base]
356
571
  # @return [String]
357
572
  def other_type_to_tag type
358
573
  if type.is_a?(RBS::Types::Optional)
@@ -378,19 +593,46 @@ module Solargraph
378
593
  elsif type.is_a?(RBS::Types::Bases::Void)
379
594
  'void'
380
595
  elsif type.is_a?(RBS::Types::Variable)
381
- "param<#{type.name}>"
596
+ "#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
382
597
  elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty?
383
- base = RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
384
- params = type.args.map { |a| other_type_to_tag(a) }.reject { |t| t == 'undefined' }
385
- return base if params.empty?
386
- "#{base}<#{params.join(', ')}>"
598
+ generic_type_tag(type.name, type.args)
599
+ elsif type.is_a?(RBS::Types::Bases::Instance)
600
+ 'self'
601
+ elsif type.is_a?(RBS::Types::Bases::Top)
602
+ # top is the most super superclass
603
+ 'BasicObject'
604
+ elsif type.is_a?(RBS::Types::Bases::Bottom)
605
+ # bottom is used in contexts where nothing will ever return
606
+ # - e.g., it could be the return type of 'exit()' or 'raise'
607
+ #
608
+ # @todo define a specific bottom type and use it to
609
+ # determine dead code
610
+ 'undefined'
611
+ elsif type.is_a?(RBS::Types::Intersection)
612
+ type.types.map { |member| other_type_to_tag(member) }.join(', ')
613
+ elsif type.is_a?(RBS::Types::Proc)
614
+ 'Proc'
387
615
  elsif type.respond_to?(:name) && type.name.respond_to?(:relative!)
388
616
  RBS_TO_YARD_TYPE[type.name.relative!.to_s] || type.name.relative!.to_s
389
617
  else
390
- Solargraph.logger.warn "Unrecognized RBS type: #{type.class} #{type}"
618
+ Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
391
619
  'undefined'
392
620
  end
393
621
  end
622
+
623
+ # @param decl [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
624
+ # @param closure [Pin::Closure]
625
+ # @return [void]
626
+ def add_mixins decl, closure
627
+ decl.each_mixin do |mixin|
628
+ klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
629
+ pins.push klass.new(
630
+ name: mixin.name.relative!.to_s,
631
+ location: rbs_location_to_location(mixin.location),
632
+ closure: closure
633
+ )
634
+ end
635
+ end
394
636
  end
395
637
  end
396
638
  end
@@ -16,39 +16,17 @@ module Solargraph
16
16
  ].map { |k| Pin::Keyword.new(k) }
17
17
 
18
18
  MISSING = [
19
- Solargraph::Pin::Method.new(name: 'tap', scope: :instance, closure: Solargraph::Pin::Namespace.new(name: 'Object')),
20
- Solargraph::Pin::Method.new(name: 'class', scope: :instance, closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [Class<self>]')
19
+ Solargraph::Pin::Method.new(name: 'tap', scope: :instance,
20
+ closure: Solargraph::Pin::Namespace.new(name: 'Object')),
21
+ Solargraph::Pin::Method.new(name: 'class', scope: :instance,
22
+ closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [Class<self>]')
21
23
  ]
22
24
 
23
- YIELDPARAMS = [
24
- Override.from_comment('Object#tap', %(
25
- @return [self]
26
- @yieldparam [self]
27
- )),
28
- Override.from_comment('String#each_line', %(
29
- @yieldparam [String]
30
- )),
31
- ]
32
-
33
- methods_with_yieldparam_subtypes = %w[
34
- Array#each Array#map Array#map! Array#any? Array#all? Array#index
35
- Array#keep_if Array#delete_if
36
- Enumerable#each_entry Enumerable#map Enumerable#any? Enumerable#all?
37
- Enumerable#select Enumerable#reject
38
- Set#each
39
- ]
40
-
41
- YIELDPARAM_SINGLE_PARAMETERS = methods_with_yieldparam_subtypes.map do |path|
42
- Override.from_comment(path, %(
43
- @yieldparam_single_parameter
44
- ))
45
- end
46
-
47
25
  CLASS_RETURN_TYPES = [
48
26
  Override.method_return('Class#new', 'self'),
49
27
  Override.method_return('Class.new', 'Class<BasicObject>'),
50
28
  Override.method_return('Class#allocate', 'self'),
51
- Override.method_return('Class.allocate', 'Class<BasicObject>'),
29
+ Override.method_return('Class.allocate', 'Class<BasicObject>')
52
30
  ]
53
31
 
54
32
  # HACK: Add Errno exception classes
@@ -60,8 +38,7 @@ module Solargraph
60
38
  end
61
39
  ERRNOS = errnos
62
40
 
63
- ALL = KEYWORDS + MISSING + YIELDPARAMS + YIELDPARAM_SINGLE_PARAMETERS + CLASS_RETURN_TYPES + ERRNOS
41
+ ALL = KEYWORDS + MISSING + CLASS_RETURN_TYPES + ERRNOS
64
42
  end
65
43
  end
66
44
  end
67
-
@@ -14,7 +14,7 @@ module Solargraph
14
14
  else
15
15
  loader = RBS::EnvironmentLoader.new(repository: RBS::Repository.new(no_stdlib: false))
16
16
  environment = RBS::Environment.from_loader(loader).resolve_type_names
17
- environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
17
+ load_environment_to_pins(loader)
18
18
  pins.concat RbsMap::CoreFills::ALL
19
19
  processed = ApiMap::Store.new(pins).pins.reject { |p| p.is_a?(Solargraph::Pin::Reference::Override) }
20
20
  pins.replace processed
@@ -28,6 +28,7 @@ module Solargraph
28
28
  return super unless stubs
29
29
  stubs.map do |stub|
30
30
  Pin::Signature.new(
31
+ [],
31
32
  [],
32
33
  ComplexType.try_parse(stub.return_type)
33
34
  )
@@ -8,6 +8,8 @@ module Solargraph
8
8
 
9
9
  attr_reader :return_type
10
10
 
11
+ # @param parameters [Array<Hash>]
12
+ # @param return_type [String]
11
13
  def initialize parameters, return_type
12
14
  @parameters = parameters
13
15
  @return_type = return_type
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rbs'
4
- require 'set'
5
4
 
6
5
  module Solargraph
7
6
  class RbsMap
@@ -16,11 +15,10 @@ module Solargraph
16
15
  cache = Cache.load('stdlib', "#{library}.ser")
17
16
  if cache
18
17
  pins.replace cache
18
+ @resolved = true
19
19
  else
20
20
  super
21
- if library == 'yaml'
22
- pins.push Solargraph::Pin::Constant.new(name: 'YAML', comments: '@return [Module<Psych>]', closure: Pin::ROOT_PIN)
23
- end
21
+ return unless resolved?
24
22
  Cache.save('stdlib', "#{library}.ser", pins)
25
23
  end
26
24
  end
@@ -30,10 +28,6 @@ module Solargraph
30
28
  def self.load library
31
29
  @stdlib_maps_hash[library] ||= StdlibMap.new(library)
32
30
  end
33
-
34
- def repository
35
- @repository ||= RBS::Repository.new
36
- end
37
31
  end
38
32
  end
39
33
  end