solargraph 0.29.5 → 0.30.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 +1 -0
- data/lib/solargraph/api_map.rb +22 -13
- data/lib/solargraph/language_server/host.rb +121 -33
- data/lib/solargraph/language_server/host/cataloger.rb +5 -4
- data/lib/solargraph/language_server/message.rb +3 -0
- data/lib/solargraph/language_server/message/extended.rb +5 -4
- data/lib/solargraph/language_server/message/extended/document.rb +1 -1
- data/lib/solargraph/language_server/message/extended/environment.rb +20 -0
- data/lib/solargraph/language_server/message/extended/search.rb +1 -1
- data/lib/solargraph/language_server/message/initialize.rb +28 -4
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/folding_range.rb +24 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +1 -0
- data/lib/solargraph/language_server/message/workspace.rb +4 -3
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +1 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +3 -6
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -0
- data/lib/solargraph/language_server/transport.rb +1 -2
- data/lib/solargraph/language_server/transport/{socket.rb → adapter.rb} +8 -10
- data/lib/solargraph/library.rb +29 -3
- data/lib/solargraph/logging.rb +25 -0
- data/lib/solargraph/page.rb +14 -4
- data/lib/solargraph/pin/documenting.rb +1 -1
- data/lib/solargraph/shell.rb +9 -10
- data/lib/solargraph/source.rb +59 -5
- data/lib/solargraph/source/encoding_fixes.rb +1 -1
- data/lib/solargraph/source_map/mapper.rb +14 -8
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +3 -0
- data/lib/solargraph/views/environment.erb +50 -0
- data/lib/solargraph/views/layout.erb +6 -0
- data/lib/solargraph/yard_map.rb +8 -8
- metadata +11 -13
- data/lib/solargraph/language_server/transport/stdio.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82f40642bcf02b95ca838da6a0ed6ff66ac9d0e8ef42ee8bf8643866342ffb39
|
4
|
+
data.tar.gz: e1e30bd1a35dfdfd1b17d74d70ab8afef82c701fdbffb4d4f08455511df95673
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67ace010ea2017c9d35c2d8aa8229187ff39c27f926c388eba9105e067088c31ed46a7dadaef787c5845eb838b9c347744cfc48e47dea480558a8d5f05c15ee7
|
7
|
+
data.tar.gz: eef1f9e7c56e8623fe44227fedd16b89a0d277ac29ac3005ade6b98387596daff15c0743deb8de8b99ff4950c72b504c4f31e0e44faf075de14fc662efa14449
|
data/lib/solargraph.rb
CHANGED
@@ -34,6 +34,7 @@ module Solargraph
|
|
34
34
|
autoload :Diagnostics, 'solargraph/diagnostics'
|
35
35
|
autoload :ComplexType, 'solargraph/complex_type'
|
36
36
|
autoload :Bundle, 'solargraph/bundle'
|
37
|
+
autoload :Logging, 'solargraph/logging'
|
37
38
|
|
38
39
|
dir = File.dirname(__FILE__)
|
39
40
|
YARDOC_PATH = File.realpath(File.join(dir, '..', 'yardoc'))
|
data/lib/solargraph/api_map.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'set'
|
3
|
+
require 'pathname'
|
3
4
|
|
4
5
|
module Solargraph
|
5
6
|
# An aggregate provider for information about workspaces, sources, gems, and
|
@@ -96,7 +97,8 @@ module Solargraph
|
|
96
97
|
reqs.delete_if do |r|
|
97
98
|
result = false
|
98
99
|
bundle.workspace.require_paths.each do |l|
|
99
|
-
|
100
|
+
pn = Pathname.new(bundle.workspace.directory).join(l, "#{r}.rb")
|
101
|
+
if new_map_hash.keys.include?(pn.to_s)
|
100
102
|
result = true
|
101
103
|
break
|
102
104
|
end
|
@@ -298,13 +300,27 @@ module Solargraph
|
|
298
300
|
result
|
299
301
|
end
|
300
302
|
|
301
|
-
# Get an array of
|
303
|
+
# Get an array of method pins for a complex type.
|
302
304
|
#
|
303
|
-
#
|
304
|
-
#
|
305
|
+
# The type's namespace and the context should be fully qualified. If the
|
306
|
+
# context matches the namespace type or is a subclass of the type,
|
307
|
+
# protected methods are included in the results. If protected methods are
|
308
|
+
# included and internal is true, private methods are also included.
|
309
|
+
#
|
310
|
+
# @example
|
311
|
+
# api_map = Solargraph::ApiMap.new
|
312
|
+
# type = Solargraph::ComplexType.parse('String')
|
313
|
+
# api_map.get_complex_type_methods(type)
|
314
|
+
#
|
315
|
+
# @param type [Solargraph::ComplexType] The complex type of the namespace
|
316
|
+
# @param context [String] The context from which the type is referenced
|
305
317
|
# @param internal [Boolean] True to include private methods
|
306
318
|
# @return [Array<Solargraph::Pin::Base>]
|
307
319
|
def get_complex_type_methods type, context = '', internal = false
|
320
|
+
# This method does not qualify the complex type's namespace because
|
321
|
+
# it can cause conflicts between similar names, e.g., `Foo` vs.
|
322
|
+
# `Other::Foo`. It still takes a context argument to determine whether
|
323
|
+
# protected and private methods are visible.
|
308
324
|
return [] if type.undefined? || type.void?
|
309
325
|
result = []
|
310
326
|
if type.duck_type?
|
@@ -314,19 +330,12 @@ module Solargraph
|
|
314
330
|
result.concat get_methods('Object')
|
315
331
|
else
|
316
332
|
unless type.nil? || type.name == 'void'
|
317
|
-
# @todo This method does not qualify the complex type's namespace
|
318
|
-
# because it can cause namespace conflicts, e.g., `Foo` vs.
|
319
|
-
# `Other::Foo`. It still takes a context argument because it
|
320
|
-
# uses context to determine whether protected and private methods
|
321
|
-
# are visible.
|
322
|
-
# namespace = qualify(type.namespace, context)
|
323
|
-
namespace = type.namespace
|
324
333
|
visibility = [:public]
|
325
|
-
if namespace == context || super_and_sub?(namespace, context)
|
334
|
+
if type.namespace == context || super_and_sub?(type.namespace, context)
|
326
335
|
visibility.push :protected
|
327
336
|
visibility.push :private if internal
|
328
337
|
end
|
329
|
-
result.concat get_methods(namespace, scope: type.scope, visibility: visibility)
|
338
|
+
result.concat get_methods(type.namespace, scope: type.scope, visibility: visibility)
|
330
339
|
end
|
331
340
|
end
|
332
341
|
result
|
@@ -12,6 +12,7 @@ module Solargraph
|
|
12
12
|
autoload :Cataloger, 'solargraph/language_server/host/cataloger'
|
13
13
|
|
14
14
|
include Solargraph::LanguageServer::UriHelpers
|
15
|
+
include Logging
|
15
16
|
|
16
17
|
def initialize
|
17
18
|
@cancel_semaphore = Mutex.new
|
@@ -31,6 +32,7 @@ module Solargraph
|
|
31
32
|
def configure update
|
32
33
|
return if update.nil?
|
33
34
|
options.merge! update
|
35
|
+
logger.level = LOG_LEVELS[options['logLevel']] || DEFAULT_LOG_LEVEL
|
34
36
|
end
|
35
37
|
|
36
38
|
# @return [Hash]
|
@@ -70,6 +72,8 @@ module Solargraph
|
|
70
72
|
# @return [Solargraph::LanguageServer::Message::Base] The message handler.
|
71
73
|
def start request
|
72
74
|
if request['method']
|
75
|
+
logger.info "Server received #{request['method']}"
|
76
|
+
logger.debug request
|
73
77
|
message = Message.select(request['method']).new(self, request)
|
74
78
|
begin
|
75
79
|
message.process
|
@@ -94,14 +98,18 @@ module Solargraph
|
|
94
98
|
#
|
95
99
|
# @param uri [String] The file uri.
|
96
100
|
def create uri
|
101
|
+
library = library_for(uri)
|
97
102
|
filename = uri_to_file(uri)
|
98
|
-
library.create_from_disk
|
103
|
+
result = library.create_from_disk(filename)
|
104
|
+
diagnoser.schedule uri if open?(uri)
|
105
|
+
result
|
99
106
|
end
|
100
107
|
|
101
108
|
# Delete the specified file from the library.
|
102
109
|
#
|
103
110
|
# @param uri [String] The file uri.
|
104
111
|
def delete uri
|
112
|
+
library = library_for(uri)
|
105
113
|
filename = uri_to_file(uri)
|
106
114
|
library.delete filename
|
107
115
|
send_notification "textDocument/publishDiagnostics", {
|
@@ -116,10 +124,17 @@ module Solargraph
|
|
116
124
|
# @param text [String] The contents of the file.
|
117
125
|
# @param version [Integer] A version number.
|
118
126
|
def open uri, text, version
|
127
|
+
library = library_for(uri)
|
119
128
|
library.open uri_to_file(uri), text, version
|
120
129
|
diagnoser.schedule uri
|
121
130
|
end
|
122
131
|
|
132
|
+
def open_from_disk uri
|
133
|
+
library = library_for(uri)
|
134
|
+
library.open_from_disk uri_to_file(uri)
|
135
|
+
diagnoser.schedule uri
|
136
|
+
end
|
137
|
+
|
123
138
|
# True if the specified file is currently open in the library.
|
124
139
|
#
|
125
140
|
# @param uri [String]
|
@@ -132,12 +147,15 @@ module Solargraph
|
|
132
147
|
#
|
133
148
|
# @param uri [String]
|
134
149
|
def close uri
|
150
|
+
library = library_for(uri)
|
135
151
|
library.close uri_to_file(uri)
|
136
152
|
diagnoser.schedule uri
|
137
153
|
end
|
138
154
|
|
139
155
|
# @param uri [String]
|
140
156
|
def diagnose uri
|
157
|
+
logger.info "Diagnosing #{uri}"
|
158
|
+
library = library_for(uri)
|
141
159
|
begin
|
142
160
|
results = library.diagnose uri_to_file(uri)
|
143
161
|
send_notification "textDocument/publishDiagnostics", {
|
@@ -155,9 +173,10 @@ module Solargraph
|
|
155
173
|
end
|
156
174
|
|
157
175
|
def change params
|
176
|
+
library = library_for(params['textDocument']['uri'])
|
158
177
|
updater = generate_updater(params)
|
159
178
|
library.update updater
|
160
|
-
cataloger.ping unless library.synchronized?
|
179
|
+
cataloger.ping(library) unless library.synchronized?
|
161
180
|
diagnoser.schedule params['textDocument']['uri']
|
162
181
|
end
|
163
182
|
|
@@ -185,22 +204,53 @@ module Solargraph
|
|
185
204
|
# Prepare a library for the specified directory.
|
186
205
|
#
|
187
206
|
# @param directory [String]
|
188
|
-
|
207
|
+
# @param name [String]
|
208
|
+
def prepare directory, name = nil
|
209
|
+
logger.info "Preparing library for #{directory}"
|
189
210
|
path = ''
|
190
211
|
path = normalize_separators(directory) unless directory.nil?
|
191
212
|
begin
|
192
|
-
|
213
|
+
lib = Solargraph::Library.load(path, name)
|
193
214
|
rescue WorkspaceTooLargeError => e
|
194
215
|
send_notification 'window/showMessage', {
|
195
216
|
'type' => Solargraph::LanguageServer::MessageTypes::WARNING,
|
196
217
|
'message' => e.message
|
197
218
|
}
|
198
|
-
|
219
|
+
lib = Solargraph::Library.new('', name)
|
199
220
|
end
|
221
|
+
libraries.push lib
|
200
222
|
diagnoser.start
|
201
223
|
cataloger.start
|
202
224
|
end
|
203
225
|
|
226
|
+
def prepare_folders array
|
227
|
+
array.each do |folder|
|
228
|
+
prepare uri_to_file(folder['uri']), folder['name']
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def remove directory
|
233
|
+
logger.info "Removing library for #{directory}"
|
234
|
+
# @param lib [Library]
|
235
|
+
libraries.delete_if do |lib|
|
236
|
+
next false if lib.workspace.directory != directory
|
237
|
+
lib.open_sources.each do |src|
|
238
|
+
orphan_library.open(src.filename, src.code, src.version)
|
239
|
+
end
|
240
|
+
true
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def remove_folders array
|
245
|
+
array.each do |folder|
|
246
|
+
remove uri_to_file(folder['uri'])
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
def folders
|
251
|
+
libraries.map { |lib| lib.workspace.directory }
|
252
|
+
end
|
253
|
+
|
204
254
|
# Send a notification to the client.
|
205
255
|
#
|
206
256
|
# @param method [String] The message method
|
@@ -214,6 +264,8 @@ module Solargraph
|
|
214
264
|
json = response.to_json
|
215
265
|
envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
|
216
266
|
queue envelope
|
267
|
+
logger.info "Server sent #{method}"
|
268
|
+
logger.debug params
|
217
269
|
end
|
218
270
|
|
219
271
|
# Send a request to the client and execute the provided block to process
|
@@ -236,6 +288,8 @@ module Solargraph
|
|
236
288
|
envelope = "Content-Length: #{json.bytesize}\r\n\r\n#{json}"
|
237
289
|
queue envelope
|
238
290
|
@next_request_id += 1
|
291
|
+
logger.info "Server sent #{method}"
|
292
|
+
logger.debug params
|
239
293
|
end
|
240
294
|
|
241
295
|
# Register the methods as capabilities with the client.
|
@@ -244,6 +298,7 @@ module Solargraph
|
|
244
298
|
#
|
245
299
|
# @param methods [Array<String>] The methods to register
|
246
300
|
def register_capabilities methods
|
301
|
+
logger.debug "Registering capabilities: #{methods}"
|
247
302
|
@register_semaphore.synchronize do
|
248
303
|
send_request 'client/registerCapability', {
|
249
304
|
registrations: methods.select{|m| can_register?(m) and !registered?(m)}.map { |m|
|
@@ -264,6 +319,7 @@ module Solargraph
|
|
264
319
|
#
|
265
320
|
# @param methods [Array<String>] The methods to unregister
|
266
321
|
def unregister_capabilities methods
|
322
|
+
logger.debug "Unregistering capabilities: #{methods}"
|
267
323
|
@register_semaphore.synchronize do
|
268
324
|
send_request 'client/unregisterCapability', {
|
269
325
|
unregisterations: methods.select{|m| registered?(m)}.map{ |m|
|
@@ -300,13 +356,6 @@ module Solargraph
|
|
300
356
|
@registered_capabilities.include?(method)
|
301
357
|
end
|
302
358
|
|
303
|
-
# True if the specified file is in the process of changing.
|
304
|
-
#
|
305
|
-
# @return [Boolean]
|
306
|
-
def changing? file_uri
|
307
|
-
unsafe_changing?(file_uri)
|
308
|
-
end
|
309
|
-
|
310
359
|
def synchronizing?
|
311
360
|
cataloger.synchronizing?
|
312
361
|
end
|
@@ -324,6 +373,7 @@ module Solargraph
|
|
324
373
|
def locate_pin params
|
325
374
|
pin = nil
|
326
375
|
unless params['data']['location'].nil?
|
376
|
+
library = library_for(file_to_uri(params['data']['location']['filename']))
|
327
377
|
location = Location.new(
|
328
378
|
params['data']['location']['filename'],
|
329
379
|
Range.from_to(
|
@@ -336,15 +386,16 @@ module Solargraph
|
|
336
386
|
pin = library.locate_pin(location)
|
337
387
|
end
|
338
388
|
# @todo Improve pin location
|
339
|
-
if pin.nil? or pin.path != params['data']['path']
|
340
|
-
|
341
|
-
end
|
389
|
+
# if pin.nil? or pin.path != params['data']['path']
|
390
|
+
# pin = library.path_pins(params['data']['path']).first
|
391
|
+
# end
|
342
392
|
pin
|
343
393
|
end
|
344
394
|
|
345
395
|
# @param uri [String]
|
346
396
|
# @return [String]
|
347
397
|
def read_text uri
|
398
|
+
library = library_for(uri)
|
348
399
|
filename = uri_to_file(uri)
|
349
400
|
library.read_text(filename)
|
350
401
|
end
|
@@ -354,9 +405,8 @@ module Solargraph
|
|
354
405
|
# @param column [Integer]
|
355
406
|
# @return [Solargraph::ApiMap::Completion]
|
356
407
|
def completions_at filename, line, column
|
357
|
-
|
358
|
-
|
359
|
-
result
|
408
|
+
library = library_for(file_to_uri(filename))
|
409
|
+
library.completions_at filename, line, column
|
360
410
|
end
|
361
411
|
|
362
412
|
# @param filename [String]
|
@@ -364,6 +414,7 @@ module Solargraph
|
|
364
414
|
# @param column [Integer]
|
365
415
|
# @return [Array<Solargraph::Pin::Base>]
|
366
416
|
def definitions_at filename, line, column
|
417
|
+
library = library_for(file_to_uri(filename))
|
367
418
|
library.definitions_at(filename, line, column)
|
368
419
|
end
|
369
420
|
|
@@ -372,6 +423,7 @@ module Solargraph
|
|
372
423
|
# @param column [Integer]
|
373
424
|
# @return [Array<Solargraph::Pin::Base>]
|
374
425
|
def signatures_at filename, line, column
|
426
|
+
library = library_for(file_to_uri(filename))
|
375
427
|
library.signatures_at(filename, line, column)
|
376
428
|
end
|
377
429
|
|
@@ -381,30 +433,38 @@ module Solargraph
|
|
381
433
|
# @param strip [Boolean] Strip special characters from variable names
|
382
434
|
# @return [Array<Solargraph::Range>]
|
383
435
|
def references_from filename, line, column, strip: true
|
436
|
+
library = library_for(file_to_uri(filename))
|
384
437
|
result = library.references_from(filename, line, column, strip: strip)
|
385
438
|
end
|
386
439
|
|
387
440
|
# @param query [String]
|
388
441
|
# @return [Array<Solargraph::Pin::Base>]
|
389
442
|
def query_symbols query
|
390
|
-
|
443
|
+
result = []
|
444
|
+
libraries.each { |lib| result.concat lib.query_symbols(query) }
|
445
|
+
result
|
391
446
|
end
|
392
447
|
|
393
448
|
# @param query [String]
|
394
449
|
# @return [Array<String>]
|
395
450
|
def search query
|
396
|
-
|
451
|
+
result = []
|
452
|
+
libraries.each { |lib| result.concat lib.search(query) }
|
453
|
+
result
|
397
454
|
end
|
398
455
|
|
399
456
|
# @param query [String]
|
400
457
|
# @return [String]
|
401
458
|
def document query
|
402
|
-
|
459
|
+
result = []
|
460
|
+
libraries.each { |lib| result.concat lib.document(query) }
|
461
|
+
result
|
403
462
|
end
|
404
463
|
|
405
464
|
# @param uri [String]
|
406
465
|
# @return [Array<Solargraph::Pin::Base>]
|
407
466
|
def document_symbols uri
|
467
|
+
library = library_for(uri)
|
408
468
|
library.document_symbols(uri_to_file(uri))
|
409
469
|
end
|
410
470
|
|
@@ -453,22 +513,52 @@ module Solargraph
|
|
453
513
|
'references' => true,
|
454
514
|
'autoformat' => false,
|
455
515
|
'diagnostics' => false,
|
456
|
-
'formatting' => false
|
516
|
+
'formatting' => false,
|
517
|
+
'folding' => true,
|
518
|
+
'logLevel' => 'warn'
|
457
519
|
}
|
458
520
|
end
|
459
521
|
|
460
522
|
# Catalog the library.
|
461
523
|
#
|
462
524
|
# @return [void]
|
463
|
-
def catalog
|
464
|
-
|
525
|
+
def catalog lib
|
526
|
+
lib.catalog
|
527
|
+
end
|
528
|
+
|
529
|
+
def folding_ranges uri
|
530
|
+
library = library_for(uri)
|
531
|
+
file = uri_to_file(uri)
|
532
|
+
library.folding_ranges(file)
|
465
533
|
end
|
466
534
|
|
467
535
|
private
|
468
536
|
|
469
|
-
# @return [
|
470
|
-
def
|
471
|
-
@
|
537
|
+
# @return [Array<Library>]
|
538
|
+
def libraries
|
539
|
+
@libraries ||= []
|
540
|
+
end
|
541
|
+
|
542
|
+
# @param uri [String]
|
543
|
+
# @return [Library]
|
544
|
+
def library_for uri
|
545
|
+
return libraries.first if libraries.length == 1
|
546
|
+
filename = uri_to_file(uri)
|
547
|
+
# Find a library with an explicit reference to the file
|
548
|
+
libraries.each do |lib|
|
549
|
+
return lib if lib.contain?(filename) || lib.open?(filename)
|
550
|
+
end
|
551
|
+
# Find a library with a workspace that contains the file
|
552
|
+
libraries.each do |lib|
|
553
|
+
return lib if filename.start_with?(lib.workspace.directory)
|
554
|
+
end
|
555
|
+
return orphan_library if orphan_library.open?(filename)
|
556
|
+
raise "No library for #{uri}"
|
557
|
+
end
|
558
|
+
|
559
|
+
# @return [Library]
|
560
|
+
def orphan_library
|
561
|
+
@orphan_library ||= Solargraph::Library.new
|
472
562
|
end
|
473
563
|
|
474
564
|
# @return [Diagnoser]
|
@@ -481,13 +571,8 @@ module Solargraph
|
|
481
571
|
@cataloger ||= Cataloger.new(self)
|
482
572
|
end
|
483
573
|
|
484
|
-
# @param file_uri [String]
|
485
|
-
# @return [Boolean]
|
486
|
-
def unsafe_changing? file_uri
|
487
|
-
file = uri_to_file(file_uri)
|
488
|
-
end
|
489
|
-
|
490
574
|
def unsafe_open? uri
|
575
|
+
library = library_for(uri)
|
491
576
|
library.open?(uri_to_file(uri))
|
492
577
|
end
|
493
578
|
|
@@ -560,6 +645,9 @@ module Solargraph
|
|
560
645
|
},
|
561
646
|
'textDocument/formatting' => {
|
562
647
|
formattingProvider: true
|
648
|
+
},
|
649
|
+
'textDocument/foldingRange' => {
|
650
|
+
foldingRangeProvider: true
|
563
651
|
}
|
564
652
|
}
|
565
653
|
end
|