solargraph 0.58.2 → 0.59.0.dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) 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 -34
  5. data/.github/workflows/rspec.yml +44 -23
  6. data/.github/workflows/typecheck.yml +2 -2
  7. data/.rubocop.yml +32 -5
  8. data/.rubocop_todo.yml +50 -966
  9. data/Gemfile +3 -1
  10. data/README.md +3 -3
  11. data/Rakefile +26 -23
  12. data/bin/solargraph +2 -1
  13. data/lib/solargraph/api_map/cache.rb +3 -3
  14. data/lib/solargraph/api_map/constants.rb +13 -3
  15. data/lib/solargraph/api_map/index.rb +23 -18
  16. data/lib/solargraph/api_map/source_to_yard.rb +22 -9
  17. data/lib/solargraph/api_map/store.rb +33 -28
  18. data/lib/solargraph/api_map.rb +150 -82
  19. data/lib/solargraph/bench.rb +44 -45
  20. data/lib/solargraph/complex_type/conformance.rb +176 -0
  21. data/lib/solargraph/complex_type/type_methods.rb +28 -17
  22. data/lib/solargraph/complex_type/unique_type.rb +218 -57
  23. data/lib/solargraph/complex_type.rb +170 -57
  24. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
  25. data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
  26. data/lib/solargraph/convention/data_definition.rb +5 -2
  27. data/lib/solargraph/convention/gemfile.rb +15 -15
  28. data/lib/solargraph/convention/gemspec.rb +23 -23
  29. data/lib/solargraph/convention/rakefile.rb +17 -17
  30. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  31. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
  32. data/lib/solargraph/convention/struct_definition.rb +8 -4
  33. data/lib/solargraph/convention.rb +78 -78
  34. data/lib/solargraph/converters/dd.rb +19 -17
  35. data/lib/solargraph/converters/dl.rb +17 -15
  36. data/lib/solargraph/converters/dt.rb +17 -15
  37. data/lib/solargraph/converters/misc.rb +3 -1
  38. data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
  39. data/lib/solargraph/diagnostics/rubocop.rb +11 -10
  40. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  41. data/lib/solargraph/diagnostics/type_check.rb +11 -10
  42. data/lib/solargraph/diagnostics/update_errors.rb +37 -41
  43. data/lib/solargraph/doc_map.rb +133 -373
  44. data/lib/solargraph/equality.rb +4 -4
  45. data/lib/solargraph/gem_pins.rb +21 -20
  46. data/lib/solargraph/language_server/error_codes.rb +20 -20
  47. data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
  48. data/lib/solargraph/language_server/host/dispatch.rb +3 -3
  49. data/lib/solargraph/language_server/host/message_worker.rb +4 -3
  50. data/lib/solargraph/language_server/host/sources.rb +2 -1
  51. data/lib/solargraph/language_server/host.rb +30 -22
  52. data/lib/solargraph/language_server/message/base.rb +97 -97
  53. data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
  54. data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
  55. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
  56. data/lib/solargraph/language_server/message/extended/document.rb +1 -0
  57. data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
  58. data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
  59. data/lib/solargraph/language_server/message/extended/search.rb +20 -20
  60. data/lib/solargraph/language_server/message/initialize.rb +197 -191
  61. data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
  62. data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
  63. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
  64. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
  65. data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
  66. data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
  67. data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
  68. data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
  69. data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
  70. data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
  71. data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
  72. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
  73. data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
  74. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
  75. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
  76. data/lib/solargraph/language_server/message.rb +94 -94
  77. data/lib/solargraph/language_server/request.rb +29 -27
  78. data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
  79. data/lib/solargraph/language_server/uri_helpers.rb +49 -49
  80. data/lib/solargraph/library.rb +85 -44
  81. data/lib/solargraph/location.rb +17 -14
  82. data/lib/solargraph/logging.rb +24 -4
  83. data/lib/solargraph/page.rb +92 -92
  84. data/lib/solargraph/parser/comment_ripper.rb +19 -4
  85. data/lib/solargraph/parser/flow_sensitive_typing.rb +326 -108
  86. data/lib/solargraph/parser/node_processor/base.rb +34 -4
  87. data/lib/solargraph/parser/node_processor.rb +8 -7
  88. data/lib/solargraph/parser/parser_gem/class_methods.rb +32 -14
  89. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
  90. data/lib/solargraph/parser/parser_gem/node_chainer.rb +50 -25
  91. data/lib/solargraph/parser/parser_gem/node_methods.rb +91 -70
  92. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
  93. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
  94. data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
  95. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +12 -12
  96. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
  97. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
  98. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
  99. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
  100. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
  101. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
  102. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
  103. data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
  104. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
  105. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  106. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
  107. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
  108. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
  109. data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
  110. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
  111. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  112. data/lib/solargraph/parser/parser_gem.rb +14 -12
  113. data/lib/solargraph/parser/region.rb +9 -3
  114. data/lib/solargraph/parser/snippet.rb +3 -1
  115. data/lib/solargraph/parser.rb +25 -23
  116. data/lib/solargraph/pin/base.rb +126 -80
  117. data/lib/solargraph/pin/base_variable.rb +273 -24
  118. data/lib/solargraph/pin/block.rb +29 -6
  119. data/lib/solargraph/pin/breakable.rb +7 -1
  120. data/lib/solargraph/pin/callable.rb +65 -21
  121. data/lib/solargraph/pin/closure.rb +7 -10
  122. data/lib/solargraph/pin/common.rb +24 -6
  123. data/lib/solargraph/pin/compound_statement.rb +55 -0
  124. data/lib/solargraph/pin/constant.rb +43 -45
  125. data/lib/solargraph/pin/conversions.rb +10 -4
  126. data/lib/solargraph/pin/delegated_method.rb +19 -8
  127. data/lib/solargraph/pin/documenting.rb +4 -2
  128. data/lib/solargraph/pin/instance_variable.rb +5 -1
  129. data/lib/solargraph/pin/keyword.rb +0 -4
  130. data/lib/solargraph/pin/local_variable.rb +15 -59
  131. data/lib/solargraph/pin/method.rb +153 -104
  132. data/lib/solargraph/pin/method_alias.rb +8 -0
  133. data/lib/solargraph/pin/namespace.rb +19 -12
  134. data/lib/solargraph/pin/parameter.rb +100 -36
  135. data/lib/solargraph/pin/proxy_type.rb +4 -1
  136. data/lib/solargraph/pin/reference/override.rb +1 -1
  137. data/lib/solargraph/pin/reference/superclass.rb +2 -0
  138. data/lib/solargraph/pin/reference.rb +19 -0
  139. data/lib/solargraph/pin/search.rb +3 -2
  140. data/lib/solargraph/pin/signature.rb +15 -12
  141. data/lib/solargraph/pin/symbol.rb +2 -1
  142. data/lib/solargraph/pin/until.rb +2 -4
  143. data/lib/solargraph/pin/while.rb +2 -4
  144. data/lib/solargraph/pin.rb +2 -0
  145. data/lib/solargraph/pin_cache.rb +490 -73
  146. data/lib/solargraph/position.rb +14 -10
  147. data/lib/solargraph/range.rb +16 -15
  148. data/lib/solargraph/rbs_map/conversions.rb +343 -214
  149. data/lib/solargraph/rbs_map/core_fills.rb +91 -84
  150. data/lib/solargraph/rbs_map/core_map.rb +24 -17
  151. data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
  152. data/lib/solargraph/rbs_map.rb +77 -32
  153. data/lib/solargraph/server_methods.rb +16 -16
  154. data/lib/solargraph/shell.rb +128 -73
  155. data/lib/solargraph/source/chain/array.rb +39 -37
  156. data/lib/solargraph/source/chain/call.rb +96 -56
  157. data/lib/solargraph/source/chain/class_variable.rb +13 -13
  158. data/lib/solargraph/source/chain/constant.rb +5 -1
  159. data/lib/solargraph/source/chain/global_variable.rb +13 -13
  160. data/lib/solargraph/source/chain/hash.rb +8 -5
  161. data/lib/solargraph/source/chain/if.rb +12 -10
  162. data/lib/solargraph/source/chain/instance_variable.rb +24 -1
  163. data/lib/solargraph/source/chain/link.rb +99 -109
  164. data/lib/solargraph/source/chain/literal.rb +9 -6
  165. data/lib/solargraph/source/chain/or.rb +10 -4
  166. data/lib/solargraph/source/chain/q_call.rb +13 -11
  167. data/lib/solargraph/source/chain/variable.rb +15 -13
  168. data/lib/solargraph/source/chain/z_super.rb +28 -30
  169. data/lib/solargraph/source/chain.rb +49 -38
  170. data/lib/solargraph/source/change.rb +12 -5
  171. data/lib/solargraph/source/cursor.rb +23 -17
  172. data/lib/solargraph/source/encoding_fixes.rb +6 -7
  173. data/lib/solargraph/source/source_chainer.rb +56 -32
  174. data/lib/solargraph/source/updater.rb +5 -1
  175. data/lib/solargraph/source.rb +59 -35
  176. data/lib/solargraph/source_map/clip.rb +48 -29
  177. data/lib/solargraph/source_map/data.rb +4 -1
  178. data/lib/solargraph/source_map/mapper.rb +71 -42
  179. data/lib/solargraph/source_map.rb +21 -9
  180. data/lib/solargraph/type_checker/problem.rb +3 -1
  181. data/lib/solargraph/type_checker/rules.rb +81 -8
  182. data/lib/solargraph/type_checker.rb +195 -120
  183. data/lib/solargraph/version.rb +1 -1
  184. data/lib/solargraph/workspace/config.rb +13 -10
  185. data/lib/solargraph/workspace/gemspecs.rb +367 -0
  186. data/lib/solargraph/workspace/require_paths.rb +1 -0
  187. data/lib/solargraph/workspace.rb +149 -30
  188. data/lib/solargraph/yard_map/helpers.rb +8 -3
  189. data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
  190. data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
  191. data/lib/solargraph/yard_map/mapper.rb +13 -8
  192. data/lib/solargraph/yard_tags.rb +20 -20
  193. data/lib/solargraph/yardoc.rb +33 -23
  194. data/lib/solargraph.rb +29 -8
  195. data/rbs/fills/rubygems/0/dependency.rbs +193 -0
  196. data/rbs/fills/tuple/tuple.rbs +28 -0
  197. data/rbs/shims/ast/0/node.rbs +1 -1
  198. data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
  199. data/solargraph.gemspec +36 -34
  200. metadata +38 -33
  201. data/lib/solargraph/type_checker/checks.rb +0 -124
  202. data/lib/solargraph/type_checker/param_def.rb +0 -37
  203. data/lib/solargraph/yard_map/to_method.rb +0 -89
@@ -12,17 +12,17 @@ module Solargraph
12
12
 
13
13
  # @param node [Parser::AST::Node]
14
14
  # @return [String]
15
- def unpack_name(node)
16
- pack_name(node).join("::")
15
+ def unpack_name node
16
+ pack_name(node).join('::')
17
17
  end
18
18
 
19
19
  # @param node [Parser::AST::Node]
20
20
  # @return [Array<String>]
21
- def pack_name(node)
21
+ def pack_name node
22
22
  # @type [Array<String>]
23
23
  parts = []
24
24
  if node.is_a?(AST::Node)
25
- node.children.each { |n|
25
+ node.children.each do |n|
26
26
  if n.is_a?(AST::Node)
27
27
  if n.type == :cbase
28
28
  parts = [''] + pack_name(n)
@@ -32,16 +32,16 @@ module Solargraph
32
32
  else
33
33
  parts.push n unless n.nil?
34
34
  end
35
- }
35
+ end
36
36
  end
37
37
  parts
38
38
  end
39
39
 
40
- # @param node [Parser::AST::Node]
40
+ # @param node [Parser::AST::Node, nil]
41
41
  # @return [String, nil]
42
42
  def infer_literal_node_type node
43
43
  return nil unless node.is_a?(AST::Node)
44
- if node.type == :str || node.type == :dstr
44
+ if %i[str dstr].include?(node.type)
45
45
  return '::String'
46
46
  elsif node.type == :array
47
47
  return '::Array'
@@ -53,30 +53,30 @@ module Solargraph
53
53
  return '::Integer'
54
54
  elsif node.type == :float
55
55
  return '::Float'
56
- elsif node.type == :sym || node.type == :dsym
56
+ elsif %i[sym dsym].include?(node.type)
57
57
  return '::Symbol'
58
58
  elsif node.type == :regexp
59
59
  return '::Regexp'
60
60
  elsif node.type == :irange
61
61
  return '::Range'
62
- elsif node.type == :true || node.type == :false
62
+ elsif %i[true false].include?(node.type)
63
63
  return '::Boolean'
64
64
  # @todo Support `nil` keyword in types
65
- # elsif node.type == :nil
66
- # return 'NilClass'
65
+ # elsif node.type == :nil
66
+ # return 'NilClass'
67
67
  end
68
68
  nil
69
69
  end
70
70
 
71
71
  # @param node [Parser::AST::Node]
72
72
  # @return [Position]
73
- def get_node_start_position(node)
73
+ def get_node_start_position node
74
74
  Position.new(node.loc.line, node.loc.column)
75
75
  end
76
76
 
77
77
  # @param node [Parser::AST::Node]
78
78
  # @return [Position]
79
- def get_node_end_position(node)
79
+ def get_node_end_position node
80
80
  Position.new(node.loc.last_line, node.loc.last_column)
81
81
  end
82
82
 
@@ -86,40 +86,42 @@ module Solargraph
86
86
  # @return [String]
87
87
  def drill_signature node, signature
88
88
  return signature unless node.is_a?(AST::Node)
89
- if node.type == :const or node.type == :cbase
90
- unless node.children[0].nil?
91
- signature += drill_signature(node.children[0], signature)
92
- end
89
+ if %i[const cbase].include?(node.type)
90
+ signature += drill_signature(node.children[0], signature) unless node.children[0].nil?
93
91
  signature += '::' unless signature.empty?
94
92
  signature += node.children[1].to_s
95
- elsif node.type == :lvar or node.type == :ivar or node.type == :cvar
93
+ elsif %i[lvar ivar cvar].include?(node.type)
96
94
  signature += '.' unless signature.empty?
97
95
  signature += node.children[0].to_s
98
96
  elsif node.type == :send
99
- unless node.children[0].nil?
100
- signature += drill_signature(node.children[0], signature)
101
- end
97
+ signature += drill_signature(node.children[0], signature) unless node.children[0].nil?
102
98
  signature += '.' unless signature.empty?
103
99
  signature += node.children[1].to_s
104
100
  end
105
101
  signature
106
102
  end
107
103
 
108
- # @param node [Parser::AST::Node]
104
+ # @param node [Parser::AST::Node, nil]
109
105
  # @return [Hash{Symbol => Chain}]
110
106
  def convert_hash node
111
107
  return {} unless Parser.is_ast_node?(node)
108
+ # @sg-ignore Translate to something flow sensitive typing understands
112
109
  return convert_hash(node.children[0]) if node.type == :kwsplat
113
- return convert_hash(node.children[0]) if Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat
110
+ # @sg-ignore Translate to something flow sensitive typing understands
111
+ if Parser.is_ast_node?(node.children[0]) && node.children[0].type == :kwsplat
112
+ # @sg-ignore Translate to something flow sensitive typing understands
113
+ return convert_hash(node.children[0])
114
+ end
115
+ # @sg-ignore Translate to something flow sensitive typing understands
114
116
  return {} unless node.type == :hash
115
117
  result = {}
118
+ # @sg-ignore Translate to something flow sensitive typing understands
116
119
  node.children.each do |pair|
117
120
  result[pair.children[0].children[0]] = Solargraph::Parser.chain(pair.children[1])
118
121
  end
119
122
  result
120
123
  end
121
124
 
122
- # @sg-ignore Wrong argument type for AST::Node.new: type expected AST::_ToSym, received :nil
123
125
  NIL_NODE = ::Parser::AST::Node.new(:nil)
124
126
 
125
127
  # @param node [Parser::AST::Node]
@@ -148,7 +150,7 @@ module Solargraph
148
150
  end
149
151
 
150
152
  # @param nodes [Enumerable<Parser::AST::Node>]
151
- def any_splatted_call?(nodes)
153
+ def any_splatted_call? nodes
152
154
  nodes.any? { |n| splatted_call?(n) }
153
155
  end
154
156
 
@@ -161,14 +163,17 @@ module Solargraph
161
163
  if node.type == :block
162
164
  result.push node
163
165
  if Parser.is_ast_node?(node.children[0]) && node.children[0].children.length > 2
164
- node.children[0].children[2..-1].each { |child| result.concat call_nodes_from(child) }
166
+ # @sg-ignore Need to add nil check here
167
+ node.children[0].children[2..].each { |child| result.concat call_nodes_from(child) }
165
168
  end
166
- node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
169
+ # @sg-ignore Need to add nil check here
170
+ node.children[1..].each { |child| result.concat call_nodes_from(child) }
167
171
  elsif node.type == :send
168
172
  result.push node
169
173
  result.concat call_nodes_from(node.children.first)
170
- node.children[2..-1].each { |child| result.concat call_nodes_from(child) }
171
- elsif [:super, :zsuper].include?(node.type)
174
+ # @sg-ignore Need to add nil check here
175
+ node.children[2..].each { |child| result.concat call_nodes_from(child) }
176
+ elsif %i[super zsuper].include?(node.type)
172
177
  result.push node
173
178
  node.children.each { |child| result.concat call_nodes_from(child) }
174
179
  else
@@ -199,40 +204,44 @@ module Solargraph
199
204
  # @return [Array<AST::Node>] low-level value nodes in
200
205
  # value position. Does not include explicit return
201
206
  # statements
202
- def value_position_nodes_only(node)
207
+ def value_position_nodes_only node
203
208
  DeepInference.value_position_nodes_only(node).map { |n| n || NIL_NODE }
204
209
  end
205
210
 
206
211
  # @param cursor [Solargraph::Source::Cursor]
207
212
  # @return [Parser::AST::Node, nil]
208
213
  def find_recipient_node cursor
209
- return repaired_find_recipient_node(cursor) if cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '('
214
+ if cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '('
215
+ return repaired_find_recipient_node(cursor)
216
+ end
210
217
  source = cursor.source
211
218
  position = cursor.position
212
219
  offset = cursor.offset
213
220
  tree = if source.synchronized?
214
- match = source.code[0..offset-1].match(/,\s*\z/)
215
- if match
216
- source.tree_at(position.line, position.column - match[0].length)
217
- else
218
- source.tree_at(position.line, position.column)
219
- end
220
- else
221
- source.tree_at(position.line, position.column - 1)
222
- end
221
+ # @sg-ignore Need to add nil check here
222
+ match = source.code[0..(offset - 1)].match(/,\s*\z/)
223
+ if match
224
+ # @sg-ignore Need to add nil check here
225
+ source.tree_at(position.line, position.column - match[0].length)
226
+ else
227
+ source.tree_at(position.line, position.column)
228
+ end
229
+ else
230
+ source.tree_at(position.line, position.column - 1)
231
+ end
223
232
  # @type [AST::Node, nil]
224
233
  prev = nil
225
234
  tree.each do |node|
226
235
  if node.type == :send
227
- args = node.children[2..-1]
236
+ args = node.children[2..]
237
+ # @sg-ignore Need to add nil check here
228
238
  if !args.empty?
239
+ # @sg-ignore Need to add nil check here
229
240
  return node if prev && args.include?(prev)
230
- else
231
- if source.synchronized?
232
- return node if source.code[0..offset-1] =~ /\(\s*\z/ && source.code[offset..-1] =~ /^\s*\)/
233
- else
234
- return node if source.code[0..offset-1] =~ /\([^(]*\z/
235
- end
241
+ elsif source.synchronized?
242
+ return node if source.code[0..(offset - 1)] =~ /\(\s*\z/ && source.code[offset..] =~ /^\s*\)/
243
+ elsif source.code[0..(offset - 1)] =~ /\([^(]*\z/
244
+ return node
236
245
  end
237
246
  end
238
247
  prev = node
@@ -245,7 +254,7 @@ module Solargraph
245
254
  def repaired_find_recipient_node cursor
246
255
  cursor = cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
247
256
  node = cursor.source.tree_at(cursor.position.line, cursor.position.column).first
248
- return node if node && node.type == :send
257
+ node if node && node.type == :send
249
258
  end
250
259
 
251
260
  #
@@ -302,19 +311,15 @@ module Solargraph
302
311
  # statements in value positions.
303
312
  module DeepInference
304
313
  class << self
305
- CONDITIONAL_ALL_BUT_FIRST = [:if, :unless]
306
- CONDITIONAL_ALL = [:or]
307
- ONLY_ONE_CHILD = [:return]
308
- FIRST_TWO_CHILDREN = [:rescue]
309
- COMPOUND_STATEMENTS = [:begin, :kwbegin]
310
- SKIPPABLE = [:def, :defs, :class, :sclass, :module]
311
- FUNCTION_VALUE = [:block]
312
- CASE_STATEMENT = [:case]
314
+ CONDITIONAL_ALL_BUT_FIRST = %i[if unless].freeze
315
+ ONLY_ONE_CHILD = [:return].freeze
316
+ FIRST_TWO_CHILDREN = [:rescue].freeze
317
+ COMPOUND_STATEMENTS = %i[begin kwbegin].freeze
318
+ SKIPPABLE = %i[def defs class sclass module].freeze
319
+ FUNCTION_VALUE = [:block].freeze
320
+ CASE_STATEMENT = [:case].freeze
313
321
 
314
322
  # @param node [AST::Node] a method body compound statement
315
- # @param include_explicit_returns [Boolean] If true,
316
- # include the value nodes of the parameter of the
317
- # 'return' statements in the type returned.
318
323
  # @return [Array<AST::Node>] low-level value nodes from
319
324
  # both nodes in value position as well as explicit
320
325
  # return statements in the method's closure.
@@ -327,14 +332,14 @@ module Solargraph
327
332
  # @return [Array<AST::Node>] low-level value nodes in
328
333
  # value position. Does not include explicit return
329
334
  # statements
330
- def value_position_nodes_only(node)
335
+ def value_position_nodes_only node
331
336
  from_value_position_statement(node, include_explicit_returns: false)
332
337
  end
333
338
 
334
339
  # Look at known control statements and use them to find
335
340
  # more specific return nodes.
336
341
  #
337
- # @param node [Parser::AST::Node] Statement which is in
342
+ # @param node [AST::Node] Statement which is in
338
343
  # value position for a method body
339
344
  # @param include_explicit_returns [Boolean] If true,
340
345
  # include the value nodes of the parameter of the
@@ -348,10 +353,9 @@ module Solargraph
348
353
  if COMPOUND_STATEMENTS.include?(node.type)
349
354
  result.concat from_value_position_compound_statement node
350
355
  elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
351
- result.concat reduce_to_value_nodes(node.children[1..-1])
356
+ # @sg-ignore Need to add nil check here
357
+ result.concat reduce_to_value_nodes(node.children[1..])
352
358
  # result.push NIL_NODE unless node.children[2]
353
- elsif CONDITIONAL_ALL.include?(node.type)
354
- result.concat reduce_to_value_nodes(node.children)
355
359
  elsif ONLY_ONE_CHILD.include?(node.type)
356
360
  result.concat reduce_to_value_nodes([node.children[0]])
357
361
  elsif FIRST_TWO_CHILDREN.include?(node.type)
@@ -362,9 +366,12 @@ module Solargraph
362
366
  # @todo any explicit returns actually return from
363
367
  # scope in which the proc is run. This asssumes
364
368
  # that the function is executed here.
365
- result.concat explicit_return_values_from_compound_statement(node.children[2]) if include_explicit_returns
369
+ if include_explicit_returns
370
+ result.concat explicit_return_values_from_compound_statement(node.children[2])
371
+ end
366
372
  elsif CASE_STATEMENT.include?(node.type)
367
- node.children[1..-1].each do |cc|
373
+ # @sg-ignore Need to add nil check here
374
+ node.children[1..].each do |cc|
368
375
  if cc.nil?
369
376
  result.push NIL_NODE
370
377
  elsif cc.type == :when
@@ -397,7 +404,7 @@ module Solargraph
397
404
  # @return [Array<Parser::AST::Node>]
398
405
  def from_value_position_compound_statement parent
399
406
  result = []
400
- nodes = parent.children.select{|n| n.is_a?(AST::Node)}
407
+ nodes = parent.children.select { |n| n.is_a?(AST::Node) }
401
408
  nodes.each_with_index do |node, idx|
402
409
  if node.type == :block
403
410
  result.concat explicit_return_values_from_compound_statement(node.children[2])
@@ -422,7 +429,10 @@ module Solargraph
422
429
  # value position. we already have the explicit values
423
430
  # from above; now we need to also gather the value
424
431
  # position nodes
425
- result.concat from_value_position_statement(nodes.last, include_explicit_returns: false) if idx == nodes.length - 1
432
+ if idx == nodes.length - 1
433
+ result.concat from_value_position_statement(nodes.last,
434
+ include_explicit_returns: false)
435
+ end
426
436
  end
427
437
  result
428
438
  end
@@ -438,7 +448,7 @@ module Solargraph
438
448
  def explicit_return_values_from_compound_statement parent
439
449
  return [] unless parent.is_a?(::Parser::AST::Node)
440
450
  result = []
441
- nodes = parent.children.select{|n| n.is_a?(::Parser::AST::Node)}
451
+ nodes = parent.children.select { |n| n.is_a?(::Parser::AST::Node) }
442
452
  nodes.each do |node|
443
453
  next if SKIPPABLE.include?(node.type)
444
454
  if node.type == :return
@@ -460,17 +470,28 @@ module Solargraph
460
470
  nodes.each do |node|
461
471
  if !node.is_a?(::Parser::AST::Node)
462
472
  result.push nil
473
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
463
474
  elsif COMPOUND_STATEMENTS.include?(node.type)
464
475
  result.concat from_value_position_compound_statement(node)
476
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
465
477
  elsif CONDITIONAL_ALL_BUT_FIRST.include?(node.type)
466
- result.concat reduce_to_value_nodes(node.children[1..-1])
478
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
479
+ result.concat reduce_to_value_nodes(node.children[1..])
480
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
467
481
  elsif node.type == :return
482
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
468
483
  result.concat reduce_to_value_nodes([node.children[0]])
484
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
469
485
  elsif node.type == :or
486
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
470
487
  result.concat reduce_to_value_nodes(node.children)
488
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
471
489
  elsif node.type == :block
490
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
472
491
  result.concat explicit_return_values_from_compound_statement(node.children[2])
492
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
473
493
  elsif node.type == :resbody
494
+ # @sg-ignore flow sensitive typing needs to narrow down type with an if is_a? check
474
495
  result.concat reduce_to_value_nodes([node.children[2]])
475
496
  else
476
497
  result.push node
@@ -10,10 +10,10 @@ module Solargraph
10
10
  def process
11
11
  process_children
12
12
 
13
- position = get_node_start_position(node)
14
- # @sg-ignore https://github.com/castwide/solargraph/pull/1114
15
- enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last
16
- FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_and(node)
13
+ FlowSensitiveTyping.new(locals,
14
+ ivars,
15
+ enclosing_breakable_pin,
16
+ enclosing_compound_statement_pin).process_and(node)
17
17
  end
18
18
  end
19
19
  end
@@ -14,16 +14,17 @@ module Solargraph
14
14
  node.children.each do |u|
15
15
  loc = get_node_location(u)
16
16
  locals.push Solargraph::Pin::Parameter.new(
17
- location: loc,
18
- closure: callable,
19
- comments: comments_for(node),
20
- name: u.children[0].to_s,
21
- assignment: u.children[1],
22
- asgn_code: u.children[1] ? region.code_for(u.children[1]) : nil,
23
- presence: callable.location.range,
24
- decl: get_decl(u),
25
- source: :parser
26
- )
17
+ location: loc,
18
+ closure: callable,
19
+ comments: comments_for(node),
20
+ name: u.children[0].to_s,
21
+ assignment: u.children[1],
22
+ asgn_code: u.children[1] ? region.code_for(u.children[1]) : nil,
23
+ # @sg-ignore Need to add nil check here
24
+ presence: callable.location.range,
25
+ decl: get_decl(u),
26
+ source: :parser
27
+ )
27
28
  callable.parameters.push locals.last
28
29
  end
29
30
  end
@@ -35,11 +36,12 @@ module Solargraph
35
36
 
36
37
  # @param callable [Pin::Callable]
37
38
  # @return [void]
38
- def forward(callable)
39
+ def forward callable
39
40
  loc = get_node_location(node)
40
41
  locals.push Solargraph::Pin::Parameter.new(
41
42
  location: loc,
42
43
  closure: callable,
44
+ # @sg-ignore Need to add nil check here
43
45
  presence: region.closure.location.range,
44
46
  decl: get_decl(node),
45
47
  source: :parser
@@ -6,6 +6,15 @@ module Solargraph
6
6
  module NodeProcessors
7
7
  class BeginNode < Parser::NodeProcessor::Base
8
8
  def process
9
+ # We intentionally don't create a CompoundStatement pin
10
+ # here, as this is not necessarily a control flow block -
11
+ # e.g., a begin...end without rescue or ensure should be
12
+ # treated by flow sensitive typing as if the begin and end
13
+ # didn't exist at all. As such, we create the
14
+ # CompoundStatement pins around the things which actually
15
+ # result in control flow changes - like
16
+ # if/while/rescue/etc
17
+
9
18
  process_children
10
19
  end
11
20
  end
@@ -9,23 +9,22 @@ module Solargraph
9
9
 
10
10
  def process
11
11
  location = get_node_location(node)
12
- parent = if other_class_eval?
13
- Solargraph::Pin::Namespace.new(
14
- location: location,
15
- type: :class,
16
- name: unpack_name(node.children[0].children[0]),
17
- source: :parser,
18
- )
19
- else
20
- region.closure
12
+ scope = region.scope || region.closure.context.scope
13
+ if other_class_eval?
14
+ clazz_name = unpack_name(node.children[0].children[0])
15
+ # instance variables should come from the Class<T> type
16
+ # - i.e., treated as class instance variables
17
+ context = ComplexType.try_parse("Class<#{clazz_name}>")
18
+ scope = :class
21
19
  end
22
20
  block_pin = Solargraph::Pin::Block.new(
23
21
  location: location,
24
- closure: parent,
22
+ closure: region.closure,
25
23
  node: node,
24
+ context: context,
26
25
  receiver: node.children[0],
27
26
  comments: comments_for(node),
28
- scope: region.scope || region.closure.context.scope,
27
+ scope: scope,
29
28
  source: :parser
30
29
  )
31
30
  pins.push block_pin
@@ -37,7 +36,8 @@ module Solargraph
37
36
  def other_class_eval?
38
37
  node.children[0].type == :send &&
39
38
  node.children[0].children[1] == :class_eval &&
40
- [:cbase, :const].include?(node.children[0].children[0]&.type)
39
+ # @sg-ignore Need to add nil check here
40
+ %i[cbase const].include?(node.children[0].children[0]&.type)
41
41
  end
42
42
  end
43
43
  end
@@ -8,38 +8,45 @@ module Solargraph
8
8
  def process
9
9
  name = node.children[0].to_s
10
10
  scope = region.scope || (region.closure.is_a?(Pin::Singleton) ? :class : :instance)
11
+ # specify context explicitly instead of relying on
12
+ # closure, as they may differ (e.g., defs inside
13
+ # class_eval)
14
+ method_context = scope == :instance ? region.closure.binder.namespace_type : region.closure.binder
11
15
  methpin = Solargraph::Pin::Method.new(
12
16
  location: get_node_location(node),
13
17
  closure: region.closure,
14
18
  name: name,
19
+ context: method_context,
15
20
  comments: comments_for(node),
16
21
  scope: scope,
17
22
  visibility: scope == :instance && name == 'initialize' ? :private : region.visibility,
18
23
  node: node,
19
- source: :parser,
24
+ source: :parser
20
25
  )
21
26
  if region.visibility == :module_function
22
27
  pins.push Solargraph::Pin::Method.new(
23
28
  location: methpin.location,
24
29
  closure: methpin.closure,
25
30
  name: methpin.name,
31
+ context: method_context,
26
32
  comments: methpin.comments,
27
33
  scope: :class,
28
34
  visibility: :public,
29
35
  parameters: methpin.parameters,
30
36
  node: methpin.node,
31
- source: :parser,
37
+ source: :parser
32
38
  )
33
39
  pins.push Solargraph::Pin::Method.new(
34
40
  location: methpin.location,
35
41
  closure: methpin.closure,
36
42
  name: methpin.name,
43
+ context: method_context,
37
44
  comments: methpin.comments,
38
45
  scope: :instance,
39
46
  visibility: :private,
40
47
  parameters: methpin.parameters,
41
48
  node: methpin.node,
42
- source: :parser,
49
+ source: :parser
43
50
  )
44
51
  else
45
52
  pins.push methpin
@@ -1,37 +1,38 @@
1
- # frozen_string_literal: true
2
-
3
- module Solargraph
4
- module Parser
5
- module ParserGem
6
- module NodeProcessors
7
- class DefsNode < DefNode
8
- include ParserGem::NodeMethods
9
-
10
- def process
11
- s_visi = region.visibility
12
- s_visi = :public if s_visi == :module_function || region.scope != :class
13
- loc = get_node_location(node)
14
- if node.children[0].is_a?(AST::Node) && node.children[0].type == :self
15
- closure = region.closure
16
- else
17
- closure = Solargraph::Pin::Namespace.new(
18
- name: unpack_name(node.children[0])
19
- )
20
- end
21
- pins.push Solargraph::Pin::Method.new(
22
- location: loc,
23
- closure: closure,
24
- name: node.children[1].to_s,
25
- comments: comments_for(node),
26
- scope: :class,
27
- visibility: s_visi,
28
- node: node,
29
- source: :parser,
30
- )
31
- process_children region.update(closure: pins.last, scope: :class)
32
- end
33
- end
34
- end
35
- end
36
- end
37
- end
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Parser
5
+ module ParserGem
6
+ module NodeProcessors
7
+ class DefsNode < DefNode
8
+ include ParserGem::NodeMethods
9
+
10
+ def process
11
+ s_visi = region.visibility
12
+ s_visi = :public if s_visi == :module_function || region.scope != :class
13
+ loc = get_node_location(node)
14
+ closure = if node.children[0].is_a?(AST::Node) && node.children[0].type == :self
15
+ region.closure
16
+ else
17
+ Solargraph::Pin::Namespace.new(
18
+ name: unpack_name(node.children[0]),
19
+ source: :parser
20
+ )
21
+ end
22
+ pins.push Solargraph::Pin::Method.new(
23
+ location: loc,
24
+ closure: closure,
25
+ name: node.children[1].to_s,
26
+ comments: comments_for(node),
27
+ scope: :class,
28
+ visibility: s_visi,
29
+ node: node,
30
+ source: :parser
31
+ )
32
+ process_children region.update(closure: pins.last, scope: :class)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -8,13 +8,43 @@ module Solargraph
8
8
  include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
- process_children
11
+ FlowSensitiveTyping.new(locals,
12
+ ivars,
13
+ enclosing_breakable_pin,
14
+ enclosing_compound_statement_pin).process_if(node)
15
+ condition_node = node.children[0]
16
+ if condition_node
17
+ pins.push Solargraph::Pin::CompoundStatement.new(
18
+ location: get_node_location(condition_node),
19
+ closure: region.closure,
20
+ node: condition_node,
21
+ source: :parser
22
+ )
23
+ NodeProcessor.process(condition_node, region, pins, locals, ivars)
24
+ end
25
+ then_node = node.children[1]
26
+ if then_node
27
+ pins.push Solargraph::Pin::CompoundStatement.new(
28
+ location: get_node_location(then_node),
29
+ closure: region.closure,
30
+ node: then_node,
31
+ source: :parser
32
+ )
33
+ NodeProcessor.process(then_node, region, pins, locals, ivars)
34
+ end
12
35
 
13
- position = get_node_start_position(node)
14
- # @sg-ignore
15
- # @type [Solargraph::Pin::Breakable, nil]
16
- enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last
17
- FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_if(node)
36
+ else_node = node.children[2]
37
+ if else_node
38
+ pins.push Solargraph::Pin::CompoundStatement.new(
39
+ location: get_node_location(else_node),
40
+ closure: region.closure,
41
+ node: else_node,
42
+ source: :parser
43
+ )
44
+ NodeProcessor.process(else_node, region, pins, locals, ivars)
45
+ end
46
+
47
+ true
18
48
  end
19
49
  end
20
50
  end