solargraph 0.43.0 → 0.44.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +20 -0
- data/README.md +2 -1
- data/lib/solargraph/documentor.rb +10 -12
- data/lib/solargraph/language_server/host/message_worker.rb +59 -0
- data/lib/solargraph/language_server/host.rb +54 -37
- data/lib/solargraph/language_server/message/base.rb +6 -2
- data/lib/solargraph/language_server/message/initialize.rb +7 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -0
- data/lib/solargraph/language_server/message/text_document.rb +18 -18
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +1 -0
- data/lib/solargraph/language_server/message.rb +2 -1
- data/lib/solargraph/language_server/transport/adapter.rb +1 -2
- data/lib/solargraph/library.rb +23 -20
- data/lib/solargraph/parser/comment_ripper.rb +1 -1
- data/lib/solargraph/parser/legacy/class_methods.rb +25 -0
- data/lib/solargraph/parser/legacy/node_methods.rb +7 -0
- data/lib/solargraph/parser/rubyvm/node_methods.rb +23 -14
- data/lib/solargraph/pin/namespace.rb +8 -2
- data/lib/solargraph/source_map/mapper.rb +2 -0
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +1 -1
- data/lib/solargraph/workspace.rb +14 -10
- data/lib/solargraph/yard_map.rb +5 -1
- data/lib/solargraph.rb +1 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0827e2be47eea923c2f61688ce4e97efa11d3d801f094ffb8a6cdb73a7fb52b3'
|
4
|
+
data.tar.gz: dcbad1eaa64acab63ccc511a93c0e1370fc469815e2e67735fc79c2f4dc08038
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa050d901186e2385685d2aab7934f611517d68b549f4cb064ab7c3524f99e890488675a06483c2b1f2e2cafc0417a3367972a1ea8b6c6614a3465e867313b03
|
7
|
+
data.tar.gz: 4b12d6b0f65f53afd0ccbbdfc84a9fe8159f2f3a4bb3c625a84f1a9ee80be53f8c8b1d1ecfbae9bcf01ceff691388af5d0cef7271bb5470730fc4aa7a2471df9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
## 0.44.0 - September 27, 2021
|
2
|
+
- Allow opening parenthesis, space, and comma when using Diff::LCS (#465)
|
3
|
+
- Support textDocument/documentHighlight
|
4
|
+
- Library#references_from performs shallow matches
|
5
|
+
|
6
|
+
## 0.43.3 - September 25, 2021
|
7
|
+
- Avoid Dir.chdir in Bundler processes (#481)
|
8
|
+
- Check stdlib for gems with empty yardocs
|
9
|
+
- Library#maybe_map checks for source in workspace
|
10
|
+
|
11
|
+
## 0.43.2 - September 23, 2021
|
12
|
+
- Synchronize server requests (#461)
|
13
|
+
|
14
|
+
## 0.43.1 - September 20, 2021
|
15
|
+
- Complete nested namespaces in open gates
|
16
|
+
- SourceMap::Mapper reports filename for encoding errors (#474)
|
17
|
+
- Handle request on a specific thread, and cancel completion when there has newer completion request (#459)
|
18
|
+
- Fix namespace links generated by views/_method.erb (#472)
|
19
|
+
- Source handles long squiggly heredocs (#460)
|
20
|
+
|
1
21
|
## 0.43.0 - July 25, 2021
|
2
22
|
- Correct arity checks when restarg precedes arg (#418)
|
3
23
|
- Improve the performance of catalog by 4 times (#457)
|
data/README.md
CHANGED
@@ -34,7 +34,8 @@ Plug-ins and extensions are available for the following editors:
|
|
34
34
|
* GitHub: https://github.com/autozimu/LanguageClient-neovim
|
35
35
|
|
36
36
|
* **Emacs**
|
37
|
-
* GitHub: https://github.com/
|
37
|
+
* GitHub: `eglot.el`, https://github.com/joaotavora/eglot
|
38
|
+
* GitHub: `lsp-mode.el`, https://github.com/emacs-lsp/lsp-mode
|
38
39
|
|
39
40
|
* **Eclipse**
|
40
41
|
* Plugin: https://marketplace.eclipse.org/content/ruby-solargraph
|
@@ -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
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
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
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module LanguageServer
|
5
|
+
class Host
|
6
|
+
# A serial worker Thread to handle message.
|
7
|
+
#
|
8
|
+
# this make check pending message possible, and maybe cancelled to speedup process
|
9
|
+
class MessageWorker
|
10
|
+
# @param host [Host]
|
11
|
+
def initialize(host)
|
12
|
+
@host = host
|
13
|
+
@mutex = Mutex.new
|
14
|
+
@resource = ConditionVariable.new
|
15
|
+
@stopped = true
|
16
|
+
end
|
17
|
+
|
18
|
+
# pending handle messages
|
19
|
+
def messages
|
20
|
+
@messages ||= []
|
21
|
+
end
|
22
|
+
|
23
|
+
def stopped?
|
24
|
+
@stopped
|
25
|
+
end
|
26
|
+
|
27
|
+
def stop
|
28
|
+
@stopped = true
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param message [Hash] The message should be handle. will pass back to Host#receive
|
32
|
+
# @return [void]
|
33
|
+
def queue(message)
|
34
|
+
@mutex.synchronize do
|
35
|
+
messages.push(message)
|
36
|
+
@resource.signal
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def start
|
41
|
+
return unless @stopped
|
42
|
+
@stopped = false
|
43
|
+
Thread.new do
|
44
|
+
tick until stopped?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def tick
|
49
|
+
message = @mutex.synchronize do
|
50
|
+
@resource.wait(@mutex) if messages.empty?
|
51
|
+
messages.shift
|
52
|
+
end
|
53
|
+
handler = @host.receive(message)
|
54
|
+
handler && handler.send_response
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -12,10 +12,11 @@ module Solargraph
|
|
12
12
|
# safety for multi-threaded transports.
|
13
13
|
#
|
14
14
|
class Host
|
15
|
-
autoload :Diagnoser,
|
16
|
-
autoload :Cataloger,
|
17
|
-
autoload :Sources,
|
18
|
-
autoload :Dispatch,
|
15
|
+
autoload :Diagnoser, 'solargraph/language_server/host/diagnoser'
|
16
|
+
autoload :Cataloger, 'solargraph/language_server/host/cataloger'
|
17
|
+
autoload :Sources, 'solargraph/language_server/host/sources'
|
18
|
+
autoload :Dispatch, 'solargraph/language_server/host/dispatch'
|
19
|
+
autoload :MessageWorker, 'solargraph/language_server/host/message_worker'
|
19
20
|
|
20
21
|
include UriHelpers
|
21
22
|
include Logging
|
@@ -27,7 +28,7 @@ module Solargraph
|
|
27
28
|
def initialize
|
28
29
|
@cancel_semaphore = Mutex.new
|
29
30
|
@buffer_semaphore = Mutex.new
|
30
|
-
@
|
31
|
+
@request_mutex = Mutex.new
|
31
32
|
@cancel = []
|
32
33
|
@buffer = String.new
|
33
34
|
@stopped = true
|
@@ -45,6 +46,7 @@ module Solargraph
|
|
45
46
|
diagnoser.start
|
46
47
|
cataloger.start
|
47
48
|
sources.start
|
49
|
+
message_worker.start
|
48
50
|
end
|
49
51
|
|
50
52
|
# Update the configuration options with the provided hash.
|
@@ -89,8 +91,15 @@ module Solargraph
|
|
89
91
|
@cancel_semaphore.synchronize { @cancel.delete id }
|
90
92
|
end
|
91
93
|
|
94
|
+
# Called by adapter, to handle the request
|
95
|
+
# @param request [Hash]
|
96
|
+
# @return [void]
|
97
|
+
def process request
|
98
|
+
message_worker.queue(request)
|
99
|
+
end
|
100
|
+
|
92
101
|
# Start processing a request from the client. After the message is
|
93
|
-
# processed,
|
102
|
+
# processed, caller is responsible for sending the response.
|
94
103
|
#
|
95
104
|
# @param request [Hash] The contents of the message.
|
96
105
|
# @return [Solargraph::LanguageServer::Message::Base] The message handler.
|
@@ -355,19 +364,21 @@ module Solargraph
|
|
355
364
|
# @yieldparam [Hash] The result sent by the client
|
356
365
|
# @return [void]
|
357
366
|
def send_request method, params, &block
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
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
|
371
382
|
end
|
372
383
|
|
373
384
|
# Register the methods as capabilities with the client.
|
@@ -378,20 +389,16 @@ module Solargraph
|
|
378
389
|
# @return [void]
|
379
390
|
def register_capabilities methods
|
380
391
|
logger.debug "Registering capabilities: #{methods}"
|
381
|
-
registrations = methods.select{|m| can_register?(m) and !registered?(m)}.map
|
392
|
+
registrations = methods.select { |m| can_register?(m) and !registered?(m) }.map do |m|
|
382
393
|
@registered_capabilities.add m
|
383
394
|
{
|
384
395
|
id: m,
|
385
396
|
method: m,
|
386
397
|
registerOptions: dynamic_capability_options[m]
|
387
398
|
}
|
388
|
-
}
|
389
|
-
return if registrations.empty?
|
390
|
-
@register_semaphore.synchronize do
|
391
|
-
send_request 'client/registerCapability', {
|
392
|
-
registrations: registrations
|
393
|
-
}
|
394
399
|
end
|
400
|
+
return if registrations.empty?
|
401
|
+
send_request 'client/registerCapability', { registrations: registrations }
|
395
402
|
end
|
396
403
|
|
397
404
|
# Unregister the methods with the client.
|
@@ -410,11 +417,7 @@ module Solargraph
|
|
410
417
|
}
|
411
418
|
}
|
412
419
|
return if unregisterations.empty?
|
413
|
-
|
414
|
-
send_request 'client/unregisterCapability', {
|
415
|
-
unregisterations: unregisterations
|
416
|
-
}
|
417
|
-
end
|
420
|
+
send_request 'client/unregisterCapability', { unregisterations: unregisterations }
|
418
421
|
end
|
419
422
|
|
420
423
|
# Flag a method as available for dynamic registration.
|
@@ -422,9 +425,7 @@ module Solargraph
|
|
422
425
|
# @param method [String] The method name, e.g., 'textDocument/completion'
|
423
426
|
# @return [void]
|
424
427
|
def allow_registration method
|
425
|
-
@
|
426
|
-
@dynamic_capabilities.add method
|
427
|
-
end
|
428
|
+
@dynamic_capabilities.add method
|
428
429
|
end
|
429
430
|
|
430
431
|
# True if the specified LSP method can be dynamically registered.
|
@@ -451,6 +452,7 @@ module Solargraph
|
|
451
452
|
def stop
|
452
453
|
return if @stopped
|
453
454
|
@stopped = true
|
455
|
+
message_worker.stop
|
454
456
|
cataloger.stop
|
455
457
|
diagnoser.stop
|
456
458
|
sources.stop
|
@@ -513,6 +515,11 @@ module Solargraph
|
|
513
515
|
library.completions_at uri_to_file(uri), line, column
|
514
516
|
end
|
515
517
|
|
518
|
+
# @return [Bool] if has pending completion request
|
519
|
+
def has_pending_completions?
|
520
|
+
message_worker.messages.reverse_each.any? { |req| req['method'] == 'textDocument/completion' }
|
521
|
+
end
|
522
|
+
|
516
523
|
# @param uri [String]
|
517
524
|
# @param line [Integer]
|
518
525
|
# @param column [Integer]
|
@@ -535,10 +542,11 @@ module Solargraph
|
|
535
542
|
# @param line [Integer]
|
536
543
|
# @param column [Integer]
|
537
544
|
# @param strip [Boolean] Strip special characters from variable names
|
545
|
+
# @param only [Boolean] If true, search current file only
|
538
546
|
# @return [Array<Solargraph::Range>]
|
539
|
-
def references_from uri, line, column, strip: true
|
547
|
+
def references_from uri, line, column, strip: true, only: false
|
540
548
|
library = library_for(uri)
|
541
|
-
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)
|
542
550
|
end
|
543
551
|
|
544
552
|
# @param query [String]
|
@@ -624,6 +632,7 @@ module Solargraph
|
|
624
632
|
'diagnostics' => false,
|
625
633
|
'formatting' => false,
|
626
634
|
'folding' => true,
|
635
|
+
'highlights' => true,
|
627
636
|
'logLevel' => 'warn'
|
628
637
|
}
|
629
638
|
end
|
@@ -646,6 +655,11 @@ module Solargraph
|
|
646
655
|
|
647
656
|
private
|
648
657
|
|
658
|
+
# @return [MessageWorker]
|
659
|
+
def message_worker
|
660
|
+
@message_worker ||= MessageWorker.new(self)
|
661
|
+
end
|
662
|
+
|
649
663
|
# @return [Diagnoser]
|
650
664
|
def diagnoser
|
651
665
|
@diagnoser ||= Diagnoser.new(self)
|
@@ -703,7 +717,7 @@ module Solargraph
|
|
703
717
|
return change if diffs.length.zero? || diffs.length > 1 || diffs.first.length > 1
|
704
718
|
# @type [Diff::LCS::Change]
|
705
719
|
diff = diffs.first.first
|
706
|
-
return change unless diff.adding? && ['.', ':'].include?(diff.element)
|
720
|
+
return change unless diff.adding? && ['.', ':', '(', ',', ' '].include?(diff.element)
|
707
721
|
position = Solargraph::Position.from_offset(source.code, diff.position)
|
708
722
|
{
|
709
723
|
'range' => {
|
@@ -771,6 +785,9 @@ module Solargraph
|
|
771
785
|
},
|
772
786
|
'textDocument/codeAction' => {
|
773
787
|
codeActionProvider: true
|
788
|
+
},
|
789
|
+
'textDocument/documentHighlight' => {
|
790
|
+
documentHighlightProvider: true
|
774
791
|
}
|
775
792
|
}
|
776
793
|
end
|
@@ -62,10 +62,14 @@ module Solargraph
|
|
62
62
|
def send_response
|
63
63
|
return if id.nil?
|
64
64
|
if host.cancel?(id)
|
65
|
+
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#cancelRequest
|
66
|
+
# cancel should send response RequestCancelled
|
65
67
|
Solargraph::Logging.logger.info "Cancelled response to #{method}"
|
66
|
-
|
68
|
+
set_result nil
|
69
|
+
set_error ErrorCodes::REQUEST_CANCELLED, "cancelled by client"
|
70
|
+
else
|
71
|
+
Solargraph::Logging.logger.info "Sending response to #{method}"
|
67
72
|
end
|
68
|
-
Solargraph::Logging.logger.info "Sending response to #{method}"
|
69
73
|
response = {
|
70
74
|
jsonrpc: "2.0",
|
71
75
|
id: id,
|
@@ -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]
|
@@ -6,6 +6,8 @@ module Solargraph
|
|
6
6
|
module TextDocument
|
7
7
|
class Completion < Base
|
8
8
|
def process
|
9
|
+
return set_error(ErrorCodes::REQUEST_CANCELLED, "cancelled by so many request") if host.has_pending_completions?
|
10
|
+
|
9
11
|
line = params['position']['line']
|
10
12
|
col = params['position']['character']
|
11
13
|
begin
|
@@ -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,
|
8
|
-
autoload :Completion,
|
9
|
-
autoload :DidOpen,
|
10
|
-
autoload :DidChange,
|
11
|
-
autoload :DidClose,
|
12
|
-
autoload :DidSave,
|
13
|
-
autoload :Hover,
|
14
|
-
autoload :SignatureHelp,
|
15
|
-
autoload :DiagnosticsQueue,
|
16
|
-
autoload :OnTypeFormatting,
|
17
|
-
autoload :Definition,
|
18
|
-
autoload :DocumentSymbol,
|
19
|
-
autoload :Formatting,
|
20
|
-
autoload :References,
|
21
|
-
autoload :Rename,
|
22
|
-
autoload :PrepareRename,
|
23
|
-
autoload :FoldingRange,
|
24
|
-
autoload :
|
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
|
data/lib/solargraph/library.rb
CHANGED
@@ -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
|
-
|
225
|
-
return []
|
225
|
+
pin = clip.define.first
|
226
|
+
return [] unless pin
|
226
227
|
result = []
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
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? &&
|
@@ -103,6 +103,31 @@ module Solargraph
|
|
103
103
|
en = Position.new(node.loc.last_line, node.loc.last_column)
|
104
104
|
Range.new(st, en)
|
105
105
|
end
|
106
|
+
|
107
|
+
def string_ranges node
|
108
|
+
return [] unless is_ast_node?(node)
|
109
|
+
result = []
|
110
|
+
if node.type == :str
|
111
|
+
result.push Range.from_node(node)
|
112
|
+
elsif node.type == :dstr
|
113
|
+
here = Range.from_node(node)
|
114
|
+
there = Range.from_node(node.children[1])
|
115
|
+
result.push Range.new(here.start, there.start)
|
116
|
+
end
|
117
|
+
node.children.each do |child|
|
118
|
+
result.concat string_ranges(child)
|
119
|
+
end
|
120
|
+
if node.type == :dstr && node.children.last.nil?
|
121
|
+
# result.push Range.new(result.last.ending, result.last.ending)
|
122
|
+
last = node.children[-2]
|
123
|
+
unless last.nil?
|
124
|
+
rng = Range.from_node(last)
|
125
|
+
pos = Position.new(rng.ending.line, rng.ending.column - 1)
|
126
|
+
result.push Range.new(pos, pos)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
result
|
130
|
+
end
|
106
131
|
end
|
107
132
|
end
|
108
133
|
end
|
@@ -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]
|
@@ -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
|
-
|
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
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
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$/
|
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
|
@@ -22,12 +22,18 @@ module Solargraph
|
|
22
22
|
@closure = Solargraph::Pin::ROOT_PIN
|
23
23
|
end
|
24
24
|
@open_gates = gates
|
25
|
-
if @
|
25
|
+
if @name.include?('::')
|
26
26
|
# In this case, a chained namespace was opened (e.g., Foo::Bar)
|
27
27
|
# but Foo does not exist.
|
28
28
|
parts = @name.split('::')
|
29
29
|
@name = parts.pop
|
30
|
-
|
30
|
+
closure_name = if [Solargraph::Pin::ROOT_PIN, nil].include?(closure)
|
31
|
+
''
|
32
|
+
else
|
33
|
+
closure.full_context.namespace + '::'
|
34
|
+
end
|
35
|
+
closure_name += parts.join('::')
|
36
|
+
@closure = Pin::Namespace.new(name: closure_name, gates: [parts.join('::')])
|
31
37
|
@context = nil
|
32
38
|
end
|
33
39
|
end
|
@@ -204,6 +204,8 @@ module Solargraph
|
|
204
204
|
com_pos = Position.new(line + 1 - comments.lines.length, 0)
|
205
205
|
process_comment(src_pos, com_pos, comments)
|
206
206
|
end
|
207
|
+
rescue StandardError => e
|
208
|
+
raise e.class, "Error processing comment directives in #{@filename}: #{e.message}"
|
207
209
|
end
|
208
210
|
end
|
209
211
|
end
|
data/lib/solargraph/version.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
Namespace:
|
3
3
|
</h2>
|
4
4
|
<p>
|
5
|
-
<a href="
|
5
|
+
<a href="solargraph:/document?query=<%= CGI.escape object.namespace.path %>"><%= object.namespace %></a>
|
6
6
|
</p>
|
7
7
|
<h2>
|
8
8
|
Overview:
|
data/lib/solargraph/workspace.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
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) })
|
data/lib/solargraph/yard_map.rb
CHANGED
@@ -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'
|
@@ -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/lib/solargraph.rb
CHANGED
@@ -57,6 +57,7 @@ module Solargraph
|
|
57
57
|
# A helper method that runs Bundler.with_unbundled_env or falls back to
|
58
58
|
# Bundler.with_clean_env for earlier versions of Bundler.
|
59
59
|
#
|
60
|
+
# @return [void]
|
60
61
|
def self.with_clean_env &block
|
61
62
|
meth = if Bundler.respond_to?(:with_unbundled_env)
|
62
63
|
:with_unbundled_env
|
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.
|
4
|
+
version: 0.44.0
|
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-
|
11
|
+
date: 2021-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backport
|
@@ -350,6 +350,7 @@ files:
|
|
350
350
|
- lib/solargraph/language_server/host/cataloger.rb
|
351
351
|
- lib/solargraph/language_server/host/diagnoser.rb
|
352
352
|
- lib/solargraph/language_server/host/dispatch.rb
|
353
|
+
- lib/solargraph/language_server/host/message_worker.rb
|
353
354
|
- lib/solargraph/language_server/host/sources.rb
|
354
355
|
- lib/solargraph/language_server/message.rb
|
355
356
|
- lib/solargraph/language_server/message/base.rb
|
@@ -380,6 +381,7 @@ files:
|
|
380
381
|
- lib/solargraph/language_server/message/text_document/did_close.rb
|
381
382
|
- lib/solargraph/language_server/message/text_document/did_open.rb
|
382
383
|
- lib/solargraph/language_server/message/text_document/did_save.rb
|
384
|
+
- lib/solargraph/language_server/message/text_document/document_highlight.rb
|
383
385
|
- lib/solargraph/language_server/message/text_document/document_symbol.rb
|
384
386
|
- lib/solargraph/language_server/message/text_document/folding_range.rb
|
385
387
|
- lib/solargraph/language_server/message/text_document/formatting.rb
|