solargraph 0.47.2 → 0.53.3

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