solargraph 0.54.1 → 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 +39 -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 +71 -122
- data/lib/solargraph/api_map.rb +97 -36
- data/lib/solargraph/bench.rb +17 -1
- data/lib/solargraph/complex_type/type_methods.rb +7 -0
- data/lib/solargraph/complex_type/unique_type.rb +109 -8
- data/lib/solargraph/complex_type.rb +48 -18
- 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 +31 -11
- 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/formatting.rb +4 -0
- data/lib/solargraph/library.rb +7 -8
- data/lib/solargraph/location.rb +15 -0
- 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 +17 -23
- data/lib/solargraph/parser/parser_gem/node_methods.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +21 -0
- 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/lvasgn_node.rb +2 -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/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 +1 -0
- data/lib/solargraph/pin/base.rb +35 -19
- data/lib/solargraph/pin/base_variable.rb +10 -3
- data/lib/solargraph/pin/block.rb +3 -3
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +3 -3
- data/lib/solargraph/pin/local_variable.rb +7 -1
- data/lib/solargraph/pin/method.rb +26 -18
- data/lib/solargraph/pin/namespace.rb +10 -7
- data/lib/solargraph/pin/parameter.rb +15 -6
- data/lib/solargraph/pin/proxy_type.rb +12 -6
- data/lib/solargraph/pin/until.rb +18 -0
- data/lib/solargraph/pin/while.rb +18 -0
- data/lib/solargraph/pin.rb +3 -0
- data/lib/solargraph/position.rb +7 -0
- data/lib/solargraph/range.rb +7 -0
- data/lib/solargraph/rbs_map/conversions.rb +16 -10
- data/lib/solargraph/rbs_map/core_fills.rb +10 -3
- data/lib/solargraph/rbs_map.rb +1 -0
- data/lib/solargraph/shell.rb +2 -0
- data/lib/solargraph/source/chain/array.rb +5 -4
- data/lib/solargraph/source/chain/call.rb +55 -19
- 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 +19 -5
- data/lib/solargraph/source/chain/literal.rb +27 -2
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +107 -63
- data/lib/solargraph/source/cursor.rb +1 -11
- data/lib/solargraph/source/source_chainer.rb +2 -2
- data/lib/solargraph/source.rb +2 -1
- data/lib/solargraph/source_map/clip.rb +4 -2
- data/lib/solargraph/type_checker/checks.rb +4 -0
- data/lib/solargraph/type_checker.rb +41 -14
- data/lib/solargraph/version.rb +1 -1
- 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 +39 -25
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
module Pin
|
|
5
5
|
class Parameter < LocalVariable
|
|
6
|
-
# @return [Symbol]
|
|
6
|
+
# @return [::Symbol]
|
|
7
7
|
attr_reader :decl
|
|
8
8
|
|
|
9
9
|
# @return [String]
|
|
@@ -11,12 +11,10 @@ module Solargraph
|
|
|
11
11
|
|
|
12
12
|
# @param decl [::Symbol] :arg, :optarg, :kwarg, :kwoptarg, :restarg, :kwrestarg, :block, :blockarg
|
|
13
13
|
# @param asgn_code [String, nil]
|
|
14
|
-
|
|
15
|
-
def initialize decl: :arg, asgn_code: nil, return_type: nil, **splat
|
|
14
|
+
def initialize decl: :arg, asgn_code: nil, **splat
|
|
16
15
|
super(**splat)
|
|
17
16
|
@asgn_code = asgn_code
|
|
18
17
|
@decl = decl
|
|
19
|
-
@return_type = return_type
|
|
20
18
|
end
|
|
21
19
|
|
|
22
20
|
def keyword?
|
|
@@ -115,12 +113,22 @@ module Solargraph
|
|
|
115
113
|
closure.is_a?(Pin::Block) ? typify_block_param(api_map) : typify_method_param(api_map)
|
|
116
114
|
end
|
|
117
115
|
|
|
116
|
+
# @param atype [ComplexType]
|
|
117
|
+
# @param api_map [ApiMap]
|
|
118
|
+
def compatible_arg?(atype, api_map)
|
|
119
|
+
# make sure we get types from up the method
|
|
120
|
+
# inheritance chain if we don't have them on this pin
|
|
121
|
+
ptype = typify api_map
|
|
122
|
+
ptype.undefined? || ptype.can_assign?(api_map, atype) || ptype.generic?
|
|
123
|
+
end
|
|
124
|
+
|
|
118
125
|
def documentation
|
|
119
126
|
tag = param_tag
|
|
120
127
|
return '' if tag.nil? || tag.text.nil?
|
|
121
128
|
tag.text
|
|
122
129
|
end
|
|
123
130
|
|
|
131
|
+
# @param pin [Pin::Parameter]
|
|
124
132
|
def try_merge! pin
|
|
125
133
|
return false unless super && closure == pin.closure
|
|
126
134
|
true
|
|
@@ -140,8 +148,9 @@ module Solargraph
|
|
|
140
148
|
# @param api_map [ApiMap]
|
|
141
149
|
# @return [ComplexType]
|
|
142
150
|
def typify_block_param api_map
|
|
143
|
-
|
|
144
|
-
|
|
151
|
+
block_pin = closure
|
|
152
|
+
if block_pin.is_a?(Pin::Block) && block_pin.receiver
|
|
153
|
+
return block_pin.typify_parameters(api_map)[index]
|
|
145
154
|
end
|
|
146
155
|
ComplexType::UNDEFINED
|
|
147
156
|
end
|
|
@@ -4,24 +4,30 @@ module Solargraph
|
|
|
4
4
|
module Pin
|
|
5
5
|
class ProxyType < Base
|
|
6
6
|
# @param return_type [ComplexType]
|
|
7
|
-
def initialize return_type: ComplexType::UNDEFINED, **splat
|
|
7
|
+
def initialize return_type: ComplexType::UNDEFINED, binder: nil, **splat
|
|
8
8
|
super(**splat)
|
|
9
9
|
@return_type = return_type
|
|
10
|
+
@binder = binder if binder
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def context
|
|
13
14
|
@return_type
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
# @param
|
|
17
|
+
# @param context [ComplexType, ComplexType::UniqueType] Used as context for this pin
|
|
18
|
+
# @param closure [Pin::Namespace, nil] Used as the closure for this pin
|
|
19
|
+
# @param binder [ComplexType, ComplexType::UniqueType, nil]
|
|
17
20
|
# @return [ProxyType]
|
|
18
|
-
def self.anonymous
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
def self.anonymous context, closure: nil, binder: nil
|
|
22
|
+
unless closure
|
|
23
|
+
parts = context.namespace.split('::')
|
|
24
|
+
namespace = parts[0..-2].join('::').to_s
|
|
25
|
+
closure = Solargraph::Pin::Namespace.new(name: namespace)
|
|
26
|
+
end
|
|
21
27
|
# name = parts.last.to_s
|
|
22
28
|
# ProxyType.new(nil, namespace, name, return_type)
|
|
23
29
|
ProxyType.new(
|
|
24
|
-
closure:
|
|
30
|
+
closure: closure, return_type: context, binder: binder || context
|
|
25
31
|
)
|
|
26
32
|
end
|
|
27
33
|
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
class Until < Base
|
|
6
|
+
include Breakable
|
|
7
|
+
|
|
8
|
+
# @param receiver [Parser::AST::Node, nil]
|
|
9
|
+
# @param node [Parser::AST::Node, nil]
|
|
10
|
+
# @param context [ComplexType, nil]
|
|
11
|
+
# @param args [::Array<Parameter>]
|
|
12
|
+
def initialize node: nil, **splat
|
|
13
|
+
super(**splat)
|
|
14
|
+
@node = node
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
module Pin
|
|
5
|
+
class While < Base
|
|
6
|
+
include Breakable
|
|
7
|
+
|
|
8
|
+
# @param receiver [Parser::AST::Node, nil]
|
|
9
|
+
# @param node [Parser::AST::Node, nil]
|
|
10
|
+
# @param context [ComplexType, nil]
|
|
11
|
+
# @param args [::Array<Parameter>]
|
|
12
|
+
def initialize node: nil, **splat
|
|
13
|
+
super(**splat)
|
|
14
|
+
@node = node
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/lib/solargraph/pin.rb
CHANGED
|
@@ -34,6 +34,9 @@ module Solargraph
|
|
|
34
34
|
autoload :Singleton, 'solargraph/pin/singleton'
|
|
35
35
|
autoload :KeywordParam, 'solargraph/pin/keyword_param'
|
|
36
36
|
autoload :Search, 'solargraph/pin/search'
|
|
37
|
+
autoload :Breakable, 'solargraph/pin/breakable'
|
|
38
|
+
autoload :Until, 'solargraph/pin/until'
|
|
39
|
+
autoload :While, 'solargraph/pin/while'
|
|
37
40
|
autoload :Callable, 'solargraph/pin/callable'
|
|
38
41
|
|
|
39
42
|
ROOT_PIN = Pin::Namespace.new(type: :class, name: '', closure: nil)
|
data/lib/solargraph/position.rb
CHANGED
|
@@ -4,6 +4,8 @@ module Solargraph
|
|
|
4
4
|
# The zero-based line and column numbers of a position in a string.
|
|
5
5
|
#
|
|
6
6
|
class Position
|
|
7
|
+
include Equality
|
|
8
|
+
|
|
7
9
|
# @return [Integer]
|
|
8
10
|
attr_reader :line
|
|
9
11
|
|
|
@@ -19,6 +21,11 @@ module Solargraph
|
|
|
19
21
|
@character = character
|
|
20
22
|
end
|
|
21
23
|
|
|
24
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
25
|
+
protected def equality_fields
|
|
26
|
+
[line, character]
|
|
27
|
+
end
|
|
28
|
+
|
|
22
29
|
# Get a hash of the position. This representation is suitable for use in
|
|
23
30
|
# the language server protocol.
|
|
24
31
|
#
|
data/lib/solargraph/range.rb
CHANGED
|
@@ -4,6 +4,8 @@ module Solargraph
|
|
|
4
4
|
# A pair of Positions that compose a section of text in code.
|
|
5
5
|
#
|
|
6
6
|
class Range
|
|
7
|
+
include Equality
|
|
8
|
+
|
|
7
9
|
# @return [Position]
|
|
8
10
|
attr_reader :start
|
|
9
11
|
|
|
@@ -17,6 +19,11 @@ module Solargraph
|
|
|
17
19
|
@ending = ending
|
|
18
20
|
end
|
|
19
21
|
|
|
22
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
23
|
+
protected def equality_fields
|
|
24
|
+
[start, ending]
|
|
25
|
+
end
|
|
26
|
+
|
|
20
27
|
# Get a hash of the range. This representation is suitable for use in
|
|
21
28
|
# the language server protocol.
|
|
22
29
|
#
|
|
@@ -80,9 +80,12 @@ module Solargraph
|
|
|
80
80
|
# @param closure [Pin::Namespace]
|
|
81
81
|
# @return [void]
|
|
82
82
|
def convert_self_type_to_pins decl, closure
|
|
83
|
+
type = build_type(decl.name, decl.args)
|
|
84
|
+
generic_values = type.all_params.map(&:to_s)
|
|
83
85
|
include_pin = Solargraph::Pin::Reference::Include.new(
|
|
84
86
|
name: decl.name.relative!.to_s,
|
|
85
87
|
type_location: location_decl_to_pin_location(decl.location),
|
|
88
|
+
generic_values: generic_values,
|
|
86
89
|
closure: closure
|
|
87
90
|
)
|
|
88
91
|
pins.push include_pin
|
|
@@ -318,7 +321,7 @@ module Solargraph
|
|
|
318
321
|
# @return [void]
|
|
319
322
|
def method_def_to_sigs decl, pin
|
|
320
323
|
decl.overloads.map do |overload|
|
|
321
|
-
generics = overload.method_type.type_params.map(&:to_s)
|
|
324
|
+
generics = overload.method_type.type_params.map(&:name).map(&:to_s)
|
|
322
325
|
signature_parameters, signature_return_type = parts_of_function(overload.method_type, pin)
|
|
323
326
|
block = if overload.method_type.block
|
|
324
327
|
block_parameters, block_return_type = parts_of_function(overload.method_type.block, pin)
|
|
@@ -348,34 +351,34 @@ module Solargraph
|
|
|
348
351
|
parameters = []
|
|
349
352
|
arg_num = -1
|
|
350
353
|
type.type.required_positionals.each do |param|
|
|
351
|
-
name = param.name ? param.name.to_s : "
|
|
354
|
+
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
352
355
|
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin, return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
|
|
353
356
|
end
|
|
354
357
|
type.type.optional_positionals.each do |param|
|
|
355
|
-
name = param.name ? param.name.to_s : "
|
|
358
|
+
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
356
359
|
parameters.push Solargraph::Pin::Parameter.new(decl: :optarg, name: name, closure: pin,
|
|
357
360
|
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
|
|
358
361
|
end
|
|
359
362
|
if type.type.rest_positionals
|
|
360
|
-
name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "
|
|
363
|
+
name = type.type.rest_positionals.name ? type.type.rest_positionals.name.to_s : "arg_#{arg_num += 1}"
|
|
361
364
|
parameters.push Solargraph::Pin::Parameter.new(decl: :restarg, name: name, closure: pin)
|
|
362
365
|
end
|
|
363
366
|
type.type.trailing_positionals.each do |param|
|
|
364
|
-
name = param.name ? param.name.to_s : "
|
|
367
|
+
name = param.name ? param.name.to_s : "arg_#{arg_num += 1}"
|
|
365
368
|
parameters.push Solargraph::Pin::Parameter.new(decl: :arg, name: name, closure: pin)
|
|
366
369
|
end
|
|
367
370
|
type.type.required_keywords.each do |orig, param|
|
|
368
|
-
name = orig ? orig.to_s : "
|
|
371
|
+
name = orig ? orig.to_s : "arg_#{arg_num += 1}"
|
|
369
372
|
parameters.push Solargraph::Pin::Parameter.new(decl: :kwarg, name: name, closure: pin,
|
|
370
373
|
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
|
|
371
374
|
end
|
|
372
375
|
type.type.optional_keywords.each do |orig, param|
|
|
373
|
-
name = orig ? orig.to_s : "
|
|
376
|
+
name = orig ? orig.to_s : "arg_#{arg_num += 1}"
|
|
374
377
|
parameters.push Solargraph::Pin::Parameter.new(decl: :kwoptarg, name: name, closure: pin,
|
|
375
378
|
return_type: ComplexType.try_parse(other_type_to_tag(param.type)).force_rooted)
|
|
376
379
|
end
|
|
377
380
|
if type.type.rest_keywords
|
|
378
|
-
name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "
|
|
381
|
+
name = type.type.rest_keywords.name ? type.type.rest_keywords.name.to_s : "arg_#{arg_num += 1}"
|
|
379
382
|
parameters.push Solargraph::Pin::Parameter.new(decl: :kwrestarg, name: type.type.rest_keywords.name.to_s, closure: pin)
|
|
380
383
|
end
|
|
381
384
|
|
|
@@ -572,7 +575,7 @@ module Solargraph
|
|
|
572
575
|
elsif type.is_a?(RBS::Types::Tuple)
|
|
573
576
|
"Array(#{type.types.map { |t| other_type_to_tag(t) }.join(', ')})"
|
|
574
577
|
elsif type.is_a?(RBS::Types::Literal)
|
|
575
|
-
type.literal.
|
|
578
|
+
type.literal.inspect
|
|
576
579
|
elsif type.is_a?(RBS::Types::Union)
|
|
577
580
|
type.types.map { |t| other_type_to_tag(t) }.join(', ')
|
|
578
581
|
elsif type.is_a?(RBS::Types::Record)
|
|
@@ -628,9 +631,12 @@ module Solargraph
|
|
|
628
631
|
def add_mixins decl, namespace
|
|
629
632
|
decl.each_mixin do |mixin|
|
|
630
633
|
klass = mixin.is_a?(RBS::AST::Members::Include) ? Pin::Reference::Include : Pin::Reference::Extend
|
|
634
|
+
type = build_type(mixin.name, mixin.args)
|
|
635
|
+
generic_values = type.all_params.map(&:to_s)
|
|
631
636
|
pins.push klass.new(
|
|
632
637
|
name: mixin.name.relative!.to_s,
|
|
633
|
-
|
|
638
|
+
type_location: location_decl_to_pin_location(mixin.location),
|
|
639
|
+
generic_values: generic_values,
|
|
634
640
|
closure: namespace
|
|
635
641
|
)
|
|
636
642
|
end
|
|
@@ -16,8 +16,6 @@ module Solargraph
|
|
|
16
16
|
].map { |k| Pin::Keyword.new(k) }
|
|
17
17
|
|
|
18
18
|
MISSING = [
|
|
19
|
-
Solargraph::Pin::Method.new(name: 'tap', scope: :instance,
|
|
20
|
-
closure: Solargraph::Pin::Namespace.new(name: 'Object')),
|
|
21
19
|
Solargraph::Pin::Method.new(name: 'class', scope: :instance,
|
|
22
20
|
closure: Solargraph::Pin::Namespace.new(name: 'Object'), comments: '@return [::Class<self>]')
|
|
23
21
|
]
|
|
@@ -35,6 +33,15 @@ module Solargraph
|
|
|
35
33
|
Override.method_return('Class#allocate', 'self')
|
|
36
34
|
]
|
|
37
35
|
|
|
36
|
+
# @todo I don't see any direct link in RBS to build this from -
|
|
37
|
+
# presumably RBS is using duck typing to match interfaces
|
|
38
|
+
# against concrete classes
|
|
39
|
+
INCLUDES = [
|
|
40
|
+
Solargraph::Pin::Reference::Include.new(name: '_ToAry',
|
|
41
|
+
closure: Solargraph::Pin::Namespace.new(name: 'Array'),
|
|
42
|
+
generic_values: ['generic<Elem>'])
|
|
43
|
+
]
|
|
44
|
+
|
|
38
45
|
# HACK: Add Errno exception classes
|
|
39
46
|
errno = Solargraph::Pin::Namespace.new(name: 'Errno')
|
|
40
47
|
errnos = []
|
|
@@ -44,7 +51,7 @@ module Solargraph
|
|
|
44
51
|
end
|
|
45
52
|
ERRNOS = errnos
|
|
46
53
|
|
|
47
|
-
ALL = KEYWORDS + MISSING + OVERRIDES + ERRNOS
|
|
54
|
+
ALL = KEYWORDS + MISSING + OVERRIDES + ERRNOS + INCLUDES
|
|
48
55
|
end
|
|
49
56
|
end
|
|
50
57
|
end
|
data/lib/solargraph/rbs_map.rb
CHANGED
data/lib/solargraph/shell.rb
CHANGED
|
@@ -111,6 +111,7 @@ module Solargraph
|
|
|
111
111
|
also be specified to clear cached system documentation.
|
|
112
112
|
Documentation will be regenerated as needed.
|
|
113
113
|
)
|
|
114
|
+
# @param gems [Array<String>]
|
|
114
115
|
# @return [void]
|
|
115
116
|
def uncache *gems
|
|
116
117
|
raise ArgumentError, 'No gems specified.' if gems.empty?
|
|
@@ -133,6 +134,7 @@ module Solargraph
|
|
|
133
134
|
|
|
134
135
|
desc 'gems [GEM[=VERSION]]', 'Cache documentation for installed gems'
|
|
135
136
|
option :rebuild, type: :boolean, desc: 'Rebuild existing documentation', default: false
|
|
137
|
+
# @param names [Array<String>]
|
|
136
138
|
# @return [void]
|
|
137
139
|
def gems *names
|
|
138
140
|
if names.empty?
|
|
@@ -3,8 +3,9 @@ module Solargraph
|
|
|
3
3
|
class Chain
|
|
4
4
|
class Array < Literal
|
|
5
5
|
# @param children [::Array<Chain>]
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
# @param node [Parser::AST::Node]
|
|
7
|
+
def initialize children, node
|
|
8
|
+
super('::Array', node)
|
|
8
9
|
@children = children
|
|
9
10
|
end
|
|
10
11
|
|
|
@@ -14,10 +15,10 @@ module Solargraph
|
|
|
14
15
|
|
|
15
16
|
# @param api_map [ApiMap]
|
|
16
17
|
# @param name_pin [Pin::Base]
|
|
17
|
-
# @param locals [
|
|
18
|
+
# @param locals [::Array<Pin::Parameter, Pin::LocalVariable>]
|
|
18
19
|
def resolve api_map, name_pin, locals
|
|
19
20
|
child_types = @children.map do |child|
|
|
20
|
-
child.infer(api_map, name_pin, locals)
|
|
21
|
+
child.infer(api_map, name_pin, locals).simplify_literals
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
type = if child_types.uniq.length == 1 && child_types.first.defined?
|
|
@@ -3,12 +3,20 @@
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
class Source
|
|
5
5
|
class Chain
|
|
6
|
+
#
|
|
7
|
+
# Handles both method calls and local variable references by
|
|
8
|
+
# first looking for a variable with the name 'word', then
|
|
9
|
+
# proceeding to method signature resolution if not found.
|
|
10
|
+
#
|
|
6
11
|
class Call < Chain::Link
|
|
7
12
|
include Solargraph::Parser::NodeMethods
|
|
8
13
|
|
|
9
14
|
# @return [String]
|
|
10
15
|
attr_reader :word
|
|
11
16
|
|
|
17
|
+
# @return [Location]
|
|
18
|
+
attr_reader :location
|
|
19
|
+
|
|
12
20
|
# @return [::Array<Chain>]
|
|
13
21
|
attr_reader :arguments
|
|
14
22
|
|
|
@@ -16,34 +24,42 @@ module Solargraph
|
|
|
16
24
|
attr_reader :block
|
|
17
25
|
|
|
18
26
|
# @param word [String]
|
|
27
|
+
# @param location [Location, nil]
|
|
19
28
|
# @param arguments [::Array<Chain>]
|
|
20
29
|
# @param block [Chain, nil]
|
|
21
|
-
def initialize word, arguments = [], block = nil
|
|
30
|
+
def initialize word, location = nil, arguments = [], block = nil
|
|
22
31
|
@word = word
|
|
32
|
+
@location = location
|
|
23
33
|
@arguments = arguments
|
|
24
34
|
@block = block
|
|
25
35
|
fix_block_pass
|
|
26
36
|
end
|
|
27
37
|
|
|
38
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
39
|
+
protected def equality_fields
|
|
40
|
+
super + [arguments, block]
|
|
41
|
+
end
|
|
42
|
+
|
|
28
43
|
def with_block?
|
|
29
44
|
!!@block
|
|
30
45
|
end
|
|
31
46
|
|
|
32
47
|
# @param api_map [ApiMap]
|
|
33
|
-
# @param name_pin [Pin::Closure] name_pin.binder should give us the object on which 'word' will be invoked
|
|
48
|
+
# @param name_pin [Pin::Closure] name_pin.binder should give us the type of the object on which 'word' will be invoked
|
|
34
49
|
# @param locals [::Array<Pin::LocalVariable>]
|
|
35
50
|
def resolve api_map, name_pin, locals
|
|
36
51
|
return super_pins(api_map, name_pin) if word == 'super'
|
|
37
52
|
return yield_pins(api_map, name_pin) if word == 'yield'
|
|
38
53
|
found = if head?
|
|
39
|
-
locals
|
|
54
|
+
api_map.visible_pins(locals, word, name_pin, location)
|
|
40
55
|
else
|
|
41
56
|
[]
|
|
42
57
|
end
|
|
43
58
|
return inferred_pins(found, api_map, name_pin, locals) unless found.empty?
|
|
44
59
|
pins = name_pin.binder.each_unique_type.flat_map do |context|
|
|
45
|
-
|
|
46
|
-
api_map.get_method_stack(
|
|
60
|
+
ns_tag = context.namespace == '' ? '' : context.namespace_type.tag
|
|
61
|
+
stack = api_map.get_method_stack(ns_tag, word, scope: context.scope)
|
|
62
|
+
[stack.first].compact
|
|
47
63
|
end
|
|
48
64
|
return [] if pins.empty?
|
|
49
65
|
inferred_pins(pins, api_map, name_pin, locals)
|
|
@@ -54,7 +70,7 @@ module Solargraph
|
|
|
54
70
|
# @param pins [::Enumerable<Pin::Method>]
|
|
55
71
|
# @param api_map [ApiMap]
|
|
56
72
|
# @param name_pin [Pin::Base]
|
|
57
|
-
# @param locals [::Array<Pin::LocalVariable>]
|
|
73
|
+
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
58
74
|
# @return [::Array<Pin::Base>]
|
|
59
75
|
def inferred_pins pins, api_map, name_pin, locals
|
|
60
76
|
result = pins.map do |p|
|
|
@@ -67,7 +83,8 @@ module Solargraph
|
|
|
67
83
|
# use it. If we didn't pass a block, the logic below will
|
|
68
84
|
# reject it regardless
|
|
69
85
|
|
|
70
|
-
|
|
86
|
+
with_block, without_block = overloads.partition(&:block?)
|
|
87
|
+
sorted_overloads = with_block + without_block
|
|
71
88
|
new_signature_pin = nil
|
|
72
89
|
sorted_overloads.each do |ol|
|
|
73
90
|
next unless ol.arity_matches?(arguments, with_block?)
|
|
@@ -80,11 +97,9 @@ module Solargraph
|
|
|
80
97
|
match = ol.parameters.any?(&:restarg?)
|
|
81
98
|
break
|
|
82
99
|
end
|
|
100
|
+
|
|
83
101
|
atype = atypes[idx] ||= arg.infer(api_map, Pin::ProxyType.anonymous(name_pin.context), locals)
|
|
84
|
-
|
|
85
|
-
# @todo Weak type comparison
|
|
86
|
-
# unless atype.tag == param.return_type.tag || api_map.super_and_sub?(param.return_type.tag, atype.tag)
|
|
87
|
-
unless param.return_type.undefined? || atype.name == param.return_type.name || api_map.super_and_sub?(param.return_type.name, atype.name) || param.return_type.generic?
|
|
102
|
+
unless param.compatible_arg?(atype, api_map) || param.restarg?
|
|
88
103
|
match = false
|
|
89
104
|
break
|
|
90
105
|
end
|
|
@@ -101,7 +116,27 @@ module Solargraph
|
|
|
101
116
|
end
|
|
102
117
|
new_signature_pin = ol.resolve_generics_from_context_until_complete(ol.generics, atypes, nil, nil, blocktype)
|
|
103
118
|
new_return_type = new_signature_pin.return_type
|
|
104
|
-
|
|
119
|
+
if head?
|
|
120
|
+
# If we're at the head of the chain, we called a
|
|
121
|
+
# method somewhere that marked itself as returning
|
|
122
|
+
# self. Given we didn't invoke this on an object,
|
|
123
|
+
# this must be a method in this same class - so we
|
|
124
|
+
# use our own self type
|
|
125
|
+
self_type = name_pin.context
|
|
126
|
+
else
|
|
127
|
+
# if we're past the head in the chain, whatever the
|
|
128
|
+
# type of the lhs side is what 'self' will be in its
|
|
129
|
+
# declaration - we can't just use the type of the
|
|
130
|
+
# method pin, as this might be a subclass of the
|
|
131
|
+
# place where the method is defined
|
|
132
|
+
self_type = name_pin.binder
|
|
133
|
+
end
|
|
134
|
+
# This same logic applies to the YARD work done by
|
|
135
|
+
# 'with_params()'.
|
|
136
|
+
#
|
|
137
|
+
# qualify(), however, happens in the namespace where
|
|
138
|
+
# the docs were written - from the method pin.
|
|
139
|
+
type = with_params(new_return_type.self_to_type(self_type), self_type).qualify(api_map, p.namespace) if new_return_type.defined?
|
|
105
140
|
type ||= ComplexType::UNDEFINED
|
|
106
141
|
end
|
|
107
142
|
break if type.defined?
|
|
@@ -117,13 +152,14 @@ module Solargraph
|
|
|
117
152
|
end
|
|
118
153
|
p
|
|
119
154
|
end
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
155
|
+
logger.debug { "Call#inferred_pins(name_pin.binder=#{name_pin.binder}, word=#{word}, pins=#{pins.map(&:desc)}, name_pin=#{name_pin}) - result=#{result}" }
|
|
156
|
+
out = result.map do |pin|
|
|
157
|
+
if pin.path == 'Class#new' && name_pin.binder.tag != 'Class'
|
|
158
|
+
reduced_context = name_pin.binder.reduce_class_type
|
|
123
159
|
pin.proxy(reduced_context)
|
|
124
160
|
else
|
|
125
161
|
next pin if pin.return_type.undefined?
|
|
126
|
-
selfy = pin.return_type.self_to_type(name_pin.
|
|
162
|
+
selfy = pin.return_type.self_to_type(name_pin.binder)
|
|
127
163
|
selfy == pin.return_type ? pin : pin.proxy(selfy)
|
|
128
164
|
end
|
|
129
165
|
end
|
|
@@ -132,7 +168,7 @@ module Solargraph
|
|
|
132
168
|
# @param pin [Pin::Base]
|
|
133
169
|
# @param api_map [ApiMap]
|
|
134
170
|
# @param context [ComplexType]
|
|
135
|
-
# @param locals [
|
|
171
|
+
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
136
172
|
# @return [Pin::Base]
|
|
137
173
|
def process_macro pin, api_map, context, locals
|
|
138
174
|
pin.macros.each do |macro|
|
|
@@ -151,7 +187,7 @@ module Solargraph
|
|
|
151
187
|
# @param pin [Pin::Method]
|
|
152
188
|
# @param api_map [ApiMap]
|
|
153
189
|
# @param context [ComplexType]
|
|
154
|
-
# @param locals [
|
|
190
|
+
# @param locals [::Array<Solargraph::Pin::LocalVariable, Solargraph::Pin::Parameter>]
|
|
155
191
|
# @return [Pin::ProxyType]
|
|
156
192
|
def process_directive pin, api_map, context, locals
|
|
157
193
|
pin.directives.each do |dir|
|
|
@@ -167,7 +203,7 @@ module Solargraph
|
|
|
167
203
|
# @param macro [YARD::Tags::MacroDirective]
|
|
168
204
|
# @param api_map [ApiMap]
|
|
169
205
|
# @param context [ComplexType]
|
|
170
|
-
# @param locals [
|
|
206
|
+
# @param locals [::Array<Pin::LocalVariable, Pin::Parameter>]
|
|
171
207
|
# @return [Pin::ProxyType]
|
|
172
208
|
def inner_process_macro pin, macro, api_map, context, locals
|
|
173
209
|
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
|
@@ -5,12 +5,18 @@ module Solargraph
|
|
|
5
5
|
class Chain
|
|
6
6
|
class Hash < Literal
|
|
7
7
|
# @param type [String]
|
|
8
|
+
# @param node [Parser::AST::Node]
|
|
8
9
|
# @param splatted [Boolean]
|
|
9
|
-
def initialize type, splatted = false
|
|
10
|
-
super(type)
|
|
10
|
+
def initialize type, node, splatted = false
|
|
11
|
+
super(type, node)
|
|
11
12
|
@splatted = splatted
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
16
|
+
protected def equality_fields
|
|
17
|
+
super + [@splatted]
|
|
18
|
+
end
|
|
19
|
+
|
|
14
20
|
def word
|
|
15
21
|
@word ||= "<#{@type}>"
|
|
16
22
|
end
|
|
@@ -13,6 +13,11 @@ module Solargraph
|
|
|
13
13
|
@links = links
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
17
|
+
protected def equality_fields
|
|
18
|
+
super + [@links]
|
|
19
|
+
end
|
|
20
|
+
|
|
16
21
|
def resolve api_map, name_pin, locals
|
|
17
22
|
types = @links.map { |link| link.infer(api_map, name_pin, locals) }
|
|
18
23
|
[Solargraph::Pin::ProxyType.anonymous(Solargraph::ComplexType.try_parse(types.map(&:tag).uniq.join(', ')))]
|
|
@@ -4,6 +4,8 @@ module Solargraph
|
|
|
4
4
|
class Source
|
|
5
5
|
class Chain
|
|
6
6
|
class Link
|
|
7
|
+
include Equality
|
|
8
|
+
|
|
7
9
|
# @return [String]
|
|
8
10
|
attr_reader :word
|
|
9
11
|
|
|
@@ -15,6 +17,11 @@ module Solargraph
|
|
|
15
17
|
@word = word
|
|
16
18
|
end
|
|
17
19
|
|
|
20
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
21
|
+
protected def equality_fields
|
|
22
|
+
[self.class, word]
|
|
23
|
+
end
|
|
24
|
+
|
|
18
25
|
def undefined?
|
|
19
26
|
word == '<undefined>'
|
|
20
27
|
end
|
|
@@ -31,18 +38,23 @@ module Solargraph
|
|
|
31
38
|
[]
|
|
32
39
|
end
|
|
33
40
|
|
|
41
|
+
# debugging description of contents; not for machine use
|
|
42
|
+
def desc
|
|
43
|
+
word
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_s
|
|
47
|
+
desc
|
|
48
|
+
end
|
|
49
|
+
|
|
34
50
|
def inspect
|
|
35
|
-
"
|
|
51
|
+
"#<#{self.class} - `#{self.desc}`>"
|
|
36
52
|
end
|
|
37
53
|
|
|
38
54
|
def head?
|
|
39
55
|
@head ||= false
|
|
40
56
|
end
|
|
41
57
|
|
|
42
|
-
def == other
|
|
43
|
-
self.class == other.class and word == other.word
|
|
44
|
-
end
|
|
45
|
-
|
|
46
58
|
# Make a copy of this link marked as the head of a chain
|
|
47
59
|
#
|
|
48
60
|
# @return [self]
|
|
@@ -70,6 +82,8 @@ module Solargraph
|
|
|
70
82
|
"#<#{self.class} - `#{self.desc}`>"
|
|
71
83
|
end
|
|
72
84
|
|
|
85
|
+
include Logging
|
|
86
|
+
|
|
73
87
|
protected
|
|
74
88
|
|
|
75
89
|
# Mark whether this link is the head of a chain
|