rbi 0.0.1 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,756 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RBI
5
+ class Printer < Visitor
6
+ extend T::Sig
7
+
8
+ sig { returns(T::Boolean) }
9
+ attr_accessor :print_locs, :in_visibility_group
10
+
11
+ sig { returns(T.nilable(Node)) }
12
+ attr_reader :previous_node
13
+
14
+ sig { params(out: T.any(IO, StringIO), indent: Integer, print_locs: T::Boolean).void }
15
+ def initialize(out: $stdout, indent: 0, print_locs: false)
16
+ super()
17
+ @out = out
18
+ @current_indent = indent
19
+ @print_locs = print_locs
20
+ @in_visibility_group = T.let(false, T::Boolean)
21
+ @previous_node = T.let(nil, T.nilable(Node))
22
+ end
23
+
24
+ # Printing
25
+
26
+ sig { void }
27
+ def indent
28
+ @current_indent += 2
29
+ end
30
+
31
+ sig { void }
32
+ def dedent
33
+ @current_indent -= 2
34
+ end
35
+
36
+ # Print a string without indentation nor `\n` at the end.
37
+ sig { params(string: String).void }
38
+ def print(string)
39
+ @out.print(string)
40
+ end
41
+
42
+ # Print a string without indentation but with a `\n` at the end.
43
+ sig { params(string: T.nilable(String)).void }
44
+ def printn(string = nil)
45
+ print(string) if string
46
+ print("\n")
47
+ end
48
+
49
+ # Print a string with indentation but without a `\n` at the end.
50
+ sig { params(string: T.nilable(String)).void }
51
+ def printt(string = nil)
52
+ print(" " * @current_indent)
53
+ print(string) if string
54
+ end
55
+
56
+ # Print a string with indentation and `\n` at the end.
57
+ sig { params(string: String).void }
58
+ def printl(string)
59
+ printt
60
+ printn(string)
61
+ end
62
+
63
+ sig { params(file: File).void }
64
+ def visit_file(file)
65
+ file.accept_printer(self)
66
+ end
67
+
68
+ sig { override.params(node: T.nilable(Node)).void }
69
+ def visit(node)
70
+ return unless node
71
+ node.accept_printer(self)
72
+ end
73
+
74
+ sig { override.params(nodes: T::Array[Node]).void }
75
+ def visit_all(nodes)
76
+ previous_node = @previous_node
77
+ @previous_node = nil
78
+ nodes.each do |node|
79
+ visit(node)
80
+ @previous_node = node
81
+ end
82
+ @previous_node = previous_node
83
+ end
84
+ end
85
+
86
+ class File
87
+ extend T::Sig
88
+
89
+ sig { params(v: Printer).void }
90
+ def accept_printer(v)
91
+ strictness = self.strictness
92
+ if strictness
93
+ v.printl("# typed: #{strictness}")
94
+ end
95
+ unless comments.empty?
96
+ v.printn if strictness
97
+ v.visit_all(comments)
98
+ end
99
+
100
+ unless root.empty? && root.comments.empty?
101
+ v.printn if strictness || !comments.empty?
102
+ v.visit(root)
103
+ end
104
+ end
105
+
106
+ sig { params(out: T.any(IO, StringIO), indent: Integer, print_locs: T::Boolean).void }
107
+ def print(out: $stdout, indent: 0, print_locs: false)
108
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs)
109
+ p.visit_file(self)
110
+ end
111
+
112
+ sig { params(indent: Integer, print_locs: T::Boolean).returns(String) }
113
+ def string(indent: 0, print_locs: false)
114
+ out = StringIO.new
115
+ print(out: out, indent: indent, print_locs: print_locs)
116
+ out.string
117
+ end
118
+ end
119
+
120
+ class Node
121
+ extend T::Sig
122
+
123
+ sig { abstract.params(v: Printer).void }
124
+ def accept_printer(v); end
125
+
126
+ sig { params(out: T.any(IO, StringIO), indent: Integer, print_locs: T::Boolean).void }
127
+ def print(out: $stdout, indent: 0, print_locs: false)
128
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs)
129
+ p.visit(self)
130
+ end
131
+
132
+ sig { params(indent: Integer, print_locs: T::Boolean).returns(String) }
133
+ def string(indent: 0, print_locs: false)
134
+ out = StringIO.new
135
+ print(out: out, indent: indent, print_locs: print_locs)
136
+ out.string
137
+ end
138
+
139
+ sig { returns(T::Boolean) }
140
+ def oneline?
141
+ true
142
+ end
143
+ end
144
+
145
+ class NodeWithComments
146
+ extend T::Sig
147
+
148
+ sig { override.returns(T::Boolean) }
149
+ def oneline?
150
+ comments.empty?
151
+ end
152
+ end
153
+
154
+ class Comment
155
+ extend T::Sig
156
+
157
+ sig { override.params(v: Printer).void }
158
+ def accept_printer(v)
159
+ lines = text.lines
160
+
161
+ if lines.empty?
162
+ v.printl("#")
163
+ end
164
+
165
+ lines.each do |line|
166
+ text = line.strip
167
+ v.printt("#")
168
+ v.print(" #{text}") unless text.empty?
169
+ v.printn
170
+ end
171
+ end
172
+ end
173
+
174
+ class EmptyComment
175
+ extend T::Sig
176
+
177
+ sig { override.params(v: Printer).void }
178
+ def accept_printer(v)
179
+ v.printn
180
+ end
181
+ end
182
+
183
+ class Tree
184
+ extend T::Sig
185
+
186
+ sig { override.params(v: Printer).void }
187
+ def accept_printer(v)
188
+ v.visit_all(comments)
189
+ v.printn if !comments.empty? && !empty?
190
+ v.visit_all(nodes)
191
+ end
192
+
193
+ sig { override.returns(T::Boolean) }
194
+ def oneline?
195
+ comments.empty? && empty?
196
+ end
197
+ end
198
+
199
+ class Scope
200
+ extend T::Sig
201
+
202
+ sig { override.params(v: Printer).void }
203
+ def accept_printer(v)
204
+ previous_node = v.previous_node
205
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
206
+
207
+ v.printl("# #{loc}") if loc && v.print_locs
208
+ v.visit_all(comments)
209
+
210
+ print_header(v)
211
+ print_body(v)
212
+ end
213
+
214
+ sig { abstract.params(v: Printer).void }
215
+ def print_header(v); end
216
+
217
+ sig { params(v: Printer).void }
218
+ def print_body(v)
219
+ unless empty?
220
+ v.indent
221
+ v.visit_all(nodes)
222
+ v.dedent
223
+ v.printl("end")
224
+ end
225
+ end
226
+ end
227
+
228
+ class Module
229
+ extend T::Sig
230
+
231
+ sig { override.params(v: Printer).void }
232
+ def print_header(v)
233
+ v.printt("module #{name}")
234
+ if empty?
235
+ v.printn("; end")
236
+ else
237
+ v.printn
238
+ end
239
+ end
240
+ end
241
+
242
+ class Class
243
+ extend T::Sig
244
+
245
+ sig { override.params(v: Printer).void }
246
+ def print_header(v)
247
+ v.printt("class #{name}")
248
+ superclass = superclass_name
249
+ v.print(" < #{superclass}") if superclass
250
+ if empty?
251
+ v.printn("; end")
252
+ else
253
+ v.printn
254
+ end
255
+ end
256
+ end
257
+
258
+ class Struct
259
+ extend T::Sig
260
+
261
+ sig { override.params(v: Printer).void }
262
+ def print_header(v)
263
+ v.printt("#{name} = ::Struct.new")
264
+ if !members.empty? || keyword_init
265
+ v.print("(")
266
+ args = members.map { |member| ":#{member}" }
267
+ args << "keyword_init: true" if keyword_init
268
+ v.print(args.join(", "))
269
+ v.print(")")
270
+ end
271
+ if empty?
272
+ v.printn
273
+ else
274
+ v.printn(" do")
275
+ end
276
+ end
277
+ end
278
+
279
+ class SingletonClass
280
+ extend T::Sig
281
+
282
+ sig { override.params(v: Printer).void }
283
+ def print_header(v)
284
+ v.printt("class << self")
285
+ if empty?
286
+ v.printn("; end")
287
+ else
288
+ v.printn
289
+ end
290
+ end
291
+ end
292
+
293
+ class Const
294
+ extend T::Sig
295
+
296
+ sig { override.params(v: Printer).void }
297
+ def accept_printer(v)
298
+ previous_node = v.previous_node
299
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
300
+
301
+ v.printl("# #{loc}") if loc && v.print_locs
302
+ v.visit_all(comments)
303
+ v.printl("#{name} = #{value}")
304
+ end
305
+ end
306
+
307
+ class Attr
308
+ extend T::Sig
309
+
310
+ sig { override.params(v: Printer).void }
311
+ def accept_printer(v)
312
+ previous_node = v.previous_node
313
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
314
+
315
+ v.visit_all(comments)
316
+ sigs.each { |sig| v.visit(sig) }
317
+ v.printl("# #{loc}") if loc && v.print_locs
318
+ v.printt
319
+ unless v.in_visibility_group || visibility.public?
320
+ v.print(visibility.visibility.to_s)
321
+ v.print(" ")
322
+ end
323
+ case self
324
+ when AttrAccessor
325
+ v.print("attr_accessor")
326
+ when AttrReader
327
+ v.print("attr_reader")
328
+ when AttrWriter
329
+ v.print("attr_writer")
330
+ end
331
+ unless names.empty?
332
+ v.print(" ")
333
+ v.print(names.map { |name| ":#{name}" }.join(", "))
334
+ end
335
+ v.printn
336
+ end
337
+
338
+ sig { override.returns(T::Boolean) }
339
+ def oneline?
340
+ comments.empty? && sigs.empty?
341
+ end
342
+ end
343
+
344
+ class Method
345
+ extend T::Sig
346
+
347
+ sig { override.params(v: Printer).void }
348
+ def accept_printer(v)
349
+ previous_node = v.previous_node
350
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
351
+
352
+ v.visit_all(comments)
353
+ v.visit_all(sigs)
354
+ v.printl("# #{loc}") if loc && v.print_locs
355
+ v.printt
356
+ unless v.in_visibility_group || visibility.public?
357
+ v.print(visibility.visibility.to_s)
358
+ v.print(" ")
359
+ end
360
+ v.print("def ")
361
+ v.print("self.") if is_singleton
362
+ v.print(name)
363
+ unless params.empty?
364
+ v.print("(")
365
+ if inline_params?
366
+ params.each_with_index do |param, index|
367
+ v.print(", ") if index > 0
368
+ v.visit(param)
369
+ end
370
+ else
371
+ v.printn
372
+ v.indent
373
+ params.each_with_index do |param, pindex|
374
+ v.printt
375
+ v.visit(param)
376
+ v.print(",") if pindex < params.size - 1
377
+
378
+ param.comments_lines.each_with_index do |comment, cindex|
379
+ if cindex > 0
380
+ param.print_comment_leading_space(v, last: pindex == params.size - 1)
381
+ else
382
+ v.print(" ")
383
+ end
384
+ v.print("# #{comment}")
385
+ end
386
+ v.printn
387
+ end
388
+ v.dedent
389
+ end
390
+ v.print(")")
391
+ end
392
+ v.print("; end")
393
+ v.printn
394
+ end
395
+
396
+ sig { override.returns(T::Boolean) }
397
+ def oneline?
398
+ comments.empty? && sigs.empty? && inline_params?
399
+ end
400
+
401
+ sig { returns(T::Boolean) }
402
+ def inline_params?
403
+ params.all? { |p| p.comments.empty? }
404
+ end
405
+ end
406
+
407
+ class Param
408
+ extend T::Sig
409
+
410
+ sig { override.params(v: Printer).void }
411
+ def accept_printer(v)
412
+ v.print(name.to_s)
413
+ end
414
+
415
+ sig { params(v: Printer, last: T::Boolean).void }
416
+ def print_comment_leading_space(v, last:)
417
+ v.printn
418
+ v.printt
419
+ v.print(" " * (name.size + 1))
420
+ v.print(" ") unless last
421
+ end
422
+
423
+ sig { returns(T::Array[String]) }
424
+ def comments_lines
425
+ comments.flat_map { |comment| comment.text.lines.map(&:strip) }
426
+ end
427
+ end
428
+
429
+ class OptParam
430
+ extend T::Sig
431
+
432
+ sig { override.params(v: Printer).void }
433
+ def accept_printer(v)
434
+ v.print("#{name} = #{value}")
435
+ end
436
+
437
+ sig { override.params(v: Printer, last: T::Boolean).void }
438
+ def print_comment_leading_space(v, last:)
439
+ super
440
+ v.print(" " * (value.size + 3))
441
+ end
442
+ end
443
+
444
+ class RestParam
445
+ extend T::Sig
446
+
447
+ sig { override.params(v: Printer).void }
448
+ def accept_printer(v)
449
+ v.print("*#{name}")
450
+ end
451
+
452
+ sig { override.params(v: Printer, last: T::Boolean).void }
453
+ def print_comment_leading_space(v, last:)
454
+ super
455
+ v.print(" ")
456
+ end
457
+ end
458
+
459
+ class KwParam
460
+ extend T::Sig
461
+
462
+ sig { override.params(v: Printer).void }
463
+ def accept_printer(v)
464
+ v.print("#{name}:")
465
+ end
466
+
467
+ sig { override.params(v: Printer, last: T::Boolean).void }
468
+ def print_comment_leading_space(v, last:)
469
+ super
470
+ v.print(" ")
471
+ end
472
+ end
473
+
474
+ class KwOptParam
475
+ extend T::Sig
476
+
477
+ sig { override.params(v: Printer).void }
478
+ def accept_printer(v)
479
+ v.print("#{name}: #{value}")
480
+ end
481
+
482
+ sig { override.params(v: Printer, last: T::Boolean).void }
483
+ def print_comment_leading_space(v, last:)
484
+ super
485
+ v.print(" " * (value.size + 2))
486
+ end
487
+ end
488
+
489
+ class KwRestParam
490
+ extend T::Sig
491
+
492
+ sig { override.params(v: Printer).void }
493
+ def accept_printer(v)
494
+ v.print("**#{name}")
495
+ end
496
+
497
+ sig { override.params(v: Printer, last: T::Boolean).void }
498
+ def print_comment_leading_space(v, last:)
499
+ super
500
+ v.print(" ")
501
+ end
502
+ end
503
+
504
+ class BlockParam
505
+ extend T::Sig
506
+
507
+ sig { override.params(v: Printer).void }
508
+ def accept_printer(v)
509
+ v.print("&#{name}")
510
+ end
511
+
512
+ sig { override.params(v: Printer, last: T::Boolean).void }
513
+ def print_comment_leading_space(v, last:)
514
+ super
515
+ v.print(" ")
516
+ end
517
+ end
518
+
519
+ class Mixin
520
+ extend T::Sig
521
+
522
+ sig { override.params(v: Printer).void }
523
+ def accept_printer(v)
524
+ previous_node = v.previous_node
525
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
526
+
527
+ v.printl("# #{loc}") if loc && v.print_locs
528
+ v.visit_all(comments)
529
+ case self
530
+ when Include
531
+ v.printt("include")
532
+ when Extend
533
+ v.printt("extend")
534
+ when MixesInClassMethods
535
+ v.printt("mixes_in_class_methods")
536
+ end
537
+ v.printn(" #{names.join(", ")}")
538
+ end
539
+ end
540
+
541
+ class Visibility
542
+ extend T::Sig
543
+
544
+ sig { override.params(v: Printer).void }
545
+ def accept_printer(v)
546
+ previous_node = v.previous_node
547
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
548
+
549
+ v.printl("# #{loc}") if loc && v.print_locs
550
+ v.visit_all(comments)
551
+ v.printl(visibility.to_s)
552
+ end
553
+ end
554
+
555
+ class Sig
556
+ extend T::Sig
557
+
558
+ sig { override.params(v: Printer).void }
559
+ def accept_printer(v)
560
+ v.printl("# #{loc}") if loc && v.print_locs
561
+ if oneline?
562
+ v.printt("sig { ")
563
+ else
564
+ v.printl("sig do")
565
+ v.indent
566
+ end
567
+ v.print("abstract.") if is_abstract
568
+ v.print("override.") if is_override
569
+ v.print("overridable.") if is_overridable
570
+ unless type_params.empty?
571
+ v.print("type_parameters(")
572
+ type_params.each_with_index do |param, index|
573
+ v.print(":#{param}")
574
+ v.print(", ") if index < type_params.length - 1
575
+ end
576
+ v.print(").")
577
+ end
578
+ unless params.empty?
579
+ if inline_params?
580
+ v.print("params(")
581
+ params.each_with_index do |param, index|
582
+ v.print(", ") if index > 0
583
+ v.visit(param)
584
+ end
585
+ v.print(").")
586
+ else
587
+ v.printl("params(")
588
+ v.indent
589
+ params.each_with_index do |param, pindex|
590
+ v.printt
591
+ v.visit(param)
592
+ v.print(",") if pindex < params.size - 1
593
+ param.comments_lines.each_with_index do |comment, cindex|
594
+ if cindex == 0
595
+ v.print(" ")
596
+ else
597
+ param.print_comment_leading_space(v, last: pindex == params.size - 1)
598
+ end
599
+ v.print("# #{comment}")
600
+ end
601
+ v.printn
602
+ end
603
+ v.dedent
604
+ v.printt(").")
605
+ end
606
+ end
607
+ if return_type && return_type != "void"
608
+ v.print("returns(#{return_type})")
609
+ else
610
+ v.print("void")
611
+ end
612
+ if checked
613
+ v.print(".checked(:#{checked})")
614
+ end
615
+ if oneline?
616
+ v.printn(" }")
617
+ else
618
+ v.printn
619
+ v.dedent
620
+ v.printl("end")
621
+ end
622
+ end
623
+
624
+ sig { override.returns(T::Boolean) }
625
+ def oneline?
626
+ inline_params?
627
+ end
628
+
629
+ sig { returns(T::Boolean) }
630
+ def inline_params?
631
+ params.all? { |p| p.comments.empty? }
632
+ end
633
+ end
634
+
635
+ class SigParam
636
+ extend T::Sig
637
+
638
+ sig { override.params(v: Printer).void }
639
+ def accept_printer(v)
640
+ v.print("#{name}: #{type}")
641
+ end
642
+
643
+ sig { params(v: Printer, last: T::Boolean).void }
644
+ def print_comment_leading_space(v, last:)
645
+ v.printn
646
+ v.printt
647
+ v.print(" " * (name.size + type.size + 3))
648
+ v.print(" ") unless last
649
+ end
650
+
651
+ sig { returns(T::Array[String]) }
652
+ def comments_lines
653
+ comments.flat_map { |comment| comment.text.lines.map(&:strip) }
654
+ end
655
+ end
656
+
657
+ class TStructField
658
+ extend T::Sig
659
+
660
+ sig { override.params(v: Printer).void }
661
+ def accept_printer(v)
662
+ previous_node = v.previous_node
663
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
664
+
665
+ v.printl("# #{loc}") if loc && v.print_locs
666
+ v.visit_all(comments)
667
+ case self
668
+ when TStructProp
669
+ v.printt("prop")
670
+ when TStructConst
671
+ v.printt("const")
672
+ end
673
+ v.print(" :#{name}, #{type}")
674
+ default = self.default
675
+ v.print(", default: #{default}") if default
676
+ v.printn
677
+ end
678
+ end
679
+
680
+ class TEnumBlock
681
+ extend T::Sig
682
+
683
+ sig { override.params(v: Printer).void }
684
+ def accept_printer(v)
685
+ v.printl("# #{loc}") if loc && v.print_locs
686
+ v.visit_all(comments)
687
+ v.printl("enums do")
688
+ v.indent
689
+ names.each do |name|
690
+ v.printl("#{name} = new")
691
+ end
692
+ v.dedent
693
+ v.printl("end")
694
+ end
695
+ end
696
+
697
+ class TypeMember
698
+ extend T::Sig
699
+
700
+ sig { override.params(v: Printer).void }
701
+ def accept_printer(v)
702
+ previous_node = v.previous_node
703
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
704
+
705
+ v.printl("# #{loc}") if loc && v.print_locs
706
+ v.visit_all(comments)
707
+ v.printl("#{name} = #{value}")
708
+ end
709
+ end
710
+
711
+ class Helper
712
+ extend T::Sig
713
+
714
+ sig { override.params(v: Printer).void }
715
+ def accept_printer(v)
716
+ previous_node = v.previous_node
717
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
718
+
719
+ v.printl("# #{loc}") if loc && v.print_locs
720
+ v.visit_all(comments)
721
+ v.printl("#{name}!")
722
+ end
723
+ end
724
+
725
+ class Group
726
+ extend T::Sig
727
+
728
+ sig { override.params(v: Printer).void }
729
+ def accept_printer(v)
730
+ v.printn unless v.previous_node.nil?
731
+ v.visit_all(nodes)
732
+ end
733
+ end
734
+
735
+ class VisibilityGroup
736
+ extend T::Sig
737
+
738
+ sig { override.params(v: Printer).void }
739
+ def accept_printer(v)
740
+ v.in_visibility_group = true
741
+ if visibility.public?
742
+ v.printn unless v.previous_node.nil?
743
+ else
744
+ v.visit(visibility)
745
+ v.printn
746
+ end
747
+ v.visit_all(nodes)
748
+ v.in_visibility_group = false
749
+ end
750
+
751
+ sig { override.returns(T::Boolean) }
752
+ def oneline?
753
+ false
754
+ end
755
+ end
756
+ end