solargraph 0.43.1 → 0.44.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 (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/lib/solargraph/complex_type.rb +4 -0
  4. data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -1
  5. data/lib/solargraph/documentor.rb +10 -12
  6. data/lib/solargraph/language_server/host/message_worker.rb +10 -7
  7. data/lib/solargraph/language_server/host.rb +32 -34
  8. data/lib/solargraph/language_server/message/initialize.rb +7 -0
  9. data/lib/solargraph/language_server/message/initialized.rb +1 -0
  10. data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -0
  11. data/lib/solargraph/language_server/message/text_document.rb +18 -18
  12. data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +1 -0
  13. data/lib/solargraph/language_server/message.rb +2 -1
  14. data/lib/solargraph/library.rb +23 -20
  15. data/lib/solargraph/parser/legacy/node_chainer.rb +17 -0
  16. data/lib/solargraph/parser/legacy/node_methods.rb +7 -0
  17. data/lib/solargraph/parser/legacy/node_processors/block_node.rb +25 -1
  18. data/lib/solargraph/parser/rubyvm/class_methods.rb +7 -2
  19. data/lib/solargraph/parser/rubyvm/node_chainer.rb +5 -0
  20. data/lib/solargraph/parser/rubyvm/node_methods.rb +23 -14
  21. data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +25 -1
  22. data/lib/solargraph/pin/block.rb +19 -9
  23. data/lib/solargraph/pin/documenting.rb +1 -1
  24. data/lib/solargraph/pin/local_variable.rb +1 -13
  25. data/lib/solargraph/source/chain/link.rb +4 -0
  26. data/lib/solargraph/source/chain/q_call.rb +11 -0
  27. data/lib/solargraph/source/chain.rb +14 -1
  28. data/lib/solargraph/source.rb +0 -3
  29. data/lib/solargraph/source_map/clip.rb +5 -5
  30. data/lib/solargraph/source_map/mapper.rb +4 -4
  31. data/lib/solargraph/version.rb +1 -1
  32. data/lib/solargraph/workspace.rb +14 -10
  33. data/lib/solargraph/yard_map.rb +6 -2
  34. data/solargraph.gemspec +1 -1
  35. metadata +8 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48b532bf77bb72b9d2d111605cc86e97a21c372319a041ef5c4dfbd03a2b98d1
4
- data.tar.gz: da953eea90b1215a794783723898277abe33a4b74e585eeb710f231b824321b7
3
+ metadata.gz: 346926f891270e103d6c7170fe5897587c1d5da45ea33b2a7f4238914b38b236
4
+ data.tar.gz: 451b09bf70dc9d760ebfdeb726821e6e653f196bd867da8c7638888803e33a72
5
5
  SHA512:
6
- metadata.gz: c3f55a7eb1f0b08247d70f7a2c28422b6444e5102a96c7c9da88b5b9b5f558732f97dc186e6dc53650bd5af20747066dbf53272a15527f000607fca17583e6da
7
- data.tar.gz: 7224059b6b2c757049bf27c4140c54063b035b13eeaf93f30c521393c5e8c863b72843c28edbfb9cbe2980fe28f79006195926f9c8bf79b204dd08a9895ec1e8
6
+ metadata.gz: 624d1de49ef2762477d7a413adf282a058143a71689ea8cdfcc91177db94c765b997fca00fefd8d0d4915e44e6cd4ae1867297671611ba6d119d610116c5b80a
7
+ data.tar.gz: 9f146a371e075407cb8be7b96de08ff24583cf18eb1a29310c1a711c1bd347715d07b0ff6603e9a98b71be7406148e17c907abdcf3bd1a2aba58bd5aeff14685
data/CHANGELOG.md CHANGED
@@ -1,4 +1,24 @@
1
- ## 0.43.1
1
+ ## 0.44.1 - November 18, 2021
2
+ - Chain nil safety navigation operator (#420)
3
+ - Update closure and context for class_eval receiver (#487)
4
+ - SourceMap::Mapper handles invalid byte sequences (#474)
5
+ - Special handle var= references, which may use as var = (have space) (#498)
6
+ - Rebind define_method to self (#494)
7
+
8
+ ## 0.44.0 - September 27, 2021
9
+ - Allow opening parenthesis, space, and comma when using Diff::LCS (#465)
10
+ - Support textDocument/documentHighlight
11
+ - Library#references_from performs shallow matches
12
+
13
+ ## 0.43.3 - September 25, 2021
14
+ - Avoid Dir.chdir in Bundler processes (#481)
15
+ - Check stdlib for gems with empty yardocs
16
+ - Library#maybe_map checks for source in workspace
17
+
18
+ ## 0.43.2 - September 23, 2021
19
+ - Synchronize server requests (#461)
20
+
21
+ ## 0.43.1 - September 20, 2021
2
22
  - Complete nested namespaces in open gates
3
23
  - SourceMap::Mapper reports filename for encoding errors (#474)
4
24
  - Handle request on a specific thread, and cancel completion when there has newer completion request (#459)
@@ -87,6 +87,10 @@ module Solargraph
87
87
  ComplexType.parse(*result.map(&:tag))
88
88
  end
89
89
 
90
+ def nullable?
91
+ @items.any?(&:nil_type?)
92
+ end
93
+
90
94
  private
91
95
 
92
96
  # @todo This is a quick and dirty hack that forces `self` keywords
@@ -31,7 +31,7 @@ module Solargraph
31
31
  # @param code [String]
32
32
  # @return [Array(Array<String>, Array<String>)]
33
33
  def generate_options filename, code
34
- args = ['-f', 'j', filename]
34
+ args = ['-f', 'j', '--force-exclusion', filename]
35
35
  base_options = RuboCop::Options.new
36
36
  options, paths = base_options.parse(args)
37
37
  options[:stdin] = code
@@ -59,18 +59,16 @@ module Solargraph
59
59
  # @return [Hash]
60
60
  def self.specs_from_bundle directory
61
61
  Solargraph.with_clean_env do
62
- Dir.chdir directory do
63
- cmd = [
64
- 'bundle', 'exec', 'ruby', '-e',
65
- "require 'bundler'; require 'json'; puts Bundler.definition.specs_for([:default]).map { |spec| [spec.name, spec.version] }.to_h.to_json"
66
- ]
67
- o, e, s = Open3.capture3(*cmd)
68
- if s.success?
69
- o && !o.empty? ? JSON.parse(o.split("\n").last) : {}
70
- else
71
- Solargraph.logger.warn e
72
- raise BundleNotFoundError, "Failed to load gems from bundle at #{directory}"
73
- end
62
+ cmd = [
63
+ 'ruby', '-e',
64
+ "require 'bundler'; require 'json'; Dir.chdir('#{directory}') { puts Bundler.definition.specs_for([:default]).map { |spec| [spec.name, spec.version] }.to_h.to_json }"
65
+ ]
66
+ o, e, s = Open3.capture3(*cmd)
67
+ if s.success?
68
+ o && !o.empty? ? JSON.parse(o.split("\n").last) : {}
69
+ else
70
+ Solargraph.logger.warn e
71
+ raise BundleNotFoundError, "Failed to load gems from bundle at #{directory}"
74
72
  end
75
73
  end
76
74
  end
@@ -23,16 +23,18 @@ module Solargraph
23
23
  def stopped?
24
24
  @stopped
25
25
  end
26
+
26
27
  def stop
27
28
  @stopped = true
28
29
  end
29
30
 
30
- # @param message the message should be handle. will pass back to Host#receive
31
+ # @param message [Hash] The message should be handle. will pass back to Host#receive
32
+ # @return [void]
31
33
  def queue(message)
32
- @mutex.synchronize {
34
+ @mutex.synchronize do
33
35
  messages.push(message)
34
36
  @resource.signal
35
- }
37
+ end
36
38
  end
37
39
 
38
40
  def start
@@ -42,13 +44,14 @@ module Solargraph
42
44
  tick until stopped?
43
45
  end
44
46
  end
47
+
45
48
  def tick
46
- message = @mutex.synchronize {
49
+ message = @mutex.synchronize do
47
50
  @resource.wait(@mutex) if messages.empty?
48
51
  messages.shift
49
- }
50
- message = @host.receive(message)
51
- message && message.send_response
52
+ end
53
+ handler = @host.receive(message)
54
+ handler && handler.send_response
52
55
  end
53
56
  end
54
57
  end
@@ -18,7 +18,6 @@ module Solargraph
18
18
  autoload :Dispatch, 'solargraph/language_server/host/dispatch'
19
19
  autoload :MessageWorker, 'solargraph/language_server/host/message_worker'
20
20
 
21
-
22
21
  include UriHelpers
23
22
  include Logging
24
23
  include Dispatch
@@ -29,7 +28,7 @@ module Solargraph
29
28
  def initialize
30
29
  @cancel_semaphore = Mutex.new
31
30
  @buffer_semaphore = Mutex.new
32
- @register_semaphore = Mutex.new
31
+ @request_mutex = Mutex.new
33
32
  @cancel = []
34
33
  @buffer = String.new
35
34
  @stopped = true
@@ -92,7 +91,9 @@ module Solargraph
92
91
  @cancel_semaphore.synchronize { @cancel.delete id }
93
92
  end
94
93
 
95
- # called by adapter, to handle the request
94
+ # Called by adapter, to handle the request
95
+ # @param request [Hash]
96
+ # @return [void]
96
97
  def process request
97
98
  message_worker.queue(request)
98
99
  end
@@ -363,19 +364,21 @@ module Solargraph
363
364
  # @yieldparam [Hash] The result sent by the client
364
365
  # @return [void]
365
366
  def send_request method, params, &block
366
- message = {
367
- jsonrpc: "2.0",
368
- method: method,
369
- params: params,
370
- id: @next_request_id
371
- }
372
- json = message.to_json
373
- requests[@next_request_id] = Request.new(@next_request_id, &block)
374
- envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
375
- queue envelope
376
- @next_request_id += 1
377
- logger.info "Server sent #{method}"
378
- logger.debug params
367
+ @request_mutex.synchronize do
368
+ message = {
369
+ jsonrpc: "2.0",
370
+ method: method,
371
+ params: params,
372
+ id: @next_request_id
373
+ }
374
+ json = message.to_json
375
+ requests[@next_request_id] = Request.new(@next_request_id, &block)
376
+ envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
377
+ queue envelope
378
+ @next_request_id += 1
379
+ logger.info "Server sent #{method}"
380
+ logger.debug params
381
+ end
379
382
  end
380
383
 
381
384
  # Register the methods as capabilities with the client.
@@ -386,20 +389,16 @@ module Solargraph
386
389
  # @return [void]
387
390
  def register_capabilities methods
388
391
  logger.debug "Registering capabilities: #{methods}"
389
- registrations = methods.select{|m| can_register?(m) and !registered?(m)}.map { |m|
392
+ registrations = methods.select { |m| can_register?(m) and !registered?(m) }.map do |m|
390
393
  @registered_capabilities.add m
391
394
  {
392
395
  id: m,
393
396
  method: m,
394
397
  registerOptions: dynamic_capability_options[m]
395
398
  }
396
- }
397
- return if registrations.empty?
398
- @register_semaphore.synchronize do
399
- send_request 'client/registerCapability', {
400
- registrations: registrations
401
- }
402
399
  end
400
+ return if registrations.empty?
401
+ send_request 'client/registerCapability', { registrations: registrations }
403
402
  end
404
403
 
405
404
  # Unregister the methods with the client.
@@ -418,11 +417,7 @@ module Solargraph
418
417
  }
419
418
  }
420
419
  return if unregisterations.empty?
421
- @register_semaphore.synchronize do
422
- send_request 'client/unregisterCapability', {
423
- unregisterations: unregisterations
424
- }
425
- end
420
+ send_request 'client/unregisterCapability', { unregisterations: unregisterations }
426
421
  end
427
422
 
428
423
  # Flag a method as available for dynamic registration.
@@ -430,9 +425,7 @@ module Solargraph
430
425
  # @param method [String] The method name, e.g., 'textDocument/completion'
431
426
  # @return [void]
432
427
  def allow_registration method
433
- @register_semaphore.synchronize do
434
- @dynamic_capabilities.add method
435
- end
428
+ @dynamic_capabilities.add method
436
429
  end
437
430
 
438
431
  # True if the specified LSP method can be dynamically registered.
@@ -549,10 +542,11 @@ module Solargraph
549
542
  # @param line [Integer]
550
543
  # @param column [Integer]
551
544
  # @param strip [Boolean] Strip special characters from variable names
545
+ # @param only [Boolean] If true, search current file only
552
546
  # @return [Array<Solargraph::Range>]
553
- def references_from uri, line, column, strip: true
547
+ def references_from uri, line, column, strip: true, only: false
554
548
  library = library_for(uri)
555
- library.references_from(uri_to_file(uri), line, column, strip: strip)
549
+ library.references_from(uri_to_file(uri), line, column, strip: strip, only: only)
556
550
  end
557
551
 
558
552
  # @param query [String]
@@ -638,6 +632,7 @@ module Solargraph
638
632
  'diagnostics' => false,
639
633
  'formatting' => false,
640
634
  'folding' => true,
635
+ 'highlights' => true,
641
636
  'logLevel' => 'warn'
642
637
  }
643
638
  end
@@ -722,7 +717,7 @@ module Solargraph
722
717
  return change if diffs.length.zero? || diffs.length > 1 || diffs.first.length > 1
723
718
  # @type [Diff::LCS::Change]
724
719
  diff = diffs.first.first
725
- return change unless diff.adding? && ['.', ':'].include?(diff.element)
720
+ return change unless diff.adding? && ['.', ':', '(', ',', ' '].include?(diff.element)
726
721
  position = Solargraph::Position.from_offset(source.code, diff.position)
727
722
  {
728
723
  'range' => {
@@ -790,6 +785,9 @@ module Solargraph
790
785
  },
791
786
  'textDocument/codeAction' => {
792
787
  codeActionProvider: true
788
+ },
789
+ 'textDocument/documentHighlight' => {
790
+ documentHighlightProvider: true
793
791
  }
794
792
  }
795
793
  end
@@ -36,6 +36,7 @@ module Solargraph
36
36
  result[:capabilities].merge! static_references unless dynamic_registration_for?('textDocument', 'references')
37
37
  result[:capabilities].merge! static_workspace_symbols unless dynamic_registration_for?('workspace', 'symbol')
38
38
  result[:capabilities].merge! static_folding_range unless dynamic_registration_for?('textDocument', 'foldingRange')
39
+ result[:capabilities].merge! static_highlights unless dynamic_registration_for?('textDocument', 'documentHighlight')
39
40
  # @todo Temporarily disabled
40
41
  # result[:capabilities].merge! static_code_action unless dynamic_registration_for?('textDocument', 'codeAction')
41
42
  set_result result
@@ -138,6 +139,12 @@ module Solargraph
138
139
  }
139
140
  end
140
141
 
142
+ def static_highlights
143
+ {
144
+ documentHighlightProvider: true
145
+ }
146
+ end
147
+
141
148
  # @param section [String]
142
149
  # @param capability [String]
143
150
  # @return [Boolean]
@@ -17,6 +17,7 @@ module Solargraph
17
17
  textDocument/rename
18
18
  textDocument/prepareRename
19
19
  textDocument/foldingRange
20
+ textDocument/documentHighlight
20
21
  workspace/symbol
21
22
  ]
22
23
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Solargraph::LanguageServer::Message::TextDocument
4
+ class DocumentHighlight < Base
5
+ def process
6
+ locs = host.references_from(params['textDocument']['uri'], params['position']['line'], params['position']['character'], strip: true, only: true)
7
+ result = locs.map do |loc|
8
+ {
9
+ range: loc.range.to_hash,
10
+ kind: 1
11
+ }
12
+ end
13
+ set_result result
14
+ end
15
+ end
16
+ end
@@ -4,24 +4,24 @@ module Solargraph
4
4
  module LanguageServer
5
5
  module Message
6
6
  module TextDocument
7
- autoload :Base, 'solargraph/language_server/message/text_document/base'
8
- autoload :Completion, 'solargraph/language_server/message/text_document/completion'
9
- autoload :DidOpen, 'solargraph/language_server/message/text_document/did_open'
10
- autoload :DidChange, 'solargraph/language_server/message/text_document/did_change'
11
- autoload :DidClose, 'solargraph/language_server/message/text_document/did_close'
12
- autoload :DidSave, 'solargraph/language_server/message/text_document/did_save'
13
- autoload :Hover, 'solargraph/language_server/message/text_document/hover'
14
- autoload :SignatureHelp, 'solargraph/language_server/message/text_document/signature_help'
15
- autoload :DiagnosticsQueue, 'solargraph/language_server/message/text_document/diagnostics_queue'
16
- autoload :OnTypeFormatting, 'solargraph/language_server/message/text_document/on_type_formatting'
17
- autoload :Definition, 'solargraph/language_server/message/text_document/definition'
18
- autoload :DocumentSymbol, 'solargraph/language_server/message/text_document/document_symbol'
19
- autoload :Formatting, 'solargraph/language_server/message/text_document/formatting'
20
- autoload :References, 'solargraph/language_server/message/text_document/references'
21
- autoload :Rename, 'solargraph/language_server/message/text_document/rename'
22
- autoload :PrepareRename, 'solargraph/language_server/message/text_document/prepare_rename'
23
- autoload :FoldingRange, 'solargraph/language_server/message/text_document/folding_range'
24
- autoload :CodeAction, 'solargraph/language_server/message/text_document/code_action'
7
+ autoload :Base, 'solargraph/language_server/message/text_document/base'
8
+ autoload :Completion, 'solargraph/language_server/message/text_document/completion'
9
+ autoload :DidOpen, 'solargraph/language_server/message/text_document/did_open'
10
+ autoload :DidChange, 'solargraph/language_server/message/text_document/did_change'
11
+ autoload :DidClose, 'solargraph/language_server/message/text_document/did_close'
12
+ autoload :DidSave, 'solargraph/language_server/message/text_document/did_save'
13
+ autoload :Hover, 'solargraph/language_server/message/text_document/hover'
14
+ autoload :SignatureHelp, 'solargraph/language_server/message/text_document/signature_help'
15
+ autoload :DiagnosticsQueue, 'solargraph/language_server/message/text_document/diagnostics_queue'
16
+ autoload :OnTypeFormatting, 'solargraph/language_server/message/text_document/on_type_formatting'
17
+ autoload :Definition, 'solargraph/language_server/message/text_document/definition'
18
+ autoload :DocumentSymbol, 'solargraph/language_server/message/text_document/document_symbol'
19
+ autoload :Formatting, 'solargraph/language_server/message/text_document/formatting'
20
+ autoload :References, 'solargraph/language_server/message/text_document/references'
21
+ autoload :Rename, 'solargraph/language_server/message/text_document/rename'
22
+ autoload :PrepareRename, 'solargraph/language_server/message/text_document/prepare_rename'
23
+ autoload :FoldingRange, 'solargraph/language_server/message/text_document/folding_range'
24
+ autoload :DocumentHighlight, 'solargraph/language_server/message/text_document/document_highlight'
25
25
  end
26
26
  end
27
27
  end
@@ -22,6 +22,7 @@ module Solargraph::LanguageServer::Message::Workspace
22
22
  (host.options['definitions'] ? y : n).push('textDocument/definition')
23
23
  (host.options['references'] ? y : n).push('textDocument/references')
24
24
  (host.options['folding'] ? y : n).push('textDocument/folding')
25
+ (host.options['highlights'] ? y : n).push('textDocument/documentHighlight')
25
26
  host.register_capabilities y
26
27
  host.unregister_capabilities n
27
28
  end
@@ -73,7 +73,8 @@ module Solargraph
73
73
  register 'textDocument/rename', TextDocument::Rename
74
74
  register 'textDocument/prepareRename', TextDocument::PrepareRename
75
75
  register 'textDocument/foldingRange', TextDocument::FoldingRange
76
- register 'textDocument/codeAction', TextDocument::CodeAction
76
+ # register 'textDocument/codeAction', TextDocument::CodeAction
77
+ register 'textDocument/documentHighlight', TextDocument::DocumentHighlight
77
78
  register 'workspace/didChangeWatchedFiles', Workspace::DidChangeWatchedFiles
78
79
  register 'workspace/didChangeConfiguration', Workspace::DidChangeConfiguration
79
80
  register 'workspace/didChangeWorkspaceFolders', Workspace::DidChangeWorkspaceFolders
@@ -216,33 +216,35 @@ module Solargraph
216
216
  # @param line [Integer]
217
217
  # @param column [Integer]
218
218
  # @param strip [Boolean] Strip special characters from variable names
219
+ # @param only [Boolean] Search for references in the current file only
219
220
  # @return [Array<Solargraph::Range>]
220
221
  # @todo Take a Location instead of filename/line/column
221
- def references_from filename, line, column, strip: false
222
+ def references_from filename, line, column, strip: false, only: false
222
223
  cursor = api_map.cursor_at(filename, Position.new(line, column))
223
224
  clip = api_map.clip(cursor)
224
- pins = clip.define
225
- return [] if pins.empty?
225
+ pin = clip.define.first
226
+ return [] unless pin
226
227
  result = []
227
- pins.uniq.each do |pin|
228
- (workspace.sources + (@current ? [@current] : [])).uniq(&:filename).each do |source|
229
- found = source.references(pin.name)
230
- found.select! do |loc|
231
- referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character)
232
- # HACK: The additional location comparison is necessary because
233
- # Clip#define can return proxies for parameter pins
234
- referenced.any? { |r| r == pin || r.location == pin.location }
235
- end
236
- # HACK: for language clients that exclude special characters from the start of variable names
237
- if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
238
- found.map! do |loc|
239
- Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column))
240
- end
228
+ files = if only
229
+ [api_map.source_map(filename)]
230
+ else
231
+ (workspace.sources + (@current ? [@current] : []))
232
+ end
233
+ files.uniq(&:filename).each do |source|
234
+ found = source.references(pin.name)
235
+ found.select! do |loc|
236
+ referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character).first
237
+ referenced && referenced.path == pin.path
238
+ end
239
+ # HACK: for language clients that exclude special characters from the start of variable names
240
+ if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
241
+ found.map! do |loc|
242
+ Solargraph::Location.new(loc.filename, Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line, loc.range.ending.column))
241
243
  end
242
- result.concat(found.sort do |a, b|
243
- a.range.start.line <=> b.range.start.line
244
- end)
245
244
  end
245
+ result.concat(found.sort do |a, b|
246
+ a.range.start.line <=> b.range.start.line
247
+ end)
246
248
  end
247
249
  result.uniq
248
250
  end
@@ -518,6 +520,7 @@ module Solargraph
518
520
 
519
521
  def maybe_map source
520
522
  return unless source
523
+ return unless @current == source || workspace.has_file?(source.filename)
521
524
  if source_map_hash.key?(source.filename)
522
525
  return if source_map_hash[source.filename].code == source.code &&
523
526
  source_map_hash[source.filename].source.synchronized? &&
@@ -71,6 +71,23 @@ module Solargraph
71
71
  else
72
72
  raise "No idea what to do with #{n}"
73
73
  end
74
+ elsif n.type == :csend
75
+ if n.children[0].is_a?(::Parser::AST::Node)
76
+ result.concat generate_links(n.children[0])
77
+ args = []
78
+ n.children[2..-1].each do |c|
79
+ args.push NodeChainer.chain(c)
80
+ end
81
+ result.push Chain::QCall.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
82
+ elsif n.children[0].nil?
83
+ args = []
84
+ n.children[2..-1].each do |c|
85
+ args.push NodeChainer.chain(c)
86
+ end
87
+ result.push Chain::QCall.new(n.children[1].to_s, args, @in_block > 0 || block_passed?(n))
88
+ else
89
+ raise "No idea what to do with #{n}"
90
+ end
74
91
  elsif n.type == :self
75
92
  result.push Chain::Head.new('self')
76
93
  elsif n.type == :zsuper
@@ -178,6 +178,7 @@ module Solargraph
178
178
 
179
179
  # @param cursor [Solargraph::Source::Cursor]
180
180
  def find_recipient_node cursor
181
+ return repaired_find_recipient_node(cursor) if cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '('
181
182
  source = cursor.source
182
183
  position = cursor.position
183
184
  offset = cursor.offset
@@ -210,6 +211,12 @@ module Solargraph
210
211
  nil
211
212
  end
212
213
 
214
+ def repaired_find_recipient_node cursor
215
+ cursor = cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
216
+ node = cursor.source.tree_at(cursor.position.line, cursor.position.column).first
217
+ return node if node && node.type == :send
218
+ end
219
+
213
220
  module DeepInference
214
221
  class << self
215
222
  CONDITIONAL = [:if, :unless]
@@ -5,15 +5,39 @@ module Solargraph
5
5
  module Legacy
6
6
  module NodeProcessors
7
7
  class BlockNode < Parser::NodeProcessor::Base
8
+ include Legacy::NodeMethods
9
+
8
10
  def process
11
+ if other_class_eval?
12
+ other_class = Solargraph::Pin::Namespace.new(
13
+ type: :class,
14
+ name: unpack_name(node.children[0].children[0])
15
+ )
16
+ make_block_in other_class.context
17
+ process_children region.update(closure: other_class)
18
+ else
19
+ make_block_in nil
20
+ process_children region.update(closure: pins.last)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def other_class_eval?
27
+ node.children[0].type == :send &&
28
+ node.children[0].children[1] == :class_eval &&
29
+ [:cbase, :const].include?(node.children[0].children[0]&.type)
30
+ end
31
+
32
+ def make_block_in context
9
33
  pins.push Solargraph::Pin::Block.new(
10
34
  location: get_node_location(node),
35
+ context: context,
11
36
  closure: region.closure,
12
37
  receiver: node.children[0],
13
38
  comments: comments_for(node),
14
39
  scope: region.scope || region.closure.context.scope
15
40
  )
16
- process_children region.update(closure: pins.last)
17
41
  end
18
42
  end
19
43
  end
@@ -40,11 +40,16 @@ module Solargraph
40
40
  # end
41
41
 
42
42
  def references source, name
43
+ if name.end_with?("=")
44
+ reg = /#{Regexp.escape name[0..-2]}\s*=/
45
+ extract_offset = ->(code, offset) { reg.match(code, offset).offset(0) }
46
+ else
47
+ extract_offset = ->(code, offset) { [soff = code.index(name, offset), soff + name.length] }
48
+ end
43
49
  inner_node_references(name, source.node).map do |n|
44
50
  rng = Range.from_node(n)
45
51
  offset = Position.to_offset(source.code, rng.start)
46
- soff = source.code.index(name, offset)
47
- eoff = soff + name.length
52
+ soff, eoff = extract_offset[source.code, offset]
48
53
  Location.new(
49
54
  source.filename,
50
55
  Range.new(
@@ -60,6 +60,11 @@ module Solargraph
60
60
  result.concat generate_links(c)
61
61
  end
62
62
  result.push Chain::Call.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
63
+ elsif n.type == :QCALL
64
+ n.children[0..-3].each do |c|
65
+ result.concat generate_links(c)
66
+ end
67
+ result.push Chain::QCall.new(n.children[-2].to_s, node_to_argchains(n.children.last), @in_block > 0 || block_passed?(n))
63
68
  elsif n.type == :ATTRASGN
64
69
  result.concat generate_links(n.children[0])
65
70
  result.push Chain::Call.new(n.children[1].to_s, node_to_argchains(n.children[2]), @in_block > 0 || block_passed?(n))
@@ -141,36 +141,45 @@ module Solargraph
141
141
  class << self
142
142
  protected
143
143
 
144
+ # @param cursor [Source::Cursor]
145
+ # @return [RubyVM::AbstractSyntaxTree::Node, nil]
144
146
  def synchronized_find_recipient_node cursor
147
+ cursor = maybe_adjust_cursor(cursor)
145
148
  source = cursor.source
146
149
  position = cursor.position
147
150
  offset = cursor.offset
148
151
  tree = source.tree_at(position.line, position.column)
149
- tree.shift while tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type) && !source.code_for(tree.first).strip.end_with?(')')
152
+ .select { |n| [:FCALL, :VCALL, :CALL].include?(n.type) }
153
+ unless source.repaired?
154
+ tree.shift while tree.first && !source.code_for(tree.first).strip.end_with?(')')
155
+ end
156
+ return tree.first if source.repaired? || source.code[0..offset-1] =~ /\(\s*$/
150
157
  tree.each do |node|
151
- if [:FCALL, :VCALL, :CALL].include?(node.type)
152
- args = node.children.find { |c| Parser.is_ast_node?(c) && [:ARRAY, :ZARRAY, :LIST].include?(c.type) }
153
- if args
154
- match = source.code[0..offset-1].match(/,[^\)]*\z/)
155
- rng = Solargraph::Range.from_node(args)
156
- if match
157
- rng = Solargraph::Range.new(rng.start, position)
158
- end
159
- return node if rng.contain?(position)
160
- elsif source.code[0..offset-1] =~ /\(\s*$/
161
- break unless source.code_for(node).strip.end_with?(')')
162
- return node
158
+ args = node.children.find { |c| Parser.is_ast_node?(c) && [:ARRAY, :ZARRAY, :LIST].include?(c.type) }
159
+ if args
160
+ match = source.code[0..offset-1].match(/,[^\)]*\z/)
161
+ rng = Solargraph::Range.from_node(args)
162
+ if match
163
+ rng = Solargraph::Range.new(rng.start, position)
163
164
  end
165
+ return node if rng.contain?(position)
164
166
  end
165
167
  end
166
168
  nil
167
169
  end
168
170
 
171
+ # @param cursor [Source::Cursor]
172
+ # @return [Source::Cursor]
173
+ def maybe_adjust_cursor cursor
174
+ return cursor unless (cursor.source.repaired? && cursor.source.code[cursor.offset - 1] == '(') || [',', ' '].include?(cursor.source.code[cursor.offset - 1])
175
+ cursor.source.cursor_at([cursor.position.line, cursor.position.column - 1])
176
+ end
177
+
169
178
  def unsynchronized_find_recipient_node cursor
170
179
  source = cursor.source
171
180
  position = cursor.position
172
181
  offset = cursor.offset
173
- if source.code[0..offset-1] =~ /\([A-Zaz0-9_\s]*\z$/ #&& source.code[offset] == ')'
182
+ if source.code[0..offset-1] =~ /\([A-Zaz0-9_\s]*\z$/
174
183
  tree = source.tree_at(position.line, position.column - 1)
175
184
  if tree.first && [:FCALL, :VCALL, :CALL].include?(tree.first.type)
176
185
  return tree.first
@@ -5,15 +5,39 @@ module Solargraph
5
5
  module Rubyvm
6
6
  module NodeProcessors
7
7
  class BlockNode < Parser::NodeProcessor::Base
8
+ include NodeMethods
9
+
8
10
  def process
11
+ if other_class_eval?
12
+ other_class = Solargraph::Pin::Namespace.new(
13
+ type: :class,
14
+ name: unpack_name(node.children[0].children[0])
15
+ )
16
+ make_block_in other_class.context
17
+ process_children region.update(closure: other_class)
18
+ else
19
+ make_block_in nil
20
+ process_children region.update(closure: pins.last)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def other_class_eval?
27
+ node.children[0].type == :CALL &&
28
+ node.children[0].children[1] == :class_eval &&
29
+ [:COLON2, :CONST].include?(node.children[0].children[0].type)
30
+ end
31
+
32
+ def make_block_in context
9
33
  pins.push Solargraph::Pin::Block.new(
10
34
  location: get_node_location(node),
35
+ context: context,
11
36
  closure: region.closure,
12
37
  receiver: node.children[0],
13
38
  comments: comments_for(node),
14
39
  scope: region.scope || region.closure.context.scope
15
40
  )
16
- process_children region.update(closure: pins.last)
17
41
  end
18
42
  end
19
43
  end
@@ -8,9 +8,10 @@ module Solargraph
8
8
  # @return [Parser::AST::Node]
9
9
  attr_reader :receiver
10
10
 
11
- def initialize receiver: nil, args: [], **splat
11
+ def initialize receiver: nil, args: [], context: nil, **splat
12
12
  super(**splat)
13
13
  @receiver = receiver
14
+ @context = context
14
15
  @parameters = args
15
16
  end
16
17
 
@@ -44,15 +45,24 @@ module Solargraph
44
45
  return nil unless api_map.rebindable_method_names.include?(word)
45
46
  chain = Parser.chain(receiver, location.filename)
46
47
  locals = api_map.source_map(location.filename).locals_at(location)
47
- if ['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'].include?(chain.links.last.word)
48
+ links_last_word = chain.links.last.word
49
+ if %w[instance_eval instance_exec class_eval class_exec module_eval module_exec].include?(links_last_word)
48
50
  return chain.base.infer(api_map, self, locals)
49
- else
50
- receiver_pin = chain.define(api_map, self, locals).first
51
- if receiver_pin && receiver_pin.docstring
52
- ys = receiver_pin.docstring.tag(:yieldself)
53
- if ys && ys.types && !ys.types.empty?
54
- return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
55
- end
51
+ end
52
+ if 'define_method' == links_last_word and chain.define(api_map, self, locals).first&.path == 'Module#define_method' # change class type to instance type
53
+ if chain.links.size > 1 # Class.define_method
54
+ ty = chain.base.infer(api_map, self, locals)
55
+ return Solargraph::ComplexType.parse(ty.namespace)
56
+ else # define_method without self
57
+ return Solargraph::ComplexType.parse(closure.binder.namespace)
58
+ end
59
+ end
60
+ # other case without early return, read block yieldself tags
61
+ receiver_pin = chain.define(api_map, self, locals).first
62
+ if receiver_pin && receiver_pin.docstring
63
+ ys = receiver_pin.docstring.tag(:yieldself)
64
+ if ys && ys.types && !ys.types.empty?
65
+ return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace)
56
66
  end
57
67
  end
58
68
  nil
@@ -80,7 +80,7 @@ module Solargraph
80
80
  end
81
81
  end
82
82
  end
83
- sections.map(&:to_s).join
83
+ sections.map(&:to_s).join.strip
84
84
  end
85
85
  end
86
86
 
@@ -18,19 +18,7 @@ module Solargraph
18
18
  true
19
19
  end
20
20
 
21
- # @param other [Pin::Base] The caller's block
22
- # @param position [Position, Array(Integer, Integer)] The caller's position
23
- # @return [Boolean]
24
- def visible_from?(other, position)
25
- position = Position.normalize(position)
26
- other.filename == filename &&
27
- match_tags(other.full_context.tag, full_context.tag) &&
28
- (other == closure ||
29
- (closure.location.range.contain?(other.location.range.start) && closure.location.range.contain?(other.location.range.ending))
30
- ) &&
31
- presence.contain?(position)
32
- end
33
-
21
+ # @param other_closure [Pin::Closure]
34
22
  # @param other_loc [Location]
35
23
  def visible_at?(other_closure, other_loc)
36
24
  return true if location.filename == other_loc.filename &&
@@ -51,6 +51,10 @@ module Solargraph
51
51
  clone.mark_head(false)
52
52
  end
53
53
 
54
+ def nullable?
55
+ false
56
+ end
57
+
54
58
  protected
55
59
 
56
60
  # Mark whether this link is the head of a chain
@@ -0,0 +1,11 @@
1
+ module Solargraph
2
+ class Source
3
+ class Chain
4
+ class QCall < Call
5
+ def nullable?
6
+ true
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -11,6 +11,7 @@ module Solargraph
11
11
  class Chain
12
12
  autoload :Link, 'solargraph/source/chain/link'
13
13
  autoload :Call, 'solargraph/source/chain/call'
14
+ autoload :QCall, 'solargraph/source/chain/q_call'
14
15
  autoload :Variable, 'solargraph/source/chain/variable'
15
16
  autoload :ClassVariable, 'solargraph/source/chain/class_variable'
16
17
  autoload :Constant, 'solargraph/source/chain/constant'
@@ -76,7 +77,8 @@ module Solargraph
76
77
  # @return [ComplexType]
77
78
  def infer api_map, name_pin, locals
78
79
  pins = define(api_map, name_pin, locals)
79
- infer_first_defined(pins, links.last.last_context, api_map)
80
+ type = infer_first_defined(pins, links.last.last_context, api_map)
81
+ maybe_nil(type)
80
82
  end
81
83
 
82
84
  # @return [Boolean]
@@ -101,6 +103,10 @@ module Solargraph
101
103
  @splat
102
104
  end
103
105
 
106
+ def nullable?
107
+ links.any?(&:nullable?)
108
+ end
109
+
104
110
  private
105
111
 
106
112
  # @param pins [Array<Pin::Base>]
@@ -146,6 +152,13 @@ module Solargraph
146
152
  return type if context.nil? || context.return_type.undefined?
147
153
  type.self_to(context.return_type.namespace)
148
154
  end
155
+
156
+ # @param type [ComplexType]
157
+ def maybe_nil type
158
+ return type if type.undefined? || type.void? || type.nullable?
159
+ return type unless nullable?
160
+ ComplexType.try_parse("#{type}, nil")
161
+ end
149
162
  end
150
163
  end
151
164
  end
@@ -42,7 +42,6 @@ module Solargraph
42
42
  @version = version
43
43
  @domains = []
44
44
  begin
45
- # @node, @comments = Source.parse_with_comments(@code, filename)
46
45
  @node, @comments = Solargraph::Parser.parse_with_comments(@code, filename)
47
46
  @parsed = true
48
47
  rescue Parser::SyntaxError, EncodingError => e
@@ -336,7 +335,6 @@ module Solargraph
336
335
  # @param parent [Symbol]
337
336
  # @return [void]
338
337
  def inner_folding_ranges top, result = [], parent = nil
339
- # return unless top.is_a?(::Parser::AST::Node)
340
338
  return unless Parser.is_ast_node?(top)
341
339
  if FOLDING_NODE_TYPES.include?(top.type)
342
340
  # @todo Smelly exception for hash's first-level array in RubyVM
@@ -433,7 +431,6 @@ module Solargraph
433
431
  # @return [void]
434
432
  def inner_tree_at node, position, stack
435
433
  return if node.nil?
436
- # here = Range.from_to(node.loc.expression.line, node.loc.expression.column, node.loc.expression.last_line, node.loc.expression.last_column)
437
434
  here = Range.from_node(node)
438
435
  if here.contain?(position) || colonized(here, position, node)
439
436
  stack.unshift node
@@ -53,11 +53,7 @@ module Solargraph
53
53
  #
54
54
  # @return [Array<Solargraph::Pin::Base>]
55
55
  def locals
56
- loc_pos = context_pin.location.range.contain?(cursor.position) ? cursor.position : context_pin.location.range.ending
57
- adj_pos = Position.new(loc_pos.line, (loc_pos.column.zero? ? 0 : loc_pos.column - 1))
58
- @locals ||= source_map.locals.select { |pin|
59
- pin.visible_from?(block, adj_pos)
60
- }.reverse
56
+ @locals ||= source_map.locals_at(location)
61
57
  end
62
58
 
63
59
  def gates
@@ -92,6 +88,10 @@ module Solargraph
92
88
  @source_map ||= api_map.source_map(cursor.filename)
93
89
  end
94
90
 
91
+ def location
92
+ Location.new(source_map.filename, Solargraph::Range.new(cursor.position, cursor.position))
93
+ end
94
+
95
95
  # @return [Solargraph::Pin::Base]
96
96
  def block
97
97
  @block ||= source_map.locate_block_pin(cursor.node_position.line, cursor.node_position.character)
@@ -61,7 +61,7 @@ module Solargraph
61
61
  end
62
62
 
63
63
  def process_comment source_position, comment_position, comment
64
- return unless comment =~ MACRO_REGEXP
64
+ return unless comment.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
65
65
  cmnt = remove_inline_comment_hashes(comment)
66
66
  parse = Solargraph::Source.parse_docstring(cmnt)
67
67
  last_line = 0
@@ -169,7 +169,7 @@ module Solargraph
169
169
  # @todo Handle parser errors in !parse directives
170
170
  end
171
171
  when 'domain'
172
- namespace = closure_at(source_position)
172
+ namespace = closure_at(source_position) || Pin::ROOT_PIN
173
173
  namespace.domains.concat directive.tag.types unless directive.tag.types.nil?
174
174
  when 'override'
175
175
  pins.push Pin::Reference::Override.new(location, directive.tag.name, docstring.tags)
@@ -182,7 +182,7 @@ module Solargraph
182
182
  started = false
183
183
  comment.lines.each { |l|
184
184
  # Trim the comment and minimum leading whitespace
185
- p = l.gsub(/^#/, '')
185
+ p = l.encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#/, '')
186
186
  if num.nil? && !p.strip.empty?
187
187
  num = p.index(/[^ ]/)
188
188
  started = true
@@ -197,7 +197,7 @@ module Solargraph
197
197
 
198
198
  # @return [void]
199
199
  def process_comment_directives
200
- return unless @code =~ MACRO_REGEXP
200
+ return unless @code.encode('UTF-8', invalid: :replace, replace: '?') =~ MACRO_REGEXP
201
201
  code_lines = @code.lines
202
202
  @source.associated_comments.each do |line, comments|
203
203
  src_pos = line ? Position.new(line, code_lines[line].to_s.chomp.index(/[^\s]/) || 0) : Position.new(code_lines.length, 0)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Solargraph
4
- VERSION = '0.43.1'
4
+ VERSION = '0.44.1'
5
5
  end
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'open3'
4
+ require 'rubygems'
5
+
3
6
  module Solargraph
4
7
  # A workspace consists of the files in a project's directory and the
5
8
  # project's configuration. It provides a Source for each file to be used
@@ -168,19 +171,20 @@ module Solargraph
168
171
  # HACK: Evaluating gemspec files violates the goal of not running
169
172
  # workspace code, but this is how Gem::Specification.load does it
170
173
  # anyway.
171
- Dir.chdir base do
174
+ cmd = ['ruby', '-e', "require 'rubygems'; require 'json'; spec = eval(File.read('#{file}'), TOPLEVEL_BINDING, '#{file}'); return unless Gem::Specification === spec; puts({name: spec.name, paths: spec.require_paths}.to_json)"]
175
+ o, e, s = Open3.capture3(*cmd)
176
+ if s.success?
172
177
  begin
173
- # @type [Gem::Specification]
174
- spec = eval(File.read(file), TOPLEVEL_BINDING, file)
175
- next unless Gem::Specification === spec
176
- @gemnames.push spec.name
177
- result.concat(spec.require_paths.map { |path| File.join(base, path) })
178
- rescue RuntimeError, ScriptError, Errno::ENOENT => e
179
- # Don't die if we have an error during eval-ing a gem spec.
180
- # Concat the default lib directory instead.
178
+ hash = o && !o.empty? ? JSON.parse(o.split("\n").last) : {}
179
+ next if hash.empty?
180
+ @gemnames.push hash['name']
181
+ result.concat(hash['paths'].map { |path| File.join(base, path) })
182
+ rescue StandardError => e
181
183
  Solargraph.logger.warn "Error reading #{file}: [#{e.class}] #{e.message}"
182
- result.push File.join(base, 'lib')
183
184
  end
185
+ else
186
+ Solargraph.logger.warn "Error reading #{file}"
187
+ Solargraph.logger.warn e
184
188
  end
185
189
  end
186
190
  result.concat(config.require_paths.map { |p| File.join(directory, p) })
@@ -10,6 +10,8 @@ module Solargraph
10
10
  # stdlib, and gems.
11
11
  #
12
12
  class YardMap
13
+ class NoYardocError < StandardError; end
14
+
13
15
  autoload :Cache, 'solargraph/yard_map/cache'
14
16
  autoload :CoreDocs, 'solargraph/yard_map/core_docs'
15
17
  autoload :CoreGen, 'solargraph/yard_map/core_gen'
@@ -86,7 +88,7 @@ module Solargraph
86
88
  @rebindable_method_names ||= pins_by_class(Pin::Method)
87
89
  .select { |pin| pin.comments && pin.comments.include?('@yieldself') }
88
90
  .map(&:name)
89
- .concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec'])
91
+ .concat(['instance_eval', 'instance_exec', 'class_eval', 'class_exec', 'module_eval', 'module_exec', 'define_method'])
90
92
  .to_set
91
93
  end
92
94
 
@@ -224,7 +226,7 @@ module Solargraph
224
226
  result.concat process_yardoc yd, spec
225
227
  result.concat add_gem_dependencies(spec) if with_dependencies?
226
228
  end
227
- rescue Gem::LoadError => e
229
+ rescue Gem::LoadError, NoYardocError => e
228
230
  base = r.split('/').first
229
231
  next if from_std.include?(base)
230
232
  from_std.push base
@@ -299,6 +301,7 @@ module Solargraph
299
301
  result = Marshal.load(dump)
300
302
  return result unless result.nil? || result.empty?
301
303
  Solargraph.logger.warn "Empty cache for #{spec.name} #{spec.version}. Reloading"
304
+ File.unlink ser
302
305
  rescue StandardError => e
303
306
  Solargraph.logger.warn "Error loading pin cache: [#{e.class}] #{e.message}"
304
307
  File.unlink ser
@@ -315,6 +318,7 @@ module Solargraph
315
318
  Solargraph.logger.info "Loading #{spec.name} #{spec.version} from #{y}"
316
319
  load_yardoc y
317
320
  result = Mapper.new(YARD::Registry.all, spec).map
321
+ raise NoYardocError, "Yardoc at #{y} is empty" if result.empty?
318
322
  if spec
319
323
  ser = File.join(CoreDocs.cache_dir, 'gems', "#{spec.name}-#{spec.version}.ser")
320
324
  file = File.open(ser, 'wb')
data/solargraph.gemspec CHANGED
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
34
34
  s.add_runtime_dependency 'tilt', '~> 2.0'
35
35
  s.add_runtime_dependency 'yard', '~> 0.9', '>= 0.9.24'
36
36
 
37
- s.add_development_dependency 'pry', '~> 0.11.3'
37
+ s.add_development_dependency 'pry'
38
38
  s.add_development_dependency 'public_suffix', '~> 3.1'
39
39
  s.add_development_dependency 'rspec', '~> 3.5', '>= 3.5.0'
40
40
  s.add_development_dependency 'simplecov', '~> 0.14'
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.43.1
4
+ version: 0.44.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fred Snyder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-20 00:00:00.000000000 Z
11
+ date: 2021-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backport
@@ -222,16 +222,16 @@ dependencies:
222
222
  name: pry
223
223
  requirement: !ruby/object:Gem::Requirement
224
224
  requirements:
225
- - - "~>"
225
+ - - ">="
226
226
  - !ruby/object:Gem::Version
227
- version: 0.11.3
227
+ version: '0'
228
228
  type: :development
229
229
  prerelease: false
230
230
  version_requirements: !ruby/object:Gem::Requirement
231
231
  requirements:
232
- - - "~>"
232
+ - - ">="
233
233
  - !ruby/object:Gem::Version
234
- version: 0.11.3
234
+ version: '0'
235
235
  - !ruby/object:Gem::Dependency
236
236
  name: public_suffix
237
237
  requirement: !ruby/object:Gem::Requirement
@@ -381,6 +381,7 @@ files:
381
381
  - lib/solargraph/language_server/message/text_document/did_close.rb
382
382
  - lib/solargraph/language_server/message/text_document/did_open.rb
383
383
  - lib/solargraph/language_server/message/text_document/did_save.rb
384
+ - lib/solargraph/language_server/message/text_document/document_highlight.rb
384
385
  - lib/solargraph/language_server/message/text_document/document_symbol.rb
385
386
  - lib/solargraph/language_server/message/text_document/folding_range.rb
386
387
  - lib/solargraph/language_server/message/text_document/formatting.rb
@@ -509,6 +510,7 @@ files:
509
510
  - lib/solargraph/source/chain/link.rb
510
511
  - lib/solargraph/source/chain/literal.rb
511
512
  - lib/solargraph/source/chain/or.rb
513
+ - lib/solargraph/source/chain/q_call.rb
512
514
  - lib/solargraph/source/chain/variable.rb
513
515
  - lib/solargraph/source/chain/z_super.rb
514
516
  - lib/solargraph/source/change.rb