solargraph 0.47.2 → 0.54.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +1 -0
- data/.github/workflows/plugins.yml +40 -0
- data/.github/workflows/rspec.yml +4 -8
- data/.github/workflows/typecheck.yml +34 -0
- data/.yardopts +2 -2
- data/CHANGELOG.md +166 -3
- data/LICENSE +1 -1
- data/README.md +19 -16
- data/SPONSORS.md +2 -9
- 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 +68 -15
- data/lib/solargraph/api_map.rb +238 -112
- data/lib/solargraph/bench.rb +3 -2
- data/lib/solargraph/cache.rb +77 -0
- data/lib/solargraph/complex_type/type_methods.rb +116 -35
- data/lib/solargraph/complex_type/unique_type.rb +261 -33
- data/lib/solargraph/complex_type.rb +149 -30
- data/lib/solargraph/convention/rakefile.rb +17 -0
- data/lib/solargraph/convention.rb +2 -3
- 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 +23 -8
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +4 -1
- 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 +4 -0
- data/lib/solargraph/language_server/host/sources.rb +8 -65
- data/lib/solargraph/language_server/host.rb +88 -93
- data/lib/solargraph/language_server/message/base.rb +1 -1
- 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/extended/download_core.rb +1 -5
- data/lib/solargraph/language_server/message/initialize.rb +27 -0
- data/lib/solargraph/language_server/message/initialized.rb +1 -0
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +4 -1
- data/lib/solargraph/language_server/message/text_document/formatting.rb +5 -4
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +1 -6
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +24 -0
- data/lib/solargraph/language_server/message/text_document.rb +1 -1
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +5 -0
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +10 -3
- data/lib/solargraph/language_server/message.rb +1 -0
- data/lib/solargraph/language_server/progress.rb +118 -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 +231 -104
- data/lib/solargraph/location.rb +1 -0
- 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 +57 -41
- 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 +53 -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 +14 -4
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{rubyvm → 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 +2 -2
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +47 -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/parser_gem/node_processors/sclass_node.rb +42 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/send_node.rb +7 -5
- data/lib/solargraph/parser/{legacy → 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 +9 -10
- data/lib/solargraph/pin/base.rb +69 -11
- data/lib/solargraph/pin/base_variable.rb +40 -7
- data/lib/solargraph/pin/block.rb +81 -33
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +34 -8
- data/lib/solargraph/pin/delegated_method.rb +101 -0
- data/lib/solargraph/pin/documenting.rb +25 -32
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +273 -17
- data/lib/solargraph/pin/namespace.rb +17 -1
- data/lib/solargraph/pin/parameter.rb +40 -28
- data/lib/solargraph/pin/reference/override.rb +2 -2
- data/lib/solargraph/pin/reference.rb +8 -0
- data/lib/solargraph/pin/search.rb +4 -4
- data/lib/solargraph/pin/signature.rb +143 -0
- data/lib/solargraph/pin.rb +2 -1
- data/lib/solargraph/range.rb +4 -6
- data/lib/solargraph/rbs_map/conversions.rb +607 -0
- data/lib/solargraph/rbs_map/core_fills.rb +50 -0
- data/lib/solargraph/rbs_map/core_map.rb +28 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -0
- data/lib/solargraph/rbs_map.rb +92 -0
- data/lib/solargraph/shell.rb +85 -59
- data/lib/solargraph/source/chain/array.rb +32 -0
- data/lib/solargraph/source/chain/block_symbol.rb +13 -0
- data/lib/solargraph/source/chain/call.rb +125 -61
- 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 +8 -2
- data/lib/solargraph/source/chain/or.rb +1 -1
- data/lib/solargraph/source/chain/z_super.rb +3 -3
- data/lib/solargraph/source/chain.rb +64 -14
- data/lib/solargraph/source/change.rb +3 -0
- data/lib/solargraph/source/cursor.rb +2 -0
- data/lib/solargraph/source/source_chainer.rb +8 -5
- data/lib/solargraph/source/updater.rb +1 -0
- data/lib/solargraph/source.rb +18 -63
- data/lib/solargraph/source_map/clip.rb +31 -23
- data/lib/solargraph/source_map/mapper.rb +23 -7
- data/lib/solargraph/source_map.rb +36 -11
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +229 -100
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/environment.erb +2 -2
- data/lib/solargraph/workspace/config.rb +15 -11
- data/lib/solargraph/workspace.rb +41 -17
- 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 +23 -7
- 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 -443
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +8 -6
- data/solargraph.gemspec +19 -8
- metadata +164 -99
- data/.travis.yml +0 -19
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/compat.rb +0 -37
- data/lib/solargraph/convention/rspec.rb +0 -30
- 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 -35
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +0 -15
- data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/def_node.rb +0 -63
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +0 -21
- data/lib/solargraph/parser/legacy/node_processors.rb +0 -54
- data/lib/solargraph/parser/legacy.rb +0 -12
- data/lib/solargraph/parser/rubyvm/class_methods.rb +0 -144
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +0 -160
- data/lib/solargraph/parser/rubyvm/node_methods.rb +0 -315
- 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 -22
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +0 -57
- 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 -45
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +0 -21
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +0 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +0 -277
- data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +0 -18
- data/lib/solargraph/parser/rubyvm/node_processors.rb +0 -63
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- data/lib/solargraph/yard_map/core_docs.rb +0 -170
- data/lib/solargraph/yard_map/core_fills.rb +0 -208
- data/lib/solargraph/yard_map/core_gen.rb +0 -76
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +0 -140
- data/lib/solargraph/yard_map/stdlib_fills.rb +0 -43
- data/lib/yard-solargraph.rb +0 -33
- data/yardoc/2.2.2.tar.gz +0 -0
data/lib/solargraph/pin/block.rb
CHANGED
@@ -3,70 +3,118 @@
|
|
3
3
|
module Solargraph
|
4
4
|
module Pin
|
5
5
|
class Block < Closure
|
6
|
-
# The signature of the method that receives this block.
|
7
|
-
#
|
8
6
|
# @return [Parser::AST::Node]
|
9
7
|
attr_reader :receiver
|
10
8
|
|
11
|
-
# @
|
12
|
-
|
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
|
13
17
|
super(**splat)
|
14
18
|
@receiver = receiver
|
15
19
|
@context = context
|
16
20
|
@parameters = args
|
21
|
+
@return_type = ComplexType.parse('::Proc')
|
22
|
+
@node = node
|
17
23
|
end
|
18
24
|
|
19
25
|
# @param api_map [ApiMap]
|
20
26
|
# @return [void]
|
21
27
|
def rebind api_map
|
22
|
-
@
|
28
|
+
@rebind ||= maybe_rebind(api_map)
|
23
29
|
end
|
24
30
|
|
25
31
|
def binder
|
26
|
-
@
|
32
|
+
@rebind&.defined? ? @rebind : closure.binder
|
27
33
|
end
|
28
34
|
|
29
|
-
# @return [Array<Parameter>]
|
35
|
+
# @return [::Array<Parameter>]
|
30
36
|
def parameters
|
31
37
|
@parameters ||= []
|
32
38
|
end
|
33
39
|
|
34
|
-
# @return [Array<String>]
|
40
|
+
# @return [::Array<String>]
|
35
41
|
def parameter_names
|
36
42
|
@parameter_names ||= parameters.map(&:name)
|
37
43
|
end
|
38
44
|
|
45
|
+
# @param yield_types [::Array<ComplexType>]
|
46
|
+
# @param parameters [::Array<Parameter>]
|
47
|
+
#
|
48
|
+
# @return [::Array<ComplexType>]
|
49
|
+
def destructure_yield_types(yield_types, parameters)
|
50
|
+
return yield_types if yield_types.length == parameters.length
|
51
|
+
|
52
|
+
# yielding a tuple into a block will destructure the tuple
|
53
|
+
if yield_types.length == 1
|
54
|
+
yield_type = yield_types.first
|
55
|
+
return yield_type.all_params if yield_type.tuple? && yield_type.all_params.length == parameters.length
|
56
|
+
end
|
57
|
+
parameters.map { ComplexType::UNDEFINED }
|
58
|
+
end
|
59
|
+
|
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
|
+
# @param api_map [ApiMap]
|
68
|
+
# @return [::Array<ComplexType>]
|
69
|
+
def typify_parameters(api_map)
|
70
|
+
chain = Parser.chain(receiver, filename, node)
|
71
|
+
clip = api_map.clip_at(location.filename, location.range.start)
|
72
|
+
locals = clip.locals - [self]
|
73
|
+
meths = chain.define(api_map, closure, locals)
|
74
|
+
# @todo Convert logic to use signatures
|
75
|
+
meths.each do |meth|
|
76
|
+
next if meth.block.nil?
|
77
|
+
|
78
|
+
yield_types = meth.block.parameters.map(&:return_type)
|
79
|
+
# 'arguments' is what the method says it will yield to the
|
80
|
+
# block; 'parameters' is what the block accepts
|
81
|
+
argument_types = destructure_yield_types(yield_types, parameters)
|
82
|
+
param_types = argument_types.each_with_index.map do |arg_type, idx|
|
83
|
+
param = parameters[idx]
|
84
|
+
param_type = chain.base.infer(api_map, param, locals)
|
85
|
+
unless arg_type.nil?
|
86
|
+
if arg_type.generic? && param_type.defined?
|
87
|
+
namespace_pin = api_map.get_namespace_pins(meth.namespace, closure.namespace).first
|
88
|
+
arg_type.resolve_generics(namespace_pin, param_type)
|
89
|
+
else
|
90
|
+
arg_type.self_to(chain.base.infer(api_map, self, locals).namespace).qualify(api_map, meth.context.namespace)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
return param_types if param_types.all?(&:defined?)
|
95
|
+
end
|
96
|
+
parameters.map { ComplexType::UNDEFINED }
|
97
|
+
end
|
98
|
+
|
39
99
|
private
|
40
100
|
|
41
101
|
# @param api_map [ApiMap]
|
42
|
-
# @return [ComplexType
|
43
|
-
def
|
44
|
-
return
|
45
|
-
|
46
|
-
return nil unless api_map.rebindable_method_names.include?(word)
|
102
|
+
# @return [ComplexType]
|
103
|
+
def maybe_rebind api_map
|
104
|
+
return ComplexType::UNDEFINED unless receiver
|
105
|
+
|
47
106
|
chain = Parser.chain(receiver, location.filename)
|
48
107
|
locals = api_map.source_map(location.filename).locals_at(location)
|
49
|
-
links_last_word = chain.links.last.word
|
50
|
-
if %w[instance_eval instance_exec class_eval class_exec module_eval module_exec].include?(links_last_word)
|
51
|
-
return chain.base.infer(api_map, self, locals)
|
52
|
-
end
|
53
|
-
if 'define_method' == links_last_word and chain.define(api_map, self, locals).first&.path == 'Module#define_method' # change class type to instance type
|
54
|
-
if chain.links.size > 1 # Class.define_method
|
55
|
-
ty = chain.base.infer(api_map, self, locals)
|
56
|
-
return Solargraph::ComplexType.parse(ty.namespace)
|
57
|
-
else # define_method without self
|
58
|
-
return Solargraph::ComplexType.parse(closure.binder.namespace)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
# other case without early return, read block yieldself tags
|
62
108
|
receiver_pin = chain.define(api_map, self, locals).first
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
109
|
+
return ComplexType::UNDEFINED unless receiver_pin
|
110
|
+
|
111
|
+
types = receiver_pin.docstring.tag(:yieldreceiver)&.types
|
112
|
+
return ComplexType::UNDEFINED unless types&.any?
|
113
|
+
|
114
|
+
target = chain.base.infer(api_map, receiver_pin, locals)
|
115
|
+
target = full_context unless target.defined?
|
116
|
+
|
117
|
+
ComplexType.try_parse(*types).qualify(api_map, receiver_pin.context.namespace).self_to(target.to_s)
|
70
118
|
end
|
71
119
|
end
|
72
120
|
end
|
@@ -6,9 +6,12 @@ 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
|
@@ -26,12 +29,24 @@ 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 generics_as_rbs
|
46
|
+
return '' if generics.empty?
|
47
|
+
|
48
|
+
generics.join(', ') + ' '
|
49
|
+
end
|
35
50
|
end
|
36
51
|
end
|
37
52
|
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]
|
@@ -19,7 +19,7 @@ module Solargraph
|
|
19
19
|
@return_type ||= ComplexType::UNDEFINED
|
20
20
|
end
|
21
21
|
|
22
|
-
# @return [ComplexType]
|
22
|
+
# @return [ComplexType, Array<UniqueType>]
|
23
23
|
def context
|
24
24
|
# Get the static context from the nearest namespace
|
25
25
|
@context ||= find_context
|
@@ -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]
|
@@ -56,7 +60,7 @@ module Solargraph
|
|
56
60
|
return here.return_type
|
57
61
|
elsif here.is_a?(Pin::Method)
|
58
62
|
if here.scope == :instance
|
59
|
-
return ComplexType.try_parse(here.context.
|
63
|
+
return ComplexType.try_parse(here.context.tag)
|
60
64
|
else
|
61
65
|
return here.context
|
62
66
|
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,20 +62,16 @@ module Solargraph
|
|
34
62
|
end
|
35
63
|
end
|
36
64
|
|
37
|
-
# @return [Hash]
|
65
|
+
# @return [::Array<Hash>]
|
38
66
|
def signature_help
|
39
|
-
|
40
|
-
label: name + '(' + parameters.map(&:full).join(', ') + ')',
|
41
|
-
documentation: documentation
|
42
|
-
}
|
67
|
+
[]
|
43
68
|
end
|
44
69
|
|
45
|
-
# @return [String]
|
70
|
+
# @return [String, nil]
|
46
71
|
def detail
|
47
72
|
# This property is not cached in an instance variable because it can
|
48
73
|
# change when pins get proxied.
|
49
74
|
detail = String.new
|
50
|
-
detail += "(#{parameters.map(&:full).join(', ')}) " unless !is_a?(Pin::Method) || parameters.empty?
|
51
75
|
detail += "=#{probed? ? '~' : (proxied? ? '^' : '>')} #{return_type.to_s}" unless return_type.undefined?
|
52
76
|
detail.strip!
|
53
77
|
return nil if detail.empty?
|
@@ -61,12 +85,14 @@ module Solargraph
|
|
61
85
|
@link_documentation ||= generate_link
|
62
86
|
end
|
63
87
|
|
88
|
+
# @return [String, nil]
|
64
89
|
def text_documentation
|
65
90
|
this_path = path || return_type.tag
|
66
91
|
return nil if this_path == 'undefined'
|
67
92
|
escape_brackets this_path
|
68
93
|
end
|
69
94
|
|
95
|
+
# @return [void]
|
70
96
|
def reset_conversions
|
71
97
|
@completion_item = nil
|
72
98
|
@resolve_completion_item = nil
|
@@ -77,7 +103,7 @@ module Solargraph
|
|
77
103
|
|
78
104
|
private
|
79
105
|
|
80
|
-
# @return [String]
|
106
|
+
# @return [String, nil]
|
81
107
|
def generate_link
|
82
108
|
this_path = path || return_type.tag
|
83
109
|
return nil if this_path == 'undefined'
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Solargraph
|
4
|
+
module Pin
|
5
|
+
# A DelegatedMethod is a more complicated version of a MethodAlias that
|
6
|
+
# allows aliasing a method from a different closure (class/module etc).
|
7
|
+
class DelegatedMethod < Pin::Method
|
8
|
+
# A DelegatedMethod can be constructed with either a :resolved_method
|
9
|
+
# pin, or a :receiver_chain. When a :receiver_chain is supplied, it
|
10
|
+
# will be used to *dynamically* resolve a receiver type within the
|
11
|
+
# given closure/scope, and the delegated method will then be resolved
|
12
|
+
# to a method pin on that type.
|
13
|
+
#
|
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]
|
17
|
+
# @param receiver_method_name [String] the method name that will be called on the receiver (defaults to :name).
|
18
|
+
def initialize(method: nil, receiver: nil, name: method&.name, receiver_method_name: name, **splat)
|
19
|
+
raise ArgumentError, 'either :method or :receiver is required' if (method && receiver) || (!method && !receiver)
|
20
|
+
super(name: name, **splat)
|
21
|
+
|
22
|
+
@receiver_chain = receiver
|
23
|
+
@resolved_method = method
|
24
|
+
@receiver_method_name = receiver_method_name
|
25
|
+
end
|
26
|
+
|
27
|
+
%i[comments parameters return_type location].each do |method|
|
28
|
+
define_method(method) do
|
29
|
+
@resolved_method ? @resolved_method.send(method) : super()
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
%i[typify realize infer probe].each do |method|
|
34
|
+
# @param api_map [ApiMap]
|
35
|
+
define_method(method) do |api_map|
|
36
|
+
resolve_method(api_map)
|
37
|
+
@resolved_method ? @resolved_method.send(method, api_map) : super(api_map)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param api_map [ApiMap]
|
42
|
+
def resolvable?(api_map)
|
43
|
+
resolve_method(api_map)
|
44
|
+
!!@resolved_method
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# Resolves the receiver chain and method name to a method pin, resetting any previously resolution.
|
50
|
+
#
|
51
|
+
# @param api_map [ApiMap]
|
52
|
+
# @return [Pin::Method, nil]
|
53
|
+
def resolve_method api_map
|
54
|
+
return if @resolved_method
|
55
|
+
|
56
|
+
resolver = @receiver_chain.define(api_map, self, []).first
|
57
|
+
|
58
|
+
unless resolver
|
59
|
+
Solargraph.logger.warn \
|
60
|
+
"Delegated receiver for #{path} was resolved to nil from `#{print_chain(@receiver_chain)}'"
|
61
|
+
return
|
62
|
+
end
|
63
|
+
|
64
|
+
receiver_type = resolver.return_type
|
65
|
+
|
66
|
+
return if receiver_type.undefined?
|
67
|
+
|
68
|
+
receiver_path, method_scope =
|
69
|
+
if @receiver_chain.constant?
|
70
|
+
# HACK: the `return_type` of a constant is Class<Whatever>, but looking up a method expects
|
71
|
+
# the arguments `"Whatever"` and `scope: :class`.
|
72
|
+
[receiver_type.to_s.sub(/^Class<(.+)>$/, '\1'), :class]
|
73
|
+
else
|
74
|
+
[receiver_type.to_s, :instance]
|
75
|
+
end
|
76
|
+
|
77
|
+
method_stack = api_map.get_method_stack(receiver_path, @receiver_method_name, scope: method_scope)
|
78
|
+
@resolved_method = method_stack.first
|
79
|
+
end
|
80
|
+
|
81
|
+
# helper to print a source chain as code, probably not 100% correct.
|
82
|
+
#
|
83
|
+
# @param chain [Source::Chain]
|
84
|
+
# @return [String]
|
85
|
+
def print_chain(chain)
|
86
|
+
out = +''
|
87
|
+
chain.links.each_with_index do |link, index|
|
88
|
+
if index > 0
|
89
|
+
if Source::Chain::Constant
|
90
|
+
out << '::' unless link.word.start_with?('::')
|
91
|
+
else
|
92
|
+
out << '.'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
out << link.word
|
96
|
+
end
|
97
|
+
out
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
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,14 +3,17 @@
|
|
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
|
@@ -22,6 +25,7 @@ module Solargraph
|
|
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
|