solargraph 0.56.2 → 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 +42 -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 +1 -0
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +3 -1
- data/lib/solargraph/convention/data_definition.rb +2 -1
- data/lib/solargraph/convention/gemspec.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +1 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +3 -1
- data/lib/solargraph/convention/struct_definition.rb +36 -13
- data/lib/solargraph/convention.rb +31 -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 +8 -15
- 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 +1 -1
- data/lib/solargraph/parser/node_processor.rb +6 -2
- 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/if_node.rb +2 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +35 -14
- data/lib/solargraph/parser/region.rb +3 -0
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/pin/base.rb +50 -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 +8 -5
- 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 +7 -5
- 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 +0 -2
- data/lib/solargraph/workspace/require_paths.rb +98 -0
- data/lib/solargraph/workspace.rb +16 -48
- data/lib/solargraph/yard_map/mapper/to_method.rb +2 -2
- data/lib/solargraph/yardoc.rb +16 -3
- data/lib/solargraph.rb +2 -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 +123 -9
- data/lib/.rubocop.yml +0 -22
@@ -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)
|
@@ -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
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Solargraph
|
2
2
|
module Parser
|
3
|
-
|
3
|
+
module NodeMethods
|
4
4
|
module_function
|
5
5
|
|
6
6
|
# @abstract
|
@@ -74,7 +74,7 @@ module Solargraph
|
|
74
74
|
|
75
75
|
# @abstract
|
76
76
|
# @param node [Parser::AST::Node]
|
77
|
-
# @return [Hash{
|
77
|
+
# @return [Hash{Symbol => Source::Chain}]
|
78
78
|
def convert_hash node
|
79
79
|
raise NotImplementedError
|
80
80
|
end
|
@@ -9,7 +9,7 @@ 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
15
|
# Register a processor for a node type. You can register multiple processors for the same type.
|
@@ -17,12 +17,16 @@ module Solargraph
|
|
17
17
|
#
|
18
18
|
# @param type [Symbol]
|
19
19
|
# @param cls [Class<NodeProcessor::Base>]
|
20
|
-
# @return [Class<NodeProcessor::Base
|
20
|
+
# @return [Array<Class<NodeProcessor::Base>>]
|
21
21
|
def register type, cls
|
22
22
|
@@processors[type] ||= []
|
23
23
|
@@processors[type] << cls
|
24
24
|
end
|
25
25
|
|
26
|
+
# @param type [Symbol]
|
27
|
+
# @param cls [Class<NodeProcessor::Base>]
|
28
|
+
#
|
29
|
+
# @return [void]
|
26
30
|
def deregister type, cls
|
27
31
|
@@processors[type].delete(cls)
|
28
32
|
end
|
@@ -17,7 +17,7 @@ module Solargraph
|
|
17
17
|
module ClassMethods
|
18
18
|
# @param code [String]
|
19
19
|
# @param filename [String, nil]
|
20
|
-
# @return [Array(Parser::AST::Node, Hash{Integer =>
|
20
|
+
# @return [Array(Parser::AST::Node, Hash{Integer => Solargraph::Parser::Snippet})]
|
21
21
|
def parse_with_comments code, filename = nil
|
22
22
|
node = parse(code, filename)
|
23
23
|
comments = CommentRipper.new(code, filename, 0).parse
|
@@ -7,6 +7,7 @@ module Solargraph
|
|
7
7
|
#
|
8
8
|
class NodeChainer
|
9
9
|
include NodeMethods
|
10
|
+
|
10
11
|
Chain = Source::Chain
|
11
12
|
|
12
13
|
# @param node [Parser::AST::Node]
|
@@ -98,7 +99,8 @@ module Solargraph
|
|
98
99
|
elsif [:gvar, :gvasgn].include?(n.type)
|
99
100
|
result.push Chain::GlobalVariable.new(n.children[0].to_s)
|
100
101
|
elsif n.type == :or_asgn
|
101
|
-
|
102
|
+
new_node = n.updated(n.children[0].type, n.children[0].children + [n.children[1]])
|
103
|
+
result.concat generate_links new_node
|
102
104
|
elsif [:class, :module, :def, :defs].include?(n.type)
|
103
105
|
# @todo Undefined or what?
|
104
106
|
result.push Chain::UNDEFINED_CALL
|
@@ -120,7 +120,7 @@ module Solargraph
|
|
120
120
|
end
|
121
121
|
|
122
122
|
# @param node [Parser::AST::Node]
|
123
|
-
# @return [Hash{
|
123
|
+
# @return [Hash{Symbol => Chain}]
|
124
124
|
def convert_hash node
|
125
125
|
return {} unless Parser.is_ast_node?(node)
|
126
126
|
return convert_hash(node.children[0]) if node.type == :kwsplat
|
@@ -179,6 +179,7 @@ module Solargraph
|
|
179
179
|
node.children[1..-1].each { |child| result.concat call_nodes_from(child) }
|
180
180
|
elsif node.type == :send
|
181
181
|
result.push node
|
182
|
+
result.concat call_nodes_from(node.children.first)
|
182
183
|
node.children[2..-1].each { |child| result.concat call_nodes_from(child) }
|
183
184
|
elsif [:super, :zsuper].include?(node.type)
|
184
185
|
result.push node
|
@@ -232,6 +233,7 @@ module Solargraph
|
|
232
233
|
else
|
233
234
|
source.tree_at(position.line, position.column - 1)
|
234
235
|
end
|
236
|
+
# @type [AST::Node, nil]
|
235
237
|
prev = nil
|
236
238
|
tree.each do |node|
|
237
239
|
if node.type == :send
|
@@ -242,7 +244,7 @@ module Solargraph
|
|
242
244
|
if source.synchronized?
|
243
245
|
return node if source.code[0..offset-1] =~ /\(\s*\z/ && source.code[offset..-1] =~ /^\s*\)/
|
244
246
|
else
|
245
|
-
return node if source.code[0..offset-1] =~ /\([
|
247
|
+
return node if source.code[0..offset-1] =~ /\([^(]*\z/
|
246
248
|
end
|
247
249
|
end
|
248
250
|
end
|
@@ -19,7 +19,7 @@ module Solargraph
|
|
19
19
|
else
|
20
20
|
region.closure
|
21
21
|
end
|
22
|
-
|
22
|
+
block_pin = Solargraph::Pin::Block.new(
|
23
23
|
location: location,
|
24
24
|
closure: parent,
|
25
25
|
node: node,
|
@@ -28,7 +28,8 @@ module Solargraph
|
|
28
28
|
scope: region.scope || region.closure.context.scope,
|
29
29
|
source: :parser
|
30
30
|
)
|
31
|
-
|
31
|
+
pins.push block_pin
|
32
|
+
process_children region.update(closure: block_pin)
|
32
33
|
end
|
33
34
|
|
34
35
|
private
|
@@ -11,6 +11,8 @@ module Solargraph
|
|
11
11
|
process_children
|
12
12
|
|
13
13
|
position = get_node_start_position(node)
|
14
|
+
# @sg-ignore
|
15
|
+
# @type [Solargraph::Pin::Breakable, nil]
|
14
16
|
enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last
|
15
17
|
FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_if(node)
|
16
18
|
end
|
@@ -22,8 +22,11 @@ module Solargraph
|
|
22
22
|
# s(:int, 2),
|
23
23
|
# s(:int, 3)))
|
24
24
|
masgn = node
|
25
|
+
# @type [Parser::AST::Node]
|
25
26
|
mlhs = masgn.children.fetch(0)
|
27
|
+
# @type [Array<Parser::AST::Node>]
|
26
28
|
lhs_arr = mlhs.children
|
29
|
+
# @type [Parser::AST::Node]
|
27
30
|
mass_rhs = node.children.fetch(1)
|
28
31
|
|
29
32
|
# Get pins created for the mlhs node
|
@@ -8,32 +8,44 @@ module Solargraph
|
|
8
8
|
include ParserGem::NodeMethods
|
9
9
|
|
10
10
|
def process
|
11
|
+
# @sg-ignore Variable type could not be inferred for method_name
|
12
|
+
# @type [Symbol]
|
13
|
+
method_name = node.children[1]
|
14
|
+
# :nocov:
|
15
|
+
unless method_name.instance_of?(Symbol)
|
16
|
+
Solargraph.assert_or_log(:parser_method_name, "Expected method name to be a Symbol, got #{method_name.class} for node #{node.inspect}")
|
17
|
+
return process_children
|
18
|
+
end
|
19
|
+
# :nocov:
|
11
20
|
if node.children[0].nil?
|
12
|
-
if [:private, :public, :protected].include?(
|
21
|
+
if [:private, :public, :protected].include?(method_name)
|
13
22
|
process_visibility
|
14
|
-
elsif
|
23
|
+
elsif method_name == :module_function
|
15
24
|
process_module_function
|
16
|
-
elsif [:attr_reader, :attr_writer, :attr_accessor].include?(
|
25
|
+
elsif [:attr_reader, :attr_writer, :attr_accessor].include?(method_name)
|
17
26
|
process_attribute
|
18
|
-
elsif
|
27
|
+
elsif method_name == :include
|
19
28
|
process_include
|
20
|
-
elsif
|
29
|
+
elsif method_name == :extend
|
21
30
|
process_extend
|
22
|
-
elsif
|
31
|
+
elsif method_name == :prepend
|
23
32
|
process_prepend
|
24
|
-
elsif
|
33
|
+
elsif method_name == :require
|
25
34
|
process_require
|
26
|
-
elsif
|
35
|
+
elsif method_name == :autoload
|
27
36
|
process_autoload
|
28
|
-
elsif
|
37
|
+
elsif method_name == :private_constant
|
29
38
|
process_private_constant
|
30
|
-
|
39
|
+
# @sg-ignore
|
40
|
+
elsif method_name == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
|
31
41
|
process_alias_method
|
32
|
-
|
42
|
+
# @sg-ignore
|
43
|
+
elsif method_name == :private_class_method && node.children[2].is_a?(AST::Node)
|
33
44
|
# Processing a private class can potentially handle children on its own
|
34
45
|
return if process_private_class_method
|
35
46
|
end
|
36
|
-
|
47
|
+
# @sg-ignore
|
48
|
+
elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)'
|
37
49
|
pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser)
|
38
50
|
end
|
39
51
|
process_children
|
@@ -45,15 +57,24 @@ module Solargraph
|
|
45
57
|
def process_visibility
|
46
58
|
if (node.children.length > 2)
|
47
59
|
node.children[2..-1].each do |child|
|
60
|
+
# @sg-ignore Variable type could not be inferred for method_name
|
61
|
+
# @type [Symbol]
|
62
|
+
visibility = node.children[1]
|
63
|
+
# :nocov:
|
64
|
+
unless visibility.instance_of?(Symbol)
|
65
|
+
Solargraph.assert_or_log(:parser_visibility, "Expected visibility name to be a Symbol, got #{visibility.class} for node #{node.inspect}")
|
66
|
+
return process_children
|
67
|
+
end
|
68
|
+
# :nocov:
|
48
69
|
if child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
|
49
70
|
name = child.children[0].to_s
|
50
71
|
matches = pins.select{ |pin| pin.is_a?(Pin::Method) && pin.name == name && pin.namespace == region.closure.full_context.namespace && pin.context.scope == (region.scope || :instance)}
|
51
72
|
matches.each do |pin|
|
52
73
|
# @todo Smelly instance variable access
|
53
|
-
pin.instance_variable_set(:@visibility,
|
74
|
+
pin.instance_variable_set(:@visibility, visibility)
|
54
75
|
end
|
55
76
|
else
|
56
|
-
process_children region.update(visibility:
|
77
|
+
process_children region.update(visibility: visibility)
|
57
78
|
end
|
58
79
|
end
|
59
80
|
else
|
@@ -23,8 +23,10 @@ module Solargraph
|
|
23
23
|
|
24
24
|
# @param source [Source]
|
25
25
|
# @param namespace [String]
|
26
|
+
# @param closure [Pin::Closure, nil]
|
26
27
|
# @param scope [Symbol, nil]
|
27
28
|
# @param visibility [Symbol]
|
29
|
+
# @param lvars [Array<Symbol>]
|
28
30
|
def initialize source: Solargraph::Source.load_string(''), closure: nil,
|
29
31
|
scope: nil, visibility: :public, lvars: []
|
30
32
|
@source = source
|
@@ -45,6 +47,7 @@ module Solargraph
|
|
45
47
|
# @param closure [Pin::Closure, nil]
|
46
48
|
# @param scope [Symbol, nil]
|
47
49
|
# @param visibility [Symbol, nil]
|
50
|
+
# @param lvars [Array<Symbol>, nil]
|
48
51
|
# @return [Region]
|
49
52
|
def update closure: nil, scope: nil, visibility: nil, lvars: nil
|
50
53
|
Region.new(
|
data/lib/solargraph/pin/base.rb
CHANGED
@@ -13,10 +13,10 @@ module Solargraph
|
|
13
13
|
# @return [YARD::CodeObjects::Base]
|
14
14
|
attr_reader :code_object
|
15
15
|
|
16
|
-
# @return [Solargraph::Location]
|
16
|
+
# @return [Solargraph::Location, nil]
|
17
17
|
attr_reader :location
|
18
18
|
|
19
|
-
# @return [Solargraph::Location]
|
19
|
+
# @return [Solargraph::Location, nil]
|
20
20
|
attr_reader :type_location
|
21
21
|
|
22
22
|
# @return [String]
|
@@ -28,6 +28,11 @@ module Solargraph
|
|
28
28
|
# @return [::Symbol]
|
29
29
|
attr_accessor :source
|
30
30
|
|
31
|
+
# @type [::Numeric, nil] A priority for determining if pins should be combined or not
|
32
|
+
# A nil priority is considered the be the lowest. All code, yard & rbs pins have nil priority
|
33
|
+
# Between 2 pins, the one with the higher priority gets chosen. If the priorities are equal, they are combined.
|
34
|
+
attr_reader :combine_priority
|
35
|
+
|
31
36
|
def presence_certain?
|
32
37
|
true
|
33
38
|
end
|
@@ -40,7 +45,8 @@ module Solargraph
|
|
40
45
|
# @param source [Symbol, nil]
|
41
46
|
# @param docstring [YARD::Docstring, nil]
|
42
47
|
# @param directives [::Array<YARD::Tags::Directive>, nil]
|
43
|
-
|
48
|
+
# @param combine_priority [::Numeric, nil] See attr_reader for combine_priority
|
49
|
+
def initialize location: nil, type_location: nil, closure: nil, source: nil, name: '', comments: '', docstring: nil, directives: nil, combine_priority: nil
|
44
50
|
@location = location
|
45
51
|
@type_location = type_location
|
46
52
|
@closure = closure
|
@@ -50,6 +56,8 @@ module Solargraph
|
|
50
56
|
@identity = nil
|
51
57
|
@docstring = docstring
|
52
58
|
@directives = directives
|
59
|
+
@combine_priority = combine_priority
|
60
|
+
|
53
61
|
assert_source_provided
|
54
62
|
assert_location_provided
|
55
63
|
end
|
@@ -61,12 +69,22 @@ module Solargraph
|
|
61
69
|
Solargraph.assert_or_log(:best_location, "Neither location nor type_location provided - #{path} #{source} #{self.class}")
|
62
70
|
end
|
63
71
|
|
72
|
+
# @return [Pin::Closure, nil]
|
73
|
+
def closure
|
74
|
+
Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
|
75
|
+
# @type [Pin::Closure, nil]
|
76
|
+
@closure
|
77
|
+
end
|
78
|
+
|
64
79
|
# @param other [self]
|
65
|
-
# @param attrs [Hash{Symbol => Object}]
|
80
|
+
# @param attrs [Hash{::Symbol => Object}]
|
66
81
|
#
|
67
82
|
# @return [self]
|
68
83
|
def combine_with(other, attrs={})
|
69
84
|
raise "tried to combine #{other.class} with #{self.class}" unless other.class == self.class
|
85
|
+
priority_choice = choose_priority(other)
|
86
|
+
return priority_choice unless priority_choice.nil?
|
87
|
+
|
70
88
|
type_location = choose(other, :type_location)
|
71
89
|
location = choose(other, :location)
|
72
90
|
combined_name = combine_name(other)
|
@@ -79,6 +97,7 @@ module Solargraph
|
|
79
97
|
source: :combined,
|
80
98
|
docstring: choose(other, :docstring),
|
81
99
|
directives: combine_directives(other),
|
100
|
+
combine_priority: combine_priority
|
82
101
|
}.merge(attrs)
|
83
102
|
assert_same_macros(other)
|
84
103
|
logger.debug { "Base#combine_with(path=#{path}) - other.comments=#{other.comments.inspect}, self.comments = #{self.comments}" }
|
@@ -87,6 +106,25 @@ module Solargraph
|
|
87
106
|
out
|
88
107
|
end
|
89
108
|
|
109
|
+
# @param other [self]
|
110
|
+
# @return [self, nil] Returns either the pin chosen based on priority or nil
|
111
|
+
# A nil return means that the combination process must proceed
|
112
|
+
def choose_priority(other)
|
113
|
+
if combine_priority.nil? && !other.combine_priority.nil?
|
114
|
+
return other
|
115
|
+
elsif other.combine_priority.nil? && !combine_priority.nil?
|
116
|
+
return self
|
117
|
+
elsif !combine_priority.nil? && !other.combine_priority.nil?
|
118
|
+
if combine_priority > other.combine_priority
|
119
|
+
return self
|
120
|
+
elsif combine_priority < other.combine_priority
|
121
|
+
return other
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
|
90
128
|
# @param other [self]
|
91
129
|
# @param attr [::Symbol]
|
92
130
|
# @sg-ignore
|
@@ -98,7 +136,6 @@ module Solargraph
|
|
98
136
|
val2 = other.send(attr)
|
99
137
|
return val1 if val1 == val2
|
100
138
|
return val2 if val1.nil?
|
101
|
-
# @sg-ignore
|
102
139
|
val1.length > val2.length ? val1 : val2
|
103
140
|
end
|
104
141
|
|
@@ -188,7 +225,7 @@ module Solargraph
|
|
188
225
|
end
|
189
226
|
|
190
227
|
# @param other [self]
|
191
|
-
# @param attr [Symbol]
|
228
|
+
# @param attr [::Symbol]
|
192
229
|
# @sg-ignore
|
193
230
|
# @return [undefined]
|
194
231
|
def choose_node(other, attr)
|
@@ -237,7 +274,6 @@ module Solargraph
|
|
237
274
|
raise "Expected #{attr} on #{other} to be an Enumerable, got #{arr2.class}" unless arr2.is_a?(::Enumerable)
|
238
275
|
# @type arr2 [::Enumerable]
|
239
276
|
|
240
|
-
# @sg-ignore
|
241
277
|
# @type [undefined]
|
242
278
|
values1 = arr1.map(&block)
|
243
279
|
# @type [undefined]
|
@@ -269,7 +305,8 @@ module Solargraph
|
|
269
305
|
# @param other [self]
|
270
306
|
# @param attr [::Symbol]
|
271
307
|
#
|
272
|
-
# @
|
308
|
+
# @sg-ignore
|
309
|
+
# @return [undefined]
|
273
310
|
def assert_same(other, attr)
|
274
311
|
return false if other.nil?
|
275
312
|
val1 = send(attr)
|
@@ -300,6 +337,8 @@ module Solargraph
|
|
300
337
|
|
301
338
|
# @param other [self]
|
302
339
|
# @param attr [::Symbol]
|
340
|
+
#
|
341
|
+
# @sg-ignore
|
303
342
|
# @return [undefined]
|
304
343
|
def choose_pin_attr(other, attr)
|
305
344
|
# @type [Pin::Base, nil]
|
@@ -307,11 +346,14 @@ module Solargraph
|
|
307
346
|
# @type [Pin::Base, nil]
|
308
347
|
val2 = other.send(attr)
|
309
348
|
if val1.class != val2.class
|
349
|
+
# :nocov:
|
310
350
|
Solargraph.assert_or_log("combine_with_#{attr}_class".to_sym,
|
311
351
|
"Inconsistent #{attr.inspect} class values between \nself =#{inspect} and \nother=#{other.inspect}:\n\n self.#{attr} = #{val1.inspect}\nother.#{attr} = #{val2.inspect}")
|
312
352
|
return val1
|
353
|
+
# :nocov:
|
313
354
|
end
|
314
355
|
# arbitrary way of choosing a pin
|
356
|
+
# @sg-ignore Need _1 support
|
315
357
|
[val1, val2].compact.min_by { _1.best_location.to_s }
|
316
358
|
end
|
317
359
|
|
@@ -3,8 +3,8 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Pin
|
5
5
|
class BaseVariable < Base
|
6
|
-
include Solargraph::Parser::NodeMethods
|
7
6
|
# include Solargraph::Source::NodeMethods
|
7
|
+
include Solargraph::Parser::NodeMethods
|
8
8
|
|
9
9
|
# @return [Parser::AST::Node, nil]
|
10
10
|
attr_reader :assignment
|
@@ -43,7 +43,6 @@ module Solargraph
|
|
43
43
|
@return_type ||= generate_complex_type
|
44
44
|
end
|
45
45
|
|
46
|
-
# @sg-ignore
|
47
46
|
def nil_assignment?
|
48
47
|
# this will always be false - should it be return_type ==
|
49
48
|
# ComplexType::NIL or somesuch?
|
@@ -21,10 +21,13 @@ module Solargraph
|
|
21
21
|
@parameters = parameters
|
22
22
|
end
|
23
23
|
|
24
|
+
# @return [String]
|
24
25
|
def method_namespace
|
25
26
|
closure.namespace
|
26
27
|
end
|
27
28
|
|
29
|
+
# @param other [self]
|
30
|
+
# @return [Pin::Block, nil]
|
28
31
|
def combine_blocks(other)
|
29
32
|
if block.nil?
|
30
33
|
other.block
|
@@ -57,6 +60,8 @@ module Solargraph
|
|
57
60
|
[]
|
58
61
|
end
|
59
62
|
|
63
|
+
# @param other [self]
|
64
|
+
# @return [Array<Pin::Parameter>]
|
60
65
|
def choose_parameters(other)
|
61
66
|
raise "Trying to combine two pins with different arities - \nself =#{inspect}, \nother=#{other.inspect}, \n\n self.arity=#{self.arity}, \nother.arity=#{other.arity}" if other.arity != arity
|
62
67
|
parameters.zip(other.parameters).map do |param, other_param|
|
@@ -70,6 +75,7 @@ module Solargraph
|
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
78
|
+
# @return [Array<Pin::Parameter>]
|
73
79
|
def blockless_parameters
|
74
80
|
if parameters.last&.block?
|
75
81
|
parameters[0..-2]
|
@@ -78,6 +84,7 @@ module Solargraph
|
|
78
84
|
end
|
79
85
|
end
|
80
86
|
|
87
|
+
# @return [Array]
|
81
88
|
def arity
|
82
89
|
[generics, blockless_parameters.map(&:arity_decl), block&.arity]
|
83
90
|
end
|
@@ -125,6 +132,7 @@ module Solargraph
|
|
125
132
|
end
|
126
133
|
end
|
127
134
|
|
135
|
+
# @return [String]
|
128
136
|
def method_name
|
129
137
|
raise "closure was nil in #{self.inspect}" if closure.nil?
|
130
138
|
@method_name ||= closure.name
|
@@ -197,6 +205,7 @@ module Solargraph
|
|
197
205
|
true
|
198
206
|
end
|
199
207
|
|
208
|
+
# @return [Integer]
|
200
209
|
def mandatory_positional_param_count
|
201
210
|
parameters.count(&:arg?)
|
202
211
|
end
|
@@ -8,6 +8,7 @@ module Solargraph
|
|
8
8
|
|
9
9
|
# @param scope [::Symbol] :class or :instance
|
10
10
|
# @param generics [::Array<Pin::Parameter>, nil]
|
11
|
+
# @param generic_defaults [Hash{String => ComplexType}]
|
11
12
|
def initialize scope: :class, generics: nil, generic_defaults: {}, **splat
|
12
13
|
super(**splat)
|
13
14
|
@scope = scope
|
@@ -15,6 +16,7 @@ module Solargraph
|
|
15
16
|
@generic_defaults = generic_defaults
|
16
17
|
end
|
17
18
|
|
19
|
+
# @return [Hash{String => ComplexType}]
|
18
20
|
def generic_defaults
|
19
21
|
@generic_defaults ||= {}
|
20
22
|
end
|
@@ -3,12 +3,16 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Pin
|
5
5
|
module Common
|
6
|
+
# @!method source
|
7
|
+
# @abstract
|
8
|
+
# @return [Source, nil]
|
9
|
+
# @type @closure [Pin::Closure, nil]
|
10
|
+
|
6
11
|
# @return [Location]
|
7
12
|
attr_reader :location
|
8
13
|
|
14
|
+
# @sg-ignore Solargraph::Pin::Common#closure return type could not be inferred
|
9
15
|
# @return [Pin::Closure, nil]
|
10
|
-
attr_reader :closure
|
11
|
-
|
12
16
|
def closure
|
13
17
|
Solargraph.assert_or_log(:closure, "Closure not set on #{self.class} #{name.inspect} from #{source.inspect}") unless @closure
|
14
18
|
@closure
|