solargraph 0.56.0 → 0.58.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 (157) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +2 -0
  3. data/.github/workflows/linting.yml +127 -0
  4. data/.github/workflows/plugins.yml +183 -7
  5. data/.github/workflows/rspec.yml +55 -5
  6. data/.github/workflows/typecheck.yml +6 -3
  7. data/.gitignore +5 -0
  8. data/.overcommit.yml +72 -0
  9. data/.rspec +1 -0
  10. data/.rubocop.yml +66 -0
  11. data/.rubocop_todo.yml +1279 -0
  12. data/.yardopts +1 -0
  13. data/CHANGELOG.md +86 -1
  14. data/README.md +8 -4
  15. data/Rakefile +125 -13
  16. data/bin/solargraph +3 -0
  17. data/lib/solargraph/api_map/cache.rb +3 -2
  18. data/lib/solargraph/api_map/constants.rb +279 -0
  19. data/lib/solargraph/api_map/index.rb +49 -31
  20. data/lib/solargraph/api_map/source_to_yard.rb +13 -4
  21. data/lib/solargraph/api_map/store.rb +144 -26
  22. data/lib/solargraph/api_map.rb +217 -245
  23. data/lib/solargraph/bench.rb +1 -0
  24. data/lib/solargraph/complex_type/type_methods.rb +6 -0
  25. data/lib/solargraph/complex_type/unique_type.rb +19 -12
  26. data/lib/solargraph/complex_type.rb +24 -3
  27. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  28. data/lib/solargraph/convention/base.rb +17 -0
  29. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
  30. data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
  31. data/lib/solargraph/convention/data_definition.rb +105 -0
  32. data/lib/solargraph/convention/gemspec.rb +3 -2
  33. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
  34. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -2
  35. data/lib/solargraph/convention/struct_definition.rb +87 -24
  36. data/lib/solargraph/convention.rb +32 -2
  37. data/lib/solargraph/diagnostics/rubocop.rb +6 -1
  38. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  39. data/lib/solargraph/doc_map.rb +52 -18
  40. data/lib/solargraph/environ.rb +9 -2
  41. data/lib/solargraph/equality.rb +1 -0
  42. data/lib/solargraph/gem_pins.rb +21 -11
  43. data/lib/solargraph/language_server/host/dispatch.rb +2 -0
  44. data/lib/solargraph/language_server/host/message_worker.rb +3 -0
  45. data/lib/solargraph/language_server/host.rb +12 -5
  46. data/lib/solargraph/language_server/message/base.rb +2 -1
  47. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
  48. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
  49. data/lib/solargraph/language_server/message/text_document/formatting.rb +19 -2
  50. data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
  51. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  52. data/lib/solargraph/language_server/progress.rb +8 -0
  53. data/lib/solargraph/language_server/request.rb +4 -1
  54. data/lib/solargraph/library.rb +50 -33
  55. data/lib/solargraph/location.rb +3 -0
  56. data/lib/solargraph/logging.rb +11 -2
  57. data/lib/solargraph/page.rb +3 -0
  58. data/lib/solargraph/parser/comment_ripper.rb +8 -1
  59. data/lib/solargraph/parser/flow_sensitive_typing.rb +33 -5
  60. data/lib/solargraph/parser/node_processor/base.rb +10 -5
  61. data/lib/solargraph/parser/node_processor.rb +24 -8
  62. data/lib/solargraph/parser/parser_gem/class_methods.rb +3 -13
  63. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  64. data/lib/solargraph/parser/parser_gem/node_chainer.rb +3 -1
  65. data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -16
  66. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +1 -0
  67. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +3 -2
  68. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
  69. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +2 -0
  70. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +7 -1
  71. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
  72. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +65 -8
  73. data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
  74. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +1 -0
  75. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +12 -3
  76. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +36 -16
  77. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
  78. data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
  79. data/lib/solargraph/parser/region.rb +3 -0
  80. data/lib/solargraph/parser/snippet.rb +2 -0
  81. data/lib/solargraph/pin/base.rb +92 -14
  82. data/lib/solargraph/pin/base_variable.rb +6 -5
  83. data/lib/solargraph/pin/block.rb +3 -2
  84. data/lib/solargraph/pin/callable.rb +14 -1
  85. data/lib/solargraph/pin/closure.rb +5 -7
  86. data/lib/solargraph/pin/common.rb +6 -2
  87. data/lib/solargraph/pin/constant.rb +2 -0
  88. data/lib/solargraph/pin/local_variable.rb +1 -2
  89. data/lib/solargraph/pin/method.rb +32 -11
  90. data/lib/solargraph/pin/method_alias.rb +3 -0
  91. data/lib/solargraph/pin/parameter.rb +24 -10
  92. data/lib/solargraph/pin/proxy_type.rb +5 -1
  93. data/lib/solargraph/pin/reference/override.rb +15 -1
  94. data/lib/solargraph/pin/reference/superclass.rb +5 -0
  95. data/lib/solargraph/pin/reference.rb +17 -0
  96. data/lib/solargraph/pin/search.rb +6 -1
  97. data/lib/solargraph/pin/signature.rb +2 -0
  98. data/lib/solargraph/pin/symbol.rb +5 -0
  99. data/lib/solargraph/pin_cache.rb +64 -4
  100. data/lib/solargraph/position.rb +3 -0
  101. data/lib/solargraph/range.rb +5 -0
  102. data/lib/solargraph/rbs_map/conversions.rb +68 -18
  103. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  104. data/lib/solargraph/rbs_map/core_map.rb +14 -7
  105. data/lib/solargraph/rbs_map.rb +14 -1
  106. data/lib/solargraph/shell.rb +85 -1
  107. data/lib/solargraph/source/chain/call.rb +7 -3
  108. data/lib/solargraph/source/chain/constant.rb +3 -66
  109. data/lib/solargraph/source/chain/if.rb +1 -1
  110. data/lib/solargraph/source/chain/link.rb +11 -2
  111. data/lib/solargraph/source/chain/or.rb +1 -1
  112. data/lib/solargraph/source/chain.rb +11 -2
  113. data/lib/solargraph/source/change.rb +2 -2
  114. data/lib/solargraph/source/cursor.rb +2 -3
  115. data/lib/solargraph/source/encoding_fixes.rb +23 -23
  116. data/lib/solargraph/source/source_chainer.rb +1 -1
  117. data/lib/solargraph/source.rb +6 -3
  118. data/lib/solargraph/source_map/clip.rb +18 -26
  119. data/lib/solargraph/source_map/data.rb +4 -0
  120. data/lib/solargraph/source_map/mapper.rb +2 -2
  121. data/lib/solargraph/source_map.rb +28 -16
  122. data/lib/solargraph/type_checker/param_def.rb +2 -0
  123. data/lib/solargraph/type_checker/rules.rb +30 -8
  124. data/lib/solargraph/type_checker.rb +301 -186
  125. data/lib/solargraph/version.rb +5 -5
  126. data/lib/solargraph/workspace/config.rb +22 -6
  127. data/lib/solargraph/workspace/require_paths.rb +97 -0
  128. data/lib/solargraph/workspace.rb +38 -67
  129. data/lib/solargraph/yard_map/helpers.rb +29 -1
  130. data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
  131. data/lib/solargraph/yard_map/mapper/to_method.rb +5 -9
  132. data/lib/solargraph/yard_map/mapper/to_namespace.rb +8 -7
  133. data/lib/solargraph/yard_map/to_method.rb +2 -1
  134. data/lib/solargraph/yardoc.rb +41 -3
  135. data/lib/solargraph.rb +15 -0
  136. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  137. data/rbs/fills/open3/0/open3.rbs +172 -0
  138. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  139. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  140. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  141. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  142. data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
  143. data/rbs_collection.yaml +4 -4
  144. data/sig/shims/ast/0/node.rbs +5 -0
  145. data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
  146. data/sig/shims/ast/2.4/ast.rbs +73 -0
  147. data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  148. data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
  149. data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
  150. data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  151. data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  152. data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
  153. data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
  154. data/solargraph.gemspec +26 -5
  155. metadata +187 -15
  156. data/lib/.rubocop.yml +0 -22
  157. data/lib/solargraph/parser/node_methods.rb +0 -97
@@ -13,7 +13,7 @@ module Solargraph
13
13
  # @return [Array<Pin::Base>]
14
14
  attr_reader :pins
15
15
 
16
- # @return [Array<Pin::BaseVariable>]
16
+ # @return [Array<Pin::LocalVariable>]
17
17
  attr_reader :locals
18
18
 
19
19
  # @param node [Parser::AST::Node]
@@ -30,9 +30,12 @@ module Solargraph
30
30
 
31
31
  # Subclasses should override this method to generate new pins.
32
32
  #
33
- # @return [void]
33
+ # @return [Boolean] continue processing the next processor of the same node type.
34
+ # @return [void] In case there is only one processor registered for the node type, it can be void.
34
35
  def process
35
36
  process_children
37
+
38
+ true
36
39
  end
37
40
 
38
41
  private
@@ -64,7 +67,9 @@ module Solargraph
64
67
  # @param position [Solargraph::Position]
65
68
  # @return [Pin::Closure, nil]
66
69
  def named_path_pin position
67
- pins.select{|pin| pin.is_a?(Pin::Closure) && pin.path && !pin.path.empty? && pin.location.range.contain?(position)}.last
70
+ pins.select do |pin|
71
+ pin.is_a?(Pin::Closure) && pin.path && !pin.path.empty? && pin.location.range.contain?(position)
72
+ end.last
68
73
  end
69
74
 
70
75
  # @todo Candidate for deprecation
@@ -72,14 +77,14 @@ module Solargraph
72
77
  # @return [Pin::Closure, nil]
73
78
  def block_pin position
74
79
  # @todo determine if this can return a Pin::Block
75
- pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
80
+ pins.select { |pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position) }.last
76
81
  end
77
82
 
78
83
  # @todo Candidate for deprecation
79
84
  # @param position [Solargraph::Position]
80
85
  # @return [Pin::Closure, nil]
81
86
  def closure_pin position
82
- pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
87
+ pins.select { |pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position) }.last
83
88
  end
84
89
  end
85
90
  end
@@ -9,16 +9,26 @@ module Solargraph
9
9
  autoload :Base, 'solargraph/parser/node_processor/base'
10
10
 
11
11
  class << self
12
- # @type [Hash{Symbol => Class<NodeProcessor::Base>}]
12
+ # @type [Hash{Symbol => Array<Class<NodeProcessor::Base>>}]
13
13
  @@processors ||= {}
14
14
 
15
- # Register a processor for a node type.
15
+ # Register a processor for a node type. You can register multiple processors for the same type.
16
+ # If a node processor returns true, it will skip the next processor of the same node type.
16
17
  #
17
18
  # @param type [Symbol]
18
19
  # @param cls [Class<NodeProcessor::Base>]
19
- # @return [Class<NodeProcessor::Base>]
20
+ # @return [Array<Class<NodeProcessor::Base>>]
20
21
  def register type, cls
21
- @@processors[type] = cls
22
+ @@processors[type] ||= []
23
+ @@processors[type] << cls
24
+ end
25
+
26
+ # @param type [Symbol]
27
+ # @param cls [Class<NodeProcessor::Base>]
28
+ #
29
+ # @return [void]
30
+ def deregister type, cls
31
+ @@processors[type].delete(cls)
22
32
  end
23
33
  end
24
34
 
@@ -36,10 +46,16 @@ module Solargraph
36
46
  )
37
47
  end
38
48
  return [pins, locals] unless Parser.is_ast_node?(node)
39
- klass = @@processors[node.type] || NodeProcessor::Base
40
- processor = klass.new(node, region, pins, locals)
41
- processor.process
42
- [processor.pins, processor.locals]
49
+ node_processor_classes = @@processors[node.type] || [NodeProcessor::Base]
50
+
51
+ node_processor_classes.each do |klass|
52
+ processor = klass.new(node, region, pins, locals)
53
+ process_next = processor.process
54
+
55
+ break unless process_next
56
+ end
57
+
58
+ [pins, locals]
43
59
  end
44
60
  end
45
61
  end
@@ -2,22 +2,13 @@
2
2
 
3
3
  require 'prism'
4
4
 
5
- # Awaiting ability to use a version containing https://github.com/whitequark/parser/pull/1076
6
- #
7
- # @!parse
8
- # class ::Parser::Base < ::Parser::Builder
9
- # # @return [Integer]
10
- # def version; end
11
- # end
12
- # class ::Parser::CurrentRuby < ::Parser::Base; end
13
-
14
5
  module Solargraph
15
6
  module Parser
16
7
  module ParserGem
17
8
  module ClassMethods
18
9
  # @param code [String]
19
10
  # @param filename [String, nil]
20
- # @return [Array(Parser::AST::Node, Hash{Integer => String})]
11
+ # @return [Array(Parser::AST::Node, Hash{Integer => Solargraph::Parser::Snippet})]
21
12
  def parse_with_comments code, filename = nil
22
13
  node = parse(code, filename)
23
14
  comments = CommentRipper.new(code, filename, 0).parse
@@ -84,6 +75,7 @@ module Solargraph
84
75
  # @param top [AST::Node]
85
76
  # @return [Array<AST::Node>]
86
77
  def inner_node_references name, top
78
+ # @type [Array<AST::Node>]
87
79
  result = []
88
80
  if top.is_a?(AST::Node) && top.to_s.include?(":#{name}")
89
81
  result.push top if top.children.any? { |c| c.to_s == name }
@@ -137,9 +129,7 @@ module Solargraph
137
129
  def string_ranges node
138
130
  return [] unless is_ast_node?(node)
139
131
  result = []
140
- if node.type == :str
141
- result.push Range.from_node(node)
142
- end
132
+ result.push Range.from_node(node) if node.type == :str
143
133
  node.children.each do |child|
144
134
  result.concat string_ranges(child)
145
135
  end
@@ -9,6 +9,7 @@ module Solargraph
9
9
  class FlawedBuilder < ::Parser::Builders::Default
10
10
  # @param token [::Parser::AST::Node]
11
11
  # @return [String]
12
+ # @sg-ignore
12
13
  def string_value(token)
13
14
  value(token)
14
15
  end
@@ -7,6 +7,7 @@ module Solargraph
7
7
  #
8
8
  class NodeChainer
9
9
  include NodeMethods
10
+
10
11
  Chain = Source::Chain
11
12
 
12
13
  # @param node [Parser::AST::Node]
@@ -98,7 +99,8 @@ module Solargraph
98
99
  elsif [:gvar, :gvasgn].include?(n.type)
99
100
  result.push Chain::GlobalVariable.new(n.children[0].to_s)
100
101
  elsif n.type == :or_asgn
101
- result.concat generate_links n.children[1]
102
+ new_node = n.updated(n.children[0].type, n.children[0].children + [n.children[1]])
103
+ result.concat generate_links new_node
102
104
  elsif [:class, :module, :def, :defs].include?(n.type)
103
105
  # @todo Undefined or what?
104
106
  result.push Chain::UNDEFINED_CALL
@@ -3,20 +3,6 @@
3
3
  require 'parser'
4
4
  require 'ast'
5
5
 
6
- # Teach AST::Node#children about its generic type
7
- #
8
- # @todo contribute back to https://github.com/ruby/gem_rbs_collection/blob/main/gems/ast/2.4/ast.rbs
9
- #
10
- # @!parse
11
- # module ::AST
12
- # class Node
13
- # # New children
14
- #
15
- # # @return [Array<self, Integer, String, Symbol, nil>]
16
- # attr_reader :children
17
- # end
18
- # end
19
-
20
6
  # https://github.com/whitequark/parser
21
7
  module Solargraph
22
8
  module Parser
@@ -120,7 +106,7 @@ module Solargraph
120
106
  end
121
107
 
122
108
  # @param node [Parser::AST::Node]
123
- # @return [Hash{Parser::AST::Node => Chain}]
109
+ # @return [Hash{Symbol => Chain}]
124
110
  def convert_hash node
125
111
  return {} unless Parser.is_ast_node?(node)
126
112
  return convert_hash(node.children[0]) if node.type == :kwsplat
@@ -133,6 +119,7 @@ module Solargraph
133
119
  result
134
120
  end
135
121
 
122
+ # @sg-ignore Wrong argument type for AST::Node.new: type expected AST::_ToSym, received :nil
136
123
  NIL_NODE = ::Parser::AST::Node.new(:nil)
137
124
 
138
125
  # @param node [Parser::AST::Node]
@@ -179,6 +166,7 @@ module Solargraph
179
166
  node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
180
167
  elsif node.type == :send
181
168
  result.push node
169
+ result.concat call_nodes_from(node.children.first)
182
170
  node.children[2..-1].each { |child| result.concat call_nodes_from(child) }
183
171
  elsif [:super, :zsuper].include?(node.type)
184
172
  result.push node
@@ -232,6 +220,7 @@ module Solargraph
232
220
  else
233
221
  source.tree_at(position.line, position.column - 1)
234
222
  end
223
+ # @type [AST::Node, nil]
235
224
  prev = nil
236
225
  tree.each do |node|
237
226
  if node.type == :send
@@ -242,7 +231,7 @@ module Solargraph
242
231
  if source.synchronized?
243
232
  return node if source.code[0..offset-1] =~ /\(\s*\z/ && source.code[offset..-1] =~ /^\s*\)/
244
233
  else
245
- return node if source.code[0..offset-1] =~ /\([^\(]*\z/
234
+ return node if source.code[0..offset-1] =~ /\([^(]*\z/
246
235
  end
247
236
  end
248
237
  end
@@ -11,6 +11,7 @@ module Solargraph
11
11
  process_children
12
12
 
13
13
  position = get_node_start_position(node)
14
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1114
14
15
  enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last
15
16
  FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_and(node)
16
17
  end
@@ -19,7 +19,7 @@ module Solargraph
19
19
  else
20
20
  region.closure
21
21
  end
22
- pins.push Solargraph::Pin::Block.new(
22
+ block_pin = Solargraph::Pin::Block.new(
23
23
  location: location,
24
24
  closure: parent,
25
25
  node: node,
@@ -28,7 +28,8 @@ module Solargraph
28
28
  scope: region.scope || region.closure.context.scope,
29
29
  source: :parser
30
30
  )
31
- process_children region.update(closure: pins.last)
31
+ pins.push block_pin
32
+ process_children region.update(closure: block_pin)
32
33
  end
33
34
 
34
35
  private
@@ -8,17 +8,6 @@ module Solargraph
8
8
  include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
- if Convention::StructDefinition::StructAssignmentNode.valid?(node)
12
- process_struct_assignment
13
- else
14
- process_constant_assignment
15
- end
16
- end
17
-
18
- private
19
-
20
- # @return [void]
21
- def process_constant_assignment
22
11
  pins.push Solargraph::Pin::Constant.new(
23
12
  location: get_node_location(node),
24
13
  closure: region.closure,
@@ -30,16 +19,7 @@ module Solargraph
30
19
  process_children
31
20
  end
32
21
 
33
- # @todo Move this out of [CasgnNode] once [Solargraph::Parser::NodeProcessor] supports
34
- # multiple processors.
35
- def process_struct_assignment
36
- processor_klass = Convention::StructDefinition::NodeProcessors::StructNode
37
- processor = processor_klass.new(node, region, pins, locals)
38
- processor.process
39
-
40
- @pins = processor.pins
41
- @locals = processor.locals
42
- end
22
+ private
43
23
 
44
24
  # @return [String]
45
25
  def const_name
@@ -11,6 +11,8 @@ module Solargraph
11
11
  process_children
12
12
 
13
13
  position = get_node_start_position(node)
14
+ # @sg-ignore
15
+ # @type [Solargraph::Pin::Breakable, nil]
14
16
  enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last
15
17
  FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_if(node)
16
18
  end
@@ -7,6 +7,7 @@ module Solargraph
7
7
  class MasgnNode < Parser::NodeProcessor::Base
8
8
  include ParserGem::NodeMethods
9
9
 
10
+ # @return [void]
10
11
  def process
11
12
  # Example:
12
13
  #
@@ -21,8 +22,11 @@ module Solargraph
21
22
  # s(:int, 2),
22
23
  # s(:int, 3)))
23
24
  masgn = node
25
+ # @type [Parser::AST::Node]
24
26
  mlhs = masgn.children.fetch(0)
27
+ # @type [Array<Parser::AST::Node>]
25
28
  lhs_arr = mlhs.children
29
+ # @type [Parser::AST::Node]
26
30
  mass_rhs = node.children.fetch(1)
27
31
 
28
32
  # Get pins created for the mlhs node
@@ -40,7 +44,9 @@ module Solargraph
40
44
  # @todo in line below, nothing in typechecking alerts
41
45
  # when a non-existant method is called on 'l'
42
46
  if pin.nil?
43
- Solargraph.logger.debug { "Could not find local for masgn= value in location #{location.inspect} in #{lhs_arr} - masgn = #{masgn}, lhs.type = #{lhs.type}" }
47
+ Solargraph.logger.debug do
48
+ "Could not find local for masgn= value in location #{location.inspect} in #{lhs_arr} - masgn = #{masgn}, lhs.type = #{lhs.type}"
49
+ end
44
50
  next
45
51
  end
46
52
  pin.mass_assignment = [mass_rhs, i]
@@ -11,17 +11,6 @@ module Solargraph
11
11
  superclass_name = nil
12
12
  superclass_name = unpack_name(node.children[1]) if node.type == :class && node.children[1]&.type == :const
13
13
 
14
- if Convention::StructDefinition::StructDefintionNode.valid?(node)
15
- process_struct_definition
16
- else
17
- process_namespace(superclass_name)
18
- end
19
- end
20
-
21
- private
22
-
23
- # @param superclass_name [String, nil]
24
- def process_namespace(superclass_name)
25
14
  loc = get_node_location(node)
26
15
  nspin = Solargraph::Pin::Namespace.new(
27
16
  type: node.type,
@@ -44,17 +33,6 @@ module Solargraph
44
33
  end
45
34
  process_children region.update(closure: nspin, visibility: :public)
46
35
  end
47
-
48
- # @todo Move this out of [NamespaceNode] once [Solargraph::Parser::NodeProcessor] supports
49
- # multiple processors.
50
- def process_struct_definition
51
- processor_klass = Convention::StructDefinition::NodeProcessors::StructNode
52
- processor = processor_klass.new(node, region, pins, locals)
53
- processor.process
54
-
55
- @pins = processor.pins
56
- @locals = processor.locals
57
- end
58
36
  end
59
37
  end
60
38
  end
@@ -7,15 +7,72 @@ module Solargraph
7
7
  module ParserGem
8
8
  module NodeProcessors
9
9
  class OpasgnNode < Parser::NodeProcessor::Base
10
+ # @return [void]
10
11
  def process
11
- # Parser::CurrentRuby.parse("a += 2")
12
- # => s(:op_asgn,
13
- # s(:lvasgn, :a), :+,
14
- # s(:int, 2))
15
- asgn = node.children[0]
16
- variable_name = asgn.children[0]
12
+ target = node.children[0]
17
13
  operator = node.children[1]
18
14
  argument = node.children[2]
15
+ if target.type == :send
16
+ # @sg-ignore Need a downcast here
17
+ process_send_target(target, operator, argument)
18
+ elsif target.type.to_s.end_with?('vasgn')
19
+ # @sg-ignore Need a downcast here
20
+ process_vasgn_target(target, operator, argument)
21
+ else
22
+ Solargraph.assert_or_log(:opasgn_unknown_target,
23
+ "Unexpected op_asgn target type: #{target.type}")
24
+ end
25
+ end
26
+
27
+ # @param call [Parser::AST::Node] the target of the assignment
28
+ # @param operator [Symbol] the operator, e.g. :+
29
+ # @param argument [Parser::AST::Node] the argument of the operation
30
+ #
31
+ # @return [void]
32
+ def process_send_target call, operator, argument
33
+ # if target is a call:
34
+ # [10] pry(main)> Parser::CurrentRuby.parse("Foo.bar += baz")
35
+ # => s(:op_asgn,
36
+ # s(:send, # call
37
+ # s(:const, nil, :Foo), # calee
38
+ # :bar), # call_method
39
+ # :+, # operator
40
+ # s(:send, nil, :baz)) # argument
41
+ # [11] pry(main)>
42
+ callee = call.children[0]
43
+ call_method = call.children[1]
44
+ asgn_method = :"#{call_method}="
45
+
46
+ # [8] pry(main)> Parser::CurrentRuby.parse("Foo.bar = Foo.bar + baz")
47
+ # => s(:send,
48
+ # s(:const, nil, :Foo), # callee
49
+ # :bar=, # asgn_method
50
+ # s(:send,
51
+ # s(:send,
52
+ # s(:const, nil, :Foo), # callee
53
+ # :bar), # call_method
54
+ # :+, # operator
55
+ # s(:send, nil, :baz))) # argument
56
+ new_send = node.updated(:send,
57
+ [callee,
58
+ asgn_method,
59
+ node.updated(:send, [call, operator, argument])])
60
+ NodeProcessor.process(new_send, region, pins, locals)
61
+ end
62
+
63
+ # @param asgn [Parser::AST::Node] the target of the assignment
64
+ # @param operator [Symbol] the operator, e.g. :+
65
+ # @param argument [Parser::AST::Node] the argument of the operation
66
+ #
67
+ # @return [void]
68
+ def process_vasgn_target asgn, operator, argument
69
+ # => s(:op_asgn,
70
+ # s(:lvasgn, :a), # asgn
71
+ # :+, # operator
72
+ # s(:int, 2)) # argument
73
+
74
+ # @type [Parser::AST::Node]
75
+ variable_name = asgn.children[0]
19
76
  # for lvasgn, gvasgn, cvasgn, convert to lvar, gvar, cvar
20
77
  # [6] pry(main)> Parser::CurrentRuby.parse("a = a + 1")
21
78
  # => s(:lvasgn, :a,
@@ -24,9 +81,9 @@ module Solargraph
24
81
  # s(:int, 1)))
25
82
  # [7] pry(main)>
26
83
  variable_reference_type = asgn.type.to_s.sub(/vasgn$/, 'var').to_sym
27
- variable_reference = node.updated(variable_reference_type, asgn.children)
84
+ target_reference = node.updated(variable_reference_type, asgn.children)
28
85
  send_children = [
29
- variable_reference,
86
+ target_reference,
30
87
  operator,
31
88
  argument
32
89
  ]
@@ -5,6 +5,7 @@ module Solargraph
5
5
  module ParserGem
6
6
  module NodeProcessors
7
7
  class OrasgnNode < Parser::NodeProcessor::Base
8
+ # @return [void]
8
9
  def process
9
10
  new_node = node.updated(node.children[0].type, node.children[0].children + [node.children[1]])
10
11
  NodeProcessor.process(new_node, region, pins, locals)
@@ -7,6 +7,7 @@ module Solargraph
7
7
  class ResbodyNode < Parser::NodeProcessor::Base
8
8
  include ParserGem::NodeMethods
9
9
 
10
+ # @return [void]
10
11
  def process
11
12
  if node.children[1] # Exception local variable name
12
13
  here = get_node_start_position(node.children[1])
@@ -7,9 +7,18 @@ module Solargraph
7
7
  class SclassNode < Parser::NodeProcessor::Base
8
8
  def process
9
9
  sclass = node.children[0]
10
- if sclass.is_a?(AST::Node) && sclass.type == :self
10
+ # @todo Changing Parser::AST::Node to AST::Node below will
11
+ # cause type errors at strong level because the combined
12
+ # pin for AST::Node#children has return type
13
+ # "Array<AST::Node>, Array". YARD annotations in AST
14
+ # provided the Array, RBS for Array<AST::Node>. We
15
+ # should probably have a rule to combine "A, A<T>""
16
+ # types to "A<T>" if the "A" comes from YARD, with the
17
+ # rationale that folks tend to be less formal with types in
18
+ # YARD.
19
+ if sclass.is_a?(::Parser::AST::Node) && sclass.type == :self
11
20
  closure = region.closure
12
- elsif sclass.is_a?(AST::Node) && sclass.type == :casgn
21
+ elsif sclass.is_a?(::Parser::AST::Node) && sclass.type == :casgn
13
22
  names = [region.closure.namespace, region.closure.name]
14
23
  if sclass.children[0].nil? && names.last != sclass.children[1].to_s
15
24
  names << sclass.children[1].to_s
@@ -18,7 +27,7 @@ module Solargraph
18
27
  end
19
28
  name = names.reject(&:empty?).join('::')
20
29
  closure = Solargraph::Pin::Namespace.new(name: name, location: region.closure.location, source: :parser)
21
- elsif sclass.is_a?(AST::Node) && sclass.type == :const
30
+ elsif sclass.is_a?(::Parser::AST::Node) && sclass.type == :const
22
31
  names = [region.closure.namespace, region.closure.name]
23
32
  also = NodeMethods.unpack_name(sclass)
24
33
  if also != region.closure.name
@@ -8,32 +8,41 @@ module Solargraph
8
8
  include ParserGem::NodeMethods
9
9
 
10
10
  def process
11
+ # @sg-ignore Variable type could not be inferred for method_name
12
+ # @type [Symbol]
13
+ method_name = node.children[1]
14
+ # :nocov:
15
+ unless method_name.instance_of?(Symbol)
16
+ Solargraph.assert_or_log(:parser_method_name, "Expected method name to be a Symbol, got #{method_name.class} for node #{node.inspect}")
17
+ return process_children
18
+ end
19
+ # :nocov:
11
20
  if node.children[0].nil?
12
- if [:private, :public, :protected].include?(node.children[1])
21
+ if [:private, :public, :protected].include?(method_name)
13
22
  process_visibility
14
- elsif node.children[1] == :module_function
23
+ elsif method_name == :module_function
15
24
  process_module_function
16
- elsif [:attr_reader, :attr_writer, :attr_accessor].include?(node.children[1])
25
+ elsif [:attr_reader, :attr_writer, :attr_accessor].include?(method_name)
17
26
  process_attribute
18
- elsif node.children[1] == :include
27
+ elsif method_name == :include
19
28
  process_include
20
- elsif node.children[1] == :extend
29
+ elsif method_name == :extend
21
30
  process_extend
22
- elsif node.children[1] == :prepend
31
+ elsif method_name == :prepend
23
32
  process_prepend
24
- elsif node.children[1] == :require
33
+ elsif method_name == :require
25
34
  process_require
26
- elsif node.children[1] == :autoload
35
+ elsif method_name == :autoload
27
36
  process_autoload
28
- elsif node.children[1] == :private_constant
37
+ elsif method_name == :private_constant
29
38
  process_private_constant
30
- elsif node.children[1] == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
39
+ elsif method_name == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
31
40
  process_alias_method
32
- elsif node.children[1] == :private_class_method && node.children[2].is_a?(AST::Node)
41
+ elsif method_name == :private_class_method && node.children[2].is_a?(AST::Node)
33
42
  # Processing a private class can potentially handle children on its own
34
43
  return if process_private_class_method
35
44
  end
36
- elsif node.children[1] == :require && node.children[0].to_s == '(const nil :Bundler)'
45
+ elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)'
37
46
  pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser)
38
47
  end
39
48
  process_children
@@ -45,15 +54,24 @@ module Solargraph
45
54
  def process_visibility
46
55
  if (node.children.length > 2)
47
56
  node.children[2..-1].each do |child|
48
- if child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
57
+ # @sg-ignore Variable type could not be inferred for method_name
58
+ # @type [Symbol]
59
+ visibility = node.children[1]
60
+ # :nocov:
61
+ unless visibility.instance_of?(Symbol)
62
+ Solargraph.assert_or_log(:parser_visibility, "Expected visibility name to be a Symbol, got #{visibility.class} for node #{node.inspect}")
63
+ return process_children
64
+ end
65
+ # :nocov:
66
+ if child.is_a?(::Parser::AST::Node) && (child.type == :sym || child.type == :str)
49
67
  name = child.children[0].to_s
50
68
  matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
51
69
  matches.each do |pin|
52
70
  # @todo Smelly instance variable access
53
- pin.instance_variable_set(:@visibility, node.children[1])
71
+ pin.instance_variable_set(:@visibility, visibility)
54
72
  end
55
73
  else
56
- process_children region.update(visibility: node.children[1])
74
+ process_children region.update(visibility: visibility)
57
75
  end
58
76
  end
59
77
  else
@@ -177,7 +195,7 @@ module Solargraph
177
195
  elsif node.children[2].type == :sym || node.children[2].type == :str
178
196
  node.children[2..-1].each do |x|
179
197
  cn = x.children[0].to_s
180
- # @type [Pin::Method]
198
+ # @type [Pin::Method, nil]
181
199
  ref = pins.find { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn }
182
200
  unless ref.nil?
183
201
  pins.delete ref
@@ -210,6 +228,7 @@ module Solargraph
210
228
  closure: cm,
211
229
  name: ivar.name,
212
230
  comments: ivar.comments,
231
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1114
213
232
  assignment: ivar.assignment,
214
233
  source: :parser
215
234
  )
@@ -218,6 +237,7 @@ module Solargraph
218
237
  closure: mm,
219
238
  name: ivar.name,
220
239
  comments: ivar.comments,
240
+ # @sg-ignore https://github.com/castwide/solargraph/pull/1114
221
241
  assignment: ivar.assignment,
222
242
  source: :parser
223
243
  )
@@ -5,6 +5,7 @@ module Solargraph
5
5
  module ParserGem
6
6
  module NodeProcessors
7
7
  class SymNode < Parser::NodeProcessor::Base
8
+ # @return [void]
8
9
  def process
9
10
  pins.push Solargraph::Pin::Symbol.new(
10
11
  get_node_location(node),
@@ -42,6 +42,8 @@ module Solargraph
42
42
  register :defs, ParserGem::NodeProcessors::DefsNode
43
43
  register :if, ParserGem::NodeProcessors::IfNode
44
44
  register :send, ParserGem::NodeProcessors::SendNode
45
+ register :class, Convention::StructDefinition::NodeProcessors::StructNode
46
+ register :class, Convention::DataDefinition::NodeProcessors::DataNode
45
47
  register :class, ParserGem::NodeProcessors::NamespaceNode
46
48
  register :module, ParserGem::NodeProcessors::NamespaceNode
47
49
  register :sclass, ParserGem::NodeProcessors::SclassNode
@@ -49,6 +51,8 @@ module Solargraph
49
51
  register :cvasgn, ParserGem::NodeProcessors::CvasgnNode
50
52
  register :lvasgn, ParserGem::NodeProcessors::LvasgnNode
51
53
  register :gvasgn, ParserGem::NodeProcessors::GvasgnNode
54
+ register :casgn, Convention::StructDefinition::NodeProcessors::StructNode
55
+ register :casgn, Convention::DataDefinition::NodeProcessors::DataNode
52
56
  register :casgn, ParserGem::NodeProcessors::CasgnNode
53
57
  register :masgn, ParserGem::NodeProcessors::MasgnNode
54
58
  register :alias, ParserGem::NodeProcessors::AliasNode