rbi 0.0.2 → 0.0.3
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/rbi/model.rb +429 -57
- data/lib/rbi/parser.rb +200 -87
- data/lib/rbi/printer.rb +123 -29
- data/lib/rbi/rewriters/add_sig_templates.rb +71 -0
- data/lib/rbi/rewriters/merge_trees.rb +48 -8
- data/lib/rbi/rewriters/nest_non_public_methods.rb +5 -5
- data/lib/rbi/rewriters/sort_nodes.rb +16 -16
- data/lib/rbi/version.rb +1 -1
- data/lib/rbi.rb +1 -0
- metadata +4 -3
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
|
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
|
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 +
|
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
|
-
|
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
|
-
|
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
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
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
|
-
|
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
|
-
|
634
|
-
|
635
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
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
|
|