solargraph 0.29.5 → 0.30.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|