rbs-inline 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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