solargraph 0.58.3 → 0.59.0.dev.1

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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/.envrc +3 -0
  3. data/.github/workflows/linting.yml +4 -5
  4. data/.github/workflows/plugins.yml +41 -38
  5. data/.github/workflows/rspec.yml +45 -13
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.gitignore +0 -1
  8. data/.rubocop_todo.yml +27 -49
  9. data/CHANGELOG.md +1 -10
  10. data/README.md +3 -3
  11. data/Rakefile +1 -0
  12. data/lib/solargraph/api_map/cache.rb +3 -3
  13. data/lib/solargraph/api_map/constants.rb +13 -3
  14. data/lib/solargraph/api_map/index.rb +22 -11
  15. data/lib/solargraph/api_map/source_to_yard.rb +13 -1
  16. data/lib/solargraph/api_map/store.rb +11 -8
  17. data/lib/solargraph/api_map.rb +105 -50
  18. data/lib/solargraph/bench.rb +45 -45
  19. data/lib/solargraph/complex_type/conformance.rb +176 -0
  20. data/lib/solargraph/complex_type/type_methods.rb +16 -2
  21. data/lib/solargraph/complex_type/unique_type.rb +170 -20
  22. data/lib/solargraph/complex_type.rb +119 -14
  23. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  24. data/lib/solargraph/convention/data_definition/data_definition_node.rb +3 -1
  25. data/lib/solargraph/convention/data_definition.rb +4 -1
  26. data/lib/solargraph/convention/gemfile.rb +15 -15
  27. data/lib/solargraph/convention/gemspec.rb +23 -23
  28. data/lib/solargraph/convention/rakefile.rb +17 -17
  29. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -0
  30. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +1 -0
  31. data/lib/solargraph/convention/struct_definition.rb +5 -1
  32. data/lib/solargraph/convention.rb +78 -78
  33. data/lib/solargraph/converters/dd.rb +17 -17
  34. data/lib/solargraph/converters/dl.rb +15 -15
  35. data/lib/solargraph/converters/dt.rb +15 -15
  36. data/lib/solargraph/converters/misc.rb +1 -1
  37. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  38. data/lib/solargraph/diagnostics/rubocop.rb +1 -0
  39. data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
  40. data/lib/solargraph/diagnostics/type_check.rb +1 -0
  41. data/lib/solargraph/diagnostics/update_errors.rb +41 -41
  42. data/lib/solargraph/doc_map.rb +134 -373
  43. data/lib/solargraph/equality.rb +1 -1
  44. data/lib/solargraph/gem_pins.rb +14 -15
  45. data/lib/solargraph/language_server/error_codes.rb +20 -20
  46. data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
  47. data/lib/solargraph/language_server/host/dispatch.rb +1 -0
  48. data/lib/solargraph/language_server/host/message_worker.rb +2 -1
  49. data/lib/solargraph/language_server/host/sources.rb +1 -0
  50. data/lib/solargraph/language_server/host.rb +6 -1
  51. data/lib/solargraph/language_server/message/base.rb +97 -97
  52. data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
  53. data/lib/solargraph/language_server/message/completion_item/resolve.rb +60 -60
  54. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -7
  55. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  56. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  57. data/lib/solargraph/language_server/message/extended/download_core.rb +19 -19
  58. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  59. data/lib/solargraph/language_server/message/initialize.rb +191 -191
  60. data/lib/solargraph/language_server/message/text_document/completion.rb +2 -0
  61. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
  62. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
  63. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +2 -0
  64. data/lib/solargraph/language_server/message/text_document/formatting.rb +2 -0
  65. data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
  66. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
  67. data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
  68. data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
  69. data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -0
  70. data/lib/solargraph/language_server/message/text_document/type_definition.rb +2 -0
  71. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +35 -35
  72. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +40 -40
  73. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +26 -26
  74. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -0
  75. data/lib/solargraph/language_server/message.rb +94 -94
  76. data/lib/solargraph/language_server/request.rb +27 -27
  77. data/lib/solargraph/language_server/transport/data_reader.rb +74 -74
  78. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  79. data/lib/solargraph/library.rb +59 -13
  80. data/lib/solargraph/location.rb +9 -4
  81. data/lib/solargraph/logging.rb +21 -1
  82. data/lib/solargraph/page.rb +92 -92
  83. data/lib/solargraph/parser/comment_ripper.rb +7 -0
  84. data/lib/solargraph/parser/flow_sensitive_typing.rb +330 -102
  85. data/lib/solargraph/parser/node_processor/base.rb +32 -2
  86. data/lib/solargraph/parser/node_processor.rb +7 -6
  87. data/lib/solargraph/parser/parser_gem/class_methods.rb +28 -10
  88. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  89. data/lib/solargraph/parser/parser_gem/node_chainer.rb +31 -6
  90. data/lib/solargraph/parser/parser_gem/node_methods.rb +27 -7
  91. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  92. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +2 -0
  93. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  94. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -11
  95. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +7 -0
  96. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +37 -37
  97. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  98. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +3 -2
  99. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  100. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  101. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +2 -2
  102. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  103. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  104. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  105. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +1 -0
  106. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +12 -7
  107. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  108. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  109. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +5 -1
  110. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  111. data/lib/solargraph/parser/parser_gem.rb +12 -12
  112. data/lib/solargraph/parser/region.rb +9 -3
  113. data/lib/solargraph/parser/snippet.rb +1 -1
  114. data/lib/solargraph/parser.rb +23 -23
  115. data/lib/solargraph/pin/base.rb +53 -21
  116. data/lib/solargraph/pin/base_variable.rb +312 -20
  117. data/lib/solargraph/pin/block.rb +26 -4
  118. data/lib/solargraph/pin/breakable.rb +5 -1
  119. data/lib/solargraph/pin/callable.rb +50 -3
  120. data/lib/solargraph/pin/closure.rb +2 -6
  121. data/lib/solargraph/pin/common.rb +20 -5
  122. data/lib/solargraph/pin/compound_statement.rb +55 -0
  123. data/lib/solargraph/pin/constant.rb +45 -45
  124. data/lib/solargraph/pin/conversions.rb +2 -1
  125. data/lib/solargraph/pin/delegated_method.rb +15 -4
  126. data/lib/solargraph/pin/documenting.rb +1 -0
  127. data/lib/solargraph/pin/instance_variable.rb +5 -1
  128. data/lib/solargraph/pin/keyword.rb +0 -4
  129. data/lib/solargraph/pin/local_variable.rb +13 -57
  130. data/lib/solargraph/pin/method.rb +90 -42
  131. data/lib/solargraph/pin/method_alias.rb +8 -0
  132. data/lib/solargraph/pin/namespace.rb +7 -1
  133. data/lib/solargraph/pin/parameter.rb +76 -13
  134. data/lib/solargraph/pin/proxy_type.rb +2 -1
  135. data/lib/solargraph/pin/reference/override.rb +1 -1
  136. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  137. data/lib/solargraph/pin/reference.rb +2 -0
  138. data/lib/solargraph/pin/search.rb +1 -0
  139. data/lib/solargraph/pin/signature.rb +8 -0
  140. data/lib/solargraph/pin/symbol.rb +1 -1
  141. data/lib/solargraph/pin/until.rb +1 -1
  142. data/lib/solargraph/pin/while.rb +1 -1
  143. data/lib/solargraph/pin.rb +2 -0
  144. data/lib/solargraph/pin_cache.rb +477 -57
  145. data/lib/solargraph/position.rb +12 -26
  146. data/lib/solargraph/range.rb +6 -6
  147. data/lib/solargraph/rbs_map/conversions.rb +33 -10
  148. data/lib/solargraph/rbs_map/core_fills.rb +84 -84
  149. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  150. data/lib/solargraph/rbs_map/stdlib_map.rb +34 -5
  151. data/lib/solargraph/rbs_map.rb +74 -20
  152. data/lib/solargraph/server_methods.rb +16 -16
  153. data/lib/solargraph/shell.rb +73 -39
  154. data/lib/solargraph/source/chain/array.rb +37 -37
  155. data/lib/solargraph/source/chain/call.rb +52 -17
  156. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  157. data/lib/solargraph/source/chain/constant.rb +2 -0
  158. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  159. data/lib/solargraph/source/chain/hash.rb +1 -0
  160. data/lib/solargraph/source/chain/if.rb +1 -0
  161. data/lib/solargraph/source/chain/instance_variable.rb +22 -1
  162. data/lib/solargraph/source/chain/link.rb +109 -109
  163. data/lib/solargraph/source/chain/literal.rb +5 -0
  164. data/lib/solargraph/source/chain/or.rb +9 -1
  165. data/lib/solargraph/source/chain/q_call.rb +11 -11
  166. data/lib/solargraph/source/chain/variable.rb +13 -13
  167. data/lib/solargraph/source/chain/z_super.rb +30 -30
  168. data/lib/solargraph/source/chain.rb +25 -22
  169. data/lib/solargraph/source/change.rb +9 -2
  170. data/lib/solargraph/source/cursor.rb +7 -1
  171. data/lib/solargraph/source/source_chainer.rb +13 -3
  172. data/lib/solargraph/source/updater.rb +4 -0
  173. data/lib/solargraph/source.rb +33 -7
  174. data/lib/solargraph/source_map/clip.rb +13 -2
  175. data/lib/solargraph/source_map/data.rb +4 -1
  176. data/lib/solargraph/source_map/mapper.rb +24 -1
  177. data/lib/solargraph/source_map.rb +14 -6
  178. data/lib/solargraph/type_checker/problem.rb +3 -1
  179. data/lib/solargraph/type_checker/rules.rb +75 -2
  180. data/lib/solargraph/type_checker.rb +111 -30
  181. data/lib/solargraph/version.rb +1 -1
  182. data/lib/solargraph/workspace/config.rb +3 -1
  183. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  184. data/lib/solargraph/workspace/require_paths.rb +1 -0
  185. data/lib/solargraph/workspace.rb +158 -16
  186. data/lib/solargraph/yard_map/helpers.rb +2 -1
  187. data/lib/solargraph/yard_map/mapper/to_method.rb +5 -1
  188. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  189. data/lib/solargraph/yard_map/mapper.rb +5 -0
  190. data/lib/solargraph/yard_tags.rb +20 -20
  191. data/lib/solargraph/yardoc.rb +33 -23
  192. data/lib/solargraph.rb +24 -3
  193. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  194. data/rbs/fills/tuple/tuple.rbs +28 -0
  195. data/rbs/shims/ast/0/node.rbs +1 -1
  196. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  197. data/solargraph.gemspec +2 -1
  198. metadata +12 -7
  199. data/lib/solargraph/type_checker/checks.rb +0 -124
  200. data/lib/solargraph/type_checker/param_def.rb +0 -37
  201. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -21,6 +21,7 @@ module Solargraph
21
21
  @context = context
22
22
  @return_type = ComplexType.parse('::Proc')
23
23
  @node = node
24
+ @name = '<block>'
24
25
  end
25
26
 
26
27
  # @param api_map [ApiMap]
@@ -30,7 +31,13 @@ module Solargraph
30
31
  end
31
32
 
32
33
  def binder
33
- @rebind&.defined? ? @rebind : closure.binder
34
+ out = @rebind if @rebind&.defined?
35
+ out ||= super
36
+ end
37
+
38
+ def context
39
+ @context = @rebind if @rebind&.defined?
40
+ super
34
41
  end
35
42
 
36
43
  # @param yield_types [::Array<ComplexType>]
@@ -50,14 +57,17 @@ module Solargraph
50
57
  # @return [::Array<ComplexType>]
51
58
  def typify_parameters(api_map)
52
59
  chain = Parser.chain(receiver, filename, node)
60
+ # @sg-ignore Need to add nil check here
53
61
  clip = api_map.clip_at(location.filename, location.range.start)
54
62
  locals = clip.locals - [self]
63
+ # @sg-ignore Need to add nil check here
55
64
  meths = chain.define(api_map, closure, locals)
56
65
  # @todo Convert logic to use signatures
57
66
  # @param meth [Pin::Method]
58
67
  meths.each do |meth|
59
68
  next if meth.block.nil?
60
69
 
70
+ # @sg-ignore flow sensitive typing needs to handle attrs
61
71
  yield_types = meth.block.parameters.map(&:return_type)
62
72
  # 'arguments' is what the method says it will yield to the
63
73
  # block; 'parameters' is what the block accepts
@@ -67,6 +77,7 @@ module Solargraph
67
77
  param_type = chain.base.infer(api_map, param, locals)
68
78
  unless arg_type.nil?
69
79
  if arg_type.generic? && param_type.defined?
80
+ # @sg-ignore Need to add nil check here
70
81
  namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
71
82
  arg_type.resolve_generics(namespace_pin, param_type)
72
83
  else
@@ -86,16 +97,27 @@ module Solargraph
86
97
  def maybe_rebind api_map
87
98
  return ComplexType::UNDEFINED unless receiver
88
99
 
89
- chain = Parser.chain(receiver, location.filename)
100
+ # @sg-ignore Need to add nil check here
101
+ chain = Parser.chain(receiver, location.filename, node)
102
+ # @sg-ignore Need to add nil check here
90
103
  locals = api_map.source_map(location.filename).locals_at(location)
104
+ # @sg-ignore Need to add nil check here
91
105
  receiver_pin = chain.define(api_map, closure, locals).first
92
106
  return ComplexType::UNDEFINED unless receiver_pin
93
107
 
94
108
  types = receiver_pin.docstring.tag(:yieldreceiver)&.types
95
109
  return ComplexType::UNDEFINED unless types&.any?
96
110
 
97
- target = chain.base.infer(api_map, receiver_pin, locals)
98
- target = full_context unless target.defined?
111
+ name_pin = self
112
+ # if we have Foo.bar { |x| ... }, and the bar method references self...
113
+ target = if chain.base.defined?
114
+ # figure out Foo
115
+ chain.base.infer(api_map, name_pin, locals)
116
+ else
117
+ # if not, any self there must be the context of our closure
118
+ # @sg-ignore Need to add nil check here
119
+ closure.full_context
120
+ end
99
121
 
100
122
  ComplexType.try_parse(*types).qualify(api_map, *receiver_pin.gates).self_to_type(target)
101
123
  end
@@ -1,9 +1,13 @@
1
1
  module Solargraph
2
2
  module Pin
3
- # Mix-in for pins which enclose code which the 'break' statement works with-in - e.g., blocks, when, until, ...
3
+ # Mix-in for pins which enclose code which the 'break' statement
4
+ # works with-in - e.g., blocks, when, until, ...
4
5
  module Breakable
5
6
  # @return [Parser::AST::Node]
6
7
  attr_reader :node
8
+
9
+ # @return [Location, nil]
10
+ attr_reader :location
7
11
  end
8
12
  end
9
13
  end
@@ -21,8 +21,15 @@ module Solargraph
21
21
  @parameters = parameters
22
22
  end
23
23
 
24
+ def reset_generated!
25
+ parameters.each(&:reset_generated!)
26
+ super
27
+ end
28
+
29
+ # @sg-ignore Need to add nil check here
24
30
  # @return [String]
25
31
  def method_namespace
32
+ # @sg-ignore Need to add nil check here
26
33
  closure.namespace
27
34
  end
28
35
 
@@ -80,6 +87,7 @@ module Solargraph
80
87
  end
81
88
  end
82
89
 
90
+ # @sg-ignore Need to add nil check here
83
91
  # @return [Array<Pin::Parameter>]
84
92
  def blockless_parameters
85
93
  if parameters.last&.block?
@@ -89,11 +97,33 @@ module Solargraph
89
97
  end
90
98
  end
91
99
 
92
- # @return [Array]
100
+ # e.g., [["T"], "", "?", "foo:"] - parameter arity declarations,
101
+ # ignoring positional names. Used to match signatures.
102
+ #
103
+ # @return [Array<Array<String>, String, nil>]
93
104
  def arity
94
105
  [generics, blockless_parameters.map(&:arity_decl), block&.arity]
95
106
  end
96
107
 
108
+ # e.g., [["T"], "1", "?3", "foo:5"] - parameter arity
109
+ # declarations, including the number of unique types in each
110
+ # parameter. Used to determine whether combining two
111
+ # signatures has lost useful information mapping specific
112
+ # parameter types to specific return types.
113
+ #
114
+ # @return [Array<Array, String, nil>]
115
+ def type_arity
116
+ [generics, blockless_parameters.map(&:type_arity_decl), block&.type_arity]
117
+ end
118
+
119
+ # Same as type_arity, but includes return type arity at the front.
120
+ #
121
+ # @return [Array<Array, String, nil>]
122
+ def full_type_arity
123
+ # @sg-ignore flow sensitive typing needs to handle attrs
124
+ [return_type ? return_type.items.count.to_s : nil] + type_arity
125
+ end
126
+
97
127
  # @param generics_to_resolve [Enumerable<String>]
98
128
  # @param arg_types [Array<ComplexType>, nil]
99
129
  # @param return_type_context [ComplexType, nil]
@@ -101,6 +131,7 @@ module Solargraph
101
131
  # @param yield_return_type_context [ComplexType, nil]
102
132
  # @param context [ComplexType, nil]
103
133
  # @param resolved_generic_values [Hash{String => ComplexType}]
134
+ #
104
135
  # @return [self]
105
136
  def resolve_generics_from_context(generics_to_resolve,
106
137
  arg_types = nil,
@@ -137,9 +168,11 @@ module Solargraph
137
168
  end
138
169
  end
139
170
 
171
+ # @sg-ignore Need to add nil check here
140
172
  # @return [String]
141
173
  def method_name
142
174
  raise "closure was nil in #{self.inspect}" if closure.nil?
175
+ # @sg-ignore Need to add nil check here
143
176
  @method_name ||= closure.name
144
177
  end
145
178
 
@@ -150,6 +183,7 @@ module Solargraph
150
183
  # @param yield_return_type_context [ComplexType, nil]
151
184
  # @param context [ComplexType, nil]
152
185
  # @param resolved_generic_values [Hash{String => ComplexType}]
186
+ #
153
187
  # @return [self]
154
188
  def resolve_generics_from_context_until_complete(generics_to_resolve,
155
189
  arg_types = nil,
@@ -184,7 +218,6 @@ module Solargraph
184
218
  resolved_generic_values: resolved_generic_values)
185
219
  end
186
220
 
187
- # @return [Array<String>]
188
221
  # @yieldparam [ComplexType]
189
222
  # @yieldreturn [ComplexType]
190
223
  # @return [self]
@@ -206,17 +239,31 @@ module Solargraph
206
239
  parcount = mandatory_positional_param_count
207
240
  parcount -= 1 if !parameters.empty? && parameters.last.block?
208
241
  return false if block? && !with_block
242
+ # @todo this and its caller should be changed so that this can
243
+ # look at the kwargs provided and check names against what
244
+ # we acccept
209
245
  return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.restarg?)
210
246
  true
211
247
  end
212
248
 
249
+ def reset_generated!
250
+ super
251
+ @parameters.each(&:reset_generated!)
252
+ end
253
+
213
254
  # @return [Integer]
214
255
  def mandatory_positional_param_count
215
256
  parameters.count(&:arg?)
216
257
  end
217
258
 
259
+ # @return [String]
260
+ def parameters_to_rbs
261
+ # @sg-ignore Need to add nil check here
262
+ rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ')
263
+ end
264
+
218
265
  def to_rbs
219
- rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
266
+ parameters_to_rbs + '-> ' + (return_type&.to_rbs || 'untyped')
220
267
  end
221
268
 
222
269
  def block?
@@ -2,12 +2,12 @@
2
2
 
3
3
  module Solargraph
4
4
  module Pin
5
- class Closure < Base
5
+ class Closure < CompoundStatement
6
6
  # @return [::Symbol] :class or :instance
7
7
  attr_reader :scope
8
8
 
9
9
  # @param scope [::Symbol] :class or :instance
10
- # @param generics [::Array<Pin::Parameter>, nil]
10
+ # @param generics [::Array<Pin::String>, nil]
11
11
  # @param generic_defaults [Hash{String => ComplexType}]
12
12
  def initialize scope: :class, generics: nil, generic_defaults: {}, **splat
13
13
  super(**splat)
@@ -44,10 +44,6 @@ module Solargraph
44
44
  end
45
45
  end
46
46
 
47
- def binder
48
- @binder || context
49
- end
50
-
51
47
  # @param api_map [Solargraph::ApiMap]
52
48
  # @return [void]
53
49
  def rebind api_map; end
@@ -6,12 +6,24 @@ module Solargraph
6
6
  # @!method source
7
7
  # @abstract
8
8
  # @return [Source, nil]
9
+ # @!method reset_generated!
10
+ # @abstract
11
+ # @return [void]
9
12
  # @type @closure [Pin::Closure, nil]
13
+ # @type @binder [ComplexType, ComplexType::UniqueType, nil]
14
+
15
+ # @todo Missed nil violation
16
+ # @return [Location, nil]
17
+ attr_accessor :location
10
18
 
11
- # @return [Location]
12
- attr_reader :location
19
+ # @param value [Pin::Closure]
20
+ # @return [void]
21
+ def closure=(value)
22
+ @closure = value
23
+ # remove cached values generated from closure
24
+ reset_generated!
25
+ end
13
26
 
14
- # @sg-ignore Solargraph::Pin::Common#closure return type could not be inferred
15
27
  # @return [Pin::Closure, nil]
16
28
  def closure
17
29
  Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
@@ -23,12 +35,13 @@ module Solargraph
23
35
  @name ||= ''
24
36
  end
25
37
 
38
+ # @todo redundant with Base#return_type?
26
39
  # @return [ComplexType]
27
40
  def return_type
28
41
  @return_type ||= ComplexType::UNDEFINED
29
42
  end
30
43
 
31
- # @return [ComplexType]
44
+ # @return [ComplexType, ComplexType::UniqueType]
32
45
  def context
33
46
  # Get the static context from the nearest namespace
34
47
  @context ||= find_context
@@ -40,7 +53,8 @@ module Solargraph
40
53
  context.namespace.to_s
41
54
  end
42
55
 
43
- # @return [ComplexType]
56
+ # @return [ComplexType, ComplexType::UniqueType]
57
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1100
44
58
  def binder
45
59
  @binder || context
46
60
  end
@@ -70,6 +84,7 @@ module Solargraph
70
84
  elsif here.is_a?(Pin::Method)
71
85
  return here.context
72
86
  end
87
+ # @sg-ignore Need to add nil check here
73
88
  here = here.closure
74
89
  end
75
90
  ComplexType::ROOT
@@ -0,0 +1,55 @@
1
+ module Solargraph
2
+ module Pin
3
+ # A series of statements where if a given statement executes, /all
4
+ # of the previous statements in the sequence must have executed as
5
+ # well/. In other words, the statements are run from the top in
6
+ # sequence, until interrupted by something like a
7
+ # return/break/next/raise/etc.
8
+ #
9
+ # This mix-in is used in flow sensitive typing to determine how
10
+ # far we can assume a given assertion about a type can be trusted
11
+ # to be true.
12
+ #
13
+ # Some examples in Ruby:
14
+ #
15
+ # * Bodies of methods and Ruby blocks
16
+ # * Branches of conditionals and loops - if/elsif/else,
17
+ # unless/else, when, until, ||=, ?:, switch/case/else
18
+ # * The body of begin-end/try/rescue/ensure statements
19
+ #
20
+ # Compare/contrast with:
21
+ #
22
+ # * Scope - a sequence where variables declared are not available
23
+ # after the end of the scope. Note that this is not necessarily
24
+ # true for a compound statement.
25
+ # * Compound statement - synonym
26
+ # * Block - in Ruby this has a special meaning (a closure passed to a method), but
27
+ # in general parlance this is also a synonym.
28
+ # * Closure - a sequence which is also a scope
29
+ # * Namespace - a named sequence which is also a scope and a
30
+ # closure
31
+ #
32
+ # See:
33
+ # https://cse.buffalo.edu/~regan/cse305/RubyBNF.pdf
34
+ # https://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html
35
+ # https://en.wikipedia.org/wiki/Block_(programming)
36
+ #
37
+ # Note:
38
+ #
39
+ # Just because statement #1 in a sequence is executed, it doesn't
40
+ # mean that future ones will. Consider the effect of
41
+ # break/next/return/raise/etc. on control flow.
42
+ class CompoundStatement < Pin::Base
43
+ attr_reader :node
44
+
45
+ # @param receiver [Parser::AST::Node, nil]
46
+ # @param node [Parser::AST::Node, nil]
47
+ # @param context [ComplexType, nil]
48
+ # @param args [::Array<Parameter>]
49
+ def initialize node: nil, **splat
50
+ super(**splat)
51
+ @node = node
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,45 +1,45 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Pin
5
- class Constant < BaseVariable
6
- attr_reader :visibility
7
-
8
- # @param visibility [::Symbol] The visibility of the constant (:public, :protected, or :private)
9
- # @param splat [Hash] Additional options supported by superclasses
10
- def initialize visibility: :public, **splat
11
- super(**splat)
12
- @visibility = visibility
13
- end
14
-
15
- def return_type
16
- @return_type ||= generate_complex_type
17
- end
18
-
19
- def completion_item_kind
20
- Solargraph::LanguageServer::CompletionItemKinds::CONSTANT
21
- end
22
-
23
- # @return [Integer]
24
- def symbol_kind
25
- LanguageServer::SymbolKinds::CONSTANT
26
- end
27
-
28
- def path
29
- @path ||= context.namespace.to_s.empty? ? name : "#{context.namespace}::#{name}"
30
- end
31
-
32
- private
33
-
34
- # @return [ComplexType]
35
- def generate_complex_type
36
- tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
37
- if tags.empty?
38
- tags = docstring.tags(:type).map(&:types).flatten.reject(&:nil?)
39
- end
40
- return ComplexType::UNDEFINED if tags.empty?
41
- ComplexType.try_parse *tags
42
- end
43
- end
44
- end
45
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Pin
5
+ class Constant < BaseVariable
6
+ attr_reader :visibility
7
+
8
+ # @param visibility [::Symbol] The visibility of the constant (:public, :protected, or :private)
9
+ # @param splat [Hash] Additional options supported by superclasses
10
+ def initialize visibility: :public, **splat
11
+ super(**splat)
12
+ @visibility = visibility
13
+ end
14
+
15
+ def return_type
16
+ @return_type ||= generate_complex_type
17
+ end
18
+
19
+ def completion_item_kind
20
+ Solargraph::LanguageServer::CompletionItemKinds::CONSTANT
21
+ end
22
+
23
+ # @return [Integer]
24
+ def symbol_kind
25
+ LanguageServer::SymbolKinds::CONSTANT
26
+ end
27
+
28
+ def path
29
+ @path ||= context.namespace.to_s.empty? ? name : "#{context.namespace}::#{name}"
30
+ end
31
+
32
+ private
33
+
34
+ # @return [ComplexType]
35
+ def generate_complex_type
36
+ tags = docstring.tags(:return).map(&:types).flatten.reject(&:nil?)
37
+ if tags.empty?
38
+ tags = docstring.tags(:type).map(&:types).flatten.reject(&:nil?)
39
+ end
40
+ return ComplexType::UNDEFINED if tags.empty?
41
+ ComplexType.try_parse *tags
42
+ end
43
+ end
44
+ end
45
+ end
@@ -43,6 +43,7 @@ module Solargraph
43
43
  data: {
44
44
  path: path,
45
45
  return_type: return_type.tag,
46
+ # @sg-ignore flow sensitive typing needs to handle attrs
46
47
  location: (location ? location.to_hash : nil),
47
48
  deprecated: deprecated?
48
49
  }
@@ -80,7 +81,7 @@ module Solargraph
80
81
 
81
82
  # Get a markdown-flavored link to a documentation page.
82
83
  #
83
- # @return [String]
84
+ # @return [String, nil]
84
85
  def link_documentation
85
86
  @link_documentation ||= generate_link
86
87
  end
@@ -13,10 +13,11 @@ module Solargraph
13
13
  #
14
14
  # @param method [Method, nil] an already resolved method pin.
15
15
  # @param receiver [Source::Chain, nil] the source code used to resolve the receiver for this delegated method.
16
- # @param name [String]
17
- # @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name).
16
+ # @param name [String, nil]
17
+ # @param receiver_method_name [String, nil] the method name that will be called on the receiver (defaults to :name).
18
18
  def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
19
19
  raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
20
+ # @sg-ignore Need to add nil check here
20
21
  super(name: name, **splat)
21
22
 
22
23
  @receiver_chain = receiver
@@ -69,30 +70,40 @@ module Solargraph
69
70
  #
70
71
  # @param api_map [ApiMap]
71
72
  # @return [Pin::Method, nil]
73
+ # @sg-ignore Declared return type ::Solargraph::Pin::Method, nil
74
+ # does not match inferred type nil, false for
75
+ # Solargraph::Pin::DelegatedMethod#resolve_method
72
76
  def resolve_method api_map
73
77
  return if @resolved_method
74
78
 
79
+ # @sg-ignore Need to add nil check here
75
80
  resolver = @receiver_chain.define(api_map, self, []).first
76
81
 
77
82
  unless resolver
78
- Solargraph.logger.warn \
79
- "Delegated receiver for #{path} was resolved to nil from `#{print_chain(@receiver_chain)}'"
83
+ # @sg-ignore Need to add nil check here
84
+ Solargraph.logger.warn "Delegated receiver for #{path} was resolved to nil from `#{print_chain(@receiver_chain)}'"
80
85
  return
81
86
  end
82
87
 
88
+ # @sg-ignore Need to add nil check here
83
89
  receiver_type = resolver.return_type
84
90
 
91
+ # @sg-ignore Need to add nil check here
85
92
  return if receiver_type.undefined?
86
93
 
87
94
  receiver_path, method_scope =
95
+ # @sg-ignore Need to add nil check here
88
96
  if @receiver_chain.constant?
89
97
  # HACK: the `return_type` of a constant is Class<Whatever>, but looking up a method expects
90
98
  # the arguments `"Whatever"` and `scope: :class`.
99
+ # @sg-ignore Need to add nil check here
91
100
  [receiver_type.to_s.sub(/^Class<(.+)>$/, '\1'), :class]
92
101
  else
102
+ # @sg-ignore Need to add nil check here
93
103
  [receiver_type.to_s, :instance]
94
104
  end
95
105
 
106
+ # @sg-ignore Need to add nil check here
96
107
  method_stack = api_map.get_method_stack(receiver_path, @receiver_method_name, scope: method_scope)
97
108
  @resolved_method = method_stack.first
98
109
  end
@@ -104,6 +104,7 @@ module Solargraph
104
104
  left = text.lines.map do |line|
105
105
  match = line.match(/^ +/)
106
106
  next 0 unless match
107
+ # @sg-ignore Need to add nil check here
107
108
  match[0].length
108
109
  end.min
109
110
  return text if left.nil? || left.zero?
@@ -3,13 +3,17 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class InstanceVariable < BaseVariable
6
- # @return [ComplexType]
6
+ # @sg-ignore Need to add nil check here
7
+ # @return [ComplexType, ComplexType::UniqueType]
7
8
  def binder
9
+ # @sg-ignore Need to add nil check here
8
10
  closure.binder
9
11
  end
10
12
 
13
+ # @sg-ignore Need to add nil check here
11
14
  # @return [::Symbol]
12
15
  def scope
16
+ # @sg-ignore Need to add nil check here
13
17
  closure.binder.scope
14
18
  end
15
19
 
@@ -11,10 +11,6 @@ module Solargraph
11
11
  def closure
12
12
  @closure ||= Pin::ROOT_PIN
13
13
  end
14
-
15
- def name
16
- @name
17
- end
18
14
  end
19
15
  end
20
16
  end
@@ -3,73 +3,29 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class LocalVariable < BaseVariable
6
- # @return [Range]
7
- attr_reader :presence
8
-
9
- def presence_certain?
10
- @presence_certain
11
- end
6
+ # @param api_map [ApiMap]
7
+ # @return [ComplexType, ComplexType::UniqueType]
8
+ def probe api_map
9
+ if presence_certain? && return_type && return_type&.defined?
10
+ # flow sensitive typing has already figured out this type
11
+ # has been downcast - use the type it figured out
12
+ # @sg-ignore flow sensitive typing should support ivars
13
+ return adjust_type api_map, return_type.qualify(api_map, *gates)
14
+ end
12
15
 
13
- # @param assignment [AST::Node, nil]
14
- # @param presence [Range, nil]
15
- # @param presence_certain [Boolean]
16
- # @param splat [Hash]
17
- def initialize assignment: nil, presence: nil, presence_certain: false, **splat
18
- super(**splat)
19
- @assignment = assignment
20
- @presence = presence
21
- @presence_certain = presence_certain
16
+ super
22
17
  end
23
18
 
24
19
  def combine_with(other, attrs={})
25
- new_attrs = {
26
- assignment: assert_same(other, :assignment),
27
- presence_certain: assert_same(other, :presence_certain?),
28
- }.merge(attrs)
29
- new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
20
+ # keep this as a parameter
21
+ return other.combine_with(self, attrs) if other.is_a?(Parameter) && !self.is_a?(Parameter)
30
22
 
31
- super(other, new_attrs)
32
- end
33
-
34
- # @param other_closure [Pin::Closure]
35
- # @param other_loc [Location]
36
- def visible_at?(other_closure, other_loc)
37
- location.filename == other_loc.filename &&
38
- presence.include?(other_loc.range.start) &&
39
- match_named_closure(other_closure, closure)
23
+ super
40
24
  end
41
25
 
42
26
  def to_rbs
43
27
  (name || '(anon)') + ' ' + (return_type&.to_rbs || 'untyped')
44
28
  end
45
-
46
- private
47
-
48
- # @param tag1 [String]
49
- # @param tag2 [String]
50
- # @return [Boolean]
51
- def match_tags tag1, tag2
52
- # @todo This is an unfortunate hack made necessary by a discrepancy in
53
- # how tags indicate the root namespace. The long-term solution is to
54
- # standardize it, whether it's `Class<>`, an empty string, or
55
- # something else.
56
- tag1 == tag2 ||
57
- (['', 'Class<>'].include?(tag1) && ['', 'Class<>'].include?(tag2))
58
- end
59
-
60
- # @param needle [Pin::Base]
61
- # @param haystack [Pin::Base]
62
- # @return [Boolean]
63
- def match_named_closure needle, haystack
64
- return true if needle == haystack || haystack.is_a?(Pin::Block)
65
- cursor = haystack
66
- until cursor.nil?
67
- return true if needle.path == cursor.path
68
- return false if cursor.path && !cursor.path.empty?
69
- cursor = cursor.closure
70
- end
71
- false
72
- end
73
29
  end
74
30
  end
75
31
  end