solargraph 0.54.2 → 0.54.3

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/lib/solargraph/api_map/cache.rb +10 -1
  4. data/lib/solargraph/api_map/index.rb +167 -0
  5. data/lib/solargraph/api_map/store.rb +48 -120
  6. data/lib/solargraph/api_map.rb +17 -5
  7. data/lib/solargraph/complex_type/unique_type.rb +21 -1
  8. data/lib/solargraph/complex_type.rb +13 -12
  9. data/lib/solargraph/convention.rb +1 -0
  10. data/lib/solargraph/doc_map.rb +1 -0
  11. data/lib/solargraph/equality.rb +33 -0
  12. data/lib/solargraph/language_server/host/message_worker.rb +3 -0
  13. data/lib/solargraph/language_server/host.rb +2 -1
  14. data/lib/solargraph/language_server/message/base.rb +1 -1
  15. data/lib/solargraph/language_server/message/initialize.rb +3 -1
  16. data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
  17. data/lib/solargraph/library.rb +3 -1
  18. data/lib/solargraph/location.rb +7 -0
  19. data/lib/solargraph/parser/node_methods.rb +1 -1
  20. data/lib/solargraph/parser/node_processor.rb +1 -0
  21. data/lib/solargraph/parser/parser_gem/node_chainer.rb +3 -3
  22. data/lib/solargraph/parser/parser_gem/node_methods.rb +2 -2
  23. data/lib/solargraph/pin/base.rb +27 -16
  24. data/lib/solargraph/pin/base_variable.rb +3 -2
  25. data/lib/solargraph/pin/callable.rb +3 -3
  26. data/lib/solargraph/pin/method.rb +6 -0
  27. data/lib/solargraph/pin/namespace.rb +1 -1
  28. data/lib/solargraph/pin/parameter.rb +2 -1
  29. data/lib/solargraph/position.rb +7 -0
  30. data/lib/solargraph/range.rb +7 -0
  31. data/lib/solargraph/rbs_map/conversions.rb +1 -1
  32. data/lib/solargraph/rbs_map.rb +1 -0
  33. data/lib/solargraph/shell.rb +2 -0
  34. data/lib/solargraph/source/chain/array.rb +1 -1
  35. data/lib/solargraph/source/chain/call.rb +9 -4
  36. data/lib/solargraph/source/chain/hash.rb +5 -0
  37. data/lib/solargraph/source/chain/if.rb +5 -0
  38. data/lib/solargraph/source/chain/link.rb +17 -5
  39. data/lib/solargraph/source/chain/literal.rb +5 -0
  40. data/lib/solargraph/source/chain.rb +33 -19
  41. data/lib/solargraph/source/cursor.rb +1 -1
  42. data/lib/solargraph/source.rb +2 -1
  43. data/lib/solargraph/source_map/clip.rb +1 -1
  44. data/lib/solargraph/type_checker.rb +8 -8
  45. data/lib/solargraph/version.rb +1 -1
  46. data/lib/solargraph/workspace/config.rb +7 -3
  47. data/lib/solargraph/workspace.rb +1 -1
  48. data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
  49. data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
  50. data/lib/solargraph/yard_map/mapper.rb +1 -0
  51. data/lib/solargraph.rb +1 -0
  52. data/solargraph.gemspec +1 -1
  53. metadata +10 -2
@@ -14,10 +14,8 @@ module Solargraph
14
14
  # expression.
15
15
  #
16
16
  class Chain
17
- #
18
- # A chain of constants, variables, and method calls for inferring types of
19
- # values.
20
- #
17
+ include Equality
18
+
21
19
  autoload :Link, 'solargraph/source/chain/link'
22
20
  autoload :Call, 'solargraph/source/chain/call'
23
21
  autoload :QCall, 'solargraph/source/chain/q_call'
@@ -49,6 +47,11 @@ module Solargraph
49
47
 
50
48
  attr_reader :node
51
49
 
50
+ # @sg-ignore Fix "Not enough arguments to Module#protected"
51
+ protected def equality_fields
52
+ [links, node]
53
+ end
54
+
52
55
  # @param node [Parser::AST::Node, nil]
53
56
  # @param links [::Array<Chain::Link>]
54
57
  # @param splat [Boolean]
@@ -107,26 +110,27 @@ module Solargraph
107
110
  end
108
111
 
109
112
  # @param api_map [ApiMap]
110
- # @param name_pin [Pin::Base] The pin for the closure in which this code runs
111
- # @param locals [::Enumerable<Pin::LocalVariable>]
113
+ # @param name_pin [Pin::Base]
114
+ # @param locals [::Array<Pin::LocalVariable>]
112
115
  # @return [ComplexType]
113
116
  # @sg-ignore
114
117
  def infer api_map, name_pin, locals
115
- out = nil
116
- cached = @@inference_cache[[node, node.location, links.map(&:word), name_pin&.return_type, locals]] unless node.nil?
117
- return cached if cached && @@inference_invalidation_key == api_map.hash
118
- out = infer_uncached api_map, name_pin, locals
119
- if @@inference_invalidation_key != api_map.hash
120
- @@inference_cache = {}
118
+ cache_key = [node, node&.location, links, name_pin&.return_type, locals]
119
+ if @@inference_invalidation_key == api_map.hash
120
+ cached = @@inference_cache[cache_key]
121
+ return cached if cached
122
+ else
121
123
  @@inference_invalidation_key = api_map.hash
124
+ @@inference_cache = {}
122
125
  end
123
- @@inference_cache[[node, node.location, links.map(&:word), name_pin&.return_type, locals]] = out unless node.nil?
124
- out
126
+ out = infer_uncached api_map, name_pin, locals
127
+ logger.debug { "Chain#infer() - caching result - cache_key_hash=#{cache_key.hash}, links.map(&:hash)=#{links.map(&:hash)}, links=#{links}, cache_key.map(&:hash) = #{cache_key.map(&:hash)}, cache_key=#{cache_key}" }
128
+ @@inference_cache[cache_key] = out
125
129
  end
126
130
 
127
131
  # @param api_map [ApiMap]
128
132
  # @param name_pin [Pin::Base]
129
- # @param locals [::Enumerable<Pin::LocalVariable>]
133
+ # @param locals [::Array<Pin::LocalVariable>]
130
134
  # @return [ComplexType]
131
135
  def infer_uncached api_map, name_pin, locals
132
136
  pins = define(api_map, name_pin, locals)
@@ -160,6 +164,16 @@ module Solargraph
160
164
  links.any?(&:nullable?)
161
165
  end
162
166
 
167
+ include Logging
168
+
169
+ def desc
170
+ links.map(&:desc).to_s
171
+ end
172
+
173
+ def to_s
174
+ desc
175
+ end
176
+
163
177
  private
164
178
 
165
179
  # @param pins [::Array<Pin::Base>]
@@ -174,9 +188,9 @@ module Solargraph
174
188
  # @param pin [Pin::Base]
175
189
  pins.each do |pin|
176
190
  # Avoid infinite recursion
177
- next if @@inference_stack.include?(pin.identity)
191
+ next if @@inference_stack.include?(pin)
178
192
 
179
- @@inference_stack.push pin.identity
193
+ @@inference_stack.push pin
180
194
  type = pin.typify(api_map)
181
195
  @@inference_stack.pop
182
196
  if type.defined?
@@ -200,9 +214,9 @@ module Solargraph
200
214
  # @param pin [Pin::Base]
201
215
  pins.each do |pin|
202
216
  # Avoid infinite recursion
203
- next if @@inference_stack.include?(pin.identity)
217
+ next if @@inference_stack.include?(pin)
204
218
 
205
- @@inference_stack.push pin.identity
219
+ @@inference_stack.push pin
206
220
  type = pin.probe(api_map)
207
221
  @@inference_stack.pop
208
222
  if type.defined?
@@ -112,7 +112,7 @@ module Solargraph
112
112
  #
113
113
  # @return [Boolean]
114
114
  def assign?
115
- [:lvasgn, :ivasgn, :gvasgn, :cvasgn].include? chain&.node&.type
115
+ %i[lvasgn ivasgn gvasgn cvasgn].include? chain&.node&.type
116
116
  end
117
117
 
118
118
  # Get a cursor pointing to the method that receives the current statement
@@ -307,7 +307,7 @@ module Solargraph
307
307
 
308
308
  # A hash of line numbers and their associated comments.
309
309
  #
310
- # @return [Hash{Integer => Array<String>}]
310
+ # @return [Hash{Integer => Array<String>, nil}]
311
311
  def stringified_comments
312
312
  @stringified_comments ||= {}
313
313
  end
@@ -375,6 +375,7 @@ module Solargraph
375
375
 
376
376
  protected
377
377
 
378
+ # @return [Array<Change>]
378
379
  def changes
379
380
  @changes ||= []
380
381
  end
@@ -40,7 +40,7 @@ module Solargraph
40
40
  end
41
41
  end
42
42
 
43
- # @return [Array<Pin::Base>]
43
+ # @return [Array<Pin::Method>]
44
44
  def signify
45
45
  return [] unless cursor.argument?
46
46
  chain = Parser.chain(cursor.recipient_node, cursor.filename)
@@ -29,6 +29,7 @@ module Solargraph
29
29
  # @todo Smarter directory resolution
30
30
  @api_map = api_map || Solargraph::ApiMap.load(File.dirname(filename))
31
31
  @rules = Rules.new(level)
32
+ # @type [Array<Range>]
32
33
  @marked_ranges = []
33
34
  end
34
35
 
@@ -413,7 +414,7 @@ module Solargraph
413
414
  # @param locals [Array<Pin::LocalVariable>]
414
415
  # @param location [Location]
415
416
  # @param pin [Pin::Method]
416
- # @param params [Hash{String => [nil, Hash]}]
417
+ # @param params [Hash{String => Hash{Symbol => String, Solargraph::ComplexType}}]
417
418
  # @param idx [Integer]
418
419
  #
419
420
  # @return [Array<Problem>]
@@ -467,10 +468,11 @@ module Solargraph
467
468
  end
468
469
 
469
470
  # @param pin [Pin::Method]
470
- # @return [Hash{String => Hash{Symbol => BaseObject}}]
471
+ # @return [Hash{String => Hash{Symbol => String, ComplexType}}]
471
472
  def param_hash(pin)
472
473
  tags = pin.docstring.tags(:param)
473
474
  return {} if tags.empty?
475
+ # @type [Hash{String => Hash{Symbol => String, ComplexType}}]
474
476
  result = {}
475
477
  tags.each do |tag|
476
478
  next if tag.types.nil? || tag.types.empty?
@@ -483,11 +485,9 @@ module Solargraph
483
485
  end
484
486
 
485
487
  # @param pins [Array<Pin::Method>]
486
- # @return [Hash{String => Hash{Symbol => BasicObject}}]
488
+ # @return [Hash{String => Hash{Symbol => String, ComplexType}}]
487
489
  def first_param_hash(pins)
488
490
  pins.each do |pin|
489
- # @todo this assignment from parametric use of Hash should not lose its generic
490
- # @type [Hash{String => Hash{Symbol => BasicObject}}]
491
491
  result = param_hash(pin)
492
492
  return result unless result.empty?
493
493
  end
@@ -512,7 +512,7 @@ module Solargraph
512
512
  !internal? pin
513
513
  end
514
514
 
515
- # @param pin [Pin::Base]
515
+ # @param pin [Pin::BaseVariable]
516
516
  def declared_externally? pin
517
517
  return true if pin.assignment.nil?
518
518
  chain = Solargraph::Parser.chain(pin.assignment, filename)
@@ -562,7 +562,7 @@ module Solargraph
562
562
  return [] unless pin.explicit?
563
563
  return [] if parameters.empty? && arguments.empty?
564
564
  return [] if pin.anon_splat?
565
- unchecked = arguments.clone
565
+ unchecked = arguments.dup # creates copy of and unthaws array
566
566
  add_params = 0
567
567
  if unchecked.empty? && parameters.any? { |param| param.decl == :kwarg }
568
568
  return [Problem.new(location, "Missing keyword arguments to #{pin.path}")]
@@ -638,7 +638,7 @@ module Solargraph
638
638
  (pin.closure && pin.closure.docstring.has_tag?('abstract'))
639
639
  end
640
640
 
641
- # @param pin [Pin::Base]
641
+ # @param pin [Pin::Method]
642
642
  # @return [Array<Source::Chain>]
643
643
  def fake_args_for(pin)
644
644
  args = []
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.54.2'
4
+ VERSION = '0.54.3'
5
5
  end
@@ -15,7 +15,7 @@ module Solargraph
15
15
  attr_reader :directory
16
16
 
17
17
  # @todo To make this strongly typed we'll need a record syntax
18
- # @return [Hash{String => undefined}]
18
+ # @return [Hash{String => Array, Hash, Integer, nil}]
19
19
  attr_reader :raw_data
20
20
 
21
21
  # @param directory [String]
@@ -90,6 +90,7 @@ module Solargraph
90
90
 
91
91
  # A hash of options supported by the formatter
92
92
  #
93
+ # @sg-ignore pending https://github.com/castwide/solargraph/pull/905
93
94
  # @return [Hash]
94
95
  def formatter
95
96
  raw_data['formatter']
@@ -104,6 +105,7 @@ module Solargraph
104
105
 
105
106
  # The maximum number of files to parse from the workspace.
106
107
  #
108
+ # @sg-ignore pending https://github.com/castwide/solargraph/pull/905
107
109
  # @return [Integer]
108
110
  def max_files
109
111
  raw_data['max_files']
@@ -123,7 +125,7 @@ module Solargraph
123
125
  File.join(@directory, '.solargraph.yml')
124
126
  end
125
127
 
126
- # @return [Hash{String => Array, Hash, Integer}]
128
+ # @return [Hash{String => Array<undefined>, Hash{String => undefined}, Integer}]
127
129
  def config_data
128
130
  workspace_config = read_config(workspace_config_path)
129
131
  global_config = read_config(global_config_path)
@@ -226,7 +228,9 @@ module Solargraph
226
228
 
227
229
  # @return [Array<String>]
228
230
  def excluded_directories
229
- @raw_data['exclude']
231
+ # @type [Array<String>]
232
+ excluded = @raw_data['exclude']
233
+ excluded
230
234
  .select { |g| glob_is_directory?(g) }
231
235
  .map { |g| File.absolute_path(glob_to_directory(g), directory) }
232
236
  end
@@ -45,7 +45,7 @@ module Solargraph
45
45
  # or add it to the sources if the workspace is configured to include it.
46
46
  # The source is ignored if the configuration excludes it.
47
47
  #
48
- # @param source [Solargraph::Source]
48
+ # @param sources [Array<Solargraph::Source>]
49
49
  # @return [Boolean] True if the source was added to the workspace
50
50
  def merge *sources
51
51
  unless directory == '*' || sources.all? { |source| source_hash.key?(source.filename) }
@@ -6,6 +6,7 @@ module Solargraph
6
6
  module ToConstant
7
7
  extend YardMap::Helpers
8
8
 
9
+ # @param code_object [YARD::CodeObjects::Base]
9
10
  def self.make code_object, closure = nil, spec = nil
10
11
  closure ||= Solargraph::Pin::Namespace.new(
11
12
  name: code_object.namespace.to_s,
@@ -6,6 +6,7 @@ module Solargraph
6
6
  module ToNamespace
7
7
  extend YardMap::Helpers
8
8
 
9
+ # @param code_object [YARD::CodeObjects::NamespaceObject]
9
10
  def self.make code_object, spec, closure = nil
10
11
  closure ||= Solargraph::Pin::Namespace.new(
11
12
  name: code_object.namespace.to_s,
@@ -12,6 +12,7 @@ module Solargraph
12
12
  def initialize code_objects, spec = nil
13
13
  @code_objects = code_objects
14
14
  @spec = spec
15
+ # @type [Array<Solargraph::Pin::Base>]
15
16
  @pins = []
16
17
  @namespace_pins = {}
17
18
  end
data/lib/solargraph.rb CHANGED
@@ -42,6 +42,7 @@ module Solargraph
42
42
  autoload :Logging, 'solargraph/logging'
43
43
  autoload :TypeChecker, 'solargraph/type_checker'
44
44
  autoload :Environ, 'solargraph/environ'
45
+ autoload :Equality, 'solargraph/equality'
45
46
  autoload :Convention, 'solargraph/convention'
46
47
  autoload :Parser, 'solargraph/parser'
47
48
  autoload :RbsMap, 'solargraph/rbs_map'
data/solargraph.gemspec CHANGED
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  s.add_runtime_dependency 'benchmark', '~> 0.4'
28
28
  s.add_runtime_dependency 'bundler', '~> 2.0'
29
29
  s.add_runtime_dependency 'diff-lcs', '~> 1.4'
30
- s.add_runtime_dependency 'jaro_winkler', '~> 1.6'
30
+ s.add_runtime_dependency 'jaro_winkler', '~> 1.6', '>= 1.6.1'
31
31
  s.add_runtime_dependency 'kramdown', '~> 2.3'
32
32
  s.add_runtime_dependency 'kramdown-parser-gfm', '~> 1.1'
33
33
  s.add_runtime_dependency 'logger', '~> 1.6'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solargraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.54.2
4
+ version: 0.54.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-28 00:00:00.000000000 Z
11
+ date: 2025-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport
@@ -73,6 +73,9 @@ dependencies:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '1.6'
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: 1.6.1
76
79
  type: :runtime
77
80
  prerelease: false
78
81
  version_requirements: !ruby/object:Gem::Requirement
@@ -80,6 +83,9 @@ dependencies:
80
83
  - - "~>"
81
84
  - !ruby/object:Gem::Version
82
85
  version: '1.6'
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 1.6.1
83
89
  - !ruby/object:Gem::Dependency
84
90
  name: kramdown
85
91
  requirement: !ruby/object:Gem::Requirement
@@ -391,6 +397,7 @@ files:
391
397
  - lib/solargraph.rb
392
398
  - lib/solargraph/api_map.rb
393
399
  - lib/solargraph/api_map/cache.rb
400
+ - lib/solargraph/api_map/index.rb
394
401
  - lib/solargraph/api_map/source_to_yard.rb
395
402
  - lib/solargraph/api_map/store.rb
396
403
  - lib/solargraph/bench.rb
@@ -417,6 +424,7 @@ files:
417
424
  - lib/solargraph/diagnostics/update_errors.rb
418
425
  - lib/solargraph/doc_map.rb
419
426
  - lib/solargraph/environ.rb
427
+ - lib/solargraph/equality.rb
420
428
  - lib/solargraph/gem_pins.rb
421
429
  - lib/solargraph/language_server.rb
422
430
  - lib/solargraph/language_server/completion_item_kinds.rb