solargraph 0.30.2 → 0.31.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +7 -0
  3. data/lib/solargraph/api_map.rb +31 -38
  4. data/lib/solargraph/api_map/store.rb +7 -1
  5. data/lib/solargraph/diagnostics/require_not_found.rb +2 -1
  6. data/lib/solargraph/language_server/host.rb +34 -83
  7. data/lib/solargraph/language_server/host/cataloger.rb +17 -7
  8. data/lib/solargraph/language_server/host/diagnoser.rb +19 -10
  9. data/lib/solargraph/language_server/host/dispatch.rb +110 -0
  10. data/lib/solargraph/language_server/host/sources.rb +100 -1
  11. data/lib/solargraph/language_server/message/base.rb +15 -11
  12. data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
  13. data/lib/solargraph/language_server/message/initialize.rb +32 -27
  14. data/lib/solargraph/language_server/message/text_document/completion.rb +1 -8
  15. data/lib/solargraph/language_server/transport/adapter.rb +26 -15
  16. data/lib/solargraph/language_server/transport/data_reader.rb +2 -2
  17. data/lib/solargraph/library.rb +30 -58
  18. data/lib/solargraph/live_map.rb +1 -1
  19. data/lib/solargraph/pin.rb +1 -0
  20. data/lib/solargraph/pin/base.rb +1 -1
  21. data/lib/solargraph/pin/base_method.rb +1 -1
  22. data/lib/solargraph/pin/method.rb +1 -1
  23. data/lib/solargraph/pin/method_alias.rb +15 -4
  24. data/lib/solargraph/plugin/process.rb +1 -1
  25. data/lib/solargraph/position.rb +1 -2
  26. data/lib/solargraph/server_methods.rb +1 -0
  27. data/lib/solargraph/shell.rb +0 -28
  28. data/lib/solargraph/source.rb +116 -20
  29. data/lib/solargraph/source/encoding_fixes.rb +1 -1
  30. data/lib/solargraph/source/source_chainer.rb +16 -8
  31. data/lib/solargraph/source_map.rb +11 -2
  32. data/lib/solargraph/source_map/clip.rb +1 -1
  33. data/lib/solargraph/source_map/mapper.rb +8 -5
  34. data/lib/solargraph/version.rb +1 -1
  35. data/lib/solargraph/views/environment.erb +3 -0
  36. data/lib/solargraph/workspace.rb +17 -14
  37. data/lib/solargraph/workspace/config.rb +1 -1
  38. data/lib/solargraph/yard_map.rb +6 -5
  39. data/lib/solargraph/yard_map/core_docs.rb +68 -18
  40. data/lib/solargraph/yard_map/core_gen.rb +47 -0
  41. data/lib/yard-coregen.rb +16 -0
  42. data/lib/yard-solargraph.rb +10 -1
  43. metadata +21 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61453319a056f4779bf21c852bb34b5f797207c19ff9266d422d25c724934bc1
4
- data.tar.gz: 405c13271fce7df56c5daae95b95430f5933a66728d3e2f6fff11762d4f392d0
3
+ metadata.gz: 7e808b8b4e3550a64f5737991858a16cfb43c1d4d839fa0be4c7018d9740783f
4
+ data.tar.gz: 7a90449ea2b30e07234f89bfb468eaf0e33e28711799b15064a9ae9dbcf83bc3
5
5
  SHA512:
6
- metadata.gz: 5dcd832eff27b926dd8d244feff2edc37398f0004fa62dd002f07981e325d6f5a88f7c93bc1ad91d1f0ce34954790afc0410ed9581936d5ad57a465f99cc2372
7
- data.tar.gz: 246cb5bbb21a7134532512c0321e86633d21adcf4eebd24de3d33427ab3da39663dafba488b8e0a304abd252c874408513ced6370cdc8e88cde18187f1242b79
6
+ metadata.gz: d87b8b907a0c33376f138381ad1b70c8c49be1ce504aec7e098bcac84030f53c9c469ea87b3b0e2fdaebe04bc51cf0b338ac3074fa1064be47f87e60c82499c4
7
+ data.tar.gz: 5888e2114dfea0da7dd3681d800400f7393cb63804f8d4f043aac2f74b0bf9bce1f986f34ae9d85bcc9753e49f5c773ad7ec3791257fbe372f632f3deb81ee04
@@ -40,6 +40,13 @@ module Solargraph
40
40
  YARDOC_PATH = File.realpath(File.join(dir, '..', 'yardoc'))
41
41
  YARD_EXTENSION_FILE = File.join(dir, 'yard-solargraph.rb')
42
42
  VIEWS_PATH = File.join(dir, 'solargraph', 'views')
43
+
44
+ # A convenience method for Solargraph::Logging.logger.
45
+ #
46
+ # @return [Logger]
47
+ def self.logger
48
+ Solargraph::Logging.logger
49
+ end
43
50
  end
44
51
 
45
52
  Solargraph::YardMap::CoreDocs.require_minimum
@@ -11,7 +11,7 @@ module Solargraph
11
11
  autoload :SourceToYard, 'solargraph/api_map/source_to_yard'
12
12
  autoload :Store, 'solargraph/api_map/store'
13
13
 
14
- include Solargraph::ApiMap::SourceToYard
14
+ include SourceToYard
15
15
 
16
16
  # Get a LiveMap associated with the current workspace.
17
17
  #
@@ -40,7 +40,7 @@ module Solargraph
40
40
  @store = Store.new(pins + YardMap.new.pins)
41
41
  @unresolved_requires = []
42
42
  }
43
- resolve_method_aliases
43
+ # resolve_method_aliases
44
44
  self
45
45
  end
46
46
 
@@ -66,9 +66,13 @@ module Solargraph
66
66
  # Bundle always needs to be merged if it adds or removes sources
67
67
  merged = (bundle.sources.length == source_map_hash.values.length)
68
68
  bundle.sources.each do |source|
69
- if source_map_hash.has_key?(source.filename)
70
- if source_map_hash[source.filename].code == source.code
69
+ if source_map_hash.key?(source.filename)
70
+ if source_map_hash[source.filename].code == source.code && source_map_hash[source.filename].source.synchronized? && source.synchronized?
71
71
  new_map_hash[source.filename] = source_map_hash[source.filename]
72
+ elsif !source.synchronized?
73
+ new_map_hash[source.filename] = source_map_hash[source.filename]
74
+ # @todo Smelly instance variable access
75
+ new_map_hash[source.filename].instance_variable_set(:@source, source)
72
76
  else
73
77
  map = Solargraph::SourceMap.map(source)
74
78
  if source_map_hash[source.filename].try_merge!(map)
@@ -114,7 +118,7 @@ module Solargraph
114
118
  @store = new_store
115
119
  @unresolved_requires = yard_map.unresolved_requires
116
120
  }
117
- resolve_method_aliases
121
+ # resolve_method_aliases
118
122
  self
119
123
  end
120
124
 
@@ -142,8 +146,7 @@ module Solargraph
142
146
  # @param directory [String]
143
147
  # @return [ApiMap]
144
148
  def self.load directory
145
- # @todo How should this work?
146
- api_map = self.new #(Solargraph::Workspace.new(directory))
149
+ api_map = self.new
147
150
  workspace = Solargraph::Workspace.new(directory)
148
151
  api_map.catalog Bundle.new(workspace: workspace)
149
152
  api_map
@@ -220,13 +223,11 @@ module Solargraph
220
223
  return qualify(context) if namespace == 'self'
221
224
  cached = cache.get_qualified_namespace(namespace, context)
222
225
  return cached.clone unless cached.nil?
223
- # result = inner_qualify(namespace, context, [])
224
- # result = result[2..-1] if !result.nil? && result.start_with?('::')
225
- if namespace.start_with?('::')
226
- result = inner_qualify(namespace[2..-1], '', [])
227
- else
228
- result = inner_qualify(namespace, context, [])
229
- end
226
+ result = if namespace.start_with?('::')
227
+ inner_qualify(namespace[2..-1], '', [])
228
+ else
229
+ inner_qualify(namespace, context, [])
230
+ end
230
231
  cache.set_qualified_namespace(namespace, context, result)
231
232
  result
232
233
  end
@@ -296,8 +297,9 @@ module Solargraph
296
297
  # exist = result.map(&:name)
297
298
  # result.concat live.reject{|p| exist.include?(p.name)}
298
299
  # end
299
- cache.set_methods(fqns, scope, visibility, deep, result)
300
- result
300
+ resolved = resolve_method_aliases(result)
301
+ cache.set_methods(fqns, scope, visibility, deep, resolved)
302
+ resolved
301
303
  end
302
304
 
303
305
  # Get an array of method pins for a complex type.
@@ -371,7 +373,7 @@ module Solargraph
371
373
  # lp = live_map.get_path_pin(path)
372
374
  # result.push lp unless lp.nil?
373
375
  # end
374
- result
376
+ resolve_method_aliases(result)
375
377
  end
376
378
 
377
379
  # Get an array of pins that match the specified path.
@@ -461,6 +463,7 @@ module Solargraph
461
463
 
462
464
  private
463
465
 
466
+ # @return [YardMap]
464
467
  def yard_map
465
468
  @yard_map ||= YardMap.new
466
469
  end
@@ -469,23 +472,17 @@ module Solargraph
469
472
  #
470
473
  # @return [Hash{String => SourceMap}]
471
474
  def source_map_hash
472
- @mutex.synchronize {
473
- @source_map_hash
474
- }
475
+ @mutex.synchronize { @source_map_hash }
475
476
  end
476
477
 
477
478
  # @return [ApiMap::Store]
478
479
  def store
479
- @mutex.synchronize {
480
- @store
481
- }
480
+ @mutex.synchronize { @store }
482
481
  end
483
482
 
484
483
  # @return [Solargraph::ApiMap::Cache]
485
484
  def cache
486
- @mutex.synchronize {
487
- @cache
488
- }
485
+ @mutex.synchronize { @cache }
489
486
  end
490
487
 
491
488
  # @param fqns [String] A fully qualified namespace
@@ -558,7 +555,7 @@ module Solargraph
558
555
  # @return [void]
559
556
  def require_extensions
560
557
  Gem::Specification.all_names.select{|n| n.match(/^solargraph\-[a-z0-9_\-]*?\-ext\-[0-9\.]*$/)}.each do |n|
561
- STDERR.puts "Loading extension #{n}"
558
+ Solargraph::Logging.logger.info "Loading extension #{n}"
562
559
  require n.match(/^(solargraph\-[a-z0-9_\-]*?\-ext)\-[0-9\.]*$/)[1]
563
560
  end
564
561
  end
@@ -583,9 +580,8 @@ module Solargraph
583
580
  return inner_qualify(root, '', skip)
584
581
  end
585
582
  else
586
- if (root == '')
583
+ if root == ''
587
584
  return name if store.namespace_exists?(name)
588
- # @todo What to do about the @namespace_includes stuff above?
589
585
  else
590
586
  roots = root.to_s.split('::')
591
587
  while roots.length > 0
@@ -642,18 +638,15 @@ module Solargraph
642
638
  false
643
639
  end
644
640
 
645
- # @return [void]
646
- def resolve_method_aliases
647
- aliased = false
648
- result = pins.map do |pin|
649
- next pin unless pin.is_a?(Pin::MethodAlias)
650
- origin = get_method_stack(pin.namespace, pin.original, scope: pin.scope).select{|pin| pin.class == Pin::Method}.first
641
+ # @param pins [Array<Pin::Base>]
642
+ # @return [Array<Pin::Base>]
643
+ def resolve_method_aliases pins
644
+ pins.map do |pin|
645
+ next pin unless pin.kind == Pin::METHOD_ALIAS
646
+ origin = get_method_stack(pin.namespace, pin.original, scope: pin.scope).select{|pin| pin.is_a?(Pin::BaseMethod)}.first
651
647
  next pin if origin.nil?
652
- aliased = true
653
648
  Pin::Method.new(pin.location, pin.namespace, pin.name, origin.comments, origin.scope, origin.visibility, origin.parameters)
654
649
  end
655
- return nil unless aliased
656
- @mutex.synchronize { @store = Store.new(result) }
657
650
  end
658
651
  end
659
652
  end
@@ -26,8 +26,9 @@ module Solargraph
26
26
  # @param visibility [Array<Symbol>]
27
27
  # @return [Array<Solargraph::Pin::Base>]
28
28
  def get_methods fqns, scope: :instance, visibility: [:public]
29
+ kinds = [Pin::METHOD, Pin::ATTRIBUTE]
29
30
  namespace_children(fqns).select{ |pin|
30
- [Pin::METHOD, Pin::ATTRIBUTE].include?(pin.kind) && pin.scope == scope && visibility.include?(pin.visibility)
31
+ kinds.include?(pin.kind) && pin.scope == scope && visibility.include?(pin.visibility)
31
32
  }
32
33
  end
33
34
 
@@ -120,6 +121,11 @@ module Solargraph
120
121
  end
121
122
  end
122
123
 
124
+ def inspect
125
+ # Avoid insane dumps in specs
126
+ to_s
127
+ end
128
+
123
129
  private
124
130
 
125
131
  # @param fqns [String]
@@ -5,9 +5,10 @@ module Solargraph
5
5
  #
6
6
  class RequireNotFound < Base
7
7
  def diagnose source, api_map
8
+ return [] unless source.parsed? && source.synchronized?
8
9
  result = []
9
10
  refs = {}
10
- map = Solargraph::SourceMap.map(source)
11
+ map = api_map.source_map(source.filename)
11
12
  map.requires.each do |ref|
12
13
  refs[ref.name] = ref
13
14
  end
@@ -11,9 +11,11 @@ module Solargraph
11
11
  autoload :Diagnoser, 'solargraph/language_server/host/diagnoser'
12
12
  autoload :Cataloger, 'solargraph/language_server/host/cataloger'
13
13
  autoload :Sources, 'solargraph/language_server/host/sources'
14
+ autoload :Dispatch, 'solargraph/language_server/host/dispatch'
14
15
 
15
- include Solargraph::LanguageServer::UriHelpers
16
+ include UriHelpers
16
17
  include Logging
18
+ include Dispatch
17
19
 
18
20
  def initialize
19
21
  @cancel_semaphore = Mutex.new
@@ -21,12 +23,23 @@ module Solargraph
21
23
  @register_semaphore = Mutex.new
22
24
  @cancel = []
23
25
  @buffer = ''
24
- @stopped = false
26
+ @stopped = true
25
27
  @next_request_id = 0
26
28
  @dynamic_capabilities = Set.new
27
29
  @registered_capabilities = Set.new
28
30
  end
29
31
 
32
+ # Start asynchronous process handling.
33
+ #
34
+ # @return [void]
35
+ def start
36
+ return unless stopped?
37
+ @stopped = false
38
+ diagnoser.start
39
+ cataloger.start
40
+ sources.start
41
+ end
42
+
30
43
  # Update the configuration options with the provided hash.
31
44
  #
32
45
  # @param update [Hash]
@@ -62,6 +75,7 @@ module Solargraph
62
75
  # Delete the specified ID from the list of cancelled IDs if it exists.
63
76
  #
64
77
  # @param id [Integer]
78
+ # @return [void]
65
79
  def clear id
66
80
  @cancel_semaphore.synchronize { @cancel.delete id }
67
81
  end
@@ -71,7 +85,7 @@ module Solargraph
71
85
  #
72
86
  # @param request [Hash] The contents of the message.
73
87
  # @return [Solargraph::LanguageServer::Message::Base] The message handler.
74
- def start request
88
+ def receive request
75
89
  if request['method']
76
90
  logger.info "Server received #{request['method']}"
77
91
  logger.debug request
@@ -79,8 +93,8 @@ module Solargraph
79
93
  begin
80
94
  message.process
81
95
  rescue Exception => e
82
- STDERR.puts e.message
83
- STDERR.puts e.backtrace
96
+ logger.warn "Error processing request: [#{e.class}] #{e.message}"
97
+ logger.warn e.backtrace
84
98
  message.set_error Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}"
85
99
  end
86
100
  message
@@ -89,7 +103,8 @@ module Solargraph
89
103
  requests[request['id']].process(request['result'])
90
104
  requests.delete request['id']
91
105
  else
92
- STDERR.puts "Invalid message received."
106
+ logger.warn "Invalid message received."
107
+ logger.debug request
93
108
  end
94
109
  end
95
110
 
@@ -112,11 +127,13 @@ module Solargraph
112
127
  # Delete the specified file from the library.
113
128
  #
114
129
  # @param uri [String] The file uri.
130
+ # @return [void]
115
131
  def delete uri
116
132
  sources.close uri
117
133
  filename = uri_to_file(uri)
118
134
  libraries.each do |lib|
119
- lib.delete filename
135
+ # lib.delete filename
136
+ lib.detach filename
120
137
  end
121
138
  send_notification "textDocument/publishDiagnostics", {
122
139
  uri: uri,
@@ -129,6 +146,7 @@ module Solargraph
129
146
  # @param uri [String] The file uri.
130
147
  # @param text [String] The contents of the file.
131
148
  # @param version [Integer] A version number.
149
+ # @return [void]
132
150
  def open uri, text, version
133
151
  src = sources.open(uri, text, version)
134
152
  libraries.each do |lib|
@@ -167,6 +185,7 @@ module Solargraph
167
185
  if sources.include?(uri)
168
186
  logger.info "Diagnosing #{uri}"
169
187
  library = library_for(uri)
188
+ library.catalog
170
189
  begin
171
190
  results = library.diagnose uri_to_file(uri)
172
191
  send_notification "textDocument/publishDiagnostics", {
@@ -196,11 +215,7 @@ module Solargraph
196
215
  # @return [void]
197
216
  def change params
198
217
  updater = generate_updater(params)
199
- src = sources.update(params['textDocument']['uri'], updater)
200
- libraries.each do |lib|
201
- lib.merge src
202
- end
203
- diagnoser.schedule params['textDocument']['uri']
218
+ sources.async_update params['textDocument']['uri'], updater
204
219
  end
205
220
 
206
221
  # Queue a message to be sent to the client.
@@ -238,16 +253,13 @@ module Solargraph
238
253
  path = normalize_separators(directory) unless directory.nil?
239
254
  begin
240
255
  lib = Solargraph::Library.load(path, name)
256
+ libraries.push lib
241
257
  rescue WorkspaceTooLargeError => e
242
258
  send_notification 'window/showMessage', {
243
259
  'type' => Solargraph::LanguageServer::MessageTypes::WARNING,
244
260
  'message' => e.message
245
261
  }
246
- lib = Solargraph::Library.new('', name)
247
262
  end
248
- libraries.push lib
249
- diagnoser.start
250
- cataloger.start
251
263
  end
252
264
 
253
265
  # Prepare multiple folders.
@@ -400,9 +412,11 @@ module Solargraph
400
412
 
401
413
  # @return [void]
402
414
  def stop
415
+ return if @stopped
403
416
  @stopped = true
404
417
  cataloger.stop
405
418
  diagnoser.stop
419
+ sources.stop
406
420
  end
407
421
 
408
422
  def stopped?
@@ -576,80 +590,17 @@ module Solargraph
576
590
  }
577
591
  end
578
592
 
579
- # Catalog the library.
580
- #
581
- # @return [void]
582
- def catalog lib
583
- lib.catalog
584
- end
585
-
586
593
  # @param uri [String]
587
594
  # @return [Array<Range>]
588
595
  def folding_ranges uri
589
- library = library_for(uri)
590
- file = uri_to_file(uri)
591
- library.folding_ranges(file)
596
+ # library = library_for(uri)
597
+ # file = uri_to_file(uri)
598
+ # library.folding_ranges(file)
599
+ sources.find(uri).folding_ranges
592
600
  end
593
601
 
594
602
  private
595
603
 
596
- # @return [Array<Library>]
597
- def libraries
598
- @libraries ||= []
599
- end
600
-
601
- # @return [Sources]
602
- def sources
603
- @sources ||= Sources.new
604
- end
605
-
606
- # @param uri [String]
607
- # @return [Library]
608
- def library_for uri
609
- explicit_library_for(uri) ||
610
- implicit_library_for(uri) ||
611
- generic_library_for(uri)
612
- end
613
-
614
- # @param uri [String]
615
- # @return [Library, nil]
616
- def explicit_library_for uri
617
- filename = uri_to_file(uri)
618
- libraries.each do |lib|
619
- if lib.contain?(filename) #|| lib.open?(filename)
620
- lib.attach sources.find(uri) if sources.include?(uri)
621
- return lib
622
- end
623
- end
624
- nil
625
- end
626
-
627
- # @param uri [String]
628
- # @return [Library, nil]
629
- def implicit_library_for uri
630
- filename = uri_to_file(uri)
631
- libraries.each do |lib|
632
- # return lib if filename.start_with?(lib.workspace.directory)
633
- if lib.open?(filename) || filename.start_with?(lib.workspace.directory)
634
- lib.attach sources.find(uri)
635
- return lib
636
- end
637
- end
638
- nil
639
- end
640
-
641
- # @param uri [String]
642
- # @return [Library]
643
- def generic_library_for uri
644
- generic_library.attach sources.find(uri)
645
- generic_library
646
- end
647
-
648
- # @return [Library]
649
- def generic_library
650
- @generic_library ||= Solargraph::Library.new
651
- end
652
-
653
604
  # @return [Diagnoser]
654
605
  def diagnoser
655
606
  @diagnoser ||= Diagnoser.new(self)