rbs-inline 0.1.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/LICENSE.txt +21 -0
- data/README.md +109 -0
- data/Rakefile +12 -0
- data/Steepfile +27 -0
- data/exe/rbs-inline +6 -0
- data/lib/rbs/inline/annotation_parser.rb +765 -0
- data/lib/rbs/inline/ast/annotations.rb +454 -0
- data/lib/rbs/inline/ast/comment_lines.rb +42 -0
- data/lib/rbs/inline/ast/declarations.rb +243 -0
- data/lib/rbs/inline/ast/members.rb +599 -0
- data/lib/rbs/inline/ast/tree.rb +141 -0
- data/lib/rbs/inline/cli.rb +106 -0
- data/lib/rbs/inline/node_utils.rb +12 -0
- data/lib/rbs/inline/parser.rb +360 -0
- data/lib/rbs/inline/version.rb +7 -0
- data/lib/rbs/inline/writer.rb +210 -0
- data/lib/rbs/inline.rb +22 -0
- data/rbs_collection.lock.yaml +68 -0
- data/rbs_collection.yaml +17 -0
- data/sig/generated/rbs/inline/annotation_parser.rbs +222 -0
- data/sig/generated/rbs/inline/ast/annotations.rbs +185 -0
- data/sig/generated/rbs/inline/ast/declarations.rbs +116 -0
- data/sig/generated/rbs/inline/ast/members.rbs +179 -0
- data/sig/generated/rbs/inline/cli.rbs +21 -0
- data/sig/generated/rbs/inline/parser.rbs +116 -0
- data/sig/rbs/inline/annotation_parser.rbs +0 -0
- data/sig/rbs/inline/ast/comment_lines.rbs +27 -0
- data/sig/rbs/inline/ast/members.rbs +24 -0
- data/sig/rbs/inline/ast/tree.rbs +98 -0
- data/sig/rbs/inline/node_utils.rbs +7 -0
- data/sig/rbs/inline/writer.rbs +27 -0
- data/sig/rbs/inline.rbs +41 -0
- data/yard-samples/hello.rb +6 -0
- data/yard-samples/sample1.rb +26 -0
- metadata +111 -0
@@ -0,0 +1,454 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
|
3
|
+
module RBS
|
4
|
+
module Inline
|
5
|
+
module AST
|
6
|
+
module Annotations
|
7
|
+
class Base
|
8
|
+
attr_reader :source #:: CommentLines
|
9
|
+
attr_reader :tree #:: Tree
|
10
|
+
|
11
|
+
# @rbs tree: Tree
|
12
|
+
# @rbs source: CommentLines
|
13
|
+
# @rbs returns void
|
14
|
+
def initialize(tree, source)
|
15
|
+
@tree = tree
|
16
|
+
@source = source
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class VarType < Base
|
21
|
+
attr_reader :name #:: Symbol
|
22
|
+
|
23
|
+
attr_reader :type #:: Types::t?
|
24
|
+
|
25
|
+
attr_reader :comment #:: String?
|
26
|
+
|
27
|
+
# @rbs override
|
28
|
+
def initialize(tree, source)
|
29
|
+
@tree = tree
|
30
|
+
@source = source
|
31
|
+
|
32
|
+
lvar_tree = tree.nth_tree!(1)
|
33
|
+
|
34
|
+
# :tLVAR doesn't have `!` prefix
|
35
|
+
# :tELVAR has `!` prefix to escape keywords
|
36
|
+
@name = lvar_tree.nth_token!(0)[1].delete_prefix("!").to_sym
|
37
|
+
|
38
|
+
if type = lvar_tree.nth_type?(2)
|
39
|
+
@type = type
|
40
|
+
end
|
41
|
+
|
42
|
+
if comment = lvar_tree.nth_tree(3)
|
43
|
+
@comment = comment.to_s
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#:: () -> bool
|
48
|
+
def complete?
|
49
|
+
if name && type
|
50
|
+
true
|
51
|
+
else
|
52
|
+
false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# `@rbs returns T`
|
58
|
+
class ReturnType < Base
|
59
|
+
attr_reader :type #:: Types::t?
|
60
|
+
|
61
|
+
attr_reader :comment #:: String?
|
62
|
+
|
63
|
+
# @rbs override
|
64
|
+
def initialize(tree, source)
|
65
|
+
@tree = tree
|
66
|
+
@source = source
|
67
|
+
|
68
|
+
return_type_decl = tree.nth_tree!(1)
|
69
|
+
|
70
|
+
if type = return_type_decl.nth_type?(1)
|
71
|
+
@type = type
|
72
|
+
end
|
73
|
+
|
74
|
+
if comment = return_type_decl.nth_tree(2)
|
75
|
+
@comment = comment.to_s
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# @rbs returns bool
|
80
|
+
def complete?
|
81
|
+
if type
|
82
|
+
true
|
83
|
+
else
|
84
|
+
false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# `@rbs @foo: T` or `@rbs self.@foo: T`
|
90
|
+
#
|
91
|
+
class IvarType < Base
|
92
|
+
attr_reader :name #:: Symbol
|
93
|
+
|
94
|
+
attr_reader :type #:: Types::t?
|
95
|
+
|
96
|
+
attr_reader :class_instance #:: bool
|
97
|
+
|
98
|
+
attr_reader :comment #:: String?
|
99
|
+
|
100
|
+
# @rbs override
|
101
|
+
def initialize(tree, source)
|
102
|
+
@tree = tree
|
103
|
+
@source = source
|
104
|
+
|
105
|
+
ivar_tree = tree.nth_tree!(1)
|
106
|
+
@class_instance = ivar_tree.nth_token?(0).is_a?(Array)
|
107
|
+
@name = ivar_tree.nth_token!(2).last.to_sym
|
108
|
+
@type = ivar_tree.nth_type?(4)
|
109
|
+
|
110
|
+
if comment = ivar_tree.nth_tree(5)
|
111
|
+
@comment = comment.to_s
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
# `#:: TYPE`
|
117
|
+
#
|
118
|
+
class Assertion < Base
|
119
|
+
attr_reader :type #:: Types::t | MethodType | nil
|
120
|
+
|
121
|
+
def initialize(tree, source)
|
122
|
+
@source = source
|
123
|
+
@tree = tree
|
124
|
+
|
125
|
+
@type = tree.nth_method_type?(1) || tree.nth_type?(1)
|
126
|
+
end
|
127
|
+
|
128
|
+
# @rbs returns bool
|
129
|
+
def complete?
|
130
|
+
if type
|
131
|
+
true
|
132
|
+
else
|
133
|
+
false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Returns a type if it's type
|
138
|
+
#
|
139
|
+
def type? #:: Types::t?
|
140
|
+
case type
|
141
|
+
when MethodType, nil
|
142
|
+
nil
|
143
|
+
else
|
144
|
+
type
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Returns a method type if it's a method type
|
149
|
+
#
|
150
|
+
def method_type? #:: MethodType?
|
151
|
+
case type
|
152
|
+
when MethodType
|
153
|
+
type
|
154
|
+
else
|
155
|
+
nil
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# `#[TYPE, ..., TYPE]`
|
161
|
+
#
|
162
|
+
class Application < Base
|
163
|
+
attr_reader :types #:: Array[Types::t]?
|
164
|
+
|
165
|
+
# @rbs override
|
166
|
+
def initialize(tree, source)
|
167
|
+
@tree = tree
|
168
|
+
@source = source
|
169
|
+
|
170
|
+
if ts = tree.nth_tree(0)
|
171
|
+
if types = ts.nth_tree(1)
|
172
|
+
@types = types.non_trivia_trees.each_slice(2).map do |type, comma|
|
173
|
+
# @type break: nil
|
174
|
+
|
175
|
+
case type
|
176
|
+
when AST::Tree, MethodType, Array, nil
|
177
|
+
break
|
178
|
+
else
|
179
|
+
type
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
# @rbs returns bool
|
187
|
+
def complete?
|
188
|
+
types ? true : false
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
# `# @rbs yields () -> void -- Comment`
|
193
|
+
#
|
194
|
+
class Yields < Base
|
195
|
+
# The type of block
|
196
|
+
#
|
197
|
+
# * Types::Block when syntactically correct input is given
|
198
|
+
# * String when syntax error is reported
|
199
|
+
# * `nil` when nothing is given
|
200
|
+
#
|
201
|
+
attr_reader :block_type #:: Types::Block | String | nil
|
202
|
+
|
203
|
+
# The content of the comment or `nil`
|
204
|
+
#
|
205
|
+
attr_reader :comment #:: String?
|
206
|
+
|
207
|
+
# If `[optional]` token is inserted just after `yields` token
|
208
|
+
#
|
209
|
+
# The Types::Block instance has correct `required` attribute based on the `[optional]` token.
|
210
|
+
# This is for the other cases, syntax error or omitted.
|
211
|
+
#
|
212
|
+
attr_reader :optional #:: bool
|
213
|
+
|
214
|
+
# @rbs override
|
215
|
+
def initialize(tree, comments)
|
216
|
+
@tree = tree
|
217
|
+
@source = comments
|
218
|
+
|
219
|
+
yields_tree = tree.nth_tree!(1)
|
220
|
+
@optional = yields_tree.nth_token?(1).is_a?(Array)
|
221
|
+
if block_token = yields_tree.nth_token(2)
|
222
|
+
block_src = block_token[1]
|
223
|
+
proc_src = "^" + block_src
|
224
|
+
proc_type = ::RBS::Parser.parse_type(proc_src, require_eof: true) rescue RBS::ParsingError
|
225
|
+
if proc_type.is_a?(Types::Proc)
|
226
|
+
@block_type = Types::Block.new(
|
227
|
+
type: proc_type.type,
|
228
|
+
required: !optional,
|
229
|
+
self_type: proc_type.self_type
|
230
|
+
)
|
231
|
+
else
|
232
|
+
@block_type = block_src
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
@comment = yields_tree.nth_tree?(3)&.to_s
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
# `# @rbs %a{a} %a{a} ...`
|
241
|
+
class RBSAnnotation < Base
|
242
|
+
attr_reader :contents #:: Array[String]
|
243
|
+
|
244
|
+
# @rbs override
|
245
|
+
def initialize(tree, comments)
|
246
|
+
@source = comments
|
247
|
+
@tree = tree
|
248
|
+
|
249
|
+
annots = tree.nth_tree!(1)
|
250
|
+
@contents = annots.non_trivia_trees.map do |token|
|
251
|
+
raise unless token.is_a?(Array)
|
252
|
+
token[1]
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# `# @rbs skip`
|
258
|
+
#
|
259
|
+
class Skip < Base
|
260
|
+
# @rbs override
|
261
|
+
def initialize(tree, source)
|
262
|
+
@tree = tree
|
263
|
+
@source = source
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
# `# @rbs inherits T`
|
268
|
+
#
|
269
|
+
class Inherits < Base
|
270
|
+
attr_reader :super_name #:: TypeName?
|
271
|
+
attr_reader :args #:: Array[Types::t]?
|
272
|
+
|
273
|
+
# @rbs override
|
274
|
+
def initialize(tree, source)
|
275
|
+
@tree = tree
|
276
|
+
@source = source
|
277
|
+
|
278
|
+
inherits = tree.nth_tree!(1)
|
279
|
+
if super_type = inherits.nth_type(1)
|
280
|
+
if super_type.is_a?(Types::ClassInstance)
|
281
|
+
@super_name = super_type.name
|
282
|
+
@args = super_type.args
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
# `# @rbs override`
|
289
|
+
#
|
290
|
+
# Specify the method types as `...` (overriding super class method)
|
291
|
+
#
|
292
|
+
class Override < Base
|
293
|
+
# @rbs override
|
294
|
+
def initialize(tree, source)
|
295
|
+
@tree = tree
|
296
|
+
@source = source
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
# `# @rbs use [USES]`
|
301
|
+
class Use < Base
|
302
|
+
attr_reader :clauses #:: Array[RBS::AST::Directives::Use::clause]
|
303
|
+
|
304
|
+
# @rbs override
|
305
|
+
def initialize(tree, source)
|
306
|
+
@tree = tree
|
307
|
+
@source = source
|
308
|
+
|
309
|
+
@clauses = []
|
310
|
+
|
311
|
+
tree.nth_tree!(1).tap do |use_tree|
|
312
|
+
_, *clause_pairs = use_tree.non_trivia_trees
|
313
|
+
clause_pairs.each_slice(2) do |clause, _comma|
|
314
|
+
if clause.is_a?(Tree)
|
315
|
+
*tokens, last_token = clause.non_trivia_trees
|
316
|
+
token_strs = tokens.map do |tok|
|
317
|
+
if tok.is_a?(Array)
|
318
|
+
tok[1]
|
319
|
+
else
|
320
|
+
raise
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
case last_token
|
325
|
+
when Array
|
326
|
+
# `*` clause
|
327
|
+
namespace = Namespace(token_strs.join)
|
328
|
+
@clauses << RBS::AST::Directives::Use::WildcardClause.new(
|
329
|
+
namespace: namespace,
|
330
|
+
location: nil
|
331
|
+
)
|
332
|
+
when Tree, nil
|
333
|
+
if last_token
|
334
|
+
if new_name_token = last_token.nth_token(1)
|
335
|
+
new_name = new_name_token[1].to_sym
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
typename = TypeName(token_strs.join)
|
340
|
+
@clauses << RBS::AST::Directives::Use::SingleClause.new(
|
341
|
+
type_name: typename,
|
342
|
+
new_name: new_name,
|
343
|
+
location: nil
|
344
|
+
)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
# `# @rbs module-self [MODULE_SELF]`
|
353
|
+
class ModuleSelf < Base
|
354
|
+
attr_reader :constraint #:: RBS::AST::Declarations::Module::Self?
|
355
|
+
|
356
|
+
attr_reader :comment #:: String?
|
357
|
+
|
358
|
+
# @rbs override
|
359
|
+
def initialize(tree, source)
|
360
|
+
@tree = tree
|
361
|
+
@source = source
|
362
|
+
|
363
|
+
module_self = tree.nth_tree!(1)
|
364
|
+
type = module_self.nth_type?(1)
|
365
|
+
|
366
|
+
case type
|
367
|
+
when Types::ClassInstance, Types::Interface
|
368
|
+
@constraint = RBS::AST::Declarations::Module::Self.new(
|
369
|
+
name: type.name,
|
370
|
+
args: type.args,
|
371
|
+
location: nil
|
372
|
+
)
|
373
|
+
end
|
374
|
+
|
375
|
+
if comment = module_self.nth_tree(2)
|
376
|
+
@comment = comment.to_s
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
# `# @rbs generic [type param]`
|
382
|
+
#
|
383
|
+
# ```rb
|
384
|
+
# # @rbs generic X
|
385
|
+
# # @rbs generic in Y
|
386
|
+
# # @rbs generic unchecked out Z < String -- Comment here
|
387
|
+
# ```
|
388
|
+
#
|
389
|
+
class Generic < Base
|
390
|
+
# TypeParam object or `nil` if syntax error
|
391
|
+
#
|
392
|
+
attr_reader :type_param #:: RBS::AST::TypeParam?
|
393
|
+
|
394
|
+
attr_reader :comment #:: String?
|
395
|
+
|
396
|
+
# @rbs override
|
397
|
+
def initialize(tree, source)
|
398
|
+
@tree = tree
|
399
|
+
@source = source
|
400
|
+
|
401
|
+
generic_tree = tree.nth_tree!(1)
|
402
|
+
unchecked = generic_tree.nth_token?(1) != nil
|
403
|
+
inout =
|
404
|
+
case generic_tree.nth_token?(2)&.[](0)
|
405
|
+
when nil
|
406
|
+
:invariant
|
407
|
+
when :kIN
|
408
|
+
:contravariant
|
409
|
+
when :kOUT
|
410
|
+
:covariant
|
411
|
+
end #: RBS::AST::TypeParam::variance
|
412
|
+
|
413
|
+
name = generic_tree.nth_token?(3)&.last
|
414
|
+
|
415
|
+
if bound = generic_tree.nth_tree?(4)
|
416
|
+
if type = bound.nth_type?(1)
|
417
|
+
case type
|
418
|
+
when Types::ClassSingleton, Types::ClassInstance, Types::Interface
|
419
|
+
upper_bound = type
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
if name
|
425
|
+
@type_param = RBS::AST::TypeParam.new(
|
426
|
+
name: name.to_sym,
|
427
|
+
variance: inout,
|
428
|
+
upper_bound: upper_bound,
|
429
|
+
location: nil
|
430
|
+
).unchecked!(unchecked)
|
431
|
+
end
|
432
|
+
|
433
|
+
if comment = generic_tree.nth_tree?(5)
|
434
|
+
@comment = comment.to_s
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
# `# @rbs!` annotation
|
440
|
+
class Embedded < Base
|
441
|
+
attr_reader :content #:: String
|
442
|
+
|
443
|
+
# @rbs override
|
444
|
+
def initialize(tree, source)
|
445
|
+
@tree = tree
|
446
|
+
@source = source
|
447
|
+
|
448
|
+
@content = tree.nth_token!(1)[1]
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RBS
|
2
|
+
module Inline
|
3
|
+
module AST
|
4
|
+
class CommentLines
|
5
|
+
attr_reader :comments
|
6
|
+
|
7
|
+
def initialize(comments)
|
8
|
+
offsets = comments.map do |comment|
|
9
|
+
comment.location.slice.index(/[^#\s]/) || 1
|
10
|
+
end
|
11
|
+
first_offset = offsets[0]
|
12
|
+
|
13
|
+
@comments = comments.map.with_index do |comment, index|
|
14
|
+
offset = offsets[index]
|
15
|
+
offset = first_offset if offset > first_offset
|
16
|
+
|
17
|
+
[comment, offset]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def string
|
22
|
+
comments.map {|comment, offset| comment.location.slice[offset..] }.join("\n")
|
23
|
+
end
|
24
|
+
|
25
|
+
def comment_location(index)
|
26
|
+
comments.each do |comment, offset|
|
27
|
+
comment_length = comment.location.length
|
28
|
+
|
29
|
+
if index + offset <= comment_length
|
30
|
+
return [comment, index + offset]
|
31
|
+
else
|
32
|
+
index = index - comment_length + offset - 1
|
33
|
+
return if index < 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|