solargraph 0.54.1 → 0.56.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/plugins.yml +2 -0
- data/.github/workflows/typecheck.yml +3 -1
- data/.gitignore +2 -0
- data/CHANGELOG.md +70 -0
- data/README.md +13 -3
- data/lib/solargraph/api_map/cache.rb +10 -1
- data/lib/solargraph/api_map/index.rb +175 -0
- data/lib/solargraph/api_map/store.rb +79 -126
- data/lib/solargraph/api_map.rb +247 -93
- data/lib/solargraph/bench.rb +17 -1
- data/lib/solargraph/complex_type/type_methods.rb +13 -1
- data/lib/solargraph/complex_type/unique_type.rb +118 -9
- data/lib/solargraph/complex_type.rb +48 -18
- data/lib/solargraph/convention/base.rb +3 -3
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +60 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +100 -0
- data/lib/solargraph/convention/struct_definition.rb +101 -0
- data/lib/solargraph/convention.rb +5 -3
- data/lib/solargraph/doc_map.rb +274 -56
- data/lib/solargraph/equality.rb +33 -0
- data/lib/solargraph/gem_pins.rb +53 -37
- data/lib/solargraph/language_server/host/message_worker.rb +31 -11
- data/lib/solargraph/language_server/host.rb +24 -13
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
- data/lib/solargraph/language_server/message/extended/document.rb +5 -2
- data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
- data/lib/solargraph/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
- data/lib/solargraph/library.rb +13 -11
- data/lib/solargraph/location.rb +28 -0
- data/lib/solargraph/logging.rb +1 -0
- data/lib/solargraph/parser/comment_ripper.rb +12 -6
- data/lib/solargraph/parser/flow_sensitive_typing.rb +227 -0
- data/lib/solargraph/parser/node_methods.rb +15 -1
- data/lib/solargraph/parser/node_processor.rb +3 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +16 -14
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +17 -23
- data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +23 -2
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +4 -3
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +29 -6
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -3
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +28 -16
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser.rb +1 -0
- data/lib/solargraph/pin/base.rb +326 -43
- data/lib/solargraph/pin/base_variable.rb +18 -10
- data/lib/solargraph/pin/block.rb +3 -3
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +77 -6
- data/lib/solargraph/pin/closure.rb +18 -1
- data/lib/solargraph/pin/common.rb +5 -0
- data/lib/solargraph/pin/delegated_method.rb +20 -1
- data/lib/solargraph/pin/documenting.rb +16 -0
- data/lib/solargraph/pin/keyword.rb +7 -2
- data/lib/solargraph/pin/local_variable.rb +15 -6
- data/lib/solargraph/pin/method.rb +172 -42
- data/lib/solargraph/pin/namespace.rb +17 -9
- data/lib/solargraph/pin/parameter.rb +61 -11
- data/lib/solargraph/pin/proxy_type.rb +12 -6
- data/lib/solargraph/pin/reference/override.rb +10 -6
- data/lib/solargraph/pin/reference/require.rb +2 -2
- data/lib/solargraph/pin/signature.rb +42 -0
- data/lib/solargraph/pin/singleton.rb +1 -1
- data/lib/solargraph/pin/symbol.rb +3 -2
- data/lib/solargraph/pin/until.rb +18 -0
- data/lib/solargraph/pin/while.rb +18 -0
- data/lib/solargraph/pin.rb +4 -1
- data/lib/solargraph/pin_cache.rb +185 -0
- data/lib/solargraph/position.rb +16 -0
- data/lib/solargraph/range.rb +16 -0
- data/lib/solargraph/rbs_map/conversions.rb +199 -66
- data/lib/solargraph/rbs_map/core_fills.rb +32 -16
- data/lib/solargraph/rbs_map/core_map.rb +34 -11
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +74 -16
- data/lib/solargraph/shell.rb +19 -18
- data/lib/solargraph/source/chain/array.rb +12 -8
- data/lib/solargraph/source/chain/block_symbol.rb +1 -1
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +62 -25
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +9 -3
- data/lib/solargraph/source/chain/head.rb +1 -1
- data/lib/solargraph/source/chain/if.rb +6 -1
- data/lib/solargraph/source/chain/link.rb +19 -5
- data/lib/solargraph/source/chain/literal.rb +27 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +106 -62
- data/lib/solargraph/source/cursor.rb +1 -11
- data/lib/solargraph/source/source_chainer.rb +2 -2
- data/lib/solargraph/source.rb +2 -1
- data/lib/solargraph/source_map/clip.rb +4 -2
- data/lib/solargraph/source_map/mapper.rb +9 -5
- data/lib/solargraph/source_map.rb +0 -17
- data/lib/solargraph/type_checker/checks.rb +4 -0
- data/lib/solargraph/type_checker.rb +41 -14
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +10 -10
- data/lib/solargraph/views/_namespace.erb +3 -3
- data/lib/solargraph/views/document.erb +10 -10
- data/lib/solargraph/workspace/config.rb +7 -3
- data/lib/solargraph/workspace.rb +16 -6
- data/lib/solargraph/yard_map/mapper/to_constant.rb +5 -2
- data/lib/solargraph/yard_map/mapper/to_method.rb +55 -15
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +5 -2
- data/lib/solargraph/yard_map/mapper.rb +5 -3
- data/lib/solargraph/yard_map/to_method.rb +4 -2
- data/lib/solargraph/yardoc.rb +6 -9
- data/lib/solargraph.rb +20 -1
- data/rbs/fills/tuple.rbs +150 -0
- data/rbs_collection.yaml +19 -0
- data/solargraph.gemspec +6 -5
- metadata +56 -29
- data/lib/solargraph/cache.rb +0 -77
|
@@ -3,20 +3,39 @@
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
module Pin
|
|
5
5
|
class Parameter < LocalVariable
|
|
6
|
-
# @return [Symbol]
|
|
6
|
+
# @return [::Symbol]
|
|
7
7
|
attr_reader :decl
|
|
8
8
|
|
|
9
9
|
# @return [String]
|
|
10
10
|
attr_reader :asgn_code
|
|
11
11
|
|
|
12
|
+
# allow this to be set to the method after the method itself has
|
|
13
|
+
# been created
|
|
14
|
+
attr_writer :closure
|
|
15
|
+
|
|
12
16
|
# @param decl [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg
|
|
13
17
|
# @param asgn_code [String, nil]
|
|
14
|
-
|
|
15
|
-
def initialize decl: :arg, asgn_code: nil, return_type: nil, **splat
|
|
18
|
+
def initialize decl: :arg, asgn_code: nil, **splat
|
|
16
19
|
super(**splat)
|
|
17
20
|
@asgn_code = asgn_code
|
|
18
21
|
@decl = decl
|
|
19
|
-
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def type_location
|
|
25
|
+
super || closure&.type_location
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def location
|
|
29
|
+
super || closure&.type_location
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def combine_with(other, attrs={})
|
|
33
|
+
new_attrs = {
|
|
34
|
+
decl: assert_same(other, :decl),
|
|
35
|
+
presence: choose(other, :presence),
|
|
36
|
+
asgn_code: choose(other, :asgn_code),
|
|
37
|
+
}.merge(attrs)
|
|
38
|
+
super(other, new_attrs)
|
|
20
39
|
end
|
|
21
40
|
|
|
22
41
|
def keyword?
|
|
@@ -27,6 +46,32 @@ module Solargraph
|
|
|
27
46
|
decl == :kwrestarg || (assignment && [:HASH, :hash].include?(assignment.type))
|
|
28
47
|
end
|
|
29
48
|
|
|
49
|
+
def needs_consistent_name?
|
|
50
|
+
keyword?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [String]
|
|
54
|
+
def arity_decl
|
|
55
|
+
name = (self.name || '(anon)')
|
|
56
|
+
type = (return_type&.to_rbs || 'untyped')
|
|
57
|
+
case decl
|
|
58
|
+
when :arg
|
|
59
|
+
""
|
|
60
|
+
when :optarg
|
|
61
|
+
"?"
|
|
62
|
+
when :kwarg
|
|
63
|
+
"#{name}:"
|
|
64
|
+
when :kwoptarg
|
|
65
|
+
"?#{name}:"
|
|
66
|
+
when :restarg
|
|
67
|
+
"*"
|
|
68
|
+
when :kwrestarg
|
|
69
|
+
"**"
|
|
70
|
+
else
|
|
71
|
+
"(unknown decl: #{decl})"
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
30
75
|
def arg?
|
|
31
76
|
decl == :arg
|
|
32
77
|
end
|
|
@@ -115,17 +160,21 @@ module Solargraph
|
|
|
115
160
|
closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
|
|
116
161
|
end
|
|
117
162
|
|
|
163
|
+
# @param atype [ComplexType]
|
|
164
|
+
# @param api_map [ApiMap]
|
|
165
|
+
def compatible_arg?(atype, api_map)
|
|
166
|
+
# make sure we get types from up the method
|
|
167
|
+
# inheritance chain if we don't have them on this pin
|
|
168
|
+
ptype = typify api_map
|
|
169
|
+
ptype.undefined? || ptype.can_assign?(api_map, atype) || ptype.generic?
|
|
170
|
+
end
|
|
171
|
+
|
|
118
172
|
def documentation
|
|
119
173
|
tag = param_tag
|
|
120
174
|
return '' if tag.nil? || tag.text.nil?
|
|
121
175
|
tag.text
|
|
122
176
|
end
|
|
123
177
|
|
|
124
|
-
def try_merge! pin
|
|
125
|
-
return false unless super && closure == pin.closure
|
|
126
|
-
true
|
|
127
|
-
end
|
|
128
|
-
|
|
129
178
|
private
|
|
130
179
|
|
|
131
180
|
# @return [YARD::Tags::Tag, nil]
|
|
@@ -140,8 +189,9 @@ module Solargraph
|
|
|
140
189
|
# @param api_map [ApiMap]
|
|
141
190
|
# @return [ComplexType]
|
|
142
191
|
def typify_block_param api_map
|
|
143
|
-
|
|
144
|
-
|
|
192
|
+
block_pin = closure
|
|
193
|
+
if block_pin.is_a?(Pin::Block) && block_pin.receiver
|
|
194
|
+
return block_pin.typify_parameters(api_map)[index]
|
|
145
195
|
end
|
|
146
196
|
ComplexType::UNDEFINED
|
|
147
197
|
end
|
|
@@ -4,24 +4,30 @@ module Solargraph
|
|
|
4
4
|
module Pin
|
|
5
5
|
class ProxyType < Base
|
|
6
6
|
# @param return_type [ComplexType]
|
|
7
|
-
def initialize return_type: ComplexType::UNDEFINED, **splat
|
|
7
|
+
def initialize return_type: ComplexType::UNDEFINED, binder: nil, **splat
|
|
8
8
|
super(**splat)
|
|
9
9
|
@return_type = return_type
|
|
10
|
+
@binder = binder if binder
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def context
|
|
13
14
|
@return_type
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
# @param
|
|
17
|
+
# @param context [ComplexType, ComplexType::UniqueType] Used as context for this pin
|
|
18
|
+
# @param closure [Pin::Namespace, nil] Used as the closure for this pin
|
|
19
|
+
# @param binder [ComplexType, ComplexType::UniqueType, nil]
|
|
17
20
|
# @return [ProxyType]
|
|
18
|
-
def self.anonymous
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
def self.anonymous context, closure: nil, binder: nil, **kwargs
|
|
22
|
+
unless closure
|
|
23
|
+
parts = context.namespace.split('::')
|
|
24
|
+
namespace = parts[0..-2].join('::').to_s
|
|
25
|
+
closure = Solargraph::Pin::Namespace.new(name: namespace, source: :proxy_type)
|
|
26
|
+
end
|
|
21
27
|
# name = parts.last.to_s
|
|
22
28
|
# ProxyType.new(nil, namespace, name, return_type)
|
|
23
29
|
ProxyType.new(
|
|
24
|
-
closure:
|
|
30
|
+
closure: closure, return_type: context, binder: binder || context, **kwargs
|
|
25
31
|
)
|
|
26
32
|
end
|
|
27
33
|
end
|
|
@@ -10,18 +10,22 @@ module Solargraph
|
|
|
10
10
|
# @return [::Array<Symbol>]
|
|
11
11
|
attr_reader :delete
|
|
12
12
|
|
|
13
|
-
def
|
|
14
|
-
|
|
13
|
+
def closure
|
|
14
|
+
nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize location, name, tags, delete = [], **splat
|
|
18
|
+
super(location: location, name: name, **splat)
|
|
15
19
|
@tags = tags
|
|
16
20
|
@delete = delete
|
|
17
21
|
end
|
|
18
22
|
|
|
19
|
-
def self.method_return name, *tags, delete: []
|
|
20
|
-
new(nil, name, [YARD::Tags::Tag.new('return', nil, tags)], delete)
|
|
23
|
+
def self.method_return name, *tags, delete: [], **splat
|
|
24
|
+
new(nil, name, [YARD::Tags::Tag.new('return', nil, tags)], delete, **splat)
|
|
21
25
|
end
|
|
22
26
|
|
|
23
|
-
def self.from_comment name, comment
|
|
24
|
-
new(nil, name, Solargraph::Source.parse_docstring(comment).to_docstring.tags)
|
|
27
|
+
def self.from_comment name, comment, **splat
|
|
28
|
+
new(nil, name, Solargraph::Source.parse_docstring(comment).to_docstring.tags, **splat)
|
|
25
29
|
end
|
|
26
30
|
end
|
|
27
31
|
end
|
|
@@ -4,9 +4,9 @@ module Solargraph
|
|
|
4
4
|
module Pin
|
|
5
5
|
class Reference
|
|
6
6
|
class Require < Reference
|
|
7
|
-
def initialize location, name
|
|
7
|
+
def initialize location, name, **splat
|
|
8
8
|
# super(location, '', name)
|
|
9
|
-
super(location: location, name: name)
|
|
9
|
+
super(location: location, name: name, closure: Pin::ROOT_PIN, **splat)
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
end
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
module Solargraph
|
|
2
2
|
module Pin
|
|
3
3
|
class Signature < Callable
|
|
4
|
+
# allow signature to be created before method pin, then set this
|
|
5
|
+
# to the method pin
|
|
6
|
+
attr_writer :closure
|
|
7
|
+
|
|
4
8
|
def initialize **splat
|
|
5
9
|
super(**splat)
|
|
6
10
|
end
|
|
@@ -12,6 +16,44 @@ module Solargraph
|
|
|
12
16
|
def identity
|
|
13
17
|
@identity ||= "signature#{object_id}"
|
|
14
18
|
end
|
|
19
|
+
|
|
20
|
+
attr_writer :closure
|
|
21
|
+
|
|
22
|
+
def dodgy_return_type_source?
|
|
23
|
+
super || closure&.dodgy_return_type_source?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def type_location
|
|
27
|
+
super || closure&.type_location
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def location
|
|
31
|
+
super || closure&.location
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def typify api_map
|
|
35
|
+
if return_type.defined?
|
|
36
|
+
qualified = return_type.qualify(api_map, closure.namespace)
|
|
37
|
+
logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
|
|
38
|
+
return qualified
|
|
39
|
+
end
|
|
40
|
+
return ComplexType::UNDEFINED if closure.nil?
|
|
41
|
+
return ComplexType::UNDEFINED unless closure.is_a?(Pin::Method)
|
|
42
|
+
method_stack = closure.rest_of_stack api_map
|
|
43
|
+
logger.debug { "Signature#typify(self=#{self}) - method_stack: #{method_stack}" }
|
|
44
|
+
method_stack.each do |pin|
|
|
45
|
+
sig = pin.signatures.find { |s| s.arity == self.arity }
|
|
46
|
+
next unless sig
|
|
47
|
+
unless sig.return_type.undefined?
|
|
48
|
+
qualified = sig.return_type.qualify(api_map, closure.namespace)
|
|
49
|
+
logger.debug { "Signature#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
|
|
50
|
+
return qualified
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
out = super
|
|
54
|
+
logger.debug { "Signature#typify(self=#{self}) => #{out}" }
|
|
55
|
+
out
|
|
56
|
+
end
|
|
15
57
|
end
|
|
16
58
|
end
|
|
17
59
|
end
|
|
@@ -5,8 +5,9 @@ module Solargraph
|
|
|
5
5
|
class Symbol < Base
|
|
6
6
|
# @param location [Solargraph::Location]
|
|
7
7
|
# @param name [String]
|
|
8
|
-
def initialize
|
|
9
|
-
|
|
8
|
+
def initialize(location, name, **kwargs)
|
|
9
|
+
# @sg-ignore "Unrecognized keyword argument kwargs to Solargraph::Pin::Base#initialize"
|
|
10
|
+
super(location: location, name: name, **kwargs)
|
|
10
11
|
# @name = name
|
|
11
12
|
# @location = location
|
|
12
13
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
class Until < Base
|
|
6
|
+
include Breakable
|
|
7
|
+
|
|
8
|
+
# @param receiver [Parser::AST::Node, nil]
|
|
9
|
+
# @param node [Parser::AST::Node, nil]
|
|
10
|
+
# @param context [ComplexType, nil]
|
|
11
|
+
# @param args [::Array<Parameter>]
|
|
12
|
+
def initialize node: nil, **splat
|
|
13
|
+
super(**splat)
|
|
14
|
+
@node = node
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
class While < Base
|
|
6
|
+
include Breakable
|
|
7
|
+
|
|
8
|
+
# @param receiver [Parser::AST::Node, nil]
|
|
9
|
+
# @param node [Parser::AST::Node, nil]
|
|
10
|
+
# @param context [ComplexType, nil]
|
|
11
|
+
# @param args [::Array<Parameter>]
|
|
12
|
+
def initialize node: nil, **splat
|
|
13
|
+
super(**splat)
|
|
14
|
+
@node = node
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/solargraph/pin.rb
CHANGED
|
@@ -34,8 +34,11 @@ module Solargraph
|
|
|
34
34
|
autoload :Singleton, 'solargraph/pin/singleton'
|
|
35
35
|
autoload :KeywordParam, 'solargraph/pin/keyword_param'
|
|
36
36
|
autoload :Search, 'solargraph/pin/search'
|
|
37
|
+
autoload :Breakable, 'solargraph/pin/breakable'
|
|
38
|
+
autoload :Until, 'solargraph/pin/until'
|
|
39
|
+
autoload :While, 'solargraph/pin/while'
|
|
37
40
|
autoload :Callable, 'solargraph/pin/callable'
|
|
38
41
|
|
|
39
|
-
ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil)
|
|
42
|
+
ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil, source: :pin_rb)
|
|
40
43
|
end
|
|
41
44
|
end
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
require 'rbs'
|
|
3
|
+
|
|
4
|
+
module Solargraph
|
|
5
|
+
module PinCache
|
|
6
|
+
class << self
|
|
7
|
+
include Logging
|
|
8
|
+
|
|
9
|
+
# The base directory where cached YARD documentation and serialized pins are serialized
|
|
10
|
+
#
|
|
11
|
+
# @return [String]
|
|
12
|
+
def base_dir
|
|
13
|
+
# The directory is not stored in a variable so it can be overridden
|
|
14
|
+
# in specs.
|
|
15
|
+
ENV['SOLARGRAPH_CACHE'] ||
|
|
16
|
+
(ENV['XDG_CACHE_HOME'] ? File.join(ENV['XDG_CACHE_HOME'], 'solargraph') : nil) ||
|
|
17
|
+
File.join(Dir.home, '.cache', 'solargraph')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# The working directory for the current Ruby, RBS, and Solargraph versions.
|
|
21
|
+
#
|
|
22
|
+
# @return [String]
|
|
23
|
+
def work_dir
|
|
24
|
+
# The directory is not stored in a variable so it can be overridden
|
|
25
|
+
# in specs.
|
|
26
|
+
File.join(base_dir, "ruby-#{RUBY_VERSION}", "rbs-#{RBS::VERSION}", "solargraph-#{Solargraph::VERSION}")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def yardoc_path gemspec
|
|
30
|
+
File.join(base_dir, "yard-#{YARD::VERSION}", "#{gemspec.name}-#{gemspec.version}.yardoc")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def stdlib_path
|
|
34
|
+
File.join(work_dir, 'stdlib')
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def stdlib_require_path require
|
|
38
|
+
File.join(stdlib_path, "#{require}.ser")
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def deserialize_stdlib_require require
|
|
42
|
+
load(stdlib_require_path(require))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def serialize_stdlib_require require, pins
|
|
46
|
+
save(stdlib_require_path(require), pins)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def core_path
|
|
50
|
+
File.join(work_dir, 'core.ser')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def deserialize_core
|
|
54
|
+
load(core_path)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def serialize_core pins
|
|
58
|
+
save(core_path, pins)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def yard_gem_path gemspec
|
|
62
|
+
File.join(work_dir, 'yard', "#{gemspec.name}-#{gemspec.version}.ser")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def deserialize_yard_gem(gemspec)
|
|
66
|
+
load(yard_gem_path(gemspec))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def serialize_yard_gem(gemspec, pins)
|
|
70
|
+
save(yard_gem_path(gemspec), pins)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def has_yard?(gemspec)
|
|
74
|
+
exist?(yard_gem_path(gemspec))
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def rbs_collection_path(gemspec, hash)
|
|
78
|
+
File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def rbs_collection_path_prefix(gemspec)
|
|
82
|
+
File.join(work_dir, 'rbs', "#{gemspec.name}-#{gemspec.version}-")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def deserialize_rbs_collection_gem(gemspec, hash)
|
|
86
|
+
load(rbs_collection_path(gemspec, hash))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def serialize_rbs_collection_gem(gemspec, hash, pins)
|
|
90
|
+
save(rbs_collection_path(gemspec, hash), pins)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def combined_path(gemspec, hash)
|
|
94
|
+
File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-#{hash || 0}.ser")
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def combined_path_prefix(gemspec)
|
|
98
|
+
File.join(work_dir, 'combined', "#{gemspec.name}-#{gemspec.version}-")
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def serialize_combined_gem(gemspec, hash, pins)
|
|
102
|
+
save(combined_path(gemspec, hash), pins)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def deserialize_combined_gem gemspec, hash
|
|
106
|
+
load(combined_path(gemspec, hash))
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def has_rbs_collection?(gemspec, hash)
|
|
110
|
+
exist?(rbs_collection_path(gemspec, hash))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def uncache_core
|
|
114
|
+
uncache(core_path)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def uncache_stdlib
|
|
118
|
+
uncache(stdlib_path)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def uncache_gem(gemspec, out: nil)
|
|
122
|
+
uncache(yardoc_path(gemspec), out: out)
|
|
123
|
+
uncache_by_prefix(rbs_collection_path_prefix(gemspec), out: out)
|
|
124
|
+
uncache(yard_gem_path(gemspec), out: out)
|
|
125
|
+
uncache_by_prefix(combined_path_prefix(gemspec), out: out)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# @return [void]
|
|
129
|
+
def clear
|
|
130
|
+
FileUtils.rm_rf base_dir, secure: true
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
# @param file [String]
|
|
136
|
+
# @return [Array<Solargraph::Pin::Base>, nil]
|
|
137
|
+
def load file
|
|
138
|
+
return nil unless File.file?(file)
|
|
139
|
+
Marshal.load(File.read(file, mode: 'rb'))
|
|
140
|
+
rescue StandardError => e
|
|
141
|
+
Solargraph.logger.warn "Failed to load cached file #{file}: [#{e.class}] #{e.message}"
|
|
142
|
+
FileUtils.rm_f file
|
|
143
|
+
nil
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def exist? *path
|
|
147
|
+
File.file? join(*path)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# @param path [Array<String>]
|
|
151
|
+
# @param pins [Array<Pin::Base>]
|
|
152
|
+
# @return [void]
|
|
153
|
+
def save file, pins
|
|
154
|
+
base = File.dirname(file)
|
|
155
|
+
FileUtils.mkdir_p base unless File.directory?(base)
|
|
156
|
+
ser = Marshal.dump(pins)
|
|
157
|
+
File.write file, ser, mode: 'wb'
|
|
158
|
+
logger.debug { "Cache#save: Saved #{pins.length} pins to #{file}" }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @return [void]
|
|
162
|
+
# @param path_segments [Array<String>]
|
|
163
|
+
def uncache *path_segments, out: nil
|
|
164
|
+
path = File.join(*path_segments)
|
|
165
|
+
if File.exist?(path)
|
|
166
|
+
FileUtils.rm_rf path, secure: true
|
|
167
|
+
out.puts "Clearing pin cache in #{path}" unless out.nil?
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# @return [void]
|
|
172
|
+
# @param path_segments [Array<String>]
|
|
173
|
+
def uncache_by_prefix *path_segments, out: nil
|
|
174
|
+
path = File.join(*path_segments)
|
|
175
|
+
glob = "#{path}*"
|
|
176
|
+
out.puts "Clearing pin cache in #{glob}" unless out.nil?
|
|
177
|
+
Dir.glob(glob).each do |file|
|
|
178
|
+
next unless File.file?(file)
|
|
179
|
+
FileUtils.rm_rf file, secure: true
|
|
180
|
+
out.puts "Clearing pin cache in #{file}" unless out.nil?
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
data/lib/solargraph/position.rb
CHANGED
|
@@ -4,6 +4,8 @@ module Solargraph
|
|
|
4
4
|
# The zero-based line and column numbers of a position in a string.
|
|
5
5
|
#
|
|
6
6
|
class Position
|
|
7
|
+
include Equality
|
|
8
|
+
|
|
7
9
|
# @return [Integer]
|
|
8
10
|
attr_reader :line
|
|
9
11
|
|
|
@@ -19,6 +21,20 @@ module Solargraph
|
|
|
19
21
|
@character = character
|
|
20
22
|
end
|
|
21
23
|
|
|
24
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
25
|
+
protected def equality_fields
|
|
26
|
+
[line, character]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def <=>(other)
|
|
30
|
+
return nil unless other.is_a?(Position)
|
|
31
|
+
if line == other.line
|
|
32
|
+
character <=> other.character
|
|
33
|
+
else
|
|
34
|
+
line <=> other.line
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
22
38
|
# Get a hash of the position. This representation is suitable for use in
|
|
23
39
|
# the language server protocol.
|
|
24
40
|
#
|
data/lib/solargraph/range.rb
CHANGED
|
@@ -4,6 +4,8 @@ module Solargraph
|
|
|
4
4
|
# A pair of Positions that compose a section of text in code.
|
|
5
5
|
#
|
|
6
6
|
class Range
|
|
7
|
+
include Equality
|
|
8
|
+
|
|
7
9
|
# @return [Position]
|
|
8
10
|
attr_reader :start
|
|
9
11
|
|
|
@@ -17,6 +19,20 @@ module Solargraph
|
|
|
17
19
|
@ending = ending
|
|
18
20
|
end
|
|
19
21
|
|
|
22
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
23
|
+
protected def equality_fields
|
|
24
|
+
[start, ending]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def <=>(other)
|
|
28
|
+
return nil unless other.is_a?(Range)
|
|
29
|
+
if start == other.start
|
|
30
|
+
ending <=> other.ending
|
|
31
|
+
else
|
|
32
|
+
start <=> other.start
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
20
36
|
# Get a hash of the range. This representation is suitable for use in
|
|
21
37
|
# the language server protocol.
|
|
22
38
|
#
|