solargraph 0.54.5 → 0.55.4

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 (103) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/typecheck.yml +1 -1
  3. data/CHANGELOG.md +27 -0
  4. data/lib/solargraph/api_map/store.rb +9 -4
  5. data/lib/solargraph/api_map.rb +116 -39
  6. data/lib/solargraph/complex_type/type_methods.rb +1 -0
  7. data/lib/solargraph/complex_type/unique_type.rb +91 -9
  8. data/lib/solargraph/complex_type.rb +35 -6
  9. data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +60 -0
  10. data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
  11. data/lib/solargraph/convention/struct_definition.rb +101 -0
  12. data/lib/solargraph/convention.rb +1 -0
  13. data/lib/solargraph/doc_map.rb +83 -23
  14. data/lib/solargraph/gem_pins.rb +2 -1
  15. data/lib/solargraph/language_server/host/message_worker.rb +10 -7
  16. data/lib/solargraph/language_server/host.rb +3 -1
  17. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -0
  18. data/lib/solargraph/location.rb +8 -0
  19. data/lib/solargraph/logging.rb +1 -0
  20. data/lib/solargraph/parser/comment_ripper.rb +12 -6
  21. data/lib/solargraph/parser/flow_sensitive_typing.rb +227 -0
  22. data/lib/solargraph/parser/node_methods.rb +14 -0
  23. data/lib/solargraph/parser/node_processor.rb +3 -2
  24. data/lib/solargraph/parser/parser_gem/class_methods.rb +9 -0
  25. data/lib/solargraph/parser/parser_gem/node_chainer.rb +10 -10
  26. data/lib/solargraph/parser/parser_gem/node_methods.rb +4 -2
  27. data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
  28. data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
  29. data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
  30. data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +4 -2
  31. data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +23 -2
  32. data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
  33. data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
  34. data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
  35. data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
  36. data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
  37. data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
  38. data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
  39. data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -6
  40. data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
  41. data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
  42. data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
  43. data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +28 -16
  44. data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +2 -1
  45. data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
  46. data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
  47. data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
  48. data/lib/solargraph/parser/region.rb +1 -1
  49. data/lib/solargraph/parser.rb +1 -0
  50. data/lib/solargraph/pin/base.rb +34 -5
  51. data/lib/solargraph/pin/base_variable.rb +7 -1
  52. data/lib/solargraph/pin/block.rb +2 -0
  53. data/lib/solargraph/pin/breakable.rb +9 -0
  54. data/lib/solargraph/pin/callable.rb +5 -3
  55. data/lib/solargraph/pin/closure.rb +6 -1
  56. data/lib/solargraph/pin/common.rb +5 -0
  57. data/lib/solargraph/pin/delegated_method.rb +20 -1
  58. data/lib/solargraph/pin/documenting.rb +16 -0
  59. data/lib/solargraph/pin/keyword.rb +7 -2
  60. data/lib/solargraph/pin/local_variable.rb +7 -1
  61. data/lib/solargraph/pin/method.rb +34 -27
  62. data/lib/solargraph/pin/namespace.rb +17 -9
  63. data/lib/solargraph/pin/parameter.rb +17 -5
  64. data/lib/solargraph/pin/proxy_type.rb +12 -6
  65. data/lib/solargraph/pin/reference/override.rb +10 -6
  66. data/lib/solargraph/pin/reference/require.rb +2 -2
  67. data/lib/solargraph/pin/signature.rb +4 -0
  68. data/lib/solargraph/pin/singleton.rb +1 -1
  69. data/lib/solargraph/pin/symbol.rb +3 -2
  70. data/lib/solargraph/pin/until.rb +18 -0
  71. data/lib/solargraph/pin/while.rb +18 -0
  72. data/lib/solargraph/pin.rb +4 -1
  73. data/lib/solargraph/rbs_map/conversions.rb +172 -56
  74. data/lib/solargraph/rbs_map/core_fills.rb +32 -16
  75. data/lib/solargraph/rbs_map/core_map.rb +3 -2
  76. data/lib/solargraph/shell.rb +1 -0
  77. data/lib/solargraph/source/chain/array.rb +11 -7
  78. data/lib/solargraph/source/chain/block_symbol.rb +1 -1
  79. data/lib/solargraph/source/chain/block_variable.rb +1 -1
  80. data/lib/solargraph/source/chain/call.rb +53 -23
  81. data/lib/solargraph/source/chain/constant.rb +1 -1
  82. data/lib/solargraph/source/chain/hash.rb +4 -3
  83. data/lib/solargraph/source/chain/head.rb +1 -1
  84. data/lib/solargraph/source/chain/if.rb +1 -1
  85. data/lib/solargraph/source/chain/link.rb +2 -0
  86. data/lib/solargraph/source/chain/literal.rb +22 -2
  87. data/lib/solargraph/source/chain/or.rb +1 -1
  88. data/lib/solargraph/source/chain/z_super.rb +1 -1
  89. data/lib/solargraph/source/chain.rb +78 -48
  90. data/lib/solargraph/source/source_chainer.rb +2 -2
  91. data/lib/solargraph/source_map/clip.rb +3 -1
  92. data/lib/solargraph/source_map/mapper.rb +9 -5
  93. data/lib/solargraph/type_checker/checks.rb +4 -0
  94. data/lib/solargraph/type_checker.rb +35 -8
  95. data/lib/solargraph/version.rb +1 -1
  96. data/lib/solargraph/yard_map/mapper/to_constant.rb +4 -2
  97. data/lib/solargraph/yard_map/mapper/to_method.rb +55 -15
  98. data/lib/solargraph/yard_map/mapper/to_namespace.rb +4 -2
  99. data/lib/solargraph/yard_map/mapper.rb +4 -3
  100. data/lib/solargraph/yard_map/to_method.rb +4 -2
  101. data/lib/solargraph.rb +20 -0
  102. data/rbs/fills/tuple.rbs +150 -0
  103. metadata +15 -2
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module StructDefinition
6
+ # A node wrapper for a Struct definition via inheritance.
7
+ # @example
8
+ # class MyStruct < Struct.new(:bar, :baz)
9
+ # def foo
10
+ # end
11
+ # end
12
+ class StructDefintionNode
13
+ class << self
14
+ # @example
15
+ # s(:class,
16
+ # s(:const, nil, :Foo),
17
+ # s(:send,
18
+ # s(:const, nil, :Struct), :new,
19
+ # s(:sym, :bar),
20
+ # s(:sym, :baz)),
21
+ # s(:hash,
22
+ # s(:pair,
23
+ # s(:sym, :keyword_init),
24
+ # s(:true)))),
25
+ # s(:def, :foo,
26
+ # s(:args),
27
+ # s(:send, nil, :bar)))
28
+ def valid?(node)
29
+ return false unless node&.type == :class
30
+
31
+ struct_definition_node?(node.children[1])
32
+ end
33
+
34
+ private
35
+
36
+ # @param struct_node [Parser::AST::Node]
37
+ # @return [Boolean]
38
+ def struct_definition_node?(struct_node)
39
+ return false unless struct_node.is_a?(::Parser::AST::Node)
40
+ return false unless struct_node&.type == :send
41
+ return false unless struct_node.children[0]&.type == :const
42
+ return false unless struct_node.children[0].children[1] == :Struct
43
+ return false unless struct_node.children[1] == :new
44
+
45
+ true
46
+ end
47
+ end
48
+
49
+ # @return [Parser::AST::Node]
50
+ def initialize(node)
51
+ @node = node
52
+ end
53
+
54
+ # @return [String]
55
+ def class_name
56
+ Parser::NodeMethods.unpack_name(node)
57
+ end
58
+
59
+ # @return [Array<Array(Parser::AST::Node, String)>]
60
+ def attributes
61
+ struct_attribute_nodes.map do |struct_def_param|
62
+ next unless struct_def_param.type == :sym
63
+ [struct_def_param, struct_def_param.children[0].to_s]
64
+ end.compact
65
+ end
66
+
67
+ def keyword_init?
68
+ keyword_init_param = struct_attribute_nodes.find do |struct_def_param|
69
+ struct_def_param.type == :hash && struct_def_param.children[0].type == :pair &&
70
+ struct_def_param.children[0].children[0].children[0] == :keyword_init
71
+ end
72
+
73
+ return false if keyword_init_param.nil?
74
+
75
+ keyword_init_param.children[0].children[1].type == :true
76
+ end
77
+
78
+ # @return [Parser::AST::Node]
79
+ def body_node
80
+ node.children[2]
81
+ end
82
+
83
+ private
84
+
85
+ # @return [Parser::AST::Node]
86
+ attr_reader :node
87
+
88
+ # @return [Parser::AST::Node]
89
+ def struct_node
90
+ node.children[1]
91
+ end
92
+
93
+ # @return [Array<Parser::AST::Node>]
94
+ def struct_attribute_nodes
95
+ struct_node.children[2..-1]
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph
4
+ module Convention
5
+ module StructDefinition
6
+ autoload :StructDefintionNode, 'solargraph/convention/struct_definition/struct_definition_node'
7
+ autoload :StructAssignmentNode, 'solargraph/convention/struct_definition/struct_assignment_node'
8
+
9
+ module NodeProcessors
10
+ class StructNode < Parser::NodeProcessor::Base
11
+ def process
12
+ return if struct_definition_node.nil?
13
+
14
+ loc = get_node_location(node)
15
+ nspin = Solargraph::Pin::Namespace.new(
16
+ type: :class,
17
+ location: loc,
18
+ closure: region.closure,
19
+ name: struct_definition_node.class_name,
20
+ comments: comments_for(node),
21
+ visibility: :public,
22
+ gates: region.closure.gates.freeze
23
+ )
24
+ pins.push nspin
25
+
26
+ # define initialize method
27
+ initialize_method_pin = Pin::Method.new(
28
+ name: 'initialize',
29
+ parameters: [],
30
+ scope: :instance,
31
+ location: get_node_location(node),
32
+ closure: nspin,
33
+ visibility: :private,
34
+ comments: comments_for(node)
35
+ )
36
+
37
+ pins.push initialize_method_pin
38
+
39
+ struct_definition_node.attributes.map do |attribute_node, attribute_name|
40
+ initialize_method_pin.parameters.push(
41
+ Pin::Parameter.new(
42
+ name: attribute_name,
43
+ decl: struct_definition_node.keyword_init? ? :kwarg : :arg,
44
+ location: get_node_location(attribute_node),
45
+ closure: initialize_method_pin
46
+ )
47
+ )
48
+ end
49
+
50
+ # define attribute accessors and instance variables
51
+ struct_definition_node.attributes.each do |attribute_node, attribute_name|
52
+ [attribute_name, "#{attribute_name}="].each do |name|
53
+ method_pin = Pin::Method.new(
54
+ name: name,
55
+ parameters: [],
56
+ scope: :instance,
57
+ location: get_node_location(attribute_node),
58
+ closure: nspin,
59
+ comments: attribute_comments(attribute_node, attribute_name),
60
+ visibility: :public
61
+ )
62
+
63
+ pins.push method_pin
64
+
65
+ next unless name.include?('=') # setter
66
+ pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
67
+ closure: method_pin,
68
+ location: get_node_location(attribute_node),
69
+ comments: attribute_comments(attribute_node, attribute_name))
70
+ end
71
+ end
72
+
73
+ process_children region.update(closure: nspin, visibility: :public)
74
+ end
75
+
76
+ private
77
+
78
+ # @return [StructDefintionNode, nil]
79
+ def struct_definition_node
80
+ @struct_definition_node ||= if StructDefintionNode.valid?(node)
81
+ StructDefintionNode.new(node)
82
+ elsif StructAssignmentNode.valid?(node)
83
+ StructAssignmentNode.new(node)
84
+ end
85
+ end
86
+
87
+ # @param attribute_node [Parser::AST::Node]
88
+ # @return [String, nil]
89
+ def attribute_comments(attribute_node, attribute_name)
90
+ struct_comments = comments_for(attribute_node)
91
+ return if struct_comments.nil? || struct_comments.empty?
92
+
93
+ struct_comments.split("\n").find do |row|
94
+ row.include?(attribute_name)
95
+ end&.gsub('@param', '@return')&.gsub(attribute_name, '')
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -10,6 +10,7 @@ module Solargraph
10
10
  autoload :Gemfile, 'solargraph/convention/gemfile'
11
11
  autoload :Gemspec, 'solargraph/convention/gemspec'
12
12
  autoload :Rakefile, 'solargraph/convention/rakefile'
13
+ autoload :StructDefinition, 'solargraph/convention/struct_definition'
13
14
 
14
15
  # @type [Set<Convention::Base>]
15
16
  @@conventions = Set.new
@@ -4,6 +4,8 @@ module Solargraph
4
4
  # A collection of pins generated from required gems.
5
5
  #
6
6
  class DocMap
7
+ include Logging
8
+
7
9
  # @return [Array<String>]
8
10
  attr_reader :requires
9
11
 
@@ -16,24 +18,27 @@ module Solargraph
16
18
  # @return [Array<Gem::Specification>]
17
19
  attr_reader :uncached_gemspecs
18
20
 
21
+ # @return [Workspace, nil]
22
+ attr_reader :workspace
23
+
19
24
  # @param requires [Array<String>]
20
25
  # @param preferences [Array<Gem::Specification>]
21
- # @param rbs_path [String, Pathname, nil]
22
- def initialize(requires, preferences, rbs_path = nil)
26
+ # @param workspace [Workspace, nil]
27
+ def initialize(requires, preferences, workspace = nil)
23
28
  @requires = requires.compact
24
29
  @preferences = preferences.compact
25
- @rbs_path = rbs_path
30
+ @workspace = workspace
26
31
  generate
27
32
  end
28
33
 
29
34
  # @return [Array<Gem::Specification>]
30
35
  def gemspecs
31
- @gemspecs ||= required_gem_map.values.compact
36
+ @gemspecs ||= required_gems_map.values.compact.flatten
32
37
  end
33
38
 
34
39
  # @return [Array<String>]
35
40
  def unresolved_requires
36
- @unresolved_requires ||= required_gem_map.select { |_, gemspec| gemspec.nil? }.keys
41
+ @unresolved_requires ||= required_gems_map.select { |_, gemspecs| gemspecs.nil? }.keys
37
42
  end
38
43
 
39
44
  # @return [Hash{Gem::Specification => Array[Pin::Base]}]
@@ -52,20 +57,22 @@ module Solargraph
52
57
  def generate
53
58
  @pins = []
54
59
  @uncached_gemspecs = []
55
- required_gem_map.each do |path, gemspec|
56
- if gemspec
57
- try_cache gemspec
58
- else
60
+ required_gems_map.each do |path, gemspecs|
61
+ if gemspecs.nil?
59
62
  try_stdlib_map path
63
+ else
64
+ gemspecs.each do |gemspec|
65
+ try_cache gemspec
66
+ end
60
67
  end
61
68
  end
62
69
  dependencies.each { |dep| try_cache dep }
63
70
  @uncached_gemspecs.uniq!
64
71
  end
65
72
 
66
- # @return [Hash{String => Gem::Specification, nil}]
67
- def required_gem_map
68
- @required_gem_map ||= requires.to_h { |path| [path, resolve_path_to_gemspec(path)] }
73
+ # @return [Hash{String => Array<Gem::Specification>}]
74
+ def required_gems_map
75
+ @required_gems_map ||= requires.to_h { |path| [path, resolve_path_to_gemspecs(path)] }
69
76
  end
70
77
 
71
78
  # @return [Hash{String => Gem::Specification}]
@@ -114,10 +121,10 @@ module Solargraph
114
121
 
115
122
  # @param gemspec [Gem::Specification]
116
123
  def update_from_collection gemspec, gempins
117
- return gempins unless @rbs_path && File.directory?(@rbs_path)
124
+ return gempins unless workspace&.rbs_collection_path && File.directory?(workspace&.rbs_collection_path)
118
125
  return gempins if RbsMap.new(gemspec.name, gemspec.version).resolved?
119
126
 
120
- rbs_map = RbsMap.new(gemspec.name, gemspec.version, directories: [@rbs_path])
127
+ rbs_map = RbsMap.new(gemspec.name, gemspec.version, directories: [workspace&.rbs_collection_path])
121
128
  return gempins unless rbs_map.resolved?
122
129
 
123
130
  Solargraph.logger.info "Updating #{gemspec.name} #{gemspec.version} from collection"
@@ -125,9 +132,10 @@ module Solargraph
125
132
  end
126
133
 
127
134
  # @param path [String]
128
- # @return [Gem::Specification, nil]
129
- def resolve_path_to_gemspec path
135
+ # @return [::Array<Gem::Specification>, nil]
136
+ def resolve_path_to_gemspecs path
130
137
  return nil if path.empty?
138
+ return gemspecs_required_from_bundler if path == 'bundler/require'
131
139
 
132
140
  gemspec = Gem::Specification.find_by_path(path)
133
141
  if gemspec.nil?
@@ -142,16 +150,17 @@ module Solargraph
142
150
  gemspec = potential_gemspec if potential_gemspec.files.any? { |gemspec_file| file == gemspec_file }
143
151
  rescue Gem::MissingSpecError
144
152
  Solargraph.logger.debug "Require path #{path} could not be resolved to a gem via find_by_path or guess of #{gem_name_guess}"
145
- nil
153
+ []
146
154
  end
147
155
  end
148
- gemspec_or_preference gemspec
156
+ return nil if gemspec.nil?
157
+ [gemspec_or_preference(gemspec)]
149
158
  end
150
159
 
151
- # @param gemspec [Gem::Specification, nil]
152
- # @return [Gem::Specification, nil]
160
+ # @param gemspec [Gem::Specification]
161
+ # @return [Gem::Specification]
153
162
  def gemspec_or_preference gemspec
154
- return gemspec unless gemspec && preference_map.key?(gemspec.name)
163
+ return gemspec unless preference_map.key?(gemspec.name)
155
164
  return gemspec if gemspec.version == preference_map[gemspec.name].version
156
165
 
157
166
  change_gemspec_version gemspec, preference_map[by_path.name].version
@@ -170,12 +179,15 @@ module Solargraph
170
179
  # @param gemspec [Gem::Specification]
171
180
  # @return [Array<Gem::Specification>]
172
181
  def fetch_dependencies gemspec
182
+ # @param spec [Gem::Dependency]
173
183
  only_runtime_dependencies(gemspec).each_with_object(Set.new) do |spec, deps|
174
184
  Solargraph.logger.info "Adding #{spec.name} dependency for #{gemspec.name}"
175
- dep = Gem::Specification.find_by_name(spec.name, spec.requirement)
185
+ dep = Gem.loaded_specs[spec.name]
186
+ # @todo is next line necessary?
187
+ dep ||= Gem::Specification.find_by_name(spec.name, spec.requirement)
176
188
  deps.merge fetch_dependencies(dep) if deps.add?(dep)
177
189
  rescue Gem::MissingSpecError
178
- Solargraph.logger.warn "Gem dependency #{spec.name} #{spec.requirements} for #{gemspec.name} not found."
190
+ Solargraph.logger.warn "Gem dependency #{spec.name} #{spec.requirement} for #{gemspec.name} not found."
179
191
  end.to_a
180
192
  end
181
193
 
@@ -184,5 +196,53 @@ module Solargraph
184
196
  def only_runtime_dependencies gemspec
185
197
  gemspec.dependencies - gemspec.development_dependencies
186
198
  end
199
+
200
+ def gemspecs_required_from_bundler
201
+ if workspace&.directory && Bundler.definition&.lockfile&.to_s&.start_with?(workspace.directory)
202
+ # Find only the gems bundler is now using
203
+ Bundler.definition.locked_gems.specs.flat_map do |lazy_spec|
204
+ logger.info "Handling #{lazy_spec.name}:#{lazy_spec.version}"
205
+ [Gem::Specification.find_by_name(lazy_spec.name, lazy_spec.version)]
206
+ rescue Gem::MissingSpecError => e
207
+ logger.info("Could not find #{lazy_spec.name}:#{lazy_spec.version} with find_by_name, falling back to guess")
208
+ # can happen in local filesystem references
209
+ specs = resolve_path_to_gemspecs lazy_spec.name
210
+ logger.warn "Gem #{lazy_spec.name} #{lazy_spec.version} from bundle not found: #{e}" if specs.nil?
211
+ next specs
212
+ end.compact
213
+ else
214
+ logger.info 'Fetching gemspecs required from Bundler (bundler/require)'
215
+ gemspecs_required_from_external_bundle
216
+ end
217
+ end
218
+
219
+ def gemspecs_required_from_external_bundle
220
+ logger.info 'Fetching gemspecs required from external bundle'
221
+ return [] unless workspace&.directory
222
+
223
+ Solargraph.with_clean_env do
224
+ cmd = [
225
+ 'ruby', '-e',
226
+ "require 'bundler'; require 'json'; Dir.chdir('#{workspace&.directory}') { puts Bundler.definition.locked_gems.specs.map { |spec| [spec.name, spec.version] }.to_h.to_json }"
227
+ ]
228
+ o, e, s = Open3.capture3(*cmd)
229
+ if s.success?
230
+ Solargraph.logger.debug "External bundle: #{o}"
231
+ hash = o && !o.empty? ? JSON.parse(o.split("\n").last) : {}
232
+ hash.flat_map do |name, version|
233
+ Gem::Specification.find_by_name(name, version)
234
+ rescue Gem::MissingSpecError => e
235
+ logger.info("Could not find #{name}:#{version} with find_by_name, falling back to guess")
236
+ # can happen in local filesystem references
237
+ specs = resolve_path_to_gemspecs name
238
+ logger.warn "Gem #{name} #{version} from bundle not found: #{e}" if specs.nil?
239
+ next specs
240
+ end.compact
241
+ else
242
+ Solargraph.logger.warn e
243
+ raise BundleNotFoundError, "Failed to load gems from bundle at #{workspace&.directory}"
244
+ end
245
+ end
246
+ end
187
247
  end
188
248
  end
@@ -42,7 +42,8 @@ module Solargraph
42
42
  generics: rbs.generics,
43
43
  node: yard.node,
44
44
  signatures: yard.signatures,
45
- return_type: best_return_type(rbs.return_type, yard.return_type)
45
+ return_type: best_return_type(rbs.return_type, yard.return_type),
46
+ source: :gem_pins
46
47
  )
47
48
  end
48
49
  in_rbs = rbs_map.pins.reject { |pin| in_yard.include?(pin.path) }
@@ -7,9 +7,16 @@ module Solargraph
7
7
  #
8
8
  class MessageWorker
9
9
  UPDATE_METHODS = [
10
- 'textDocument/didOpen',
11
10
  'textDocument/didChange',
12
- 'workspace/didChangeWatchedFiles'
11
+ 'textDocument/didClose',
12
+ 'textDocument/didOpen',
13
+ 'textDocument/didSave',
14
+ 'workspace/didChangeConfiguration',
15
+ 'workspace/didChangeWatchedFiles',
16
+ 'workspace/didCreateFiles',
17
+ 'workspace/didChangeWorkspaceFolders',
18
+ 'workspace/didDeleteFiles',
19
+ 'workspace/didRenameFiles'
13
20
  ].freeze
14
21
 
15
22
  # @param host [Host]
@@ -84,11 +91,7 @@ module Solargraph
84
91
  idx = messages.find_index do |msg|
85
92
  UPDATE_METHODS.include?(msg['method']) || version_dependent?(msg)
86
93
  end
87
- return messages.shift unless idx
88
-
89
- msg = messages[idx]
90
- messages.delete_at idx
91
- msg
94
+ idx ? messages.delete_at(idx) : messages.shift
92
95
  end
93
96
 
94
97
  # True if the message requires a previous update to have executed in
@@ -501,7 +501,8 @@ module Solargraph
501
501
  parameters: pin.parameters,
502
502
  return_type: ComplexType.try_parse(params['data']['path']),
503
503
  comments: pin.comments,
504
- closure: pin.closure
504
+ closure: pin.closure,
505
+ source: :solargraph
505
506
  )
506
507
  end)
507
508
  end
@@ -749,6 +750,7 @@ module Solargraph
749
750
  return change if source.code.length + 1 != change['text'].length
750
751
  diffs = Diff::LCS.diff(source.code, change['text'])
751
752
  return change if diffs.length.zero? || diffs.length > 1 || diffs.first.length > 1
753
+ # @sg-ignore push this upstream
752
754
  # @type [Diff::LCS::Change]
753
755
  diff = diffs.first.first
754
756
  return change unless diff.adding? && ['.', ':', '(', ',', ' '].include?(diff.element)
@@ -83,6 +83,7 @@ module Solargraph
83
83
  @fetched = true
84
84
  begin
85
85
  @available ||= begin
86
+ # @type [Gem::Dependency, nil]
86
87
  tuple = CheckGemVersion.fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
87
88
  if tuple.nil?
88
89
  @error = 'An error occurred fetching the gem data'
@@ -30,6 +30,14 @@ module Solargraph
30
30
  range.contain?(location.range.start) && range.contain?(location.range.ending) && filename == location.filename
31
31
  end
32
32
 
33
+ def inspect
34
+ "<#{self.class.name}: filename=#{filename}, range=#{range.inspect}>"
35
+ end
36
+
37
+ def to_s
38
+ inspect
39
+ end
40
+
33
41
  # @return [Hash]
34
42
  def to_hash
35
43
  {
@@ -13,6 +13,7 @@ module Solargraph
13
13
  }
14
14
 
15
15
  @@logger = Logger.new(STDERR, level: DEFAULT_LOG_LEVEL)
16
+ # @sg-ignore Fix cvar issue
16
17
  @@logger.formatter = proc do |severity, datetime, progname, msg|
17
18
  "[#{severity}] #{msg}\n"
18
19
  end
@@ -13,6 +13,8 @@ module Solargraph
13
13
  end
14
14
 
15
15
  def on_comment *args
16
+ # @sg-ignore
17
+ # @type [Array(Symbol, String, Array([Integer, nil], [Integer, nil]))]
16
18
  result = super
17
19
  if @buffer_lines[result[2][0]][0..result[2][1]].strip =~ /^#/
18
20
  chomped = result[1].chomp
@@ -24,24 +26,28 @@ module Solargraph
24
26
  result
25
27
  end
26
28
 
29
+ # @param result [Array(Symbol, String, Array([Integer, nil], [Integer, nil]))]
30
+ # @return [void]
31
+ def create_snippet(result)
32
+ chomped = result[1].chomp
33
+ @comments[result[2][0]] = Snippet.new(Range.from_to(result[2][0] || 0, result[2][1] || 0, result[2][0] || 0, (result[2][1] || 0) + chomped.length), chomped)
34
+ end
35
+
27
36
  def on_embdoc_beg *args
28
37
  result = super
29
- chomped = result[1].chomp
30
- @comments[result[2][0]] = Snippet.new(Range.from_to(result[2][0], result[2][1], result[2][0], result[2][1] + chomped.length), chomped)
38
+ create_snippet(result)
31
39
  result
32
40
  end
33
41
 
34
42
  def on_embdoc *args
35
43
  result = super
36
- chomped = result[1].chomp
37
- @comments[result[2][0]] = Snippet.new(Range.from_to(result[2][0], result[2][1], result[2][0], result[2][1] + chomped.length), chomped)
44
+ create_snippet(result)
38
45
  result
39
46
  end
40
47
 
41
48
  def on_embdoc_end *args
42
49
  result = super
43
- chomped = result[1].chomp
44
- @comments[result[2][0]] = Snippet.new(Range.from_to(result[2][0], result[2][1], result[2][0], result[2][1] + chomped.length), chomped)
50
+ create_snippet(result)
45
51
  result
46
52
  end
47
53