solargraph 0.58.0 → 0.59.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/.envrc +3 -0
- data/.gitattributes +2 -0
- data/.github/workflows/linting.yml +6 -5
- data/.github/workflows/plugins.yml +48 -35
- data/.github/workflows/rspec.yml +15 -28
- data/.github/workflows/typecheck.yml +3 -2
- data/.gitignore +1 -0
- data/.rubocop.yml +38 -6
- data/.rubocop_todo.yml +53 -966
- data/CHANGELOG.md +24 -0
- data/Gemfile +3 -1
- data/README.md +3 -3
- data/Rakefile +26 -23
- data/bin/solargraph +9 -8
- data/lib/solargraph/api_map/cache.rb +110 -110
- data/lib/solargraph/api_map/constants.rb +288 -279
- data/lib/solargraph/api_map/index.rb +204 -193
- data/lib/solargraph/api_map/source_to_yard.rb +110 -97
- data/lib/solargraph/api_map/store.rb +395 -384
- data/lib/solargraph/api_map.rb +1029 -945
- data/lib/solargraph/bench.rb +44 -45
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +240 -228
- data/lib/solargraph/complex_type/unique_type.rb +641 -482
- data/lib/solargraph/complex_type.rb +557 -444
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -61
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
- data/lib/solargraph/convention/data_definition.rb +108 -105
- data/lib/solargraph/convention/gemfile.rb +15 -15
- data/lib/solargraph/convention/gemspec.rb +23 -23
- data/lib/solargraph/convention/rakefile.rb +17 -17
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
- data/lib/solargraph/convention/struct_definition.rb +168 -164
- data/lib/solargraph/convention.rb +78 -78
- data/lib/solargraph/converters/dd.rb +19 -17
- data/lib/solargraph/converters/dl.rb +17 -15
- data/lib/solargraph/converters/dt.rb +17 -15
- data/lib/solargraph/converters/misc.rb +3 -1
- data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
- data/lib/solargraph/diagnostics/rubocop.rb +119 -118
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
- data/lib/solargraph/diagnostics/type_check.rb +56 -55
- data/lib/solargraph/diagnostics/update_errors.rb +37 -41
- data/lib/solargraph/doc_map.rb +438 -439
- data/lib/solargraph/equality.rb +34 -34
- data/lib/solargraph/gem_pins.rb +98 -98
- data/lib/solargraph/language_server/error_codes.rb +20 -20
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
- data/lib/solargraph/language_server/host/dispatch.rb +130 -130
- data/lib/solargraph/language_server/host/message_worker.rb +113 -112
- data/lib/solargraph/language_server/host/sources.rb +100 -99
- data/lib/solargraph/language_server/host.rb +886 -878
- data/lib/solargraph/language_server/message/base.rb +97 -97
- data/lib/solargraph/language_server/message/client/register_capability.rb +13 -15
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -60
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +108 -114
- data/lib/solargraph/language_server/message/extended/document.rb +24 -23
- data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
- data/lib/solargraph/language_server/message/extended/download_core.rb +20 -19
- data/lib/solargraph/language_server/message/extended/search.rb +20 -20
- data/lib/solargraph/language_server/message/initialize.rb +197 -191
- data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
- data/lib/solargraph/language_server/message/text_document/definition.rb +49 -40
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +36 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
- data/lib/solargraph/language_server/message/text_document/hover.rb +58 -58
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +18 -11
- data/lib/solargraph/language_server/message/text_document/references.rb +23 -16
- data/lib/solargraph/language_server/message/text_document/rename.rb +26 -19
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +33 -25
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +41 -35
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +48 -40
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +32 -26
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +33 -23
- data/lib/solargraph/language_server/message.rb +94 -94
- data/lib/solargraph/language_server/request.rb +29 -27
- data/lib/solargraph/language_server/transport/data_reader.rb +72 -74
- data/lib/solargraph/language_server/uri_helpers.rb +49 -49
- data/lib/solargraph/library.rb +702 -683
- data/lib/solargraph/location.rb +85 -82
- data/lib/solargraph/logging.rb +55 -37
- data/lib/solargraph/page.rb +92 -92
- data/lib/solargraph/parser/comment_ripper.rb +84 -69
- data/lib/solargraph/parser/flow_sensitive_typing.rb +471 -255
- data/lib/solargraph/parser/node_processor/base.rb +122 -92
- data/lib/solargraph/parser/node_processor.rb +63 -62
- data/lib/solargraph/parser/parser_gem/class_methods.rb +165 -149
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +19 -19
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
- data/lib/solargraph/parser/parser_gem/node_methods.rb +507 -486
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +45 -46
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +38 -37
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +42 -40
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +51 -52
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +302 -291
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -29
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
- data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
- data/lib/solargraph/parser/parser_gem.rb +14 -12
- data/lib/solargraph/parser/region.rb +75 -69
- data/lib/solargraph/parser/snippet.rb +19 -17
- data/lib/solargraph/parser.rb +25 -23
- data/lib/solargraph/pin/base.rb +773 -729
- data/lib/solargraph/pin/base_variable.rb +375 -126
- data/lib/solargraph/pin/block.rb +127 -104
- data/lib/solargraph/pin/breakable.rb +15 -9
- data/lib/solargraph/pin/callable.rb +275 -231
- data/lib/solargraph/pin/closure.rb +69 -72
- data/lib/solargraph/pin/common.rb +97 -79
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/constant.rb +43 -45
- data/lib/solargraph/pin/conversions.rb +129 -123
- data/lib/solargraph/pin/delegated_method.rb +131 -120
- data/lib/solargraph/pin/documenting.rb +116 -114
- data/lib/solargraph/pin/instance_variable.rb +38 -34
- data/lib/solargraph/pin/keyword.rb +16 -20
- data/lib/solargraph/pin/local_variable.rb +31 -75
- data/lib/solargraph/pin/method.rb +724 -672
- data/lib/solargraph/pin/method_alias.rb +42 -34
- data/lib/solargraph/pin/namespace.rb +122 -115
- data/lib/solargraph/pin/parameter.rb +339 -275
- data/lib/solargraph/pin/proxy_type.rb +42 -39
- data/lib/solargraph/pin/reference/override.rb +47 -47
- data/lib/solargraph/pin/reference/superclass.rb +17 -15
- data/lib/solargraph/pin/reference/type_alias.rb +16 -0
- data/lib/solargraph/pin/reference.rb +59 -39
- data/lib/solargraph/pin/search.rb +62 -61
- data/lib/solargraph/pin/signature.rb +64 -61
- data/lib/solargraph/pin/symbol.rb +54 -53
- data/lib/solargraph/pin/until.rb +16 -18
- data/lib/solargraph/pin/while.rb +16 -18
- data/lib/solargraph/pin.rb +46 -44
- data/lib/solargraph/pin_cache.rb +248 -245
- data/lib/solargraph/position.rb +139 -119
- data/lib/solargraph/range.rb +113 -112
- data/lib/solargraph/rbs_map/conversions.rb +952 -823
- data/lib/solargraph/rbs_map/core_fills.rb +91 -84
- data/lib/solargraph/rbs_map/core_map.rb +65 -58
- data/lib/solargraph/rbs_map/stdlib_map.rb +71 -43
- data/lib/solargraph/rbs_map.rb +207 -163
- data/lib/solargraph/server_methods.rb +16 -16
- data/lib/solargraph/shell.rb +555 -352
- data/lib/solargraph/source/chain/array.rb +39 -37
- data/lib/solargraph/source/chain/call.rb +377 -337
- data/lib/solargraph/source/chain/class_variable.rb +13 -13
- data/lib/solargraph/source/chain/constant.rb +30 -26
- data/lib/solargraph/source/chain/global_variable.rb +13 -13
- data/lib/solargraph/source/chain/hash.rb +37 -34
- data/lib/solargraph/source/chain/if.rb +30 -28
- data/lib/solargraph/source/chain/instance_variable.rb +36 -13
- data/lib/solargraph/source/chain/link.rb +99 -109
- data/lib/solargraph/source/chain/literal.rb +51 -48
- data/lib/solargraph/source/chain/or.rb +29 -23
- data/lib/solargraph/source/chain/q_call.rb +13 -11
- data/lib/solargraph/source/chain/variable.rb +15 -13
- data/lib/solargraph/source/chain/z_super.rb +28 -30
- data/lib/solargraph/source/chain.rb +304 -291
- data/lib/solargraph/source/change.rb +89 -82
- data/lib/solargraph/source/cursor.rb +172 -166
- data/lib/solargraph/source/encoding_fixes.rb +22 -23
- data/lib/solargraph/source/source_chainer.rb +218 -194
- data/lib/solargraph/source/updater.rb +59 -55
- data/lib/solargraph/source.rb +522 -498
- data/lib/solargraph/source_map/clip.rb +245 -226
- data/lib/solargraph/source_map/data.rb +37 -34
- data/lib/solargraph/source_map/mapper.rb +286 -259
- data/lib/solargraph/source_map.rb +224 -212
- data/lib/solargraph/type_checker/problem.rb +34 -32
- data/lib/solargraph/type_checker/rules.rb +157 -84
- data/lib/solargraph/type_checker.rb +888 -814
- data/lib/solargraph/version.rb +5 -5
- data/lib/solargraph/workspace/config.rb +258 -255
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +98 -97
- data/lib/solargraph/workspace.rb +242 -220
- data/lib/solargraph/yard_map/helpers.rb +49 -44
- data/lib/solargraph/yard_map/mapper/to_method.rb +136 -130
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
- data/lib/solargraph/yard_map/mapper.rb +84 -79
- data/lib/solargraph/yard_map.rb +17 -18
- data/lib/solargraph/yard_tags.rb +20 -20
- data/lib/solargraph/yardoc.rb +90 -87
- data/lib/solargraph.rb +128 -105
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +5 -0
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/rbs_collection.yaml +1 -1
- data/solargraph.gemspec +37 -35
- metadata +52 -51
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
- data/sig/shims/ast/0/node.rbs +0 -5
- /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
|
@@ -1,444 +1,557 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
# A container for type data based on YARD type tags.
|
|
5
|
-
#
|
|
6
|
-
class ComplexType
|
|
7
|
-
GENERIC_TAG_NAME = 'generic'
|
|
8
|
-
# @!parse
|
|
9
|
-
# include TypeMethods
|
|
10
|
-
include Equality
|
|
11
|
-
|
|
12
|
-
autoload :
|
|
13
|
-
autoload :
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# @
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
items.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
# @param
|
|
34
|
-
#
|
|
35
|
-
# @return [ComplexType]
|
|
36
|
-
def qualify api_map, *gates
|
|
37
|
-
red = reduce_object
|
|
38
|
-
types = red.items.map do |t|
|
|
39
|
-
next t if [
|
|
40
|
-
next t if ['::Boolean'].include?(t.rooted_name)
|
|
41
|
-
t.qualify
|
|
42
|
-
end
|
|
43
|
-
ComplexType.new(types).reduce_object
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# @param generics_to_resolve [Enumerable<String>]]
|
|
47
|
-
# @param context_type [UniqueType, nil]
|
|
48
|
-
# @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
|
|
49
|
-
# @return [self]
|
|
50
|
-
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
|
|
51
|
-
return self unless generic?
|
|
52
|
-
|
|
53
|
-
ComplexType.new(@items.map
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
# @
|
|
85
|
-
#
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
# @
|
|
92
|
-
# @
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
# @param
|
|
110
|
-
# @param
|
|
111
|
-
# @param
|
|
112
|
-
# @param
|
|
113
|
-
# @
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
# @
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
# @
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
# @
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
#
|
|
208
|
-
#
|
|
209
|
-
#
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
# @param
|
|
245
|
-
# @
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
#
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
def
|
|
286
|
-
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
# @
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
end
|
|
297
|
-
ComplexType.new(
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
end
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
# A container for type data based on YARD type tags.
|
|
5
|
+
#
|
|
6
|
+
class ComplexType
|
|
7
|
+
GENERIC_TAG_NAME = 'generic'
|
|
8
|
+
# @!parse
|
|
9
|
+
# include TypeMethods
|
|
10
|
+
include Equality
|
|
11
|
+
|
|
12
|
+
autoload :Conformance, 'solargraph/complex_type/conformance'
|
|
13
|
+
autoload :TypeMethods, 'solargraph/complex_type/type_methods'
|
|
14
|
+
autoload :UniqueType, 'solargraph/complex_type/unique_type'
|
|
15
|
+
|
|
16
|
+
# @param types [Array<UniqueType, ComplexType>]
|
|
17
|
+
def initialize types = [UniqueType::UNDEFINED]
|
|
18
|
+
# @todo @items here should not need an annotation
|
|
19
|
+
# @type [Array<UniqueType>]
|
|
20
|
+
items = types.flat_map(&:items).uniq(&:to_s)
|
|
21
|
+
if items.any? { |i| i.name == 'false' } && items.any? { |i| i.name == 'true' }
|
|
22
|
+
items.delete_if { |i| %w[false true].include?(i.name) }
|
|
23
|
+
items.unshift(UniqueType::BOOLEAN)
|
|
24
|
+
end
|
|
25
|
+
# @type [Array<UniqueType>]
|
|
26
|
+
items = [UniqueType::UNDEFINED] if items.any?(&:undefined?)
|
|
27
|
+
# @todo shouldn't need this cast - if statement above adds an 'Array' type
|
|
28
|
+
# @type [Array<UniqueType>]
|
|
29
|
+
@items = items
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @param api_map [ApiMap]
|
|
33
|
+
# @param gates [Array<String>]
|
|
34
|
+
#
|
|
35
|
+
# @return [ComplexType]
|
|
36
|
+
def qualify api_map, *gates
|
|
37
|
+
red = reduce_object
|
|
38
|
+
types = red.items.map do |t|
|
|
39
|
+
next t if %w[nil void undefined].include?(t.name)
|
|
40
|
+
next t if ['::Boolean'].include?(t.rooted_name)
|
|
41
|
+
api_map.unalias(t.name) || t.qualify(api_map, *gates)
|
|
42
|
+
end
|
|
43
|
+
ComplexType.new(types).reduce_object
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @param generics_to_resolve [Enumerable<String>]]
|
|
47
|
+
# @param context_type [ComplexType, ComplexType::UniqueType, nil]
|
|
48
|
+
# @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
|
|
49
|
+
# @return [self]
|
|
50
|
+
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
|
|
51
|
+
return self unless generic?
|
|
52
|
+
|
|
53
|
+
ComplexType.new(@items.map do |i|
|
|
54
|
+
i.resolve_generics_from_context(generics_to_resolve, context_type,
|
|
55
|
+
resolved_generic_values: resolved_generic_values)
|
|
56
|
+
end)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @return [UniqueType]
|
|
60
|
+
def first
|
|
61
|
+
@items.first
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# @return [String]
|
|
65
|
+
def to_rbs
|
|
66
|
+
((@items.length > 1 ? '(' : '') +
|
|
67
|
+
@items.map(&:to_rbs).join(' | ') +
|
|
68
|
+
(@items.length > 1 ? ')' : ''))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @param dst [ComplexType, ComplexType::UniqueType]
|
|
72
|
+
# @return [ComplexType]
|
|
73
|
+
def self_to_type dst
|
|
74
|
+
object_type_dst = dst.reduce_class_type
|
|
75
|
+
transform do |t|
|
|
76
|
+
next t if t.name != 'self'
|
|
77
|
+
object_type_dst
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# @yieldparam [UniqueType]
|
|
82
|
+
# @yieldreturn [UniqueType]
|
|
83
|
+
# @return [Array<UniqueType>]
|
|
84
|
+
# @sg-ignore Declared return type
|
|
85
|
+
# ::Array<::Solargraph::ComplexType::UniqueType> does not match
|
|
86
|
+
# inferred type ::Array<::Proc> for Solargraph::ComplexType#map
|
|
87
|
+
def map &block
|
|
88
|
+
@items.map(&block)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @yieldparam [UniqueType]
|
|
92
|
+
# @return [Enumerable<UniqueType>]
|
|
93
|
+
def each &block
|
|
94
|
+
@items.each(&block)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @yieldparam [UniqueType]
|
|
98
|
+
# @return [void]
|
|
99
|
+
# @overload each_unique_type()
|
|
100
|
+
# @return [Enumerator<UniqueType>]
|
|
101
|
+
def each_unique_type &block
|
|
102
|
+
return enum_for(__method__) unless block_given?
|
|
103
|
+
|
|
104
|
+
@items.each do |item|
|
|
105
|
+
item.each_unique_type(&block)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# @param new_name [String, nil]
|
|
110
|
+
# @param make_rooted [Boolean, nil]
|
|
111
|
+
# @param new_key_types [Array<ComplexType>, nil]
|
|
112
|
+
# @param make_rooted [Boolean, nil]
|
|
113
|
+
# @param new_subtypes [Array<ComplexType>, nil]
|
|
114
|
+
# @return [self]
|
|
115
|
+
def recreate new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil
|
|
116
|
+
ComplexType.new(map do |ut|
|
|
117
|
+
ut.recreate(new_name: new_name,
|
|
118
|
+
make_rooted: make_rooted,
|
|
119
|
+
new_key_types: new_key_types,
|
|
120
|
+
new_subtypes: new_subtypes)
|
|
121
|
+
end)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @return [Integer]
|
|
125
|
+
def length
|
|
126
|
+
@items.length
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# @return [Array<UniqueType>]
|
|
130
|
+
def to_a
|
|
131
|
+
@items
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @param index [Integer]
|
|
135
|
+
# @return [UniqueType]
|
|
136
|
+
def [] index
|
|
137
|
+
@items[index]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# @return [Array<UniqueType>]
|
|
141
|
+
def select &block
|
|
142
|
+
@items.select(&block)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @return [String]
|
|
146
|
+
def namespace
|
|
147
|
+
# cache this attr for high frequency call
|
|
148
|
+
@namespace ||= method_missing(:namespace).to_s
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @return [Array<String>]
|
|
152
|
+
def namespaces
|
|
153
|
+
@items.map(&:namespace)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @param name [Symbol]
|
|
157
|
+
#
|
|
158
|
+
# @return [Object, nil]
|
|
159
|
+
# @param [Array<Object>] args
|
|
160
|
+
def method_missing name, *args, &block
|
|
161
|
+
return if @items.first.nil?
|
|
162
|
+
return @items.first.send(name, *args, &block) if respond_to_missing?(name)
|
|
163
|
+
super
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# @param name [Symbol]
|
|
167
|
+
# @param include_private [Boolean]
|
|
168
|
+
def respond_to_missing? name, include_private = false
|
|
169
|
+
TypeMethods.public_instance_methods.include?(name) || super
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def to_s
|
|
173
|
+
map(&:tag).join(', ')
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# @return [String]
|
|
177
|
+
def tags
|
|
178
|
+
map(&:tag).join(', ')
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# @return [String]
|
|
182
|
+
def simple_tags
|
|
183
|
+
simplify_literals.tags
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def literal?
|
|
187
|
+
@items.any?(&:literal?)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# @return [ComplexType]
|
|
191
|
+
def downcast_to_literal_if_possible
|
|
192
|
+
ComplexType.new(items.map(&:downcast_to_literal_if_possible))
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# @return [String]
|
|
196
|
+
def desc
|
|
197
|
+
rooted_tags
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# @param api_map [ApiMap]
|
|
201
|
+
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
202
|
+
# @param situation [:method_call, :return_type, :assignment]
|
|
203
|
+
# @param rules [Array<:allow_subtype_skew, :allow_empty_params, :allow_reverse_match, :allow_any_match, :allow_undefined, :allow_unresolved_generic, :allow_unmatched_interface>]
|
|
204
|
+
#
|
|
205
|
+
# allow_subtype_skew: if not provided, check if any subtypes of
|
|
206
|
+
# the expected type match the inferred type
|
|
207
|
+
#
|
|
208
|
+
# allow_reverse_match: check if any subtypes
|
|
209
|
+
# of the expected type match the inferred type
|
|
210
|
+
#
|
|
211
|
+
# allow_empty_params: allow a general inferred type without
|
|
212
|
+
# parameters to conform to a more specific expected type
|
|
213
|
+
#
|
|
214
|
+
# allow_any_match: any unique type matched in the inferred
|
|
215
|
+
# qualifies as a match
|
|
216
|
+
#
|
|
217
|
+
# allow_undefined: treat undefined as a wildcard that matches
|
|
218
|
+
# anything
|
|
219
|
+
#
|
|
220
|
+
# @param variance [:invariant, :covariant, :contravariant]
|
|
221
|
+
# @return [Boolean]
|
|
222
|
+
def conforms_to? api_map, expected,
|
|
223
|
+
situation,
|
|
224
|
+
rules = [],
|
|
225
|
+
variance: erased_variance(situation)
|
|
226
|
+
expected = expected.downcast_to_literal_if_possible
|
|
227
|
+
inferred = downcast_to_literal_if_possible
|
|
228
|
+
|
|
229
|
+
return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
|
|
230
|
+
|
|
231
|
+
if rules.include? :allow_any_match
|
|
232
|
+
inferred.any? do |inf|
|
|
233
|
+
inf.conforms_to?(api_map, expected, situation, rules,
|
|
234
|
+
variance: variance)
|
|
235
|
+
end
|
|
236
|
+
else
|
|
237
|
+
inferred.all? do |inf|
|
|
238
|
+
inf.conforms_to?(api_map, expected, situation, rules,
|
|
239
|
+
variance: variance)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# @param api_map [ApiMap]
|
|
245
|
+
# @param expected [ComplexType, UniqueType]
|
|
246
|
+
# @param inferred [ComplexType, UniqueType]
|
|
247
|
+
# @return [Boolean]
|
|
248
|
+
def duck_types_match? api_map, expected, inferred
|
|
249
|
+
raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
|
|
250
|
+
expected.each do |exp|
|
|
251
|
+
next unless exp.duck_type?
|
|
252
|
+
quack = exp.to_s[1..]
|
|
253
|
+
# @sg-ignore Need to add nil check here
|
|
254
|
+
return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
|
|
255
|
+
end
|
|
256
|
+
true
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# @return [String]
|
|
260
|
+
def rooted_tags
|
|
261
|
+
map(&:rooted_tag).join(', ')
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
# @yieldparam [UniqueType]
|
|
265
|
+
def all? &block
|
|
266
|
+
@items.all?(&block)
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# @yieldparam [UniqueType]
|
|
270
|
+
# @yieldreturn [Boolean]
|
|
271
|
+
# @return [Boolean]
|
|
272
|
+
def any? &block
|
|
273
|
+
@items.compact.any?(&block)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def selfy?
|
|
277
|
+
@items.any?(&:selfy?)
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def generic?
|
|
281
|
+
any?(&:generic?)
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# @return [self]
|
|
285
|
+
def simplify_literals
|
|
286
|
+
ComplexType.new(map(&:simplify_literals))
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# @param new_name [String, nil]
|
|
290
|
+
# @yieldparam t [UniqueType]
|
|
291
|
+
# @yieldreturn [UniqueType]
|
|
292
|
+
# @return [ComplexType]
|
|
293
|
+
def transform new_name = nil, &transform_type
|
|
294
|
+
if new_name&.start_with?('::')
|
|
295
|
+
raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}"
|
|
296
|
+
end
|
|
297
|
+
ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
# @return [self]
|
|
301
|
+
def force_rooted
|
|
302
|
+
transform do |t|
|
|
303
|
+
t.recreate(make_rooted: true)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# @param definitions [Pin::Namespace, Pin::Method]
|
|
308
|
+
# @param context_type [ComplexType]
|
|
309
|
+
# @return [ComplexType]
|
|
310
|
+
def resolve_generics definitions, context_type
|
|
311
|
+
result = @items.map { |i| i.resolve_generics(definitions, context_type) }
|
|
312
|
+
ComplexType.new(result)
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def nullable?
|
|
316
|
+
@items.any?(&:nil_type?)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
# @return [ComplexType]
|
|
320
|
+
def without_nil
|
|
321
|
+
new_items = @items.reject(&:nil_type?)
|
|
322
|
+
return ComplexType::UNDEFINED if new_items.empty?
|
|
323
|
+
ComplexType.new(new_items)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
# @return [Array<ComplexType>]
|
|
327
|
+
def all_params
|
|
328
|
+
@items.first.all_params || []
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
# @return [ComplexType]
|
|
332
|
+
def reduce_class_type
|
|
333
|
+
new_items = items.flat_map do |type|
|
|
334
|
+
next type unless %w[Module Class].include?(type.name)
|
|
335
|
+
next type if type.all_params.empty?
|
|
336
|
+
|
|
337
|
+
type.all_params
|
|
338
|
+
end
|
|
339
|
+
ComplexType.new(new_items)
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
# every type and subtype in this union have been resolved to be
|
|
343
|
+
# fully qualified
|
|
344
|
+
def all_rooted?
|
|
345
|
+
all?(&:all_rooted?)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# @param other [ComplexType, UniqueType]
|
|
349
|
+
def erased_version_of? other
|
|
350
|
+
return false if items.length != 1 || other.items.length != 1
|
|
351
|
+
|
|
352
|
+
@items.first.erased_version_of?(other.items.first)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
# every top-level type has resolved to be fully qualified; see
|
|
356
|
+
# #all_rooted? to check their subtypes as well
|
|
357
|
+
def rooted?
|
|
358
|
+
all?(&:rooted?)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
attr_reader :items
|
|
362
|
+
|
|
363
|
+
# @param exclude_types [ComplexType, nil]
|
|
364
|
+
# @param api_map [ApiMap]
|
|
365
|
+
# @return [ComplexType, self]
|
|
366
|
+
def exclude exclude_types, api_map
|
|
367
|
+
return self if exclude_types.nil?
|
|
368
|
+
|
|
369
|
+
types = items - exclude_types.items
|
|
370
|
+
types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
|
|
371
|
+
ComplexType.new(types)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
# @see https://en.wikipedia.org/wiki/Intersection_type
|
|
375
|
+
#
|
|
376
|
+
# @param intersection_type [ComplexType, ComplexType::UniqueType, nil]
|
|
377
|
+
# @param api_map [ApiMap]
|
|
378
|
+
# @return [self, ComplexType::UniqueType]
|
|
379
|
+
def intersect_with intersection_type, api_map
|
|
380
|
+
return self if intersection_type.nil?
|
|
381
|
+
return intersection_type if undefined?
|
|
382
|
+
types = []
|
|
383
|
+
# try to find common types via conformance
|
|
384
|
+
items.each do |ut|
|
|
385
|
+
intersection_type.each do |int_type|
|
|
386
|
+
if int_type.conforms_to?(api_map, ut, :assignment)
|
|
387
|
+
types << int_type
|
|
388
|
+
elsif ut.conforms_to?(api_map, int_type, :assignment)
|
|
389
|
+
types << ut
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
|
|
394
|
+
ComplexType.new(types)
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
protected
|
|
398
|
+
|
|
399
|
+
def equality_fields
|
|
400
|
+
[self.class, items]
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# @return [ComplexType]
|
|
404
|
+
def reduce_object
|
|
405
|
+
new_items = items.flat_map do |ut|
|
|
406
|
+
next [ut] if ut.name != 'Object' || ut.subtypes.empty?
|
|
407
|
+
ut.subtypes
|
|
408
|
+
end
|
|
409
|
+
ComplexType.new(new_items)
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
def bottom?
|
|
413
|
+
@items.all?(&:bot?)
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
class << self
|
|
417
|
+
# Parse type strings into a ComplexType.
|
|
418
|
+
#
|
|
419
|
+
# @example
|
|
420
|
+
# ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
|
|
421
|
+
#
|
|
422
|
+
# @param partial [Boolean] if true, method is receiving a string
|
|
423
|
+
# that will be used inside another ComplexType. It returns
|
|
424
|
+
# arrays of ComplexTypes instead of a single cohesive one.
|
|
425
|
+
# Consumers should not need to use this parameter; it should
|
|
426
|
+
# only be used internally.
|
|
427
|
+
# @param strings [Array<String>] The type definitions to parse
|
|
428
|
+
# @return [ComplexType]
|
|
429
|
+
# # @overload parse(*strings, partial: false)
|
|
430
|
+
# # @todo Need ability to use a literal true as a type below
|
|
431
|
+
# # @param partial [Boolean] True if the string is part of a another type
|
|
432
|
+
# # @return [Array<UniqueType>]
|
|
433
|
+
# @sg-ignore To be able to select the right signature above,
|
|
434
|
+
# Chain::Call needs to know the decl type (:arg, :optarg,
|
|
435
|
+
# :kwarg, etc) of the arguments given, instead of just having
|
|
436
|
+
# an array of Chains as the arguments.
|
|
437
|
+
def parse *strings, partial: false
|
|
438
|
+
# @type [Hash{Array<String> => ComplexType, Array<ComplexType::UniqueType>}]
|
|
439
|
+
@cache ||= {}
|
|
440
|
+
unless partial
|
|
441
|
+
cached = @cache[strings]
|
|
442
|
+
return cached unless cached.nil?
|
|
443
|
+
end
|
|
444
|
+
# @types [Array<ComplexType::UniqueType>]
|
|
445
|
+
types = []
|
|
446
|
+
key_types = nil
|
|
447
|
+
strings.each do |type_string|
|
|
448
|
+
point_stack = 0
|
|
449
|
+
curly_stack = 0
|
|
450
|
+
paren_stack = 0
|
|
451
|
+
base = String.new
|
|
452
|
+
subtype_string = String.new
|
|
453
|
+
# @param char [String]
|
|
454
|
+
type_string&.each_char do |char|
|
|
455
|
+
if char == '='
|
|
456
|
+
# raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
|
457
|
+
elsif char == '<'
|
|
458
|
+
point_stack += 1
|
|
459
|
+
elsif char == '>'
|
|
460
|
+
if subtype_string.end_with?('=') && curly_stack.positive?
|
|
461
|
+
subtype_string += char
|
|
462
|
+
elsif base.end_with?('=')
|
|
463
|
+
raise ComplexTypeError, 'Invalid hash thing' unless key_types.nil?
|
|
464
|
+
# types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
|
|
465
|
+
# @sg-ignore Need to add nil check here
|
|
466
|
+
types.push UniqueType.parse(base[0..-2].strip, subtype_string)
|
|
467
|
+
# @todo this should either expand key_type's type
|
|
468
|
+
# automatically or complain about not being
|
|
469
|
+
# compatible with key_type's type in type checking
|
|
470
|
+
key_types = types
|
|
471
|
+
types = []
|
|
472
|
+
base.clear
|
|
473
|
+
subtype_string.clear
|
|
474
|
+
next
|
|
475
|
+
else
|
|
476
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack.zero?
|
|
477
|
+
point_stack -= 1
|
|
478
|
+
subtype_string += char
|
|
479
|
+
end
|
|
480
|
+
next
|
|
481
|
+
elsif char == '{'
|
|
482
|
+
curly_stack += 1
|
|
483
|
+
elsif char == '}'
|
|
484
|
+
curly_stack -= 1
|
|
485
|
+
subtype_string += char
|
|
486
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack.negative?
|
|
487
|
+
next
|
|
488
|
+
elsif char == '('
|
|
489
|
+
paren_stack += 1
|
|
490
|
+
elsif char == ')'
|
|
491
|
+
paren_stack -= 1
|
|
492
|
+
subtype_string += char
|
|
493
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack.negative?
|
|
494
|
+
next
|
|
495
|
+
elsif char == ',' && point_stack.zero? && curly_stack.zero? && paren_stack.zero?
|
|
496
|
+
# types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
|
|
497
|
+
types.push UniqueType.parse(base.strip, subtype_string.strip)
|
|
498
|
+
base.clear
|
|
499
|
+
subtype_string.clear
|
|
500
|
+
next
|
|
501
|
+
end
|
|
502
|
+
if point_stack.zero? && curly_stack.zero? && paren_stack.zero?
|
|
503
|
+
base.concat char
|
|
504
|
+
else
|
|
505
|
+
subtype_string.concat char
|
|
506
|
+
end
|
|
507
|
+
end
|
|
508
|
+
if point_stack != 0 || curly_stack != 0 || paren_stack != 0
|
|
509
|
+
raise ComplexTypeError,
|
|
510
|
+
"Unclosed subtype in #{type_string}"
|
|
511
|
+
end
|
|
512
|
+
# types.push ComplexType.new([UniqueType.new(base, subtype_string)])
|
|
513
|
+
types.push UniqueType.parse(base.strip, subtype_string.strip)
|
|
514
|
+
end
|
|
515
|
+
unless key_types.nil?
|
|
516
|
+
raise ComplexTypeError, 'Invalid use of key/value parameters' unless partial
|
|
517
|
+
return key_types if types.empty?
|
|
518
|
+
return [key_types, types]
|
|
519
|
+
end
|
|
520
|
+
result = partial ? types : ComplexType.new(types)
|
|
521
|
+
@cache[strings] = result unless partial
|
|
522
|
+
result
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# @param strings [Array<String>]
|
|
526
|
+
# @return [ComplexType]
|
|
527
|
+
def try_parse *strings
|
|
528
|
+
parse(*strings)
|
|
529
|
+
rescue ComplexTypeError => e
|
|
530
|
+
Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
|
|
531
|
+
ComplexType::UNDEFINED
|
|
532
|
+
end
|
|
533
|
+
end
|
|
534
|
+
|
|
535
|
+
VOID = ComplexType.parse('void')
|
|
536
|
+
UNDEFINED = ComplexType.parse('undefined')
|
|
537
|
+
SYMBOL = ComplexType.parse('::Symbol')
|
|
538
|
+
ROOT = ComplexType.parse('::Class<>')
|
|
539
|
+
NIL = ComplexType.parse('nil')
|
|
540
|
+
SELF = ComplexType.parse('self')
|
|
541
|
+
BOOLEAN = ComplexType.parse('::Boolean')
|
|
542
|
+
BOT = ComplexType.parse('bot')
|
|
543
|
+
|
|
544
|
+
private
|
|
545
|
+
|
|
546
|
+
# @todo This is a quick and dirty hack that forces `self` keywords
|
|
547
|
+
# to reference an instance of their class and never the class itself.
|
|
548
|
+
# This behavior may change depending on which result is expected
|
|
549
|
+
# from YARD conventions. See https://github.com/lsegal/yard/issues/1257
|
|
550
|
+
# @param dst [String]
|
|
551
|
+
# @return [String]
|
|
552
|
+
def reduce_class dst
|
|
553
|
+
dst = dst.sub(/^(Class|Module)</, '').sub(/>$/, '') while dst =~ /^(Class|Module)<(.*?)>$/
|
|
554
|
+
dst
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
end
|