solargraph 0.56.0 → 0.58.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/.gitattributes +2 -0
- data/.github/workflows/linting.yml +127 -0
- data/.github/workflows/plugins.yml +183 -7
- data/.github/workflows/rspec.yml +55 -5
- data/.github/workflows/typecheck.yml +6 -3
- data/.gitignore +5 -0
- data/.overcommit.yml +72 -0
- data/.rspec +1 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +1279 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +86 -1
- data/README.md +8 -4
- data/Rakefile +125 -13
- data/bin/solargraph +3 -0
- data/lib/solargraph/api_map/cache.rb +3 -2
- data/lib/solargraph/api_map/constants.rb +279 -0
- data/lib/solargraph/api_map/index.rb +49 -31
- data/lib/solargraph/api_map/source_to_yard.rb +13 -4
- data/lib/solargraph/api_map/store.rb +144 -26
- data/lib/solargraph/api_map.rb +217 -245
- data/lib/solargraph/bench.rb +1 -0
- data/lib/solargraph/complex_type/type_methods.rb +6 -0
- data/lib/solargraph/complex_type/unique_type.rb +19 -12
- data/lib/solargraph/complex_type.rb +24 -3
- data/lib/solargraph/convention/active_support_concern.rb +111 -0
- data/lib/solargraph/convention/base.rb +17 -0
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
- data/lib/solargraph/convention/data_definition.rb +105 -0
- data/lib/solargraph/convention/gemspec.rb +3 -2
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -2
- data/lib/solargraph/convention/struct_definition.rb +87 -24
- data/lib/solargraph/convention.rb +32 -2
- data/lib/solargraph/diagnostics/rubocop.rb +6 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/doc_map.rb +52 -18
- data/lib/solargraph/environ.rb +9 -2
- data/lib/solargraph/equality.rb +1 -0
- data/lib/solargraph/gem_pins.rb +21 -11
- data/lib/solargraph/language_server/host/dispatch.rb +2 -0
- data/lib/solargraph/language_server/host/message_worker.rb +3 -0
- data/lib/solargraph/language_server/host.rb +12 -5
- data/lib/solargraph/language_server/message/base.rb +2 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/definition.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/formatting.rb +19 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -0
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
- data/lib/solargraph/language_server/progress.rb +8 -0
- data/lib/solargraph/language_server/request.rb +4 -1
- data/lib/solargraph/library.rb +50 -33
- data/lib/solargraph/location.rb +3 -0
- data/lib/solargraph/logging.rb +11 -2
- data/lib/solargraph/page.rb +3 -0
- data/lib/solargraph/parser/comment_ripper.rb +8 -1
- data/lib/solargraph/parser/flow_sensitive_typing.rb +33 -5
- data/lib/solargraph/parser/node_processor/base.rb +10 -5
- data/lib/solargraph/parser/node_processor.rb +24 -8
- data/lib/solargraph/parser/parser_gem/class_methods.rb +3 -13
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -16
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +2 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +7 -1
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +0 -22
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +65 -8
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +12 -3
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +36 -16
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/region.rb +3 -0
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/pin/base.rb +92 -14
- data/lib/solargraph/pin/base_variable.rb +6 -5
- data/lib/solargraph/pin/block.rb +3 -2
- data/lib/solargraph/pin/callable.rb +14 -1
- data/lib/solargraph/pin/closure.rb +5 -7
- data/lib/solargraph/pin/common.rb +6 -2
- data/lib/solargraph/pin/constant.rb +2 -0
- data/lib/solargraph/pin/local_variable.rb +1 -2
- data/lib/solargraph/pin/method.rb +32 -11
- data/lib/solargraph/pin/method_alias.rb +3 -0
- data/lib/solargraph/pin/parameter.rb +24 -10
- data/lib/solargraph/pin/proxy_type.rb +5 -1
- data/lib/solargraph/pin/reference/override.rb +15 -1
- data/lib/solargraph/pin/reference/superclass.rb +5 -0
- data/lib/solargraph/pin/reference.rb +17 -0
- data/lib/solargraph/pin/search.rb +6 -1
- data/lib/solargraph/pin/signature.rb +2 -0
- data/lib/solargraph/pin/symbol.rb +5 -0
- data/lib/solargraph/pin_cache.rb +64 -4
- data/lib/solargraph/position.rb +3 -0
- data/lib/solargraph/range.rb +5 -0
- data/lib/solargraph/rbs_map/conversions.rb +68 -18
- data/lib/solargraph/rbs_map/core_fills.rb +18 -0
- data/lib/solargraph/rbs_map/core_map.rb +14 -7
- data/lib/solargraph/rbs_map.rb +14 -1
- data/lib/solargraph/shell.rb +85 -1
- data/lib/solargraph/source/chain/call.rb +7 -3
- data/lib/solargraph/source/chain/constant.rb +3 -66
- data/lib/solargraph/source/chain/if.rb +1 -1
- data/lib/solargraph/source/chain/link.rb +11 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +11 -2
- data/lib/solargraph/source/change.rb +2 -2
- data/lib/solargraph/source/cursor.rb +2 -3
- data/lib/solargraph/source/encoding_fixes.rb +23 -23
- data/lib/solargraph/source/source_chainer.rb +1 -1
- data/lib/solargraph/source.rb +6 -3
- data/lib/solargraph/source_map/clip.rb +18 -26
- data/lib/solargraph/source_map/data.rb +4 -0
- data/lib/solargraph/source_map/mapper.rb +2 -2
- data/lib/solargraph/source_map.rb +28 -16
- data/lib/solargraph/type_checker/param_def.rb +2 -0
- data/lib/solargraph/type_checker/rules.rb +30 -8
- data/lib/solargraph/type_checker.rb +301 -186
- data/lib/solargraph/version.rb +5 -5
- data/lib/solargraph/workspace/config.rb +22 -6
- data/lib/solargraph/workspace/require_paths.rb +97 -0
- data/lib/solargraph/workspace.rb +38 -67
- data/lib/solargraph/yard_map/helpers.rb +29 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -5
- data/lib/solargraph/yard_map/mapper/to_method.rb +5 -9
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +8 -7
- data/lib/solargraph/yard_map/to_method.rb +2 -1
- data/lib/solargraph/yardoc.rb +41 -3
- data/lib/solargraph.rb +15 -0
- data/rbs/fills/bundler/0/bundler.rbs +4271 -0
- data/rbs/fills/open3/0/open3.rbs +172 -0
- data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
- data/rbs/fills/rubygems/0/errors.rbs +364 -0
- data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
- data/rbs/fills/rubygems/0/specification.rbs +1753 -0
- data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +2 -3
- data/rbs_collection.yaml +4 -4
- data/sig/shims/ast/0/node.rbs +5 -0
- data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
- data/sig/shims/ast/2.4/ast.rbs +73 -0
- data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
- data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
- data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
- data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
- data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
- data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
- data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
- data/solargraph.gemspec +26 -5
- metadata +187 -15
- data/lib/.rubocop.yml +0 -22
- data/lib/solargraph/parser/node_methods.rb +0 -97
|
@@ -94,7 +94,8 @@ module Solargraph
|
|
|
94
94
|
# processed, caller is responsible for sending the response.
|
|
95
95
|
#
|
|
96
96
|
# @param request [Hash{String => unspecified}] The contents of the message.
|
|
97
|
-
#
|
|
97
|
+
#
|
|
98
|
+
# @return [Solargraph::LanguageServer::Message::Base, Solargraph::LanguageServer::Request, nil] The message handler.
|
|
98
99
|
def receive request
|
|
99
100
|
if request['method']
|
|
100
101
|
logger.info "Host received ##{request['id']} #{request['method']}"
|
|
@@ -299,6 +300,7 @@ module Solargraph
|
|
|
299
300
|
end
|
|
300
301
|
end
|
|
301
302
|
|
|
303
|
+
# @return [String]
|
|
302
304
|
def command_path
|
|
303
305
|
options['commandPath'] || 'solargraph'
|
|
304
306
|
end
|
|
@@ -502,6 +504,7 @@ module Solargraph
|
|
|
502
504
|
name: 'new',
|
|
503
505
|
scope: :class,
|
|
504
506
|
location: pin.location,
|
|
507
|
+
# @sg-ignore Unresolved call to parameters on Solargraph::Pin::Base
|
|
505
508
|
parameters: pin.parameters,
|
|
506
509
|
return_type: ComplexType.try_parse(params['data']['path']),
|
|
507
510
|
comments: pin.comments,
|
|
@@ -533,7 +536,7 @@ module Solargraph
|
|
|
533
536
|
# @param uri [String]
|
|
534
537
|
# @param line [Integer]
|
|
535
538
|
# @param column [Integer]
|
|
536
|
-
# @return [Solargraph::SourceMap::Completion]
|
|
539
|
+
# @return [Solargraph::SourceMap::Completion, nil]
|
|
537
540
|
def completions_at uri, line, column
|
|
538
541
|
library = library_for(uri)
|
|
539
542
|
library.completions_at uri_to_file(uri), line, column
|
|
@@ -547,7 +550,7 @@ module Solargraph
|
|
|
547
550
|
# @param uri [String]
|
|
548
551
|
# @param line [Integer]
|
|
549
552
|
# @param column [Integer]
|
|
550
|
-
# @return [Array<Solargraph::Pin::Base
|
|
553
|
+
# @return [Array<Solargraph::Pin::Base>, nil]
|
|
551
554
|
def definitions_at uri, line, column
|
|
552
555
|
library = library_for(uri)
|
|
553
556
|
library.definitions_at(uri_to_file(uri), line, column)
|
|
@@ -556,7 +559,7 @@ module Solargraph
|
|
|
556
559
|
# @param uri [String]
|
|
557
560
|
# @param line [Integer]
|
|
558
561
|
# @param column [Integer]
|
|
559
|
-
# @return [Array<Solargraph::Pin::Base
|
|
562
|
+
# @return [Array<Solargraph::Pin::Base>, nil]
|
|
560
563
|
def type_definitions_at uri, line, column
|
|
561
564
|
library = library_for(uri)
|
|
562
565
|
library.type_definitions_at(uri_to_file(uri), line, column)
|
|
@@ -580,6 +583,10 @@ module Solargraph
|
|
|
580
583
|
def references_from uri, line, column, strip: true, only: false
|
|
581
584
|
library = library_for(uri)
|
|
582
585
|
library.references_from(uri_to_file(uri), line, column, strip: strip, only: only)
|
|
586
|
+
rescue FileNotFoundError, InvalidOffsetError => e
|
|
587
|
+
Solargraph.logger.warn "[#{e.class}] #{e.message}"
|
|
588
|
+
Solargraph.logger.debug e.backtrace
|
|
589
|
+
[]
|
|
583
590
|
end
|
|
584
591
|
|
|
585
592
|
# @param query [String]
|
|
@@ -716,7 +723,7 @@ module Solargraph
|
|
|
716
723
|
# A hash of client requests by ID. The host uses this to keep track of
|
|
717
724
|
# pending responses.
|
|
718
725
|
#
|
|
719
|
-
# @return [Hash{Integer => Solargraph::LanguageServer::
|
|
726
|
+
# @return [Hash{Integer => Solargraph::LanguageServer::Request}]
|
|
720
727
|
def requests
|
|
721
728
|
@requests ||= {}
|
|
722
729
|
end
|
|
@@ -16,7 +16,7 @@ module Solargraph
|
|
|
16
16
|
# @return [String]
|
|
17
17
|
attr_reader :method
|
|
18
18
|
|
|
19
|
-
# @return [Hash{String =>
|
|
19
|
+
# @return [Hash{String => undefined}]
|
|
20
20
|
attr_reader :params
|
|
21
21
|
|
|
22
22
|
# @return [Hash, Array, nil]
|
|
@@ -79,6 +79,7 @@ module Solargraph
|
|
|
79
79
|
|
|
80
80
|
private
|
|
81
81
|
|
|
82
|
+
# @return [void]
|
|
82
83
|
def accept_or_cancel
|
|
83
84
|
if host.cancel?(id)
|
|
84
85
|
# https://microsoft.github.io/language-server-protocol/specifications/specification-current/#cancelRequest
|
|
@@ -83,7 +83,7 @@ module Solargraph
|
|
|
83
83
|
@fetched = true
|
|
84
84
|
begin
|
|
85
85
|
@available ||= begin
|
|
86
|
-
# @sg-ignore
|
|
86
|
+
# @sg-ignore Variable type could not be inferred for tuple
|
|
87
87
|
# @type [Gem::Dependency, nil]
|
|
88
88
|
tuple = CheckGemVersion.fetcher.search_for_dependency(Gem::Dependency.new('solargraph')).flatten.first
|
|
89
89
|
if tuple.nil?
|
|
@@ -10,6 +10,7 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
|
10
10
|
|
|
11
11
|
private
|
|
12
12
|
|
|
13
|
+
# @return [Array<Hash>, nil]
|
|
13
14
|
def code_location
|
|
14
15
|
suggestions = host.definitions_at(params['textDocument']['uri'], @line, @column)
|
|
15
16
|
return nil if suggestions.empty?
|
|
@@ -21,6 +22,7 @@ module Solargraph::LanguageServer::Message::TextDocument
|
|
|
21
22
|
end
|
|
22
23
|
end
|
|
23
24
|
|
|
25
|
+
# @return [Array<Hash>, nil]
|
|
24
26
|
def require_location
|
|
25
27
|
# @todo Terrible hack
|
|
26
28
|
lib = host.library_for(params['textDocument']['uri'])
|
|
@@ -18,10 +18,18 @@ module Solargraph
|
|
|
18
18
|
|
|
19
19
|
require_rubocop(config['version'])
|
|
20
20
|
options, paths = ::RuboCop::Options.new.parse(args)
|
|
21
|
+
# @sg-ignore Unresolved call to []=
|
|
21
22
|
options[:stdin] = original
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
|
|
24
|
+
# Ensure only one instance of RuboCop::Runner is running at
|
|
25
|
+
# a time - it uses 'chdir' to read config files with ERB,
|
|
26
|
+
# which can conflict with other chdirs.
|
|
27
|
+
corrections = Solargraph::CHDIR_MUTEX.synchronize do
|
|
28
|
+
redirect_stdout do
|
|
29
|
+
::RuboCop::Runner.new(options, ::RuboCop::ConfigStore.new).run(paths)
|
|
30
|
+
end
|
|
24
31
|
end
|
|
32
|
+
# @sg-ignore Unresolved call to []=
|
|
25
33
|
result = options[:stdin]
|
|
26
34
|
|
|
27
35
|
log_corrections(corrections)
|
|
@@ -34,6 +42,7 @@ module Solargraph
|
|
|
34
42
|
private
|
|
35
43
|
|
|
36
44
|
# @param corrections [String]
|
|
45
|
+
# @return [void]
|
|
37
46
|
def log_corrections(corrections)
|
|
38
47
|
corrections = corrections&.strip
|
|
39
48
|
return if corrections&.empty?
|
|
@@ -45,6 +54,8 @@ module Solargraph
|
|
|
45
54
|
end
|
|
46
55
|
end
|
|
47
56
|
|
|
57
|
+
# @param file_uri [String]
|
|
58
|
+
# @return [Hash{String => undefined}]
|
|
48
59
|
def config_for(file_uri)
|
|
49
60
|
conf = host.formatter_config(file_uri)
|
|
50
61
|
return {} unless conf.is_a?(Hash)
|
|
@@ -52,7 +63,9 @@ module Solargraph
|
|
|
52
63
|
conf['rubocop'] || {}
|
|
53
64
|
end
|
|
54
65
|
|
|
66
|
+
# @param file_uri [String]
|
|
55
67
|
# @param config [Hash{String => String}]
|
|
68
|
+
# @return [Array<String>]
|
|
56
69
|
def cli_args file_uri, config
|
|
57
70
|
file = UriHelpers.uri_to_file(file_uri)
|
|
58
71
|
args = [
|
|
@@ -71,6 +84,8 @@ module Solargraph
|
|
|
71
84
|
end
|
|
72
85
|
|
|
73
86
|
# @param config [Hash{String => String}]
|
|
87
|
+
# @sg-ignore
|
|
88
|
+
# @return [Class<RuboCop::Formatter::BaseFormatter>]
|
|
74
89
|
def formatter_class(config)
|
|
75
90
|
if self.class.const_defined?('BlankRubocopFormatter')
|
|
76
91
|
# @sg-ignore
|
|
@@ -83,7 +98,9 @@ module Solargraph
|
|
|
83
98
|
end
|
|
84
99
|
|
|
85
100
|
# @param value [Array, String]
|
|
101
|
+
# @return [String, nil]
|
|
86
102
|
def cop_list(value)
|
|
103
|
+
# @type [String]
|
|
87
104
|
value = value.join(',') if value.respond_to?(:join)
|
|
88
105
|
return nil if value == '' || !value.is_a?(String)
|
|
89
106
|
value
|
|
@@ -9,11 +9,13 @@ module Solargraph::LanguageServer::Message::Workspace
|
|
|
9
9
|
|
|
10
10
|
private
|
|
11
11
|
|
|
12
|
+
# @return [void]
|
|
12
13
|
def add_folders
|
|
13
14
|
return unless params['event'] && params['event']['added']
|
|
14
15
|
host.prepare_folders params['event']['added']
|
|
15
16
|
end
|
|
16
17
|
|
|
18
|
+
# @return [void]
|
|
17
19
|
def remove_folders
|
|
18
20
|
return unless params['event'] && params['event']['removed']
|
|
19
21
|
params['event']['removed'].each do |folder|
|
|
@@ -39,6 +39,7 @@ module Solargraph
|
|
|
39
39
|
|
|
40
40
|
# @param message [String]
|
|
41
41
|
# @param percentage [Integer]
|
|
42
|
+
# @return [void]
|
|
42
43
|
def begin message, percentage
|
|
43
44
|
@kind = 'begin'
|
|
44
45
|
@message = message
|
|
@@ -47,6 +48,7 @@ module Solargraph
|
|
|
47
48
|
|
|
48
49
|
# @param message [String]
|
|
49
50
|
# @param percentage [Integer]
|
|
51
|
+
# @return [void]
|
|
50
52
|
def report message, percentage
|
|
51
53
|
@kind = 'report'
|
|
52
54
|
@message = message
|
|
@@ -54,6 +56,7 @@ module Solargraph
|
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
# @param message [String]
|
|
59
|
+
# @return [void]
|
|
57
60
|
def finish message
|
|
58
61
|
@kind = 'end'
|
|
59
62
|
@message = message
|
|
@@ -62,6 +65,7 @@ module Solargraph
|
|
|
62
65
|
end
|
|
63
66
|
|
|
64
67
|
# @param host [Solargraph::LanguageServer::Host]
|
|
68
|
+
# @return [void]
|
|
65
69
|
def send host
|
|
66
70
|
return unless host.client_supports_progress? && !finished?
|
|
67
71
|
|
|
@@ -91,6 +95,7 @@ module Solargraph
|
|
|
91
95
|
@status = CREATED
|
|
92
96
|
end
|
|
93
97
|
|
|
98
|
+
# @return [Hash]
|
|
94
99
|
def build
|
|
95
100
|
{
|
|
96
101
|
token: uuid,
|
|
@@ -101,6 +106,7 @@ module Solargraph
|
|
|
101
106
|
}
|
|
102
107
|
end
|
|
103
108
|
|
|
109
|
+
# @return [Hash]
|
|
104
110
|
def build_value
|
|
105
111
|
case kind
|
|
106
112
|
when 'begin'
|
|
@@ -115,6 +121,7 @@ module Solargraph
|
|
|
115
121
|
end
|
|
116
122
|
|
|
117
123
|
# @param host [Host]
|
|
124
|
+
# @return [void]
|
|
118
125
|
def keep_alive host
|
|
119
126
|
mutex.synchronize { @last = Time.now }
|
|
120
127
|
@keep_alive ||= Thread.new do
|
|
@@ -127,6 +134,7 @@ module Solargraph
|
|
|
127
134
|
end
|
|
128
135
|
end
|
|
129
136
|
|
|
137
|
+
# @return [Thread::Mutex]
|
|
130
138
|
def mutex
|
|
131
139
|
@mutex ||= Mutex.new
|
|
132
140
|
end
|
|
@@ -11,11 +11,14 @@ module Solargraph
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
# @param result [Object]
|
|
14
|
-
# @
|
|
14
|
+
# @generic T
|
|
15
|
+
# @yieldreturn [generic<T>]
|
|
16
|
+
# @return [generic<T>, nil]
|
|
15
17
|
def process result
|
|
16
18
|
@block.call(result) unless @block.nil?
|
|
17
19
|
end
|
|
18
20
|
|
|
21
|
+
# @return [void]
|
|
19
22
|
def send_response
|
|
20
23
|
# noop
|
|
21
24
|
end
|
data/lib/solargraph/library.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require 'pathname'
|
|
4
4
|
require 'observer'
|
|
5
|
+
require 'open3'
|
|
5
6
|
|
|
6
7
|
module Solargraph
|
|
7
8
|
# A Library handles coordination between a Workspace and an ApiMap.
|
|
@@ -258,11 +259,11 @@ module Solargraph
|
|
|
258
259
|
referenced&.path == pin.path
|
|
259
260
|
end
|
|
260
261
|
if pin.path == 'Class#new'
|
|
261
|
-
caller = cursor.chain.base.infer(api_map, clip.send(:
|
|
262
|
+
caller = cursor.chain.base.infer(api_map, clip.send(:closure), clip.locals).first
|
|
262
263
|
if caller.defined?
|
|
263
264
|
found.select! do |loc|
|
|
264
265
|
clip = api_map.clip_at(loc.filename, loc.range.start)
|
|
265
|
-
other = clip.send(:cursor).chain.base.infer(api_map, clip.send(:
|
|
266
|
+
other = clip.send(:cursor).chain.base.infer(api_map, clip.send(:closure), clip.locals).first
|
|
266
267
|
caller == other
|
|
267
268
|
end
|
|
268
269
|
else
|
|
@@ -401,8 +402,8 @@ module Solargraph
|
|
|
401
402
|
repargs = {}
|
|
402
403
|
workspace.config.reporters.each do |line|
|
|
403
404
|
if line == 'all!'
|
|
404
|
-
Diagnostics.reporters.each do |
|
|
405
|
-
repargs[reporter] ||= []
|
|
405
|
+
Diagnostics.reporters.each do |reporter_name|
|
|
406
|
+
repargs[Diagnostics.reporter(reporter_name)] ||= []
|
|
406
407
|
end
|
|
407
408
|
else
|
|
408
409
|
args = line.split(':').map(&:strip)
|
|
@@ -436,17 +437,6 @@ module Solargraph
|
|
|
436
437
|
)
|
|
437
438
|
end
|
|
438
439
|
|
|
439
|
-
# Get an array of foldable ranges for the specified file.
|
|
440
|
-
#
|
|
441
|
-
# @deprecated The library should not need to handle folding ranges. The
|
|
442
|
-
# source itself has all the information it needs.
|
|
443
|
-
#
|
|
444
|
-
# @param filename [String]
|
|
445
|
-
# @return [Array<Range>]
|
|
446
|
-
def folding_ranges filename
|
|
447
|
-
read(filename).folding_ranges
|
|
448
|
-
end
|
|
449
|
-
|
|
450
440
|
# Create a library from a directory.
|
|
451
441
|
#
|
|
452
442
|
# @param directory [String] The path to be used for the workspace
|
|
@@ -510,7 +500,7 @@ module Solargraph
|
|
|
510
500
|
|
|
511
501
|
private
|
|
512
502
|
|
|
513
|
-
# @return [Hash{String =>
|
|
503
|
+
# @return [Hash{String => Array<String>}]
|
|
514
504
|
def source_map_external_require_hash
|
|
515
505
|
@source_map_external_require_hash ||= {}
|
|
516
506
|
end
|
|
@@ -518,6 +508,7 @@ module Solargraph
|
|
|
518
508
|
# @param source_map [SourceMap]
|
|
519
509
|
# @return [void]
|
|
520
510
|
def find_external_requires source_map
|
|
511
|
+
# @type [Set<String>]
|
|
521
512
|
new_set = source_map.requires.map(&:name).to_set
|
|
522
513
|
# return if new_set == source_map_external_require_hash[source_map.filename]
|
|
523
514
|
_filenames = nil
|
|
@@ -531,7 +522,7 @@ module Solargraph
|
|
|
531
522
|
@external_requires = nil
|
|
532
523
|
end
|
|
533
524
|
|
|
534
|
-
# @return [Mutex]
|
|
525
|
+
# @return [Thread::Mutex]
|
|
535
526
|
def mutex
|
|
536
527
|
@mutex ||= Mutex.new
|
|
537
528
|
end
|
|
@@ -588,29 +579,54 @@ module Solargraph
|
|
|
588
579
|
# @return [void]
|
|
589
580
|
def cache_next_gemspec
|
|
590
581
|
return if @cache_progress
|
|
591
|
-
|
|
592
|
-
|
|
582
|
+
|
|
583
|
+
spec = cacheable_specs.first
|
|
593
584
|
return end_cache_progress unless spec
|
|
594
585
|
|
|
595
586
|
pending = api_map.uncached_gemspecs.length - cache_errors.length - 1
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
rescue Errno::EINVAL => _e
|
|
603
|
-
logger.info "Cached #{spec.name} #{spec.version} with EINVAL"
|
|
604
|
-
rescue StandardError => e
|
|
605
|
-
cache_errors.add spec
|
|
606
|
-
Solargraph.logger.warn "Error caching gemspec #{spec.name} #{spec.version}: [#{e.class}] #{e.message}"
|
|
607
|
-
ensure
|
|
608
|
-
end_cache_progress
|
|
587
|
+
|
|
588
|
+
if Yardoc.processing?(spec)
|
|
589
|
+
logger.info "Enqueuing cache of #{spec.name} #{spec.version} (already being processed)"
|
|
590
|
+
queued_gemspec_cache.push(spec)
|
|
591
|
+
return if pending - queued_gemspec_cache.length < 1
|
|
592
|
+
|
|
609
593
|
catalog
|
|
610
594
|
sync_catalog
|
|
595
|
+
else
|
|
596
|
+
logger.info "Caching #{spec.name} #{spec.version}"
|
|
597
|
+
Thread.new do
|
|
598
|
+
report_cache_progress spec.name, pending
|
|
599
|
+
_o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s)
|
|
600
|
+
if s.success?
|
|
601
|
+
logger.info "Cached #{spec.name} #{spec.version}"
|
|
602
|
+
else
|
|
603
|
+
cache_errors.add spec
|
|
604
|
+
logger.warn "Error caching gemspec #{spec.name} #{spec.version}"
|
|
605
|
+
logger.warn e
|
|
606
|
+
end
|
|
607
|
+
end_cache_progress
|
|
608
|
+
catalog
|
|
609
|
+
sync_catalog
|
|
610
|
+
end
|
|
611
611
|
end
|
|
612
612
|
end
|
|
613
613
|
|
|
614
|
+
# @return [Array<Gem::Specification>]
|
|
615
|
+
def cacheable_specs
|
|
616
|
+
cacheable = api_map.uncached_yard_gemspecs +
|
|
617
|
+
api_map.uncached_rbs_collection_gemspecs -
|
|
618
|
+
queued_gemspec_cache -
|
|
619
|
+
cache_errors.to_a
|
|
620
|
+
return cacheable unless cacheable.empty?
|
|
621
|
+
|
|
622
|
+
queued_gemspec_cache
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
# @return [Array<Gem::Specification>]
|
|
626
|
+
def queued_gemspec_cache
|
|
627
|
+
@queued_gemspec_cache ||= []
|
|
628
|
+
end
|
|
629
|
+
|
|
614
630
|
# @param gem_name [String]
|
|
615
631
|
# @param pending [Integer]
|
|
616
632
|
# @return [void]
|
|
@@ -648,13 +664,14 @@ module Solargraph
|
|
|
648
664
|
@total = nil
|
|
649
665
|
end
|
|
650
666
|
|
|
667
|
+
# @return [void]
|
|
651
668
|
def sync_catalog
|
|
652
669
|
return if @sync_count == 0
|
|
653
670
|
|
|
654
671
|
mutex.synchronize do
|
|
655
672
|
logger.info "Cataloging #{workspace.directory.empty? ? 'generic workspace' : workspace.directory}"
|
|
656
|
-
api_map.catalog bench
|
|
657
673
|
source_map_hash.values.each { |map| find_external_requires(map) }
|
|
674
|
+
api_map.catalog bench
|
|
658
675
|
logger.info "Catalog complete (#{api_map.source_maps.length} files, #{api_map.pins.length} pins)"
|
|
659
676
|
logger.info "#{api_map.uncached_yard_gemspecs.length} uncached YARD gemspecs"
|
|
660
677
|
logger.info "#{api_map.uncached_rbs_collection_gemspecs.length} uncached RBS collection gemspecs"
|
data/lib/solargraph/location.rb
CHANGED
|
@@ -25,6 +25,7 @@ module Solargraph
|
|
|
25
25
|
[filename, range]
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
# @param other [self]
|
|
28
29
|
def <=>(other)
|
|
29
30
|
return nil unless other.is_a?(Location)
|
|
30
31
|
if filename == other.filename
|
|
@@ -60,6 +61,7 @@ module Solargraph
|
|
|
60
61
|
end
|
|
61
62
|
|
|
62
63
|
# @param node [Parser::AST::Node, nil]
|
|
64
|
+
# @return [Location, nil]
|
|
63
65
|
def self.from_node(node)
|
|
64
66
|
return nil if node.nil? || node.loc.nil?
|
|
65
67
|
range = Range.from_node(node)
|
|
@@ -69,6 +71,7 @@ module Solargraph
|
|
|
69
71
|
# @param other [BasicObject]
|
|
70
72
|
def == other
|
|
71
73
|
return false unless other.is_a?(Location)
|
|
74
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
72
75
|
filename == other.filename and range == other.range
|
|
73
76
|
end
|
|
74
77
|
|
data/lib/solargraph/logging.rb
CHANGED
|
@@ -11,8 +11,17 @@ module Solargraph
|
|
|
11
11
|
'info' => Logger::INFO,
|
|
12
12
|
'debug' => Logger::DEBUG
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
configured_level = ENV.fetch('SOLARGRAPH_LOG', nil)
|
|
15
|
+
level = if LOG_LEVELS.keys.include?(configured_level)
|
|
16
|
+
LOG_LEVELS.fetch(configured_level)
|
|
17
|
+
else
|
|
18
|
+
if configured_level
|
|
19
|
+
warn "Invalid value for SOLARGRAPH_LOG: #{configured_level.inspect} - " \
|
|
20
|
+
"valid values are #{LOG_LEVELS.keys}"
|
|
21
|
+
end
|
|
22
|
+
DEFAULT_LOG_LEVEL
|
|
23
|
+
end
|
|
24
|
+
@@logger = Logger.new(STDERR, level: level)
|
|
16
25
|
# @sg-ignore Fix cvar issue
|
|
17
26
|
@@logger.formatter = proc do |severity, datetime, progname, msg|
|
|
18
27
|
"[#{severity}] #{msg}\n"
|
data/lib/solargraph/page.rb
CHANGED
|
@@ -29,6 +29,7 @@ module Solargraph
|
|
|
29
29
|
# @param text [String]
|
|
30
30
|
# @return [String]
|
|
31
31
|
def htmlify text
|
|
32
|
+
# @type [String]
|
|
32
33
|
YARD::Templates::Helpers::Markup::RDocMarkup.new(text).to_html
|
|
33
34
|
end
|
|
34
35
|
|
|
@@ -70,8 +71,10 @@ module Solargraph
|
|
|
70
71
|
# @param template [String]
|
|
71
72
|
# @param layout [Boolean]
|
|
72
73
|
# @param locals [Hash]
|
|
74
|
+
# @sg-ignore
|
|
73
75
|
# @return [String]
|
|
74
76
|
def render template, layout: true, locals: {}
|
|
77
|
+
# @type [String]
|
|
75
78
|
@render_method.call(template, layout: layout, locals: locals)
|
|
76
79
|
end
|
|
77
80
|
|
|
@@ -3,6 +3,13 @@ require 'ripper'
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
module Parser
|
|
5
5
|
class CommentRipper < Ripper::SexpBuilderPP
|
|
6
|
+
# @!override Ripper::SexpBuilder#on_embdoc_beg
|
|
7
|
+
# @return [Array(Symbol, String, Array)]
|
|
8
|
+
# @!override Ripper::SexpBuilder#on_embdoc
|
|
9
|
+
# @return [Array(Symbol, String, Array)]
|
|
10
|
+
# @!override Ripper::SexpBuilder#on_embdoc_end
|
|
11
|
+
# @return [Array(Symbol, String, Array)]
|
|
12
|
+
|
|
6
13
|
# @param src [String]
|
|
7
14
|
# @param filename [String]
|
|
8
15
|
# @param lineno [Integer]
|
|
@@ -51,7 +58,7 @@ module Solargraph
|
|
|
51
58
|
result
|
|
52
59
|
end
|
|
53
60
|
|
|
54
|
-
# @return [Hash{Integer =>
|
|
61
|
+
# @return [Hash{Integer => Solargraph::Parser::Snippet}]
|
|
55
62
|
def parse
|
|
56
63
|
@comments = {}
|
|
57
64
|
super
|
|
@@ -4,14 +4,20 @@ module Solargraph
|
|
|
4
4
|
include Solargraph::Parser::NodeMethods
|
|
5
5
|
|
|
6
6
|
# @param locals [Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
7
|
+
# @param enclosing_breakable_pin [Solargraph::Pin::Breakable, nil]
|
|
7
8
|
def initialize(locals, enclosing_breakable_pin = nil)
|
|
8
9
|
@locals = locals
|
|
9
10
|
@enclosing_breakable_pin = enclosing_breakable_pin
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
# @param and_node [Parser::AST::Node]
|
|
14
|
+
# @param true_ranges [Array<Range>]
|
|
15
|
+
#
|
|
16
|
+
# @return [void]
|
|
13
17
|
def process_and(and_node, true_ranges = [])
|
|
18
|
+
# @type [Parser::AST::Node]
|
|
14
19
|
lhs = and_node.children[0]
|
|
20
|
+
# @type [Parser::AST::Node]
|
|
15
21
|
rhs = and_node.children[1]
|
|
16
22
|
|
|
17
23
|
before_rhs_loc = rhs.location.expression.adjust(begin_pos: -1)
|
|
@@ -23,6 +29,8 @@ module Solargraph
|
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
# @param if_node [Parser::AST::Node]
|
|
32
|
+
#
|
|
33
|
+
# @return [void]
|
|
26
34
|
def process_if(if_node)
|
|
27
35
|
#
|
|
28
36
|
# See if we can refine a type based on the result of 'if foo.nil?'
|
|
@@ -36,7 +44,9 @@ module Solargraph
|
|
|
36
44
|
# s(:send, nil, :bar))
|
|
37
45
|
# [4] pry(main)>
|
|
38
46
|
conditional_node = if_node.children[0]
|
|
47
|
+
# @type [Parser::AST::Node]
|
|
39
48
|
then_clause = if_node.children[1]
|
|
49
|
+
# @type [Parser::AST::Node]
|
|
40
50
|
else_clause = if_node.children[2]
|
|
41
51
|
|
|
42
52
|
true_ranges = []
|
|
@@ -72,8 +82,11 @@ module Solargraph
|
|
|
72
82
|
# them based on the Closure and Location.
|
|
73
83
|
#
|
|
74
84
|
# @param pins [Array<Pin::LocalVariable>]
|
|
85
|
+
# @param name [String]
|
|
75
86
|
# @param closure [Pin::Closure]
|
|
76
87
|
# @param location [Location]
|
|
88
|
+
#
|
|
89
|
+
# @return [Array<Pin::LocalVariable>]
|
|
77
90
|
def self.visible_pins(pins, name, closure, location)
|
|
78
91
|
logger.debug { "FlowSensitiveTyping#visible_pins(name=#{name}, closure=#{closure}, location=#{location})" }
|
|
79
92
|
pins_with_name = pins.select { |p| p.name == name }
|
|
@@ -107,7 +120,10 @@ module Solargraph
|
|
|
107
120
|
private
|
|
108
121
|
|
|
109
122
|
# @param pin [Pin::LocalVariable]
|
|
110
|
-
# @param
|
|
123
|
+
# @param downcast_type_name [String]
|
|
124
|
+
# @param presence [Range]
|
|
125
|
+
#
|
|
126
|
+
# @return [void]
|
|
111
127
|
def add_downcast_local(pin, downcast_type_name, presence)
|
|
112
128
|
# @todo Create pin#update method
|
|
113
129
|
new_pin = Solargraph::Pin::LocalVariable.new(
|
|
@@ -126,6 +142,7 @@ module Solargraph
|
|
|
126
142
|
|
|
127
143
|
# @param facts_by_pin [Hash{Pin::LocalVariable => Array<Hash{Symbol => String}>}]
|
|
128
144
|
# @param presences [Array<Range>]
|
|
145
|
+
#
|
|
129
146
|
# @return [void]
|
|
130
147
|
def process_facts(facts_by_pin, presences)
|
|
131
148
|
#
|
|
@@ -142,6 +159,9 @@ module Solargraph
|
|
|
142
159
|
end
|
|
143
160
|
|
|
144
161
|
# @param conditional_node [Parser::AST::Node]
|
|
162
|
+
# @param true_ranges [Array<Range>]
|
|
163
|
+
#
|
|
164
|
+
# @return [void]
|
|
145
165
|
def process_conditional(conditional_node, true_ranges)
|
|
146
166
|
if conditional_node.type == :send
|
|
147
167
|
process_isa(conditional_node, true_ranges)
|
|
@@ -151,7 +171,7 @@ module Solargraph
|
|
|
151
171
|
end
|
|
152
172
|
|
|
153
173
|
# @param isa_node [Parser::AST::Node]
|
|
154
|
-
# @return [Array(String, String)]
|
|
174
|
+
# @return [Array(String, String), nil]
|
|
155
175
|
def parse_isa(isa_node)
|
|
156
176
|
return unless isa_node&.type == :send && isa_node.children[1] == :is_a?
|
|
157
177
|
# Check if conditional node follows this pattern:
|
|
@@ -176,12 +196,20 @@ module Solargraph
|
|
|
176
196
|
[isa_type_name, variable_name]
|
|
177
197
|
end
|
|
178
198
|
|
|
199
|
+
# @param variable_name [String]
|
|
200
|
+
# @param position [Position]
|
|
201
|
+
#
|
|
202
|
+
# @return [Solargraph::Pin::LocalVariable, nil]
|
|
179
203
|
def find_local(variable_name, position)
|
|
180
204
|
pins = locals.select { |pin| pin.name == variable_name && pin.presence.include?(position) }
|
|
181
205
|
return unless pins.length == 1
|
|
182
206
|
pins.first
|
|
183
207
|
end
|
|
184
208
|
|
|
209
|
+
# @param isa_node [Parser::AST::Node]
|
|
210
|
+
# @param true_presences [Array<Range>]
|
|
211
|
+
#
|
|
212
|
+
# @return [void]
|
|
185
213
|
def process_isa(isa_node, true_presences)
|
|
186
214
|
isa_type_name, variable_name = parse_isa(isa_node)
|
|
187
215
|
return if variable_name.nil? || variable_name.empty?
|
|
@@ -197,10 +225,12 @@ module Solargraph
|
|
|
197
225
|
end
|
|
198
226
|
|
|
199
227
|
# @param node [Parser::AST::Node]
|
|
228
|
+
#
|
|
229
|
+
# @return [String, nil]
|
|
200
230
|
def type_name(node)
|
|
201
231
|
# e.g.,
|
|
202
232
|
# s(:const, nil, :Baz)
|
|
203
|
-
return unless node
|
|
233
|
+
return unless node&.type == :const
|
|
204
234
|
module_node = node.children[0]
|
|
205
235
|
class_node = node.children[1]
|
|
206
236
|
|
|
@@ -212,8 +242,6 @@ module Solargraph
|
|
|
212
242
|
"#{module_type_name}::#{class_node}"
|
|
213
243
|
end
|
|
214
244
|
|
|
215
|
-
# @todo "return type could not be inferred" should not trigger here
|
|
216
|
-
# @sg-ignore
|
|
217
245
|
# @param clause_node [Parser::AST::Node]
|
|
218
246
|
def always_breaks?(clause_node)
|
|
219
247
|
clause_node&.type == :break
|