solargraph 0.51.2 → 0.54.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +1 -3
- data/.github/workflows/typecheck.yml +34 -0
- data/.yardopts +2 -2
- data/CHANGELOG.md +127 -5
- data/README.md +13 -16
- data/SPONSORS.md +1 -7
- data/lib/solargraph/api_map/cache.rb +50 -20
- data/lib/solargraph/api_map/source_to_yard.rb +17 -10
- data/lib/solargraph/api_map/store.rb +60 -15
- data/lib/solargraph/api_map.rb +282 -123
- data/lib/solargraph/bench.rb +3 -2
- data/lib/solargraph/cache.rb +29 -5
- data/lib/solargraph/complex_type/type_methods.rb +122 -39
- data/lib/solargraph/complex_type/unique_type.rb +310 -76
- data/lib/solargraph/complex_type.rb +166 -44
- data/lib/solargraph/convention.rb +0 -1
- data/lib/solargraph/converters/dd.rb +5 -0
- data/lib/solargraph/converters/dl.rb +3 -0
- data/lib/solargraph/converters/dt.rb +3 -0
- data/lib/solargraph/diagnostics/rubocop.rb +8 -7
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +1 -0
- data/lib/solargraph/diagnostics/type_check.rb +1 -0
- data/lib/solargraph/diagnostics.rb +2 -2
- data/lib/solargraph/doc_map.rb +187 -0
- data/lib/solargraph/gem_pins.rb +72 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +22 -5
- data/lib/solargraph/language_server/host/message_worker.rb +49 -5
- data/lib/solargraph/language_server/host/sources.rb +8 -65
- data/lib/solargraph/language_server/host.rb +65 -84
- data/lib/solargraph/language_server/message/base.rb +19 -12
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +3 -1
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +13 -1
- data/lib/solargraph/language_server/message/initialize.rb +19 -2
- 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 +1 -0
- data/lib/solargraph/language_server/message/text_document/hover.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +3 -3
- data/lib/solargraph/language_server/message/text_document.rb +0 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +135 -0
- data/lib/solargraph/language_server/transport/adapter.rb +16 -1
- data/lib/solargraph/language_server/transport/data_reader.rb +2 -0
- data/lib/solargraph/language_server.rb +1 -0
- data/lib/solargraph/library.rb +207 -111
- data/lib/solargraph/location.rb +15 -1
- data/lib/solargraph/page.rb +6 -0
- data/lib/solargraph/parser/comment_ripper.rb +4 -0
- data/lib/solargraph/parser/node_methods.rb +47 -7
- data/lib/solargraph/parser/node_processor/base.rb +11 -1
- data/lib/solargraph/parser/node_processor.rb +1 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -9
- data/lib/solargraph/parser/{legacy → parser_gem}/flawed_builder.rb +3 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_chainer.rb +62 -43
- data/lib/solargraph/parser/parser_gem/node_methods.rb +495 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/alias_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +57 -0
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/begin_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/block_node.rb +3 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/casgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +7 -20
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/gvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/ivasgn_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/lvasgn_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +53 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/namespace_node.rb +2 -2
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/resbody_node.rb +3 -3
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/sclass_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +8 -6
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +56 -0
- data/lib/solargraph/parser/parser_gem.rb +12 -0
- data/lib/solargraph/parser/region.rb +1 -1
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +8 -12
- data/lib/solargraph/pin/base.rb +78 -10
- data/lib/solargraph/pin/base_variable.rb +40 -7
- data/lib/solargraph/pin/block.rb +69 -46
- data/lib/solargraph/pin/callable.rb +147 -0
- data/lib/solargraph/pin/closure.rb +23 -3
- data/lib/solargraph/pin/common.rb +6 -6
- data/lib/solargraph/pin/conversions.rb +36 -5
- data/lib/solargraph/pin/delegated_method.rb +6 -2
- data/lib/solargraph/pin/documenting.rb +25 -32
- data/lib/solargraph/pin/instance_variable.rb +6 -2
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +205 -32
- data/lib/solargraph/pin/namespace.rb +20 -7
- data/lib/solargraph/pin/parameter.rb +41 -36
- data/lib/solargraph/pin/proxy_type.rb +1 -1
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +3 -3
- data/lib/solargraph/pin/signature.rb +8 -14
- data/lib/solargraph/pin.rb +4 -2
- data/lib/solargraph/range.rb +4 -6
- data/lib/solargraph/rbs_map/conversions.rb +326 -76
- data/lib/solargraph/rbs_map/core_fills.rb +16 -33
- data/lib/solargraph/rbs_map/core_map.rb +3 -13
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -8
- data/lib/solargraph/rbs_map.rb +32 -13
- data/lib/solargraph/shell.rb +95 -72
- data/lib/solargraph/source/chain/array.rb +33 -0
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +152 -69
- data/lib/solargraph/source/chain/constant.rb +15 -1
- data/lib/solargraph/source/chain/if.rb +23 -0
- data/lib/solargraph/source/chain/link.rb +17 -2
- data/lib/solargraph/source/chain/or.rb +2 -2
- data/lib/solargraph/source/chain/z_super.rb +3 -3
- data/lib/solargraph/source/chain.rb +85 -26
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +16 -2
- data/lib/solargraph/source/source_chainer.rb +8 -5
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +120 -148
- data/lib/solargraph/source_map/clip.rb +16 -27
- data/lib/solargraph/source_map/data.rb +30 -0
- data/lib/solargraph/source_map/mapper.rb +15 -3
- data/lib/solargraph/source_map.rb +48 -24
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker/rules.rb +6 -1
- data/lib/solargraph/type_checker.rb +150 -39
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +9 -6
- data/lib/solargraph/workspace.rb +30 -3
- data/lib/solargraph/yard_map/cache.rb +6 -0
- data/lib/solargraph/yard_map/helpers.rb +1 -1
- data/lib/solargraph/yard_map/mapper/to_method.rb +16 -3
- data/lib/solargraph/yard_map/mapper.rb +1 -1
- data/lib/solargraph/yard_map/to_method.rb +11 -4
- data/lib/solargraph/yard_map.rb +1 -292
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +6 -4
- data/solargraph.gemspec +7 -6
- metadata +71 -82
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/documentor.rb +0 -76
- data/lib/solargraph/language_server/host/cataloger.rb +0 -56
- data/lib/solargraph/parser/legacy/node_methods.rb +0 -325
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +0 -50
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -55
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -153
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -317
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +0 -85
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +0 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +0 -33
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +0 -75
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -68
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +0 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +0 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +0 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +0 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +0 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +0 -51
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -32
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -279
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -64
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- data/lib/solargraph/rbs_map/core_signs.rb +0 -33
- data/lib/yard-solargraph.rb +0 -33
data/lib/solargraph/pin/block.rb
CHANGED
@@ -2,76 +2,99 @@
|
|
2
2
|
|
3
3
|
module Solargraph
|
4
4
|
module Pin
|
5
|
-
class Block <
|
6
|
-
# The signature of the method that receives this block.
|
7
|
-
#
|
5
|
+
class Block < Callable
|
8
6
|
# @return [Parser::AST::Node]
|
9
7
|
attr_reader :receiver
|
10
8
|
|
11
|
-
# @
|
12
|
-
|
13
|
-
|
9
|
+
# @return [Parser::AST::Node]
|
10
|
+
attr_reader :node
|
11
|
+
|
12
|
+
# @param receiver [Parser::AST::Node, nil]
|
13
|
+
# @param node [Parser::AST::Node, nil]
|
14
|
+
# @param context [ComplexType, nil]
|
15
|
+
# @param args [::Array<Parameter>]
|
16
|
+
def initialize receiver: nil, args: [], context: nil, node: nil, **splat
|
17
|
+
super(**splat, parameters: args)
|
14
18
|
@receiver = receiver
|
15
19
|
@context = context
|
16
|
-
@
|
20
|
+
@return_type = ComplexType.parse('::Proc')
|
21
|
+
@node = node
|
17
22
|
end
|
18
23
|
|
19
24
|
# @param api_map [ApiMap]
|
20
25
|
# @return [void]
|
21
26
|
def rebind api_map
|
22
|
-
@
|
27
|
+
@rebind ||= maybe_rebind(api_map)
|
23
28
|
end
|
24
29
|
|
25
30
|
def binder
|
26
|
-
@
|
31
|
+
@rebind&.defined? ? @rebind : closure.binder
|
27
32
|
end
|
28
33
|
|
29
|
-
# @
|
30
|
-
|
31
|
-
|
34
|
+
# @param yield_types [::Array<ComplexType>]
|
35
|
+
# @param parameters [::Array<Parameter>]
|
36
|
+
#
|
37
|
+
# @return [::Array<ComplexType>]
|
38
|
+
def destructure_yield_types(yield_types, parameters)
|
39
|
+
# yielding a tuple into a block will destructure the tuple
|
40
|
+
if yield_types.length == 1
|
41
|
+
yield_type = yield_types.first
|
42
|
+
return yield_type.all_params if yield_type.tuple? && yield_type.all_params.length == parameters.length
|
43
|
+
end
|
44
|
+
parameters.map.with_index { |_, idx| yield_types[idx] || ComplexType::UNDEFINED }
|
32
45
|
end
|
33
46
|
|
34
|
-
# @
|
35
|
-
|
36
|
-
|
47
|
+
# @param api_map [ApiMap]
|
48
|
+
# @return [::Array<ComplexType>]
|
49
|
+
def typify_parameters(api_map)
|
50
|
+
chain = Parser.chain(receiver, filename, node)
|
51
|
+
clip = api_map.clip_at(location.filename, location.range.start)
|
52
|
+
locals = clip.locals - [self]
|
53
|
+
meths = chain.define(api_map, closure, locals)
|
54
|
+
# @todo Convert logic to use signatures
|
55
|
+
meths.each do |meth|
|
56
|
+
next if meth.block.nil?
|
57
|
+
|
58
|
+
yield_types = meth.block.parameters.map(&:return_type)
|
59
|
+
# 'arguments' is what the method says it will yield to the
|
60
|
+
# block; 'parameters' is what the block accepts
|
61
|
+
argument_types = destructure_yield_types(yield_types, parameters)
|
62
|
+
param_types = argument_types.each_with_index.map do |arg_type, idx|
|
63
|
+
param = parameters[idx]
|
64
|
+
param_type = chain.base.infer(api_map, param, locals)
|
65
|
+
unless arg_type.nil?
|
66
|
+
if arg_type.generic? && param_type.defined?
|
67
|
+
namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
|
68
|
+
arg_type.resolve_generics(namespace_pin, param_type)
|
69
|
+
else
|
70
|
+
arg_type.self_to_type(chain.base.infer(api_map, self, locals)).qualify(api_map, meth.context.namespace)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
return param_types if param_types.all?(&:defined?)
|
75
|
+
end
|
76
|
+
parameters.map { ComplexType::UNDEFINED }
|
37
77
|
end
|
38
78
|
|
39
79
|
private
|
40
80
|
|
41
81
|
# @param api_map [ApiMap]
|
42
|
-
# @return [ComplexType
|
43
|
-
def
|
44
|
-
return
|
45
|
-
|
46
|
-
return nil unless api_map.rebindable_method_names.include?(word)
|
82
|
+
# @return [ComplexType]
|
83
|
+
def maybe_rebind api_map
|
84
|
+
return ComplexType::UNDEFINED unless receiver
|
85
|
+
|
47
86
|
chain = Parser.chain(receiver, location.filename)
|
48
87
|
locals = api_map.source_map(location.filename).locals_at(location)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
61
|
-
# other case without early return, read block yieldself tags
|
62
|
-
receiver_pin = chain.define(api_map, self, locals).first
|
63
|
-
if receiver_pin && receiver_pin.docstring
|
64
|
-
ys = receiver_pin.docstring.tag(:yieldself)
|
65
|
-
if ys && ys.types && !ys.types.empty?
|
66
|
-
target = if chain.links.first.is_a?(Source::Chain::Constant)
|
67
|
-
receiver_pin.full_context.namespace
|
68
|
-
else
|
69
|
-
full_context.namespace
|
70
|
-
end
|
71
|
-
return ComplexType.try_parse(*ys.types).qualify(api_map, receiver_pin.context.namespace).self_to(target)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
nil
|
88
|
+
receiver_pin = chain.define(api_map, closure, locals).first
|
89
|
+
return ComplexType::UNDEFINED unless receiver_pin
|
90
|
+
|
91
|
+
types = receiver_pin.docstring.tag(:yieldreceiver)&.types
|
92
|
+
return ComplexType::UNDEFINED unless types&.any?
|
93
|
+
|
94
|
+
target = chain.base.infer(api_map, receiver_pin, locals)
|
95
|
+
target = full_context unless target.defined?
|
96
|
+
|
97
|
+
ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to_type(target)
|
75
98
|
end
|
76
99
|
end
|
77
100
|
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module Pin
|
5
|
+
class Callable < Closure
|
6
|
+
# @return [self]
|
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 [Enumerable<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 signature [Pin::Signature]
|
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
|
@@ -6,16 +6,19 @@ module Solargraph
|
|
6
6
|
# @return [::Symbol] :class or :instance
|
7
7
|
attr_reader :scope
|
8
8
|
|
9
|
-
|
9
|
+
# @param scope [::Symbol] :class or :instance
|
10
|
+
# @param generics [::Array<Pin::Parameter>, nil]
|
11
|
+
def initialize scope: :class, generics: nil, **splat
|
10
12
|
super(**splat)
|
11
13
|
@scope = scope
|
14
|
+
@generics = generics
|
12
15
|
end
|
13
16
|
|
14
17
|
def context
|
15
18
|
@context ||= begin
|
16
19
|
result = super
|
17
20
|
if scope == :instance
|
18
|
-
|
21
|
+
result.reduce_class_type
|
19
22
|
else
|
20
23
|
result
|
21
24
|
end
|
@@ -26,12 +29,29 @@ module Solargraph
|
|
26
29
|
@binder || context
|
27
30
|
end
|
28
31
|
|
29
|
-
# @return [Array<String>]
|
32
|
+
# @return [::Array<String>]
|
30
33
|
def gates
|
31
34
|
# @todo This check might not be necessary. There should always be a
|
32
35
|
# root pin
|
33
36
|
closure ? closure.gates : ['']
|
34
37
|
end
|
38
|
+
|
39
|
+
# @return [::Array<String>]
|
40
|
+
def generics
|
41
|
+
@generics ||= docstring.tags(:generic).map(&:name)
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String]
|
45
|
+
def to_rbs
|
46
|
+
rbs_generics + return_type.to_rbs
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [String]
|
50
|
+
def rbs_generics
|
51
|
+
return '' if generics.empty?
|
52
|
+
|
53
|
+
'[' + generics.map { |gen| gen.to_s }.join(', ') + '] '
|
54
|
+
end
|
35
55
|
end
|
36
56
|
end
|
37
57
|
end
|
@@ -6,7 +6,7 @@ module Solargraph
|
|
6
6
|
# @return [Location]
|
7
7
|
attr_reader :location
|
8
8
|
|
9
|
-
# @return [Pin::
|
9
|
+
# @return [Pin::Closure, nil]
|
10
10
|
attr_reader :closure
|
11
11
|
|
12
12
|
# @return [String]
|
@@ -46,6 +46,10 @@ module Solargraph
|
|
46
46
|
@path ||= name.empty? ? context.namespace : "#{context.namespace}::#{name}"
|
47
47
|
end
|
48
48
|
|
49
|
+
protected
|
50
|
+
|
51
|
+
attr_writer :context
|
52
|
+
|
49
53
|
private
|
50
54
|
|
51
55
|
# @return [ComplexType]
|
@@ -55,11 +59,7 @@ module Solargraph
|
|
55
59
|
if here.is_a?(Pin::Namespace)
|
56
60
|
return here.return_type
|
57
61
|
elsif here.is_a?(Pin::Method)
|
58
|
-
|
59
|
-
return ComplexType.try_parse(here.context.namespace)
|
60
|
-
else
|
61
|
-
return here.context
|
62
|
-
end
|
62
|
+
return here.context
|
63
63
|
end
|
64
64
|
here = here.closure
|
65
65
|
end
|
@@ -5,7 +5,35 @@ require 'cgi'
|
|
5
5
|
module Solargraph
|
6
6
|
module Pin
|
7
7
|
# @todo Move this stuff. It should be the responsibility of the language server.
|
8
|
+
# @todo abstract methods below should be verified to be overridden
|
9
|
+
# by type checker when mixin included by non-abstract class
|
8
10
|
module Conversions
|
11
|
+
# @!parse
|
12
|
+
# include Documenting
|
13
|
+
# include Common
|
14
|
+
|
15
|
+
# @return [Integer]
|
16
|
+
# @abstract
|
17
|
+
def completion_item_kind
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
|
21
|
+
# @abstract
|
22
|
+
# @return [Boolean]
|
23
|
+
def deprecated?
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
|
27
|
+
# @abstract
|
28
|
+
def probed?
|
29
|
+
raise NotImplementedError
|
30
|
+
end
|
31
|
+
|
32
|
+
# @abstract
|
33
|
+
def proxied?
|
34
|
+
raise NotImplementedError
|
35
|
+
end
|
36
|
+
|
9
37
|
# @return [Hash]
|
10
38
|
def completion_item
|
11
39
|
@completion_item ||= {
|
@@ -34,12 +62,12 @@ module Solargraph
|
|
34
62
|
end
|
35
63
|
end
|
36
64
|
|
37
|
-
# @return [Array<Hash>]
|
65
|
+
# @return [::Array<Hash>]
|
38
66
|
def signature_help
|
39
67
|
[]
|
40
68
|
end
|
41
69
|
|
42
|
-
# @return [String]
|
70
|
+
# @return [String, nil]
|
43
71
|
def detail
|
44
72
|
# This property is not cached in an instance variable because it can
|
45
73
|
# change when pins get proxied.
|
@@ -57,12 +85,14 @@ module Solargraph
|
|
57
85
|
@link_documentation ||= generate_link
|
58
86
|
end
|
59
87
|
|
88
|
+
# @return [String, nil]
|
60
89
|
def text_documentation
|
61
|
-
this_path = path || return_type.tag
|
90
|
+
this_path = path || name || return_type.tag
|
62
91
|
return nil if this_path == 'undefined'
|
63
92
|
escape_brackets this_path
|
64
93
|
end
|
65
94
|
|
95
|
+
# @return [void]
|
66
96
|
def reset_conversions
|
67
97
|
@completion_item = nil
|
68
98
|
@resolve_completion_item = nil
|
@@ -73,11 +103,12 @@ module Solargraph
|
|
73
103
|
|
74
104
|
private
|
75
105
|
|
76
|
-
# @return [String]
|
106
|
+
# @return [String, nil]
|
77
107
|
def generate_link
|
78
|
-
this_path = path || return_type.tag
|
108
|
+
this_path = path || name || return_type.tag
|
79
109
|
return nil if this_path == 'undefined'
|
80
110
|
return nil if this_path.nil? || this_path == 'undefined'
|
111
|
+
return this_path if path.nil?
|
81
112
|
"[#{escape_brackets(this_path).gsub('_', '\\\\_')}](solargraph:/document?query=#{CGI.escape(this_path)})"
|
82
113
|
end
|
83
114
|
|
@@ -11,8 +11,9 @@ module Solargraph
|
|
11
11
|
# given closure/scope, and the delegated method will then be resolved
|
12
12
|
# to a method pin on that type.
|
13
13
|
#
|
14
|
-
# @param
|
15
|
-
# @param receiver [Source::Chain] the source code used to resolve the receiver for this delegated method.
|
14
|
+
# @param method [Method, nil] an already resolved method pin.
|
15
|
+
# @param receiver [Source::Chain, nil] the source code used to resolve the receiver for this delegated method.
|
16
|
+
# @param name [String]
|
16
17
|
# @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name).
|
17
18
|
def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
|
18
19
|
raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
|
@@ -37,6 +38,7 @@ module Solargraph
|
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
41
|
+
# @param api_map [ApiMap]
|
40
42
|
def resolvable?(api_map)
|
41
43
|
resolve_method(api_map)
|
42
44
|
!!@resolved_method
|
@@ -79,6 +81,7 @@ module Solargraph
|
|
79
81
|
# helper to print a source chain as code, probably not 100% correct.
|
80
82
|
#
|
81
83
|
# @param chain [Source::Chain]
|
84
|
+
# @return [String]
|
82
85
|
def print_chain(chain)
|
83
86
|
out = +''
|
84
87
|
chain.links.each_with_index do |link, index|
|
@@ -91,6 +94,7 @@ module Solargraph
|
|
91
94
|
end
|
92
95
|
out << link.word
|
93
96
|
end
|
97
|
+
out
|
94
98
|
end
|
95
99
|
end
|
96
100
|
end
|
@@ -38,23 +38,20 @@ module Solargraph
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def to_s
|
41
|
-
return
|
42
|
-
|
41
|
+
return to_code if code?
|
42
|
+
to_markdown
|
43
43
|
end
|
44
44
|
|
45
45
|
private
|
46
46
|
|
47
|
-
# @param text [String]
|
48
47
|
# @return [String]
|
49
|
-
def
|
50
|
-
#
|
51
|
-
text.gsub('[', '!!!!b').gsub(']', 'e!!!!')
|
48
|
+
def to_code
|
49
|
+
"\n```ruby\n#{Documenting.normalize_indentation(@plaintext)}#{@plaintext.end_with?("\n") ? '' : "\n"}```\n\n"
|
52
50
|
end
|
53
51
|
|
54
|
-
# @param text [String]
|
55
52
|
# @return [String]
|
56
|
-
def
|
57
|
-
|
53
|
+
def to_markdown
|
54
|
+
ReverseMarkdown.convert Kramdown::Document.new(@plaintext, input: 'GFM').to_html
|
58
55
|
end
|
59
56
|
end
|
60
57
|
|
@@ -65,40 +62,36 @@ module Solargraph
|
|
65
62
|
# line and at least two spaces of indentation. This is a common
|
66
63
|
# convention in Ruby core documentation, e.g., String#split.
|
67
64
|
sections = [DocSection.new(false)]
|
68
|
-
normalize_indentation(docstring.to_s
|
69
|
-
if l.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
sections.last.concat l[2..-1]
|
76
|
-
else
|
77
|
-
# Regular documentation
|
78
|
-
sections.push DocSection.new(false) if sections.last.code?
|
79
|
-
sections.last.concat l
|
80
|
-
end
|
65
|
+
Documenting.normalize_indentation(Documenting.strip_html_comments(docstring.to_s.gsub("\t", ' '))).lines.each do |l|
|
66
|
+
if l.start_with?(' ')
|
67
|
+
# Code block
|
68
|
+
sections.push DocSection.new(true) unless sections.last.code?
|
69
|
+
elsif sections.last.code?
|
70
|
+
# Regular documentation
|
71
|
+
sections.push DocSection.new(false)
|
81
72
|
end
|
73
|
+
sections.last.concat l
|
82
74
|
end
|
83
75
|
sections.map(&:to_s).join.strip
|
84
76
|
end
|
85
77
|
end
|
86
78
|
|
87
|
-
private
|
88
|
-
|
89
79
|
# @param text [String]
|
90
80
|
# @return [String]
|
91
|
-
def
|
92
|
-
text.
|
81
|
+
def self.strip_html_comments text
|
82
|
+
text.gsub(/<!--([\s\S]*?)-->/, '').strip
|
93
83
|
end
|
94
84
|
|
95
|
-
# @param
|
85
|
+
# @param text [String]
|
96
86
|
# @return [String]
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
87
|
+
def self.normalize_indentation text
|
88
|
+
left = text.lines.map do |line|
|
89
|
+
match = line.match(/^ +/)
|
90
|
+
next 0 unless match
|
91
|
+
match[0].length
|
92
|
+
end.min
|
93
|
+
return text if left.nil? || left.zero?
|
94
|
+
text.lines.map { |line| line[left..] }.join
|
102
95
|
end
|
103
96
|
end
|
104
97
|
end
|
@@ -3,25 +3,29 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Pin
|
5
5
|
class InstanceVariable < BaseVariable
|
6
|
+
# @return [ComplexType]
|
6
7
|
def binder
|
7
8
|
closure.binder
|
8
9
|
end
|
9
10
|
|
11
|
+
# @return [::Symbol]
|
10
12
|
def scope
|
11
13
|
closure.binder.scope
|
12
14
|
end
|
13
15
|
|
16
|
+
# @return [ComplexType]
|
14
17
|
def context
|
15
18
|
@context ||= begin
|
16
19
|
result = super
|
17
20
|
if scope == :class
|
18
|
-
ComplexType.parse("Class<#{result.
|
21
|
+
ComplexType.parse("::Class<#{result.rooted_namespace}>")
|
19
22
|
else
|
20
|
-
|
23
|
+
result.reduce_class_type
|
21
24
|
end
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
28
|
+
# @param other [InstanceVariable]
|
25
29
|
def nearly? other
|
26
30
|
super && binder == other.binder
|
27
31
|
end
|
@@ -6,12 +6,16 @@ module Solargraph
|
|
6
6
|
# @return [Range]
|
7
7
|
attr_reader :presence
|
8
8
|
|
9
|
+
# @param assignment [AST::Node, nil]
|
10
|
+
# @param presence [Range, nil]
|
11
|
+
# @param splat [Hash]
|
9
12
|
def initialize assignment: nil, presence: nil, **splat
|
10
13
|
super(**splat)
|
11
14
|
@assignment = assignment
|
12
15
|
@presence = presence
|
13
16
|
end
|
14
17
|
|
18
|
+
# @param pin [self]
|
15
19
|
def try_merge! pin
|
16
20
|
return false unless super
|
17
21
|
@presence = pin.presence
|
@@ -21,11 +25,16 @@ module Solargraph
|
|
21
25
|
# @param other_closure [Pin::Closure]
|
22
26
|
# @param other_loc [Location]
|
23
27
|
def visible_at?(other_closure, other_loc)
|
24
|
-
|
28
|
+
location.filename == other_loc.filename &&
|
25
29
|
presence.include?(other_loc.range.start) &&
|
26
30
|
match_named_closure(other_closure, closure)
|
27
31
|
end
|
28
32
|
|
33
|
+
# @return [String]
|
34
|
+
def to_rbs
|
35
|
+
(name || '(anon)') + ' ' + (return_type&.to_rbs || 'untyped')
|
36
|
+
end
|
37
|
+
|
29
38
|
private
|
30
39
|
|
31
40
|
# @param tag1 [String]
|
@@ -40,6 +49,9 @@ module Solargraph
|
|
40
49
|
(['', 'Class<>'].include?(tag1) && ['', 'Class<>'].include?(tag2))
|
41
50
|
end
|
42
51
|
|
52
|
+
# @param needle [Pin::Base]
|
53
|
+
# @param haystack [Pin::Base]
|
54
|
+
# @return [Boolean]
|
43
55
|
def match_named_closure needle, haystack
|
44
56
|
return true if needle == haystack || haystack.is_a?(Pin::Block)
|
45
57
|
cursor = haystack
|