solargraph 0.51.2 → 0.54.2

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