solargraph 0.58.1 → 0.59.0.dev.1
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/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +40 -36
- data/.github/workflows/rspec.yml +45 -13
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop_todo.yml +27 -49
- data/README.md +3 -3
- data/Rakefile +1 -0
- data/lib/solargraph/api_map/cache.rb +110 -110
- data/lib/solargraph/api_map/constants.rb +289 -279
- data/lib/solargraph/api_map/index.rb +204 -193
- data/lib/solargraph/api_map/source_to_yard.rb +109 -97
- data/lib/solargraph/api_map/store.rb +387 -384
- data/lib/solargraph/api_map.rb +1000 -945
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +242 -228
- data/lib/solargraph/complex_type/unique_type.rb +632 -482
- data/lib/solargraph/complex_type.rb +549 -444
- 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/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/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/doc_map.rb +200 -439
- data/lib/solargraph/equality.rb +34 -34
- data/lib/solargraph/gem_pins.rb +97 -98
- data/lib/solargraph/language_server/host/dispatch.rb +131 -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 +883 -878
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
- data/lib/solargraph/language_server/message/extended/document.rb +24 -23
- data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
- data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
- data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
- data/lib/solargraph/library.rb +729 -683
- data/lib/solargraph/location.rb +87 -82
- data/lib/solargraph/logging.rb +57 -37
- data/lib/solargraph/parser/comment_ripper.rb +76 -69
- data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -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 +167 -149
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
- data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -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 +46 -46
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -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 +53 -52
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
- 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/region.rb +75 -69
- data/lib/solargraph/parser/snippet.rb +17 -17
- data/lib/solargraph/pin/base.rb +761 -729
- data/lib/solargraph/pin/base_variable.rb +418 -126
- data/lib/solargraph/pin/block.rb +126 -104
- data/lib/solargraph/pin/breakable.rb +13 -9
- data/lib/solargraph/pin/callable.rb +278 -231
- data/lib/solargraph/pin/closure.rb +68 -72
- data/lib/solargraph/pin/common.rb +94 -79
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/conversions.rb +124 -123
- data/lib/solargraph/pin/delegated_method.rb +131 -120
- data/lib/solargraph/pin/documenting.rb +115 -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 +720 -672
- data/lib/solargraph/pin/method_alias.rb +42 -34
- data/lib/solargraph/pin/namespace.rb +121 -115
- data/lib/solargraph/pin/parameter.rb +338 -275
- data/lib/solargraph/pin/proxy_type.rb +40 -39
- data/lib/solargraph/pin/reference/override.rb +47 -47
- data/lib/solargraph/pin/reference/superclass.rb +17 -15
- data/lib/solargraph/pin/reference.rb +41 -39
- data/lib/solargraph/pin/search.rb +62 -61
- data/lib/solargraph/pin/signature.rb +69 -61
- data/lib/solargraph/pin/symbol.rb +53 -53
- data/lib/solargraph/pin/until.rb +18 -18
- data/lib/solargraph/pin/while.rb +18 -18
- data/lib/solargraph/pin.rb +46 -44
- data/lib/solargraph/pin_cache.rb +665 -245
- data/lib/solargraph/position.rb +118 -119
- data/lib/solargraph/range.rb +112 -112
- data/lib/solargraph/rbs_map/conversions.rb +846 -823
- data/lib/solargraph/rbs_map/core_map.rb +65 -58
- data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
- data/lib/solargraph/rbs_map.rb +217 -163
- data/lib/solargraph/shell.rb +397 -352
- data/lib/solargraph/source/chain/call.rb +372 -337
- data/lib/solargraph/source/chain/constant.rb +28 -26
- data/lib/solargraph/source/chain/hash.rb +35 -34
- data/lib/solargraph/source/chain/if.rb +29 -28
- data/lib/solargraph/source/chain/instance_variable.rb +34 -13
- data/lib/solargraph/source/chain/literal.rb +53 -48
- data/lib/solargraph/source/chain/or.rb +31 -23
- data/lib/solargraph/source/chain.rb +294 -291
- data/lib/solargraph/source/change.rb +89 -82
- data/lib/solargraph/source/cursor.rb +172 -166
- data/lib/solargraph/source/source_chainer.rb +204 -194
- data/lib/solargraph/source/updater.rb +59 -55
- data/lib/solargraph/source.rb +524 -498
- data/lib/solargraph/source_map/clip.rb +237 -226
- data/lib/solargraph/source_map/data.rb +37 -34
- data/lib/solargraph/source_map/mapper.rb +282 -259
- data/lib/solargraph/source_map.rb +220 -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 +895 -814
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +257 -255
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +98 -97
- data/lib/solargraph/workspace.rb +362 -220
- data/lib/solargraph/yard_map/helpers.rb +45 -44
- data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
- data/lib/solargraph/yard_map/mapper.rb +84 -79
- data/lib/solargraph/yardoc.rb +97 -87
- data/lib/solargraph.rb +126 -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 +2 -1
- metadata +22 -17
- 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
data/lib/solargraph/source.rb
CHANGED
|
@@ -1,498 +1,524 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'yard'
|
|
4
|
-
|
|
5
|
-
module Solargraph
|
|
6
|
-
# A Ruby file that has been parsed into an AST.
|
|
7
|
-
#
|
|
8
|
-
class Source
|
|
9
|
-
autoload :Updater, 'solargraph/source/updater'
|
|
10
|
-
autoload :Change, 'solargraph/source/change'
|
|
11
|
-
autoload :EncodingFixes, 'solargraph/source/encoding_fixes'
|
|
12
|
-
autoload :Cursor, 'solargraph/source/cursor'
|
|
13
|
-
autoload :Chain, 'solargraph/source/chain'
|
|
14
|
-
autoload :SourceChainer, 'solargraph/source/source_chainer'
|
|
15
|
-
|
|
16
|
-
include EncodingFixes
|
|
17
|
-
|
|
18
|
-
# @return [String, nil]
|
|
19
|
-
attr_reader :filename
|
|
20
|
-
|
|
21
|
-
# @return [String]
|
|
22
|
-
def code
|
|
23
|
-
finalize
|
|
24
|
-
@code
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# @return [Parser::AST::Node, nil]
|
|
28
|
-
def node
|
|
29
|
-
finalize
|
|
30
|
-
@node
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# @return [Hash{Integer => Solargraph::Parser::Snippet}]
|
|
34
|
-
def comments
|
|
35
|
-
finalize
|
|
36
|
-
@comments
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# @todo Deprecate?
|
|
40
|
-
# @return [Integer]
|
|
41
|
-
attr_reader :version
|
|
42
|
-
|
|
43
|
-
# @param code [String]
|
|
44
|
-
# @param filename [String, nil]
|
|
45
|
-
# @param version [Integer]
|
|
46
|
-
def initialize code, filename = nil, version = 0
|
|
47
|
-
@code = normalize(code)
|
|
48
|
-
@repaired = code
|
|
49
|
-
@filename = filename
|
|
50
|
-
@version = version
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
# @param range [Solargraph::Range]
|
|
54
|
-
# @return [String]
|
|
55
|
-
def at range
|
|
56
|
-
from_to range.start.line, range.start.character, range.ending.line, range.ending.character
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# @param l1 [Integer]
|
|
60
|
-
# @param c1 [Integer]
|
|
61
|
-
# @param l2 [Integer]
|
|
62
|
-
# @param c2 [Integer]
|
|
63
|
-
#
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
code
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
# @
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
84
|
-
# @
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
stack
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
src.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
end
|
|
168
|
-
|
|
169
|
-
# @param
|
|
170
|
-
# @return [
|
|
171
|
-
def
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
# @param
|
|
181
|
-
# @return [
|
|
182
|
-
def
|
|
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
|
-
# @return [
|
|
236
|
-
def
|
|
237
|
-
@
|
|
238
|
-
# @type [
|
|
239
|
-
result =
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
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
|
-
end
|
|
284
|
-
|
|
285
|
-
#
|
|
286
|
-
#
|
|
287
|
-
# @param
|
|
288
|
-
# @return [
|
|
289
|
-
def
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
if
|
|
297
|
-
|
|
298
|
-
|
|
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
|
-
|
|
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
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
@
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
# @
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
# @return [
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'yard'
|
|
4
|
+
|
|
5
|
+
module Solargraph
|
|
6
|
+
# A Ruby file that has been parsed into an AST.
|
|
7
|
+
#
|
|
8
|
+
class Source
|
|
9
|
+
autoload :Updater, 'solargraph/source/updater'
|
|
10
|
+
autoload :Change, 'solargraph/source/change'
|
|
11
|
+
autoload :EncodingFixes, 'solargraph/source/encoding_fixes'
|
|
12
|
+
autoload :Cursor, 'solargraph/source/cursor'
|
|
13
|
+
autoload :Chain, 'solargraph/source/chain'
|
|
14
|
+
autoload :SourceChainer, 'solargraph/source/source_chainer'
|
|
15
|
+
|
|
16
|
+
include EncodingFixes
|
|
17
|
+
|
|
18
|
+
# @return [String, nil]
|
|
19
|
+
attr_reader :filename
|
|
20
|
+
|
|
21
|
+
# @return [String]
|
|
22
|
+
def code
|
|
23
|
+
finalize
|
|
24
|
+
@code
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @return [Parser::AST::Node, nil]
|
|
28
|
+
def node
|
|
29
|
+
finalize
|
|
30
|
+
@node
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Hash{Integer => Solargraph::Parser::Snippet}]
|
|
34
|
+
def comments
|
|
35
|
+
finalize
|
|
36
|
+
@comments
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @todo Deprecate?
|
|
40
|
+
# @return [Integer]
|
|
41
|
+
attr_reader :version
|
|
42
|
+
|
|
43
|
+
# @param code [String]
|
|
44
|
+
# @param filename [String, nil]
|
|
45
|
+
# @param version [Integer]
|
|
46
|
+
def initialize code, filename = nil, version = 0
|
|
47
|
+
@code = normalize(code)
|
|
48
|
+
@repaired = code
|
|
49
|
+
@filename = filename
|
|
50
|
+
@version = version
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @param range [Solargraph::Range]
|
|
54
|
+
# @return [String]
|
|
55
|
+
def at range
|
|
56
|
+
from_to range.start.line, range.start.character, range.ending.line, range.ending.character
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @param l1 [Integer]
|
|
60
|
+
# @param c1 [Integer]
|
|
61
|
+
# @param l2 [Integer]
|
|
62
|
+
# @param c2 [Integer]
|
|
63
|
+
#
|
|
64
|
+
# @sg-ignore Need to add nil check here
|
|
65
|
+
# @return [String]
|
|
66
|
+
def from_to l1, c1, l2, c2
|
|
67
|
+
b = Solargraph::Position.line_char_to_offset(code, l1, c1)
|
|
68
|
+
e = Solargraph::Position.line_char_to_offset(code, l2, c2)
|
|
69
|
+
code[b..e-1]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Get the nearest node that contains the specified index.
|
|
73
|
+
#
|
|
74
|
+
# @param line [Integer]
|
|
75
|
+
# @param column [Integer]
|
|
76
|
+
# @return [AST::Node]
|
|
77
|
+
def node_at(line, column)
|
|
78
|
+
tree_at(line, column).first
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Get an array of nodes containing the specified index, starting with the
|
|
82
|
+
# nearest node and ending with the root.
|
|
83
|
+
#
|
|
84
|
+
# @param line [Integer]
|
|
85
|
+
# @param column [Integer]
|
|
86
|
+
# @return [Array<Parser::AST::Node>]
|
|
87
|
+
def tree_at(line, column)
|
|
88
|
+
position = Position.new(line, column)
|
|
89
|
+
stack = []
|
|
90
|
+
inner_tree_at node, position, stack
|
|
91
|
+
stack
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Synchronize the Source with an update. This method applies changes to the
|
|
95
|
+
# code, parses the new code's AST, and returns the resulting Source object.
|
|
96
|
+
#
|
|
97
|
+
# @param updater [Source::Updater]
|
|
98
|
+
# @return [Source]
|
|
99
|
+
def synchronize updater
|
|
100
|
+
raise 'Invalid synchronization' unless updater.filename == filename
|
|
101
|
+
real_code = updater.write(@code)
|
|
102
|
+
if real_code == @code
|
|
103
|
+
@version = updater.version
|
|
104
|
+
return self
|
|
105
|
+
end
|
|
106
|
+
Source.new(@code, filename, updater.version).tap do |src|
|
|
107
|
+
src.repaired = @repaired
|
|
108
|
+
src.error_ranges.concat error_ranges
|
|
109
|
+
src.changes.concat(changes + updater.changes)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# @param position [Position, Array(Integer, Integer)]
|
|
114
|
+
# @return [Source::Cursor]
|
|
115
|
+
def cursor_at position
|
|
116
|
+
finalize
|
|
117
|
+
Cursor.new(self, position)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# @return [Boolean]
|
|
121
|
+
def parsed?
|
|
122
|
+
finalize
|
|
123
|
+
@parsed
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def repaired?
|
|
127
|
+
code != @repaired
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# @param position [Position]
|
|
131
|
+
# @return [Boolean]
|
|
132
|
+
def string_at? position
|
|
133
|
+
return false if Position.to_offset(code, position) >= code.length
|
|
134
|
+
string_nodes.each do |node|
|
|
135
|
+
range = Range.from_node(node)
|
|
136
|
+
# @sg-ignore Need to add nil check here
|
|
137
|
+
next if range.ending.line < position.line
|
|
138
|
+
# @sg-ignore Need to add nil check here
|
|
139
|
+
break if range.ending.line > position.line
|
|
140
|
+
# @sg-ignore Need to add nil check here
|
|
141
|
+
return true if node.type == :str && range.include?(position) && range.start != position
|
|
142
|
+
# @sg-ignore Need to add nil check here
|
|
143
|
+
return true if [:STR, :str].include?(node.type) && range.include?(position) && range.start != position
|
|
144
|
+
if node.type == :dstr
|
|
145
|
+
inner = node_at(position.line, position.column)
|
|
146
|
+
next if inner.nil?
|
|
147
|
+
inner_range = Range.from_node(inner)
|
|
148
|
+
# @sg-ignore Need to add nil check here
|
|
149
|
+
next unless range.include?(inner_range.ending)
|
|
150
|
+
return true if inner.type == :str
|
|
151
|
+
# @sg-ignore Need to add nil check here
|
|
152
|
+
inner_code = at(Solargraph::Range.new(inner_range.start, position))
|
|
153
|
+
# @sg-ignore Need to add nil check here
|
|
154
|
+
return true if (inner.type == :dstr && inner_range.ending.character <= position.character) && !inner_code.end_with?('}') ||
|
|
155
|
+
# @sg-ignore Need to add nil check here
|
|
156
|
+
(inner.type != :dstr && inner_range.ending.line == position.line && position.character <= inner_range.ending.character && inner_code.end_with?('}'))
|
|
157
|
+
end
|
|
158
|
+
# @sg-ignore Need to add nil check here
|
|
159
|
+
break if range.ending.line > position.line
|
|
160
|
+
end
|
|
161
|
+
false
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# @return [::Array<Range>]
|
|
165
|
+
def string_ranges
|
|
166
|
+
@string_ranges ||= Parser.string_ranges(node)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @param position [Position]
|
|
170
|
+
# @return [Boolean]
|
|
171
|
+
def comment_at? position
|
|
172
|
+
comment_ranges.each do |range|
|
|
173
|
+
return true if range.include?(position) ||
|
|
174
|
+
(range.ending.line == position.line && range.ending.column < position.column)
|
|
175
|
+
break if range.ending.line > position.line
|
|
176
|
+
end
|
|
177
|
+
false
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# @param name [String]
|
|
181
|
+
# @return [Array<Location>]
|
|
182
|
+
def references name
|
|
183
|
+
Parser.references self, name
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# @return [Array<Range>]
|
|
187
|
+
def error_ranges
|
|
188
|
+
@error_ranges ||= []
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# @param node [Parser::AST::Node]
|
|
192
|
+
# @return [String]
|
|
193
|
+
def code_for(node)
|
|
194
|
+
rng = Range.from_node(node)
|
|
195
|
+
# @sg-ignore Need to add nil check here
|
|
196
|
+
b = Position.line_char_to_offset(code, rng.start.line, rng.start.column)
|
|
197
|
+
# @sg-ignore Need to add nil check here
|
|
198
|
+
e = Position.line_char_to_offset(code, rng.ending.line, rng.ending.column)
|
|
199
|
+
frag = code[b..e-1].to_s
|
|
200
|
+
frag.strip.gsub(/,$/, '')
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# @param node [AST::Node]
|
|
204
|
+
#
|
|
205
|
+
# @return [String, nil]
|
|
206
|
+
def comments_for node
|
|
207
|
+
rng = Range.from_node(node)
|
|
208
|
+
# @sg-ignore Need to add nil check here
|
|
209
|
+
stringified_comments[rng.start.line] ||= begin
|
|
210
|
+
# @sg-ignore Need to add nil check here
|
|
211
|
+
buff = associated_comments[rng.start.line]
|
|
212
|
+
buff ? stringify_comment_array(buff) : nil
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# A location representing the file in its entirety.
|
|
217
|
+
#
|
|
218
|
+
# @return [Location]
|
|
219
|
+
def location
|
|
220
|
+
st = Position.new(0, 0)
|
|
221
|
+
en = Position.from_offset(code, code.length)
|
|
222
|
+
range = Range.new(st, en)
|
|
223
|
+
Location.new(filename, range)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
FOLDING_NODE_TYPES = %i[
|
|
227
|
+
class sclass module def defs if str dstr array while unless kwbegin hash block
|
|
228
|
+
].freeze
|
|
229
|
+
|
|
230
|
+
# Get an array of ranges that can be folded, e.g., the range of a class
|
|
231
|
+
# definition or an if condition.
|
|
232
|
+
#
|
|
233
|
+
# See FOLDING_NODE_TYPES for the list of node types that can be folded.
|
|
234
|
+
#
|
|
235
|
+
# @return [Array<Range>]
|
|
236
|
+
def folding_ranges
|
|
237
|
+
@folding_ranges ||= begin
|
|
238
|
+
# @type [Array<Range>]
|
|
239
|
+
result = []
|
|
240
|
+
inner_folding_ranges node, result
|
|
241
|
+
result.concat foldable_comment_block_ranges
|
|
242
|
+
result
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def synchronized?
|
|
247
|
+
true
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# Get a hash of comments grouped by the line numbers of the associated code.
|
|
251
|
+
#
|
|
252
|
+
# @return [Hash{Integer => String, nil}]
|
|
253
|
+
def associated_comments
|
|
254
|
+
@associated_comments ||= begin
|
|
255
|
+
# @type [Hash{Integer => String}]
|
|
256
|
+
result = {}
|
|
257
|
+
buffer = String.new('')
|
|
258
|
+
# @type [Integer, nil]
|
|
259
|
+
last = nil
|
|
260
|
+
comments.each_pair do |num, snip|
|
|
261
|
+
if !last || num == last + 1
|
|
262
|
+
buffer.concat "#{snip.text}\n"
|
|
263
|
+
else
|
|
264
|
+
result[first_not_empty_from(last + 1)] = buffer.clone
|
|
265
|
+
buffer.replace "#{snip.text}\n"
|
|
266
|
+
end
|
|
267
|
+
last = num
|
|
268
|
+
end
|
|
269
|
+
result[first_not_empty_from(last + 1)] = buffer unless buffer.empty? || last.nil?
|
|
270
|
+
result
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
private
|
|
275
|
+
|
|
276
|
+
# @param line [Integer]
|
|
277
|
+
# @return [Integer]
|
|
278
|
+
def first_not_empty_from line
|
|
279
|
+
cursor = line
|
|
280
|
+
cursor += 1 while cursor < code_lines.length && code_lines[cursor].strip.empty?
|
|
281
|
+
cursor = line if cursor > code_lines.length - 1
|
|
282
|
+
cursor
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
# @param top [Parser::AST::Node, nil]
|
|
286
|
+
# @param result [Array<Range>]
|
|
287
|
+
# @param parent [Symbol, nil]
|
|
288
|
+
# @return [void]
|
|
289
|
+
def inner_folding_ranges top, result = [], parent = nil
|
|
290
|
+
return unless Parser.is_ast_node?(top)
|
|
291
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
292
|
+
if FOLDING_NODE_TYPES.include?(top.type)
|
|
293
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
294
|
+
range = Range.from_node(top)
|
|
295
|
+
# @sg-ignore Need to add nil check here
|
|
296
|
+
if result.empty? || range.start.line > result.last.start.line
|
|
297
|
+
# @sg-ignore Need to add nil check here
|
|
298
|
+
result.push range unless range.ending.line - range.start.line < 2
|
|
299
|
+
end
|
|
300
|
+
end
|
|
301
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
302
|
+
top.children.each do |child|
|
|
303
|
+
inner_folding_ranges(child, result, top.type)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Get a string representation of an array of comments.
|
|
308
|
+
#
|
|
309
|
+
# @param comments [String]
|
|
310
|
+
# @return [String]
|
|
311
|
+
def stringify_comment_array comments
|
|
312
|
+
ctxt = String.new('')
|
|
313
|
+
started = false
|
|
314
|
+
skip = nil
|
|
315
|
+
comments.lines.each { |l|
|
|
316
|
+
# Trim the comment and minimum leading whitespace
|
|
317
|
+
p = l.force_encoding('UTF-8').encode('UTF-8', invalid: :replace, replace: '?').gsub(/^#+/, '')
|
|
318
|
+
if p.strip.empty?
|
|
319
|
+
next unless started
|
|
320
|
+
ctxt.concat p
|
|
321
|
+
else
|
|
322
|
+
here = p.index(/[^ \t]/)
|
|
323
|
+
# @sg-ignore flow sensitive typing should be able to handle redefinition
|
|
324
|
+
skip = here if skip.nil? || here < skip
|
|
325
|
+
ctxt.concat p[skip..-1]
|
|
326
|
+
end
|
|
327
|
+
started = true
|
|
328
|
+
}
|
|
329
|
+
ctxt
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# A hash of line numbers and their associated comments.
|
|
333
|
+
#
|
|
334
|
+
# @return [Hash{Integer => String}]
|
|
335
|
+
def stringified_comments
|
|
336
|
+
@stringified_comments ||= {}
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
# @return [Array<Parser::AST::Node>]
|
|
340
|
+
def string_nodes
|
|
341
|
+
@string_nodes ||= string_nodes_in(node)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
# @return [Array<Solargraph::Range>]
|
|
345
|
+
def comment_ranges
|
|
346
|
+
@comment_ranges ||= comments.values.map(&:range)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
# Get an array of foldable comment block ranges. Blocks are excluded if
|
|
350
|
+
# they are less than 3 lines long.
|
|
351
|
+
#
|
|
352
|
+
# @return [Array<Range>]
|
|
353
|
+
def foldable_comment_block_ranges
|
|
354
|
+
return [] unless synchronized?
|
|
355
|
+
result = []
|
|
356
|
+
grouped = []
|
|
357
|
+
comments.keys.each do |l|
|
|
358
|
+
if grouped.empty? || l == grouped.last + 1
|
|
359
|
+
grouped.push l
|
|
360
|
+
else
|
|
361
|
+
result.push Range.from_to(grouped.first, 0, grouped.last, 0) unless grouped.length < 3
|
|
362
|
+
grouped = [l]
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
result.push Range.from_to(grouped.first, 0, grouped.last, 0) unless grouped.length < 3
|
|
366
|
+
result
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# @param n [Parser::AST::Node, nil]
|
|
370
|
+
# @return [Array<Parser::AST::Node>]
|
|
371
|
+
def string_nodes_in n
|
|
372
|
+
result = []
|
|
373
|
+
if Parser.is_ast_node?(n)
|
|
374
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
375
|
+
if n.type == :str || n.type == :dstr || n.type == :STR || n.type == :DSTR
|
|
376
|
+
result.push n
|
|
377
|
+
else
|
|
378
|
+
# @sg-ignore Translate to something flow sensitive typing understands
|
|
379
|
+
n.children.each{ |c| result.concat string_nodes_in(c) }
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
result
|
|
383
|
+
end
|
|
384
|
+
|
|
385
|
+
# @param node [Parser::AST::Node, nil]
|
|
386
|
+
# @param position [Position]
|
|
387
|
+
# @param stack [Array<Parser::AST::Node>]
|
|
388
|
+
# @return [void]
|
|
389
|
+
def inner_tree_at node, position, stack
|
|
390
|
+
return if node.nil?
|
|
391
|
+
here = Range.from_node(node)
|
|
392
|
+
# @sg-ignore Need to add nil check here
|
|
393
|
+
if here.contain?(position)
|
|
394
|
+
stack.unshift node
|
|
395
|
+
node.children.each do |c|
|
|
396
|
+
next unless Parser.is_ast_node?(c)
|
|
397
|
+
next if c.loc.expression.nil?
|
|
398
|
+
inner_tree_at(c, position, stack)
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
protected
|
|
404
|
+
|
|
405
|
+
# @return [Array<Change>]
|
|
406
|
+
def changes
|
|
407
|
+
@changes ||= []
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# @return [String]
|
|
411
|
+
attr_writer :filename
|
|
412
|
+
|
|
413
|
+
# @return [Integer]
|
|
414
|
+
attr_writer :version
|
|
415
|
+
|
|
416
|
+
# @return [void]
|
|
417
|
+
def finalize
|
|
418
|
+
return if @finalized && changes.empty?
|
|
419
|
+
|
|
420
|
+
changes.each do |change|
|
|
421
|
+
@code = change.write(@code)
|
|
422
|
+
end
|
|
423
|
+
@finalized = true
|
|
424
|
+
begin
|
|
425
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@code, filename, 0)
|
|
426
|
+
@parsed = true
|
|
427
|
+
@repaired = @code
|
|
428
|
+
rescue Parser::SyntaxError, EncodingError => e
|
|
429
|
+
@node = nil
|
|
430
|
+
@comments = {}
|
|
431
|
+
@parsed = false
|
|
432
|
+
ensure
|
|
433
|
+
@code.freeze
|
|
434
|
+
end
|
|
435
|
+
if !@parsed && !changes.empty?
|
|
436
|
+
changes.each do |change|
|
|
437
|
+
@repaired = change.repair(@repaired)
|
|
438
|
+
end
|
|
439
|
+
error_ranges.concat(changes.map(&:range))
|
|
440
|
+
begin
|
|
441
|
+
@node, @comments = Solargraph::Parser.parse_with_comments(@repaired, filename, 0)
|
|
442
|
+
@parsed = true
|
|
443
|
+
rescue Parser::SyntaxError, EncodingError => e
|
|
444
|
+
@node = nil
|
|
445
|
+
@comments = {}
|
|
446
|
+
@parsed = false
|
|
447
|
+
end
|
|
448
|
+
elsif @parsed
|
|
449
|
+
error_ranges.clear
|
|
450
|
+
end
|
|
451
|
+
changes.clear
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# @param val [String]
|
|
455
|
+
# @return [String]
|
|
456
|
+
def code=(val)
|
|
457
|
+
@code_lines = nil
|
|
458
|
+
@finalized = false
|
|
459
|
+
@code = val
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
# @return [Parser::AST::Node, nil]
|
|
463
|
+
attr_writer :node
|
|
464
|
+
|
|
465
|
+
# @return [Array<Range>]
|
|
466
|
+
attr_writer :error_ranges
|
|
467
|
+
|
|
468
|
+
# @return [String]
|
|
469
|
+
attr_writer :repaired
|
|
470
|
+
|
|
471
|
+
# @return [String]
|
|
472
|
+
def repaired
|
|
473
|
+
finalize
|
|
474
|
+
@repaired
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
# @return [Boolean]
|
|
478
|
+
attr_writer :parsed
|
|
479
|
+
|
|
480
|
+
# @return [Hash{Integer => String}
|
|
481
|
+
attr_writer :comments
|
|
482
|
+
|
|
483
|
+
# @return [Boolean]
|
|
484
|
+
attr_writer :synchronized
|
|
485
|
+
|
|
486
|
+
private
|
|
487
|
+
|
|
488
|
+
# @return [Array<String>]
|
|
489
|
+
def code_lines
|
|
490
|
+
@code_lines ||= code.lines
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
class << self
|
|
494
|
+
# @param filename [String]
|
|
495
|
+
# @return [Solargraph::Source]
|
|
496
|
+
def load filename
|
|
497
|
+
file = File.open(filename)
|
|
498
|
+
code = file.read
|
|
499
|
+
file.close
|
|
500
|
+
Source.load_string(code, filename)
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
# @param code [String]
|
|
504
|
+
# @param filename [String, nil]
|
|
505
|
+
# @param version [Integer]
|
|
506
|
+
# @return [Solargraph::Source]
|
|
507
|
+
def load_string code, filename = nil, version = 0
|
|
508
|
+
Source.new code, filename, version
|
|
509
|
+
end
|
|
510
|
+
|
|
511
|
+
# @param comments [String]
|
|
512
|
+
# @return [YARD::DocstringParser]
|
|
513
|
+
def parse_docstring comments
|
|
514
|
+
# HACK: Pass a dummy code object to the parser for plugins that
|
|
515
|
+
# expect it not to be nil
|
|
516
|
+
YARD::Docstring.parser.parse(comments, YARD::CodeObjects::Base.new(:root, 'stub'))
|
|
517
|
+
rescue StandardError => e
|
|
518
|
+
Solargraph.logger.info "YARD failed to parse docstring: [#{e.class}] #{e.message}"
|
|
519
|
+
Solargraph.logger.debug "Unparsed comment: #{comments}"
|
|
520
|
+
YARD::Docstring.parser
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
end
|