solargraph 0.58.2 → 0.59.0.dev.1
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/.envrc +3 -0
- data/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +40 -36
- data/.github/workflows/rspec.yml +45 -13
- data/.github/workflows/typecheck.yml +2 -2
- data/.gitignore +0 -1
- data/.rubocop_todo.yml +27 -49
- data/CHANGELOG.md +1 -7
- data/README.md +3 -3
- data/Rakefile +1 -0
- data/lib/solargraph/api_map/cache.rb +3 -3
- data/lib/solargraph/api_map/constants.rb +13 -3
- data/lib/solargraph/api_map/index.rb +22 -11
- data/lib/solargraph/api_map/source_to_yard.rb +13 -1
- data/lib/solargraph/api_map/store.rb +11 -8
- data/lib/solargraph/api_map.rb +105 -50
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +16 -2
- data/lib/solargraph/complex_type/unique_type.rb +170 -20
- data/lib/solargraph/complex_type.rb +119 -14
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +3 -1
- data/lib/solargraph/convention/data_definition.rb +4 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +1 -0
- data/lib/solargraph/convention/struct_definition.rb +5 -1
- data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +2 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/doc_map.rb +134 -373
- data/lib/solargraph/equality.rb +1 -1
- data/lib/solargraph/gem_pins.rb +14 -15
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
- data/lib/solargraph/language_server/host/dispatch.rb +1 -0
- data/lib/solargraph/language_server/host/message_worker.rb +2 -1
- data/lib/solargraph/language_server/host/sources.rb +1 -0
- data/lib/solargraph/language_server/host.rb +6 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -7
- data/lib/solargraph/language_server/message/extended/document.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/completion.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +2 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -0
- data/lib/solargraph/library.rb +59 -13
- data/lib/solargraph/location.rb +9 -4
- data/lib/solargraph/logging.rb +21 -1
- data/lib/solargraph/parser/comment_ripper.rb +7 -0
- data/lib/solargraph/parser/flow_sensitive_typing.rb +330 -102
- data/lib/solargraph/parser/node_processor/base.rb +32 -2
- data/lib/solargraph/parser/node_processor.rb +7 -6
- data/lib/solargraph/parser/parser_gem/class_methods.rb +28 -10
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +31 -6
- data/lib/solargraph/parser/parser_gem/node_methods.rb +27 -7
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +2 -0
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -11
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +7 -0
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +3 -2
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +2 -2
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +12 -7
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +5 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +1 -1
- data/lib/solargraph/pin/base.rb +53 -21
- data/lib/solargraph/pin/base_variable.rb +312 -20
- data/lib/solargraph/pin/block.rb +26 -4
- data/lib/solargraph/pin/breakable.rb +5 -1
- data/lib/solargraph/pin/callable.rb +50 -3
- data/lib/solargraph/pin/closure.rb +2 -6
- data/lib/solargraph/pin/common.rb +20 -5
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/conversions.rb +2 -1
- data/lib/solargraph/pin/delegated_method.rb +15 -4
- data/lib/solargraph/pin/documenting.rb +1 -0
- data/lib/solargraph/pin/instance_variable.rb +5 -1
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/local_variable.rb +13 -57
- data/lib/solargraph/pin/method.rb +90 -42
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +7 -1
- data/lib/solargraph/pin/parameter.rb +76 -13
- data/lib/solargraph/pin/proxy_type.rb +2 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference.rb +2 -0
- data/lib/solargraph/pin/search.rb +1 -0
- data/lib/solargraph/pin/signature.rb +8 -0
- data/lib/solargraph/pin/symbol.rb +1 -1
- data/lib/solargraph/pin/until.rb +1 -1
- data/lib/solargraph/pin/while.rb +1 -1
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/pin_cache.rb +477 -57
- data/lib/solargraph/position.rb +12 -26
- data/lib/solargraph/range.rb +6 -6
- data/lib/solargraph/rbs_map/conversions.rb +33 -10
- data/lib/solargraph/rbs_map/core_map.rb +24 -17
- data/lib/solargraph/rbs_map/stdlib_map.rb +34 -5
- data/lib/solargraph/rbs_map.rb +74 -20
- data/lib/solargraph/shell.rb +73 -28
- data/lib/solargraph/source/chain/call.rb +52 -17
- data/lib/solargraph/source/chain/constant.rb +2 -0
- data/lib/solargraph/source/chain/hash.rb +1 -0
- data/lib/solargraph/source/chain/if.rb +1 -0
- data/lib/solargraph/source/chain/instance_variable.rb +22 -1
- data/lib/solargraph/source/chain/literal.rb +5 -0
- data/lib/solargraph/source/chain/or.rb +9 -1
- data/lib/solargraph/source/chain.rb +25 -22
- data/lib/solargraph/source/change.rb +9 -2
- data/lib/solargraph/source/cursor.rb +7 -1
- data/lib/solargraph/source/source_chainer.rb +13 -3
- data/lib/solargraph/source/updater.rb +4 -0
- data/lib/solargraph/source.rb +33 -7
- data/lib/solargraph/source_map/clip.rb +13 -2
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +24 -1
- data/lib/solargraph/source_map.rb +14 -6
- data/lib/solargraph/type_checker/problem.rb +3 -1
- data/lib/solargraph/type_checker/rules.rb +75 -2
- data/lib/solargraph/type_checker.rb +111 -30
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +3 -1
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +158 -16
- data/lib/solargraph/yard_map/helpers.rb +2 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +5 -1
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/mapper.rb +5 -0
- data/lib/solargraph/yardoc.rb +33 -23
- data/lib/solargraph.rb +24 -3
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +1 -1
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/solargraph.gemspec +2 -1
- metadata +12 -7
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
module LanguageServer
|
|
5
|
-
class Host
|
|
6
|
-
# An asynchronous diagnosis reporter.
|
|
7
|
-
#
|
|
8
|
-
class Diagnoser
|
|
9
|
-
# @param host [Host]
|
|
10
|
-
def initialize host
|
|
11
|
-
@host = host
|
|
12
|
-
@mutex = Mutex.new
|
|
13
|
-
@queue = []
|
|
14
|
-
@stopped = true
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# Schedule a file to be diagnosed.
|
|
18
|
-
#
|
|
19
|
-
# @param uri [String]
|
|
20
|
-
# @return [void]
|
|
21
|
-
def schedule uri
|
|
22
|
-
mutex.synchronize { queue.push uri }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Stop the diagnosis thread.
|
|
26
|
-
#
|
|
27
|
-
# @return [void]
|
|
28
|
-
def stop
|
|
29
|
-
@stopped = true
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
# True is the diagnoser is stopped.
|
|
33
|
-
#
|
|
34
|
-
# @return [Boolean]
|
|
35
|
-
def stopped?
|
|
36
|
-
@stopped
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Start the diagnosis thread.
|
|
40
|
-
#
|
|
41
|
-
# @return [self, nil]
|
|
42
|
-
def start
|
|
43
|
-
return unless @stopped
|
|
44
|
-
@stopped = false
|
|
45
|
-
Thread.new do
|
|
46
|
-
until stopped?
|
|
47
|
-
tick
|
|
48
|
-
sleep 0.1
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
self
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Perform diagnoses.
|
|
55
|
-
#
|
|
56
|
-
# @return [void]
|
|
57
|
-
def tick
|
|
58
|
-
return if queue.empty? || host.synchronizing?
|
|
59
|
-
if !host.options['diagnostics']
|
|
60
|
-
mutex.synchronize { queue.clear }
|
|
61
|
-
return
|
|
62
|
-
end
|
|
63
|
-
current = mutex.synchronize { queue.shift }
|
|
64
|
-
return if queue.include?(current)
|
|
65
|
-
begin
|
|
66
|
-
host.diagnose current
|
|
67
|
-
rescue InvalidOffsetError
|
|
68
|
-
# @todo This error can occur when the Source is out of sync with
|
|
69
|
-
# with the ApiMap. It's probably not the best way to handle it,
|
|
70
|
-
# but it's quick and easy.
|
|
71
|
-
Logging.logger.warn "Deferring diagnosis due to invalid offset: #{current}"
|
|
72
|
-
mutex.synchronize { queue.push current }
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
private
|
|
77
|
-
|
|
78
|
-
# @return [Host]
|
|
79
|
-
attr_reader :host
|
|
80
|
-
|
|
81
|
-
# @return [Mutex]
|
|
82
|
-
attr_reader :mutex
|
|
83
|
-
|
|
84
|
-
# @return [::Array]
|
|
85
|
-
attr_reader :queue
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module LanguageServer
|
|
5
|
+
class Host
|
|
6
|
+
# An asynchronous diagnosis reporter.
|
|
7
|
+
#
|
|
8
|
+
class Diagnoser
|
|
9
|
+
# @param host [Host]
|
|
10
|
+
def initialize host
|
|
11
|
+
@host = host
|
|
12
|
+
@mutex = Mutex.new
|
|
13
|
+
@queue = []
|
|
14
|
+
@stopped = true
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Schedule a file to be diagnosed.
|
|
18
|
+
#
|
|
19
|
+
# @param uri [String]
|
|
20
|
+
# @return [void]
|
|
21
|
+
def schedule uri
|
|
22
|
+
mutex.synchronize { queue.push uri }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Stop the diagnosis thread.
|
|
26
|
+
#
|
|
27
|
+
# @return [void]
|
|
28
|
+
def stop
|
|
29
|
+
@stopped = true
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# True is the diagnoser is stopped.
|
|
33
|
+
#
|
|
34
|
+
# @return [Boolean]
|
|
35
|
+
def stopped?
|
|
36
|
+
@stopped
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Start the diagnosis thread.
|
|
40
|
+
#
|
|
41
|
+
# @return [self, nil]
|
|
42
|
+
def start
|
|
43
|
+
return unless @stopped
|
|
44
|
+
@stopped = false
|
|
45
|
+
Thread.new do
|
|
46
|
+
until stopped?
|
|
47
|
+
tick
|
|
48
|
+
sleep 0.1
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
self
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Perform diagnoses.
|
|
55
|
+
#
|
|
56
|
+
# @return [void]
|
|
57
|
+
def tick
|
|
58
|
+
return if queue.empty? || host.synchronizing?
|
|
59
|
+
if !host.options['diagnostics']
|
|
60
|
+
mutex.synchronize { queue.clear }
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
current = mutex.synchronize { queue.shift }
|
|
64
|
+
return if queue.include?(current)
|
|
65
|
+
begin
|
|
66
|
+
host.diagnose current
|
|
67
|
+
rescue InvalidOffsetError
|
|
68
|
+
# @todo This error can occur when the Source is out of sync with
|
|
69
|
+
# with the ApiMap. It's probably not the best way to handle it,
|
|
70
|
+
# but it's quick and easy.
|
|
71
|
+
Logging.logger.warn "Deferring diagnosis due to invalid offset: #{current}"
|
|
72
|
+
mutex.synchronize { queue.push current }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
# @return [Host]
|
|
79
|
+
attr_reader :host
|
|
80
|
+
|
|
81
|
+
# @return [Mutex]
|
|
82
|
+
attr_reader :mutex
|
|
83
|
+
|
|
84
|
+
# @return [::Array]
|
|
85
|
+
attr_reader :queue
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -33,6 +33,7 @@ module Solargraph
|
|
|
33
33
|
# @return [void]
|
|
34
34
|
def update_libraries uri
|
|
35
35
|
src = sources.find(uri)
|
|
36
|
+
# @sg-ignore Need to add nil check here
|
|
36
37
|
using = libraries.select { |lib| lib.contain?(src.filename) }
|
|
37
38
|
using.push library_for(uri) if using.empty?
|
|
38
39
|
using.each { |lib| lib.merge src }
|
|
@@ -28,7 +28,7 @@ module Solargraph
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
# pending handle messages
|
|
31
|
-
# @return [Array<Hash>]
|
|
31
|
+
# @return [Array<Hash{String => undefined}>]
|
|
32
32
|
def messages
|
|
33
33
|
@messages ||= []
|
|
34
34
|
end
|
|
@@ -66,6 +66,7 @@ module Solargraph
|
|
|
66
66
|
@resource.wait(@mutex) if messages.empty?
|
|
67
67
|
next_message
|
|
68
68
|
end
|
|
69
|
+
# @sg-ignore Need to add nil check here
|
|
69
70
|
handler = @host.receive(message)
|
|
70
71
|
handler&.send_response
|
|
71
72
|
end
|
|
@@ -55,6 +55,7 @@ module Solargraph
|
|
|
55
55
|
# @raise [FileNotFoundError] if the URI does not match an open source.
|
|
56
56
|
#
|
|
57
57
|
# @param uri [String]
|
|
58
|
+
# @sg-ignore flow ensitive typing should understand raise
|
|
58
59
|
# @return [Solargraph::Source]
|
|
59
60
|
def find uri
|
|
60
61
|
open_source_hash[uri] || raise(Solargraph::FileNotFoundError, "Host could not find #{uri}")
|
|
@@ -105,6 +105,7 @@ module Solargraph
|
|
|
105
105
|
message.process unless cancel?(request['id'])
|
|
106
106
|
rescue StandardError => e
|
|
107
107
|
logger.warn "Error processing request: [#{e.class}] #{e.message}"
|
|
108
|
+
# @sg-ignore Need to add nil check here
|
|
108
109
|
logger.warn e.backtrace.join("\n")
|
|
109
110
|
message.set_error Solargraph::LanguageServer::ErrorCodes::INTERNAL_ERROR, "[#{e.class}] #{e.message}"
|
|
110
111
|
end
|
|
@@ -300,8 +301,11 @@ module Solargraph
|
|
|
300
301
|
end
|
|
301
302
|
end
|
|
302
303
|
|
|
304
|
+
# @sg-ignore Need to validate config
|
|
303
305
|
# @return [String]
|
|
306
|
+
# @sg-ignore Need to validate config
|
|
304
307
|
def command_path
|
|
308
|
+
# @type [String]
|
|
305
309
|
options['commandPath'] || 'solargraph'
|
|
306
310
|
end
|
|
307
311
|
|
|
@@ -729,9 +733,11 @@ module Solargraph
|
|
|
729
733
|
end
|
|
730
734
|
|
|
731
735
|
# @param path [String]
|
|
736
|
+
# @sg-ignore Need to be able to choose signature on String#gsub
|
|
732
737
|
# @return [String]
|
|
733
738
|
def normalize_separators path
|
|
734
739
|
return path if File::ALT_SEPARATOR.nil?
|
|
740
|
+
# @sg-ignore flow sensitive typing needs to handle constants
|
|
735
741
|
path.gsub(File::ALT_SEPARATOR, File::SEPARATOR)
|
|
736
742
|
end
|
|
737
743
|
|
|
@@ -765,7 +771,6 @@ module Solargraph
|
|
|
765
771
|
return change if source.code.length + 1 != change['text'].length
|
|
766
772
|
diffs = Diff::LCS.diff(source.code, change['text'])
|
|
767
773
|
return change if diffs.length.zero? || diffs.length > 1 || diffs.first.length > 1
|
|
768
|
-
# @sg-ignore push this upstream
|
|
769
774
|
# @type [Diff::LCS::Change]
|
|
770
775
|
diff = diffs.first.first
|
|
771
776
|
return change unless diff.adding? && ['.', ':', '(', ',', ' '].include?(diff.element)
|
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
# @todo PR the RBS gem to add this
|
|
5
|
-
# @!parse
|
|
6
|
-
# module ::Gem
|
|
7
|
-
# class SpecFetcher; end
|
|
8
|
-
# end
|
|
9
|
-
|
|
10
4
|
module Solargraph
|
|
11
5
|
module LanguageServer
|
|
12
6
|
module Message
|
|
@@ -64,6 +58,7 @@ module Solargraph
|
|
|
64
58
|
end
|
|
65
59
|
elsif fetched?
|
|
66
60
|
Solargraph::Logging.logger.warn error
|
|
61
|
+
# @sg-ignore Need to add nil check here
|
|
67
62
|
host.show_message(error, MessageTypes::ERROR) if params['verbose']
|
|
68
63
|
end
|
|
69
64
|
set_result({
|
|
@@ -78,12 +73,12 @@ module Solargraph
|
|
|
78
73
|
attr_reader :current
|
|
79
74
|
|
|
80
75
|
# @return [Gem::Version]
|
|
76
|
+
# @sg-ignore Need to add nil check here
|
|
81
77
|
def available
|
|
82
78
|
if !@available && !@fetched
|
|
83
79
|
@fetched = true
|
|
84
80
|
begin
|
|
85
81
|
@available ||= begin
|
|
86
|
-
# @sg-ignore Variable type could not be inferred for tuple
|
|
87
82
|
# @type [Gem::Dependency, nil]
|
|
88
83
|
tuple = CheckGemVersion.fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
|
|
89
84
|
if tuple.nil?
|
|
@@ -15,6 +15,7 @@ module Solargraph
|
|
|
15
15
|
items = []
|
|
16
16
|
last_context = nil
|
|
17
17
|
idx = -1
|
|
18
|
+
# @sg-ignore Need to add nil check here
|
|
18
19
|
completion.pins.each do |pin|
|
|
19
20
|
idx += 1 if last_context != pin.context
|
|
20
21
|
items.push pin.completion_item.merge({
|
|
@@ -37,6 +38,7 @@ module Solargraph
|
|
|
37
38
|
end
|
|
38
39
|
rescue FileNotFoundError => e
|
|
39
40
|
Logging.logger.warn "[#{e.class}] #{e.message}"
|
|
41
|
+
# @sg-ignore Need to add nil check here
|
|
40
42
|
Logging.logger.warn e.backtrace.join("\n")
|
|
41
43
|
set_result empty_result
|
|
42
44
|
end
|
|
@@ -13,7 +13,9 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
|
13
13
|
# @return [Array<Hash>, nil]
|
|
14
14
|
def code_location
|
|
15
15
|
suggestions = host.definitions_at(params['textDocument']['uri'], @line, @column)
|
|
16
|
+
# @sg-ignore Need to add nil check here
|
|
16
17
|
return nil if suggestions.empty?
|
|
18
|
+
# @sg-ignore Need to add nil check here
|
|
17
19
|
suggestions.reject { |pin| pin.best_location.nil? || pin.best_location.filename.nil? }.map do |pin|
|
|
18
20
|
{
|
|
19
21
|
uri: file_to_uri(pin.best_location.filename),
|
|
@@ -13,7 +13,9 @@ class Solargraph::LanguageServer::Message::TextDocument::DocumentSymbol < Solarg
|
|
|
13
13
|
containerName: pin.namespace,
|
|
14
14
|
kind: pin.symbol_kind,
|
|
15
15
|
location: {
|
|
16
|
+
# @sg-ignore Need to add nil check here
|
|
16
17
|
uri: file_to_uri(pin.best_location.filename),
|
|
18
|
+
# @sg-ignore Need to add nil check here
|
|
17
19
|
range: pin.best_location.range.to_hash
|
|
18
20
|
},
|
|
19
21
|
deprecated: pin.deprecated?
|
|
@@ -98,9 +98,11 @@ module Solargraph
|
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
# @param value [Array, String]
|
|
101
|
+
#
|
|
101
102
|
# @return [String, nil]
|
|
102
103
|
def cop_list(value)
|
|
103
104
|
# @type [String]
|
|
105
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
104
106
|
value = value.join(',') if value.respond_to?(:join)
|
|
105
107
|
return nil if value == '' || !value.is_a?(String)
|
|
106
108
|
value
|
|
@@ -11,6 +11,7 @@ module Solargraph
|
|
|
11
11
|
contents = []
|
|
12
12
|
suggestions = host.definitions_at(params['textDocument']['uri'], line, col)
|
|
13
13
|
last_link = nil
|
|
14
|
+
# @sg-ignore Need to add nil check here
|
|
14
15
|
suggestions.each do |pin|
|
|
15
16
|
parts = []
|
|
16
17
|
this_link = host.options['enablePages'] ? pin.link_documentation : pin.text_documentation
|
|
@@ -31,6 +32,7 @@ module Solargraph
|
|
|
31
32
|
)
|
|
32
33
|
rescue FileNotFoundError => e
|
|
33
34
|
Logging.logger.warn "[#{e.class}] #{e.message}"
|
|
35
|
+
# @sg-ignore Need to add nil check here
|
|
34
36
|
Logging.logger.warn e.backtrace.join("\n")
|
|
35
37
|
set_result nil
|
|
36
38
|
end
|
|
@@ -13,7 +13,9 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
|
13
13
|
# @return [Array<Hash>, nil]
|
|
14
14
|
def code_location
|
|
15
15
|
suggestions = host.type_definitions_at(params['textDocument']['uri'], @line, @column)
|
|
16
|
+
# @sg-ignore Need to add nil check here
|
|
16
17
|
return nil if suggestions.empty?
|
|
18
|
+
# @sg-ignore Need to add nil check here
|
|
17
19
|
suggestions.reject { |pin| pin.best_location.nil? || pin.best_location.filename.nil? }.map do |pin|
|
|
18
20
|
{
|
|
19
21
|
uri: file_to_uri(pin.best_location.filename),
|
|
@@ -6,6 +6,7 @@ class Solargraph::LanguageServer::Message::Workspace::WorkspaceSymbol < Solargra
|
|
|
6
6
|
def process
|
|
7
7
|
pins = host.query_symbols(params['query'])
|
|
8
8
|
info = pins.map do |pin|
|
|
9
|
+
# @sg-ignore Need to add nil check here
|
|
9
10
|
uri = file_to_uri(pin.best_location.filename)
|
|
10
11
|
{
|
|
11
12
|
name: pin.path,
|
|
@@ -13,6 +14,7 @@ class Solargraph::LanguageServer::Message::Workspace::WorkspaceSymbol < Solargra
|
|
|
13
14
|
kind: pin.symbol_kind,
|
|
14
15
|
location: {
|
|
15
16
|
uri: uri,
|
|
17
|
+
# @sg-ignore Need to add nil check here
|
|
16
18
|
range: pin.best_location.range.to_hash
|
|
17
19
|
},
|
|
18
20
|
deprecated: pin.deprecated?
|
data/lib/solargraph/library.rb
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'rubygems'
|
|
3
4
|
require 'pathname'
|
|
4
5
|
require 'observer'
|
|
5
6
|
require 'open3'
|
|
6
7
|
|
|
8
|
+
# @!parse
|
|
9
|
+
# class ::Gem::Specification
|
|
10
|
+
# # @return [String]
|
|
11
|
+
# def name; end
|
|
12
|
+
# end
|
|
13
|
+
|
|
7
14
|
module Solargraph
|
|
8
15
|
# A Library handles coordination between a Workspace and an ApiMap.
|
|
9
16
|
#
|
|
@@ -33,6 +40,7 @@ module Solargraph
|
|
|
33
40
|
# @type [Source, nil]
|
|
34
41
|
@current = nil
|
|
35
42
|
@sync_count = 0
|
|
43
|
+
@cache_progress = nil
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
def inspect
|
|
@@ -57,8 +65,11 @@ module Solargraph
|
|
|
57
65
|
# @param source [Source, nil]
|
|
58
66
|
# @return [void]
|
|
59
67
|
def attach source
|
|
68
|
+
# @sg-ignore Need to add nil check here
|
|
60
69
|
if @current && (!source || @current.filename != source.filename) && source_map_hash.key?(@current.filename) && !workspace.has_file?(@current.filename)
|
|
70
|
+
# @sg-ignore Need to add nil check here
|
|
61
71
|
source_map_hash.delete @current.filename
|
|
72
|
+
# @sg-ignore Need to add nil check here
|
|
62
73
|
source_map_external_require_hash.delete @current.filename
|
|
63
74
|
@external_requires = nil
|
|
64
75
|
end
|
|
@@ -182,9 +193,14 @@ module Solargraph
|
|
|
182
193
|
if cursor.comment?
|
|
183
194
|
source = read(filename)
|
|
184
195
|
offset = Solargraph::Position.to_offset(source.code, Solargraph::Position.new(line, column))
|
|
196
|
+
# @sg-ignore Need to add nil check here
|
|
197
|
+
# @type [MatchData, nil]
|
|
185
198
|
lft = source.code[0..offset-1].match(/\[[a-z0-9_:<, ]*?([a-z0-9_:]*)\z/i)
|
|
199
|
+
# @sg-ignore Need to add nil check here
|
|
200
|
+
# @type [MatchData, nil]
|
|
186
201
|
rgt = source.code[offset..-1].match(/^([a-z0-9_]*)(:[a-z0-9_:]*)?[\]>, ]/i)
|
|
187
202
|
if lft && rgt
|
|
203
|
+
# @sg-ignore Need to add nil check here
|
|
188
204
|
tag = (lft[1] + rgt[1]).sub(/:+$/, '')
|
|
189
205
|
clip = mutex.synchronize { api_map.clip(cursor) }
|
|
190
206
|
clip.translate tag
|
|
@@ -255,15 +271,19 @@ module Solargraph
|
|
|
255
271
|
files.uniq(&:filename).each do |source|
|
|
256
272
|
found = source.references(pin.name)
|
|
257
273
|
found.select! do |loc|
|
|
274
|
+
# @sg-ignore Need to add nil check here
|
|
275
|
+
# @type [Solargraph::Pin::Base, nil]
|
|
258
276
|
referenced = definitions_at(loc.filename, loc.range.ending.line, loc.range.ending.character).first
|
|
259
277
|
referenced&.path == pin.path
|
|
260
278
|
end
|
|
261
279
|
if pin.path == 'Class#new'
|
|
280
|
+
# @todo flow sensitive typing should allow shadowing of Kernel#caller
|
|
262
281
|
caller = cursor.chain.base.infer(api_map, clip.send(:closure), clip.locals).first
|
|
263
282
|
if caller.defined?
|
|
264
283
|
found.select! do |loc|
|
|
265
284
|
clip = api_map.clip_at(loc.filename, loc.range.start)
|
|
266
285
|
other = clip.send(:cursor).chain.base.infer(api_map, clip.send(:closure), clip.locals).first
|
|
286
|
+
# @todo flow sensitive typing should allow shadowing of Kernel#caller
|
|
267
287
|
caller == other
|
|
268
288
|
end
|
|
269
289
|
else
|
|
@@ -273,12 +293,13 @@ module Solargraph
|
|
|
273
293
|
# HACK: for language clients that exclude special characters from the start of variable names
|
|
274
294
|
if strip && match = cursor.word.match(/^[^a-z0-9_]+/i)
|
|
275
295
|
found.map! do |loc|
|
|
276
|
-
Solargraph::Location.new(loc.filename,
|
|
296
|
+
Solargraph::Location.new(loc.filename,
|
|
297
|
+
# @sg-ignore flow sensitive typing needs to handle if foo = bar
|
|
298
|
+
Solargraph::Range.from_to(loc.range.start.line, loc.range.start.column + match[0].length, loc.range.ending.line,
|
|
299
|
+
loc.range.ending.column))
|
|
277
300
|
end
|
|
278
301
|
end
|
|
279
|
-
result.concat(found.sort
|
|
280
|
-
a.range.start.line <=> b.range.start.line
|
|
281
|
-
end)
|
|
302
|
+
result.concat(found.sort { |a, b| a.range.start.line <=> b.range.start.line })
|
|
282
303
|
end
|
|
283
304
|
result.uniq
|
|
284
305
|
end
|
|
@@ -299,13 +320,12 @@ module Solargraph
|
|
|
299
320
|
def locate_ref location
|
|
300
321
|
map = source_map_hash[location.filename]
|
|
301
322
|
return if map.nil?
|
|
323
|
+
# @sg-ignore Need to add nil check here
|
|
302
324
|
pin = map.requires.select { |p| p.location.range.contain?(location.range.start) }.first
|
|
303
325
|
return nil if pin.nil?
|
|
304
326
|
# @param full [String]
|
|
305
327
|
return_if_match = proc do |full|
|
|
306
|
-
if source_map_hash.key?(full)
|
|
307
|
-
return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0))
|
|
308
|
-
end
|
|
328
|
+
return Location.new(full, Solargraph::Range.from_to(0, 0, 0, 0)) if source_map_hash.key?(full)
|
|
309
329
|
end
|
|
310
330
|
workspace.require_paths.each do |path|
|
|
311
331
|
full = File.join path, pin.name
|
|
@@ -403,6 +423,7 @@ module Solargraph
|
|
|
403
423
|
workspace.config.reporters.each do |line|
|
|
404
424
|
if line == 'all!'
|
|
405
425
|
Diagnostics.reporters.each do |reporter_name|
|
|
426
|
+
# @sg-ignore Need to add nil check here
|
|
406
427
|
repargs[Diagnostics.reporter(reporter_name)] ||= []
|
|
407
428
|
end
|
|
408
429
|
else
|
|
@@ -410,7 +431,9 @@ module Solargraph
|
|
|
410
431
|
name = args.shift
|
|
411
432
|
reporter = Diagnostics.reporter(name)
|
|
412
433
|
raise DiagnosticsError, "Diagnostics reporter #{name} does not exist" if reporter.nil?
|
|
434
|
+
# @sg-ignore flow sensitive typing needs to handle 'raise if'
|
|
413
435
|
repargs[reporter] ||= []
|
|
436
|
+
# @sg-ignore flow sensitive typing needs to handle 'raise if'
|
|
414
437
|
repargs[reporter].concat args
|
|
415
438
|
end
|
|
416
439
|
end
|
|
@@ -433,6 +456,7 @@ module Solargraph
|
|
|
433
456
|
source_maps: source_map_hash.values,
|
|
434
457
|
workspace: workspace,
|
|
435
458
|
external_requires: external_requires,
|
|
459
|
+
# @sg-ignore Need to add nil check here
|
|
436
460
|
live_map: @current ? source_map_hash[@current.filename] : nil
|
|
437
461
|
)
|
|
438
462
|
end
|
|
@@ -469,10 +493,13 @@ module Solargraph
|
|
|
469
493
|
# @return [SourceMap, Boolean]
|
|
470
494
|
def next_map
|
|
471
495
|
return false if mapped?
|
|
496
|
+
# @sg-ignore Need to add nil check here
|
|
472
497
|
src = workspace.sources.find { |s| !source_map_hash.key?(s.filename) }
|
|
473
498
|
if src
|
|
474
499
|
Logging.logger.debug "Mapping #{src.filename}"
|
|
500
|
+
# @sg-ignore Need to add nil check here
|
|
475
501
|
source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
|
|
502
|
+
# @sg-ignore Need to add nil check here
|
|
476
503
|
source_map_hash[src.filename]
|
|
477
504
|
else
|
|
478
505
|
false
|
|
@@ -482,7 +509,9 @@ module Solargraph
|
|
|
482
509
|
# @return [self]
|
|
483
510
|
def map!
|
|
484
511
|
workspace.sources.each do |src|
|
|
512
|
+
# @sg-ignore Need to add nil check here
|
|
485
513
|
source_map_hash[src.filename] = Solargraph::SourceMap.map(src)
|
|
514
|
+
# @sg-ignore Need to add nil check here
|
|
486
515
|
find_external_requires source_map_hash[src.filename]
|
|
487
516
|
end
|
|
488
517
|
self
|
|
@@ -500,6 +529,11 @@ module Solargraph
|
|
|
500
529
|
|
|
501
530
|
private
|
|
502
531
|
|
|
532
|
+
# @return [PinCache]
|
|
533
|
+
def pin_cache
|
|
534
|
+
workspace.pin_cache
|
|
535
|
+
end
|
|
536
|
+
|
|
503
537
|
# @return [Hash{String => Array<String>}]
|
|
504
538
|
def source_map_external_require_hash
|
|
505
539
|
@source_map_external_require_hash ||= {}
|
|
@@ -513,6 +547,7 @@ module Solargraph
|
|
|
513
547
|
# return if new_set == source_map_external_require_hash[source_map.filename]
|
|
514
548
|
_filenames = nil
|
|
515
549
|
filenames = ->{ _filenames ||= workspace.filenames.to_set }
|
|
550
|
+
# @sg-ignore Need to add nil check here
|
|
516
551
|
source_map_external_require_hash[source_map.filename] = new_set.reject do |path|
|
|
517
552
|
workspace.require_paths.any? do |base|
|
|
518
553
|
full = File.join(base, path)
|
|
@@ -562,11 +597,15 @@ module Solargraph
|
|
|
562
597
|
# @return [void]
|
|
563
598
|
def maybe_map source
|
|
564
599
|
return unless source
|
|
600
|
+
# @sg-ignore Need to add nil check here
|
|
565
601
|
return unless @current == source || workspace.has_file?(source.filename)
|
|
602
|
+
# @sg-ignore Need to add nil check here
|
|
566
603
|
if source_map_hash.key?(source.filename)
|
|
567
604
|
new_map = Solargraph::SourceMap.map(source)
|
|
605
|
+
# @sg-ignore Need to add nil check here
|
|
568
606
|
source_map_hash[source.filename] = new_map
|
|
569
607
|
else
|
|
608
|
+
# @sg-ignore Need to add nil check here
|
|
570
609
|
source_map_hash[source.filename] = Solargraph::SourceMap.map(source)
|
|
571
610
|
end
|
|
572
611
|
end
|
|
@@ -585,7 +624,7 @@ module Solargraph
|
|
|
585
624
|
|
|
586
625
|
pending = api_map.uncached_gemspecs.length - cache_errors.length - 1
|
|
587
626
|
|
|
588
|
-
if
|
|
627
|
+
if pin_cache.yardoc_processing?(spec)
|
|
589
628
|
logger.info "Enqueuing cache of #{spec.name} #{spec.version} (already being processed)"
|
|
590
629
|
queued_gemspec_cache.push(spec)
|
|
591
630
|
return if pending - queued_gemspec_cache.length < 1
|
|
@@ -596,7 +635,10 @@ module Solargraph
|
|
|
596
635
|
logger.info "Caching #{spec.name} #{spec.version}"
|
|
597
636
|
Thread.new do
|
|
598
637
|
report_cache_progress spec.name, pending
|
|
599
|
-
|
|
638
|
+
kwargs = {}
|
|
639
|
+
kwargs[:chdir] = workspace.directory.to_s if workspace.directory && !workspace.directory.empty?
|
|
640
|
+
_o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s,
|
|
641
|
+
**kwargs)
|
|
600
642
|
if s.success?
|
|
601
643
|
logger.info "Cached #{spec.name} #{spec.version}"
|
|
602
644
|
else
|
|
@@ -613,8 +655,7 @@ module Solargraph
|
|
|
613
655
|
|
|
614
656
|
# @return [Array<Gem::Specification>]
|
|
615
657
|
def cacheable_specs
|
|
616
|
-
cacheable = api_map.
|
|
617
|
-
api_map.uncached_rbs_collection_gemspecs -
|
|
658
|
+
cacheable = api_map.uncached_gemspecs +
|
|
618
659
|
queued_gemspec_cache -
|
|
619
660
|
cache_errors.to_a
|
|
620
661
|
return cacheable unless cacheable.empty?
|
|
@@ -632,11 +673,15 @@ module Solargraph
|
|
|
632
673
|
# @return [void]
|
|
633
674
|
def report_cache_progress gem_name, pending
|
|
634
675
|
@total ||= pending
|
|
676
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
635
677
|
@total = pending if pending > @total
|
|
678
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
636
679
|
finished = @total - pending
|
|
680
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
637
681
|
pct = if @total.zero?
|
|
638
682
|
0
|
|
639
683
|
else
|
|
684
|
+
# @sg-ignore flow sensitive typing needs better handling of ||= on lvars
|
|
640
685
|
((finished.to_f / @total.to_f) * 100).to_i
|
|
641
686
|
end
|
|
642
687
|
message = "#{gem_name}#{pending > 0 ? " (+#{pending})" : ''}"
|
|
@@ -647,9 +692,11 @@ module Solargraph
|
|
|
647
692
|
@cache_progress = LanguageServer::Progress.new('Caching gem')
|
|
648
693
|
# If we don't send both a begin and a report, the progress notification
|
|
649
694
|
# might get stuck in the status bar forever
|
|
695
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
650
696
|
@cache_progress.begin(message, pct)
|
|
651
697
|
changed
|
|
652
698
|
notify_observers @cache_progress
|
|
699
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
653
700
|
@cache_progress.report(message, pct)
|
|
654
701
|
end
|
|
655
702
|
changed
|
|
@@ -673,8 +720,7 @@ module Solargraph
|
|
|
673
720
|
source_map_hash.values.each { |map| find_external_requires(map) }
|
|
674
721
|
api_map.catalog bench
|
|
675
722
|
logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)"
|
|
676
|
-
logger.info "#{api_map.
|
|
677
|
-
logger.info "#{api_map.uncached_rbs_collection_gemspecs.length} uncached RBS collection gemspecs"
|
|
723
|
+
logger.info "#{api_map.uncached_gemspecs.length} uncached gemspecs"
|
|
678
724
|
cache_next_gemspec
|
|
679
725
|
@sync_count = 0
|
|
680
726
|
end
|