solargraph 0.50.0 → 0.53.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/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 +81 -3
- data/README.md +13 -16
- data/SPONSORS.md +2 -9
- data/lib/solargraph/api_map/cache.rb +60 -20
- data/lib/solargraph/api_map/store.rb +47 -11
- data/lib/solargraph/api_map.rb +161 -95
- data/lib/solargraph/bench.rb +2 -2
- data/lib/solargraph/cache.rb +30 -6
- data/lib/solargraph/complex_type/type_methods.rb +54 -9
- data/lib/solargraph/complex_type/unique_type.rb +154 -57
- data/lib/solargraph/complex_type.rb +91 -17
- data/lib/solargraph/convention.rb +0 -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 +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 +146 -0
- data/lib/solargraph/gem_pins.rb +64 -0
- data/lib/solargraph/language_server/host/cataloger.rb +1 -0
- data/lib/solargraph/language_server/host/diagnoser.rb +2 -2
- data/lib/solargraph/language_server/host/dispatch.rb +10 -4
- data/lib/solargraph/language_server/host/message_worker.rb +4 -0
- data/lib/solargraph/language_server/host/sources.rb +7 -4
- data/lib/solargraph/language_server/host.rb +26 -7
- 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 +11 -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 +4 -4
- data/lib/solargraph/language_server/message/text_document/hover.rb +2 -0
- 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.rb +1 -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/library.rb +86 -16
- data/lib/solargraph/location.rb +1 -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 +9 -0
- data/lib/solargraph/parser/{legacy → parser_gem}/class_methods.rb +31 -5
- 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 +499 -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 +2 -2
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/cvasgn_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/def_node.rb +1 -1
- data/lib/solargraph/parser/{legacy → parser_gem}/node_processors/defs_node.rb +2 -2
- data/lib/solargraph/parser/{rubyvm → 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/{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 +2 -2
- data/lib/solargraph/parser/{rubyvm → parser_gem}/node_processors/sym_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors.rb +54 -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 +64 -9
- data/lib/solargraph/pin/base_variable.rb +6 -2
- data/lib/solargraph/pin/block.rb +19 -9
- data/lib/solargraph/pin/closure.rb +17 -2
- data/lib/solargraph/pin/common.rb +7 -3
- data/lib/solargraph/pin/conversions.rb +33 -3
- data/lib/solargraph/pin/delegated_method.rb +97 -0
- data/lib/solargraph/pin/documenting.rb +25 -34
- data/lib/solargraph/pin/instance_variable.rb +4 -0
- data/lib/solargraph/pin/local_variable.rb +13 -1
- data/lib/solargraph/pin/method.rb +182 -18
- data/lib/solargraph/pin/namespace.rb +18 -5
- data/lib/solargraph/pin/parameter.rb +44 -14
- 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 +123 -3
- data/lib/solargraph/pin.rb +1 -1
- data/lib/solargraph/range.rb +4 -6
- data/lib/solargraph/rbs_map/conversions.rb +294 -50
- data/lib/solargraph/rbs_map/core_fills.rb +7 -24
- data/lib/solargraph/rbs_map/core_map.rb +3 -2
- data/lib/solargraph/rbs_map/core_signs.rb +2 -0
- data/lib/solargraph/rbs_map/stdlib_map.rb +2 -5
- data/lib/solargraph/rbs_map.rb +20 -11
- data/lib/solargraph/shell.rb +62 -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 +99 -46
- 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 +29 -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.rb +18 -19
- data/lib/solargraph/source_map/clip.rb +25 -23
- data/lib/solargraph/source_map/mapper.rb +12 -1
- data/lib/solargraph/source_map.rb +30 -7
- data/lib/solargraph/type_checker/checks.rb +10 -2
- data/lib/solargraph/type_checker.rb +123 -45
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +14 -11
- data/lib/solargraph/workspace.rb +3 -2
- 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 +11 -1
- 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 -284
- data/lib/solargraph/yard_tags.rb +20 -0
- data/lib/solargraph/yardoc.rb +52 -0
- data/lib/solargraph.rb +6 -4
- data/solargraph.gemspec +11 -5
- metadata +131 -75
- data/lib/solargraph/api_map/bundler_methods.rb +0 -22
- data/lib/solargraph/convention/rspec.rb +0 -30
- data/lib/solargraph/documentor.rb +0 -76
- 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/gvasgn_node.rb +0 -23
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +0 -18
- 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 -149
- 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 -33
- 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/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 -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 -63
- data/lib/solargraph/parser/rubyvm/node_wrapper.rb +0 -47
- data/lib/solargraph/parser/rubyvm.rb +0 -40
- data/lib/yard-solargraph.rb +0 -33
|
@@ -2,9 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
module Solargraph
|
|
4
4
|
class ComplexType
|
|
5
|
-
# Methods for accessing type data
|
|
5
|
+
# Methods for accessing type data available from
|
|
6
|
+
# both ComplexType and UniqueType.
|
|
6
7
|
#
|
|
8
|
+
# @abstract This mixin relies on these -
|
|
9
|
+
# instance variables:
|
|
10
|
+
# @name: String
|
|
11
|
+
# @subtypes: Array<ComplexType>
|
|
12
|
+
# @rooted: boolish
|
|
13
|
+
# methods:
|
|
14
|
+
# transform()
|
|
7
15
|
module TypeMethods
|
|
16
|
+
# @!method transform(new_name = nil, &transform_type)
|
|
17
|
+
# @param new_name [String, nil]
|
|
18
|
+
# @yieldparam t [UniqueType]
|
|
19
|
+
# @yieldreturn [UniqueType]
|
|
20
|
+
# @return [UniqueType, nil]
|
|
21
|
+
|
|
8
22
|
# @return [String]
|
|
9
23
|
attr_reader :name
|
|
10
24
|
|
|
@@ -24,8 +38,7 @@ module Solargraph
|
|
|
24
38
|
|
|
25
39
|
# @return [Boolean]
|
|
26
40
|
def nil_type?
|
|
27
|
-
@nil_type
|
|
28
|
-
@nil_type
|
|
41
|
+
@nil_type ||= (name.casecmp('nil') == 0)
|
|
29
42
|
end
|
|
30
43
|
|
|
31
44
|
# @return [Boolean]
|
|
@@ -45,6 +58,22 @@ module Solargraph
|
|
|
45
58
|
name == 'undefined'
|
|
46
59
|
end
|
|
47
60
|
|
|
61
|
+
# @param generics_to_erase [Enumerable<String>]
|
|
62
|
+
# @return [self]
|
|
63
|
+
def erase_generics(generics_to_erase)
|
|
64
|
+
transform do |type|
|
|
65
|
+
if type.name == ComplexType::GENERIC_TAG_NAME
|
|
66
|
+
if type.all_params.length == 1 && generics_to_erase.include?(type.all_params.first.to_s)
|
|
67
|
+
ComplexType::UNDEFINED
|
|
68
|
+
else
|
|
69
|
+
type
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
type
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
48
77
|
# @return [Boolean]
|
|
49
78
|
def list_parameters?
|
|
50
79
|
substring.start_with?('<')
|
|
@@ -80,12 +109,25 @@ module Solargraph
|
|
|
80
109
|
end.call
|
|
81
110
|
end
|
|
82
111
|
|
|
83
|
-
# @return [
|
|
112
|
+
# @return [String]
|
|
113
|
+
def rooted_namespace
|
|
114
|
+
return namespace unless rooted?
|
|
115
|
+
"::#{namespace}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# @return [String]
|
|
119
|
+
def rooted_name
|
|
120
|
+
return name unless rooted?
|
|
121
|
+
"::#{name}"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @return [::Symbol] :class or :instance
|
|
84
125
|
def scope
|
|
85
126
|
@scope ||= :instance if duck_type? || nil_type?
|
|
86
127
|
@scope ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? :class : :instance
|
|
87
128
|
end
|
|
88
129
|
|
|
130
|
+
# @param other [Object]
|
|
89
131
|
def == other
|
|
90
132
|
return false unless self.class == other.class
|
|
91
133
|
tag == other.tag
|
|
@@ -99,9 +141,9 @@ module Solargraph
|
|
|
99
141
|
#
|
|
100
142
|
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
101
143
|
# @param context [String] The namespace from which to resolve names
|
|
102
|
-
# @return [ComplexType] The generated ComplexType
|
|
144
|
+
# @return [self, ComplexType, UniqueType] The generated ComplexType
|
|
103
145
|
def qualify api_map, context = ''
|
|
104
|
-
return self if name ==
|
|
146
|
+
return self if name == GENERIC_TAG_NAME
|
|
105
147
|
return ComplexType.new([self]) if duck_type? || void? || undefined?
|
|
106
148
|
recon = (rooted? ? '' : context)
|
|
107
149
|
fqns = api_map.qualify(name, recon)
|
|
@@ -110,13 +152,16 @@ module Solargraph
|
|
|
110
152
|
return UniqueType::UNDEFINED
|
|
111
153
|
end
|
|
112
154
|
fqns = "::#{fqns}" # Ensure the resulting complex type is rooted
|
|
113
|
-
|
|
114
|
-
|
|
155
|
+
all_ltypes = key_types.map { |t| t.qualify api_map, context }.uniq
|
|
156
|
+
all_rtypes = value_types.map { |t| t.qualify api_map, context }
|
|
115
157
|
if list_parameters?
|
|
158
|
+
rtypes = all_rtypes.uniq
|
|
116
159
|
Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>")
|
|
117
160
|
elsif fixed_parameters?
|
|
118
|
-
Solargraph::ComplexType.parse("#{fqns}(#{
|
|
161
|
+
Solargraph::ComplexType.parse("#{fqns}(#{all_rtypes.map(&:tag).join(', ')})")
|
|
119
162
|
elsif hash_parameters?
|
|
163
|
+
ltypes = all_ltypes.uniq
|
|
164
|
+
rtypes = all_rtypes.uniq
|
|
120
165
|
Solargraph::ComplexType.parse("#{fqns}{#{ltypes.map(&:tag).join(', ')} => #{rtypes.map(&:tag).join(', ')}}")
|
|
121
166
|
else
|
|
122
167
|
Solargraph::ComplexType.parse(fqns)
|
|
@@ -27,18 +27,27 @@ module Solargraph
|
|
|
27
27
|
end
|
|
28
28
|
@substring = substring
|
|
29
29
|
@tag = @name + substring
|
|
30
|
+
# @type [Array<ComplexType>]
|
|
30
31
|
@key_types = []
|
|
32
|
+
# @type [Array<ComplexType>]
|
|
31
33
|
@subtypes = []
|
|
34
|
+
# @type [Array<ComplexType>]
|
|
32
35
|
@all_params = []
|
|
33
36
|
return unless parameters?
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
# @todo we should be able to probe the type of 'subs' without
|
|
38
|
+
# hoisting the definition outside of the if statement
|
|
39
|
+
subs = if @substring.start_with?('<(') && @substring.end_with?(')>')
|
|
40
|
+
ComplexType.parse(substring[2..-3], partial: true)
|
|
41
|
+
else
|
|
42
|
+
ComplexType.parse(substring[1..-2], partial: true)
|
|
43
|
+
end
|
|
39
44
|
if hash_parameters?
|
|
40
45
|
raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
|
|
46
|
+
# @todo should be able to resolve map; both types have it
|
|
47
|
+
# with same return type
|
|
48
|
+
# @sg-ignore
|
|
41
49
|
@key_types.concat subs[0].map { |u| ComplexType.new([u]) }
|
|
50
|
+
# @sg-ignore
|
|
42
51
|
@subtypes.concat subs[1].map { |u| ComplexType.new([u]) }
|
|
43
52
|
else
|
|
44
53
|
@subtypes.concat subs
|
|
@@ -51,73 +60,161 @@ module Solargraph
|
|
|
51
60
|
tag
|
|
52
61
|
end
|
|
53
62
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def parameterized?
|
|
59
|
-
name == 'param' || all_params.any?(&:parameterized?)
|
|
63
|
+
# @return [Array<UniqueType>]
|
|
64
|
+
def items
|
|
65
|
+
[self]
|
|
60
66
|
end
|
|
61
67
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
param_type = context.return_type.all_params[idx]
|
|
67
|
-
return ComplexType::UNDEFINED unless param_type
|
|
68
|
-
param_type.to_s
|
|
69
|
-
else
|
|
70
|
-
name
|
|
71
|
-
end
|
|
72
|
-
new_key_types = if name != 'param'
|
|
73
|
-
@key_types.map { |t| t.resolve_parameters(definitions, context) }.select(&:defined?)
|
|
68
|
+
# @return [String]
|
|
69
|
+
def rbs_name
|
|
70
|
+
if name == 'undefined'
|
|
71
|
+
'untyped'
|
|
74
72
|
else
|
|
75
|
-
|
|
73
|
+
rooted_name
|
|
76
74
|
end
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @return [String]
|
|
78
|
+
def to_rbs
|
|
79
|
+
if ['Tuple', 'Array'].include?(name) && fixed_parameters?
|
|
80
|
+
# tuples don't have a name; they're just [foo, bar, baz].
|
|
81
|
+
if substring == '()'
|
|
82
|
+
# but there are no zero element tuples, so we go with an array
|
|
83
|
+
'Array[]'
|
|
84
|
+
else
|
|
85
|
+
# already generated surrounded by []
|
|
86
|
+
parameters_as_rbs
|
|
87
|
+
end
|
|
79
88
|
else
|
|
80
|
-
|
|
89
|
+
"#{rbs_name}#{parameters_as_rbs}"
|
|
81
90
|
end
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# @return [String]
|
|
94
|
+
def parameters_as_rbs
|
|
95
|
+
parameters? ? "[#{all_params.map { |s| s.to_rbs }.join(', ')}]" : ''
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def generic?
|
|
99
|
+
name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
# @param generics_to_resolve [Enumerable<String>]
|
|
104
|
+
# @param context_type [UniqueType, nil]
|
|
105
|
+
# @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
|
|
106
|
+
# @return [UniqueType, ComplexType]
|
|
107
|
+
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
|
|
108
|
+
transform(name) do |t|
|
|
109
|
+
next t unless t.name == ComplexType::GENERIC_TAG_NAME
|
|
110
|
+
|
|
111
|
+
new_binding = false
|
|
112
|
+
|
|
113
|
+
type_param = t.subtypes.first&.name
|
|
114
|
+
next t unless generics_to_resolve.include? type_param
|
|
115
|
+
unless context_type.nil? || !resolved_generic_values[type_param].nil?
|
|
116
|
+
new_binding = true
|
|
117
|
+
resolved_generic_values[type_param] = context_type
|
|
118
|
+
end
|
|
119
|
+
if new_binding
|
|
120
|
+
resolved_generic_values.transform_values! do |complex_type|
|
|
121
|
+
complex_type.resolve_generics_from_context(generics_to_resolve, nil, resolved_generic_values: resolved_generic_values)
|
|
90
122
|
end
|
|
123
|
+
end
|
|
124
|
+
resolved_generic_values[type_param] || t
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Probe the concrete type for each of the generic type
|
|
129
|
+
# parameters used in this type, and return a new type if
|
|
130
|
+
# possible.
|
|
131
|
+
#
|
|
132
|
+
# @param definitions [Pin::Namespace, Pin::Method] The module/class/method which uses generic types
|
|
133
|
+
# @param context_type [ComplexType] The receiver type
|
|
134
|
+
# @return [UniqueType, ComplexType]
|
|
135
|
+
def resolve_generics definitions, context_type
|
|
136
|
+
return self if definitions.nil? || definitions.generics.empty?
|
|
137
|
+
|
|
138
|
+
transform(name) do |t|
|
|
139
|
+
if t.name == GENERIC_TAG_NAME
|
|
140
|
+
idx = definitions.generics.index(t.subtypes.first&.name)
|
|
141
|
+
next t if idx.nil?
|
|
142
|
+
context_type.all_params[idx] || ComplexType::UNDEFINED
|
|
91
143
|
else
|
|
92
|
-
|
|
144
|
+
t
|
|
93
145
|
end
|
|
94
|
-
else
|
|
95
|
-
UniqueType.new(new_name)
|
|
96
146
|
end
|
|
147
|
+
end
|
|
97
148
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
# ComplexType.try_parse(param_type.to_s)
|
|
149
|
+
# @yieldparam t [self]
|
|
150
|
+
# @yieldreturn [self]
|
|
151
|
+
# @return [Array<self>]
|
|
152
|
+
def map &block
|
|
153
|
+
[block.yield(self)]
|
|
104
154
|
end
|
|
105
155
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
156
|
+
# @return [Array<UniqueType>]
|
|
157
|
+
def to_a
|
|
158
|
+
[self]
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# @param new_name [String, nil]
|
|
162
|
+
# @param new_key_types [Array<UniqueType>, nil]
|
|
163
|
+
# @param new_subtypes [Array<UniqueType>, nil]
|
|
164
|
+
# @return [self]
|
|
165
|
+
def recreate(new_name: nil, new_key_types: nil, new_subtypes: nil)
|
|
166
|
+
new_name ||= name
|
|
167
|
+
new_key_types ||= @key_types
|
|
168
|
+
new_subtypes ||= @subtypes
|
|
169
|
+
if new_key_types.none?(&:defined?) && new_subtypes.none?(&:defined?)
|
|
170
|
+
# if all subtypes are undefined, erase down to the non-parametric type
|
|
171
|
+
UniqueType.new(new_name)
|
|
172
|
+
elsif new_key_types.empty? && new_subtypes.empty?
|
|
173
|
+
UniqueType.new(new_name)
|
|
174
|
+
elsif hash_parameters?
|
|
112
175
|
UniqueType.new(new_name, "{#{new_key_types.join(', ')} => #{new_subtypes.join(', ')}}")
|
|
113
|
-
elsif
|
|
114
|
-
if
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
176
|
+
elsif @substring.start_with?('<(')
|
|
177
|
+
# @todo This clause is probably wrong, and if so, fixing it
|
|
178
|
+
# will be some level of breaking change. Probably best
|
|
179
|
+
# handled before real tuple support is rolled out and
|
|
180
|
+
# folks start relying on it more.
|
|
181
|
+
#
|
|
182
|
+
# (String) is a one element tuple in https://yardoc.org/types
|
|
183
|
+
# <String> is an array of zero or more Strings in https://yardoc.org/types
|
|
184
|
+
# Array<(String)> could be an Array of one-element tuples or a
|
|
185
|
+
# one element tuple. https://yardoc.org/types treats it
|
|
186
|
+
# as the former.
|
|
187
|
+
# Array<(String), Integer> is not ambiguous if we accept
|
|
188
|
+
# (String) as a tuple type, but not currently understood
|
|
189
|
+
# by Solargraph.
|
|
190
|
+
UniqueType.new(new_name, "<(#{new_subtypes.join(', ')})>")
|
|
191
|
+
elsif fixed_parameters?
|
|
192
|
+
UniqueType.new(new_name, "(#{new_subtypes.join(', ')})")
|
|
119
193
|
else
|
|
120
|
-
UniqueType.new(new_name)
|
|
194
|
+
UniqueType.new(new_name, "<#{new_subtypes.join(', ')}>")
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Apply the given transformation to each subtype and then finally to this type
|
|
199
|
+
#
|
|
200
|
+
# @param new_name [String, nil]
|
|
201
|
+
# @yieldparam t [UniqueType]
|
|
202
|
+
# @yieldreturn [self]
|
|
203
|
+
# @return [self]
|
|
204
|
+
def transform(new_name = nil, &transform_type)
|
|
205
|
+
new_key_types = @key_types.flat_map { |ct| ct.map { |ut| ut.transform(&transform_type) } }.compact
|
|
206
|
+
new_subtypes = @subtypes.flat_map { |ct| ct.map { |ut| ut.transform(&transform_type) } }.compact
|
|
207
|
+
new_type = recreate(new_name: new_name || rooted_name, new_key_types: new_key_types, new_subtypes: new_subtypes)
|
|
208
|
+
yield new_type
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Transform references to the 'self' type to the specified concrete namespace
|
|
212
|
+
# @param dst [String]
|
|
213
|
+
# @return [UniqueType]
|
|
214
|
+
def self_to dst
|
|
215
|
+
transform do |t|
|
|
216
|
+
next t if t.name != 'self'
|
|
217
|
+
t.recreate(new_name: dst, new_key_types: [], new_subtypes: [])
|
|
121
218
|
end
|
|
122
219
|
end
|
|
123
220
|
|
|
@@ -4,50 +4,70 @@ module Solargraph
|
|
|
4
4
|
# A container for type data based on YARD type tags.
|
|
5
5
|
#
|
|
6
6
|
class ComplexType
|
|
7
|
+
GENERIC_TAG_NAME = 'generic'.freeze
|
|
7
8
|
# @!parse
|
|
8
9
|
# include TypeMethods
|
|
9
10
|
|
|
10
11
|
autoload :TypeMethods, 'solargraph/complex_type/type_methods'
|
|
11
12
|
autoload :UniqueType, 'solargraph/complex_type/unique_type'
|
|
12
13
|
|
|
13
|
-
# @param types [Array<UniqueType>]
|
|
14
|
+
# @param types [Array<[UniqueType, ComplexType]>]
|
|
14
15
|
def initialize types = [UniqueType::UNDEFINED]
|
|
15
|
-
@items
|
|
16
|
+
# @todo @items here should not need an annotation
|
|
17
|
+
# @type [Array<UniqueType>]
|
|
18
|
+
@items = types.flat_map(&:items).uniq(&:to_s)
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
# @param api_map [ApiMap]
|
|
19
22
|
# @param context [String]
|
|
20
23
|
# @return [ComplexType]
|
|
21
24
|
def qualify api_map, context = ''
|
|
22
|
-
|
|
25
|
+
red = reduce_object
|
|
26
|
+
types = red.items.map do |t|
|
|
23
27
|
next t if ['Boolean', 'nil', 'void', 'undefined'].include?(t.name)
|
|
24
28
|
t.qualify api_map, context
|
|
25
29
|
end
|
|
26
|
-
ComplexType.new(types)
|
|
30
|
+
ComplexType.new(types).reduce_object
|
|
27
31
|
end
|
|
28
32
|
|
|
33
|
+
# @param generics_to_resolve [Enumerable<String>]]
|
|
34
|
+
# @param context_type [UniqueType, nil]
|
|
35
|
+
# @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
|
|
36
|
+
# @return [self]
|
|
37
|
+
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
|
|
38
|
+
return self unless generic?
|
|
39
|
+
|
|
40
|
+
ComplexType.new(@items.map { |i| i.resolve_generics_from_context(generics_to_resolve, context_type, resolved_generic_values: resolved_generic_values) })
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @return [UniqueType]
|
|
29
44
|
def first
|
|
30
45
|
@items.first
|
|
31
46
|
end
|
|
32
47
|
|
|
48
|
+
# @return [String]
|
|
33
49
|
def to_rbs
|
|
34
|
-
((@items.length > 1 ? '(' : '') +
|
|
35
|
-
|
|
36
|
-
|
|
50
|
+
((@items.length > 1 ? '(' : '') +
|
|
51
|
+
@items.map(&:to_rbs).join(' | ') +
|
|
52
|
+
(@items.length > 1 ? ')' : ''))
|
|
37
53
|
end
|
|
38
54
|
|
|
55
|
+
# @yieldparam [UniqueType]
|
|
56
|
+
# @return [Array]
|
|
39
57
|
def map &block
|
|
40
58
|
@items.map &block
|
|
41
59
|
end
|
|
42
60
|
|
|
43
61
|
# @yieldparam [UniqueType]
|
|
44
|
-
# @return [
|
|
62
|
+
# @return [Enumerable<UniqueType>]
|
|
45
63
|
def each &block
|
|
46
64
|
@items.each &block
|
|
47
65
|
end
|
|
48
66
|
|
|
49
67
|
# @yieldparam [UniqueType]
|
|
50
|
-
# @return [
|
|
68
|
+
# @return [void]
|
|
69
|
+
# @overload each_unique_type()
|
|
70
|
+
# @return [Enumerator<UniqueType>]
|
|
51
71
|
def each_unique_type &block
|
|
52
72
|
return enum_for(__method__) unless block_given?
|
|
53
73
|
|
|
@@ -56,28 +76,48 @@ module Solargraph
|
|
|
56
76
|
end
|
|
57
77
|
end
|
|
58
78
|
|
|
79
|
+
# @return [Integer]
|
|
59
80
|
def length
|
|
60
81
|
@items.length
|
|
61
82
|
end
|
|
62
83
|
|
|
84
|
+
# @return [Array<UniqueType>]
|
|
85
|
+
def to_a
|
|
86
|
+
@items
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @param index [Integer]
|
|
90
|
+
# @return [UniqueType]
|
|
63
91
|
def [](index)
|
|
64
92
|
@items[index]
|
|
65
93
|
end
|
|
66
94
|
|
|
95
|
+
# @return [Array<UniqueType>]
|
|
67
96
|
def select &block
|
|
68
97
|
@items.select &block
|
|
69
98
|
end
|
|
99
|
+
|
|
100
|
+
# @return [String]
|
|
70
101
|
def namespace
|
|
71
102
|
# cache this attr for high frequency call
|
|
72
103
|
@namespace ||= method_missing(:namespace).to_s
|
|
73
104
|
end
|
|
74
105
|
|
|
106
|
+
# @return [Array<String>]
|
|
107
|
+
def namespaces
|
|
108
|
+
@items.map(&:namespace)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# @param name [Symbol]
|
|
112
|
+
# @return [Object, nil]
|
|
75
113
|
def method_missing name, *args, &block
|
|
76
114
|
return if @items.first.nil?
|
|
77
115
|
return @items.first.send(name, *args, &block) if respond_to_missing?(name)
|
|
78
116
|
super
|
|
79
117
|
end
|
|
80
118
|
|
|
119
|
+
# @param name [Symbol]
|
|
120
|
+
# @param include_private [Boolean]
|
|
81
121
|
def respond_to_missing?(name, include_private = false)
|
|
82
122
|
TypeMethods.public_instance_methods.include?(name) || super
|
|
83
123
|
end
|
|
@@ -98,12 +138,23 @@ module Solargraph
|
|
|
98
138
|
@items.any?(&:selfy?)
|
|
99
139
|
end
|
|
100
140
|
|
|
101
|
-
def
|
|
102
|
-
any?(&:
|
|
141
|
+
def generic?
|
|
142
|
+
any?(&:generic?)
|
|
103
143
|
end
|
|
104
144
|
|
|
105
|
-
|
|
106
|
-
|
|
145
|
+
# @param new_name [String, nil]
|
|
146
|
+
# @yieldparam t [UniqueType]
|
|
147
|
+
# @yieldreturn [UniqueType]
|
|
148
|
+
# @return [ComplexType]
|
|
149
|
+
def transform(new_name = nil, &transform_type)
|
|
150
|
+
ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# @param definitions [Pin::Namespace, Pin::Method]
|
|
154
|
+
# @param context_type [ComplexType]
|
|
155
|
+
# @return [ComplexType]
|
|
156
|
+
def resolve_generics definitions, context_type
|
|
157
|
+
result = @items.map { |i| i.resolve_generics(definitions, context_type) }
|
|
107
158
|
ComplexType.parse(*result.map(&:tag))
|
|
108
159
|
end
|
|
109
160
|
|
|
@@ -113,17 +164,32 @@ module Solargraph
|
|
|
113
164
|
return self unless selfy?
|
|
114
165
|
red = reduce_class(dst)
|
|
115
166
|
result = @items.map { |i| i.self_to red }
|
|
116
|
-
ComplexType.parse(*result.map(&:
|
|
167
|
+
ComplexType.parse(*result.map(&:tag))
|
|
117
168
|
end
|
|
118
169
|
|
|
119
170
|
def nullable?
|
|
120
171
|
@items.any?(&:nil_type?)
|
|
121
172
|
end
|
|
122
173
|
|
|
174
|
+
# @return [Array<ComplexType>]
|
|
123
175
|
def all_params
|
|
124
176
|
@items.first.all_params || []
|
|
125
177
|
end
|
|
126
178
|
|
|
179
|
+
attr_reader :items
|
|
180
|
+
|
|
181
|
+
protected
|
|
182
|
+
|
|
183
|
+
# @return [ComplexType]
|
|
184
|
+
def reduce_object
|
|
185
|
+
return self if name != 'Object' || subtypes.empty?
|
|
186
|
+
ComplexType.try_parse(reduce_class(subtypes.join(', ')))
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def bottom?
|
|
190
|
+
@items.all?(&:bot?)
|
|
191
|
+
end
|
|
192
|
+
|
|
127
193
|
private
|
|
128
194
|
|
|
129
195
|
# @todo This is a quick and dirty hack that forces `self` keywords
|
|
@@ -153,9 +219,13 @@ module Solargraph
|
|
|
153
219
|
# used internally.
|
|
154
220
|
#
|
|
155
221
|
# @param *strings [Array<String>] The type definitions to parse
|
|
156
|
-
# @
|
|
157
|
-
# @
|
|
222
|
+
# @return [ComplexType]
|
|
223
|
+
# @overload parse(*strings, partial: false)
|
|
224
|
+
# @todo Need ability to use a literal true as a type below
|
|
225
|
+
# @param partial [Boolean] True if the string is part of a another type
|
|
226
|
+
# @return [Array<UniqueType>]
|
|
158
227
|
def parse *strings, partial: false
|
|
228
|
+
# @type [Hash{Array<String> => ComplexType}]
|
|
159
229
|
@cache ||= {}
|
|
160
230
|
unless partial
|
|
161
231
|
cached = @cache[strings]
|
|
@@ -181,6 +251,9 @@ module Solargraph
|
|
|
181
251
|
raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
|
|
182
252
|
# types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
|
|
183
253
|
types.push UniqueType.new(base[0..-2].strip)
|
|
254
|
+
# @todo this should either expand key_type's type
|
|
255
|
+
# automatically or complain about not being
|
|
256
|
+
# compatible with key_type's type in type checking
|
|
184
257
|
key_types = types
|
|
185
258
|
types = []
|
|
186
259
|
base.clear
|
|
@@ -203,7 +276,7 @@ module Solargraph
|
|
|
203
276
|
paren_stack += 1
|
|
204
277
|
elsif char == ')'
|
|
205
278
|
paren_stack -= 1
|
|
206
|
-
subtype_string += char
|
|
279
|
+
subtype_string += char
|
|
207
280
|
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
|
|
208
281
|
next
|
|
209
282
|
elsif char == ',' && point_stack == 0 && curly_stack == 0 && paren_stack == 0
|
|
@@ -250,5 +323,6 @@ module Solargraph
|
|
|
250
323
|
NIL = ComplexType.parse('nil')
|
|
251
324
|
SELF = ComplexType.parse('self')
|
|
252
325
|
BOOLEAN = ComplexType.parse('Boolean')
|
|
326
|
+
BOT = ComplexType.parse('bot')
|
|
253
327
|
end
|
|
254
328
|
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'set'
|
|
4
3
|
|
|
5
4
|
module Solargraph
|
|
6
5
|
# Conventions provide a way to modify an ApiMap based on expectations about
|
|
@@ -9,7 +8,6 @@ module Solargraph
|
|
|
9
8
|
module Convention
|
|
10
9
|
autoload :Base, 'solargraph/convention/base'
|
|
11
10
|
autoload :Gemfile, 'solargraph/convention/gemfile'
|
|
12
|
-
autoload :Rspec, 'solargraph/convention/rspec'
|
|
13
11
|
autoload :Gemspec, 'solargraph/convention/gemspec'
|
|
14
12
|
autoload :Rakefile, 'solargraph/convention/rakefile'
|
|
15
13
|
|
|
@@ -43,7 +41,6 @@ module Solargraph
|
|
|
43
41
|
|
|
44
42
|
register Gemfile
|
|
45
43
|
register Gemspec
|
|
46
|
-
register Rspec
|
|
47
44
|
register Rakefile
|
|
48
45
|
end
|
|
49
46
|
end
|
|
@@ -1,6 +1,11 @@
|
|
|
1
|
+
require 'nokogiri'
|
|
2
|
+
|
|
1
3
|
module ReverseMarkdown
|
|
2
4
|
module Converters
|
|
3
5
|
class Dd < Base
|
|
6
|
+
# @return [String]
|
|
7
|
+
# @param node [Nokogiri::XML::Element]
|
|
8
|
+
# @param state [Hash]
|
|
4
9
|
def convert node, state = {}
|
|
5
10
|
content = treat_children(node, state)
|
|
6
11
|
": #{content.strip}\n"
|