rbi 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rbi/printer.rb CHANGED
@@ -163,6 +163,15 @@ module RBI
163
163
  end
164
164
  end
165
165
 
166
+ class EmptyComment
167
+ extend T::Sig
168
+
169
+ sig { override.params(v: Printer).void }
170
+ def accept_printer(v)
171
+ v.printn
172
+ end
173
+ end
174
+
166
175
  class Tree
167
176
  extend T::Sig
168
177
 
@@ -238,6 +247,27 @@ module RBI
238
247
  end
239
248
  end
240
249
 
250
+ class Struct
251
+ extend T::Sig
252
+
253
+ sig { override.params(v: Printer).void }
254
+ def print_header(v)
255
+ v.printt("#{name} = ::Struct.new")
256
+ if !members.empty? || keyword_init
257
+ v.print("(")
258
+ args = members.map { |member| ":#{member}" }
259
+ args << "keyword_init: true" if keyword_init
260
+ v.print(args.join(", "))
261
+ v.print(")")
262
+ end
263
+ if empty?
264
+ v.printn
265
+ else
266
+ v.printn(" do")
267
+ end
268
+ end
269
+ end
270
+
241
271
  class SingletonClass
242
272
  extend T::Sig
243
273
 
@@ -278,7 +308,7 @@ module RBI
278
308
  sigs.each { |sig| v.visit(sig) }
279
309
  v.printl("# #{loc}") if loc && v.print_locs
280
310
  v.printt
281
- unless v.in_visibility_group || visibility == Visibility::Public
311
+ unless v.in_visibility_group || visibility.public?
282
312
  v.print(visibility.visibility.to_s)
283
313
  v.print(" ")
284
314
  end
@@ -315,7 +345,7 @@ module RBI
315
345
  v.visit_all(sigs)
316
346
  v.printl("# #{loc}") if loc && v.print_locs
317
347
  v.printt
318
- unless v.in_visibility_group || visibility == Visibility::Public
348
+ unless v.in_visibility_group || visibility.public?
319
349
  v.print(visibility.visibility.to_s)
320
350
  v.print(" ")
321
351
  end
@@ -338,7 +368,7 @@ module RBI
338
368
  v.print(",") if pindex < params.size - 1
339
369
  param.comments.each_with_index do |comment, cindex|
340
370
  if cindex > 0
341
- param.print_comment_leading_space(v)
371
+ param.print_comment_leading_space(v, last: pindex == params.size - 1)
342
372
  else
343
373
  v.print(" ")
344
374
  end
@@ -373,11 +403,12 @@ module RBI
373
403
  v.print(name.to_s)
374
404
  end
375
405
 
376
- sig { params(v: Printer).void }
377
- def print_comment_leading_space(v)
406
+ sig { params(v: Printer, last: T::Boolean).void }
407
+ def print_comment_leading_space(v, last:)
378
408
  v.printn
379
409
  v.printt
380
- v.print(" " * (name.size + 2))
410
+ v.print(" " * (name.size + 1))
411
+ v.print(" ") unless last
381
412
  end
382
413
  end
383
414
 
@@ -389,8 +420,8 @@ module RBI
389
420
  v.print("#{name} = #{value}")
390
421
  end
391
422
 
392
- sig { override.params(v: Printer).void }
393
- def print_comment_leading_space(v)
423
+ sig { override.params(v: Printer, last: T::Boolean).void }
424
+ def print_comment_leading_space(v, last:)
394
425
  super
395
426
  v.print(" " * (value.size + 3))
396
427
  end
@@ -404,8 +435,8 @@ module RBI
404
435
  v.print("*#{name}")
405
436
  end
406
437
 
407
- sig { override.params(v: Printer).void }
408
- def print_comment_leading_space(v)
438
+ sig { override.params(v: Printer, last: T::Boolean).void }
439
+ def print_comment_leading_space(v, last:)
409
440
  super
410
441
  v.print(" ")
411
442
  end
@@ -419,8 +450,8 @@ module RBI
419
450
  v.print("#{name}:")
420
451
  end
421
452
 
422
- sig { override.params(v: Printer).void }
423
- def print_comment_leading_space(v)
453
+ sig { override.params(v: Printer, last: T::Boolean).void }
454
+ def print_comment_leading_space(v, last:)
424
455
  super
425
456
  v.print(" ")
426
457
  end
@@ -434,11 +465,9 @@ module RBI
434
465
  v.print("#{name}: #{value}")
435
466
  end
436
467
 
437
- sig { override.params(v: Printer).void }
438
- def print_comment_leading_space(v)
439
- v.printn
440
- v.printt
441
- v.print(" " * (name.size + 2))
468
+ sig { override.params(v: Printer, last: T::Boolean).void }
469
+ def print_comment_leading_space(v, last:)
470
+ super
442
471
  v.print(" " * (value.size + 2))
443
472
  end
444
473
  end
@@ -451,8 +480,8 @@ module RBI
451
480
  v.print("**#{name}")
452
481
  end
453
482
 
454
- sig { override.params(v: Printer).void }
455
- def print_comment_leading_space(v)
483
+ sig { override.params(v: Printer, last: T::Boolean).void }
484
+ def print_comment_leading_space(v, last:)
456
485
  super
457
486
  v.print(" ")
458
487
  end
@@ -465,6 +494,12 @@ module RBI
465
494
  def accept_printer(v)
466
495
  v.print("&#{name}")
467
496
  end
497
+
498
+ sig { override.params(v: Printer, last: T::Boolean).void }
499
+ def print_comment_leading_space(v, last:)
500
+ super
501
+ v.print(" ")
502
+ end
468
503
  end
469
504
 
470
505
  class Mixin
@@ -494,7 +529,11 @@ module RBI
494
529
 
495
530
  sig { override.params(v: Printer).void }
496
531
  def accept_printer(v)
532
+ previous_node = v.previous_node
533
+ v.printn if previous_node && (!previous_node.oneline? || !oneline?)
534
+
497
535
  v.printl("# #{loc}") if loc && v.print_locs
536
+ v.visit_all(comments)
498
537
  v.printl(visibility.to_s)
499
538
  end
500
539
  end
@@ -505,7 +544,12 @@ module RBI
505
544
  sig { override.params(v: Printer).void }
506
545
  def accept_printer(v)
507
546
  v.printl("# #{loc}") if loc && v.print_locs
508
- v.printt("sig { ")
547
+ if oneline?
548
+ v.printt("sig { ")
549
+ else
550
+ v.printl("sig do")
551
+ v.indent
552
+ end
509
553
  v.print("abstract.") if is_abstract
510
554
  v.print("override.") if is_override
511
555
  v.print("overridable.") if is_overridable
@@ -518,12 +562,33 @@ module RBI
518
562
  v.print(").")
519
563
  end
520
564
  unless params.empty?
521
- v.print("params(")
522
- params.each_with_index do |param, index|
523
- v.visit(param)
524
- v.print(", ") if index < params.length - 1
565
+ if inline_params?
566
+ v.print("params(")
567
+ params.each_with_index do |param, index|
568
+ v.print(", ") if index > 0
569
+ v.visit(param)
570
+ end
571
+ v.print(").")
572
+ else
573
+ v.printl("params(")
574
+ v.indent
575
+ params.each_with_index do |param, pindex|
576
+ v.printt
577
+ v.visit(param)
578
+ v.print(",") if pindex < params.size - 1
579
+ param.comments.each_with_index do |comment, cindex|
580
+ if cindex == 0
581
+ v.print(" ")
582
+ else
583
+ param.print_comment_leading_space(v, last: pindex == params.size - 1)
584
+ end
585
+ v.print("# #{comment.text.strip}")
586
+ end
587
+ v.printn
588
+ end
589
+ v.dedent
590
+ v.printt(").")
525
591
  end
526
- v.print(").")
527
592
  end
528
593
  if return_type && return_type != "void"
529
594
  v.print("returns(#{return_type})")
@@ -533,7 +598,23 @@ module RBI
533
598
  if checked
534
599
  v.print(".checked(:#{checked})")
535
600
  end
536
- v.printn(" }")
601
+ if oneline?
602
+ v.printn(" }")
603
+ else
604
+ v.printn
605
+ v.dedent
606
+ v.printl("end")
607
+ end
608
+ end
609
+
610
+ sig { override.returns(T::Boolean) }
611
+ def oneline?
612
+ inline_params?
613
+ end
614
+
615
+ sig { returns(T::Boolean) }
616
+ def inline_params?
617
+ params.all? { |p| p.comments.empty? }
537
618
  end
538
619
  end
539
620
 
@@ -544,6 +625,14 @@ module RBI
544
625
  def accept_printer(v)
545
626
  v.print("#{name}: #{type}")
546
627
  end
628
+
629
+ sig { params(v: Printer, last: T::Boolean).void }
630
+ def print_comment_leading_space(v, last:)
631
+ v.printn
632
+ v.printt
633
+ v.print(" " * (name.size + type.size + 3))
634
+ v.print(" ") unless last
635
+ end
547
636
  end
548
637
 
549
638
  class TStructField
@@ -630,14 +719,19 @@ module RBI
630
719
  sig { override.params(v: Printer).void }
631
720
  def accept_printer(v)
632
721
  v.in_visibility_group = true
633
- v.printn unless v.previous_node.nil?
634
- case visibility
635
- when Visibility::Protected, Visibility::Private
722
+ if visibility.public?
723
+ v.printn unless v.previous_node.nil?
724
+ else
636
725
  v.visit(visibility)
637
726
  v.printn
638
727
  end
639
728
  v.visit_all(nodes)
640
729
  v.in_visibility_group = false
641
730
  end
731
+
732
+ sig { override.returns(T::Boolean) }
733
+ def oneline?
734
+ false
735
+ end
642
736
  end
643
737
  end
@@ -0,0 +1,71 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RBI
5
+ module Rewriters
6
+ class AddSigTemplates < Visitor
7
+ extend T::Sig
8
+
9
+ sig { params(with_todo_comment: T::Boolean).void }
10
+ def initialize(with_todo_comment: true)
11
+ super()
12
+ @with_todo_comment = with_todo_comment
13
+ end
14
+
15
+ sig { override.params(node: T.nilable(Node)).void }
16
+ def visit(node)
17
+ case node
18
+ when Tree
19
+ visit_all(node.nodes)
20
+ when Attr
21
+ add_attr_sig(node)
22
+ when Method
23
+ add_method_sig(node)
24
+ end
25
+ end
26
+
27
+ private
28
+
29
+ sig { params(attr: Attr).void }
30
+ def add_attr_sig(attr)
31
+ return unless attr.sigs.empty?
32
+ return if attr.names.size > 1
33
+
34
+ params = []
35
+ params << SigParam.new(attr.names.first.to_s, "T.untyped") if attr.is_a?(AttrWriter)
36
+
37
+ attr.sigs << Sig.new(
38
+ params: params,
39
+ return_type: "T.untyped"
40
+ )
41
+ add_todo_comment(attr)
42
+ end
43
+
44
+ sig { params(method: Method).void }
45
+ def add_method_sig(method)
46
+ return unless method.sigs.empty?
47
+
48
+ method.sigs << Sig.new(
49
+ params: method.params.map { |param| SigParam.new(param.name, "T.untyped") },
50
+ return_type: "T.untyped"
51
+ )
52
+ add_todo_comment(method)
53
+ end
54
+
55
+ sig { params(node: NodeWithComments).void }
56
+ def add_todo_comment(node)
57
+ node.comments << Comment.new("TODO: fill in signature with appropriate type information") if @with_todo_comment
58
+ end
59
+ end
60
+ end
61
+
62
+ class Tree
63
+ extend T::Sig
64
+
65
+ sig { params(with_todo_comment: T::Boolean).void }
66
+ def add_sig_templates!(with_todo_comment: true)
67
+ visitor = Rewriters::AddSigTemplates.new(with_todo_comment: with_todo_comment)
68
+ visitor.visit(self)
69
+ end
70
+ end
71
+ end
@@ -39,9 +39,17 @@ module RBI
39
39
  class Merge
40
40
  extend T::Sig
41
41
 
42
- sig { params(left: Tree, right: Tree, left_name: String, right_name: String).returns(Tree) }
43
- def self.merge_trees(left, right, left_name: "left", right_name: "right")
44
- rewriter = Rewriters::Merge.new(left_name: left_name, right_name: right_name)
42
+ class Keep < ::T::Enum
43
+ enums do
44
+ NONE = new
45
+ LEFT = new
46
+ RIGHT = new
47
+ end
48
+ end
49
+
50
+ sig { params(left: Tree, right: Tree, left_name: String, right_name: String, keep: Keep).returns(Tree) }
51
+ def self.merge_trees(left, right, left_name: "left", right_name: "right", keep: Keep::NONE)
52
+ rewriter = Rewriters::Merge.new(left_name: left_name, right_name: right_name, keep: keep)
45
53
  rewriter.merge(left)
46
54
  rewriter.merge(right)
47
55
  tree = rewriter.tree
@@ -52,17 +60,18 @@ module RBI
52
60
  sig { returns(Tree) }
53
61
  attr_reader :tree
54
62
 
55
- sig { params(left_name: String, right_name: String).void }
56
- def initialize(left_name: "left", right_name: "right")
63
+ sig { params(left_name: String, right_name: String, keep: Keep).void }
64
+ def initialize(left_name: "left", right_name: "right", keep: Keep::NONE)
57
65
  @left_name = left_name
58
66
  @right_name = right_name
67
+ @keep = keep
59
68
  @tree = T.let(Tree.new, Tree)
60
69
  @scope_stack = T.let([@tree], T::Array[Tree])
61
70
  end
62
71
 
63
72
  sig { params(tree: Tree).returns(T::Array[Conflict]) }
64
73
  def merge(tree)
65
- v = TreeMerger.new(@tree, left_name: @left_name, right_name: @right_name)
74
+ v = TreeMerger.new(@tree, left_name: @left_name, right_name: @right_name, keep: @keep)
66
75
  v.visit(tree)
67
76
  v.conflicts
68
77
  end
@@ -88,14 +97,15 @@ module RBI
88
97
  sig { returns(T::Array[Conflict]) }
89
98
  attr_reader :conflicts
90
99
 
91
- sig { params(output: Tree, left_name: String, right_name: String).void }
92
- def initialize(output, left_name: "left", right_name: "right")
100
+ sig { params(output: Tree, left_name: String, right_name: String, keep: Keep).void }
101
+ def initialize(output, left_name: "left", right_name: "right", keep: Keep::NONE)
93
102
  super()
94
103
  @tree = output
95
104
  @index = T.let(output.index, Index)
96
105
  @scope_stack = T.let([@tree], T::Array[Tree])
97
106
  @left_name = left_name
98
107
  @right_name = right_name
108
+ @keep = keep
99
109
  @conflicts = T.let([], T::Array[Conflict])
100
110
  end
101
111
 
@@ -110,6 +120,10 @@ module RBI
110
120
  if prev.is_a?(Scope)
111
121
  if node.compatible_with?(prev)
112
122
  prev.merge_with(node)
123
+ elsif @keep == Keep::LEFT
124
+ # do nothing it's already merged
125
+ elsif @keep == Keep::RIGHT
126
+ prev = replace_scope_header(prev, node)
113
127
  else
114
128
  make_conflict_scope(prev, node)
115
129
  end
@@ -129,6 +143,10 @@ module RBI
129
143
  if prev
130
144
  if node.compatible_with?(prev)
131
145
  prev.merge_with(node)
146
+ elsif @keep == Keep::LEFT
147
+ # do nothing it's already merged
148
+ elsif @keep == Keep::RIGHT
149
+ prev.replace(node)
132
150
  else
133
151
  make_conflict_tree(prev, node)
134
152
  end
@@ -175,6 +193,17 @@ module RBI
175
193
  end
176
194
  tree.right << right
177
195
  end
196
+
197
+ sig { params(left: Scope, right: Scope).returns(Scope) }
198
+ def replace_scope_header(left, right)
199
+ right_copy = right.dup_empty
200
+ left.replace(right_copy)
201
+ left.nodes.each do |node|
202
+ right_copy << node
203
+ end
204
+ @index.index(right_copy)
205
+ right_copy
206
+ end
178
207
  end
179
208
 
180
209
  # Merge adjacent conflict trees
@@ -300,6 +329,8 @@ module RBI
300
329
  Module.new(name, loc: loc, comments: comments)
301
330
  when Class
302
331
  Class.new(name, superclass_name: superclass_name, loc: loc, comments: comments)
332
+ when Struct
333
+ Struct.new(name, members: members, keyword_init: keyword_init, loc: loc, comments: comments)
303
334
  when SingletonClass
304
335
  SingletonClass.new(loc: loc, comments: comments)
305
336
  else
@@ -326,6 +357,15 @@ module RBI
326
357
  end
327
358
  end
328
359
 
360
+ class Struct
361
+ extend T::Sig
362
+
363
+ sig { override.params(other: Node).returns(T::Boolean) }
364
+ def compatible_with?(other)
365
+ other.is_a?(Struct) && members == other.members && keyword_init == other.keyword_init
366
+ end
367
+ end
368
+
329
369
  class Const
330
370
  extend T::Sig
331
371