rbi 0.3.9 → 0.3.11

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.
data/lib/rbi/parser.rb CHANGED
@@ -751,7 +751,7 @@ module RBI
751
751
  )
752
752
  when Prism::BlockParameterNode
753
753
  BlockParam.new(
754
- param.name&.to_s || "&block",
754
+ param.name&.to_s || "",
755
755
  loc: node_loc(param),
756
756
  comments: node_comments(param),
757
757
  )
data/lib/rbi/printer.rb CHANGED
@@ -5,6 +5,10 @@ module RBI
5
5
  class PrinterError < Error; end
6
6
 
7
7
  class Printer < Visitor
8
+ # Pre-computed indentation strings to avoid allocating " " * indent on every line.
9
+ MAX_CACHED_INDENT = 50 #: Integer
10
+ INDENT_CACHE = Array.new(MAX_CACHED_INDENT + 1) { |i| (" " * i).freeze }.freeze #: Array[String]
11
+
8
12
  #: bool
9
13
  attr_accessor :print_locs, :in_visibility_group
10
14
 
@@ -17,7 +21,7 @@ module RBI
17
21
  #: Integer?
18
22
  attr_reader :max_line_length
19
23
 
20
- #: (?out: (IO | StringIO), ?indent: Integer, ?print_locs: bool, ?max_line_length: Integer?) -> void
24
+ #: (?out: (IO | StringIO | String), ?indent: Integer, ?print_locs: bool, ?max_line_length: Integer?) -> void
21
25
  def initialize(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
22
26
  super()
23
27
  @out = out
@@ -40,36 +44,46 @@ module RBI
40
44
  @current_indent -= 2
41
45
  end
42
46
 
47
+ #: -> String
48
+ def current_indent_string
49
+ INDENT_CACHE[@current_indent] || " " * @current_indent
50
+ end
51
+
43
52
  # Print a string without indentation nor `\n` at the end.
44
53
  #: (String string) -> void
45
54
  def print(string)
46
- @out.print(string)
55
+ @out << string
47
56
  end
48
57
 
49
58
  # Print a string without indentation but with a `\n` at the end.
50
59
  #: (?String? string) -> void
51
60
  def printn(string = nil)
52
- print(string) if string
53
- print("\n")
61
+ if string
62
+ @out << string
63
+ end
64
+ @out << "\n"
54
65
  end
55
66
 
56
67
  # Print a string with indentation but without a `\n` at the end.
57
68
  #: (?String? string) -> void
58
69
  def printt(string = nil)
59
- print(" " * @current_indent)
60
- print(string) if string
70
+ @out << current_indent_string
71
+ @out << string if string
61
72
  end
62
73
 
63
74
  # Print a string with indentation and `\n` at the end.
64
75
  #: (String string) -> void
65
76
  def printl(string)
66
- printt
67
- printn(string)
77
+ @out << current_indent_string
78
+ @out << string
79
+ @out << "\n"
68
80
  end
69
81
 
70
82
  # @override
71
83
  #: (Array[Node] nodes) -> void
72
84
  def visit_all(nodes)
85
+ return if nodes.empty?
86
+
73
87
  previous_node = @previous_node
74
88
  @previous_node = nil
75
89
  nodes.each do |node|
@@ -86,13 +100,13 @@ module RBI
86
100
  if strictness
87
101
  printl("# typed: #{strictness}")
88
102
  end
89
- unless file.comments.empty?
103
+ if file.comments?
90
104
  printn if strictness
91
105
  visit_all(file.comments)
92
106
  end
93
107
 
94
- unless file.root.empty? && file.root.comments.empty?
95
- printn if strictness || !file.comments.empty?
108
+ unless file.root.empty? && !file.root.comments?
109
+ printn if strictness || file.comments?
96
110
  visit(file.root)
97
111
  end
98
112
  end
@@ -102,16 +116,20 @@ module RBI
102
116
  # @override
103
117
  #: (RBSComment node) -> void
104
118
  def visit_rbs_comment(node)
105
- lines = node.text.lines
106
-
107
- if lines.empty?
119
+ text = node.text
120
+ if text.empty?
108
121
  printl("#:")
122
+ return
109
123
  end
110
124
 
111
- lines.each do |line|
112
- text = line.rstrip
125
+ # Use each_line to avoid allocating an intermediate array from .lines
126
+ text.each_line do |line|
127
+ stripped = line.rstrip
113
128
  printt("#:")
114
- print(" #{text}") unless text.empty?
129
+ unless stripped.empty?
130
+ print(" ")
131
+ print(stripped)
132
+ end
115
133
  printn
116
134
  end
117
135
  end
@@ -119,16 +137,20 @@ module RBI
119
137
  # @override
120
138
  #: (Comment node) -> void
121
139
  def visit_comment(node)
122
- lines = node.text.lines
123
-
124
- if lines.empty?
140
+ text = node.text
141
+ if text.empty?
125
142
  printl("#")
143
+ return
126
144
  end
127
145
 
128
- lines.each do |line|
129
- text = line.rstrip
146
+ # Use each_line to avoid allocating an intermediate array from .lines
147
+ text.each_line do |line|
148
+ stripped = line.rstrip
130
149
  printt("#")
131
- print(" #{text}") unless text.empty?
150
+ unless stripped.empty?
151
+ print(" ")
152
+ print(stripped)
153
+ end
132
154
  printn
133
155
  end
134
156
  end
@@ -142,8 +164,8 @@ module RBI
142
164
  # @override
143
165
  #: (Tree node) -> void
144
166
  def visit_tree(node)
145
- visit_all(node.comments)
146
- printn if !node.comments.empty? && !node.empty?
167
+ visit_all(node.comments) if node.comments?
168
+ printn if node.comments? && !node.empty?
147
169
  visit_all(node.nodes)
148
170
  end
149
171
 
@@ -175,7 +197,7 @@ module RBI
175
197
  def visit_scope(node)
176
198
  print_blank_line_before(node)
177
199
  print_loc(node)
178
- visit_all(node.comments)
200
+ visit_all(node.comments) if node.comments?
179
201
 
180
202
  visit_scope_header(node)
181
203
  visit_scope_body(node)
@@ -231,7 +253,7 @@ module RBI
231
253
  def visit_const(node)
232
254
  print_blank_line_before(node)
233
255
  print_loc(node)
234
- visit_all(node.comments)
256
+ visit_all(node.comments) if node.comments?
235
257
 
236
258
  printl("#{node.name} = #{node.value}")
237
259
  end
@@ -258,13 +280,13 @@ module RBI
258
280
  def visit_attr(node)
259
281
  print_blank_line_before(node)
260
282
 
261
- visit_all(node.comments)
262
- node.sigs.each { |sig| visit(sig) }
283
+ visit_all(node.comments) if node.comments?
284
+ node.sigs.each { |sig| visit(sig) } if node.sigs?
263
285
 
264
286
  print_loc(node)
265
287
  printt
266
288
  unless in_visibility_group || node.visibility.public?
267
- self.print(node.visibility.visibility.to_s)
289
+ print(node.visibility.visibility.name)
268
290
  print(" ")
269
291
  end
270
292
  case node
@@ -275,9 +297,15 @@ module RBI
275
297
  when AttrWriter
276
298
  print("attr_writer")
277
299
  end
278
- unless node.names.empty?
300
+ names = node.names
301
+ unless names.empty?
279
302
  print(" ")
280
- print(node.names.map { |name| ":#{name}" }.join(", "))
303
+ if names.size == 1
304
+ print(":")
305
+ self.print(names.first.to_s)
306
+ else
307
+ print(names.map { |name| ":#{name}" }.join(", "))
308
+ end
281
309
  end
282
310
  printn
283
311
  end
@@ -286,13 +314,13 @@ module RBI
286
314
  #: (Method node) -> void
287
315
  def visit_method(node)
288
316
  print_blank_line_before(node)
289
- visit_all(node.comments)
290
- visit_all(node.sigs)
317
+ visit_all(node.comments) if node.comments?
318
+ visit_all(node.sigs) if node.sigs?
291
319
 
292
320
  print_loc(node)
293
321
  printt
294
322
  unless in_visibility_group || node.visibility.public?
295
- self.print(node.visibility.visibility.to_s)
323
+ print(node.visibility.visibility.name)
296
324
  print(" ")
297
325
  end
298
326
  print("def ")
@@ -300,7 +328,7 @@ module RBI
300
328
  print(node.name)
301
329
  unless node.params.empty?
302
330
  print("(")
303
- if node.params.all? { |p| p.comments.empty? }
331
+ if node.params.all? { |p| !p.comments? }
304
332
  node.params.each_with_index do |param, index|
305
333
  print(", ") if index > 0
306
334
  visit(param)
@@ -341,37 +369,45 @@ module RBI
341
369
  # @override
342
370
  #: (OptParam node) -> void
343
371
  def visit_opt_param(node)
344
- print("#{node.name} = #{node.value}")
372
+ print(node.name)
373
+ print(" = ")
374
+ print(node.value)
345
375
  end
346
376
 
347
377
  # @override
348
378
  #: (RestParam node) -> void
349
379
  def visit_rest_param(node)
350
- print("*#{node.name}")
380
+ print("*")
381
+ print(node.name)
351
382
  end
352
383
 
353
384
  # @override
354
385
  #: (KwParam node) -> void
355
386
  def visit_kw_param(node)
356
- print("#{node.name}:")
387
+ print(node.name)
388
+ print(":")
357
389
  end
358
390
 
359
391
  # @override
360
392
  #: (KwOptParam node) -> void
361
393
  def visit_kw_opt_param(node)
362
- print("#{node.name}: #{node.value}")
394
+ print(node.name)
395
+ print(": ")
396
+ print(node.value)
363
397
  end
364
398
 
365
399
  # @override
366
400
  #: (KwRestParam node) -> void
367
401
  def visit_kw_rest_param(node)
368
- print("**#{node.name}")
402
+ print("**")
403
+ print(node.name)
369
404
  end
370
405
 
371
406
  # @override
372
407
  #: (BlockParam node) -> void
373
408
  def visit_block_param(node)
374
- print("&#{node.name}")
409
+ print("&")
410
+ print(node.name) unless node.name.empty?
375
411
  end
376
412
 
377
413
  # @override
@@ -390,7 +426,7 @@ module RBI
390
426
  def visit_mixin(node)
391
427
  print_blank_line_before(node)
392
428
  print_loc(node)
393
- visit_all(node.comments)
429
+ visit_all(node.comments) if node.comments?
394
430
 
395
431
  case node
396
432
  when Include
@@ -425,9 +461,9 @@ module RBI
425
461
  def visit_visibility(node)
426
462
  print_blank_line_before(node)
427
463
  print_loc(node)
428
- visit_all(node.comments)
464
+ visit_all(node.comments) if node.comments?
429
465
 
430
- printl(node.visibility.to_s)
466
+ printl(node.visibility.name)
431
467
  end
432
468
 
433
469
  # @override
@@ -435,7 +471,7 @@ module RBI
435
471
  def visit_send(node)
436
472
  print_blank_line_before(node)
437
473
  print_loc(node)
438
- visit_all(node.comments)
474
+ visit_all(node.comments) if node.comments?
439
475
 
440
476
  printt(node.method)
441
477
  unless node.args.empty?
@@ -457,14 +493,16 @@ module RBI
457
493
  # @override
458
494
  #: (KwArg node) -> void
459
495
  def visit_kw_arg(node)
460
- print("#{node.keyword}: #{node.value}")
496
+ print(node.keyword)
497
+ print(": ")
498
+ print(node.value)
461
499
  end
462
500
 
463
501
  # @override
464
502
  #: (Sig node) -> void
465
503
  def visit_sig(node)
466
504
  print_loc(node)
467
- visit_all(node.comments)
505
+ visit_all(node.comments) if node.comments?
468
506
 
469
507
  max_line_length = self.max_line_length
470
508
  if oneline?(node) && max_line_length.nil?
@@ -484,7 +522,9 @@ module RBI
484
522
  # @override
485
523
  #: (SigParam node) -> void
486
524
  def visit_sig_param(node)
487
- print("#{node.name}: #{node.type}")
525
+ print(node.name)
526
+ print(": ")
527
+ self.print(node.type.to_s)
488
528
  end
489
529
 
490
530
  # @override
@@ -509,7 +549,7 @@ module RBI
509
549
  def visit_t_struct_field(node)
510
550
  print_blank_line_before(node)
511
551
  print_loc(node)
512
- visit_all(node.comments)
552
+ visit_all(node.comments) if node.comments?
513
553
 
514
554
  case node
515
555
  when TStructProp
@@ -533,7 +573,7 @@ module RBI
533
573
  #: (TEnumBlock node) -> void
534
574
  def visit_tenum_block(node)
535
575
  print_loc(node)
536
- visit_all(node.comments)
576
+ visit_all(node.comments) if node.comments?
537
577
 
538
578
  printl("enums do")
539
579
  indent
@@ -547,7 +587,7 @@ module RBI
547
587
  def visit_tenum_value(node)
548
588
  print_blank_line_before(node)
549
589
  print_loc(node)
550
- visit_all(node.comments)
590
+ visit_all(node.comments) if node.comments?
551
591
 
552
592
  printl("#{node.name} = new")
553
593
  end
@@ -557,7 +597,7 @@ module RBI
557
597
  def visit_type_member(node)
558
598
  print_blank_line_before(node)
559
599
  print_loc(node)
560
- visit_all(node.comments)
600
+ visit_all(node.comments) if node.comments?
561
601
 
562
602
  printl("#{node.name} = #{node.value}")
563
603
  end
@@ -567,7 +607,7 @@ module RBI
567
607
  def visit_helper(node)
568
608
  print_blank_line_before(node)
569
609
  print_loc(node)
570
- visit_all(node.comments)
610
+ visit_all(node.comments) if node.comments?
571
611
 
572
612
  printl("#{node.name}!")
573
613
  end
@@ -604,7 +644,7 @@ module RBI
604
644
  def visit_requires_ancestor(node)
605
645
  print_blank_line_before(node)
606
646
  print_loc(node)
607
- visit_all(node.comments)
647
+ visit_all(node.comments) if node.comments?
608
648
 
609
649
  printl("requires_ancestor { #{node.name} }")
610
650
  end
@@ -624,7 +664,7 @@ module RBI
624
664
  def visit_scope_conflict(node)
625
665
  print_blank_line_before(node)
626
666
  print_loc(node)
627
- visit_all(node.comments)
667
+ visit_all(node.comments) if node.comments?
628
668
 
629
669
  printl("<<<<<<< #{node.left_name}")
630
670
  visit_scope_header(node.left)
@@ -682,22 +722,22 @@ module RBI
682
722
  when ScopeConflict
683
723
  oneline?(node.left)
684
724
  when Tree
685
- node.comments.empty? && node.empty?
725
+ !node.comments? && node.empty?
686
726
  when Attr
687
- node.comments.empty? && node.sigs.empty?
727
+ !node.comments? && !node.sigs?
688
728
  when Const
689
- return false unless node.comments.empty?
729
+ return false if node.comments?
690
730
 
691
731
  loc = node.loc
692
732
  return true unless loc
693
733
 
694
734
  loc.begin_line == loc.end_line
695
735
  when Method
696
- node.comments.empty? && node.sigs.empty? && node.params.all? { |p| p.comments.empty? }
736
+ !node.comments? && !node.sigs? && node.params.all? { |p| !p.comments? }
697
737
  when Sig
698
- node.params.all? { |p| p.comments.empty? }
738
+ node.params.all? { |p| !p.comments? }
699
739
  when NodeWithComments
700
- node.comments.empty?
740
+ !node.comments?
701
741
  when VisibilityGroup
702
742
  false
703
743
  else
@@ -713,7 +753,8 @@ module RBI
713
753
  print("(:final)") if node.is_final
714
754
  print(" { ")
715
755
  sig_modifiers(node).each do |modifier|
716
- print("#{modifier}.")
756
+ print(modifier)
757
+ print(".")
717
758
  end
718
759
  unless node.params.empty?
719
760
  print("params(")
@@ -724,10 +765,12 @@ module RBI
724
765
  print(").")
725
766
  end
726
767
  return_type = node.return_type
727
- if node.return_type.to_s == "void"
768
+ if return_type == "void" || return_type.to_s == "void"
728
769
  print("void")
729
770
  else
730
- print("returns(#{return_type})")
771
+ print("returns(")
772
+ self.print(return_type.to_s)
773
+ print(")")
731
774
  end
732
775
  printn(" }")
733
776
  end
@@ -735,6 +778,7 @@ module RBI
735
778
  #: (Sig node) -> void
736
779
  def print_sig_as_block(node)
737
780
  modifiers = sig_modifiers(node)
781
+ has_modifiers = !modifiers.empty?
738
782
 
739
783
  printt
740
784
  print("T::Sig::WithoutRuntime.") if node.without_runtime
@@ -742,7 +786,7 @@ module RBI
742
786
  print("(:final)") if node.is_final
743
787
  printn(" do")
744
788
  indent
745
- if modifiers.any?
789
+ if has_modifiers
746
790
  printl(
747
791
  modifiers.first, #: as !nil
748
792
  )
@@ -753,47 +797,59 @@ module RBI
753
797
  end
754
798
 
755
799
  params = node.params
756
- if params.any?
800
+ has_params = !params.empty?
801
+ if has_params
757
802
  printt
758
- print(".") if modifiers.any?
803
+ print(".") if has_modifiers
759
804
  printn("params(")
760
805
  indent
806
+ last_pindex = params.size - 1
761
807
  params.each_with_index do |param, pindex|
762
808
  printt
763
809
  visit(param)
764
- print(",") if pindex < params.size - 1
765
-
766
- comment_lines = param.comments.flat_map { |comment| comment.text.lines.map(&:rstrip) }
767
- comment_lines.each_with_index do |comment, cindex|
768
- if cindex == 0
769
- print(" ")
770
- else
771
- print_sig_param_comment_leading_space(param, last: pindex == params.size - 1)
810
+ is_last = pindex == last_pindex
811
+ print(",") unless is_last
812
+
813
+ if param.comments?
814
+ comment_lines = param.comments.flat_map { |comment| comment.text.lines.map(&:rstrip) }
815
+ comment_lines.each_with_index do |comment, cindex|
816
+ if cindex == 0
817
+ print(" ")
818
+ else
819
+ print_sig_param_comment_leading_space(param, last: is_last)
820
+ end
821
+ print("# #{comment}")
772
822
  end
773
- print("# #{comment}")
774
823
  end
775
824
  printn
776
825
  end
777
826
  dedent
778
827
  printt(")")
779
828
  end
780
- printt if params.empty?
781
- print(".") if modifiers.any? || params.any?
829
+ printt unless has_params
830
+ print(".") if has_modifiers || has_params
782
831
 
783
832
  return_type = node.return_type
784
- if return_type.to_s == "void"
833
+ if return_type == "void" || return_type.to_s == "void"
785
834
  print("void")
786
835
  else
787
- print("returns(#{return_type})")
836
+ print("returns(")
837
+ self.print(return_type.to_s)
838
+ print(")")
788
839
  end
789
840
  printn
790
841
  dedent
791
- dedent if modifiers.any?
842
+ dedent if has_modifiers
792
843
  printl("end")
793
844
  end
794
845
 
846
+ EMPTY_MODIFIERS = [].freeze #: Array[String]
847
+
795
848
  #: (Sig node) -> Array[String]
796
849
  def sig_modifiers(node)
850
+ return EMPTY_MODIFIERS unless node.is_abstract || node.is_override || node.is_overridable ||
851
+ node.type_params? || node.checked
852
+
797
853
  modifiers = [] #: Array[String]
798
854
  modifiers << "abstract" if node.is_abstract
799
855
 
@@ -808,7 +864,9 @@ module RBI
808
864
  end
809
865
 
810
866
  modifiers << "overridable" if node.is_overridable
811
- modifiers << "type_parameters(#{node.type_params.map { |type| ":#{type}" }.join(", ")})" if node.type_params.any?
867
+ if node.type_params?
868
+ modifiers << "type_parameters(#{node.type_params.map { |type| ":#{type}" }.join(", ")})"
869
+ end
812
870
  modifiers << "checked(:#{node.checked})" if node.checked
813
871
  modifiers
814
872
  end
@@ -823,9 +881,12 @@ module RBI
823
881
 
824
882
  #: (?indent: Integer, ?print_locs: bool, ?max_line_length: Integer?) -> String
825
883
  def string(indent: 0, print_locs: false, max_line_length: nil)
826
- out = StringIO.new
827
- print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
828
- out.string
884
+ # Use a mutable String buffer instead of StringIO for faster concatenation.
885
+ # String#<< is ~2x faster than StringIO#print for many small writes.
886
+ out = +""
887
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
888
+ p.visit_file(self)
889
+ out
829
890
  end
830
891
  end
831
892
 
@@ -838,9 +899,11 @@ module RBI
838
899
 
839
900
  #: (?indent: Integer, ?print_locs: bool, ?max_line_length: Integer?) -> String
840
901
  def string(indent: 0, print_locs: false, max_line_length: nil)
841
- out = StringIO.new
842
- print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
843
- out.string
902
+ # Use a mutable String buffer instead of StringIO for faster concatenation.
903
+ out = +""
904
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
905
+ p.visit(self)
906
+ out
844
907
  end
845
908
  end
846
909
  end
@@ -43,7 +43,7 @@ module RBI
43
43
  block_param = @method.params.grep(RBI::BlockParam).first
44
44
  raise Error, "No block param found" unless block_param
45
45
 
46
- block_name = block_param.name
46
+ block_name = block_param.name.empty? ? "block" : block_param.name
47
47
  block_type = translate_type(type.type) #: as RBI::Type::Proc
48
48
 
49
49
  bind = type.self_type
@@ -41,8 +41,7 @@ module RBI
41
41
  when ::RBS::Types::Bases::Bottom
42
42
  Type.noreturn
43
43
  when ::RBS::Types::Bases::Class
44
- # TODO: unsupported yet
45
- Type.untyped
44
+ Type.simple("Class")
46
45
  when ::RBS::Types::Bases::Instance
47
46
  Type.attached_class
48
47
  when ::RBS::Types::Bases::Nil
@@ -54,19 +53,28 @@ module RBI
54
53
  when ::RBS::Types::Bases::Void
55
54
  Type.void
56
55
  when ::RBS::Types::ClassSingleton
57
- Type.class_of(Type.simple(type.name.to_s))
56
+ type_parameter = type.args.first ? translate(type.args.first) : nil
57
+ Type.class_of(Type.simple(type.name.to_s), type_parameter)
58
58
  when ::RBS::Types::ClassInstance
59
59
  translate_class_instance(type)
60
60
  when ::RBS::Types::Function
61
61
  translate_function(type)
62
62
  when ::RBS::Types::Interface
63
63
  # TODO: unsupported yet
64
+ # RBS interfaces (like _Foo) don't have a direct Sorbet equivalent
65
+ # and the names aren't valid Ruby identifiers
64
66
  Type.untyped
65
67
  when ::RBS::Types::Intersection
66
68
  Type.all(*type.types.map { |t| translate(t) })
67
69
  when ::RBS::Types::Literal
68
- # TODO: unsupported yet
69
- Type.untyped
70
+ # Sorbet doesn't support literal types, so map to their base type
71
+ case type.literal
72
+ when nil then Type.simple("NilClass")
73
+ when true then Type.simple("TrueClass")
74
+ when false then Type.simple("FalseClass")
75
+ else
76
+ Type.simple(type.literal.class.to_s)
77
+ end
70
78
  when ::RBS::Types::Optional
71
79
  Type.nilable(translate(type.type))
72
80
  when ::RBS::Types::Proc
@@ -275,7 +275,7 @@ module RBI
275
275
  print_loc(node)
276
276
  printt
277
277
  unless in_visibility_group || node.visibility.public? || node.visibility.protected?
278
- self.print(node.visibility.visibility.to_s)
278
+ print(node.visibility.visibility.name)
279
279
  print(" ")
280
280
  end
281
281
  case node
@@ -355,7 +355,7 @@ module RBI
355
355
  print_loc(node)
356
356
  printt
357
357
  unless in_visibility_group || node.visibility.public?
358
- self.print(node.visibility.visibility.to_s)
358
+ print(node.visibility.visibility.name)
359
359
  print(" ")
360
360
  end
361
361
  print("def ")
@@ -380,7 +380,7 @@ module RBI
380
380
  end
381
381
  else
382
382
  if node.params.any?
383
- params = node.params.reject { |param| param.is_a?(BlockParam) }
383
+ params = node.params.grep_v(BlockParam)
384
384
  block = node.params.find { |param| param.is_a?(BlockParam) }
385
385
 
386
386
  print("(")
@@ -666,7 +666,7 @@ module RBI
666
666
  print_loc(node)
667
667
  visit_all(node.comments)
668
668
 
669
- printl(node.visibility.to_s)
669
+ printl(node.visibility.name)
670
670
  end
671
671
 
672
672
  # @override
@@ -1106,6 +1106,11 @@ module RBI
1106
1106
  @string << "singleton("
1107
1107
  visit(type.type)
1108
1108
  @string << ")"
1109
+ if (type_parameter = type.type_parameter)
1110
+ @string << "["
1111
+ visit(type_parameter)
1112
+ @string << "]"
1113
+ end
1109
1114
  end
1110
1115
 
1111
1116
  #: (Type::All type) -> void