rbi 0.0.6 → 0.0.10

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/printer.rb CHANGED
@@ -11,14 +11,28 @@ module RBI
11
11
  sig { returns(T.nilable(Node)) }
12
12
  attr_reader :previous_node
13
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)
14
+ sig { returns(Integer) }
15
+ attr_reader :current_indent
16
+
17
+ sig { returns(T.nilable(Integer)) }
18
+ attr_reader :max_line_length
19
+
20
+ sig do
21
+ params(
22
+ out: T.any(IO, StringIO),
23
+ indent: Integer,
24
+ print_locs: T::Boolean,
25
+ max_line_length: T.nilable(Integer)
26
+ ).void
27
+ end
28
+ def initialize(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
16
29
  super()
17
30
  @out = out
18
31
  @current_indent = indent
19
32
  @print_locs = print_locs
20
33
  @in_visibility_group = T.let(false, T::Boolean)
21
34
  @previous_node = T.let(nil, T.nilable(Node))
35
+ @max_line_length = max_line_length
22
36
  end
23
37
 
24
38
  # Printing
@@ -123,19 +137,35 @@ module RBI
123
137
  sig { abstract.params(v: Printer).void }
124
138
  def accept_printer(v); end
125
139
 
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)
140
+ sig do
141
+ params(
142
+ out: T.any(IO, StringIO),
143
+ indent: Integer,
144
+ print_locs: T::Boolean,
145
+ max_line_length: T.nilable(Integer)
146
+ ).void
147
+ end
148
+ def print(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
149
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
129
150
  p.visit(self)
130
151
  end
131
152
 
132
- sig { params(indent: Integer, print_locs: T::Boolean).returns(String) }
133
- def string(indent: 0, print_locs: false)
153
+ sig { params(indent: Integer, print_locs: T::Boolean, max_line_length: T.nilable(Integer)).returns(String) }
154
+ def string(indent: 0, print_locs: false, max_line_length: nil)
134
155
  out = StringIO.new
135
- print(out: out, indent: indent, print_locs: print_locs)
156
+ print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
136
157
  out.string
137
158
  end
138
159
 
160
+ sig { params(v: Printer).void }
161
+ def print_blank_line_before(v)
162
+ previous_node = v.previous_node
163
+ return unless previous_node
164
+ return if previous_node.is_a?(BlankLine)
165
+ return if previous_node.oneline? && oneline?
166
+ v.printn
167
+ end
168
+
139
169
  sig { returns(T::Boolean) }
140
170
  def oneline?
141
171
  true
@@ -171,7 +201,7 @@ module RBI
171
201
  end
172
202
  end
173
203
 
174
- class EmptyComment
204
+ class BlankLine
175
205
  extend T::Sig
176
206
 
177
207
  sig { override.params(v: Printer).void }
@@ -201,8 +231,7 @@ module RBI
201
231
 
202
232
  sig { override.params(v: Printer).void }
203
233
  def accept_printer(v)
204
- previous_node = v.previous_node
205
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
234
+ print_blank_line_before(v)
206
235
 
207
236
  v.printl("# #{loc}") if loc && v.print_locs
208
237
  v.visit_all(comments)
@@ -295,8 +324,7 @@ module RBI
295
324
 
296
325
  sig { override.params(v: Printer).void }
297
326
  def accept_printer(v)
298
- previous_node = v.previous_node
299
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
327
+ print_blank_line_before(v)
300
328
 
301
329
  v.printl("# #{loc}") if loc && v.print_locs
302
330
  v.visit_all(comments)
@@ -309,8 +337,7 @@ module RBI
309
337
 
310
338
  sig { override.params(v: Printer).void }
311
339
  def accept_printer(v)
312
- previous_node = v.previous_node
313
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
340
+ print_blank_line_before(v)
314
341
 
315
342
  v.visit_all(comments)
316
343
  sigs.each { |sig| v.visit(sig) }
@@ -346,8 +373,7 @@ module RBI
346
373
 
347
374
  sig { override.params(v: Printer).void }
348
375
  def accept_printer(v)
349
- previous_node = v.previous_node
350
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
376
+ print_blank_line_before(v)
351
377
 
352
378
  v.visit_all(comments)
353
379
  v.visit_all(sigs)
@@ -521,8 +547,7 @@ module RBI
521
547
 
522
548
  sig { override.params(v: Printer).void }
523
549
  def accept_printer(v)
524
- previous_node = v.previous_node
525
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
550
+ print_blank_line_before(v)
526
551
 
527
552
  v.printl("# #{loc}") if loc && v.print_locs
528
553
  v.visit_all(comments)
@@ -543,8 +568,7 @@ module RBI
543
568
 
544
569
  sig { override.params(v: Printer).void }
545
570
  def accept_printer(v)
546
- previous_node = v.previous_node
547
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
571
+ print_blank_line_before(v)
548
572
 
549
573
  v.printl("# #{loc}") if loc && v.print_locs
550
574
  v.visit_all(comments)
@@ -552,72 +576,65 @@ module RBI
552
576
  end
553
577
  end
554
578
 
555
- class Sig
579
+ class Send
556
580
  extend T::Sig
557
581
 
558
582
  sig { override.params(v: Printer).void }
559
583
  def accept_printer(v)
584
+ print_blank_line_before(v)
585
+
560
586
  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
587
+ v.visit_all(comments)
588
+ v.printt(method)
589
+ unless args.empty?
590
+ v.print(" ")
591
+ args.each_with_index do |arg, index|
592
+ v.visit(arg)
593
+ v.print(", ") if index < args.size - 1
575
594
  end
576
- v.print(").")
577
595
  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(").")
596
+ v.printn
597
+ end
598
+ end
599
+
600
+ class Arg
601
+ extend T::Sig
602
+
603
+ sig { override.params(v: Printer).void }
604
+ def accept_printer(v)
605
+ v.print(value)
606
+ end
607
+ end
608
+
609
+ class KwArg
610
+ extend T::Sig
611
+
612
+ sig { override.params(v: Printer).void }
613
+ def accept_printer(v)
614
+ v.print(keyword)
615
+ v.print(": ")
616
+ v.print(value)
617
+ end
618
+ end
619
+
620
+ class Sig
621
+ extend T::Sig
622
+
623
+ sig { override.params(v: Printer).void }
624
+ def accept_printer(v)
625
+ v.printl("# #{loc}") if loc && v.print_locs
626
+ max_line_length = v.max_line_length
627
+ if oneline? && max_line_length.nil?
628
+ print_as_line(v)
629
+ elsif max_line_length
630
+ line = string(indent: v.current_indent)
631
+ if line.length <= max_line_length
632
+ v.print(line)
586
633
  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(").")
634
+ print_as_block(v)
605
635
  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
636
  else
618
- v.printn
619
- v.dedent
620
- v.printl("end")
637
+ print_as_block(v)
621
638
  end
622
639
  end
623
640
 
@@ -630,6 +647,90 @@ module RBI
630
647
  def inline_params?
631
648
  params.all? { |p| p.comments.empty? }
632
649
  end
650
+
651
+ private
652
+
653
+ sig { returns(T::Array[String]) }
654
+ def sig_modifiers
655
+ modifiers = T.let([], T::Array[String])
656
+ modifiers << "abstract" if is_abstract
657
+ modifiers << "override" if is_override
658
+ modifiers << "overridable" if is_overridable
659
+ modifiers << "type_parameters(#{type_params.map { |type| ":#{type}" }.join(", ")})" if type_params.any?
660
+ modifiers << "checked(:#{checked})" if checked
661
+ modifiers
662
+ end
663
+
664
+ sig { params(v: Printer).void }
665
+ def print_as_line(v)
666
+ v.printt("sig { ")
667
+ sig_modifiers.each do |modifier|
668
+ v.print("#{modifier}.")
669
+ end
670
+ unless params.empty?
671
+ v.print("params(")
672
+ params.each_with_index do |param, index|
673
+ v.print(", ") if index > 0
674
+ v.visit(param)
675
+ end
676
+ v.print(").")
677
+ end
678
+ if return_type && return_type != "void"
679
+ v.print("returns(#{return_type})")
680
+ else
681
+ v.print("void")
682
+ end
683
+ v.printn(" }")
684
+ end
685
+
686
+ sig { params(v: Printer).void }
687
+ def print_as_block(v)
688
+ modifiers = sig_modifiers
689
+
690
+ v.printl("sig do")
691
+ v.indent
692
+ if modifiers.any?
693
+ v.printl(T.must(modifiers.first))
694
+ v.indent
695
+ modifiers[1..]&.each do |modifier|
696
+ v.printl(".#{modifier}")
697
+ end
698
+ end
699
+
700
+ if params.any?
701
+ v.printt
702
+ v.print(".") if modifiers.any?
703
+ v.printn("params(")
704
+ v.indent
705
+ params.each_with_index do |param, pindex|
706
+ v.printt
707
+ v.visit(param)
708
+ v.print(",") if pindex < params.size - 1
709
+ param.comments_lines.each_with_index do |comment, cindex|
710
+ if cindex == 0
711
+ v.print(" ")
712
+ else
713
+ param.print_comment_leading_space(v, last: pindex == params.size - 1)
714
+ end
715
+ v.print("# #{comment}")
716
+ end
717
+ v.printn
718
+ end
719
+ v.dedent
720
+ v.printt(")")
721
+ end
722
+ v.printt if params.empty?
723
+ v.print(".") if modifiers.any? || params.any?
724
+ if return_type && return_type != "void"
725
+ v.print("returns(#{return_type})")
726
+ else
727
+ v.print("void")
728
+ end
729
+ v.printn
730
+ v.dedent
731
+ v.dedent if modifiers.any?
732
+ v.printl("end")
733
+ end
633
734
  end
634
735
 
635
736
  class SigParam
@@ -659,8 +760,7 @@ module RBI
659
760
 
660
761
  sig { override.params(v: Printer).void }
661
762
  def accept_printer(v)
662
- previous_node = v.previous_node
663
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
763
+ print_blank_line_before(v)
664
764
 
665
765
  v.printl("# #{loc}") if loc && v.print_locs
666
766
  v.visit_all(comments)
@@ -699,8 +799,7 @@ module RBI
699
799
 
700
800
  sig { override.params(v: Printer).void }
701
801
  def accept_printer(v)
702
- previous_node = v.previous_node
703
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
802
+ print_blank_line_before(v)
704
803
 
705
804
  v.printl("# #{loc}") if loc && v.print_locs
706
805
  v.visit_all(comments)
@@ -713,8 +812,7 @@ module RBI
713
812
 
714
813
  sig { override.params(v: Printer).void }
715
814
  def accept_printer(v)
716
- previous_node = v.previous_node
717
- v.printn if previous_node && (!previous_node.oneline? || !oneline?)
815
+ print_blank_line_before(v)
718
816
 
719
817
  v.printl("# #{loc}") if loc && v.print_locs
720
818
  v.visit_all(comments)
@@ -753,4 +851,17 @@ module RBI
753
851
  false
754
852
  end
755
853
  end
854
+
855
+ class RequiresAncestor
856
+ extend T::Sig
857
+
858
+ sig { override.params(v: Printer).void }
859
+ def accept_printer(v)
860
+ print_blank_line_before(v)
861
+
862
+ v.printl("# #{loc}") if loc && v.print_locs
863
+ v.visit_all(comments)
864
+ v.printl("requires_ancestor { #{name} }")
865
+ end
866
+ end
756
867
  end
@@ -0,0 +1,57 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RBI
5
+ module Rewriters
6
+ class Annotate < Visitor
7
+ extend T::Sig
8
+
9
+ sig { params(annotation: String, annotate_scopes: T::Boolean, annotate_properties: T::Boolean).void }
10
+ def initialize(annotation, annotate_scopes: false, annotate_properties: false)
11
+ super()
12
+ @annotation = annotation
13
+ @annotate_scopes = annotate_scopes
14
+ @annotate_properties = annotate_properties
15
+ end
16
+
17
+ sig { override.params(node: T.nilable(Node)).void }
18
+ def visit(node)
19
+ case node
20
+ when Scope
21
+ annotate_node(node) if @annotate_scopes || root?(node)
22
+ when Const, Attr, Method, TStructField, TypeMember
23
+ annotate_node(node) if @annotate_properties
24
+ end
25
+ visit_all(node.nodes) if node.is_a?(Tree)
26
+ end
27
+
28
+ private
29
+
30
+ sig { params(node: NodeWithComments).void }
31
+ def annotate_node(node)
32
+ return if node.annotations.one?(@annotation)
33
+ node.comments << Comment.new("@#{@annotation}")
34
+ end
35
+
36
+ sig { params(node: Node).returns(T::Boolean) }
37
+ def root?(node)
38
+ parent = node.parent_tree
39
+ parent.is_a?(Tree) && parent.parent_tree.nil?
40
+ end
41
+ end
42
+ end
43
+
44
+ class Tree
45
+ extend T::Sig
46
+
47
+ sig { params(annotation: String, annotate_scopes: T::Boolean, annotate_properties: T::Boolean).void }
48
+ def annotate!(annotation, annotate_scopes: false, annotate_properties: false)
49
+ visitor = Rewriters::Annotate.new(
50
+ annotation,
51
+ annotate_scopes: annotate_scopes,
52
+ annotate_properties: annotate_properties
53
+ )
54
+ visitor.visit(self)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,45 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RBI
5
+ module Rewriters
6
+ class Deannotate < Visitor
7
+ extend T::Sig
8
+
9
+ sig { params(annotation: String).void }
10
+ def initialize(annotation)
11
+ super()
12
+ @annotation = annotation
13
+ end
14
+
15
+ sig { override.params(node: T.nilable(Node)).void }
16
+ def visit(node)
17
+ case node
18
+ when Scope, Const, Attr, Method, TStructField, TypeMember
19
+ deannotate_node(node)
20
+ end
21
+ visit_all(node.nodes) if node.is_a?(Tree)
22
+ end
23
+
24
+ private
25
+
26
+ sig { params(node: NodeWithComments).void }
27
+ def deannotate_node(node)
28
+ return unless node.annotations.one?(@annotation)
29
+ node.comments.reject! do |comment|
30
+ comment.text == "@#{@annotation}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ class Tree
37
+ extend T::Sig
38
+
39
+ sig { params(annotation: String).void }
40
+ def deannotate!(annotation)
41
+ visitor = Rewriters::Deannotate.new(annotation)
42
+ visitor.visit(self)
43
+ end
44
+ end
45
+ end
@@ -49,12 +49,18 @@ module RBI
49
49
  case self
50
50
  when Include, Extend
51
51
  Group::Kind::Mixins
52
+ when RequiresAncestor
53
+ Group::Kind::RequiredAncestors
52
54
  when Helper
53
55
  Group::Kind::Helpers
54
56
  when TypeMember
55
57
  Group::Kind::TypeMembers
56
58
  when MixesInClassMethods
57
59
  Group::Kind::MixesInClassMethods
60
+ when Send
61
+ Group::Kind::Sends
62
+ when Attr
63
+ Group::Kind::Attrs
58
64
  when TStructField
59
65
  Group::Kind::TStructFields
60
66
  when TEnumBlock
@@ -67,6 +73,8 @@ module RBI
67
73
  else
68
74
  Group::Kind::Methods
69
75
  end
76
+ when SingletonClass
77
+ Group::Kind::SingletonClasses
70
78
  when Scope, Const
71
79
  Group::Kind::Consts
72
80
  else
@@ -90,13 +98,17 @@ module RBI
90
98
  class Kind < T::Enum
91
99
  enums do
92
100
  Mixins = new
101
+ RequiredAncestors = new
93
102
  Helpers = new
94
103
  TypeMembers = new
95
104
  MixesInClassMethods = new
105
+ Sends = new
106
+ Attrs = new
96
107
  TStructFields = new
97
108
  TEnums = new
98
109
  Inits = new
99
110
  Methods = new
111
+ SingletonClasses = new
100
112
  Consts = new
101
113
  end
102
114
  end
@@ -47,7 +47,7 @@ module RBI
47
47
  end
48
48
  end
49
49
 
50
- sig { params(left: Tree, right: Tree, left_name: String, right_name: String, keep: Keep).returns(Tree) }
50
+ sig { params(left: Tree, right: Tree, left_name: String, right_name: String, keep: Keep).returns(MergeTree) }
51
51
  def self.merge_trees(left, right, left_name: "left", right_name: "right", keep: Keep::NONE)
52
52
  left.nest_singleton_methods!
53
53
  right.nest_singleton_methods!
@@ -59,7 +59,7 @@ module RBI
59
59
  tree
60
60
  end
61
61
 
62
- sig { returns(Tree) }
62
+ sig { returns(MergeTree) }
63
63
  attr_reader :tree
64
64
 
65
65
  sig { params(left_name: String, right_name: String, keep: Keep).void }
@@ -67,15 +67,15 @@ module RBI
67
67
  @left_name = left_name
68
68
  @right_name = right_name
69
69
  @keep = keep
70
- @tree = T.let(Tree.new, Tree)
70
+ @tree = T.let(MergeTree.new, MergeTree)
71
71
  @scope_stack = T.let([@tree], T::Array[Tree])
72
72
  end
73
73
 
74
- sig { params(tree: Tree).returns(T::Array[Conflict]) }
74
+ sig { params(tree: Tree).void }
75
75
  def merge(tree)
76
76
  v = TreeMerger.new(@tree, left_name: @left_name, right_name: @right_name, keep: @keep)
77
77
  v.visit(tree)
78
- v.conflicts
78
+ @tree.conflicts.concat(v.conflicts)
79
79
  end
80
80
 
81
81
  # Used for logging / error displaying purpose
@@ -314,9 +314,31 @@ module RBI
314
314
  class Tree
315
315
  extend T::Sig
316
316
 
317
- sig { params(other: Tree).returns(Tree) }
318
- def merge(other)
319
- Rewriters::Merge.merge_trees(self, other)
317
+ sig { params(other: Tree, left_name: String, right_name: String, keep: Rewriters::Merge::Keep).returns(MergeTree) }
318
+ def merge(other, left_name: "left", right_name: "right", keep: Rewriters::Merge::Keep::NONE)
319
+ Rewriters::Merge.merge_trees(self, other, left_name: left_name, right_name: right_name, keep: keep)
320
+ end
321
+ end
322
+
323
+ # A tree that _might_ contain conflicts
324
+ class MergeTree < Tree
325
+ extend T::Sig
326
+
327
+ sig { returns(T::Array[Rewriters::Merge::Conflict]) }
328
+ attr_reader :conflicts
329
+
330
+ sig do
331
+ params(
332
+ loc: T.nilable(Loc),
333
+ comments: T::Array[Comment],
334
+ conflicts: T::Array[Rewriters::Merge::Conflict],
335
+ block: T.nilable(T.proc.params(node: Tree).void)
336
+ ).void
337
+ end
338
+ def initialize(loc: nil, comments: [], conflicts: [], &block)
339
+ super(loc: loc, comments: comments)
340
+ @conflicts = conflicts
341
+ block&.call(self)
320
342
  end
321
343
  end
322
344
 
@@ -490,6 +512,15 @@ module RBI
490
512
  end
491
513
  end
492
514
 
515
+ class Send
516
+ extend T::Sig
517
+
518
+ sig { override.params(other: Node).returns(T::Boolean) }
519
+ def compatible_with?(other)
520
+ other.is_a?(Send) && method == other.method && args == other.args
521
+ end
522
+ end
523
+
493
524
  class TStructField
494
525
  extend T::Sig
495
526