solargraph 0.54.0 → 0.55.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/CHANGELOG.md +58 -0
- data/lib/solargraph/api_map/cache.rb +10 -1
- data/lib/solargraph/api_map/index.rb +167 -0
- data/lib/solargraph/api_map/store.rb +75 -122
- data/lib/solargraph/api_map.rb +109 -41
- data/lib/solargraph/bench.rb +17 -1
- data/lib/solargraph/complex_type/type_methods.rb +17 -11
- data/lib/solargraph/complex_type/unique_type.rb +181 -17
- data/lib/solargraph/complex_type.rb +103 -24
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +51 -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 +2 -0
- data/lib/solargraph/doc_map.rb +43 -18
- data/lib/solargraph/equality.rb +33 -0
- data/lib/solargraph/language_server/host/message_worker.rb +51 -5
- data/lib/solargraph/language_server/host.rb +13 -11
- data/lib/solargraph/language_server/message/base.rb +19 -12
- 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/definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +4 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +19 -2
- data/lib/solargraph/library.rb +31 -41
- data/lib/solargraph/location.rb +29 -1
- data/lib/solargraph/parser/comment_ripper.rb +11 -6
- data/lib/solargraph/parser/flow_sensitive_typing.rb +226 -0
- data/lib/solargraph/parser/node_methods.rb +15 -1
- data/lib/solargraph/parser/parser_gem/class_methods.rb +11 -6
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +10 -10
- data/lib/solargraph/parser/parser_gem/node_methods.rb +6 -4
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +23 -19
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +21 -1
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +21 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +8 -2
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +26 -5
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +41 -0
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +28 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +28 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +10 -0
- data/lib/solargraph/parser.rb +3 -5
- data/lib/solargraph/pin/base.rb +47 -17
- data/lib/solargraph/pin/base_variable.rb +11 -4
- data/lib/solargraph/pin/block.rb +8 -26
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +147 -0
- data/lib/solargraph/pin/closure.rb +8 -3
- data/lib/solargraph/pin/common.rb +2 -6
- data/lib/solargraph/pin/conversions.rb +3 -2
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/local_variable.rb +7 -1
- data/lib/solargraph/pin/method.rb +76 -48
- data/lib/solargraph/pin/namespace.rb +14 -11
- data/lib/solargraph/pin/parameter.rb +24 -17
- data/lib/solargraph/pin/proxy_type.rb +13 -7
- data/lib/solargraph/pin/signature.rb +3 -129
- data/lib/solargraph/pin/until.rb +18 -0
- data/lib/solargraph/pin/while.rb +18 -0
- data/lib/solargraph/pin.rb +7 -1
- data/lib/solargraph/position.rb +7 -0
- data/lib/solargraph/range.rb +9 -4
- data/lib/solargraph/rbs_map/conversions.rb +84 -45
- data/lib/solargraph/rbs_map/core_fills.rb +16 -9
- data/lib/solargraph/rbs_map.rb +1 -0
- data/lib/solargraph/shell.rb +19 -2
- data/lib/solargraph/source/chain/array.rb +10 -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 +125 -61
- data/lib/solargraph/source/chain/constant.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +8 -2
- data/lib/solargraph/source/chain/if.rb +5 -0
- data/lib/solargraph/source/chain/link.rb +28 -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 +131 -63
- data/lib/solargraph/source/cursor.rb +3 -2
- data/lib/solargraph/source/source_chainer.rb +2 -2
- data/lib/solargraph/source.rb +104 -86
- data/lib/solargraph/source_map/clip.rb +8 -6
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map.rb +28 -16
- data/lib/solargraph/type_checker/checks.rb +4 -0
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +48 -21
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +7 -3
- data/lib/solargraph/workspace.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +1 -0
- data/lib/solargraph/yard_map/mapper/to_method.rb +42 -15
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +1 -0
- data/lib/solargraph/yard_map/mapper.rb +1 -0
- data/lib/solargraph/yardoc.rb +1 -1
- data/lib/solargraph.rb +1 -0
- data/solargraph.gemspec +5 -5
- metadata +41 -25
data/lib/solargraph/pin/block.rb
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
module Pin
|
|
5
|
-
class Block <
|
|
5
|
+
class Block < Callable
|
|
6
|
+
include Breakable
|
|
7
|
+
|
|
6
8
|
# @return [Parser::AST::Node]
|
|
7
9
|
attr_reader :receiver
|
|
8
10
|
|
|
@@ -14,10 +16,9 @@ module Solargraph
|
|
|
14
16
|
# @param context [ComplexType, nil]
|
|
15
17
|
# @param args [::Array<Parameter>]
|
|
16
18
|
def initialize receiver: nil, args: [], context: nil, node: nil, **splat
|
|
17
|
-
super(**splat)
|
|
19
|
+
super(**splat, parameters: args)
|
|
18
20
|
@receiver = receiver
|
|
19
21
|
@context = context
|
|
20
|
-
@parameters = args
|
|
21
22
|
@return_type = ComplexType.parse('::Proc')
|
|
22
23
|
@node = node
|
|
23
24
|
end
|
|
@@ -32,38 +33,19 @@ module Solargraph
|
|
|
32
33
|
@rebind&.defined? ? @rebind : closure.binder
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
# @return [::Array<Parameter>]
|
|
36
|
-
def parameters
|
|
37
|
-
@parameters ||= []
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# @return [::Array<String>]
|
|
41
|
-
def parameter_names
|
|
42
|
-
@parameter_names ||= parameters.map(&:name)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
36
|
# @param yield_types [::Array<ComplexType>]
|
|
46
37
|
# @param parameters [::Array<Parameter>]
|
|
47
38
|
#
|
|
48
39
|
# @return [::Array<ComplexType>]
|
|
49
40
|
def destructure_yield_types(yield_types, parameters)
|
|
50
|
-
return yield_types if yield_types.length == parameters.length
|
|
51
|
-
|
|
52
41
|
# yielding a tuple into a block will destructure the tuple
|
|
53
42
|
if yield_types.length == 1
|
|
54
43
|
yield_type = yield_types.first
|
|
55
44
|
return yield_type.all_params if yield_type.tuple? && yield_type.all_params.length == parameters.length
|
|
56
45
|
end
|
|
57
|
-
parameters.map { ComplexType::UNDEFINED }
|
|
46
|
+
parameters.map.with_index { |_, idx| yield_types[idx] || ComplexType::UNDEFINED }
|
|
58
47
|
end
|
|
59
48
|
|
|
60
|
-
# @todo the next step with parameters, arguments, destructuring,
|
|
61
|
-
# kwargs, etc logic is probably either creating a Parameters
|
|
62
|
-
# or Callable pin that encapsulates and shares the logic
|
|
63
|
-
# between methods, blocks and signatures. It could live in
|
|
64
|
-
# Signature if Method didn't also own potentially different
|
|
65
|
-
# set of parameters, generics and return types.
|
|
66
|
-
|
|
67
49
|
# @param api_map [ApiMap]
|
|
68
50
|
# @return [::Array<ComplexType>]
|
|
69
51
|
def typify_parameters(api_map)
|
|
@@ -87,7 +69,7 @@ module Solargraph
|
|
|
87
69
|
namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
|
|
88
70
|
arg_type.resolve_generics(namespace_pin, param_type)
|
|
89
71
|
else
|
|
90
|
-
arg_type.
|
|
72
|
+
arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, meth.context.namespace)
|
|
91
73
|
end
|
|
92
74
|
end
|
|
93
75
|
end
|
|
@@ -105,7 +87,7 @@ module Solargraph
|
|
|
105
87
|
|
|
106
88
|
chain = Parser.chain(receiver, location.filename)
|
|
107
89
|
locals = api_map.source_map(location.filename).locals_at(location)
|
|
108
|
-
receiver_pin = chain.define(api_map,
|
|
90
|
+
receiver_pin = chain.define(api_map, closure, locals).first
|
|
109
91
|
return ComplexType::UNDEFINED unless receiver_pin
|
|
110
92
|
|
|
111
93
|
types = receiver_pin.docstring.tag(:yieldreceiver)&.types
|
|
@@ -114,7 +96,7 @@ module Solargraph
|
|
|
114
96
|
target = chain.base.infer(api_map, receiver_pin, locals)
|
|
115
97
|
target = full_context unless target.defined?
|
|
116
98
|
|
|
117
|
-
ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).
|
|
99
|
+
ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to_type(target)
|
|
118
100
|
end
|
|
119
101
|
end
|
|
120
102
|
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
class Callable < Closure
|
|
6
|
+
# @return [Signature]
|
|
7
|
+
attr_reader :block
|
|
8
|
+
|
|
9
|
+
attr_reader :parameters
|
|
10
|
+
|
|
11
|
+
# @return [ComplexType, nil]
|
|
12
|
+
attr_reader :return_type
|
|
13
|
+
|
|
14
|
+
# @param block [Signature, nil]
|
|
15
|
+
# @param return_type [ComplexType, nil]
|
|
16
|
+
# @param parameters [::Array<Pin::Parameter>]
|
|
17
|
+
def initialize block: nil, return_type: nil, parameters: [], **splat
|
|
18
|
+
super(**splat)
|
|
19
|
+
@block = block
|
|
20
|
+
@return_type = return_type
|
|
21
|
+
@parameters = parameters
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @return [::Array<String>]
|
|
25
|
+
def parameter_names
|
|
26
|
+
@parameter_names ||= parameters.map(&:name)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @param generics_to_resolve [Enumerable<String>]
|
|
30
|
+
# @param arg_types [Array<ComplexType>, nil]
|
|
31
|
+
# @param return_type_context [ComplexType, nil]
|
|
32
|
+
# @param yield_arg_types [Array<ComplexType>, nil]
|
|
33
|
+
# @param yield_return_type_context [ComplexType, nil]
|
|
34
|
+
# @param context [ComplexType, nil]
|
|
35
|
+
# @param resolved_generic_values [Hash{String => ComplexType}]
|
|
36
|
+
# @return [self]
|
|
37
|
+
def resolve_generics_from_context(generics_to_resolve,
|
|
38
|
+
arg_types = nil,
|
|
39
|
+
return_type_context = nil,
|
|
40
|
+
yield_arg_types = nil,
|
|
41
|
+
yield_return_type_context = nil,
|
|
42
|
+
resolved_generic_values: {})
|
|
43
|
+
callable = super(generics_to_resolve, return_type_context, resolved_generic_values: resolved_generic_values)
|
|
44
|
+
callable.parameters = callable.parameters.each_with_index.map do |param, i|
|
|
45
|
+
if arg_types.nil?
|
|
46
|
+
param.dup
|
|
47
|
+
else
|
|
48
|
+
param.resolve_generics_from_context(generics_to_resolve,
|
|
49
|
+
arg_types[i],
|
|
50
|
+
resolved_generic_values: resolved_generic_values)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
callable.block = block.resolve_generics_from_context(generics_to_resolve,
|
|
54
|
+
yield_arg_types,
|
|
55
|
+
yield_return_type_context,
|
|
56
|
+
resolved_generic_values: resolved_generic_values) if callable.block?
|
|
57
|
+
callable
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @param generics_to_resolve [::Array<String>]
|
|
61
|
+
# @param arg_types [Array<ComplexType>, nil]
|
|
62
|
+
# @param return_type_context [ComplexType, nil]
|
|
63
|
+
# @param yield_arg_types [Array<ComplexType>, nil]
|
|
64
|
+
# @param yield_return_type_context [ComplexType, nil]
|
|
65
|
+
# @param context [ComplexType, nil]
|
|
66
|
+
# @param resolved_generic_values [Hash{String => ComplexType}]
|
|
67
|
+
# @return [self]
|
|
68
|
+
def resolve_generics_from_context_until_complete(generics_to_resolve,
|
|
69
|
+
arg_types = nil,
|
|
70
|
+
return_type_context = nil,
|
|
71
|
+
yield_arg_types = nil,
|
|
72
|
+
yield_return_type_context = nil,
|
|
73
|
+
resolved_generic_values: {})
|
|
74
|
+
# See
|
|
75
|
+
# https://github.com/soutaro/steep/tree/master/lib/steep/type_inference
|
|
76
|
+
# and
|
|
77
|
+
# https://github.com/sorbet/sorbet/blob/master/infer/inference.cc
|
|
78
|
+
# for other implementations
|
|
79
|
+
|
|
80
|
+
return self if generics_to_resolve.empty?
|
|
81
|
+
|
|
82
|
+
last_resolved_generic_values = resolved_generic_values.dup
|
|
83
|
+
new_pin = resolve_generics_from_context(generics_to_resolve,
|
|
84
|
+
arg_types,
|
|
85
|
+
return_type_context,
|
|
86
|
+
yield_arg_types,
|
|
87
|
+
yield_return_type_context,
|
|
88
|
+
resolved_generic_values: resolved_generic_values)
|
|
89
|
+
if last_resolved_generic_values == resolved_generic_values
|
|
90
|
+
# erase anything unresolved
|
|
91
|
+
return new_pin.erase_generics(self.generics)
|
|
92
|
+
end
|
|
93
|
+
new_pin.resolve_generics_from_context_until_complete(generics_to_resolve,
|
|
94
|
+
arg_types,
|
|
95
|
+
return_type_context,
|
|
96
|
+
yield_arg_types,
|
|
97
|
+
yield_return_type_context,
|
|
98
|
+
resolved_generic_values: resolved_generic_values)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @return [Array<String>]
|
|
102
|
+
# @yieldparam [ComplexType]
|
|
103
|
+
# @yieldreturn [ComplexType]
|
|
104
|
+
# @return [self]
|
|
105
|
+
def transform_types(&transform)
|
|
106
|
+
# @todo 'super' alone should work here I think, but doesn't typecheck at level typed
|
|
107
|
+
callable = super(&transform)
|
|
108
|
+
callable.block = block.transform_types(&transform) if block?
|
|
109
|
+
callable.parameters = parameters.map do |param|
|
|
110
|
+
param.transform_types(&transform)
|
|
111
|
+
end
|
|
112
|
+
callable
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @param arguments [::Array<Chain>]
|
|
116
|
+
# @param with_block [Boolean]
|
|
117
|
+
# @return [Boolean]
|
|
118
|
+
def arity_matches? arguments, with_block
|
|
119
|
+
argcount = arguments.length
|
|
120
|
+
parcount = mandatory_positional_param_count
|
|
121
|
+
parcount -= 1 if !parameters.empty? && parameters.last.block?
|
|
122
|
+
return false if block? && !with_block
|
|
123
|
+
return false if argcount < parcount && !(argcount == parcount - 1 && parameters.last.restarg?)
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def mandatory_positional_param_count
|
|
128
|
+
parameters.count(&:arg?)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# @return [String]
|
|
132
|
+
def to_rbs
|
|
133
|
+
rbs_generics + '(' + parameters.map { |param| param.to_rbs }.join(', ') + ') ' + (block.nil? ? '' : '{ ' + block.to_rbs + ' } ') + '-> ' + return_type.to_rbs
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def block?
|
|
137
|
+
!!@block
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
protected
|
|
141
|
+
|
|
142
|
+
attr_writer :block
|
|
143
|
+
|
|
144
|
+
attr_writer :parameters
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -18,7 +18,7 @@ module Solargraph
|
|
|
18
18
|
@context ||= begin
|
|
19
19
|
result = super
|
|
20
20
|
if scope == :instance
|
|
21
|
-
|
|
21
|
+
result.reduce_class_type
|
|
22
22
|
else
|
|
23
23
|
result
|
|
24
24
|
end
|
|
@@ -42,10 +42,15 @@ module Solargraph
|
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
# @return [String]
|
|
45
|
-
def
|
|
45
|
+
def to_rbs
|
|
46
|
+
rbs_generics + return_type.to_rbs
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @return [String]
|
|
50
|
+
def rbs_generics
|
|
46
51
|
return '' if generics.empty?
|
|
47
52
|
|
|
48
|
-
generics.join(', ') + ' '
|
|
53
|
+
'[' + generics.map { |gen| gen.to_s }.join(', ') + '] '
|
|
49
54
|
end
|
|
50
55
|
end
|
|
51
56
|
end
|
|
@@ -19,7 +19,7 @@ module Solargraph
|
|
|
19
19
|
@return_type ||= ComplexType::UNDEFINED
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
# @return [ComplexType
|
|
22
|
+
# @return [ComplexType]
|
|
23
23
|
def context
|
|
24
24
|
# Get the static context from the nearest namespace
|
|
25
25
|
@context ||= find_context
|
|
@@ -59,11 +59,7 @@ module Solargraph
|
|
|
59
59
|
if here.is_a?(Pin::Namespace)
|
|
60
60
|
return here.return_type
|
|
61
61
|
elsif here.is_a?(Pin::Method)
|
|
62
|
-
|
|
63
|
-
return ComplexType.try_parse(here.context.tag)
|
|
64
|
-
else
|
|
65
|
-
return here.context
|
|
66
|
-
end
|
|
62
|
+
return here.context
|
|
67
63
|
end
|
|
68
64
|
here = here.closure
|
|
69
65
|
end
|
|
@@ -87,7 +87,7 @@ module Solargraph
|
|
|
87
87
|
|
|
88
88
|
# @return [String, nil]
|
|
89
89
|
def text_documentation
|
|
90
|
-
this_path = path || return_type.tag
|
|
90
|
+
this_path = path || name || return_type.tag
|
|
91
91
|
return nil if this_path == 'undefined'
|
|
92
92
|
escape_brackets this_path
|
|
93
93
|
end
|
|
@@ -105,9 +105,10 @@ module Solargraph
|
|
|
105
105
|
|
|
106
106
|
# @return [String, nil]
|
|
107
107
|
def generate_link
|
|
108
|
-
this_path = path || return_type.tag
|
|
108
|
+
this_path = path || name || return_type.tag
|
|
109
109
|
return nil if this_path == 'undefined'
|
|
110
110
|
return nil if this_path.nil? || this_path == 'undefined'
|
|
111
|
+
return this_path if path.nil?
|
|
111
112
|
"[#{escape_brackets(this_path).gsub('_', '\\\\_')}](solargraph:/document?query=#{CGI.escape(this_path)})"
|
|
112
113
|
end
|
|
113
114
|
|
|
@@ -18,9 +18,9 @@ module Solargraph
|
|
|
18
18
|
@context ||= begin
|
|
19
19
|
result = super
|
|
20
20
|
if scope == :class
|
|
21
|
-
ComplexType.parse("Class<#{result.
|
|
21
|
+
ComplexType.parse("::Class<#{result.rooted_namespace}>")
|
|
22
22
|
else
|
|
23
|
-
|
|
23
|
+
result.reduce_class_type
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -6,13 +6,19 @@ module Solargraph
|
|
|
6
6
|
# @return [Range]
|
|
7
7
|
attr_reader :presence
|
|
8
8
|
|
|
9
|
+
def presence_certain?
|
|
10
|
+
@presence_certain
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
# @param assignment [AST::Node, nil]
|
|
10
14
|
# @param presence [Range, nil]
|
|
15
|
+
# @param presence_certain [Boolean]
|
|
11
16
|
# @param splat [Hash]
|
|
12
|
-
def initialize assignment: nil, presence: nil, **splat
|
|
17
|
+
def initialize assignment: nil, presence: nil, presence_certain: false, **splat
|
|
13
18
|
super(**splat)
|
|
14
19
|
@assignment = assignment
|
|
15
20
|
@presence = presence
|
|
21
|
+
@presence_certain = presence_certain
|
|
16
22
|
end
|
|
17
23
|
|
|
18
24
|
# @param pin [self]
|
|
@@ -4,12 +4,9 @@ module Solargraph
|
|
|
4
4
|
module Pin
|
|
5
5
|
# The base class for method and attribute pins.
|
|
6
6
|
#
|
|
7
|
-
class Method <
|
|
7
|
+
class Method < Callable
|
|
8
8
|
include Solargraph::Parser::NodeMethods
|
|
9
9
|
|
|
10
|
-
# @return [::Array<Pin::Parameter>]
|
|
11
|
-
attr_reader :parameters
|
|
12
|
-
|
|
13
10
|
# @return [::Symbol] :public, :private, or :protected
|
|
14
11
|
attr_reader :visibility
|
|
15
12
|
|
|
@@ -18,24 +15,24 @@ module Solargraph
|
|
|
18
15
|
|
|
19
16
|
# @param visibility [::Symbol] :public, :protected, or :private
|
|
20
17
|
# @param explicit [Boolean]
|
|
21
|
-
# @param parameters [::Array<Pin::Parameter>]
|
|
22
18
|
# @param block [Pin::Signature, nil, ::Symbol]
|
|
23
|
-
# @param node [Parser::AST::Node,
|
|
19
|
+
# @param node [Parser::AST::Node, nil]
|
|
24
20
|
# @param attribute [Boolean]
|
|
25
21
|
# @param signatures [::Array<Signature>, nil]
|
|
26
22
|
# @param anon_splat [Boolean]
|
|
27
|
-
|
|
28
|
-
def initialize visibility: :public, explicit: true, parameters: [], block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, return_type: nil, **splat
|
|
23
|
+
def initialize visibility: :public, explicit: true, block: :undefined, node: nil, attribute: false, signatures: nil, anon_splat: false, **splat
|
|
29
24
|
super(**splat)
|
|
30
25
|
@visibility = visibility
|
|
31
26
|
@explicit = explicit
|
|
32
|
-
@parameters = parameters
|
|
33
27
|
@block = block
|
|
34
28
|
@node = node
|
|
35
29
|
@attribute = attribute
|
|
36
30
|
@signatures = signatures
|
|
37
31
|
@anon_splat = anon_splat
|
|
38
|
-
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def == other
|
|
35
|
+
super && other.node == node
|
|
39
36
|
end
|
|
40
37
|
|
|
41
38
|
def transform_types(&transform)
|
|
@@ -44,15 +41,16 @@ module Solargraph
|
|
|
44
41
|
m.signatures = m.signatures.map do |sig|
|
|
45
42
|
sig.transform_types(&transform)
|
|
46
43
|
end
|
|
47
|
-
m.parameters = m.parameters.map do |param|
|
|
48
|
-
param.transform_types(&transform)
|
|
49
|
-
end
|
|
50
44
|
m.block = block&.transform_types(&transform)
|
|
51
45
|
m.signature_help = nil
|
|
52
46
|
m.documentation = nil
|
|
53
47
|
m
|
|
54
48
|
end
|
|
55
49
|
|
|
50
|
+
def all_rooted?
|
|
51
|
+
super && parameters.all?(&:all_rooted?) && (!block || block&.all_rooted?) && signatures.all?(&:all_rooted?)
|
|
52
|
+
end
|
|
53
|
+
|
|
56
54
|
# @param signature [Pin::Signature]
|
|
57
55
|
# @return [Pin::Method]
|
|
58
56
|
def with_single_signature(signature)
|
|
@@ -71,15 +69,14 @@ module Solargraph
|
|
|
71
69
|
m
|
|
72
70
|
end
|
|
73
71
|
|
|
72
|
+
def block?
|
|
73
|
+
!block.nil?
|
|
74
|
+
end
|
|
75
|
+
|
|
74
76
|
# @return [Pin::Signature, nil]
|
|
75
77
|
def block
|
|
76
78
|
return @block unless @block == :undefined
|
|
77
|
-
@block = signatures.first
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# @return [::Array<String>]
|
|
81
|
-
def parameter_names
|
|
82
|
-
@parameter_names ||= parameters.map(&:name)
|
|
79
|
+
@block = signatures.first&.block
|
|
83
80
|
end
|
|
84
81
|
|
|
85
82
|
def completion_item_kind
|
|
@@ -123,9 +120,9 @@ module Solargraph
|
|
|
123
120
|
)
|
|
124
121
|
end
|
|
125
122
|
yield_return_type = ComplexType.try_parse(*yieldreturn_tags.flat_map(&:types))
|
|
126
|
-
block = Signature.new(generics, yield_parameters, yield_return_type)
|
|
123
|
+
block = Signature.new(generics: generics, parameters: yield_parameters, return_type: yield_return_type)
|
|
127
124
|
end
|
|
128
|
-
Signature.new(generics, parameters, return_type, block)
|
|
125
|
+
Signature.new(generics: generics, parameters: parameters, return_type: return_type, block: block)
|
|
129
126
|
end
|
|
130
127
|
|
|
131
128
|
# @return [::Array<Signature>]
|
|
@@ -169,9 +166,9 @@ module Solargraph
|
|
|
169
166
|
def desc
|
|
170
167
|
# ensure the signatures line up when logged
|
|
171
168
|
if signatures.length > 1
|
|
172
|
-
"\n#{to_rbs}\n"
|
|
169
|
+
path + " \n#{to_rbs}\n"
|
|
173
170
|
else
|
|
174
|
-
|
|
171
|
+
super
|
|
175
172
|
end
|
|
176
173
|
end
|
|
177
174
|
|
|
@@ -199,13 +196,14 @@ module Solargraph
|
|
|
199
196
|
name.end_with?('?') ? ComplexType::BOOLEAN : ComplexType::UNDEFINED
|
|
200
197
|
end
|
|
201
198
|
|
|
199
|
+
# @sg-ignore
|
|
202
200
|
def documentation
|
|
203
201
|
if @documentation.nil?
|
|
204
|
-
|
|
202
|
+
method_docs ||= super || ''
|
|
205
203
|
param_tags = docstring.tags(:param)
|
|
206
204
|
unless param_tags.nil? or param_tags.empty?
|
|
207
|
-
|
|
208
|
-
|
|
205
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
206
|
+
method_docs += "Params:\n"
|
|
209
207
|
lines = []
|
|
210
208
|
param_tags.each do |p|
|
|
211
209
|
l = "* #{p.name}"
|
|
@@ -213,12 +211,12 @@ module Solargraph
|
|
|
213
211
|
l += " #{p.text}"
|
|
214
212
|
lines.push l
|
|
215
213
|
end
|
|
216
|
-
|
|
214
|
+
method_docs += lines.join("\n")
|
|
217
215
|
end
|
|
218
216
|
yieldparam_tags = docstring.tags(:yieldparam)
|
|
219
217
|
unless yieldparam_tags.nil? or yieldparam_tags.empty?
|
|
220
|
-
|
|
221
|
-
|
|
218
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
219
|
+
method_docs += "Block Params:\n"
|
|
222
220
|
lines = []
|
|
223
221
|
yieldparam_tags.each do |p|
|
|
224
222
|
l = "* #{p.name}"
|
|
@@ -226,12 +224,12 @@ module Solargraph
|
|
|
226
224
|
l += " #{p.text}"
|
|
227
225
|
lines.push l
|
|
228
226
|
end
|
|
229
|
-
|
|
227
|
+
method_docs += lines.join("\n")
|
|
230
228
|
end
|
|
231
229
|
yieldreturn_tags = docstring.tags(:yieldreturn)
|
|
232
230
|
unless yieldreturn_tags.empty?
|
|
233
|
-
|
|
234
|
-
|
|
231
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
232
|
+
method_docs += "Block Returns:\n"
|
|
235
233
|
lines = []
|
|
236
234
|
yieldreturn_tags.each do |r|
|
|
237
235
|
l = "*"
|
|
@@ -239,12 +237,12 @@ module Solargraph
|
|
|
239
237
|
l += " #{r.text}"
|
|
240
238
|
lines.push l
|
|
241
239
|
end
|
|
242
|
-
|
|
240
|
+
method_docs += lines.join("\n")
|
|
243
241
|
end
|
|
244
242
|
return_tags = docstring.tags(:return)
|
|
245
243
|
unless return_tags.empty?
|
|
246
|
-
|
|
247
|
-
|
|
244
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
245
|
+
method_docs += "Returns:\n"
|
|
248
246
|
lines = []
|
|
249
247
|
return_tags.each do |r|
|
|
250
248
|
l = "*"
|
|
@@ -252,10 +250,11 @@ module Solargraph
|
|
|
252
250
|
l += " #{r.text}"
|
|
253
251
|
lines.push l
|
|
254
252
|
end
|
|
255
|
-
|
|
253
|
+
method_docs += lines.join("\n")
|
|
256
254
|
end
|
|
257
|
-
|
|
258
|
-
|
|
255
|
+
method_docs += "\n\n" unless method_docs.empty?
|
|
256
|
+
method_docs += "Visibility: #{visibility}"
|
|
257
|
+
@documentation = method_docs
|
|
259
258
|
concat_example_tags
|
|
260
259
|
end
|
|
261
260
|
@documentation.to_s
|
|
@@ -269,10 +268,11 @@ module Solargraph
|
|
|
269
268
|
@attribute
|
|
270
269
|
end
|
|
271
270
|
|
|
271
|
+
# @parm other [Method]
|
|
272
272
|
def nearly? other
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
scope == other.scope
|
|
273
|
+
super &&
|
|
274
|
+
parameters == other.parameters &&
|
|
275
|
+
scope == other.scope &&
|
|
276
276
|
visibility == other.visibility
|
|
277
277
|
end
|
|
278
278
|
|
|
@@ -280,9 +280,11 @@ module Solargraph
|
|
|
280
280
|
attribute? ? infer_from_iv(api_map) : infer_from_return_nodes(api_map)
|
|
281
281
|
end
|
|
282
282
|
|
|
283
|
+
# @param pin [Pin::Method]
|
|
283
284
|
def try_merge! pin
|
|
284
285
|
return false unless super
|
|
285
286
|
@node = pin.node
|
|
287
|
+
@resolved_ref_tag = false
|
|
286
288
|
true
|
|
287
289
|
end
|
|
288
290
|
|
|
@@ -292,8 +294,8 @@ module Solargraph
|
|
|
292
294
|
# tag's source is likely malformed.
|
|
293
295
|
@overloads ||= docstring.tags(:overload).select(&:parameters).map do |tag|
|
|
294
296
|
Pin::Signature.new(
|
|
295
|
-
generics,
|
|
296
|
-
tag.parameters.map do |src|
|
|
297
|
+
generics: generics,
|
|
298
|
+
parameters: tag.parameters.map do |src|
|
|
297
299
|
name, decl = parse_overload_param(src.first)
|
|
298
300
|
Pin::Parameter.new(
|
|
299
301
|
location: location,
|
|
@@ -305,7 +307,7 @@ module Solargraph
|
|
|
305
307
|
return_type: param_type_from_name(tag, src.first)
|
|
306
308
|
)
|
|
307
309
|
end,
|
|
308
|
-
ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
|
|
310
|
+
return_type: ComplexType.try_parse(*tag.docstring.tags(:return).flat_map(&:types))
|
|
309
311
|
)
|
|
310
312
|
end
|
|
311
313
|
@overloads
|
|
@@ -315,12 +317,33 @@ module Solargraph
|
|
|
315
317
|
@anon_splat
|
|
316
318
|
end
|
|
317
319
|
|
|
320
|
+
# @param api_map [ApiMap]
|
|
321
|
+
# @return [self]
|
|
322
|
+
def resolve_ref_tag api_map
|
|
323
|
+
return self if @resolved_ref_tag
|
|
324
|
+
|
|
325
|
+
@resolved_ref_tag = true
|
|
326
|
+
return self unless docstring.ref_tags.any?
|
|
327
|
+
docstring.ref_tags.each do |tag|
|
|
328
|
+
ref = if tag.owner.to_s.start_with?(/[#\.]/)
|
|
329
|
+
api_map.get_methods(namespace)
|
|
330
|
+
.select { |pin| pin.path.end_with?(tag.owner.to_s) }
|
|
331
|
+
.first
|
|
332
|
+
else
|
|
333
|
+
# @todo Resolve relative namespaces
|
|
334
|
+
api_map.get_path_pins(tag.owner.to_s).first
|
|
335
|
+
end
|
|
336
|
+
next unless ref
|
|
337
|
+
|
|
338
|
+
docstring.add_tag(*ref.docstring.tags(:param))
|
|
339
|
+
end
|
|
340
|
+
self
|
|
341
|
+
end
|
|
342
|
+
|
|
318
343
|
protected
|
|
319
344
|
|
|
320
345
|
attr_writer :block
|
|
321
346
|
|
|
322
|
-
attr_writer :parameters
|
|
323
|
-
|
|
324
347
|
attr_writer :signatures
|
|
325
348
|
|
|
326
349
|
attr_writer :signature_help
|
|
@@ -452,7 +475,7 @@ module Solargraph
|
|
|
452
475
|
end
|
|
453
476
|
result.push ComplexType::NIL if has_nil
|
|
454
477
|
return ComplexType::UNDEFINED if result.empty?
|
|
455
|
-
ComplexType.
|
|
478
|
+
ComplexType.new(result.uniq)
|
|
456
479
|
end
|
|
457
480
|
|
|
458
481
|
# @param [ApiMap] api_map
|
|
@@ -467,7 +490,7 @@ module Solargraph
|
|
|
467
490
|
types.push type if type.defined?
|
|
468
491
|
end
|
|
469
492
|
return ComplexType::UNDEFINED if types.empty?
|
|
470
|
-
ComplexType.
|
|
493
|
+
ComplexType.new(types.uniq)
|
|
471
494
|
end
|
|
472
495
|
|
|
473
496
|
# When YARD parses an overload tag, it includes rest modifiers in the parameters names.
|
|
@@ -475,6 +498,7 @@ module Solargraph
|
|
|
475
498
|
# @param name [String]
|
|
476
499
|
# @return [::Array(String, ::Symbol)]
|
|
477
500
|
def parse_overload_param(name)
|
|
501
|
+
# @todo this needs to handle mandatory vs not args, kwargs, blocks, etc
|
|
478
502
|
if name.start_with?('**')
|
|
479
503
|
[name[2..-1], :kwrestarg]
|
|
480
504
|
elsif name.start_with?('*')
|
|
@@ -496,6 +520,10 @@ module Solargraph
|
|
|
496
520
|
.join("\n")
|
|
497
521
|
.concat("```\n")
|
|
498
522
|
end
|
|
523
|
+
|
|
524
|
+
protected
|
|
525
|
+
|
|
526
|
+
attr_writer :signatures
|
|
499
527
|
end
|
|
500
528
|
end
|
|
501
529
|
end
|