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