solargraph 0.56.2 → 0.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/linting.yml +127 -0
  3. data/.github/workflows/plugins.yml +183 -7
  4. data/.github/workflows/rspec.yml +55 -5
  5. data/.github/workflows/typecheck.yml +6 -3
  6. data/.gitignore +5 -0
  7. data/.overcommit.yml +72 -0
  8. data/.rspec +1 -0
  9. data/.rubocop.yml +66 -0
  10. data/.rubocop_todo.yml +1279 -0
  11. data/.yardopts +1 -0
  12. data/CHANGELOG.md +69 -0
  13. data/README.md +8 -4
  14. data/Rakefile +125 -13
  15. data/bin/solargraph +8 -5
  16. data/lib/solargraph/api_map/cache.rb +3 -2
  17. data/lib/solargraph/api_map/constants.rb +279 -0
  18. data/lib/solargraph/api_map/index.rb +49 -31
  19. data/lib/solargraph/api_map/source_to_yard.rb +13 -4
  20. data/lib/solargraph/api_map/store.rb +144 -26
  21. data/lib/solargraph/api_map.rb +217 -245
  22. data/lib/solargraph/bench.rb +1 -0
  23. data/lib/solargraph/complex_type/type_methods.rb +6 -0
  24. data/lib/solargraph/complex_type/unique_type.rb +19 -12
  25. data/lib/solargraph/complex_type.rb +24 -3
  26. data/lib/solargraph/convention/active_support_concern.rb +111 -0
  27. data/lib/solargraph/convention/base.rb +17 -0
  28. data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -0
  29. data/lib/solargraph/convention/data_definition/data_definition_node.rb +4 -2
  30. data/lib/solargraph/convention/data_definition.rb +2 -1
  31. data/lib/solargraph/convention/gemspec.rb +1 -1
  32. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -0
  33. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +3 -1
  34. data/lib/solargraph/convention/struct_definition.rb +36 -13
  35. data/lib/solargraph/convention.rb +31 -2
  36. data/lib/solargraph/diagnostics/rubocop.rb +6 -1
  37. data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
  38. data/lib/solargraph/doc_map.rb +44 -13
  39. data/lib/solargraph/environ.rb +9 -2
  40. data/lib/solargraph/equality.rb +1 -0
  41. data/lib/solargraph/gem_pins.rb +21 -11
  42. data/lib/solargraph/language_server/host/dispatch.rb +2 -0
  43. data/lib/solargraph/language_server/host/message_worker.rb +3 -0
  44. data/lib/solargraph/language_server/host.rb +12 -5
  45. data/lib/solargraph/language_server/message/base.rb +2 -1
  46. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
  47. data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
  48. data/lib/solargraph/language_server/message/text_document/formatting.rb +19 -2
  49. data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
  50. data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
  51. data/lib/solargraph/language_server/progress.rb +8 -0
  52. data/lib/solargraph/language_server/request.rb +4 -1
  53. data/lib/solargraph/library.rb +11 -18
  54. data/lib/solargraph/location.rb +3 -0
  55. data/lib/solargraph/logging.rb +11 -2
  56. data/lib/solargraph/page.rb +3 -0
  57. data/lib/solargraph/parser/comment_ripper.rb +8 -1
  58. data/lib/solargraph/parser/flow_sensitive_typing.rb +33 -5
  59. data/lib/solargraph/parser/node_processor/base.rb +1 -1
  60. data/lib/solargraph/parser/node_processor.rb +6 -2
  61. data/lib/solargraph/parser/parser_gem/class_methods.rb +3 -13
  62. data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
  63. data/lib/solargraph/parser/parser_gem/node_chainer.rb +3 -1
  64. data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -16
  65. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +1 -0
  66. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +3 -2
  67. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +2 -0
  68. data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -0
  69. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +64 -8
  70. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +12 -3
  71. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +36 -16
  72. data/lib/solargraph/parser/region.rb +3 -0
  73. data/lib/solargraph/parser/snippet.rb +2 -0
  74. data/lib/solargraph/pin/base.rb +77 -14
  75. data/lib/solargraph/pin/base_variable.rb +6 -5
  76. data/lib/solargraph/pin/block.rb +3 -2
  77. data/lib/solargraph/pin/callable.rb +14 -1
  78. data/lib/solargraph/pin/closure.rb +5 -7
  79. data/lib/solargraph/pin/common.rb +6 -2
  80. data/lib/solargraph/pin/constant.rb +2 -0
  81. data/lib/solargraph/pin/local_variable.rb +1 -2
  82. data/lib/solargraph/pin/method.rb +28 -9
  83. data/lib/solargraph/pin/method_alias.rb +3 -0
  84. data/lib/solargraph/pin/parameter.rb +24 -10
  85. data/lib/solargraph/pin/proxy_type.rb +5 -1
  86. data/lib/solargraph/pin/reference/override.rb +15 -1
  87. data/lib/solargraph/pin/reference/superclass.rb +5 -0
  88. data/lib/solargraph/pin/reference.rb +17 -0
  89. data/lib/solargraph/pin/search.rb +6 -1
  90. data/lib/solargraph/pin/signature.rb +2 -0
  91. data/lib/solargraph/pin/symbol.rb +5 -0
  92. data/lib/solargraph/pin_cache.rb +64 -4
  93. data/lib/solargraph/position.rb +3 -0
  94. data/lib/solargraph/range.rb +5 -0
  95. data/lib/solargraph/rbs_map/conversions.rb +29 -6
  96. data/lib/solargraph/rbs_map/core_fills.rb +18 -0
  97. data/lib/solargraph/rbs_map/core_map.rb +14 -7
  98. data/lib/solargraph/rbs_map.rb +14 -1
  99. data/lib/solargraph/shell.rb +85 -1
  100. data/lib/solargraph/source/chain/call.rb +7 -3
  101. data/lib/solargraph/source/chain/constant.rb +3 -66
  102. data/lib/solargraph/source/chain/if.rb +1 -1
  103. data/lib/solargraph/source/chain/link.rb +11 -2
  104. data/lib/solargraph/source/chain/or.rb +1 -1
  105. data/lib/solargraph/source/chain.rb +11 -2
  106. data/lib/solargraph/source/change.rb +2 -2
  107. data/lib/solargraph/source/cursor.rb +2 -3
  108. data/lib/solargraph/source/source_chainer.rb +1 -1
  109. data/lib/solargraph/source.rb +6 -3
  110. data/lib/solargraph/source_map/clip.rb +18 -26
  111. data/lib/solargraph/source_map/data.rb +4 -0
  112. data/lib/solargraph/source_map/mapper.rb +2 -2
  113. data/lib/solargraph/source_map.rb +28 -16
  114. data/lib/solargraph/type_checker/param_def.rb +2 -0
  115. data/lib/solargraph/type_checker/rules.rb +30 -8
  116. data/lib/solargraph/type_checker.rb +301 -186
  117. data/lib/solargraph/version.rb +1 -1
  118. data/lib/solargraph/workspace/config.rb +21 -5
  119. data/lib/solargraph/workspace/require_paths.rb +97 -0
  120. data/lib/solargraph/workspace.rb +30 -67
  121. data/lib/solargraph/yard_map/mapper/to_method.rb +4 -3
  122. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  123. data/lib/solargraph/yard_map/to_method.rb +2 -1
  124. data/lib/solargraph/yardoc.rb +39 -3
  125. data/lib/solargraph.rb +2 -0
  126. data/rbs/fills/bundler/0/bundler.rbs +4271 -0
  127. data/rbs/fills/open3/0/open3.rbs +172 -0
  128. data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
  129. data/rbs/fills/rubygems/0/errors.rbs +364 -0
  130. data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
  131. data/rbs/fills/rubygems/0/specification.rbs +1753 -0
  132. data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
  133. data/rbs_collection.yaml +4 -4
  134. data/sig/shims/ast/0/node.rbs +5 -0
  135. data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
  136. data/sig/shims/ast/2.4/ast.rbs +73 -0
  137. data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
  138. data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
  139. data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
  140. data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
  141. data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
  142. data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
  143. data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
  144. data/solargraph.gemspec +26 -5
  145. metadata +181 -13
  146. data/lib/.rubocop.yml +0 -22
  147. data/lib/solargraph/parser/node_methods.rb +0 -97
@@ -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
  )
@@ -23,8 +23,10 @@ module Solargraph
23
23
 
24
24
  # @param source [Source]
25
25
  # @param namespace [String]
26
+ # @param closure [Pin::Closure, nil]
26
27
  # @param scope [Symbol, nil]
27
28
  # @param visibility [Symbol]
29
+ # @param lvars [Array<Symbol>]
28
30
  def initialize source: Solargraph::Source.load_string(''), closure: nil,
29
31
  scope: nil, visibility: :public, lvars: []
30
32
  @source = source
@@ -45,6 +47,7 @@ module Solargraph
45
47
  # @param closure [Pin::Closure, nil]
46
48
  # @param scope [Symbol, nil]
47
49
  # @param visibility [Symbol, nil]
50
+ # @param lvars [Array<Symbol>, nil]
48
51
  # @return [Region]
49
52
  def update closure: nil, scope: nil, visibility: nil, lvars: nil
50
53
  Region.new(
@@ -6,6 +6,8 @@ module Solargraph
6
6
  # @return [String]
7
7
  attr_reader :text
8
8
 
9
+ # @param range [Solargraph::Range]
10
+ # @param text [String]
9
11
  def initialize range, text
10
12
  @range = range
11
13
  @text = text
@@ -13,10 +13,10 @@ module Solargraph
13
13
  # @return [YARD::CodeObjects::Base]
14
14
  attr_reader :code_object
15
15
 
16
- # @return [Solargraph::Location]
16
+ # @return [Solargraph::Location, nil]
17
17
  attr_reader :location
18
18
 
19
- # @return [Solargraph::Location]
19
+ # @return [Solargraph::Location, nil]
20
20
  attr_reader :type_location
21
21
 
22
22
  # @return [String]
@@ -28,6 +28,11 @@ module Solargraph
28
28
  # @return [::Symbol]
29
29
  attr_accessor :source
30
30
 
31
+ # @type [::Numeric, nil] A priority for determining if pins should be combined or not
32
+ # A nil priority is considered the be the lowest. All code, yard & rbs pins have nil priority
33
+ # Between 2 pins, the one with the higher priority gets chosen. If the priorities are equal, they are combined.
34
+ attr_reader :combine_priority
35
+
31
36
  def presence_certain?
32
37
  true
33
38
  end
@@ -40,7 +45,8 @@ module Solargraph
40
45
  # @param source [Symbol, nil]
41
46
  # @param docstring [YARD::Docstring, nil]
42
47
  # @param directives [::Array<YARD::Tags::Directive>, nil]
43
- def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: nil
48
+ # @param combine_priority [::Numeric, nil] See attr_reader for combine_priority
49
+ def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: nil, combine_priority: nil
44
50
  @location = location
45
51
  @type_location = type_location
46
52
  @closure = closure
@@ -50,6 +56,8 @@ module Solargraph
50
56
  @identity = nil
51
57
  @docstring = docstring
52
58
  @directives = directives
59
+ @combine_priority = combine_priority
60
+
53
61
  assert_source_provided
54
62
  assert_location_provided
55
63
  end
@@ -61,12 +69,22 @@ module Solargraph
61
69
  Solargraph.assert_or_log(:best_location, "Neither location nor type_location provided - #{path} #{source} #{self.class}")
62
70
  end
63
71
 
72
+ # @return [Pin::Closure, nil]
73
+ def closure
74
+ Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
75
+ # @type [Pin::Closure, nil]
76
+ @closure
77
+ end
78
+
64
79
  # @param other [self]
65
- # @param attrs [Hash{Symbol => Object}]
80
+ # @param attrs [Hash{::Symbol => Object}]
66
81
  #
67
82
  # @return [self]
68
83
  def combine_with(other, attrs={})
69
84
  raise "tried to combine #{other.class} with #{self.class}" unless other.class == self.class
85
+ priority_choice = choose_priority(other)
86
+ return priority_choice unless priority_choice.nil?
87
+
70
88
  type_location = choose(other, :type_location)
71
89
  location = choose(other, :location)
72
90
  combined_name = combine_name(other)
@@ -79,6 +97,7 @@ module Solargraph
79
97
  source: :combined,
80
98
  docstring: choose(other, :docstring),
81
99
  directives: combine_directives(other),
100
+ combine_priority: combine_priority
82
101
  }.merge(attrs)
83
102
  assert_same_macros(other)
84
103
  logger.debug { "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{self.comments}" }
@@ -87,6 +106,25 @@ module Solargraph
87
106
  out
88
107
  end
89
108
 
109
+ # @param other [self]
110
+ # @return [self, nil] Returns either the pin chosen based on priority or nil
111
+ # A nil return means that the combination process must proceed
112
+ def choose_priority(other)
113
+ if combine_priority.nil? && !other.combine_priority.nil?
114
+ return other
115
+ elsif other.combine_priority.nil? && !combine_priority.nil?
116
+ return self
117
+ elsif !combine_priority.nil? && !other.combine_priority.nil?
118
+ if combine_priority > other.combine_priority
119
+ return self
120
+ elsif combine_priority < other.combine_priority
121
+ return other
122
+ end
123
+ end
124
+
125
+ nil
126
+ end
127
+
90
128
  # @param other [self]
91
129
  # @param attr [::Symbol]
92
130
  # @sg-ignore
@@ -98,7 +136,6 @@ module Solargraph
98
136
  val2 = other.send(attr)
99
137
  return val1 if val1 == val2
100
138
  return val2 if val1.nil?
101
- # @sg-ignore
102
139
  val1.length > val2.length ? val1 : val2
103
140
  end
104
141
 
@@ -158,9 +195,9 @@ module Solargraph
158
195
  return_type
159
196
  else
160
197
  all_items = return_type.items + other.return_type.items
161
- if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.rooted_tag }
198
+ if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.reduce_class_type.rooted_tag }
162
199
  # assume this was a declaration that should have said 'self'
163
- all_items.delete_if { |item| item.rooted_tag == context.rooted_tag }
200
+ all_items.delete_if { |item| item.rooted_tag == context.reduce_class_type.rooted_tag }
164
201
  end
165
202
  ComplexType.new(all_items)
166
203
  end
@@ -188,7 +225,7 @@ module Solargraph
188
225
  end
189
226
 
190
227
  # @param other [self]
191
- # @param attr [Symbol]
228
+ # @param attr [::Symbol]
192
229
  # @sg-ignore
193
230
  # @return [undefined]
194
231
  def choose_node(other, attr)
@@ -222,6 +259,7 @@ module Solargraph
222
259
  def assert_same_macros(other)
223
260
  return unless self.source == :yardoc && other.source == :yardoc
224
261
  assert_same_count(other, :macros)
262
+ # @param [YARD::Tags::MacroDirective]
225
263
  assert_same_array_content(other, :macros) { |macro| macro.tag.name }
226
264
  end
227
265
 
@@ -237,7 +275,6 @@ module Solargraph
237
275
  raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
238
276
  # @type arr2 [::Enumerable]
239
277
 
240
- # @sg-ignore
241
278
  # @type [undefined]
242
279
  values1 = arr1.map(&block)
243
280
  # @type [undefined]
@@ -269,7 +306,8 @@ module Solargraph
269
306
  # @param other [self]
270
307
  # @param attr [::Symbol]
271
308
  #
272
- # @return [Object, nil]
309
+ # @sg-ignore
310
+ # @return [undefined]
273
311
  def assert_same(other, attr)
274
312
  return false if other.nil?
275
313
  val1 = send(attr)
@@ -300,6 +338,8 @@ module Solargraph
300
338
 
301
339
  # @param other [self]
302
340
  # @param attr [::Symbol]
341
+ #
342
+ # @sg-ignore Missing @return tag for Solargraph::Pin::Base#choose_pin_attr
303
343
  # @return [undefined]
304
344
  def choose_pin_attr(other, attr)
305
345
  # @type [Pin::Base, nil]
@@ -307,12 +347,22 @@ module Solargraph
307
347
  # @type [Pin::Base, nil]
308
348
  val2 = other.send(attr)
309
349
  if val1.class != val2.class
350
+ # :nocov:
310
351
  Solargraph.assert_or_log("combine_with_#{attr}_class".to_sym,
311
352
  "Inconsistent #{attr.inspect} class values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
312
353
  return val1
354
+ # :nocov:
313
355
  end
314
356
  # arbitrary way of choosing a pin
315
- [val1, val2].compact.min_by { _1.best_location.to_s }
357
+ [val1, val2].compact.max_by do |closure|
358
+ [
359
+ # maximize number of gates, as types in other combined pins may
360
+ # depend on those gates
361
+ closure.gates.length,
362
+ # use basename so that results don't vary system to system
363
+ File.basename(closure.best_location.to_s)
364
+ ]
365
+ end
316
366
  end
317
367
 
318
368
  # @return [void]
@@ -414,9 +464,10 @@ module Solargraph
414
464
  # Pin equality is determined using the #nearly? method and also
415
465
  # requiring both pins to have the same location.
416
466
  #
417
- # @param other [self]
467
+ # @param other [Object]
418
468
  def == other
419
469
  return false unless nearly? other
470
+ # @sg-ignore Should add more explicit type check on other
420
471
  comments == other.comments && location == other.location
421
472
  end
422
473
 
@@ -471,7 +522,7 @@ module Solargraph
471
522
  # @param api_map [ApiMap]
472
523
  # @return [ComplexType]
473
524
  def typify api_map
474
- return_type.qualify(api_map, namespace)
525
+ return_type.qualify(api_map, *(closure&.gates || ['']))
475
526
  end
476
527
 
477
528
  # Infer the pin's return type via static code analysis.
@@ -532,12 +583,24 @@ module Solargraph
532
583
  @identity ||= "#{closure&.path}|#{name}|#{location}"
533
584
  end
534
585
 
586
+ # The namespaces available for resolving the current namespace. Each gate
587
+ # should be a fully qualified namespace or the root namespace (i.e., an
588
+ # empty string.)
589
+ #
590
+ # Example: Given the name 'Bar' and the gates ['Foo', ''],
591
+ # the fully qualified namespace should be 'Foo::Bar' or 'Bar'.
592
+ #
593
+ # @return [Array<String>]
594
+ def gates
595
+ @gates ||= closure&.gates || ['']
596
+ end
597
+
535
598
  # @return [String, nil]
536
599
  def to_rbs
537
600
  return_type.to_rbs
538
601
  end
539
602
 
540
- # @return [String]
603
+ # @return [String, nil]
541
604
  def type_desc
542
605
  rbs = to_rbs
543
606
  # RBS doesn't have a way to represent a Class<x> type
@@ -3,8 +3,8 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  class BaseVariable < Base
6
- include Solargraph::Parser::NodeMethods
7
6
  # include Solargraph::Source::NodeMethods
7
+ include Solargraph::Parser::NodeMethods
8
8
 
9
9
  # @return [Parser::AST::Node, nil]
10
10
  attr_reader :assignment
@@ -12,8 +12,9 @@ module Solargraph
12
12
  attr_accessor :mass_assignment
13
13
 
14
14
  # @param return_type [ComplexType, nil]
15
+ # @param mass_assignment [::Array(Parser::AST::Node, Integer), nil]
15
16
  # @param assignment [Parser::AST::Node, nil]
16
- def initialize assignment: nil, return_type: nil, **splat
17
+ def initialize assignment: nil, return_type: nil, mass_assignment: nil, **splat
17
18
  super(**splat)
18
19
  @assignment = assignment
19
20
  # @type [nil, ::Array(Parser::AST::Node, Integer)]
@@ -22,12 +23,12 @@ module Solargraph
22
23
  end
23
24
 
24
25
  def combine_with(other, attrs={})
25
- attrs.merge({
26
+ new_attrs = attrs.merge({
26
27
  assignment: assert_same(other, :assignment),
27
28
  mass_assignment: assert_same(other, :mass_assignment),
28
29
  return_type: combine_return_type(other),
29
30
  })
30
- super(other, attrs)
31
+ super(other, new_attrs)
31
32
  end
32
33
 
33
34
  def completion_item_kind
@@ -43,7 +44,6 @@ module Solargraph
43
44
  @return_type ||= generate_complex_type
44
45
  end
45
46
 
46
- # @sg-ignore
47
47
  def nil_assignment?
48
48
  # this will always be false - should it be return_type ==
49
49
  # ComplexType::NIL or somesuch?
@@ -105,6 +105,7 @@ module Solargraph
105
105
  # @param other [Object]
106
106
  def == other
107
107
  return false unless super
108
+ # @sg-ignore Should add type check on other
108
109
  assignment == other.assignment
109
110
  end
110
111
 
@@ -54,6 +54,7 @@ module Solargraph
54
54
  locals = clip.locals - [self]
55
55
  meths = chain.define(api_map, closure, locals)
56
56
  # @todo Convert logic to use signatures
57
+ # @param meth [Pin::Method]
57
58
  meths.each do |meth|
58
59
  next if meth.block.nil?
59
60
 
@@ -69,7 +70,7 @@ module Solargraph
69
70
  namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
70
71
  arg_type.resolve_generics(namespace_pin, param_type)
71
72
  else
72
- arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, meth.context.namespace)
73
+ arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, *meth.gates)
73
74
  end
74
75
  end
75
76
  end
@@ -96,7 +97,7 @@ module Solargraph
96
97
  target = chain.base.infer(api_map, receiver_pin, locals)
97
98
  target = full_context unless target.defined?
98
99
 
99
- ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to_type(target)
100
+ ComplexType.try_parse(*types).qualify(api_map, *receiver_pin.gates).self_to_type(target)
100
101
  end
101
102
  end
102
103
  end
@@ -21,16 +21,21 @@ module Solargraph
21
21
  @parameters = parameters
22
22
  end
23
23
 
24
+ # @return [String]
24
25
  def method_namespace
25
26
  closure.namespace
26
27
  end
27
28
 
29
+ # @param other [self]
30
+ #
31
+ # @return [Pin::Signature, nil]
28
32
  def combine_blocks(other)
29
33
  if block.nil?
30
34
  other.block
31
35
  elsif other.block.nil?
32
36
  block
33
37
  else
38
+ # @type [Pin::Signature, nil]
34
39
  choose_pin_attr(other, :block)
35
40
  end
36
41
  end
@@ -57,8 +62,13 @@ module Solargraph
57
62
  []
58
63
  end
59
64
 
65
+ # @param other [self]
66
+ #
67
+ # @return [Array<Pin::Parameter>]
60
68
  def choose_parameters(other)
61
69
  raise "Trying to combine two pins with different arities - \nself =#{inspect}, \nother=#{other.inspect}, \n\n self.arity=#{self.arity}, \nother.arity=#{other.arity}" if other.arity != arity
70
+ # @param param [Pin::Parameter]
71
+ # @param other_param [Pin::Parameter]
62
72
  parameters.zip(other.parameters).map do |param, other_param|
63
73
  if param.nil? && other_param.block?
64
74
  other_param
@@ -70,6 +80,7 @@ module Solargraph
70
80
  end
71
81
  end
72
82
 
83
+ # @return [Array<Pin::Parameter>]
73
84
  def blockless_parameters
74
85
  if parameters.last&.block?
75
86
  parameters[0..-2]
@@ -78,6 +89,7 @@ module Solargraph
78
89
  end
79
90
  end
80
91
 
92
+ # @return [Array]
81
93
  def arity
82
94
  [generics, blockless_parameters.map(&:arity_decl), block&.arity]
83
95
  end
@@ -125,6 +137,7 @@ module Solargraph
125
137
  end
126
138
  end
127
139
 
140
+ # @return [String]
128
141
  def method_name
129
142
  raise "closure was nil in #{self.inspect}" if closure.nil?
130
143
  @method_name ||= closure.name
@@ -197,11 +210,11 @@ module Solargraph
197
210
  true
198
211
  end
199
212
 
213
+ # @return [Integer]
200
214
  def mandatory_positional_param_count
201
215
  parameters.count(&:arg?)
202
216
  end
203
217
 
204
- # @return [String]
205
218
  def to_rbs
206
219
  rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
207
220
  end
@@ -8,6 +8,7 @@ module Solargraph
8
8
 
9
9
  # @param scope [::Symbol] :class or :instance
10
10
  # @param generics [::Array<Pin::Parameter>, nil]
11
+ # @param generic_defaults [Hash{String => ComplexType}]
11
12
  def initialize scope: :class, generics: nil, generic_defaults: {}, **splat
12
13
  super(**splat)
13
14
  @scope = scope
@@ -15,6 +16,7 @@ module Solargraph
15
16
  @generic_defaults = generic_defaults
16
17
  end
17
18
 
19
+ # @return [Hash{String => ComplexType}]
18
20
  def generic_defaults
19
21
  @generic_defaults ||= {}
20
22
  end
@@ -46,19 +48,15 @@ module Solargraph
46
48
  @binder || context
47
49
  end
48
50
 
49
- # @return [::Array<String>]
50
- def gates
51
- # @todo This check might not be necessary. There should always be a
52
- # root pin
53
- closure ? closure.gates : ['']
54
- end
51
+ # @param api_map [Solargraph::ApiMap]
52
+ # @return [void]
53
+ def rebind api_map; end
55
54
 
56
55
  # @return [::Array<String>]
57
56
  def generics
58
57
  @generics ||= docstring.tags(:generic).map(&:name)
59
58
  end
60
59
 
61
- # @return [String]
62
60
  def to_rbs
63
61
  rbs_generics + return_type.to_rbs
64
62
  end
@@ -3,12 +3,16 @@
3
3
  module Solargraph
4
4
  module Pin
5
5
  module Common
6
+ # @!method source
7
+ # @abstract
8
+ # @return [Source, nil]
9
+ # @type @closure [Pin::Closure, nil]
10
+
6
11
  # @return [Location]
7
12
  attr_reader :location
8
13
 
14
+ # @sg-ignore Solargraph::Pin::Common#closure return type could not be inferred
9
15
  # @return [Pin::Closure, nil]
10
- attr_reader :closure
11
-
12
16
  def closure
13
17
  Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
14
18
  @closure
@@ -5,6 +5,8 @@ module Solargraph
5
5
  class Constant < BaseVariable
6
6
  attr_reader :visibility
7
7
 
8
+ # @param visibility [::Symbol] The visibility of the constant (:public, :protected, or :private)
9
+ # @param splat [Hash] Additional options supported by superclasses
8
10
  def initialize visibility: :public, **splat
9
11
  super(**splat)
10
12
  @visibility = visibility
@@ -26,7 +26,7 @@ module Solargraph
26
26
  assignment: assert_same(other, :assignment),
27
27
  presence_certain: assert_same(other, :presence_certain?),
28
28
  }.merge(attrs)
29
- new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
29
+ new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
30
30
 
31
31
  super(other, new_attrs)
32
32
  end
@@ -39,7 +39,6 @@ module Solargraph
39
39
  match_named_closure(other_closure, closure)
40
40
  end
41
41
 
42
- # @return [String]
43
42
  def to_rbs
44
43
  (name || '(anon)') + ' ' + (return_type&.to_rbs || 'untyped')
45
44
  end