solargraph 0.21.1 → 0.22.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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +0 -1
  3. data/lib/solargraph/api_map.rb +40 -23
  4. data/lib/solargraph/api_map/completion.rb +3 -0
  5. data/lib/solargraph/api_map/probe.rb +16 -19
  6. data/lib/solargraph/api_map/store.rb +6 -2
  7. data/lib/solargraph/diagnostics/rubocop.rb +6 -0
  8. data/lib/solargraph/language_server/host.rb +9 -1
  9. data/lib/solargraph/language_server/message.rb +3 -0
  10. data/lib/solargraph/language_server/message/extended.rb +1 -0
  11. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
  12. data/lib/solargraph/language_server/message/extended/download_core.rb +25 -0
  13. data/lib/solargraph/language_server/message/initialize.rb +3 -1
  14. data/lib/solargraph/language_server/message/text_document.rb +13 -11
  15. data/lib/solargraph/language_server/message/text_document/definition.rb +1 -1
  16. data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
  17. data/lib/solargraph/language_server/message/text_document/references.rb +14 -0
  18. data/lib/solargraph/language_server/message/text_document/rename.rb +17 -0
  19. data/lib/solargraph/language_server/uri_helpers.rb +2 -0
  20. data/lib/solargraph/library.rb +37 -0
  21. data/lib/solargraph/live_map.rb +8 -2
  22. data/lib/solargraph/live_map/cache.rb +7 -0
  23. data/lib/solargraph/pin.rb +1 -0
  24. data/lib/solargraph/pin/attribute.rb +5 -1
  25. data/lib/solargraph/pin/namespace.rb +0 -2
  26. data/lib/solargraph/pin/proxy_method.rb +31 -0
  27. data/lib/solargraph/plugin/process.rb +1 -1
  28. data/lib/solargraph/plugin/runtime.rb +0 -1
  29. data/lib/solargraph/shell.rb +0 -1
  30. data/lib/solargraph/source.rb +31 -1
  31. data/lib/solargraph/source/fragment.rb +12 -15
  32. data/lib/solargraph/source/location.rb +3 -0
  33. data/lib/solargraph/source/mapper.rb +20 -10
  34. data/lib/solargraph/source/node_methods.rb +111 -0
  35. data/lib/solargraph/version.rb +1 -1
  36. data/lib/solargraph/workspace.rb +7 -1
  37. data/lib/solargraph/workspace/config.rb +6 -2
  38. data/lib/solargraph/yard_map.rb +12 -1
  39. metadata +25 -7
  40. data/lib/solargraph/node_methods.rb +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f93d18c2483c24a81693e662698b7d67e86086211608d6f50a0128b95cc817b6
4
- data.tar.gz: f0346ff1adf21faebba30306cc2e682cf99d83bcedf66ebfca3029dad4031025
3
+ metadata.gz: c647321bb57cb5ba859e1762032855324aa967e78a562c0e259508e5c24c22ee
4
+ data.tar.gz: 057c1a4298f9c4574c0773425cce496216ab60e22165871487d6d77e13733745
5
5
  SHA512:
6
- metadata.gz: d87a287c2608cbd7af255684a790ab079b85821a2abf3a6051212b36a156bf3662310bf5e9e7d3857ad89338b81628e94eb270dc74db258c6cb2ff2f4f0bc852
7
- data.tar.gz: ad9ae29c4d354588e383fb68926175bad72e419a2ef736f7e9f7069c701d3b94bc5ab784768be4dd1823ef1ac65201bea9e971ea554c6918f2f23d9fd1c42b92
6
+ metadata.gz: ae8cb69f92e2f3ad78959bd8767b78dda5a7d4baa861fa59680be191b7c92944f0df15ff12ccad2ed4a93231afcc55db53bd40cf9b42473387491f4d168f1cef
7
+ data.tar.gz: 8d02f2a10b1a71579a0b48e9dae4268689cc0ec642c137b1adedf6fc99749ae5a1b04f46b4d9b30448d3316a71b65dfdf79b5066c0af499e2181fcc5a107201f
data/lib/solargraph.rb CHANGED
@@ -20,7 +20,6 @@ module Solargraph
20
20
  autoload :Shell, 'solargraph/shell'
21
21
  autoload :Source, 'solargraph/source'
22
22
  autoload :ApiMap, 'solargraph/api_map'
23
- autoload :NodeMethods, 'solargraph/node_methods'
24
23
  autoload :YardMap, 'solargraph/yard_map'
25
24
  autoload :Pin, 'solargraph/pin'
26
25
  autoload :LiveMap, 'solargraph/live_map'
@@ -20,6 +20,14 @@ module Solargraph
20
20
  # @return [Solargraph::Workspace]
21
21
  attr_reader :workspace
22
22
 
23
+ # @return [ApiMap::Store]
24
+ attr_reader :store
25
+
26
+ # Get a LiveMap associated with the current workspace.
27
+ #
28
+ # @return [Solargraph::LiveMap]
29
+ attr_reader :live_map
30
+
23
31
  # @param workspace [Solargraph::Workspace]
24
32
  def initialize workspace = Solargraph::Workspace.new(nil)
25
33
  @workspace = workspace
@@ -28,7 +36,7 @@ module Solargraph
28
36
  @yard_stale = true
29
37
  # process_maps
30
38
  @sources = workspace.sources
31
- yard_map
39
+ refresh_store_and_maps
32
40
  end
33
41
 
34
42
  # Create an ApiMap with a workspace in the specified directory.
@@ -38,11 +46,6 @@ module Solargraph
38
46
  self.new(Solargraph::Workspace.new(directory))
39
47
  end
40
48
 
41
- # @return [ApiMap::Store]
42
- def store
43
- @store ||= ApiMap::Store.new(@sources)
44
- end
45
-
46
49
  def pins
47
50
  store.pins
48
51
  end
@@ -68,19 +71,12 @@ module Solargraph
68
71
  # @return [Solargraph::YardMap]
69
72
  def yard_map
70
73
  # refresh
71
- if @yard_map.nil? || @yard_map.required.to_set != required.to_set
74
+ if @yard_map.required.to_set != required.to_set
72
75
  @yard_map = Solargraph::YardMap.new(required: required, workspace: workspace)
73
76
  end
74
77
  @yard_map
75
78
  end
76
79
 
77
- # Get a LiveMap associated with the current workspace.
78
- #
79
- # @return [Solargraph::LiveMap]
80
- def live_map
81
- @live_map ||= Solargraph::LiveMap.new(self)
82
- end
83
-
84
80
  # Declare a virtual source that will be included in the map regardless of
85
81
  # whether it's in the workspace.
86
82
  #
@@ -231,7 +227,7 @@ module Solargraph
231
227
  # @param namespace [String] A fully qualified namespace
232
228
  # @return [Array<Solargraph::Pin::ClassVariable>]
233
229
  def get_class_variable_pins(namespace)
234
- prefer_non_nil_variables(@cvar_pins[namespace] || [])
230
+ prefer_non_nil_variables(store.get_class_variables(namespace))
235
231
  end
236
232
 
237
233
  # @return [Array<Solargraph::Pin::Base>]
@@ -262,6 +258,11 @@ module Solargraph
262
258
  else
263
259
  result.concat inner_get_methods(fqns, scope, visibility, deep, skip)
264
260
  end
261
+ live = live_map.get_methods(fqns, '', scope.to_s, visibility.include?(:private))
262
+ unless live.empty?
263
+ exist = result.map(&:name)
264
+ result.concat live.reject{|p| exist.include?(p.name)}
265
+ end
265
266
  result
266
267
  end
267
268
 
@@ -295,7 +296,7 @@ module Solargraph
295
296
  if fragment.base.empty?
296
297
  result.concat get_methods(pin.path)
297
298
  else
298
- type = probe.infer_signature_type(fragment.base, pin, fragment.locals)
299
+ type = probe.infer_signature_type("#{pin.path}.new.#{fragment.base}", pin, fragment.locals)
299
300
  unless type.nil?
300
301
  namespace, scope = extract_namespace_and_scope(type)
301
302
  result.concat get_methods(namespace, scope: scope)
@@ -321,7 +322,11 @@ module Solargraph
321
322
  # @return [Array<Solargraph::Pin::Base>]
322
323
  def define fragment
323
324
  return [] if fragment.string? or fragment.comment?
324
- probe.infer_signature_pins fragment.whole_signature, fragment.named_path, fragment.locals
325
+ if fragment.base_literal?
326
+ probe.infer_signature_pins fragment.whole_signature, Pin::ProxyMethod.new(fragment.base_literal), fragment.locals
327
+ else
328
+ probe.infer_signature_pins fragment.whole_signature, fragment.named_path, fragment.locals
329
+ end
325
330
  end
326
331
 
327
332
  # Infer a return type from a fragment. This method will attempt to resolve
@@ -345,9 +350,13 @@ module Solargraph
345
350
  def signify fragment
346
351
  return [] unless fragment.argument?
347
352
  return [] if fragment.recipient.whole_signature.nil? or fragment.recipient.whole_signature.empty?
348
- probe.infer_signature_pins(
349
- fragment.recipient.whole_signature, fragment.named_path, fragment.locals
350
- ).select{ |pin| pin.kind == Pin::METHOD }
353
+ result = []
354
+ if fragment.recipient.base_literal?
355
+ result.concat probe.infer_signature_pins(fragment.recipient.whole_signature, Pin::ProxyMethod.new(fragment.recipient.base_literal), fragment.locals)
356
+ else
357
+ result.concat probe.infer_signature_pins(fragment.recipient.whole_signature, fragment.named_path, fragment.locals)
358
+ end
359
+ result.select{ |pin| pin.kind == Pin::METHOD }
351
360
  end
352
361
 
353
362
  # Get an array of all suggestions that match the specified path.
@@ -359,6 +368,10 @@ module Solargraph
359
368
  result = []
360
369
  result.concat store.get_path_pins(path)
361
370
  result.concat yard_map.objects(path)
371
+ if result.empty?
372
+ lp = live_map.get_path_pin(path)
373
+ result.push lp unless lp.nil?
374
+ end
362
375
  result
363
376
  end
364
377
 
@@ -426,6 +439,12 @@ module Solargraph
426
439
 
427
440
  private
428
441
 
442
+ def refresh_store_and_maps
443
+ @store = ApiMap::Store.new(@sources)
444
+ @live_map = Solargraph::LiveMap.new(self)
445
+ @yard_map = Solargraph::YardMap.new(required: required, workspace: workspace)
446
+ end
447
+
429
448
  def process_virtual
430
449
  unless @virtual_source.nil?
431
450
  map_source @virtual_source
@@ -451,9 +470,7 @@ module Solargraph
451
470
  return [] if skip.include?(reqstr)
452
471
  skip.push reqstr
453
472
  result = []
454
- if scope == :instance
455
- result.concat store.get_attrs(fqns)
456
- end
473
+ result.concat store.get_attrs(fqns, scope)
457
474
  result.concat store.get_methods(fqns, scope: scope, visibility: visibility)
458
475
  if deep
459
476
  sc = store.get_superclass(fqns)
@@ -1,5 +1,8 @@
1
1
  module Solargraph
2
2
  class ApiMap
3
+ # The result of a completion request containing the pins that describe
4
+ # completion options and the range to be replaced.
5
+ #
3
6
  class Completion
4
7
  # @return [Array<Solargraph::Pin::Base>]
5
8
  attr_reader :pins
@@ -1,16 +1,6 @@
1
1
  module Solargraph
2
2
  class ApiMap
3
3
  class Probe
4
- class VirtualPin
5
- attr_reader :return_type
6
- def initialize return_type
7
- @return_type = return_type
8
- end
9
- def namespace
10
- @namespace ||= TypeMethods.extract_namespace(@return_type)
11
- end
12
- end
13
-
14
4
  include TypeMethods
15
5
 
16
6
  # @return [Solargraph::ApiMap]
@@ -29,8 +19,8 @@ module Solargraph
29
19
  return infer_word_pins(base, context_pin, locals) if rest.nil?
30
20
  pins = infer_word_pins(base, context_pin, locals).map do |pin|
31
21
  next pin unless pin.return_type.nil?
32
- type = resolve_pin_type(pin)
33
- VirtualPin.new(type)
22
+ type = resolve_pin_type(pin, locals - [pin])
23
+ Pin::ProxyMethod.new(type)
34
24
  end
35
25
  return [] if pins.empty?
36
26
  rest = rest.split('.')
@@ -58,7 +48,7 @@ module Solargraph
58
48
  def infer_signature_type signature, context_pin, locals
59
49
  pins = infer_signature_pins(signature, context_pin, locals)
60
50
  pins.each do |pin|
61
- type = resolve_pin_type(pin)
51
+ type = resolve_pin_type(pin, locals - [pin])
62
52
  return qualify(type, pin.named_context) unless type.nil?
63
53
  end
64
54
  nil
@@ -75,9 +65,16 @@ module Solargraph
75
65
  namespace, scope = extract_namespace_and_scope_from_pin(context_pin)
76
66
  return api_map.pins.select{|pin| word_matches_context?(word, namespace, scope, pin)} if variable_name?(word)
77
67
  result = []
78
- result.concat api_map.get_path_suggestions(word)
68
+ cparts = namespace.split('::')
69
+ until cparts.empty?
70
+ break unless result.empty?
71
+ cur = cparts.join('::')
72
+ result.concat api_map.get_path_suggestions("#{cur}::#{word}")
73
+ cparts.pop
74
+ end
75
+ result.concat api_map.get_path_suggestions(word) if result.empty?
79
76
  result.concat api_map.get_methods(namespace, scope: scope, visibility: [:public, :private, :protected]).select{|pin| pin.name == word} unless word.include?('::')
80
- result.concat api_map.get_constants('', namespace).select{|pin| pin.name == word}
77
+ result.concat api_map.get_constants('', namespace).select{|pin| pin.name == word} if result.empty?
81
78
  result
82
79
  end
83
80
 
@@ -151,11 +148,11 @@ module Solargraph
151
148
  pin
152
149
  end
153
150
 
154
- def resolve_pin_type pin
151
+ def resolve_pin_type pin, locals
155
152
  pin.return_type
156
153
  return pin.return_type unless pin.return_type.nil?
157
154
  return resolve_block_parameter(pin) if pin.kind == Pin::BLOCK_PARAMETER
158
- return resolve_variable(pin) if pin.variable?
155
+ return resolve_variable(pin, locals) if pin.variable?
159
156
  nil
160
157
  end
161
158
 
@@ -184,10 +181,10 @@ module Solargraph
184
181
  nil
185
182
  end
186
183
 
187
- def resolve_variable(pin)
184
+ def resolve_variable(pin, locals)
188
185
  return nil if pin.nil_assignment?
189
186
  # @todo Do we need the locals here?
190
- return infer_signature_type(pin.signature, pin.context, [])
187
+ return infer_signature_type(pin.signature, pin.context, locals)
191
188
  end
192
189
 
193
190
  def get_subtypes type
@@ -43,8 +43,8 @@ module Solargraph
43
43
  }
44
44
  end
45
45
 
46
- def get_attrs fqns
47
- namespace_pins(fqns).select{ |pin| pin.kind == Pin::ATTRIBUTE }
46
+ def get_attrs fqns, scope
47
+ namespace_pins(fqns).select{ |pin| pin.kind == Pin::ATTRIBUTE and pin.scope == scope }
48
48
  end
49
49
 
50
50
  def get_superclass fqns
@@ -80,6 +80,10 @@ module Solargraph
80
80
  namespace_pins(fqns).select{|pin| pin.kind == Pin::INSTANCE_VARIABLE and pin.scope == scope}
81
81
  end
82
82
 
83
+ def get_class_variables(fqns)
84
+ namespace_pins(fqns).select{|pin| pin.kind == Pin::CLASS_VARIABLE}
85
+ end
86
+
83
87
  def get_symbols
84
88
  symbols.uniq(&:name)
85
89
  end
@@ -15,6 +15,8 @@ module Solargraph
15
15
  @command = command
16
16
  end
17
17
 
18
+ # @param source [Solargraph::Source]
19
+ # @param api_map [Solargraph::ApiMap]
18
20
  # @return [Array<Hash>]
19
21
  def diagnose source, api_map
20
22
  begin
@@ -22,6 +24,10 @@ module Solargraph
22
24
  filename = source.filename
23
25
  raise DiagnosticsError, 'No command specified' if command.nil? or command.empty?
24
26
  cmd = "#{Shellwords.escape(command)} -f j -s #{Shellwords.escape(filename)}"
27
+ unless api_map.workspace.nil? or api_map.workspace.directory.nil?
28
+ rc = File.join(api_map.workspace.directory, '.rubocop.yml')
29
+ cmd += " -c #{Shellwords.escape(rc)}" if File.file?(rc)
30
+ end
25
31
  o, e, s = Open3.capture3(cmd, stdin_data: text)
26
32
  STDERR.puts e unless e.empty?
27
33
  raise DiagnosticsError, "Command '#{command}' is not available (gem exception)" if e.include?('Gem::Exception')
@@ -323,6 +323,14 @@ module Solargraph
323
323
  result
324
324
  end
325
325
 
326
+ def references_from filename, line, column
327
+ result = nil
328
+ @change_semaphore.synchronize do
329
+ result = library.references_from(filename, line, column)
330
+ end
331
+ result
332
+ end
333
+
326
334
  def query_symbols query
327
335
  result = nil
328
336
  @change_semaphore.synchronize { result = library.query_symbols(query) }
@@ -446,7 +454,7 @@ module Solargraph
446
454
  Thread.new do
447
455
  diagnoser = Diagnostics::Rubocop.new
448
456
  until stopped?
449
- sleep 1
457
+ sleep 0.1
450
458
  if !options['diagnostics']
451
459
  @change_semaphore.synchronize { @diagnostics_queue.clear }
452
460
  next
@@ -56,6 +56,8 @@ module Solargraph
56
56
  register 'textDocument/formatting', TextDocument::Formatting
57
57
  register 'textDocument/onTypeFormatting', TextDocument::OnTypeFormatting
58
58
  register 'textDocument/documentSymbol', TextDocument::DocumentSymbol
59
+ register 'textDocument/references', TextDocument::References
60
+ register 'textDocument/rename', TextDocument::Rename
59
61
  register 'workspace/didChangeWatchedFiles', Workspace::DidChangeWatchedFiles
60
62
  register 'workspace/didChangeConfiguration', Workspace::DidChangeConfiguration
61
63
  register 'workspace/symbol', Workspace::WorkspaceSymbol
@@ -64,6 +66,7 @@ module Solargraph
64
66
  register '$/solargraph/search', Extended::Search
65
67
  register '$/solargraph/checkGemVersion', Extended::CheckGemVersion
66
68
  register '$/solargraph/documentGems', Extended::DocumentGems
69
+ register '$/solargraph/downloadCore', Extended::DownloadCore
67
70
  register 'shutdown', Shutdown
68
71
  register 'exit', ExitNotification
69
72
  end
@@ -11,6 +11,7 @@ module Solargraph
11
11
  autoload :Search, 'solargraph/language_server/message/extended/search'
12
12
  autoload :CheckGemVersion, 'solargraph/language_server/message/extended/check_gem_version'
13
13
  autoload :DocumentGems, 'solargraph/language_server/message/extended/document_gems'
14
+ autoload :DownloadCore, 'solargraph/language_server/message/extended/download_core'
14
15
  end
15
16
  end
16
17
  end
@@ -11,7 +11,7 @@ module Solargraph
11
11
  class CheckGemVersion < Base
12
12
  def process
13
13
  o, s = Open3.capture2("gem search solargraph")
14
- match = o.match(/solargraph \([0-9\.]*?\)/)
14
+ match = o.match(/solargraph \(([\d]*\.[\d]*\.[\d]*)\)/)
15
15
  # @todo Error if no match or status code != 0
16
16
  available = Gem::Version.new(match[1])
17
17
  current = Gem::Version.new(Solargraph::VERSION)
@@ -0,0 +1,25 @@
1
+ require 'open3'
2
+
3
+ module Solargraph
4
+ module LanguageServer
5
+ module Message
6
+ module Extended
7
+ # Update core Ruby documentation.
8
+ #
9
+ class DownloadCore < Base
10
+ def process
11
+ cmd = "solargraph download-core"
12
+ o, s = Open3.capture2(cmd)
13
+ if s != 0
14
+ host.show_message "An error occurred while downloading documentation.", LanguageServer::MessageTypes::ERROR
15
+ else
16
+ ver = o.match(/[\d]*\.[\d]*\.[\d]*/)[0]
17
+ host.show_message "Downloaded documentation for Ruby #{ver}.", LanguageServer::MessageTypes::INFO
18
+ # @todo YardMap should be refreshed
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -11,12 +11,14 @@ module Solargraph
11
11
  definitionProvider: true,
12
12
  documentSymbolProvider: true,
13
13
  workspaceSymbolProvider: true,
14
+ renameProvider: true,
14
15
  workspace: {
15
16
  workspaceFolders: {
16
17
  supported: true,
17
18
  changeNotifications: true
18
19
  }
19
- }
20
+ },
21
+ referencesProvider: true
20
22
  }
21
23
  }
22
24
  result[:capabilities].merge! static_completion unless dynamic_completion?
@@ -2,19 +2,21 @@ module Solargraph
2
2
  module LanguageServer
3
3
  module Message
4
4
  module TextDocument
5
- autoload :Base, 'solargraph/language_server/message/text_document/base'
6
- autoload :Completion, 'solargraph/language_server/message/text_document/completion'
7
- autoload :DidOpen, 'solargraph/language_server/message/text_document/did_open'
8
- autoload :DidChange, 'solargraph/language_server/message/text_document/did_change'
9
- autoload :DidClose, 'solargraph/language_server/message/text_document/did_close'
10
- autoload :DidSave, 'solargraph/language_server/message/text_document/did_save'
11
- autoload :Hover, 'solargraph/language_server/message/text_document/hover'
12
- autoload :SignatureHelp, 'solargraph/language_server/message/text_document/signature_help'
5
+ autoload :Base, 'solargraph/language_server/message/text_document/base'
6
+ autoload :Completion, 'solargraph/language_server/message/text_document/completion'
7
+ autoload :DidOpen, 'solargraph/language_server/message/text_document/did_open'
8
+ autoload :DidChange, 'solargraph/language_server/message/text_document/did_change'
9
+ autoload :DidClose, 'solargraph/language_server/message/text_document/did_close'
10
+ autoload :DidSave, 'solargraph/language_server/message/text_document/did_save'
11
+ autoload :Hover, 'solargraph/language_server/message/text_document/hover'
12
+ autoload :SignatureHelp, 'solargraph/language_server/message/text_document/signature_help'
13
13
  autoload :DiagnosticsQueue, 'solargraph/language_server/message/text_document/diagnostics_queue'
14
14
  autoload :OnTypeFormatting, 'solargraph/language_server/message/text_document/on_type_formatting'
15
- autoload :Definition, 'solargraph/language_server/message/text_document/definition'
16
- autoload :DocumentSymbol, 'solargraph/language_server/message/text_document/document_symbol'
17
- autoload :Formatting, 'solargraph/language_server/message/text_document/formatting'
15
+ autoload :Definition, 'solargraph/language_server/message/text_document/definition'
16
+ autoload :DocumentSymbol, 'solargraph/language_server/message/text_document/document_symbol'
17
+ autoload :Formatting, 'solargraph/language_server/message/text_document/formatting'
18
+ autoload :References, 'solargraph/language_server/message/text_document/references'
19
+ autoload :Rename, 'solargraph/language_server/message/text_document/rename'
18
20
  end
19
21
  end
20
22
  end
@@ -11,7 +11,7 @@ module Solargraph::LanguageServer::Message::TextDocument
11
11
  line = params['position']['line']
12
12
  col = params['position']['character']
13
13
  suggestions = host.definitions_at(filename, line, col)
14
- locations = suggestions.map do |pin|
14
+ locations = suggestions.reject{|pin| pin.location.nil?}.map do |pin|
15
15
  unless pin.location.nil?
16
16
  {
17
17
  uri: file_to_uri(pin.location.filename),