solargraph 0.56.0 → 0.56.2
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/CHANGELOG.md +14 -1
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +60 -0
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +89 -0
- data/lib/solargraph/convention/data_definition.rb +104 -0
- data/lib/solargraph/convention/gemspec.rb +2 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +1 -1
- data/lib/solargraph/convention/struct_definition.rb +60 -20
- data/lib/solargraph/convention.rb +1 -0
- data/lib/solargraph/doc_map.rb +8 -5
- data/lib/solargraph/library.rb +39 -15
- data/lib/solargraph/parser/node_processor/base.rb +9 -4
- data/lib/solargraph/parser/node_processor.rb +19 -7
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +1 -21
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +4 -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/sym_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/pin/base.rb +15 -0
- data/lib/solargraph/pin/method.rb +4 -2
- data/lib/solargraph/rbs_map/conversions.rb +41 -14
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +1 -1
- data/lib/solargraph/workspace.rb +8 -0
- 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 +1 -6
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +7 -7
- data/lib/solargraph/yardoc.rb +2 -0
- data/lib/solargraph.rb +13 -0
- data/solargraph.gemspec +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82754cd0869fed91a86a2bfb08ca0f54d6468f942620cddd3148bad99724ad88
|
4
|
+
data.tar.gz: 4e017a78936b0d24eaa6d5db7edcd01ea2b43d6cb365eb5b4892576a141ca2b7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 304fb86181925f916d7119da44b85a3753fc33d961da8a61c5525dbcb8d814a87baeeb9767d17b7ec6548c3ffe725bfda6eafbfd7ea75e8bdddf3f1a1a5c103b
|
7
|
+
data.tar.gz: 73d437e753be70628008f09a7846cba5e16fd47d045017b41c0b301d8a5b34ca04a45127a37c6eada4e61287944ca1af659ecab8df4681bab42a8ecc37d73bc4
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
|
+
## 0.56.2 - July 29, 2025
|
2
|
+
- Add support for Ruby Data.define (#970)
|
3
|
+
- Ensure that pin locations are always populated (#965)
|
4
|
+
- Improve struct support (#992)
|
5
|
+
- Include Rakefile, Gemfile, and gemspec files in config by default (#984)
|
6
|
+
- Use Open3 to cache gemspecs (#1000)
|
7
|
+
- Eager load node processors (#1002)
|
8
|
+
|
9
|
+
## 0.56.1 - July 13, 2025
|
10
|
+
- Library avoids blocking on pending yardoc caches (#990)
|
11
|
+
- DocMap checks for default Gemfile (#989)
|
12
|
+
- [Bug fix] Fixed an error in rbs/fills/tuple.rbs (#993)
|
13
|
+
|
1
14
|
## 0.56.0 - July 1, 2025
|
2
|
-
- [regression] Gem caching perf and logging fixes #983
|
15
|
+
- [regression] Gem caching perf and logging fixes #983
|
3
16
|
|
4
17
|
## 0.55.5 - July 1, 2025
|
5
18
|
- Flatten results of DocMap external bundle query (#981)
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module Convention
|
5
|
+
module DataDefinition
|
6
|
+
# A node wrapper for a Data definition via const assignment.
|
7
|
+
# @example
|
8
|
+
# MyData = Data.new(:bar, :baz) do
|
9
|
+
# def foo
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
class DataAssignmentNode < DataDefintionNode
|
13
|
+
class << self
|
14
|
+
# @example
|
15
|
+
# s(:casgn, nil, :Foo,
|
16
|
+
# s(:block,
|
17
|
+
# s(:send,
|
18
|
+
# s(:const, nil, :Data), :define,
|
19
|
+
# s(:sym, :bar),
|
20
|
+
# s(:sym, :baz)),
|
21
|
+
# s(:args),
|
22
|
+
# s(:def, :foo,
|
23
|
+
# s(:args),
|
24
|
+
# s(:send, nil, :bar))))
|
25
|
+
def match?(node)
|
26
|
+
return false unless node&.type == :casgn
|
27
|
+
return false if node.children[2].nil?
|
28
|
+
|
29
|
+
data_node = if node.children[2].type == :block
|
30
|
+
node.children[2].children[0]
|
31
|
+
else
|
32
|
+
node.children[2]
|
33
|
+
end
|
34
|
+
|
35
|
+
data_definition_node?(data_node)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def class_name
|
40
|
+
if node.children[0]
|
41
|
+
Parser::NodeMethods.unpack_name(node.children[0]) + "::#{node.children[1]}"
|
42
|
+
else
|
43
|
+
node.children[1].to_s
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# @return [Parser::AST::Node]
|
50
|
+
def data_node
|
51
|
+
if node.children[2].type == :block
|
52
|
+
node.children[2].children[0]
|
53
|
+
else
|
54
|
+
node.children[2]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module Convention
|
5
|
+
module DataDefinition
|
6
|
+
# A node wrapper for a Data definition via inheritance.
|
7
|
+
# @example
|
8
|
+
# class MyData < Data.new(:bar, :baz)
|
9
|
+
# def foo
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
class DataDefintionNode
|
13
|
+
class << self
|
14
|
+
# @example
|
15
|
+
# s(:class,
|
16
|
+
# s(:const, nil, :Foo),
|
17
|
+
# s(:send,
|
18
|
+
# s(:const, nil, :Data), :define,
|
19
|
+
# s(:sym, :bar),
|
20
|
+
# s(:sym, :baz)),
|
21
|
+
# s(:hash,
|
22
|
+
# s(:pair,
|
23
|
+
# s(:sym, :keyword_init),
|
24
|
+
# s(:true)))),
|
25
|
+
# s(:def, :foo,
|
26
|
+
# s(:args),
|
27
|
+
# s(:send, nil, :bar)))
|
28
|
+
def match?(node)
|
29
|
+
return false unless node&.type == :class
|
30
|
+
|
31
|
+
data_definition_node?(node.children[1])
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# @param data_node [Parser::AST::Node]
|
37
|
+
# @return [Boolean]
|
38
|
+
def data_definition_node?(data_node)
|
39
|
+
return false unless data_node.is_a?(::Parser::AST::Node)
|
40
|
+
return false unless data_node&.type == :send
|
41
|
+
return false unless data_node.children[0]&.type == :const
|
42
|
+
return false unless data_node.children[0].children[1] == :Data
|
43
|
+
return false unless data_node.children[1] == :define
|
44
|
+
|
45
|
+
true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [Parser::AST::Node]
|
50
|
+
def initialize(node)
|
51
|
+
@node = node
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [String]
|
55
|
+
def class_name
|
56
|
+
Parser::NodeMethods.unpack_name(node)
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [Array<Array(Parser::AST::Node, String)>]
|
60
|
+
def attributes
|
61
|
+
data_attribute_nodes.map do |data_def_param|
|
62
|
+
next unless data_def_param.type == :sym
|
63
|
+
[data_def_param, data_def_param.children[0].to_s]
|
64
|
+
end.compact
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Parser::AST::Node]
|
68
|
+
def body_node
|
69
|
+
node.children[2]
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# @return [Parser::AST::Node]
|
75
|
+
attr_reader :node
|
76
|
+
|
77
|
+
# @return [Parser::AST::Node]
|
78
|
+
def data_node
|
79
|
+
node.children[1]
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Array<Parser::AST::Node>]
|
83
|
+
def data_attribute_nodes
|
84
|
+
data_node.children[2..-1]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module Convention
|
5
|
+
module DataDefinition
|
6
|
+
autoload :DataDefintionNode, 'solargraph/convention/data_definition/data_definition_node'
|
7
|
+
autoload :DataAssignmentNode, 'solargraph/convention/data_definition/data_assignment_node'
|
8
|
+
|
9
|
+
module NodeProcessors
|
10
|
+
class DataNode < Parser::NodeProcessor::Base
|
11
|
+
# @return [Boolean] continue processing the next processor of the same node.
|
12
|
+
def process
|
13
|
+
return true if data_definition_node.nil?
|
14
|
+
|
15
|
+
loc = get_node_location(node)
|
16
|
+
nspin = Solargraph::Pin::Namespace.new(
|
17
|
+
type: :class,
|
18
|
+
location: loc,
|
19
|
+
closure: region.closure,
|
20
|
+
name: data_definition_node.class_name,
|
21
|
+
comments: comments_for(node),
|
22
|
+
visibility: :public,
|
23
|
+
gates: region.closure.gates.freeze
|
24
|
+
)
|
25
|
+
pins.push nspin
|
26
|
+
|
27
|
+
# define initialize method
|
28
|
+
initialize_method_pin = Pin::Method.new(
|
29
|
+
name: 'initialize',
|
30
|
+
parameters: [],
|
31
|
+
scope: :instance,
|
32
|
+
location: get_node_location(node),
|
33
|
+
closure: nspin,
|
34
|
+
visibility: :private,
|
35
|
+
comments: comments_for(node)
|
36
|
+
)
|
37
|
+
|
38
|
+
# TODO: Support both arg and kwarg initializers for Data.define
|
39
|
+
# Solargraph::SourceMap::Clip#complete_keyword_parameters does not seem to currently take into account [Pin::Method#signatures] hence we only one for :kwarg
|
40
|
+
pins.push initialize_method_pin
|
41
|
+
|
42
|
+
data_definition_node.attributes.map do |attribute_node, attribute_name|
|
43
|
+
initialize_method_pin.parameters.push(
|
44
|
+
Pin::Parameter.new(
|
45
|
+
name: attribute_name,
|
46
|
+
decl: :kwarg,
|
47
|
+
location: get_node_location(attribute_node),
|
48
|
+
closure: initialize_method_pin
|
49
|
+
)
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
53
|
+
# define attribute readers and instance variables
|
54
|
+
data_definition_node.attributes.each do |attribute_node, attribute_name|
|
55
|
+
name = attribute_name.to_s
|
56
|
+
method_pin = Pin::Method.new(
|
57
|
+
name: name,
|
58
|
+
parameters: [],
|
59
|
+
scope: :instance,
|
60
|
+
location: get_node_location(attribute_node),
|
61
|
+
closure: nspin,
|
62
|
+
comments: attribute_comments(attribute_node, attribute_name),
|
63
|
+
visibility: :public
|
64
|
+
)
|
65
|
+
|
66
|
+
pins.push method_pin
|
67
|
+
|
68
|
+
pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
|
69
|
+
closure: method_pin,
|
70
|
+
location: get_node_location(attribute_node),
|
71
|
+
comments: attribute_comments(attribute_node, attribute_name))
|
72
|
+
end
|
73
|
+
|
74
|
+
process_children region.update(closure: nspin, visibility: :public)
|
75
|
+
|
76
|
+
false
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# @return [DataDefintionNode, nil]
|
82
|
+
def data_definition_node
|
83
|
+
@data_definition_node ||= if DataDefintionNode.match?(node)
|
84
|
+
DataDefintionNode.new(node)
|
85
|
+
elsif DataAssignmentNode.match?(node)
|
86
|
+
DataAssignmentNode.new(node)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# @param attribute_node [Parser::AST::Node]
|
91
|
+
# @return [String, nil]
|
92
|
+
def attribute_comments(attribute_node, attribute_name)
|
93
|
+
data_comments = comments_for(attribute_node)
|
94
|
+
return if data_comments.nil? || data_comments.empty?
|
95
|
+
|
96
|
+
data_comments.split("\n").find do |row|
|
97
|
+
row.include?(attribute_name)
|
98
|
+
end&.gsub('@param', '@return')&.gsub(attribute_name, '')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -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,7 +18,7 @@ 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
23
|
gates: region.closure.gates.freeze
|
23
24
|
)
|
@@ -31,7 +32,7 @@ module Solargraph
|
|
31
32
|
location: get_node_location(node),
|
32
33
|
closure: nspin,
|
33
34
|
visibility: :private,
|
34
|
-
|
35
|
+
docstring: docstring
|
35
36
|
)
|
36
37
|
|
37
38
|
pins.push initialize_method_pin
|
@@ -50,49 +51,88 @@ module Solargraph
|
|
50
51
|
# define attribute accessors and instance variables
|
51
52
|
struct_definition_node.attributes.each do |attribute_node, attribute_name|
|
52
53
|
[attribute_name, "#{attribute_name}="].each do |name|
|
54
|
+
docs = docstring.tags.find { |t| t.tag_name == 'param' && t.name == attribute_name }
|
55
|
+
|
53
56
|
method_pin = Pin::Method.new(
|
54
57
|
name: name,
|
55
58
|
parameters: [],
|
56
59
|
scope: :instance,
|
57
60
|
location: get_node_location(attribute_node),
|
58
61
|
closure: nspin,
|
59
|
-
|
62
|
+
# even assignments return the value
|
63
|
+
comments: attribute_comment(docs, false),
|
60
64
|
visibility: :public
|
61
65
|
)
|
62
66
|
|
63
|
-
|
67
|
+
if name.end_with?('=')
|
68
|
+
method_pin.parameters << Pin::Parameter.new(
|
69
|
+
name: attribute_name,
|
70
|
+
location: get_node_location(attribute_node),
|
71
|
+
closure: nspin,
|
72
|
+
comments: attribute_comment(docs, true)
|
73
|
+
)
|
64
74
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
75
|
+
pins.push Pin::InstanceVariable.new(name: "@#{attribute_name}",
|
76
|
+
closure: method_pin,
|
77
|
+
location: get_node_location(attribute_node),
|
78
|
+
comments: attribute_comment(docs, false))
|
79
|
+
end
|
80
|
+
|
81
|
+
pins.push method_pin
|
70
82
|
end
|
71
83
|
end
|
72
84
|
|
73
85
|
process_children region.update(closure: nspin, visibility: :public)
|
86
|
+
false
|
74
87
|
end
|
75
88
|
|
76
89
|
private
|
77
90
|
|
78
91
|
# @return [StructDefintionNode, nil]
|
79
92
|
def struct_definition_node
|
80
|
-
@struct_definition_node ||= if StructDefintionNode.
|
93
|
+
@struct_definition_node ||= if StructDefintionNode.match?(node)
|
81
94
|
StructDefintionNode.new(node)
|
82
|
-
elsif StructAssignmentNode.
|
95
|
+
elsif StructAssignmentNode.match?(node)
|
83
96
|
StructAssignmentNode.new(node)
|
84
97
|
end
|
85
98
|
end
|
86
99
|
|
87
|
-
#
|
88
|
-
# @return [
|
89
|
-
def
|
90
|
-
|
91
|
-
|
100
|
+
# Gets/generates the relevant docstring for this struct & it's attributes
|
101
|
+
# @return [YARD::Docstring]
|
102
|
+
def docstring
|
103
|
+
@docstring ||= parse_comments
|
104
|
+
end
|
105
|
+
|
106
|
+
# Parses any relevant comments for a struct int a yard docstring
|
107
|
+
# @return [YARD::Docstring]
|
108
|
+
def parse_comments
|
109
|
+
struct_comments = comments_for(node) || ''
|
110
|
+
struct_definition_node.attributes.each do |attr_node, attr_name|
|
111
|
+
comment = comments_for(attr_node)
|
112
|
+
next if comment.nil?
|
113
|
+
|
114
|
+
# We should support specific comments for an attribute, and that can be either a @return on an @param
|
115
|
+
# But since we merge into the struct_comments, then we should interpret either as a param
|
116
|
+
comment = '@param ' + attr_name + comment[7..] if comment.start_with?('@return')
|
117
|
+
|
118
|
+
struct_comments += "\n#{comment}"
|
119
|
+
end
|
120
|
+
|
121
|
+
Solargraph::Source.parse_docstring(struct_comments).to_docstring
|
122
|
+
end
|
123
|
+
|
124
|
+
# @param tag [YARD::Tags::Tag, nil] The param tag for this attribute. If nil, this method is a no-op
|
125
|
+
# @param for_setter [Boolean] If true, will return a @param tag instead of a @return tag
|
126
|
+
def attribute_comment(tag, for_setter)
|
127
|
+
return "" if tag.nil?
|
128
|
+
|
129
|
+
suffix = "[#{tag.types&.join(',') || 'undefined'}] #{tag.text}"
|
92
130
|
|
93
|
-
|
94
|
-
|
95
|
-
|
131
|
+
if for_setter
|
132
|
+
"@param #{tag.name} #{suffix}"
|
133
|
+
else
|
134
|
+
"@return #{suffix}"
|
135
|
+
end
|
96
136
|
end
|
97
137
|
end
|
98
138
|
end
|
@@ -11,6 +11,7 @@ module Solargraph
|
|
11
11
|
autoload :Gemspec, 'solargraph/convention/gemspec'
|
12
12
|
autoload :Rakefile, 'solargraph/convention/rakefile'
|
13
13
|
autoload :StructDefinition, 'solargraph/convention/struct_definition'
|
14
|
+
autoload :DataDefinition, 'solargraph/convention/data_definition'
|
14
15
|
|
15
16
|
# @type [Set<Convention::Base>]
|
16
17
|
@@conventions = Set.new
|
data/lib/solargraph/doc_map.rb
CHANGED
@@ -21,8 +21,9 @@ module Solargraph
|
|
21
21
|
|
22
22
|
# @return [Array<Gem::Specification>]
|
23
23
|
def uncached_gemspecs
|
24
|
-
(
|
25
|
-
|
24
|
+
uncached_yard_gemspecs.concat(uncached_rbs_collection_gemspecs)
|
25
|
+
.sort
|
26
|
+
.uniq { |gemspec| "#{gemspec.name}:#{gemspec.version}" }
|
26
27
|
end
|
27
28
|
|
28
29
|
# @return [Array<Gem::Specification>]
|
@@ -355,7 +356,10 @@ module Solargraph
|
|
355
356
|
end
|
356
357
|
|
357
358
|
def gemspecs_required_from_bundler
|
358
|
-
|
359
|
+
# @todo Handle projects with custom Bundler/Gemfile setups
|
360
|
+
return unless workspace.gemfile?
|
361
|
+
|
362
|
+
if workspace.gemfile? && Bundler.definition&.lockfile&.to_s&.start_with?(workspace.directory)
|
359
363
|
# Find only the gems bundler is now using
|
360
364
|
Bundler.definition.locked_gems.specs.flat_map do |lazy_spec|
|
361
365
|
logger.info "Handling #{lazy_spec.name}:#{lazy_spec.version}"
|
@@ -396,8 +400,7 @@ module Solargraph
|
|
396
400
|
next specs
|
397
401
|
end.compact
|
398
402
|
else
|
399
|
-
Solargraph.logger.warn e
|
400
|
-
raise BundleNotFoundError, "Failed to load gems from bundle at #{workspace&.directory}"
|
403
|
+
Solargraph.logger.warn "Failed to load gems from bundle at #{workspace&.directory}: #{e}"
|
401
404
|
end
|
402
405
|
end
|
403
406
|
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.
|
@@ -588,29 +589,52 @@ module Solargraph
|
|
588
589
|
# @return [void]
|
589
590
|
def cache_next_gemspec
|
590
591
|
return if @cache_progress
|
591
|
-
|
592
|
-
|
592
|
+
|
593
|
+
spec = cacheable_specs.first
|
593
594
|
return end_cache_progress unless spec
|
594
595
|
|
595
596
|
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
|
597
|
+
|
598
|
+
if Yardoc.processing?(spec)
|
599
|
+
logger.info "Enqueuing cache of #{spec.name} #{spec.version} (already being processed)"
|
600
|
+
queued_gemspec_cache.push(spec)
|
601
|
+
return if pending - queued_gemspec_cache.length < 1
|
602
|
+
|
609
603
|
catalog
|
610
604
|
sync_catalog
|
605
|
+
else
|
606
|
+
logger.info "Caching #{spec.name} #{spec.version}"
|
607
|
+
Thread.new do
|
608
|
+
report_cache_progress spec.name, pending
|
609
|
+
_o, e, s = Open3.capture3(workspace.command_path, 'cache', spec.name, spec.version.to_s)
|
610
|
+
if s.success?
|
611
|
+
logger.info "Cached #{spec.name} #{spec.version}"
|
612
|
+
else
|
613
|
+
cache_errors.add spec
|
614
|
+
logger.warn "Error caching gemspec #{spec.name} #{spec.version}"
|
615
|
+
logger.warn e
|
616
|
+
end
|
617
|
+
end_cache_progress
|
618
|
+
catalog
|
619
|
+
sync_catalog
|
620
|
+
end
|
611
621
|
end
|
612
622
|
end
|
613
623
|
|
624
|
+
def cacheable_specs
|
625
|
+
cacheable = api_map.uncached_yard_gemspecs +
|
626
|
+
api_map.uncached_rbs_collection_gemspecs -
|
627
|
+
queued_gemspec_cache -
|
628
|
+
cache_errors.to_a
|
629
|
+
return cacheable unless cacheable.empty?
|
630
|
+
|
631
|
+
queued_gemspec_cache
|
632
|
+
end
|
633
|
+
|
634
|
+
def queued_gemspec_cache
|
635
|
+
@queued_gemspec_cache ||= []
|
636
|
+
end
|
637
|
+
|
614
638
|
# @param gem_name [String]
|
615
639
|
# @param pending [Integer]
|
616
640
|
# @return [void]
|
@@ -30,9 +30,12 @@ module Solargraph
|
|
30
30
|
|
31
31
|
# Subclasses should override this method to generate new pins.
|
32
32
|
#
|
33
|
-
# @return [
|
33
|
+
# @return [Boolean] continue processing the next processor of the same node type.
|
34
|
+
# @return [void] In case there is only one processor registered for the node type, it can be void.
|
34
35
|
def process
|
35
36
|
process_children
|
37
|
+
|
38
|
+
true
|
36
39
|
end
|
37
40
|
|
38
41
|
private
|
@@ -64,7 +67,9 @@ module Solargraph
|
|
64
67
|
# @param position [Solargraph::Position]
|
65
68
|
# @return [Pin::Closure, nil]
|
66
69
|
def named_path_pin position
|
67
|
-
pins.select
|
70
|
+
pins.select do |pin|
|
71
|
+
pin.is_a?(Pin::Closure) && pin.path && !pin.path.empty? && pin.location.range.contain?(position)
|
72
|
+
end.last
|
68
73
|
end
|
69
74
|
|
70
75
|
# @todo Candidate for deprecation
|
@@ -72,14 +77,14 @@ module Solargraph
|
|
72
77
|
# @return [Pin::Closure, nil]
|
73
78
|
def block_pin position
|
74
79
|
# @todo determine if this can return a Pin::Block
|
75
|
-
pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
|
80
|
+
pins.select { |pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position) }.last
|
76
81
|
end
|
77
82
|
|
78
83
|
# @todo Candidate for deprecation
|
79
84
|
# @param position [Solargraph::Position]
|
80
85
|
# @return [Pin::Closure, nil]
|
81
86
|
def closure_pin position
|
82
|
-
pins.select{|pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position)}.last
|
87
|
+
pins.select { |pin| pin.is_a?(Pin::Closure) && pin.location.range.contain?(position) }.last
|
83
88
|
end
|
84
89
|
end
|
85
90
|
end
|
@@ -9,16 +9,22 @@ module Solargraph
|
|
9
9
|
autoload :Base, 'solargraph/parser/node_processor/base'
|
10
10
|
|
11
11
|
class << self
|
12
|
-
# @type [Hash
|
12
|
+
# @type [Hash<Symbol, Array<Class<NodeProcessor::Base>>>]
|
13
13
|
@@processors ||= {}
|
14
14
|
|
15
|
-
# Register a processor for a node type.
|
15
|
+
# Register a processor for a node type. You can register multiple processors for the same type.
|
16
|
+
# If a node processor returns true, it will skip the next processor of the same node type.
|
16
17
|
#
|
17
18
|
# @param type [Symbol]
|
18
19
|
# @param cls [Class<NodeProcessor::Base>]
|
19
20
|
# @return [Class<NodeProcessor::Base>]
|
20
21
|
def register type, cls
|
21
|
-
@@processors[type]
|
22
|
+
@@processors[type] ||= []
|
23
|
+
@@processors[type] << cls
|
24
|
+
end
|
25
|
+
|
26
|
+
def deregister type, cls
|
27
|
+
@@processors[type].delete(cls)
|
22
28
|
end
|
23
29
|
end
|
24
30
|
|
@@ -36,10 +42,16 @@ module Solargraph
|
|
36
42
|
)
|
37
43
|
end
|
38
44
|
return [pins, locals] unless Parser.is_ast_node?(node)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
node_processor_classes = @@processors[node.type] || [NodeProcessor::Base]
|
46
|
+
|
47
|
+
node_processor_classes.each do |klass|
|
48
|
+
processor = klass.new(node, region, pins, locals)
|
49
|
+
process_next = processor.process
|
50
|
+
|
51
|
+
break unless process_next
|
52
|
+
end
|
53
|
+
|
54
|
+
[pins, locals]
|
43
55
|
end
|
44
56
|
end
|
45
57
|
end
|