solargraph 0.58.3 → 0.59.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 (206) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +6 -5
  4. data/.github/workflows/plugins.yml +46 -34
  5. data/.github/workflows/rspec.yml +15 -28
  6. data/.github/workflows/typecheck.yml +3 -2
  7. data/.rubocop.yml +38 -6
  8. data/.rubocop_todo.yml +53 -966
  9. data/CHANGELOG.md +12 -0
  10. data/Gemfile +3 -1
  11. data/README.md +3 -3
  12. data/Rakefile +26 -23
  13. data/bin/solargraph +2 -1
  14. data/lib/solargraph/api_map/cache.rb +3 -3
  15. data/lib/solargraph/api_map/constants.rb +12 -3
  16. data/lib/solargraph/api_map/index.rb +29 -18
  17. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  18. data/lib/solargraph/api_map/store.rb +39 -28
  19. data/lib/solargraph/api_map.rb +156 -72
  20. data/lib/solargraph/bench.rb +2 -3
  21. data/lib/solargraph/complex_type/conformance.rb +176 -0
  22. data/lib/solargraph/complex_type/type_methods.rb +30 -18
  23. data/lib/solargraph/complex_type/unique_type.rb +216 -57
  24. data/lib/solargraph/complex_type.rb +171 -58
  25. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
  26. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  27. data/lib/solargraph/convention/data_definition.rb +5 -2
  28. data/lib/solargraph/convention/gemfile.rb +1 -1
  29. data/lib/solargraph/convention/gemspec.rb +1 -1
  30. data/lib/solargraph/convention/rakefile.rb +1 -1
  31. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  32. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  33. data/lib/solargraph/convention/struct_definition.rb +8 -4
  34. data/lib/solargraph/convention.rb +2 -2
  35. data/lib/solargraph/converters/dd.rb +2 -0
  36. data/lib/solargraph/converters/dl.rb +2 -0
  37. data/lib/solargraph/converters/dt.rb +2 -0
  38. data/lib/solargraph/converters/misc.rb +2 -0
  39. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  40. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  41. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  42. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  43. data/lib/solargraph/diagnostics/update_errors.rb +4 -8
  44. data/lib/solargraph/doc_map.rb +38 -39
  45. data/lib/solargraph/equality.rb +4 -4
  46. data/lib/solargraph/gem_pins.rb +6 -6
  47. data/lib/solargraph/language_server/error_codes.rb +10 -10
  48. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  49. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  50. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  51. data/lib/solargraph/language_server/host/sources.rb +2 -1
  52. data/lib/solargraph/language_server/host.rb +30 -22
  53. data/lib/solargraph/language_server/message/base.rb +1 -1
  54. data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
  55. data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
  56. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  57. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  58. data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
  59. data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
  60. data/lib/solargraph/language_server/message/extended/search.rb +1 -1
  61. data/lib/solargraph/language_server/message/initialize.rb +20 -14
  62. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  63. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  64. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
  65. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  66. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  67. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  68. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
  69. data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
  70. data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
  71. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  72. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  73. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
  74. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
  75. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
  76. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  77. data/lib/solargraph/language_server/message.rb +1 -1
  78. data/lib/solargraph/language_server/request.rb +4 -2
  79. data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
  80. data/lib/solargraph/language_server/uri_helpers.rb +2 -2
  81. data/lib/solargraph/library.rb +57 -38
  82. data/lib/solargraph/location.rb +17 -14
  83. data/lib/solargraph/logging.rb +22 -4
  84. data/lib/solargraph/page.rb +1 -1
  85. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  86. data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
  87. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  88. data/lib/solargraph/parser/node_processor.rb +8 -7
  89. data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
  90. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
  91. data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
  92. data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
  93. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  94. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  95. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  96. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
  97. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  98. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
  99. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  100. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  101. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  102. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  103. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  104. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  105. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  107. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  108. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  109. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
  110. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  111. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  112. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  113. data/lib/solargraph/parser/parser_gem.rb +2 -0
  114. data/lib/solargraph/parser/region.rb +9 -3
  115. data/lib/solargraph/parser/snippet.rb +3 -1
  116. data/lib/solargraph/parser.rb +2 -0
  117. data/lib/solargraph/pin/base.rb +124 -80
  118. data/lib/solargraph/pin/base_variable.rb +273 -24
  119. data/lib/solargraph/pin/block.rb +29 -6
  120. data/lib/solargraph/pin/breakable.rb +7 -1
  121. data/lib/solargraph/pin/callable.rb +65 -21
  122. data/lib/solargraph/pin/closure.rb +7 -10
  123. data/lib/solargraph/pin/common.rb +24 -6
  124. data/lib/solargraph/pin/compound_statement.rb +55 -0
  125. data/lib/solargraph/pin/constant.rb +3 -5
  126. data/lib/solargraph/pin/conversions.rb +10 -4
  127. data/lib/solargraph/pin/delegated_method.rb +19 -8
  128. data/lib/solargraph/pin/documenting.rb +4 -2
  129. data/lib/solargraph/pin/instance_variable.rb +5 -1
  130. data/lib/solargraph/pin/keyword.rb +0 -4
  131. data/lib/solargraph/pin/local_variable.rb +15 -59
  132. data/lib/solargraph/pin/method.rb +156 -104
  133. data/lib/solargraph/pin/method_alias.rb +8 -0
  134. data/lib/solargraph/pin/namespace.rb +19 -12
  135. data/lib/solargraph/pin/parameter.rb +100 -36
  136. data/lib/solargraph/pin/proxy_type.rb +4 -1
  137. data/lib/solargraph/pin/reference/override.rb +1 -1
  138. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  139. data/lib/solargraph/pin/reference/type_alias.rb +16 -0
  140. data/lib/solargraph/pin/reference.rb +20 -0
  141. data/lib/solargraph/pin/search.rb +3 -2
  142. data/lib/solargraph/pin/signature.rb +15 -12
  143. data/lib/solargraph/pin/symbol.rb +2 -1
  144. data/lib/solargraph/pin/until.rb +2 -4
  145. data/lib/solargraph/pin/while.rb +2 -4
  146. data/lib/solargraph/pin.rb +2 -0
  147. data/lib/solargraph/pin_cache.rb +22 -19
  148. data/lib/solargraph/position.rb +17 -10
  149. data/lib/solargraph/range.rb +16 -15
  150. data/lib/solargraph/rbs_map/conversions.rb +358 -229
  151. data/lib/solargraph/rbs_map/core_fills.rb +18 -11
  152. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  153. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  154. data/lib/solargraph/rbs_map.rb +76 -32
  155. data/lib/solargraph/server_methods.rb +1 -1
  156. data/lib/solargraph/shell.rb +258 -66
  157. data/lib/solargraph/source/chain/array.rb +4 -2
  158. data/lib/solargraph/source/chain/call.rb +96 -56
  159. data/lib/solargraph/source/chain/class_variable.rb +1 -1
  160. data/lib/solargraph/source/chain/constant.rb +5 -1
  161. data/lib/solargraph/source/chain/global_variable.rb +1 -1
  162. data/lib/solargraph/source/chain/hash.rb +8 -5
  163. data/lib/solargraph/source/chain/if.rb +12 -10
  164. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  165. data/lib/solargraph/source/chain/link.rb +12 -22
  166. data/lib/solargraph/source/chain/literal.rb +9 -6
  167. data/lib/solargraph/source/chain/or.rb +10 -4
  168. data/lib/solargraph/source/chain/q_call.rb +2 -0
  169. data/lib/solargraph/source/chain/variable.rb +3 -1
  170. data/lib/solargraph/source/chain/z_super.rb +1 -3
  171. data/lib/solargraph/source/chain.rb +51 -38
  172. data/lib/solargraph/source/change.rb +12 -5
  173. data/lib/solargraph/source/cursor.rb +23 -17
  174. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  175. data/lib/solargraph/source/source_chainer.rb +56 -32
  176. data/lib/solargraph/source/updater.rb +5 -1
  177. data/lib/solargraph/source.rb +59 -35
  178. data/lib/solargraph/source_map/clip.rb +48 -29
  179. data/lib/solargraph/source_map/data.rb +4 -1
  180. data/lib/solargraph/source_map/mapper.rb +69 -42
  181. data/lib/solargraph/source_map.rb +21 -9
  182. data/lib/solargraph/type_checker/problem.rb +3 -1
  183. data/lib/solargraph/type_checker/rules.rb +81 -8
  184. data/lib/solargraph/type_checker.rb +195 -121
  185. data/lib/solargraph/version.rb +1 -1
  186. data/lib/solargraph/workspace/config.rb +14 -11
  187. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  188. data/lib/solargraph/workspace/require_paths.rb +1 -0
  189. data/lib/solargraph/workspace.rb +50 -28
  190. data/lib/solargraph/yard_map/helpers.rb +8 -3
  191. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  192. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  193. data/lib/solargraph/yard_map/mapper.rb +13 -8
  194. data/lib/solargraph/yard_map.rb +17 -18
  195. data/lib/solargraph/yard_tags.rb +2 -2
  196. data/lib/solargraph/yardoc.rb +7 -4
  197. data/lib/solargraph.rb +31 -8
  198. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  199. data/rbs/fills/tuple/tuple.rbs +28 -0
  200. data/rbs/shims/ast/0/node.rbs +1 -1
  201. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  202. data/solargraph.gemspec +37 -35
  203. metadata +41 -41
  204. data/lib/solargraph/type_checker/checks.rb +0 -124
  205. data/lib/solargraph/type_checker/param_def.rb +0 -37
  206. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -23,7 +23,7 @@ module Solargraph
23
23
  end
24
24
 
25
25
  # @param loader [RBS::EnvironmentLoader]
26
- def initialize(loader:)
26
+ def initialize loader:
27
27
  @loader = loader
28
28
  @pins = []
29
29
  load_environment_to_pins(loader)
@@ -37,18 +37,15 @@ module Solargraph
37
37
 
38
38
  private
39
39
 
40
- # @return [Hash{String => RBS::AST::Declarations::TypeAlias}]
41
- def type_aliases
42
- @type_aliases ||= {}
43
- end
44
-
45
40
  # @param loader [RBS::EnvironmentLoader]
41
+ #
46
42
  # @return [void]
47
- def load_environment_to_pins(loader)
43
+ def load_environment_to_pins loader
48
44
  environment = RBS::Environment.from_loader(loader).resolve_type_names
49
- cursor = pins.length
50
45
  if environment.declarations.empty?
51
- Solargraph.logger.info "No RBS declarations found in environment for core_root #{loader.core_root.inspect}, libraries #{loader.libs} and directories #{loader.dirs}"
46
+ Solargraph.logger.info 'No RBS declarations found in environment for core_root ' \
47
+ "#{loader.core_root.inspect}, libraries #{loader.libs} and " \
48
+ "directories #{loader.dirs}"
52
49
  return
53
50
  end
54
51
  environment.declarations.each { |decl| convert_decl_to_pin(decl, Solargraph::Pin::ROOT_PIN) }
@@ -60,22 +57,62 @@ module Solargraph
60
57
  def convert_decl_to_pin decl, closure
61
58
  case decl
62
59
  when RBS::AST::Declarations::Class
60
+ # @sg-ignore flow sensitive typing should support case/when
61
+ unless closure.name == '' || decl.name.absolute?
62
+ Solargraph.assert_or_log(:rbs_closure, "Ignoring closure #{closure.inspect} on class #{decl.inspect}")
63
+ end
63
64
  class_decl_to_pin decl
64
65
  when RBS::AST::Declarations::Interface
66
+ # @sg-ignore flow sensitive typing should support case/when
67
+ unless closure.name == '' || decl.name.absolute?
68
+ Solargraph.assert_or_log(:rbs_closure, "Ignoring closure #{closure.inspect} on interface #{decl.inspect}")
69
+ end
65
70
  # STDERR.puts "Skipping interface #{decl.name.relative!}"
66
- interface_decl_to_pin decl, closure
71
+ interface_decl_to_pin decl
67
72
  when RBS::AST::Declarations::TypeAlias
68
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
69
- type_aliases[decl.name.to_s] = decl
73
+ # @sg-ignore flow sensitive typing should support case/when
74
+ unless closure.name == '' || decl.name.absolute?
75
+ Solargraph.assert_or_log(:rbs_closure,
76
+ # @sg-ignore flow sensitive typing should support case/when
77
+ "Ignoring closure #{closure.inspect} on alias type name #{decl.name}")
78
+ end
79
+ pins.push(
80
+ # @sg-ignore Wrong argument type for Solargraph::Pin::Reference::TypeAlias.new: return_type expected Solargraph::ComplexType, received Solargraph::ComplexType::UniqueType, Solargraph::ComplexType
81
+ Solargraph::Pin::Reference::TypeAlias.new(
82
+ # @sg-ignore Unresolved calls to name, type, type_location; return_type type mismatch
83
+ name: ComplexType.try_parse(decl.name.to_s).to_s, return_type: other_type_to_type(decl.type).force_rooted, closure: closure, source: :rbs, type_location: location_decl_to_pin_location(decl.location)
84
+ )
85
+ )
70
86
  when RBS::AST::Declarations::Module
87
+ # @sg-ignore flow sensitive typing should support case/when
88
+ unless closure.name == '' || decl.name.absolute?
89
+ Solargraph.assert_or_log(:rbs_closure,
90
+ # @sg-ignore flow sensitive typing should support case/when
91
+ "Ignoring closure #{closure.inspect} on alias type name #{decl.name}")
92
+ end
71
93
  module_decl_to_pin decl
72
94
  when RBS::AST::Declarations::Constant
95
+ # @sg-ignore flow sensitive typing should support case/when
96
+ unless closure.name == '' || decl.name.absolute?
97
+ Solargraph.assert_or_log(:rbs_closure, "Ignoring closure #{closure.inspect} on constant #{decl.inspect}")
98
+ end
73
99
  constant_decl_to_pin decl
74
100
  when RBS::AST::Declarations::ClassAlias
101
+ # @sg-ignore flow sensitive typing should support case/when
102
+ unless closure.name == '' || decl.new_name.absolute?
103
+ Solargraph.assert_or_log(:rbs_closure, "Ignoring closure #{closure.inspect} on class alias #{decl.inspect}")
104
+ end
75
105
  class_alias_decl_to_pin decl
76
106
  when RBS::AST::Declarations::ModuleAlias
107
+ unless closure.name == ''
108
+ Solargraph.assert_or_log(:rbs_closure,
109
+ "Ignoring closure #{closure.inspect} on module alias #{decl.inspect}")
110
+ end
77
111
  module_alias_decl_to_pin decl
78
112
  when RBS::AST::Declarations::Global
113
+ unless closure.name == ''
114
+ Solargraph.assert_or_log(:rbs_closure, "Ignoring closure #{closure.inspect} on global decl #{decl.inspect}")
115
+ end
79
116
  global_decl_to_pin decl
80
117
  else
81
118
  Solargraph.logger.warn "Skipping declaration #{decl.class}"
@@ -86,7 +123,61 @@ module Solargraph
86
123
  # @param module_pin [Pin::Namespace]
87
124
  # @return [void]
88
125
  def convert_self_types_to_pins decl, module_pin
89
- decl.self_types.each { |self_type| context = convert_self_type_to_pins(self_type, module_pin) }
126
+ decl.self_types.each { |self_type| convert_self_type_to_pins(self_type, module_pin) }
127
+ end
128
+
129
+ # @type [Hash{String => String}]
130
+ RBS_TO_CLASS = {
131
+ 'bool' => 'Boolean',
132
+ 'string' => 'String',
133
+ 'int' => 'Integer'
134
+ }.freeze
135
+ private_constant :RBS_TO_CLASS
136
+
137
+ # rooted names (namespaces) use the prefix of :: when they are
138
+ # relative to the root namespace, or not if they are relative to
139
+ # the current namespace.
140
+ #
141
+ # @param type_name [RBS::TypeName]
142
+ #
143
+ # @return [String]
144
+ def rooted_name type_name
145
+ name = type_name.to_s
146
+ RBS_TO_CLASS.fetch(name, name)
147
+ end
148
+
149
+ # fqns names are implicitly fully qualified - they are relative
150
+ # to the root namespace and are not prefixed with ::
151
+ #
152
+ # @param type_name [RBS::TypeName]
153
+ #
154
+ # @return [String]
155
+ def fqns type_name
156
+ unless type_name.absolute?
157
+ Solargraph.assert_or_log(:rbs_fqns, "Received unexpected unqualified type name: #{type_name}")
158
+ end
159
+ ns = type_name.relative!.to_s
160
+ RBS_TO_CLASS.fetch(ns, ns)
161
+ end
162
+
163
+ # @param type_name [RBS::TypeName]
164
+ # @param type_args [Enumerable<RBS::Types::Bases::Base>]
165
+ # @return [ComplexType::UniqueType]
166
+ def build_type type_name, type_args = []
167
+ # we use .absolute? below to tell the type object what to
168
+ # expect
169
+ rbs_name = type_name.relative!.to_s
170
+ base = RBS_TO_CLASS.fetch(rbs_name, rbs_name)
171
+
172
+ params = type_args.map { |a| other_type_to_type(a) }
173
+ # tuples have their own class and are handled in other_type_to_type
174
+ if base == 'Hash' && params.length == 2
175
+ ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: type_name.absolute?,
176
+ parameters_type: :hash)
177
+ else
178
+ ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: type_name.absolute?,
179
+ parameters_type: :list)
180
+ end
90
181
  end
91
182
 
92
183
  # @param decl [RBS::AST::Declarations::Module::Self]
@@ -94,9 +185,9 @@ module Solargraph
94
185
  # @return [void]
95
186
  def convert_self_type_to_pins decl, closure
96
187
  type = build_type(decl.name, decl.args)
97
- generic_values = type.all_params.map(&:to_s)
188
+ generic_values = type.all_params.map(&:rooted_tags)
98
189
  include_pin = Solargraph::Pin::Reference::Include.new(
99
- name: decl.name.relative!.to_s,
190
+ name: type.name,
100
191
  type_location: location_decl_to_pin_location(decl.location),
101
192
  generic_values: generic_values,
102
193
  closure: closure,
@@ -120,32 +211,44 @@ module Solargraph
120
211
  def convert_member_to_pin member, closure, context
121
212
  case member
122
213
  when RBS::AST::Members::MethodDefinition
214
+ # @sg-ignore flow based typing needs to understand case when class pattern
123
215
  method_def_to_pin(member, closure, context)
124
216
  when RBS::AST::Members::AttrReader
217
+ # @sg-ignore flow based typing needs to understand case when class pattern
125
218
  attr_reader_to_pin(member, closure, context)
126
219
  when RBS::AST::Members::AttrWriter
220
+ # @sg-ignore flow based typing needs to understand case when class pattern
127
221
  attr_writer_to_pin(member, closure, context)
128
222
  when RBS::AST::Members::AttrAccessor
223
+ # @sg-ignore flow based typing needs to understand case when class pattern
129
224
  attr_accessor_to_pin(member, closure, context)
130
225
  when RBS::AST::Members::Include
226
+ # @sg-ignore flow based typing needs to understand case when class pattern
131
227
  include_to_pin(member, closure)
132
228
  when RBS::AST::Members::Prepend
229
+ # @sg-ignore flow based typing needs to understand case when class pattern
133
230
  prepend_to_pin(member, closure)
134
231
  when RBS::AST::Members::Extend
232
+ # @sg-ignore flow based typing needs to understand case when class pattern
135
233
  extend_to_pin(member, closure)
136
234
  when RBS::AST::Members::Alias
235
+ # @sg-ignore flow based typing needs to understand case when class pattern
137
236
  alias_to_pin(member, closure)
138
237
  when RBS::AST::Members::ClassInstanceVariable
238
+ # @sg-ignore flow based typing needs to understand case when class pattern
139
239
  civar_to_pin(member, closure)
140
240
  when RBS::AST::Members::ClassVariable
241
+ # @sg-ignore flow based typing needs to understand case when class pattern
141
242
  cvar_to_pin(member, closure)
142
243
  when RBS::AST::Members::InstanceVariable
244
+ # @sg-ignore flow based typing needs to understand case when class pattern
143
245
  ivar_to_pin(member, closure)
144
246
  when RBS::AST::Members::Public
145
247
  return Context.new(:public)
146
248
  when RBS::AST::Members::Private
147
249
  return Context.new(:private)
148
250
  when RBS::AST::Declarations::Base
251
+ # @sg-ignore flow based typing needs to understand case when class pattern
149
252
  convert_decl_to_pin(member, closure)
150
253
  else
151
254
  Solargraph.logger.warn "Skipping member type #{member.class}"
@@ -153,18 +256,31 @@ module Solargraph
153
256
  context
154
257
  end
155
258
 
259
+ # Pull the name of type variables for a generic - not the
260
+ # values, the names (e.g., T, U, V). As such, "rooting" isn't a
261
+ # thing, these are all in the global namespace.
262
+ #
263
+ # @param decl [RBS::AST::Declarations::Class, RBS::AST::Declarations::Interface,
264
+ # RBS::AST::Declarations::Module, RBS::MethodType]
265
+ #
266
+ # @return [Array<String>]
267
+ def type_parameter_names decl
268
+ decl.type_params.map(&:name).map(&:to_s)
269
+ end
270
+
156
271
  # @param decl [RBS::AST::Declarations::Class]
157
272
  # @return [void]
158
273
  def class_decl_to_pin decl
159
- generics = decl.type_params.map(&:name).map(&:to_s)
274
+ # @type [Hash{String => ComplexType, ComplexType::UniqueType}]
160
275
  generic_defaults = {}
161
276
  decl.type_params.each do |param|
162
- if param.default_type
163
- tag = other_type_to_tag param.default_type
164
- generic_defaults[param.name.to_s] = ComplexType.parse(tag).force_rooted
165
- end
277
+ generic_defaults[param.name.to_s] = other_type_to_type param.default_type if param.default_type
166
278
  end
167
- class_name = decl.name.relative!.to_s
279
+
280
+ class_name = fqns(decl.name)
281
+
282
+ generics = type_parameter_names(decl)
283
+
168
284
  class_pin = Solargraph::Pin::Namespace.new(
169
285
  type: :class,
170
286
  name: class_name,
@@ -181,13 +297,12 @@ module Solargraph
181
297
  pins.push class_pin
182
298
  if decl.super_class
183
299
  type = build_type(decl.super_class.name, decl.super_class.args)
184
- generic_values = type.all_params.map(&:to_s)
185
- superclass_name = decl.super_class.name.to_s
300
+ generic_values = type.all_params.map(&:rooted_tags)
186
301
  pins.push Solargraph::Pin::Reference::Superclass.new(
187
302
  type_location: location_decl_to_pin_location(decl.super_class.location),
188
303
  closure: class_pin,
189
304
  generic_values: generic_values,
190
- name: superclass_name,
305
+ name: type.rooted_name, # reference pins use rooted names
191
306
  source: :rbs
192
307
  )
193
308
  end
@@ -196,16 +311,15 @@ module Solargraph
196
311
  end
197
312
 
198
313
  # @param decl [RBS::AST::Declarations::Interface]
199
- # @param closure [Pin::Closure]
200
314
  # @return [void]
201
- def interface_decl_to_pin decl, closure
315
+ def interface_decl_to_pin decl
202
316
  class_pin = Solargraph::Pin::Namespace.new(
203
317
  type: :module,
204
318
  type_location: location_decl_to_pin_location(decl.location),
205
- name: decl.name.relative!.to_s,
319
+ name: fqns(decl.name),
206
320
  closure: Solargraph::Pin::ROOT_PIN,
207
321
  comments: decl.comment&.string,
208
- generics: decl.type_params.map(&:name).map(&:to_s),
322
+ generics: type_parameter_names(decl),
209
323
  # HACK: Using :hidden to keep interfaces from appearing in
210
324
  # autocompletion
211
325
  visibility: :hidden,
@@ -221,45 +335,51 @@ module Solargraph
221
335
  def module_decl_to_pin decl
222
336
  module_pin = Solargraph::Pin::Namespace.new(
223
337
  type: :module,
224
- name: decl.name.relative!.to_s,
338
+ name: fqns(decl.name),
225
339
  type_location: location_decl_to_pin_location(decl.location),
226
340
  closure: Solargraph::Pin::ROOT_PIN,
227
341
  comments: decl.comment&.string,
228
- generics: decl.type_params.map(&:name).map(&:to_s),
342
+ generics: type_parameter_names(decl),
229
343
  source: :rbs
230
344
  )
231
345
  pins.push module_pin
232
346
  convert_self_types_to_pins decl, module_pin
233
347
  convert_members_to_pins decl, module_pin
234
348
 
349
+ raise "Invalid type for module declaration: #{module_pin.class}" unless module_pin.is_a?(Pin::Namespace)
350
+
235
351
  add_mixins decl, module_pin.closure
236
352
  end
237
353
 
238
- # @param name [String]
239
- # @param tag [String]
240
- # @param comments [String]
241
- # @param decl [RBS::AST::Declarations::ClassAlias, RBS::AST::Declarations::Constant, RBS::AST::Declarations::ModuleAlias]
242
- # @param base [String, nil] Optional conversion of tag to base<tag>
354
+ # @param fqns [String]
355
+ # @param type [ComplexType, ComplexType::UniqueType]
356
+ # @param comments [String, nil]
357
+ # @param decl [RBS::AST::Declarations::ClassAlias,
358
+ # RBS::AST::Declarations::Constant,
359
+ # RBS::AST::Declarations::ModuleAlias]
360
+ # @param base [String, nil] Optional conversion of tag to
361
+ # base<tag> - valid values are Class and Module
243
362
  #
244
363
  # @return [Solargraph::Pin::Constant]
245
- def create_constant(name, tag, comments, decl, base = nil)
246
- parts = name.split('::')
364
+ def create_constant fqns, type, comments, decl, base = nil
365
+ parts = fqns.split('::')
247
366
  if parts.length > 1
248
- name = parts.last
367
+ fqns = parts.last
368
+ # @sg-ignore Need to add nil check here
249
369
  closure = pins.select { |pin| pin && pin.path == parts[0..-2].join('::') }.first
250
370
  else
251
- name = parts.first
371
+ fqns = parts.first
252
372
  closure = Solargraph::Pin::ROOT_PIN
253
373
  end
254
374
  constant_pin = Solargraph::Pin::Constant.new(
255
- name: name,
375
+ name: fqns,
256
376
  closure: closure,
257
377
  type_location: location_decl_to_pin_location(decl.location),
258
378
  comments: comments,
259
379
  source: :rbs
260
380
  )
261
- tag = "#{base}<#{tag}>" if base
262
- rooted_tag = ComplexType.parse(tag).force_rooted.rooted_tags
381
+ rooted_tag = type.rooted_tags
382
+ rooted_tag = "#{base}<#{rooted_tag}>" if base
263
383
  constant_pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
264
384
  constant_pin
265
385
  end
@@ -268,27 +388,27 @@ module Solargraph
268
388
  # @return [void]
269
389
  def class_alias_decl_to_pin decl
270
390
  # See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ClassAlias
271
- new_name = decl.new_name.relative!.to_s
272
- old_name = decl.old_name.relative!.to_s
273
-
274
- pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Class')
391
+ new_name = fqns(decl.new_name)
392
+ old_type = build_type(decl.old_name)
393
+ pins.push create_constant(new_name, old_type, decl.comment&.string, decl, '::Class')
275
394
  end
276
395
 
277
396
  # @param decl [RBS::AST::Declarations::ModuleAlias]
278
397
  # @return [void]
279
398
  def module_alias_decl_to_pin decl
280
399
  # See https://www.rubydoc.info/gems/rbs/3.4.3/RBS/AST/Declarations/ModuleAlias
281
- new_name = decl.new_name.relative!.to_s
282
- old_name = decl.old_name.relative!.to_s
400
+ new_name = fqns(decl.new_name)
401
+ old_type = build_type(decl.old_name)
283
402
 
284
- pins.push create_constant(new_name, old_name, decl.comment&.string, decl, 'Module')
403
+ pins.push create_constant(new_name, old_type, decl.comment&.string, decl, '::Module')
285
404
  end
286
405
 
287
406
  # @param decl [RBS::AST::Declarations::Constant]
288
407
  # @return [void]
289
408
  def constant_decl_to_pin decl
290
- tag = other_type_to_tag(decl.type)
291
- pins.push create_constant(decl.name.relative!.to_s, tag, decl.comment&.string, decl)
409
+ target_type = other_type_to_type(decl.type)
410
+ constant_name = fqns(decl.name)
411
+ pins.push create_constant(constant_name, target_type, decl.comment&.string, decl)
292
412
  end
293
413
 
294
414
  # @param decl [RBS::AST::Declarations::Global]
@@ -303,12 +423,11 @@ module Solargraph
303
423
  type_location: location_decl_to_pin_location(decl.location),
304
424
  source: :rbs
305
425
  )
306
- rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
426
+ rooted_tag = other_type_to_type(decl.type).rooted_tags
307
427
  pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
308
428
  pins.push pin
309
429
  end
310
430
 
311
-
312
431
  # Visibility overrides that will allow the Solargraph project
313
432
  # and plugins to pass typechecking using SOLARGRAPH_ASSERTS=on,
314
433
  # so that we can detect any regressions/issues elsewhere in the
@@ -324,42 +443,47 @@ module Solargraph
324
443
  # allow that to be extended via .solargraph.yml
325
444
  # @type [Hash{Array(String, Symbol, String) => Symbol}
326
445
  VISIBILITY_OVERRIDE = {
327
- ["Rails::Engine", :instance, "run_tasks_blocks"] => :protected,
446
+ ['Rails::Engine', :instance, 'run_tasks_blocks'] => :protected,
328
447
  # Should have been marked as both instance and class method in module -e.g., 'module_function'
329
- ["Kernel", :instance, "pretty_inspect"] => :private,
448
+ ['Kernel', :instance, 'pretty_inspect'] => :private,
330
449
  # marked incorrectly in RBS
331
- ["WEBrick::HTTPUtils::FormData", :instance, "next_data"] => :protected,
332
- ["Rails::Command", :class, "command_type"] => :private,
333
- ["Rails::Command", :class, "lookup_paths"] => :private,
334
- ["Rails::Command", :class, "file_lookup_paths"] => :private,
335
- ["Rails::Railtie", :instance, "run_console_blocks"] => :protected,
336
- ["Rails::Railtie", :instance, "run_generators_blocks"] => :protected,
337
- ["Rails::Railtie", :instance, "run_runner_blocks"] => :protected,
338
- ["Rails::Railtie", :instance, "run_tasks_blocks"] => :protected,
339
- ["ActionController::Base", :instance, "_protected_ivars"] => :private,
340
- ["ActionView::Template", :instance, "method_name"] => :public,
341
- ["Module", :instance, "ruby2_keywords"] => :private,
342
- ["Nokogiri::XML::Node", :instance, "coerce"] => :protected,
343
- ["Nokogiri::XML::Document", :class, "empty_doc?"] => :private,
344
- ["Nokogiri::Decorators::Slop", :instance, "respond_to_missing?"] => :public,
345
- ["RuboCop::Cop::RangeHelp", :instance, "source_range"] => :private,
346
- ["AST::Node", :instance, "original_dup"] => :private,
347
- ["Rainbow::Presenter", :instance, "wrap_with_sgr"] => :private,
348
- }
349
-
350
- # @param decl [RBS::AST::Members::MethodDefinition, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrAccessor]
450
+ ['WEBrick::HTTPUtils::FormData', :instance, 'next_data'] => :protected,
451
+ ['Rails::Command', :class, 'command_type'] => :private,
452
+ ['Rails::Command', :class, 'lookup_paths'] => :private,
453
+ ['Rails::Command', :class, 'file_lookup_paths'] => :private,
454
+ ['Rails::Railtie', :instance, 'run_console_blocks'] => :protected,
455
+ ['Rails::Railtie', :instance, 'run_generators_blocks'] => :protected,
456
+ ['Rails::Railtie', :instance, 'run_runner_blocks'] => :protected,
457
+ ['Rails::Railtie', :instance, 'run_tasks_blocks'] => :protected,
458
+ ['ActionController::Base', :instance, '_protected_ivars'] => :private,
459
+ ['ActionView::Template', :instance, 'method_name'] => :public,
460
+ ['Module', :instance, 'ruby2_keywords'] => :private,
461
+ ['Nokogiri::XML::Node', :instance, 'coerce'] => :protected,
462
+ ['Nokogiri::XML::Document', :class, 'empty_doc?'] => :private,
463
+ ['Nokogiri::Decorators::Slop', :instance, 'respond_to_missing?'] => :public,
464
+ ['RuboCop::Cop::RangeHelp', :instance, 'source_range'] => :private,
465
+ ['AST::Node', :instance, 'original_dup'] => :private,
466
+ ['Rainbow::Presenter', :instance, 'wrap_with_sgr'] => :private
467
+ }.freeze
468
+ private_constant :VISIBILITY_OVERRIDE
469
+
470
+ # @param decl [RBS::AST::Members::MethodDefinition, RBS::AST::Members::AttrReader,
471
+ # RBS::AST::Members::AttrWriter, RBS::AST::Members::AttrAccessor]
351
472
  # @param closure [Pin::Closure]
352
473
  # @param context [Context]
353
474
  # @param scope [Symbol] :instance or :class
354
475
  # @param name [String] The name of the method
355
- # @sg-ignore
356
476
  # @return [Symbol]
357
- def calculate_method_visibility(decl, context, closure, scope, name)
477
+ # @sg-ignore Declared return type ::Symbol does not match inferred type
478
+ # ::Symbol, :public, :private, nil for Solargraph::RbsMap::Conversions#calculate_method_visibility
479
+ def calculate_method_visibility decl, context, closure, scope, name
358
480
  override_key = [closure.path, scope, name]
359
481
  visibility = VISIBILITY_OVERRIDE[override_key]
360
482
  simple_override_key = [closure.path, scope]
361
483
  visibility ||= VISIBILITY_OVERRIDE[simple_override_key]
362
- visibility ||= :private if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(decl.name)
484
+ if closure.path == 'Kernel' && Kernel.private_instance_methods(false).include?(decl.name)
485
+ visibility ||= :private
486
+ end
363
487
  if decl.kind == :singleton_instance
364
488
  # this is a 'module function'
365
489
  visibility ||= :private
@@ -379,7 +503,9 @@ module Solargraph
379
503
  # having different type params / orders - we may need to match
380
504
  # this data model and have generics live in signatures to
381
505
  # handle those correctly
382
- generics = decl.overloads.map(&:method_type).flat_map(&:type_params).map(&:name).map(&:to_s).uniq
506
+ generics = decl.overloads.map(&:method_type).map do |method_type|
507
+ type_parameter_names method_type
508
+ end
383
509
 
384
510
  if decl.instance?
385
511
  name = decl.name.to_s
@@ -403,24 +529,23 @@ module Solargraph
403
529
  pin.instance_variable_set(:@return_type, ComplexType::VOID)
404
530
  end
405
531
  end
406
- if decl.singleton?
407
- final_scope = :class
408
- name = decl.name.to_s
409
- visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
410
- pin = Solargraph::Pin::Method.new(
411
- name: name,
412
- closure: closure,
413
- comments: decl.comment&.string,
414
- type_location: location_decl_to_pin_location(decl.location),
415
- visibility: visibility,
416
- scope: final_scope,
417
- signatures: [],
418
- generics: generics,
419
- source: :rbs
420
- )
421
- pin.signatures.concat method_def_to_sigs(decl, pin)
422
- pins.push pin
423
- end
532
+ return unless decl.singleton?
533
+ final_scope = :class
534
+ name = decl.name.to_s
535
+ visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
536
+ pin = Solargraph::Pin::Method.new(
537
+ name: name,
538
+ closure: closure,
539
+ comments: decl.comment&.string,
540
+ type_location: location_decl_to_pin_location(decl.location),
541
+ visibility: visibility,
542
+ scope: final_scope,
543
+ signatures: [],
544
+ generics: generics,
545
+ source: :rbs
546
+ )
547
+ pin.signatures.concat method_def_to_sigs(decl, pin)
548
+ pins.push pin
424
549
  end
425
550
 
426
551
  # @param decl [RBS::AST::Members::MethodDefinition]
@@ -429,101 +554,112 @@ module Solargraph
429
554
  def method_def_to_sigs decl, pin
430
555
  # @param overload [RBS::AST::Members::MethodDefinition::Overload]
431
556
  decl.overloads.map do |overload|
557
+ # @sg-ignore Wrong argument type for Solargraph::RbsMap::Conversions#location_decl_to_pin_location:
558
+ # location expected RBS::Location, nil, received RBS::Location<:type, :type_params>, RBS::AST::Members::Attribute::loc, nil
432
559
  type_location = location_decl_to_pin_location(overload.method_type.location)
433
- generics = overload.method_type.type_params.map(&:name).map(&:to_s)
560
+ generics = type_parameter_names(overload.method_type)
434
561
  signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin)
435
- block = if overload.method_type.block
436
- block_parameters, block_return_type = parts_of_function(overload.method_type.block, pin)
437
- Pin::Signature.new(generics: generics, parameters: block_parameters, return_type: block_return_type, source: :rbs,
562
+ rbs_block = overload.method_type.block
563
+ block = if rbs_block
564
+ block_parameters, block_return_type = parts_of_function(rbs_block, pin)
565
+ Pin::Signature.new(generics: generics, parameters: block_parameters,
566
+ return_type: block_return_type, source: :rbs,
438
567
  type_location: type_location, closure: pin)
439
568
  end
440
- Pin::Signature.new(generics: generics, parameters: signature_parameters, return_type: signature_return_type, block: block, source: :rbs,
569
+ Pin::Signature.new(generics: generics, parameters: signature_parameters,
570
+ return_type: signature_return_type, block: block, source: :rbs,
441
571
  type_location: type_location, closure: pin)
442
572
  end
443
573
  end
444
574
 
445
575
  # @param location [RBS::Location, nil]
446
576
  # @return [Solargraph::Location, nil]
447
- def location_decl_to_pin_location(location)
577
+ def location_decl_to_pin_location location
448
578
  return nil if location&.name.nil?
449
579
 
580
+ # @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
450
581
  start_pos = Position.new(location.start_line - 1, location.start_column)
582
+ # @sg-ignore flow sensitive typing should handle return nil if location&.name.nil?
451
583
  end_pos = Position.new(location.end_line - 1, location.end_column)
452
584
  range = Range.new(start_pos, end_pos)
585
+ # @sg-ignore flow sensitve typing should handle return nil if location&.name.nil?
453
586
  Location.new(location.name.to_s, range)
454
587
  end
455
588
 
456
- # @param type [RBS::MethodType,RBS::Types::Block]
589
+ # @param type [RBS::MethodType, RBS::Types::Block]
457
590
  # @param pin [Pin::Method]
458
591
  # @return [Array(Array<Pin::Parameter>, ComplexType)]
459
592
  def parts_of_function type, pin
460
593
  type_location = pin.type_location
461
594
  if defined?(RBS::Types::UntypedFunction) && type.type.is_a?(RBS::Types::UntypedFunction)
462
595
  return [
463
- [Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs, type_location: type_location)],
464
- ComplexType.try_parse(method_type_to_tag(type)).force_rooted
596
+ [Solargraph::Pin::Parameter.new(decl: :restarg, name: 'arg', closure: pin, source: :rbs,
597
+ type_location: type_location)],
598
+ method_type_to_type(type)
465
599
  ]
466
600
  end
467
601
 
468
602
  parameters = []
469
603
  arg_num = -1
470
604
  type.type.required_positionals.each do |param|
471
- # @sg-ignore RBS generic type understanding issue
605
+ # @sg-ignore Unresolved call to name
472
606
  name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
473
- # @sg-ignore RBS generic type understanding issue
474
- 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, source: :rbs, type_location: type_location)
607
+ parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin,
608
+ # @sg-ignore RBS generic type understanding issue
609
+ return_type: other_type_to_type(param.type),
610
+ source: :rbs, type_location: type_location)
475
611
  end
476
612
  type.type.optional_positionals.each do |param|
477
- # @sg-ignore RBS generic type understanding issue
613
+ # @sg-ignore Unresolved call to name
478
614
  name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
479
615
  parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
480
616
  # @sg-ignore RBS generic type understanding issue
481
- return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
617
+ return_type: other_type_to_type(param.type),
482
618
  type_location: type_location,
483
619
  source: :rbs)
484
620
  end
485
621
  if type.type.rest_positionals
486
622
  name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg_#{arg_num += 1}"
487
- inner_rest_positional_type =
488
- ComplexType.try_parse(other_type_to_tag(type.type.rest_positionals.type))
623
+ inner_rest_positional_type = other_type_to_type(type.type.rest_positionals.type)
489
624
  rest_positional_type = ComplexType::UniqueType.new('Array',
490
625
  [],
491
626
  [inner_rest_positional_type],
492
627
  rooted: true, parameters_type: :list)
493
628
  parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin,
494
629
  source: :rbs, type_location: type_location,
495
- return_type: rest_positional_type,)
630
+ return_type: rest_positional_type)
496
631
  end
497
632
  type.type.trailing_positionals.each do |param|
498
- # @sg-ignore RBS generic type understanding issue
633
+ # @sg-ignore Unresolved call to name
499
634
  name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
500
- parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs, type_location: type_location)
635
+ parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, source: :rbs,
636
+ type_location: type_location)
501
637
  end
502
638
  type.type.required_keywords.each do |orig, param|
503
- # @sg-ignore RBS generic type understanding issue
639
+ # @sg-ignore Unresolved call to to_s
504
640
  name = orig ? orig.to_s : "arg_#{arg_num += 1}"
505
641
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
506
642
  # @sg-ignore RBS generic type understanding issue
507
- return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
643
+ return_type: other_type_to_type(param.type),
508
644
  source: :rbs, type_location: type_location)
509
645
  end
510
646
  type.type.optional_keywords.each do |orig, param|
511
- # @sg-ignore RBS generic type understanding issue
647
+ # @sg-ignore Unresolved call to to_s
512
648
  name = orig ? orig.to_s : "arg_#{arg_num += 1}"
513
649
  parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
514
650
  # @sg-ignore RBS generic type understanding issue
515
- return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted,
651
+ return_type: other_type_to_type(param.type),
516
652
  type_location: type_location,
517
653
  source: :rbs)
518
654
  end
519
655
  if type.type.rest_keywords
520
656
  name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg_#{arg_num += 1}"
521
- parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg, name: type.type.rest_keywords.name.to_s, closure: pin,
657
+ parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg,
658
+ name: type.type.rest_keywords.name.to_s, closure: pin,
522
659
  source: :rbs, type_location: type_location)
523
660
  end
524
661
 
525
- rooted_tag = method_type_to_tag(type)
526
- return_type = ComplexType.try_parse(rooted_tag).force_rooted
662
+ return_type = method_type_to_type(type)
527
663
  [parameters, return_type]
528
664
  end
529
665
 
@@ -531,7 +667,7 @@ module Solargraph
531
667
  # @param closure [Pin::Namespace]
532
668
  # @param context [Context]
533
669
  # @return [void]
534
- def attr_reader_to_pin(decl, closure, context)
670
+ def attr_reader_to_pin decl, closure, context
535
671
  name = decl.name.to_s
536
672
  final_scope = decl.kind == :instance ? :instance : :class
537
673
  visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
@@ -545,9 +681,11 @@ module Solargraph
545
681
  visibility: visibility,
546
682
  source: :rbs
547
683
  )
548
- rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
684
+ rooted_tag = other_type_to_type(decl.type).rooted_tags
549
685
  pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
550
- logger.debug { "Conversions#attr_reader_to_pin(name=#{name.inspect}, visibility=#{visibility.inspect}) => #{pin.inspect}" }
686
+ logger.debug do
687
+ "Conversions#attr_reader_to_pin(name=#{name.inspect}, visibility=#{visibility.inspect}) => #{pin.inspect}"
688
+ end
551
689
  pins.push pin
552
690
  end
553
691
 
@@ -555,9 +693,9 @@ module Solargraph
555
693
  # @param closure [Pin::Namespace]
556
694
  # @param context [Context]
557
695
  # @return [void]
558
- def attr_writer_to_pin(decl, closure, context)
696
+ def attr_writer_to_pin decl, closure, context
559
697
  final_scope = decl.kind == :instance ? :instance : :class
560
- name = "#{decl.name.to_s}="
698
+ name = "#{decl.name}="
561
699
  visibility = calculate_method_visibility(decl, context, closure, final_scope, name)
562
700
  type_location = location_decl_to_pin_location(decl.location)
563
701
  pin = Solargraph::Pin::Method.new(
@@ -574,13 +712,13 @@ module Solargraph
574
712
  pin.parameters <<
575
713
  Solargraph::Pin::Parameter.new(
576
714
  name: 'value',
577
- return_type: ComplexType.try_parse(other_type_to_tag(decl.type)).force_rooted,
715
+ return_type: other_type_to_type(decl.type),
578
716
  source: :rbs,
579
717
  closure: pin,
580
718
  type_location: type_location
581
719
  )
582
- rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
583
- pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tag))
720
+ rooted_tags = other_type_to_type(decl.type).rooted_tags
721
+ pin.docstring.add_tag(YARD::Tags::Tag.new(:return, '', rooted_tags))
584
722
  pins.push pin
585
723
  end
586
724
 
@@ -588,7 +726,7 @@ module Solargraph
588
726
  # @param closure [Pin::Namespace]
589
727
  # @param context [Context]
590
728
  # @return [void]
591
- def attr_accessor_to_pin(decl, closure, context)
729
+ def attr_accessor_to_pin decl, closure, context
592
730
  attr_reader_to_pin(decl, closure, context)
593
731
  attr_writer_to_pin(decl, closure, context)
594
732
  end
@@ -596,7 +734,7 @@ module Solargraph
596
734
  # @param decl [RBS::AST::Members::InstanceVariable]
597
735
  # @param closure [Pin::Namespace]
598
736
  # @return [void]
599
- def ivar_to_pin(decl, closure)
737
+ def ivar_to_pin decl, closure
600
738
  pin = Solargraph::Pin::InstanceVariable.new(
601
739
  name: decl.name.to_s,
602
740
  closure: closure,
@@ -604,7 +742,7 @@ module Solargraph
604
742
  comments: decl.comment&.string,
605
743
  source: :rbs
606
744
  )
607
- rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
745
+ rooted_tag = other_type_to_type(decl.type).rooted_tags
608
746
  pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
609
747
  pins.push pin
610
748
  end
@@ -612,7 +750,7 @@ module Solargraph
612
750
  # @param decl [RBS::AST::Members::ClassVariable]
613
751
  # @param closure [Pin::Namespace]
614
752
  # @return [void]
615
- def cvar_to_pin(decl, closure)
753
+ def cvar_to_pin decl, closure
616
754
  name = decl.name.to_s
617
755
  pin = Solargraph::Pin::ClassVariable.new(
618
756
  name: name,
@@ -621,7 +759,7 @@ module Solargraph
621
759
  type_location: location_decl_to_pin_location(decl.location),
622
760
  source: :rbs
623
761
  )
624
- rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
762
+ rooted_tag = other_type_to_type(decl.type).rooted_tags
625
763
  pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
626
764
  pins.push pin
627
765
  end
@@ -629,7 +767,7 @@ module Solargraph
629
767
  # @param decl [RBS::AST::Members::ClassInstanceVariable]
630
768
  # @param closure [Pin::Namespace]
631
769
  # @return [void]
632
- def civar_to_pin(decl, closure)
770
+ def civar_to_pin decl, closure
633
771
  name = decl.name.to_s
634
772
  pin = Solargraph::Pin::InstanceVariable.new(
635
773
  name: name,
@@ -638,7 +776,7 @@ module Solargraph
638
776
  type_location: location_decl_to_pin_location(decl.location),
639
777
  source: :rbs
640
778
  )
641
- rooted_tag = ComplexType.parse(other_type_to_tag(decl.type)).force_rooted.rooted_tags
779
+ rooted_tag = other_type_to_type(decl.type).rooted_tags
642
780
  pin.docstring.add_tag(YARD::Tags::Tag.new(:type, '', rooted_tag))
643
781
  pins.push pin
644
782
  end
@@ -648,9 +786,9 @@ module Solargraph
648
786
  # @return [void]
649
787
  def include_to_pin decl, closure
650
788
  type = build_type(decl.name, decl.args)
651
- generic_values = type.all_params.map(&:to_s)
789
+ generic_values = type.all_params.map(&:rooted_tags)
652
790
  pins.push Solargraph::Pin::Reference::Include.new(
653
- name: decl.name.relative!.to_s,
791
+ name: type.rooted_name, # reference pins use rooted names
654
792
  type_location: location_decl_to_pin_location(decl.location),
655
793
  generic_values: generic_values,
656
794
  closure: closure,
@@ -662,9 +800,12 @@ module Solargraph
662
800
  # @param closure [Pin::Namespace]
663
801
  # @return [void]
664
802
  def prepend_to_pin decl, closure
803
+ type = build_type(decl.name, decl.args)
804
+ generic_values = type.all_params.map(&:rooted_tags)
665
805
  pins.push Solargraph::Pin::Reference::Prepend.new(
666
- name: decl.name.relative!.to_s,
806
+ name: type.rooted_name, # reference pins use rooted names
667
807
  type_location: location_decl_to_pin_location(decl.location),
808
+ generic_values: generic_values,
668
809
  closure: closure,
669
810
  source: :rbs
670
811
  )
@@ -674,9 +815,12 @@ module Solargraph
674
815
  # @param closure [Pin::Namespace]
675
816
  # @return [void]
676
817
  def extend_to_pin decl, closure
818
+ type = build_type(decl.name, decl.args)
819
+ generic_values = type.all_params.map(&:rooted_tags)
677
820
  pins.push Solargraph::Pin::Reference::Extend.new(
678
- name: decl.name.relative!.to_s,
821
+ name: type.rooted_name, # reference pins use rooted names
679
822
  type_location: location_decl_to_pin_location(decl.location),
823
+ generic_values: generic_values,
680
824
  closure: closure,
681
825
  source: :rbs
682
826
  )
@@ -693,124 +837,109 @@ module Solargraph
693
837
  original: decl.old_name.to_s,
694
838
  closure: closure,
695
839
  scope: final_scope,
696
- source: :rbs,
840
+ source: :rbs
697
841
  )
698
842
  end
699
843
 
700
- RBS_TO_YARD_TYPE = {
701
- 'bool' => 'Boolean',
702
- 'string' => 'String',
703
- 'int' => 'Integer',
704
- 'untyped' => '',
705
- 'NilClass' => 'nil'
706
- }
707
-
708
- # @param type [RBS::MethodType]
709
- # @return [String]
710
- def method_type_to_tag type
711
- if type_aliases.key?(type.type.return_type.to_s)
712
- other_type_to_tag(type_aliases[type.type.return_type.to_s].type)
713
- else
714
- other_type_to_tag type.type.return_type
715
- end
716
- end
717
-
718
- # @param type_name [RBS::TypeName]
719
- # @param type_args [Enumerable<RBS::Types::Bases::Base>]
720
- # @return [ComplexType::UniqueType]
721
- def build_type(type_name, type_args = [])
722
- base = RBS_TO_YARD_TYPE[type_name.relative!.to_s] || type_name.relative!.to_s
723
- params = type_args.map { |a| other_type_to_tag(a) }.map do |t|
724
- ComplexType.try_parse(t).force_rooted
725
- end
726
- if base == 'Hash' && params.length == 2
727
- ComplexType::UniqueType.new(base, [params.first], [params.last], rooted: true, parameters_type: :hash)
728
- else
729
- ComplexType::UniqueType.new(base, [], params.reject(&:undefined?), rooted: true, parameters_type: :list)
730
- end
731
- end
732
-
733
- # @param type_name [RBS::TypeName]
734
- # @param type_args [Enumerable<RBS::Types::Bases::Base>]
735
- # @return [String]
736
- def type_tag(type_name, type_args = [])
737
- build_type(type_name, type_args).tags
844
+ # @param type [RBS::MethodType, RBS::Types::Block]
845
+ # @return [ComplexType, ComplexType::UniqueType]
846
+ def method_type_to_type type
847
+ other_type_to_type type.type.return_type
738
848
  end
739
849
 
740
- # @param type [RBS::Types::Bases::Base]
741
- # @return [String]
742
- def other_type_to_tag type
743
- if type.is_a?(RBS::Types::Optional)
744
- "#{other_type_to_tag(type.type)}, nil"
745
- elsif type.is_a?(RBS::Types::Bases::Any)
746
- 'undefined'
747
- elsif type.is_a?(RBS::Types::Bases::Bool)
748
- 'Boolean'
749
- elsif type.is_a?(RBS::Types::Tuple)
750
- "Array(#{type.types.map { |t| other_type_to_tag(t) }.join(', ')})"
751
- elsif type.is_a?(RBS::Types::Literal)
752
- type.literal.inspect
753
- elsif type.is_a?(RBS::Types::Union)
754
- type.types.map { |t| other_type_to_tag(t) }.join(', ')
755
- elsif type.is_a?(RBS::Types::Record)
850
+ # @param type [RBS::Types::Bases::Base,Object] RBS type object.
851
+ # Note: Generally these extend from RBS::Types::Bases::Base,
852
+ # but not all.
853
+ #
854
+ # @return [ComplexType, ComplexType::UniqueType]
855
+ def other_type_to_type type
856
+ case type
857
+ when RBS::Types::Optional
858
+ # @sg-ignore flow based typing needs to understand case when class pattern
859
+ ComplexType.new([other_type_to_type(type.type),
860
+ ComplexType::UniqueType::NIL])
861
+ when RBS::Types::Bases::Any
862
+ ComplexType::UNDEFINED
863
+ when RBS::Types::Bases::Bool
864
+ ComplexType::BOOLEAN
865
+ when RBS::Types::Tuple
866
+ # @sg-ignore flow based typing needs to understand case when class pattern
867
+ tuple_types = type.types.map { |t| other_type_to_type(t) }
868
+ ComplexType::UniqueType.new('Array', [], tuple_types, rooted: true, parameters_type: :fixed)
869
+ when RBS::Types::Literal
870
+ # @sg-ignore flow based typing needs to understand case when class pattern
871
+ ComplexType.try_parse(type.literal.inspect).force_rooted
872
+ when RBS::Types::Union
873
+ # @sg-ignore flow based typing needs to understand case when class pattern
874
+ ComplexType.new(type.types.map { |t| other_type_to_type(t) })
875
+ when RBS::Types::Record
756
876
  # @todo Better record support
757
- 'Hash'
758
- elsif type.is_a?(RBS::Types::Bases::Nil)
759
- 'nil'
760
- elsif type.is_a?(RBS::Types::Bases::Self)
761
- 'self'
762
- elsif type.is_a?(RBS::Types::Bases::Void)
763
- 'void'
764
- elsif type.is_a?(RBS::Types::Variable)
765
- "#{Solargraph::ComplexType::GENERIC_TAG_NAME}<#{type.name}>"
766
- elsif type.is_a?(RBS::Types::ClassInstance) #&& !type.args.empty?
767
- type_tag(type.name, type.args)
768
- elsif type.is_a?(RBS::Types::Bases::Instance)
769
- 'self'
770
- elsif type.is_a?(RBS::Types::Bases::Top)
877
+ ComplexType::UniqueType.new('Hash', rooted: true)
878
+ when RBS::Types::Bases::Nil
879
+ ComplexType::NIL
880
+ when RBS::Types::Bases::Self
881
+ ComplexType::SELF
882
+ when RBS::Types::Bases::Void
883
+ ComplexType::VOID
884
+ when RBS::Types::Variable
885
+ # @sg-ignore flow based typing needs to understand case when class pattern
886
+ ComplexType.parse("generic<#{type.name}>").force_rooted
887
+ when RBS::Types::ClassInstance # && !type.args.empty?
888
+ # @sg-ignore flow based typing needs to understand case when class pattern
889
+ build_type(type.name, type.args)
890
+ when RBS::Types::Bases::Instance
891
+ ComplexType::SELF
892
+ when RBS::Types::Bases::Top
771
893
  # top is the most super superclass
772
- 'BasicObject'
773
- elsif type.is_a?(RBS::Types::Bases::Bottom)
894
+ ComplexType::UniqueType.new('BasicObject', rooted: true)
895
+ when RBS::Types::Bases::Bottom
774
896
  # bottom is used in contexts where nothing will ever return
775
897
  # - e.g., it could be the return type of 'exit()' or 'raise'
776
898
  #
777
899
  # @todo define a specific bottom type and use it to
778
900
  # determine dead code
779
- 'undefined'
780
- elsif type.is_a?(RBS::Types::Intersection)
781
- type.types.map { |member| other_type_to_tag(member) }.join(', ')
782
- elsif type.is_a?(RBS::Types::Proc)
783
- 'Proc'
784
- elsif type.is_a?(RBS::Types::Alias)
901
+ ComplexType::UNDEFINED
902
+ when RBS::Types::Intersection
903
+ # @sg-ignore flow based typing needs to understand case when class pattern
904
+ ComplexType.new(type.types.map { |member| other_type_to_type(member) })
905
+ when RBS::Types::Proc
906
+ ComplexType::UniqueType.new('Proc', rooted: true)
907
+ when RBS::Types::Alias
785
908
  # type-level alias use - e.g., 'bool' in "type bool = true | false"
786
909
  # @todo ensure these get resolved after processing all aliases
787
910
  # @todo handle recursive aliases
788
- type_tag(type.name, type.args)
789
- elsif type.is_a?(RBS::Types::Interface)
911
+ # @sg-ignore flow based typing needs to understand case when class pattern
912
+ build_type(type.name, type.args)
913
+ when RBS::Types::Interface
790
914
  # represents a mix-in module which can be considered a
791
915
  # subtype of a consumer of it
792
- type_tag(type.name, type.args)
793
- elsif type.is_a?(RBS::Types::ClassSingleton)
916
+ # @sg-ignore flow based typing needs to understand case when class pattern
917
+ build_type(type.name, type.args)
918
+ when RBS::Types::ClassSingleton
794
919
  # e.g., singleton(String)
795
- type_tag(type.name)
920
+ # @sg-ignore flow based typing needs to understand case when class pattern
921
+ build_type(type.name)
796
922
  else
923
+ # RBS doesn't provide a common base class for its type AST nodes
924
+ #
925
+ # @sg-ignore all types should include location
797
926
  Solargraph.logger.warn "Unrecognized RBS type: #{type.class} at #{type.location}"
798
- 'undefined'
927
+ ComplexType::UNDEFINED
799
928
  end
800
929
  end
801
930
 
802
931
  # @param decl [RBS::AST::Declarations::Class, RBS::AST::Declarations::Module]
803
- # @param namespace [Pin::Namespace]
932
+ # @param namespace [Pin::Namespace, nil]
804
933
  # @return [void]
805
934
  def add_mixins decl, namespace
806
- # @param mixin [RBS::AST::Members::Include, RBS::AST::Members::Members::Extend, RBS::AST::Members::Members::Prepend]
935
+ # @param mixin [RBS::AST::Members::Include, RBS::AST::Members::Extend, RBS::AST::Members::Prepend]
807
936
  decl.each_mixin do |mixin|
808
937
  # @todo are we handling prepend correctly?
809
938
  klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
810
939
  type = build_type(mixin.name, mixin.args)
811
- generic_values = type.all_params.map(&:to_s)
940
+ generic_values = type.all_params.map(&:rooted_tags)
812
941
  pins.push klass.new(
813
- name: mixin.name.relative!.to_s,
942
+ name: type.rooted_name, # reference pins use rooted names
814
943
  type_location: location_decl_to_pin_location(mixin.location),
815
944
  generic_values: generic_values,
816
945
  closure: namespace,