solargraph 0.56.1 → 0.57.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.
- checksums.yaml +4 -4
- data/.github/workflows/linting.yml +125 -0
- data/.github/workflows/plugins.yml +148 -6
- data/.github/workflows/rspec.yml +39 -4
- data/.github/workflows/typecheck.yml +5 -2
- data/.gitignore +5 -0
- data/.overcommit.yml +72 -0
- data/.rspec +1 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +2627 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +50 -0
- data/README.md +8 -4
- data/Rakefile +125 -13
- data/lib/solargraph/api_map/cache.rb +3 -2
- data/lib/solargraph/api_map/constants.rb +218 -0
- data/lib/solargraph/api_map/index.rb +20 -26
- data/lib/solargraph/api_map/source_to_yard.rb +10 -4
- data/lib/solargraph/api_map/store.rb +126 -18
- data/lib/solargraph/api_map.rb +212 -234
- data/lib/solargraph/bench.rb +1 -0
- data/lib/solargraph/complex_type/type_methods.rb +1 -0
- data/lib/solargraph/complex_type/unique_type.rb +7 -7
- data/lib/solargraph/complex_type.rb +5 -1
- 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 +1 -1
- data/lib/solargraph/doc_map.rb +40 -12
- data/lib/solargraph/environ.rb +9 -2
- data/lib/solargraph/gem_pins.rb +17 -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 +2 -1
- 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 +16 -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 +1 -0
- data/lib/solargraph/library.rb +17 -24
- data/lib/solargraph/location.rb +2 -0
- data/lib/solargraph/logging.rb +11 -2
- data/lib/solargraph/page.rb +4 -0
- data/lib/solargraph/parser/comment_ripper.rb +8 -1
- data/lib/solargraph/parser/flow_sensitive_typing.rb +32 -4
- data/lib/solargraph/parser/node_methods.rb +2 -2
- 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 +1 -1
- 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 +4 -2
- 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 +1 -0
- 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/send_node.rb +35 -14
- 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 +65 -8
- data/lib/solargraph/pin/base_variable.rb +1 -2
- data/lib/solargraph/pin/callable.rb +9 -0
- data/lib/solargraph/pin/closure.rb +2 -0
- data/lib/solargraph/pin/common.rb +6 -2
- data/lib/solargraph/pin/constant.rb +2 -0
- data/lib/solargraph/pin/delegated_method.rb +1 -0
- data/lib/solargraph/pin/local_variable.rb +4 -1
- data/lib/solargraph/pin/method.rb +12 -7
- data/lib/solargraph/pin/method_alias.rb +3 -0
- data/lib/solargraph/pin/parameter.rb +18 -8
- data/lib/solargraph/pin/proxy_type.rb +1 -0
- data/lib/solargraph/pin/reference/override.rb +15 -1
- data/lib/solargraph/pin/reference/superclass.rb +5 -0
- data/lib/solargraph/pin/reference.rb +26 -0
- data/lib/solargraph/pin/search.rb +3 -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 +2 -0
- data/lib/solargraph/range.rb +1 -0
- data/lib/solargraph/rbs_map/conversions.rb +47 -18
- data/lib/solargraph/rbs_map/core_map.rb +3 -0
- data/lib/solargraph/rbs_map.rb +15 -2
- data/lib/solargraph/shell.rb +3 -0
- data/lib/solargraph/source/chain/link.rb +10 -1
- data/lib/solargraph/source/chain.rb +9 -2
- data/lib/solargraph/source/change.rb +2 -2
- data/lib/solargraph/source/cursor.rb +2 -3
- data/lib/solargraph/source/source_chainer.rb +1 -1
- data/lib/solargraph/source.rb +5 -2
- data/lib/solargraph/source_map/clip.rb +1 -1
- data/lib/solargraph/source_map/data.rb +4 -0
- data/lib/solargraph/source_map/mapper.rb +4 -2
- data/lib/solargraph/source_map.rb +21 -14
- data/lib/solargraph/type_checker/param_def.rb +2 -0
- data/lib/solargraph/type_checker/rules.rb +8 -0
- data/lib/solargraph/type_checker.rb +173 -120
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +1 -3
- data/lib/solargraph/workspace/require_paths.rb +98 -0
- data/lib/solargraph/workspace.rb +16 -48
- 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 +3 -8
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +7 -7
- data/lib/solargraph/yardoc.rb +16 -3
- data/lib/solargraph.rb +15 -0
- data/rbs/fills/tuple.rbs +2 -3
- data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -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 +14 -4
- metadata +126 -9
- data/lib/.rubocop.yml +0 -22
@@ -8,8 +8,9 @@ module Solargraph
|
|
8
8
|
|
9
9
|
module NodeProcessors
|
10
10
|
class StructNode < Parser::NodeProcessor::Base
|
11
|
+
# @return [Boolean] continue processing the next processor of the same node.
|
11
12
|
def process
|
12
|
-
return if struct_definition_node.nil?
|
13
|
+
return true if struct_definition_node.nil?
|
13
14
|
|
14
15
|
loc = get_node_location(node)
|
15
16
|
nspin = Solargraph::Pin::Namespace.new(
|
@@ -17,9 +18,10 @@ module Solargraph
|
|
17
18
|
location: loc,
|
18
19
|
closure: region.closure,
|
19
20
|
name: struct_definition_node.class_name,
|
20
|
-
|
21
|
+
docstring: docstring,
|
21
22
|
visibility: :public,
|
22
|
-
gates: region.closure.gates.freeze
|
23
|
+
gates: region.closure.gates.freeze,
|
24
|
+
source: :struct_definition
|
23
25
|
)
|
24
26
|
pins.push nspin
|
25
27
|
|
@@ -31,7 +33,8 @@ module Solargraph
|
|
31
33
|
location: get_node_location(node),
|
32
34
|
closure: nspin,
|
33
35
|
visibility: :private,
|
34
|
-
|
36
|
+
docstring: docstring,
|
37
|
+
source: :struct_definition
|
35
38
|
)
|
36
39
|
|
37
40
|
pins.push initialize_method_pin
|
@@ -42,7 +45,8 @@ module Solargraph
|
|
42
45
|
name: attribute_name,
|
43
46
|
decl: struct_definition_node.keyword_init? ? :kwarg : :arg,
|
44
47
|
location: get_node_location(attribute_node),
|
45
|
-
closure: initialize_method_pin
|
48
|
+
closure: initialize_method_pin,
|
49
|
+
source: :struct_definition
|
46
50
|
)
|
47
51
|
)
|
48
52
|
end
|
@@ -50,49 +54,108 @@ module Solargraph
|
|
50
54
|
# define attribute accessors and instance variables
|
51
55
|
struct_definition_node.attributes.each do |attribute_node, attribute_name|
|
52
56
|
[attribute_name, "#{attribute_name}="].each do |name|
|
57
|
+
docs = docstring.tags.find { |t| t.tag_name == 'param' && t.name == attribute_name }
|
58
|
+
|
59
|
+
attribute_type = ComplexType.parse(tag_string(docs))
|
60
|
+
return_type_comment = attribute_comment(docs, false)
|
61
|
+
param_comment = attribute_comment(docs, true)
|
62
|
+
|
53
63
|
method_pin = Pin::Method.new(
|
54
64
|
name: name,
|
55
65
|
parameters: [],
|
56
66
|
scope: :instance,
|
57
67
|
location: get_node_location(attribute_node),
|
58
68
|
closure: nspin,
|
59
|
-
|
60
|
-
|
69
|
+
docstring: YARD::Docstring.new(return_type_comment),
|
70
|
+
# even assignments return the value
|
71
|
+
comments: return_type_comment,
|
72
|
+
return_type: attribute_type,
|
73
|
+
visibility: :public,
|
74
|
+
source: :struct_definition
|
61
75
|
)
|
62
76
|
|
63
|
-
|
77
|
+
if name.end_with?('=')
|
78
|
+
method_pin.parameters << Pin::Parameter.new(
|
79
|
+
name: attribute_name,
|
80
|
+
location: get_node_location(attribute_node),
|
81
|
+
closure: method_pin,
|
82
|
+
return_type: attribute_type,
|
83
|
+
comments: param_comment,
|
84
|
+
source: :struct_definition
|
85
|
+
)
|
64
86
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
87
|
+
pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
|
88
|
+
closure: method_pin,
|
89
|
+
location: get_node_location(attribute_node),
|
90
|
+
return_type: attribute_type,
|
91
|
+
comments: "@type [#{attribute_type.rooted_tags}]",
|
92
|
+
source: :struct_definition)
|
93
|
+
end
|
94
|
+
|
95
|
+
pins.push method_pin
|
70
96
|
end
|
71
97
|
end
|
72
98
|
|
73
99
|
process_children region.update(closure: nspin, visibility: :public)
|
100
|
+
false
|
74
101
|
end
|
75
102
|
|
76
103
|
private
|
77
104
|
|
78
|
-
# @return [StructDefintionNode, nil]
|
105
|
+
# @return [StructDefintionNode, StructAssignmentNode, nil]
|
79
106
|
def struct_definition_node
|
80
|
-
@struct_definition_node ||= if StructDefintionNode.
|
107
|
+
@struct_definition_node ||= if StructDefintionNode.match?(node)
|
81
108
|
StructDefintionNode.new(node)
|
82
|
-
elsif StructAssignmentNode.
|
109
|
+
elsif StructAssignmentNode.match?(node)
|
83
110
|
StructAssignmentNode.new(node)
|
84
111
|
end
|
85
112
|
end
|
86
113
|
|
87
|
-
#
|
88
|
-
# @return [
|
89
|
-
def
|
90
|
-
|
91
|
-
|
114
|
+
# Gets/generates the relevant docstring for this struct & it's attributes
|
115
|
+
# @return [YARD::Docstring]
|
116
|
+
def docstring
|
117
|
+
@docstring ||= parse_comments
|
118
|
+
end
|
119
|
+
|
120
|
+
# Parses any relevant comments for a struct int a yard docstring
|
121
|
+
# @return [YARD::Docstring]
|
122
|
+
def parse_comments
|
123
|
+
struct_comments = comments_for(node) || ''
|
124
|
+
struct_definition_node.attributes.each do |attr_node, attr_name|
|
125
|
+
comment = comments_for(attr_node)
|
126
|
+
next if comment.nil?
|
92
127
|
|
93
|
-
|
94
|
-
|
95
|
-
|
128
|
+
# We should support specific comments for an attribute, and that can be either a @return on an @param
|
129
|
+
# But since we merge into the struct_comments, then we should interpret either as a param
|
130
|
+
comment = "@param #{attr_name}#{comment[7..]}" if comment.start_with?('@return')
|
131
|
+
|
132
|
+
struct_comments += "\n#{comment}"
|
133
|
+
end
|
134
|
+
|
135
|
+
Solargraph::Source.parse_docstring(struct_comments).to_docstring
|
136
|
+
end
|
137
|
+
|
138
|
+
# @param tag [YARD::Tags::Tag, nil] The param tag for this attribute.xtract_
|
139
|
+
#
|
140
|
+
# @return [String]
|
141
|
+
def tag_string(tag)
|
142
|
+
tag&.types&.join(',') || 'undefined'
|
143
|
+
end
|
144
|
+
|
145
|
+
# @param tag [YARD::Tags::Tag, nil] The param tag for this attribute. If nil, this method is a no-op
|
146
|
+
# @param for_setter [Boolean] If true, will return a @param tag instead of a @return tag
|
147
|
+
#
|
148
|
+
# @return [String] The formatted comment for the attribute
|
149
|
+
def attribute_comment(tag, for_setter)
|
150
|
+
return "" if tag.nil?
|
151
|
+
|
152
|
+
suffix = "[#{tag_string(tag)}] #{tag.text}"
|
153
|
+
|
154
|
+
if for_setter
|
155
|
+
"@param #{tag.name} #{suffix}"
|
156
|
+
else
|
157
|
+
"@return #{suffix}"
|
158
|
+
end
|
96
159
|
end
|
97
160
|
end
|
98
161
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
3
|
module Solargraph
|
5
4
|
# Conventions provide a way to modify an ApiMap based on expectations about
|
6
5
|
# one of its sources.
|
@@ -11,6 +10,8 @@ module Solargraph
|
|
11
10
|
autoload :Gemspec, 'solargraph/convention/gemspec'
|
12
11
|
autoload :Rakefile, 'solargraph/convention/rakefile'
|
13
12
|
autoload :StructDefinition, 'solargraph/convention/struct_definition'
|
13
|
+
autoload :DataDefinition, 'solargraph/convention/data_definition'
|
14
|
+
autoload :ActiveSupportConcern, 'solargraph/convention/active_support_concern'
|
14
15
|
|
15
16
|
# @type [Set<Convention::Base>]
|
16
17
|
@@conventions = Set.new
|
@@ -21,6 +22,12 @@ module Solargraph
|
|
21
22
|
@@conventions.add convention.new
|
22
23
|
end
|
23
24
|
|
25
|
+
# @param convention [Class<Convention::Base>]
|
26
|
+
# @return [void]
|
27
|
+
def self.unregister convention
|
28
|
+
@@conventions.delete_if { |c| c.is_a?(convention) }
|
29
|
+
end
|
30
|
+
|
24
31
|
# @param source_map [SourceMap]
|
25
32
|
# @return [Environ]
|
26
33
|
def self.for_local(source_map)
|
@@ -31,7 +38,7 @@ module Solargraph
|
|
31
38
|
result
|
32
39
|
end
|
33
40
|
|
34
|
-
# @param
|
41
|
+
# @param doc_map [DocMap]
|
35
42
|
# @return [Environ]
|
36
43
|
def self.for_global(doc_map)
|
37
44
|
result = Environ.new
|
@@ -41,8 +48,31 @@ module Solargraph
|
|
41
48
|
result
|
42
49
|
end
|
43
50
|
|
51
|
+
# Provides any additional method pins based on the described object.
|
52
|
+
#
|
53
|
+
# @param api_map [ApiMap]
|
54
|
+
# @param rooted_tag [String] A fully qualified namespace, with
|
55
|
+
# generic parameter values if applicable
|
56
|
+
# @param scope [Symbol] :class or :instance
|
57
|
+
# @param visibility [Array<Symbol>] :public, :protected, and/or :private
|
58
|
+
# @param deep [Boolean]
|
59
|
+
# @param skip [Set<String>]
|
60
|
+
# @param no_core [Boolean] Skip core classes if true
|
61
|
+
#
|
62
|
+
# @return [Environ]
|
63
|
+
def self.for_object api_map, rooted_tag, scope, visibility,
|
64
|
+
deep, skip, no_core
|
65
|
+
result = Environ.new
|
66
|
+
@@conventions.each do |conv|
|
67
|
+
result.merge conv.object(api_map, rooted_tag, scope, visibility,
|
68
|
+
deep, skip, no_core)
|
69
|
+
end
|
70
|
+
result
|
71
|
+
end
|
72
|
+
|
44
73
|
register Gemfile
|
45
74
|
register Gemspec
|
46
75
|
register Rakefile
|
76
|
+
register ActiveSupportConcern
|
47
77
|
end
|
48
78
|
end
|
@@ -28,7 +28,12 @@ module Solargraph
|
|
28
28
|
options, paths = generate_options(source.filename, source.code)
|
29
29
|
store = RuboCop::ConfigStore.new
|
30
30
|
runner = RuboCop::Runner.new(options, store)
|
31
|
-
|
31
|
+
# Ensure only one instance of RuboCop::Runner is running at
|
32
|
+
# a time - it uses 'chdir' to read config files with ERB,
|
33
|
+
# which can conflict with other chdirs.
|
34
|
+
result = Solargraph::CHDIR_MUTEX.synchronize do
|
35
|
+
redirect_stdout{ runner.run(paths) }
|
36
|
+
end
|
32
37
|
|
33
38
|
return [] if result.empty?
|
34
39
|
|
@@ -15,10 +15,10 @@ module Solargraph
|
|
15
15
|
# @return [void]
|
16
16
|
def require_rubocop(version = nil)
|
17
17
|
begin
|
18
|
+
# @type [String]
|
18
19
|
gem_path = Gem::Specification.find_by_name('rubocop', version).full_gem_path
|
19
20
|
gem_lib_path = File.join(gem_path, 'lib')
|
20
21
|
$LOAD_PATH.unshift(gem_lib_path) unless $LOAD_PATH.include?(gem_lib_path)
|
21
|
-
# @todo Gem::MissingSpecVersionError is undocumented for some reason
|
22
22
|
# @sg-ignore
|
23
23
|
rescue Gem::MissingSpecVersionError => e
|
24
24
|
raise InvalidRubocopVersionError,
|
data/lib/solargraph/doc_map.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
require 'benchmark'
|
5
|
+
require 'open3'
|
5
6
|
|
6
7
|
module Solargraph
|
7
8
|
# A collection of pins generated from required gems.
|
@@ -32,8 +33,10 @@ module Solargraph
|
|
32
33
|
# @return [Array<Gem::Specification>]
|
33
34
|
attr_reader :uncached_rbs_collection_gemspecs
|
34
35
|
|
36
|
+
# @return [String, nil]
|
35
37
|
attr_reader :rbs_collection_path
|
36
38
|
|
39
|
+
# @return [String, nil]
|
37
40
|
attr_reader :rbs_collection_config_path
|
38
41
|
|
39
42
|
# @return [Workspace, nil]
|
@@ -52,10 +55,13 @@ module Solargraph
|
|
52
55
|
@rbs_collection_path = workspace&.rbs_collection_path
|
53
56
|
@rbs_collection_config_path = workspace&.rbs_collection_config_path
|
54
57
|
@environ = Convention.for_global(self)
|
58
|
+
@requires.concat @environ.requires if @environ
|
55
59
|
load_serialized_gem_pins
|
56
60
|
pins.concat @environ.pins
|
57
61
|
end
|
58
62
|
|
63
|
+
# @param out [IO]
|
64
|
+
# @return [void]
|
59
65
|
def cache_all!(out)
|
60
66
|
# if we log at debug level:
|
61
67
|
if logger.info?
|
@@ -73,12 +79,18 @@ module Solargraph
|
|
73
79
|
@uncached_yard_gemspecs = []
|
74
80
|
end
|
75
81
|
|
82
|
+
# @param gemspec [Gem::Specification]
|
83
|
+
# @param out [IO]
|
84
|
+
# @return [void]
|
76
85
|
def cache_yard_pins(gemspec, out)
|
77
|
-
pins = GemPins.build_yard_pins(gemspec)
|
86
|
+
pins = GemPins.build_yard_pins(yard_plugins, gemspec)
|
78
87
|
PinCache.serialize_yard_gem(gemspec, pins)
|
79
88
|
logger.info { "Cached #{pins.length} YARD pins for gem #{gemspec.name}:#{gemspec.version}" } unless pins.empty?
|
80
89
|
end
|
81
90
|
|
91
|
+
# @param gemspec [Gem::Specification]
|
92
|
+
# @param out [IO]
|
93
|
+
# @return [void]
|
82
94
|
def cache_rbs_collection_pins(gemspec, out)
|
83
95
|
rbs_map = RbsMap.from_gemspec(gemspec, rbs_collection_path, rbs_collection_config_path)
|
84
96
|
pins = rbs_map.pins
|
@@ -90,6 +102,9 @@ module Solargraph
|
|
90
102
|
end
|
91
103
|
|
92
104
|
# @param gemspec [Gem::Specification]
|
105
|
+
# @param rebuild [Boolean] whether to rebuild the pins even if they are cached
|
106
|
+
# @param out [IO, nil] output stream for logging
|
107
|
+
# @return [void]
|
93
108
|
def cache(gemspec, rebuild: false, out: nil)
|
94
109
|
build_yard = uncached_yard_gemspecs.include?(gemspec) || rebuild
|
95
110
|
build_rbs_collection = uncached_rbs_collection_gemspecs.include?(gemspec) || rebuild
|
@@ -113,30 +128,42 @@ module Solargraph
|
|
113
128
|
@unresolved_requires ||= required_gems_map.select { |_, gemspecs| gemspecs.nil? }.keys
|
114
129
|
end
|
115
130
|
|
131
|
+
# @return [Hash{Array(String, String) => Array<Gem::Specification>}] Indexed by gemspec name and version
|
116
132
|
def self.all_yard_gems_in_memory
|
117
133
|
@yard_gems_in_memory ||= {}
|
118
134
|
end
|
119
135
|
|
136
|
+
# @return [Hash{String => Hash{Array(String, String) => Array<Pin::Base>}}] stored by RBS collection path
|
120
137
|
def self.all_rbs_collection_gems_in_memory
|
121
138
|
@rbs_collection_gems_in_memory ||= {}
|
122
139
|
end
|
123
140
|
|
141
|
+
# @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
|
124
142
|
def yard_pins_in_memory
|
125
143
|
self.class.all_yard_gems_in_memory
|
126
144
|
end
|
127
145
|
|
146
|
+
# @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
|
128
147
|
def rbs_collection_pins_in_memory
|
129
148
|
self.class.all_rbs_collection_gems_in_memory[rbs_collection_path] ||= {}
|
130
149
|
end
|
131
150
|
|
151
|
+
# @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
|
132
152
|
def self.all_combined_pins_in_memory
|
133
153
|
@combined_pins_in_memory ||= {}
|
134
154
|
end
|
135
155
|
|
156
|
+
# @todo this should also include an index by the hash of the RBS collection
|
157
|
+
# @return [Hash{Array(String, String) => Array<Pin::Base>}] Indexed by gemspec name and version
|
136
158
|
def combined_pins_in_memory
|
137
159
|
self.class.all_combined_pins_in_memory
|
138
160
|
end
|
139
161
|
|
162
|
+
# @return [Array<String>]
|
163
|
+
def yard_plugins
|
164
|
+
@environ.yard_plugins
|
165
|
+
end
|
166
|
+
|
140
167
|
# @return [Set<Gem::Specification>]
|
141
168
|
def dependencies
|
142
169
|
@dependencies ||= (gemspecs.flat_map { |spec| fetch_dependencies(spec) } - gemspecs).to_set
|
@@ -150,7 +177,11 @@ module Solargraph
|
|
150
177
|
@uncached_yard_gemspecs = []
|
151
178
|
@uncached_rbs_collection_gemspecs = []
|
152
179
|
with_gemspecs, without_gemspecs = required_gems_map.partition { |_, v| v }
|
180
|
+
# @sg-ignore Wrong argument type for Hash.[]: arg_0 expected _ToHash<Array(String, Array<Gem::Specification>), undefined>, received Array<Array(String, Array<Gem::Specification>)>
|
181
|
+
# @type [Array<String>]
|
153
182
|
paths = Hash[without_gemspecs].keys
|
183
|
+
# @sg-ignore Wrong argument type for Hash.[]: arg_0 expected _ToHash<Array(String, Array<Gem::Specification>), undefined>, received Array<Array(String, Array<Gem::Specification>)>
|
184
|
+
# @type [Array<Gem::Specification>]
|
154
185
|
gemspecs = Hash[with_gemspecs].values.flatten.compact + dependencies.to_a
|
155
186
|
|
156
187
|
paths.each do |path|
|
@@ -259,6 +290,8 @@ module Solargraph
|
|
259
290
|
end
|
260
291
|
end
|
261
292
|
|
293
|
+
# @param gemspec [Gem::Specification]
|
294
|
+
# @param rbs_version_cache_key [String]
|
262
295
|
# @return [Array<Pin::Base>, nil]
|
263
296
|
def deserialize_rbs_collection_cache gemspec, rbs_version_cache_key
|
264
297
|
return if rbs_collection_pins_in_memory.key?([gemspec, rbs_version_cache_key])
|
@@ -274,22 +307,13 @@ module Solargraph
|
|
274
307
|
end
|
275
308
|
end
|
276
309
|
|
277
|
-
# @param gemspec [Gem::Specification]
|
278
|
-
# @return [Boolean]
|
279
|
-
def try_gem_in_memory gemspec
|
280
|
-
gempins = DocMap.gems_in_memory[gemspec]
|
281
|
-
return false unless gempins
|
282
|
-
Solargraph.logger.debug "Found #{gemspec.name} #{gemspec.version} in memory"
|
283
|
-
@pins.concat gempins
|
284
|
-
true
|
285
|
-
end
|
286
|
-
|
287
310
|
# @param path [String]
|
288
311
|
# @return [::Array<Gem::Specification>, nil]
|
289
312
|
def resolve_path_to_gemspecs path
|
290
313
|
return nil if path.empty?
|
291
314
|
return gemspecs_required_from_bundler if path == 'bundler/require'
|
292
315
|
|
316
|
+
# @type [Gem::Specification, nil]
|
293
317
|
gemspec = Gem::Specification.find_by_path(path)
|
294
318
|
if gemspec.nil?
|
295
319
|
gem_name_guess = path.split('/').first
|
@@ -313,10 +337,12 @@ module Solargraph
|
|
313
337
|
# @param gemspec [Gem::Specification]
|
314
338
|
# @return [Gem::Specification]
|
315
339
|
def gemspec_or_preference gemspec
|
340
|
+
# :nocov: dormant feature
|
316
341
|
return gemspec unless preference_map.key?(gemspec.name)
|
317
342
|
return gemspec if gemspec.version == preference_map[gemspec.name].version
|
318
343
|
|
319
|
-
change_gemspec_version gemspec, preference_map[
|
344
|
+
change_gemspec_version gemspec, preference_map[gemspec.name].version
|
345
|
+
# :nocov:
|
320
346
|
end
|
321
347
|
|
322
348
|
# @param gemspec [Gem::Specification]
|
@@ -355,6 +381,7 @@ module Solargraph
|
|
355
381
|
self.class.inspect
|
356
382
|
end
|
357
383
|
|
384
|
+
# @return [Array<Gem::Specification>]
|
358
385
|
def gemspecs_required_from_bundler
|
359
386
|
# @todo Handle projects with custom Bundler/Gemfile setups
|
360
387
|
return unless workspace.gemfile?
|
@@ -377,6 +404,7 @@ module Solargraph
|
|
377
404
|
end
|
378
405
|
end
|
379
406
|
|
407
|
+
# @return [Array<Gem::Specification>]
|
380
408
|
def gemspecs_required_from_external_bundle
|
381
409
|
logger.info 'Fetching gemspecs required from external bundle'
|
382
410
|
return [] unless workspace&.directory
|
data/lib/solargraph/environ.rb
CHANGED
@@ -13,16 +13,21 @@ module Solargraph
|
|
13
13
|
# @return [Array<String>]
|
14
14
|
attr_reader :domains
|
15
15
|
|
16
|
-
# @return [Array<Pin::
|
16
|
+
# @return [Array<Pin::Base>]
|
17
17
|
attr_reader :pins
|
18
18
|
|
19
|
+
# @return [Array<String>]
|
20
|
+
attr_reader :yard_plugins
|
21
|
+
|
19
22
|
# @param requires [Array<String>]
|
20
23
|
# @param domains [Array<String>]
|
21
24
|
# @param pins [Array<Pin::Base>]
|
22
|
-
|
25
|
+
# @param yard_plugins[Array<String>]
|
26
|
+
def initialize requires: [], domains: [], pins: [], yard_plugins: []
|
23
27
|
@requires = requires
|
24
28
|
@domains = domains
|
25
29
|
@pins = pins
|
30
|
+
@yard_plugins = yard_plugins
|
26
31
|
end
|
27
32
|
|
28
33
|
# @return [self]
|
@@ -30,6 +35,7 @@ module Solargraph
|
|
30
35
|
domains.clear
|
31
36
|
requires.clear
|
32
37
|
pins.clear
|
38
|
+
yard_plugins.clear
|
33
39
|
self
|
34
40
|
end
|
35
41
|
|
@@ -39,6 +45,7 @@ module Solargraph
|
|
39
45
|
domains.concat other.domains
|
40
46
|
requires.concat other.requires
|
41
47
|
pins.concat other.pins
|
48
|
+
yard_plugins.concat other.yard_plugins
|
42
49
|
self
|
43
50
|
end
|
44
51
|
end
|
data/lib/solargraph/gem_pins.rb
CHANGED
@@ -11,17 +11,9 @@ module Solargraph
|
|
11
11
|
include Logging
|
12
12
|
end
|
13
13
|
|
14
|
-
# @param gemspec [Gem::Specification]
|
15
|
-
# @return [Array<Pin::Base>]
|
16
|
-
def self.build_yard_pins(gemspec)
|
17
|
-
Yardoc.cache(gemspec) unless Yardoc.cached?(gemspec)
|
18
|
-
yardoc = Yardoc.load!(gemspec)
|
19
|
-
YardMap::Mapper.new(yardoc, gemspec).map
|
20
|
-
end
|
21
|
-
|
22
14
|
# @param pins [Array<Pin::Base>]
|
15
|
+
# @return [Array<Pin::Base>]
|
23
16
|
def self.combine_method_pins_by_path(pins)
|
24
|
-
# bad_pins = pins.select { |pin| pin.is_a?(Pin::Method) && pin.path == 'StringIO.open' && pin.source == :rbs }; raise "wtf: #{bad_pins}" if bad_pins.length > 1
|
25
17
|
method_pins, alias_pins = pins.partition { |pin| pin.class == Pin::Method }
|
26
18
|
by_path = method_pins.group_by(&:path)
|
27
19
|
by_path.transform_values! do |pins|
|
@@ -30,8 +22,12 @@ module Solargraph
|
|
30
22
|
by_path.values + alias_pins
|
31
23
|
end
|
32
24
|
|
25
|
+
# @param pins [Array<Pin::Method>]
|
26
|
+
# @return [Pin::Method, nil]
|
33
27
|
def self.combine_method_pins(*pins)
|
34
|
-
|
28
|
+
# @type [Pin::Method, nil]
|
29
|
+
combined_pin = nil
|
30
|
+
out = pins.reduce(combined_pin) do |memo, pin|
|
35
31
|
next pin if memo.nil?
|
36
32
|
if memo == pin && memo.source != :combined
|
37
33
|
# @todo we should track down situations where we are handled
|
@@ -45,8 +41,18 @@ module Solargraph
|
|
45
41
|
out
|
46
42
|
end
|
47
43
|
|
44
|
+
# @param yard_plugins [Array<String>] The names of YARD plugins to use.
|
45
|
+
# @param gemspec [Gem::Specification]
|
46
|
+
# @return [Array<Pin::Base>]
|
47
|
+
def self.build_yard_pins(yard_plugins, gemspec)
|
48
|
+
Yardoc.cache(yard_plugins, gemspec) unless Yardoc.cached?(gemspec)
|
49
|
+
yardoc = Yardoc.load!(gemspec)
|
50
|
+
YardMap::Mapper.new(yardoc, gemspec).map
|
51
|
+
end
|
52
|
+
|
48
53
|
# @param yard_pins [Array<Pin::Base>]
|
49
|
-
# @param
|
54
|
+
# @param rbs_pins [Array<Pin::Base>]
|
55
|
+
#
|
50
56
|
# @return [Array<Pin::Base>]
|
51
57
|
def self.combine(yard_pins, rbs_pins)
|
52
58
|
in_yard = Set.new
|
@@ -95,6 +95,7 @@ module Solargraph
|
|
95
95
|
nil
|
96
96
|
end
|
97
97
|
|
98
|
+
# @return [Hash{String => undefined}]
|
98
99
|
def options
|
99
100
|
@options ||= {}.freeze
|
100
101
|
end
|
@@ -118,6 +119,7 @@ module Solargraph
|
|
118
119
|
end
|
119
120
|
|
120
121
|
# @param library [Solargraph::Library]
|
122
|
+
# @param progress [Solargraph::LanguageServer::Progress, nil]
|
121
123
|
# @return [void]
|
122
124
|
def update progress
|
123
125
|
progress&.send(self)
|
@@ -72,10 +72,12 @@ module Solargraph
|
|
72
72
|
|
73
73
|
private
|
74
74
|
|
75
|
+
# @return [Hash, nil]
|
75
76
|
def next_message
|
76
77
|
cancel_message || next_priority
|
77
78
|
end
|
78
79
|
|
80
|
+
# @return [Hash, nil]
|
79
81
|
def cancel_message
|
80
82
|
# Handle cancellations first
|
81
83
|
idx = messages.find_index { |msg| msg['method'] == '$/cancelRequest' }
|
@@ -86,6 +88,7 @@ module Solargraph
|
|
86
88
|
msg
|
87
89
|
end
|
88
90
|
|
91
|
+
# @return [Hash, nil]
|
89
92
|
def next_priority
|
90
93
|
# Prioritize updates and version-dependent messages for performance
|
91
94
|
idx = messages.find_index do |msg|
|
@@ -299,6 +299,7 @@ module Solargraph
|
|
299
299
|
end
|
300
300
|
end
|
301
301
|
|
302
|
+
# @return [String]
|
302
303
|
def command_path
|
303
304
|
options['commandPath'] || 'solargraph'
|
304
305
|
end
|
@@ -716,7 +717,7 @@ module Solargraph
|
|
716
717
|
# A hash of client requests by ID. The host uses this to keep track of
|
717
718
|
# pending responses.
|
718
719
|
#
|
719
|
-
# @return [Hash{Integer => Solargraph::LanguageServer::
|
720
|
+
# @return [Hash{Integer => Solargraph::LanguageServer::Request}]
|
720
721
|
def requests
|
721
722
|
@requests ||= {}
|
722
723
|
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>]
|
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>]
|
24
26
|
def require_location
|
25
27
|
# @todo Terrible hack
|
26
28
|
lib = host.library_for(params['textDocument']['uri'])
|