solargraph 0.57.0 → 0.58.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitattributes +2 -0
- data/.github/workflows/linting.yml +4 -2
- data/.github/workflows/plugins.yml +61 -27
- data/.github/workflows/rspec.yml +19 -4
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +90 -1438
- data/CHANGELOG.md +30 -0
- data/Rakefile +1 -1
- data/bin/solargraph +3 -0
- data/lib/solargraph/api_map/constants.rb +107 -46
- data/lib/solargraph/api_map/index.rb +32 -8
- data/lib/solargraph/api_map/source_to_yard.rb +5 -2
- data/lib/solargraph/api_map/store.rb +22 -12
- data/lib/solargraph/api_map.rb +27 -33
- data/lib/solargraph/complex_type/type_methods.rb +5 -0
- data/lib/solargraph/complex_type/unique_type.rb +12 -5
- data/lib/solargraph/complex_type.rb +19 -2
- data/lib/solargraph/convention/active_support_concern.rb +1 -1
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +1 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -2
- data/lib/solargraph/doc_map.rb +9 -6
- data/lib/solargraph/environ.rb +1 -1
- data/lib/solargraph/equality.rb +1 -0
- data/lib/solargraph/gem_pins.rb +4 -0
- data/lib/solargraph/language_server/host.rb +10 -4
- data/lib/solargraph/language_server/message/text_document/definition.rb +2 -2
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +1 -1
- data/lib/solargraph/language_server/progress.rb +1 -1
- data/lib/solargraph/language_server/request.rb +3 -1
- data/lib/solargraph/library.rb +3 -3
- data/lib/solargraph/location.rb +1 -0
- data/lib/solargraph/page.rb +0 -1
- data/lib/solargraph/parser/flow_sensitive_typing.rb +1 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +2 -12
- data/lib/solargraph/parser/parser_gem/node_methods.rb +1 -14
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +64 -8
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +12 -3
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +4 -5
- data/lib/solargraph/pin/base.rb +29 -8
- data/lib/solargraph/pin/base_variable.rb +5 -3
- data/lib/solargraph/pin/block.rb +3 -2
- data/lib/solargraph/pin/callable.rb +6 -2
- data/lib/solargraph/pin/closure.rb +3 -7
- data/lib/solargraph/pin/delegated_method.rb +0 -1
- data/lib/solargraph/pin/local_variable.rb +0 -4
- data/lib/solargraph/pin/method.rb +20 -4
- data/lib/solargraph/pin/parameter.rb +6 -2
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference.rb +2 -11
- data/lib/solargraph/pin/search.rb +3 -0
- data/lib/solargraph/pin_cache.rb +5 -5
- data/lib/solargraph/position.rb +1 -0
- data/lib/solargraph/range.rb +4 -0
- data/lib/solargraph/rbs_map/conversions.rb +22 -1
- data/lib/solargraph/rbs_map/core_fills.rb +18 -0
- data/lib/solargraph/rbs_map/core_map.rb +11 -7
- data/lib/solargraph/rbs_map.rb +2 -2
- data/lib/solargraph/shell.rb +82 -1
- data/lib/solargraph/source/chain/call.rb +7 -3
- data/lib/solargraph/source/chain/constant.rb +3 -66
- data/lib/solargraph/source/chain/if.rb +1 -1
- data/lib/solargraph/source/chain/link.rb +1 -1
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain.rb +2 -0
- data/lib/solargraph/source/encoding_fixes.rb +23 -23
- data/lib/solargraph/source.rb +1 -1
- data/lib/solargraph/source_map/clip.rb +17 -25
- data/lib/solargraph/source_map/mapper.rb +0 -2
- data/lib/solargraph/source_map.rb +8 -3
- data/lib/solargraph/type_checker/rules.rb +23 -9
- data/lib/solargraph/type_checker.rb +133 -71
- data/lib/solargraph/version.rb +5 -5
- data/lib/solargraph/workspace/config.rb +21 -3
- data/lib/solargraph/workspace/require_paths.rb +0 -1
- data/lib/solargraph/workspace.rb +14 -19
- data/lib/solargraph/yard_map/mapper/to_method.rb +2 -1
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/to_method.rb +2 -1
- data/lib/solargraph/yardoc.rb +27 -4
- data/rbs/fills/bundler/0/bundler.rbs +4271 -0
- data/rbs/fills/open3/0/open3.rbs +172 -0
- data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
- data/rbs/fills/rubygems/0/errors.rbs +364 -0
- data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
- data/rbs/fills/rubygems/0/specification.rbs +1753 -0
- data/rbs_collection.yaml +4 -4
- data/sig/shims/ast/0/node.rbs +5 -0
- data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
- data/sig/shims/ast/2.4/ast.rbs +73 -0
- data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
- data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
- data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
- data/solargraph.gemspec +15 -4
- metadata +67 -12
- data/lib/solargraph/parser/node_methods.rb +0 -97
- /data/rbs/fills/{tuple.rbs → tuple/tuple.rbs} +0 -0
|
@@ -2,15 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require 'prism'
|
|
4
4
|
|
|
5
|
-
# Awaiting ability to use a version containing https://github.com/whitequark/parser/pull/1076
|
|
6
|
-
#
|
|
7
|
-
# @!parse
|
|
8
|
-
# class ::Parser::Base < ::Parser::Builder
|
|
9
|
-
# # @return [Integer]
|
|
10
|
-
# def version; end
|
|
11
|
-
# end
|
|
12
|
-
# class ::Parser::CurrentRuby < ::Parser::Base; end
|
|
13
|
-
|
|
14
5
|
module Solargraph
|
|
15
6
|
module Parser
|
|
16
7
|
module ParserGem
|
|
@@ -84,6 +75,7 @@ module Solargraph
|
|
|
84
75
|
# @param top [AST::Node]
|
|
85
76
|
# @return [Array<AST::Node>]
|
|
86
77
|
def inner_node_references name, top
|
|
78
|
+
# @type [Array<AST::Node>]
|
|
87
79
|
result = []
|
|
88
80
|
if top.is_a?(AST::Node) && top.to_s.include?(":#{name}")
|
|
89
81
|
result.push top if top.children.any? { |c| c.to_s == name }
|
|
@@ -137,9 +129,7 @@ module Solargraph
|
|
|
137
129
|
def string_ranges node
|
|
138
130
|
return [] unless is_ast_node?(node)
|
|
139
131
|
result = []
|
|
140
|
-
if node.type == :str
|
|
141
|
-
result.push Range.from_node(node)
|
|
142
|
-
end
|
|
132
|
+
result.push Range.from_node(node) if node.type == :str
|
|
143
133
|
node.children.each do |child|
|
|
144
134
|
result.concat string_ranges(child)
|
|
145
135
|
end
|
|
@@ -3,20 +3,6 @@
|
|
|
3
3
|
require 'parser'
|
|
4
4
|
require 'ast'
|
|
5
5
|
|
|
6
|
-
# Teach AST::Node#children about its generic type
|
|
7
|
-
#
|
|
8
|
-
# @todo contribute back to https://github.com/ruby/gem_rbs_collection/blob/main/gems/ast/2.4/ast.rbs
|
|
9
|
-
#
|
|
10
|
-
# @!parse
|
|
11
|
-
# module ::AST
|
|
12
|
-
# class Node
|
|
13
|
-
# # New children
|
|
14
|
-
#
|
|
15
|
-
# # @return [Array<self, Integer, String, Symbol, nil>]
|
|
16
|
-
# attr_reader :children
|
|
17
|
-
# end
|
|
18
|
-
# end
|
|
19
|
-
|
|
20
6
|
# https://github.com/whitequark/parser
|
|
21
7
|
module Solargraph
|
|
22
8
|
module Parser
|
|
@@ -133,6 +119,7 @@ module Solargraph
|
|
|
133
119
|
result
|
|
134
120
|
end
|
|
135
121
|
|
|
122
|
+
# @sg-ignore Wrong argument type for AST::Node.new: type expected AST::_ToSym, received :nil
|
|
136
123
|
NIL_NODE = ::Parser::AST::Node.new(:nil)
|
|
137
124
|
|
|
138
125
|
# @param node [Parser::AST::Node]
|
|
@@ -11,6 +11,7 @@ module Solargraph
|
|
|
11
11
|
process_children
|
|
12
12
|
|
|
13
13
|
position = get_node_start_position(node)
|
|
14
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
14
15
|
enclosing_breakable_pin = pins.select{|pin| pin.is_a?(Pin::Breakable) && pin.location.range.contain?(position)}.last
|
|
15
16
|
FlowSensitiveTyping.new(locals, enclosing_breakable_pin).process_and(node)
|
|
16
17
|
end
|
|
@@ -9,14 +9,70 @@ module Solargraph
|
|
|
9
9
|
class OpasgnNode < Parser::NodeProcessor::Base
|
|
10
10
|
# @return [void]
|
|
11
11
|
def process
|
|
12
|
-
|
|
13
|
-
# => s(:op_asgn,
|
|
14
|
-
# s(:lvasgn, :a), :+,
|
|
15
|
-
# s(:int, 2))
|
|
16
|
-
asgn = node.children[0]
|
|
17
|
-
variable_name = asgn.children[0]
|
|
12
|
+
target = node.children[0]
|
|
18
13
|
operator = node.children[1]
|
|
19
14
|
argument = node.children[2]
|
|
15
|
+
if target.type == :send
|
|
16
|
+
# @sg-ignore Need a downcast here
|
|
17
|
+
process_send_target(target, operator, argument)
|
|
18
|
+
elsif target.type.to_s.end_with?('vasgn')
|
|
19
|
+
# @sg-ignore Need a downcast here
|
|
20
|
+
process_vasgn_target(target, operator, argument)
|
|
21
|
+
else
|
|
22
|
+
Solargraph.assert_or_log(:opasgn_unknown_target,
|
|
23
|
+
"Unexpected op_asgn target type: #{target.type}")
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param call [Parser::AST::Node] the target of the assignment
|
|
28
|
+
# @param operator [Symbol] the operator, e.g. :+
|
|
29
|
+
# @param argument [Parser::AST::Node] the argument of the operation
|
|
30
|
+
#
|
|
31
|
+
# @return [void]
|
|
32
|
+
def process_send_target call, operator, argument
|
|
33
|
+
# if target is a call:
|
|
34
|
+
# [10] pry(main)> Parser::CurrentRuby.parse("Foo.bar += baz")
|
|
35
|
+
# => s(:op_asgn,
|
|
36
|
+
# s(:send, # call
|
|
37
|
+
# s(:const, nil, :Foo), # calee
|
|
38
|
+
# :bar), # call_method
|
|
39
|
+
# :+, # operator
|
|
40
|
+
# s(:send, nil, :baz)) # argument
|
|
41
|
+
# [11] pry(main)>
|
|
42
|
+
callee = call.children[0]
|
|
43
|
+
call_method = call.children[1]
|
|
44
|
+
asgn_method = :"#{call_method}="
|
|
45
|
+
|
|
46
|
+
# [8] pry(main)> Parser::CurrentRuby.parse("Foo.bar = Foo.bar + baz")
|
|
47
|
+
# => s(:send,
|
|
48
|
+
# s(:const, nil, :Foo), # callee
|
|
49
|
+
# :bar=, # asgn_method
|
|
50
|
+
# s(:send,
|
|
51
|
+
# s(:send,
|
|
52
|
+
# s(:const, nil, :Foo), # callee
|
|
53
|
+
# :bar), # call_method
|
|
54
|
+
# :+, # operator
|
|
55
|
+
# s(:send, nil, :baz))) # argument
|
|
56
|
+
new_send = node.updated(:send,
|
|
57
|
+
[callee,
|
|
58
|
+
asgn_method,
|
|
59
|
+
node.updated(:send, [call, operator, argument])])
|
|
60
|
+
NodeProcessor.process(new_send, region, pins, locals)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @param asgn [Parser::AST::Node] the target of the assignment
|
|
64
|
+
# @param operator [Symbol] the operator, e.g. :+
|
|
65
|
+
# @param argument [Parser::AST::Node] the argument of the operation
|
|
66
|
+
#
|
|
67
|
+
# @return [void]
|
|
68
|
+
def process_vasgn_target asgn, operator, argument
|
|
69
|
+
# => s(:op_asgn,
|
|
70
|
+
# s(:lvasgn, :a), # asgn
|
|
71
|
+
# :+, # operator
|
|
72
|
+
# s(:int, 2)) # argument
|
|
73
|
+
|
|
74
|
+
# @type [Parser::AST::Node]
|
|
75
|
+
variable_name = asgn.children[0]
|
|
20
76
|
# for lvasgn, gvasgn, cvasgn, convert to lvar, gvar, cvar
|
|
21
77
|
# [6] pry(main)> Parser::CurrentRuby.parse("a = a + 1")
|
|
22
78
|
# => s(:lvasgn, :a,
|
|
@@ -25,9 +81,9 @@ module Solargraph
|
|
|
25
81
|
# s(:int, 1)))
|
|
26
82
|
# [7] pry(main)>
|
|
27
83
|
variable_reference_type = asgn.type.to_s.sub(/vasgn$/, 'var').to_sym
|
|
28
|
-
|
|
84
|
+
target_reference = node.updated(variable_reference_type, asgn.children)
|
|
29
85
|
send_children = [
|
|
30
|
-
|
|
86
|
+
target_reference,
|
|
31
87
|
operator,
|
|
32
88
|
argument
|
|
33
89
|
]
|
|
@@ -7,9 +7,18 @@ module Solargraph
|
|
|
7
7
|
class SclassNode < Parser::NodeProcessor::Base
|
|
8
8
|
def process
|
|
9
9
|
sclass = node.children[0]
|
|
10
|
-
|
|
10
|
+
# @todo Changing Parser::AST::Node to AST::Node below will
|
|
11
|
+
# cause type errors at strong level because the combined
|
|
12
|
+
# pin for AST::Node#children has return type
|
|
13
|
+
# "Array<AST::Node>, Array". YARD annotations in AST
|
|
14
|
+
# provided the Array, RBS for Array<AST::Node>. We
|
|
15
|
+
# should probably have a rule to combine "A, A<T>""
|
|
16
|
+
# types to "A<T>" if the "A" comes from YARD, with the
|
|
17
|
+
# rationale that folks tend to be less formal with types in
|
|
18
|
+
# YARD.
|
|
19
|
+
if sclass.is_a?(::Parser::AST::Node) && sclass.type == :self
|
|
11
20
|
closure = region.closure
|
|
12
|
-
elsif sclass.is_a?(AST::Node) && sclass.type == :casgn
|
|
21
|
+
elsif sclass.is_a?(::Parser::AST::Node) && sclass.type == :casgn
|
|
13
22
|
names = [region.closure.namespace, region.closure.name]
|
|
14
23
|
if sclass.children[0].nil? && names.last != sclass.children[1].to_s
|
|
15
24
|
names << sclass.children[1].to_s
|
|
@@ -18,7 +27,7 @@ module Solargraph
|
|
|
18
27
|
end
|
|
19
28
|
name = names.reject(&:empty?).join('::')
|
|
20
29
|
closure = Solargraph::Pin::Namespace.new(name: name, location: region.closure.location, source: :parser)
|
|
21
|
-
elsif sclass.is_a?(AST::Node) && sclass.type == :const
|
|
30
|
+
elsif sclass.is_a?(::Parser::AST::Node) && sclass.type == :const
|
|
22
31
|
names = [region.closure.namespace, region.closure.name]
|
|
23
32
|
also = NodeMethods.unpack_name(sclass)
|
|
24
33
|
if also != region.closure.name
|
|
@@ -36,15 +36,12 @@ module Solargraph
|
|
|
36
36
|
process_autoload
|
|
37
37
|
elsif method_name == :private_constant
|
|
38
38
|
process_private_constant
|
|
39
|
-
# @sg-ignore
|
|
40
39
|
elsif method_name == :alias_method && node.children[2] && node.children[2] && node.children[2].type == :sym && node.children[3] && node.children[3].type == :sym
|
|
41
40
|
process_alias_method
|
|
42
|
-
# @sg-ignore
|
|
43
41
|
elsif method_name == :private_class_method && node.children[2].is_a?(AST::Node)
|
|
44
42
|
# Processing a private class can potentially handle children on its own
|
|
45
43
|
return if process_private_class_method
|
|
46
44
|
end
|
|
47
|
-
# @sg-ignore
|
|
48
45
|
elsif method_name == :require && node.children[0].to_s == '(const nil :Bundler)'
|
|
49
46
|
pins.push Pin::Reference::Require.new(Solargraph::Location.new(region.filename, Solargraph::Range.from_to(0, 0, 0, 0)), 'bundler/require', source: :parser)
|
|
50
47
|
end
|
|
@@ -66,7 +63,7 @@ module Solargraph
|
|
|
66
63
|
return process_children
|
|
67
64
|
end
|
|
68
65
|
# :nocov:
|
|
69
|
-
if child.is_a?(AST::Node) && (child.type == :sym || child.type == :str)
|
|
66
|
+
if child.is_a?(::Parser::AST::Node) && (child.type == :sym || child.type == :str)
|
|
70
67
|
name = child.children[0].to_s
|
|
71
68
|
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)}
|
|
72
69
|
matches.each do |pin|
|
|
@@ -198,7 +195,7 @@ module Solargraph
|
|
|
198
195
|
elsif node.children[2].type == :sym || node.children[2].type == :str
|
|
199
196
|
node.children[2..-1].each do |x|
|
|
200
197
|
cn = x.children[0].to_s
|
|
201
|
-
# @type [Pin::Method]
|
|
198
|
+
# @type [Pin::Method, nil]
|
|
202
199
|
ref = pins.find { |p| p.is_a?(Pin::Method) && p.namespace == region.closure.full_context.namespace && p.name == cn }
|
|
203
200
|
unless ref.nil?
|
|
204
201
|
pins.delete ref
|
|
@@ -231,6 +228,7 @@ module Solargraph
|
|
|
231
228
|
closure: cm,
|
|
232
229
|
name: ivar.name,
|
|
233
230
|
comments: ivar.comments,
|
|
231
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
234
232
|
assignment: ivar.assignment,
|
|
235
233
|
source: :parser
|
|
236
234
|
)
|
|
@@ -239,6 +237,7 @@ module Solargraph
|
|
|
239
237
|
closure: mm,
|
|
240
238
|
name: ivar.name,
|
|
241
239
|
comments: ivar.comments,
|
|
240
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
242
241
|
assignment: ivar.assignment,
|
|
243
242
|
source: :parser
|
|
244
243
|
)
|
data/lib/solargraph/pin/base.rb
CHANGED
|
@@ -195,9 +195,9 @@ module Solargraph
|
|
|
195
195
|
return_type
|
|
196
196
|
else
|
|
197
197
|
all_items = return_type.items + other.return_type.items
|
|
198
|
-
if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.rooted_tag }
|
|
198
|
+
if all_items.any? { |item| item.selfy? } && all_items.any? { |item| item.rooted_tag == context.reduce_class_type.rooted_tag }
|
|
199
199
|
# assume this was a declaration that should have said 'self'
|
|
200
|
-
all_items.delete_if { |item| item.rooted_tag == context.rooted_tag }
|
|
200
|
+
all_items.delete_if { |item| item.rooted_tag == context.reduce_class_type.rooted_tag }
|
|
201
201
|
end
|
|
202
202
|
ComplexType.new(all_items)
|
|
203
203
|
end
|
|
@@ -259,6 +259,7 @@ module Solargraph
|
|
|
259
259
|
def assert_same_macros(other)
|
|
260
260
|
return unless self.source == :yardoc && other.source == :yardoc
|
|
261
261
|
assert_same_count(other, :macros)
|
|
262
|
+
# @param [YARD::Tags::MacroDirective]
|
|
262
263
|
assert_same_array_content(other, :macros) { |macro| macro.tag.name }
|
|
263
264
|
end
|
|
264
265
|
|
|
@@ -338,7 +339,7 @@ module Solargraph
|
|
|
338
339
|
# @param other [self]
|
|
339
340
|
# @param attr [::Symbol]
|
|
340
341
|
#
|
|
341
|
-
# @sg-ignore
|
|
342
|
+
# @sg-ignore Missing @return tag for Solargraph::Pin::Base#choose_pin_attr
|
|
342
343
|
# @return [undefined]
|
|
343
344
|
def choose_pin_attr(other, attr)
|
|
344
345
|
# @type [Pin::Base, nil]
|
|
@@ -353,8 +354,15 @@ module Solargraph
|
|
|
353
354
|
# :nocov:
|
|
354
355
|
end
|
|
355
356
|
# arbitrary way of choosing a pin
|
|
356
|
-
|
|
357
|
-
|
|
357
|
+
[val1, val2].compact.max_by do |closure|
|
|
358
|
+
[
|
|
359
|
+
# maximize number of gates, as types in other combined pins may
|
|
360
|
+
# depend on those gates
|
|
361
|
+
closure.gates.length,
|
|
362
|
+
# use basename so that results don't vary system to system
|
|
363
|
+
File.basename(closure.best_location.to_s)
|
|
364
|
+
]
|
|
365
|
+
end
|
|
358
366
|
end
|
|
359
367
|
|
|
360
368
|
# @return [void]
|
|
@@ -456,9 +464,10 @@ module Solargraph
|
|
|
456
464
|
# Pin equality is determined using the #nearly? method and also
|
|
457
465
|
# requiring both pins to have the same location.
|
|
458
466
|
#
|
|
459
|
-
# @param other [
|
|
467
|
+
# @param other [Object]
|
|
460
468
|
def == other
|
|
461
469
|
return false unless nearly? other
|
|
470
|
+
# @sg-ignore Should add more explicit type check on other
|
|
462
471
|
comments == other.comments && location == other.location
|
|
463
472
|
end
|
|
464
473
|
|
|
@@ -513,7 +522,7 @@ module Solargraph
|
|
|
513
522
|
# @param api_map [ApiMap]
|
|
514
523
|
# @return [ComplexType]
|
|
515
524
|
def typify api_map
|
|
516
|
-
return_type.qualify(api_map,
|
|
525
|
+
return_type.qualify(api_map, *(closure&.gates || ['']))
|
|
517
526
|
end
|
|
518
527
|
|
|
519
528
|
# Infer the pin's return type via static code analysis.
|
|
@@ -574,12 +583,24 @@ module Solargraph
|
|
|
574
583
|
@identity ||= "#{closure&.path}|#{name}|#{location}"
|
|
575
584
|
end
|
|
576
585
|
|
|
586
|
+
# The namespaces available for resolving the current namespace. Each gate
|
|
587
|
+
# should be a fully qualified namespace or the root namespace (i.e., an
|
|
588
|
+
# empty string.)
|
|
589
|
+
#
|
|
590
|
+
# Example: Given the name 'Bar' and the gates ['Foo', ''],
|
|
591
|
+
# the fully qualified namespace should be 'Foo::Bar' or 'Bar'.
|
|
592
|
+
#
|
|
593
|
+
# @return [Array<String>]
|
|
594
|
+
def gates
|
|
595
|
+
@gates ||= closure&.gates || ['']
|
|
596
|
+
end
|
|
597
|
+
|
|
577
598
|
# @return [String, nil]
|
|
578
599
|
def to_rbs
|
|
579
600
|
return_type.to_rbs
|
|
580
601
|
end
|
|
581
602
|
|
|
582
|
-
# @return [String]
|
|
603
|
+
# @return [String, nil]
|
|
583
604
|
def type_desc
|
|
584
605
|
rbs = to_rbs
|
|
585
606
|
# RBS doesn't have a way to represent a Class<x> type
|
|
@@ -12,8 +12,9 @@ module Solargraph
|
|
|
12
12
|
attr_accessor :mass_assignment
|
|
13
13
|
|
|
14
14
|
# @param return_type [ComplexType, nil]
|
|
15
|
+
# @param mass_assignment [::Array(Parser::AST::Node, Integer), nil]
|
|
15
16
|
# @param assignment [Parser::AST::Node, nil]
|
|
16
|
-
def initialize assignment: nil, return_type: nil, **splat
|
|
17
|
+
def initialize assignment: nil, return_type: nil, mass_assignment: nil, **splat
|
|
17
18
|
super(**splat)
|
|
18
19
|
@assignment = assignment
|
|
19
20
|
# @type [nil, ::Array(Parser::AST::Node, Integer)]
|
|
@@ -22,12 +23,12 @@ module Solargraph
|
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
def combine_with(other, attrs={})
|
|
25
|
-
attrs.merge({
|
|
26
|
+
new_attrs = attrs.merge({
|
|
26
27
|
assignment: assert_same(other, :assignment),
|
|
27
28
|
mass_assignment: assert_same(other, :mass_assignment),
|
|
28
29
|
return_type: combine_return_type(other),
|
|
29
30
|
})
|
|
30
|
-
super(other,
|
|
31
|
+
super(other, new_attrs)
|
|
31
32
|
end
|
|
32
33
|
|
|
33
34
|
def completion_item_kind
|
|
@@ -104,6 +105,7 @@ module Solargraph
|
|
|
104
105
|
# @param other [Object]
|
|
105
106
|
def == other
|
|
106
107
|
return false unless super
|
|
108
|
+
# @sg-ignore Should add type check on other
|
|
107
109
|
assignment == other.assignment
|
|
108
110
|
end
|
|
109
111
|
|
data/lib/solargraph/pin/block.rb
CHANGED
|
@@ -54,6 +54,7 @@ module Solargraph
|
|
|
54
54
|
locals = clip.locals - [self]
|
|
55
55
|
meths = chain.define(api_map, closure, locals)
|
|
56
56
|
# @todo Convert logic to use signatures
|
|
57
|
+
# @param meth [Pin::Method]
|
|
57
58
|
meths.each do |meth|
|
|
58
59
|
next if meth.block.nil?
|
|
59
60
|
|
|
@@ -69,7 +70,7 @@ module Solargraph
|
|
|
69
70
|
namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
|
|
70
71
|
arg_type.resolve_generics(namespace_pin, param_type)
|
|
71
72
|
else
|
|
72
|
-
arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, meth.
|
|
73
|
+
arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, *meth.gates)
|
|
73
74
|
end
|
|
74
75
|
end
|
|
75
76
|
end
|
|
@@ -96,7 +97,7 @@ module Solargraph
|
|
|
96
97
|
target = chain.base.infer(api_map, receiver_pin, locals)
|
|
97
98
|
target = full_context unless target.defined?
|
|
98
99
|
|
|
99
|
-
ComplexType.try_parse(*types).qualify(api_map, receiver_pin.
|
|
100
|
+
ComplexType.try_parse(*types).qualify(api_map, *receiver_pin.gates).self_to_type(target)
|
|
100
101
|
end
|
|
101
102
|
end
|
|
102
103
|
end
|
|
@@ -27,13 +27,15 @@ module Solargraph
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# @param other [self]
|
|
30
|
-
#
|
|
30
|
+
#
|
|
31
|
+
# @return [Pin::Signature, nil]
|
|
31
32
|
def combine_blocks(other)
|
|
32
33
|
if block.nil?
|
|
33
34
|
other.block
|
|
34
35
|
elsif other.block.nil?
|
|
35
36
|
block
|
|
36
37
|
else
|
|
38
|
+
# @type [Pin::Signature, nil]
|
|
37
39
|
choose_pin_attr(other, :block)
|
|
38
40
|
end
|
|
39
41
|
end
|
|
@@ -61,9 +63,12 @@ module Solargraph
|
|
|
61
63
|
end
|
|
62
64
|
|
|
63
65
|
# @param other [self]
|
|
66
|
+
#
|
|
64
67
|
# @return [Array<Pin::Parameter>]
|
|
65
68
|
def choose_parameters(other)
|
|
66
69
|
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
|
|
70
|
+
# @param param [Pin::Parameter]
|
|
71
|
+
# @param other_param [Pin::Parameter]
|
|
67
72
|
parameters.zip(other.parameters).map do |param, other_param|
|
|
68
73
|
if param.nil? && other_param.block?
|
|
69
74
|
other_param
|
|
@@ -210,7 +215,6 @@ module Solargraph
|
|
|
210
215
|
parameters.count(&:arg?)
|
|
211
216
|
end
|
|
212
217
|
|
|
213
|
-
# @return [String]
|
|
214
218
|
def to_rbs
|
|
215
219
|
rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
|
|
216
220
|
end
|
|
@@ -48,19 +48,15 @@ module Solargraph
|
|
|
48
48
|
@binder || context
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
# @
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
# root pin
|
|
55
|
-
closure ? closure.gates : ['']
|
|
56
|
-
end
|
|
51
|
+
# @param api_map [Solargraph::ApiMap]
|
|
52
|
+
# @return [void]
|
|
53
|
+
def rebind api_map; end
|
|
57
54
|
|
|
58
55
|
# @return [::Array<String>]
|
|
59
56
|
def generics
|
|
60
57
|
@generics ||= docstring.tags(:generic).map(&:name)
|
|
61
58
|
end
|
|
62
59
|
|
|
63
|
-
# @return [String]
|
|
64
60
|
def to_rbs
|
|
65
61
|
rbs_generics + return_type.to_rbs
|
|
66
62
|
end
|
|
@@ -51,7 +51,6 @@ module Solargraph
|
|
|
51
51
|
%i[typify realize infer probe].each do |method|
|
|
52
52
|
# @param api_map [ApiMap]
|
|
53
53
|
define_method(method) do |api_map|
|
|
54
|
-
# @sg-ignore Unresolved call to resolve_method
|
|
55
54
|
resolve_method(api_map)
|
|
56
55
|
# @sg-ignore Need to set context correctly in define_method blocks
|
|
57
56
|
@resolved_method ? @resolved_method.send(method, api_map) : super(api_map)
|
|
@@ -26,9 +26,6 @@ module Solargraph
|
|
|
26
26
|
assignment: assert_same(other, :assignment),
|
|
27
27
|
presence_certain: assert_same(other, :presence_certain?),
|
|
28
28
|
}.merge(attrs)
|
|
29
|
-
# @sg-ignore Wrong argument type for
|
|
30
|
-
# Solargraph::Pin::Base#assert_same: other expected
|
|
31
|
-
# Solargraph::Pin::Base, received self
|
|
32
29
|
new_attrs[:presence] = assert_same(other, :presence) unless attrs.key?(:presence)
|
|
33
30
|
|
|
34
31
|
super(other, new_attrs)
|
|
@@ -42,7 +39,6 @@ module Solargraph
|
|
|
42
39
|
match_named_closure(other_closure, closure)
|
|
43
40
|
end
|
|
44
41
|
|
|
45
|
-
# @return [String]
|
|
46
42
|
def to_rbs
|
|
47
43
|
(name || '(anon)') + ' ' + (return_type&.to_rbs || 'untyped')
|
|
48
44
|
end
|
|
@@ -17,7 +17,7 @@ module Solargraph
|
|
|
17
17
|
|
|
18
18
|
# @param visibility [::Symbol] :public, :protected, or :private
|
|
19
19
|
# @param explicit [Boolean]
|
|
20
|
-
# @param block [Pin::Signature, nil,
|
|
20
|
+
# @param block [Pin::Signature, nil, :undefined]
|
|
21
21
|
# @param node [Parser::AST::Node, nil]
|
|
22
22
|
# @param attribute [Boolean]
|
|
23
23
|
# @param signatures [::Array<Signature>, nil]
|
|
@@ -34,14 +34,18 @@ module Solargraph
|
|
|
34
34
|
@anon_splat = anon_splat
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
+
# @param signature_pins [Array<Pin::Signature>]
|
|
37
38
|
# @return [Array<Pin::Signature>]
|
|
38
39
|
def combine_all_signature_pins(*signature_pins)
|
|
40
|
+
# @type [Hash{Array => Array<Pin::Signature>}]
|
|
39
41
|
by_arity = {}
|
|
40
42
|
signature_pins.each do |signature_pin|
|
|
41
43
|
by_arity[signature_pin.arity] ||= []
|
|
42
44
|
by_arity[signature_pin.arity] << signature_pin
|
|
43
45
|
end
|
|
44
46
|
by_arity.transform_values! do |same_arity_pins|
|
|
47
|
+
# @param memo [Pin::Signature, nil]
|
|
48
|
+
# @param signature [Pin::Signature]
|
|
45
49
|
same_arity_pins.reduce(nil) do |memo, signature|
|
|
46
50
|
next signature if memo.nil?
|
|
47
51
|
memo.combine_with(signature)
|
|
@@ -88,6 +92,7 @@ module Solargraph
|
|
|
88
92
|
end
|
|
89
93
|
new_attrs = {
|
|
90
94
|
visibility: combine_visibility(other),
|
|
95
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1050
|
|
91
96
|
explicit: explicit? || other.explicit?,
|
|
92
97
|
block: combine_blocks(other),
|
|
93
98
|
node: choose_node(other, :node),
|
|
@@ -298,7 +303,7 @@ module Solargraph
|
|
|
298
303
|
type = see_reference(api_map) || typify_from_super(api_map)
|
|
299
304
|
logger.debug { "Method#typify(self=#{self}) - type=#{type&.rooted_tags.inspect}" }
|
|
300
305
|
unless type.nil?
|
|
301
|
-
qualified = type.qualify(api_map,
|
|
306
|
+
qualified = type.qualify(api_map, *closure.gates)
|
|
302
307
|
logger.debug { "Method#typify(self=#{self}) => #{qualified.rooted_tags.inspect}" }
|
|
303
308
|
return qualified
|
|
304
309
|
end
|
|
@@ -376,11 +381,14 @@ module Solargraph
|
|
|
376
381
|
@attribute
|
|
377
382
|
end
|
|
378
383
|
|
|
379
|
-
# @parm other [
|
|
384
|
+
# @parm other [self]
|
|
380
385
|
def nearly? other
|
|
381
386
|
super &&
|
|
387
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1050
|
|
382
388
|
parameters == other.parameters &&
|
|
389
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1050
|
|
383
390
|
scope == other.scope &&
|
|
391
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1050
|
|
384
392
|
visibility == other.visibility
|
|
385
393
|
end
|
|
386
394
|
|
|
@@ -392,9 +400,12 @@ module Solargraph
|
|
|
392
400
|
def overloads
|
|
393
401
|
# Ignore overload tags with nil parameters. If it's not an array, the
|
|
394
402
|
# tag's source is likely malformed.
|
|
403
|
+
|
|
404
|
+
# @param tag [YARD::Tags::OverloadTag]
|
|
395
405
|
@overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag|
|
|
396
406
|
Pin::Signature.new(
|
|
397
407
|
generics: generics,
|
|
408
|
+
# @param src [Array(String, String)]
|
|
398
409
|
parameters: tag.parameters.map do |src|
|
|
399
410
|
name, decl = parse_overload_param(src.first)
|
|
400
411
|
Pin::Parameter.new(
|
|
@@ -507,6 +518,7 @@ module Solargraph
|
|
|
507
518
|
#
|
|
508
519
|
# @return [ComplexType]
|
|
509
520
|
def param_type_from_name(tag, name)
|
|
521
|
+
# @param t [YARD::Tags::Tag]
|
|
510
522
|
param = tag.tags(:param).select { |t| t.name == name }.first
|
|
511
523
|
return ComplexType::UNDEFINED unless param
|
|
512
524
|
ComplexType.try_parse(*param.types)
|
|
@@ -522,8 +534,12 @@ module Solargraph
|
|
|
522
534
|
# @param api_map [ApiMap]
|
|
523
535
|
# @return [ComplexType, nil]
|
|
524
536
|
def see_reference api_map
|
|
537
|
+
# This should actually be an intersection type
|
|
538
|
+
# @param ref [YARD::Tags::Tag, Solargraph::Yard::Tags::RefTag]
|
|
525
539
|
docstring.ref_tags.each do |ref|
|
|
540
|
+
# @sg-ignore ref should actually be an intersection type
|
|
526
541
|
next unless ref.tag_name == 'return' && ref.owner
|
|
542
|
+
# @sg-ignore ref should actually be an intersection type
|
|
527
543
|
result = resolve_reference(ref.owner.to_s, api_map)
|
|
528
544
|
return result unless result.nil?
|
|
529
545
|
end
|
|
@@ -556,7 +572,7 @@ module Solargraph
|
|
|
556
572
|
if parts.first.empty? || parts.one?
|
|
557
573
|
path = "#{namespace}#{ref}"
|
|
558
574
|
else
|
|
559
|
-
fqns = api_map.qualify(parts.first,
|
|
575
|
+
fqns = api_map.qualify(parts.first, *gates)
|
|
560
576
|
return ComplexType::UNDEFINED if fqns.nil?
|
|
561
577
|
path = fqns + ref[parts.first.length] + parts.last
|
|
562
578
|
end
|
|
@@ -166,7 +166,7 @@ module Solargraph
|
|
|
166
166
|
|
|
167
167
|
# @param api_map [ApiMap]
|
|
168
168
|
def typify api_map
|
|
169
|
-
return return_type.qualify(api_map, closure.
|
|
169
|
+
return return_type.qualify(api_map, *closure.gates) unless return_type.undefined?
|
|
170
170
|
closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
|
|
171
171
|
end
|
|
172
172
|
|
|
@@ -222,7 +222,7 @@ module Solargraph
|
|
|
222
222
|
if found.nil? and !index.nil?
|
|
223
223
|
found = params[index] if params[index] && (params[index].name.nil? || params[index].name.empty?)
|
|
224
224
|
end
|
|
225
|
-
return ComplexType.try_parse(*found.types).qualify(api_map, meth.
|
|
225
|
+
return ComplexType.try_parse(*found.types).qualify(api_map, *meth.closure.gates) unless found.nil? || found.types.nil?
|
|
226
226
|
end
|
|
227
227
|
ComplexType::UNDEFINED
|
|
228
228
|
end
|
|
@@ -232,8 +232,12 @@ module Solargraph
|
|
|
232
232
|
# @param skip [::Array]
|
|
233
233
|
# @return [::Array<YARD::Tags::Tag>]
|
|
234
234
|
def see_reference heredoc, api_map, skip = []
|
|
235
|
+
# This should actually be an intersection type
|
|
236
|
+
# @param ref [YARD::Tags::Tag, Solargraph::Yard::Tags::RefTag]
|
|
235
237
|
heredoc.ref_tags.each do |ref|
|
|
238
|
+
# @sg-ignore ref should actually be an intersection type
|
|
236
239
|
next unless ref.tag_name == 'param' && ref.owner
|
|
240
|
+
# @sg-ignore ref should actually be an intersection type
|
|
237
241
|
result = resolve_reference(ref.owner.to_s, api_map, skip)
|
|
238
242
|
return result unless result.nil?
|
|
239
243
|
end
|
|
@@ -4,9 +4,12 @@ module Solargraph
|
|
|
4
4
|
module Pin
|
|
5
5
|
class ProxyType < Base
|
|
6
6
|
# @param return_type [ComplexType]
|
|
7
|
+
# @param gates [Array<String>, nil] Namespaces to try while resolving non-rooted types
|
|
7
8
|
# @param binder [ComplexType, ComplexType::UniqueType, nil]
|
|
8
|
-
|
|
9
|
+
# @param gates [Array<String>, nil]
|
|
10
|
+
def initialize return_type: ComplexType::UNDEFINED, binder: nil, gates: nil, **splat
|
|
9
11
|
super(**splat)
|
|
12
|
+
@gates = gates
|
|
10
13
|
@return_type = return_type
|
|
11
14
|
@binder = binder if binder
|
|
12
15
|
end
|
|
@@ -18,18 +18,9 @@ module Solargraph
|
|
|
18
18
|
@generic_values = generic_values
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
# @return [String]
|
|
22
|
-
def parameter_tag
|
|
23
|
-
@parameter_tag ||= if generic_values&.any?
|
|
24
|
-
"<#{generic_values.join(', ')}>"
|
|
25
|
-
else
|
|
26
|
-
''
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
21
|
# @return [ComplexType]
|
|
31
|
-
def
|
|
32
|
-
@
|
|
22
|
+
def type
|
|
23
|
+
@type ||= ComplexType.try_parse(
|
|
33
24
|
name +
|
|
34
25
|
if generic_values&.length&.> 0
|
|
35
26
|
"<#{generic_values.join(', ')}>"
|