solargraph 0.25.1 → 0.26.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/lib/solargraph.rb +18 -16
- data/lib/solargraph/api_map.rb +100 -161
- data/lib/solargraph/api_map/source_to_yard.rb +9 -9
- data/lib/solargraph/api_map/store.rb +50 -13
- data/lib/solargraph/basic_type.rb +33 -0
- data/lib/solargraph/basic_type_methods.rb +111 -0
- data/lib/solargraph/complex_type.rb +51 -89
- data/lib/solargraph/core_fills.rb +12 -8
- data/lib/solargraph/diagnostics/type_not_defined.rb +2 -2
- data/lib/solargraph/language_server.rb +3 -0
- data/lib/solargraph/language_server/completion_item_kinds.rb +2 -0
- data/lib/solargraph/language_server/error_codes.rb +2 -0
- data/lib/solargraph/language_server/host.rb +53 -6
- data/lib/solargraph/language_server/message.rb +13 -0
- data/lib/solargraph/language_server/message/text_document/definition.rb +4 -6
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +2 -1
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -1
- data/lib/solargraph/language_server/message_types.rb +2 -0
- data/lib/solargraph/language_server/request.rb +4 -0
- data/lib/solargraph/language_server/symbol_kinds.rb +28 -26
- data/lib/solargraph/language_server/transport.rb +3 -0
- data/lib/solargraph/language_server/uri_helpers.rb +2 -0
- data/lib/solargraph/library.rb +12 -7
- data/lib/solargraph/pin.rb +1 -1
- data/lib/solargraph/pin/attribute.rb +5 -5
- data/lib/solargraph/pin/base.rb +51 -16
- data/lib/solargraph/pin/base_variable.rb +25 -7
- data/lib/solargraph/pin/block.rb +18 -1
- data/lib/solargraph/pin/block_parameter.rb +42 -5
- data/lib/solargraph/pin/conversions.rb +4 -2
- data/lib/solargraph/pin/method.rb +6 -6
- data/lib/solargraph/pin/method_parameter.rb +6 -6
- data/lib/solargraph/pin/namespace.rb +7 -2
- data/lib/solargraph/pin/proxy_type.rb +39 -0
- data/lib/solargraph/pin/symbol.rb +20 -12
- data/lib/solargraph/pin/yard_pin/method.rb +2 -2
- data/lib/solargraph/source.rb +89 -38
- data/lib/solargraph/source/call_chainer.rb +273 -0
- data/lib/solargraph/source/chain.rb +104 -0
- data/lib/solargraph/source/chain/call.rb +72 -0
- data/lib/solargraph/source/chain/class_variable.rb +11 -0
- data/lib/solargraph/source/chain/constant.rb +17 -0
- data/lib/solargraph/source/chain/definition.rb +16 -0
- data/lib/solargraph/source/chain/global_variable.rb +11 -0
- data/lib/solargraph/source/chain/head.rb +20 -0
- data/lib/solargraph/source/chain/instance_variable.rb +11 -0
- data/lib/solargraph/source/chain/link.rb +33 -0
- data/lib/solargraph/source/chain/literal.rb +21 -0
- data/lib/solargraph/source/chain/variable.rb +11 -0
- data/lib/solargraph/source/change.rb +3 -1
- data/lib/solargraph/{api_map → source}/completion.rb +3 -1
- data/lib/solargraph/source/encoding_fixes.rb +21 -0
- data/lib/solargraph/source/fragment.rb +139 -284
- data/lib/solargraph/source/mapper.rb +27 -16
- data/lib/solargraph/source/node_chainer.rb +94 -0
- data/lib/solargraph/source/node_methods.rb +2 -2
- data/lib/solargraph/source/position.rb +4 -0
- data/lib/solargraph/source/range.rb +10 -2
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +13 -2
- metadata +20 -6
- data/lib/solargraph/api_map/probe.rb +0 -251
- data/lib/solargraph/api_map/type_methods.rb +0 -40
- data/lib/solargraph/pin/proxy_method.rb +0 -30
@@ -8,17 +8,21 @@ module Solargraph
|
|
8
8
|
'then', 'true', 'undef', 'unless', 'until', 'when', 'while', 'yield'
|
9
9
|
].freeze
|
10
10
|
|
11
|
-
METHODS_RETURNING_SELF = %w
|
11
|
+
METHODS_RETURNING_SELF = %w[
|
12
|
+
Array#select Array#reject Array#keep_if Array#delete_if
|
13
|
+
Enumerable#select
|
12
14
|
Object#clone Object#dup Object#freeze Object#taint Object#untaint
|
13
|
-
|
15
|
+
].freeze
|
14
16
|
|
15
|
-
METHODS_RETURNING_SUBTYPES = %w
|
16
|
-
Array#[]
|
17
|
-
|
17
|
+
METHODS_RETURNING_SUBTYPES = %w[
|
18
|
+
Array#[] Array#first Array#last
|
19
|
+
].freeze
|
18
20
|
|
19
|
-
METHODS_WITH_YIELDPARAM_SUBTYPES = %w
|
20
|
-
Array#each
|
21
|
-
|
21
|
+
METHODS_WITH_YIELDPARAM_SUBTYPES = %w[
|
22
|
+
Array#each Array#map Array#any? Array#all?
|
23
|
+
Enumerable#each_entry Enumerable#map Enumerable#any? Enumerable#all?
|
24
|
+
Set#each
|
25
|
+
].freeze
|
22
26
|
|
23
27
|
CUSTOM_RETURN_TYPES = {
|
24
28
|
'String#split' => 'Array<String>'
|
@@ -73,10 +73,10 @@ module Solargraph
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def defined_return_type? pin, api_map
|
76
|
-
return true unless pin.
|
76
|
+
return true unless pin.return_complex_type.undefined?
|
77
77
|
matches = api_map.get_method_stack(pin.namespace, pin.name, scope: pin.scope)
|
78
78
|
matches.shift
|
79
|
-
matches.any?{|m| !m.
|
79
|
+
matches.any?{|m| !m.return_complex_type.undefined?}
|
80
80
|
end
|
81
81
|
|
82
82
|
def defined_param_type? pin, param, api_map
|
@@ -3,6 +3,9 @@ require 'solargraph/language_server/completion_item_kinds'
|
|
3
3
|
require 'solargraph/language_server/symbol_kinds'
|
4
4
|
|
5
5
|
module Solargraph
|
6
|
+
# The LanguageServer namespace contains the classes and modules that compose
|
7
|
+
# concrete implementations of language servers.
|
8
|
+
#
|
6
9
|
module LanguageServer
|
7
10
|
autoload :Host, 'solargraph/language_server/host'
|
8
11
|
autoload :Message, 'solargraph/language_server/message'
|
@@ -136,7 +136,7 @@ module Solargraph
|
|
136
136
|
def open? uri
|
137
137
|
result = nil
|
138
138
|
@change_semaphore.synchronize do
|
139
|
-
result =
|
139
|
+
result = unsafe_open?(uri)
|
140
140
|
end
|
141
141
|
result
|
142
142
|
end
|
@@ -343,7 +343,7 @@ module Solargraph
|
|
343
343
|
def locate_pin params
|
344
344
|
pin = nil
|
345
345
|
@change_semaphore.synchronize do
|
346
|
-
pin = library.locate_pin(params['data']['location']) unless params['data']['location'].nil?
|
346
|
+
pin = library.locate_pin(params['data']['location']).first unless params['data']['location'].nil?
|
347
347
|
# @todo Improve pin location
|
348
348
|
if pin.nil? or pin.path != params['data']['path']
|
349
349
|
pin = library.path_pins(params['data']['path']).first
|
@@ -352,6 +352,8 @@ module Solargraph
|
|
352
352
|
pin
|
353
353
|
end
|
354
354
|
|
355
|
+
# @param uri [String]
|
356
|
+
# @return [String]
|
355
357
|
def read_text uri
|
356
358
|
filename = uri_to_file(uri)
|
357
359
|
text = nil
|
@@ -361,6 +363,10 @@ module Solargraph
|
|
361
363
|
text
|
362
364
|
end
|
363
365
|
|
366
|
+
# @param filename [String]
|
367
|
+
# @param line [Integer]
|
368
|
+
# @param column [Integer]
|
369
|
+
# @return [Solargraph::ApiMap::Completion]
|
364
370
|
def completions_at filename, line, column
|
365
371
|
result = nil
|
366
372
|
@change_semaphore.synchronize do
|
@@ -369,6 +375,9 @@ module Solargraph
|
|
369
375
|
result
|
370
376
|
end
|
371
377
|
|
378
|
+
# @param filename [String]
|
379
|
+
# @param line [Integer]
|
380
|
+
# @param column [Integer]
|
372
381
|
# @return [Array<Solargraph::Pin::Base>]
|
373
382
|
def definitions_at filename, line, column
|
374
383
|
result = []
|
@@ -378,6 +387,10 @@ module Solargraph
|
|
378
387
|
result
|
379
388
|
end
|
380
389
|
|
390
|
+
# @param filename [String]
|
391
|
+
# @param line [Integer]
|
392
|
+
# @param column [Integer]
|
393
|
+
# @return [Array<Solargraph::Pin::Base>]
|
381
394
|
def signatures_at filename, line, column
|
382
395
|
result = nil
|
383
396
|
@change_semaphore.synchronize do
|
@@ -386,6 +399,10 @@ module Solargraph
|
|
386
399
|
result
|
387
400
|
end
|
388
401
|
|
402
|
+
# @param filename [String]
|
403
|
+
# @param line [Integer]
|
404
|
+
# @param column [Integer]
|
405
|
+
# @return [Array<Solargraph::Source::Range>]
|
389
406
|
def references_from filename, line, column
|
390
407
|
result = nil
|
391
408
|
@change_semaphore.synchronize do
|
@@ -394,18 +411,24 @@ module Solargraph
|
|
394
411
|
result
|
395
412
|
end
|
396
413
|
|
414
|
+
# @param query [String]
|
415
|
+
# @return [Array<Solargraph::Pin::Base>]
|
397
416
|
def query_symbols query
|
398
417
|
result = nil
|
399
418
|
@change_semaphore.synchronize { result = library.query_symbols(query) }
|
400
419
|
result
|
401
420
|
end
|
402
421
|
|
422
|
+
# @param query [String]
|
423
|
+
# @return [Array<String>]
|
403
424
|
def search query
|
404
425
|
result = nil
|
405
426
|
@change_semaphore.synchronize { result = library.search(query) }
|
406
427
|
result
|
407
428
|
end
|
408
429
|
|
430
|
+
# @param query [String]
|
431
|
+
# @return [String]
|
409
432
|
def document query
|
410
433
|
result = nil
|
411
434
|
@change_semaphore.synchronize { result = library.document(query) }
|
@@ -418,6 +441,10 @@ module Solargraph
|
|
418
441
|
library.file_symbols(uri_to_file(uri))
|
419
442
|
end
|
420
443
|
|
444
|
+
# Send a notification to the client.
|
445
|
+
#
|
446
|
+
# @param text [String]
|
447
|
+
# @param type [Integer] A MessageType constant
|
421
448
|
def show_message text, type = LanguageServer::MessageTypes::INFO
|
422
449
|
send_notification 'window/showMessage', {
|
423
450
|
type: type,
|
@@ -425,6 +452,13 @@ module Solargraph
|
|
425
452
|
}
|
426
453
|
end
|
427
454
|
|
455
|
+
# Send a notification with optional responses.
|
456
|
+
#
|
457
|
+
# @param text [String]
|
458
|
+
# @param type [Integer] A MessageType constant
|
459
|
+
# @param actions [Array<String>] Response options for the client
|
460
|
+
# @param &block The block that processes the response
|
461
|
+
# @yieldparam [String] The action received from the client
|
428
462
|
def show_message_request text, type, actions, &block
|
429
463
|
send_request 'window/showMessageRequest', {
|
430
464
|
type: type,
|
@@ -441,6 +475,7 @@ module Solargraph
|
|
441
475
|
requests.keys
|
442
476
|
end
|
443
477
|
|
478
|
+
# @return [Hash{String => Object}]
|
444
479
|
def default_configuration
|
445
480
|
{
|
446
481
|
'completion' => true,
|
@@ -462,10 +497,16 @@ module Solargraph
|
|
462
497
|
@library
|
463
498
|
end
|
464
499
|
|
500
|
+
# @param file_uri [String]
|
501
|
+
# @return [Boolean]
|
465
502
|
def unsafe_changing? file_uri
|
466
503
|
@change_queue.any?{|change| change['textDocument']['uri'] == file_uri}
|
467
504
|
end
|
468
505
|
|
506
|
+
def unsafe_open? uri
|
507
|
+
library.open?(uri_to_file(uri))
|
508
|
+
end
|
509
|
+
|
469
510
|
def requests
|
470
511
|
@requests ||= {}
|
471
512
|
end
|
@@ -509,9 +550,13 @@ module Solargraph
|
|
509
550
|
@diagnostics_queue.push change['textDocument']['uri']
|
510
551
|
next true
|
511
552
|
else
|
512
|
-
|
513
|
-
|
514
|
-
|
553
|
+
if unsafe_open?(change['textDocument']['uri'])
|
554
|
+
STDERR.puts "Skipping out of order change to #{change['textDocument']['uri']}"
|
555
|
+
next false
|
556
|
+
else
|
557
|
+
STDERR.puts "Deleting out of order change to closed file #{change['textDocument']['uri']}"
|
558
|
+
next true
|
559
|
+
end
|
515
560
|
end
|
516
561
|
end
|
517
562
|
refreshable = changed and @change_queue.empty?
|
@@ -520,9 +565,11 @@ module Solargraph
|
|
520
565
|
# Trying to get anything out of the error except its class
|
521
566
|
# hangs the thread for some reason
|
522
567
|
STDERR.puts "An error occurred in the change thread: #{e.class}"
|
568
|
+
STDERR.puts e.backtrace
|
569
|
+
@change_queue.clear
|
523
570
|
end
|
524
571
|
end
|
525
|
-
sleep 0.
|
572
|
+
sleep 0.01
|
526
573
|
end
|
527
574
|
end
|
528
575
|
end
|
@@ -3,6 +3,9 @@ require 'uri'
|
|
3
3
|
|
4
4
|
module Solargraph
|
5
5
|
module LanguageServer
|
6
|
+
# The Message namespace contains classes that implement language server
|
7
|
+
# protocol methods.
|
8
|
+
#
|
6
9
|
module Message
|
7
10
|
autoload :Base, 'solargraph/language_server/message/base'
|
8
11
|
autoload :Initialize, 'solargraph/language_server/message/initialize'
|
@@ -18,6 +21,15 @@ module Solargraph
|
|
18
21
|
autoload :Workspace, 'solargraph/language_server/message/workspace'
|
19
22
|
|
20
23
|
class << self
|
24
|
+
# Register a method name and message for handling by the language
|
25
|
+
# server.
|
26
|
+
#
|
27
|
+
# @example
|
28
|
+
# Message.register 'initialize', Solargraph::Message::Initialize
|
29
|
+
#
|
30
|
+
# @param path [String] The method name
|
31
|
+
# @param message_class [Class<Message::Base>] The message class
|
32
|
+
# @return [void]
|
21
33
|
def register path, message_class
|
22
34
|
method_map[path] = message_class
|
23
35
|
end
|
@@ -36,6 +48,7 @@ module Solargraph
|
|
36
48
|
|
37
49
|
private
|
38
50
|
|
51
|
+
# @return [Hash{String => Class<Message::Base>}]
|
39
52
|
def method_map
|
40
53
|
@method_map ||= {}
|
41
54
|
end
|
@@ -12,12 +12,10 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
12
12
|
col = params['position']['character']
|
13
13
|
suggestions = host.definitions_at(filename, line, col)
|
14
14
|
locations = suggestions.reject{|pin| pin.location.nil?}.map do |pin|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
}
|
20
|
-
end
|
15
|
+
{
|
16
|
+
uri: file_to_uri(pin.location.filename),
|
17
|
+
range: pin.location.range.to_hash
|
18
|
+
}
|
21
19
|
end
|
22
20
|
set_result locations
|
23
21
|
end
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module Solargraph
|
2
2
|
module LanguageServer
|
3
3
|
class Request
|
4
|
+
# @param id [Integer]
|
5
|
+
# @param &block The block that processes the client's response
|
4
6
|
def initialize id, &block
|
5
7
|
@id = id
|
6
8
|
@block = block
|
7
9
|
end
|
8
10
|
|
11
|
+
# @param result [Object]
|
12
|
+
# @return [void]
|
9
13
|
def process result
|
10
14
|
@block.call(result) unless @block.nil?
|
11
15
|
end
|
@@ -1,32 +1,34 @@
|
|
1
1
|
module Solargraph
|
2
2
|
module LanguageServer
|
3
|
+
# The SymbolKind constants for the language server protocol.
|
4
|
+
#
|
3
5
|
module SymbolKinds
|
4
|
-
FILE = 1
|
5
|
-
MODULE = 2
|
6
|
-
NAMESPACE = 3
|
7
|
-
PACKAGE = 4
|
8
|
-
CLASS = 5
|
9
|
-
METHOD = 6
|
10
|
-
PROPERTY = 7
|
11
|
-
FIELD = 8
|
12
|
-
CONSTRUCTOR = 9
|
13
|
-
ENUM = 10
|
14
|
-
INTERFACE = 11
|
15
|
-
FUNCTION = 12
|
16
|
-
VARIABLE = 13
|
17
|
-
CONSTANT = 14
|
18
|
-
STRING = 15
|
19
|
-
NUMBER = 16
|
20
|
-
BOOLEAN = 17
|
21
|
-
ARRAY = 18
|
22
|
-
OBJECT = 19
|
23
|
-
KEY = 20
|
24
|
-
NULL = 21
|
25
|
-
ENUM_MEMBER = 22
|
26
|
-
STRUCT = 23
|
27
|
-
EVENT = 24
|
28
|
-
OPERATOR = 25
|
29
|
-
TYPE_PARAMETER = 26
|
6
|
+
FILE = 1
|
7
|
+
MODULE = 2
|
8
|
+
NAMESPACE = 3
|
9
|
+
PACKAGE = 4
|
10
|
+
CLASS = 5
|
11
|
+
METHOD = 6
|
12
|
+
PROPERTY = 7
|
13
|
+
FIELD = 8
|
14
|
+
CONSTRUCTOR = 9
|
15
|
+
ENUM = 10
|
16
|
+
INTERFACE = 11
|
17
|
+
FUNCTION = 12
|
18
|
+
VARIABLE = 13
|
19
|
+
CONSTANT = 14
|
20
|
+
STRING = 15
|
21
|
+
NUMBER = 16
|
22
|
+
BOOLEAN = 17
|
23
|
+
ARRAY = 18
|
24
|
+
OBJECT = 19
|
25
|
+
KEY = 20
|
26
|
+
NULL = 21
|
27
|
+
ENUM_MEMBER = 22
|
28
|
+
STRUCT = 23
|
29
|
+
EVENT = 24
|
30
|
+
OPERATOR = 25
|
31
|
+
TYPE_PARAMETER = 26
|
30
32
|
end
|
31
33
|
end
|
32
34
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module Solargraph
|
2
2
|
module LanguageServer
|
3
|
+
# The Transport namespace contains concrete implementations of
|
4
|
+
# communication protocols for language servers.
|
5
|
+
#
|
3
6
|
module Transport
|
4
7
|
autoload :DataReader, 'solargraph/language_server/transport/data_reader'
|
5
8
|
autoload :Socket, 'solargraph/language_server/transport/socket'
|
data/lib/solargraph/library.rb
CHANGED
@@ -114,7 +114,7 @@ module Solargraph
|
|
114
114
|
source = read(filename)
|
115
115
|
api_map.virtualize source
|
116
116
|
fragment = source.fragment_at(line, column)
|
117
|
-
|
117
|
+
fragment.complete(api_map)
|
118
118
|
end
|
119
119
|
|
120
120
|
# Get definition suggestions for the expression at the specified file and
|
@@ -128,7 +128,7 @@ module Solargraph
|
|
128
128
|
source = read(filename)
|
129
129
|
api_map.virtualize source
|
130
130
|
fragment = source.fragment_at(line, column)
|
131
|
-
|
131
|
+
fragment.define(api_map)
|
132
132
|
end
|
133
133
|
|
134
134
|
# Get signature suggestions for the method at the specified file and
|
@@ -142,14 +142,18 @@ module Solargraph
|
|
142
142
|
source = read(filename)
|
143
143
|
api_map.virtualize source
|
144
144
|
fragment = source.fragment_at(line, column)
|
145
|
-
|
145
|
+
fragment.signify(api_map)
|
146
146
|
end
|
147
147
|
|
148
|
+
# @param filename [String]
|
149
|
+
# @param line [Integer]
|
150
|
+
# @param column [Integer]
|
151
|
+
# @return [Array<Solargraph::Source::Range>]
|
148
152
|
def references_from filename, line, column
|
149
153
|
source = read(filename)
|
150
154
|
api_map.virtualize source
|
151
155
|
fragment = source.fragment_at(line, column)
|
152
|
-
pins =
|
156
|
+
pins = fragment.define(api_map)
|
153
157
|
return [] if pins.empty?
|
154
158
|
result = []
|
155
159
|
# @param pin [Solargraph::Pin::Base]
|
@@ -159,9 +163,10 @@ module Solargraph
|
|
159
163
|
result.push mn_loc unless mn_loc.nil?
|
160
164
|
end
|
161
165
|
(workspace.sources + source_hash.values).uniq(&:filename).each do |source|
|
162
|
-
found = source.references(pin.name)
|
163
|
-
|
164
|
-
|
166
|
+
found = source.references(pin.name)
|
167
|
+
found.select do |loc|
|
168
|
+
referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character)
|
169
|
+
referenced.any?{|r| r.path == pin.path}
|
165
170
|
end
|
166
171
|
result.concat found.sort{|a, b| a.range.start.line <=> b.range.start.line}
|
167
172
|
end
|