rbi 0.1.13 → 0.1.14

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
@@ -2,6 +2,8 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RBI
5
+ class PrinterError < Error; end
6
+
5
7
  class Printer < Visitor
6
8
  extend T::Sig
7
9
 
@@ -74,18 +76,6 @@ module RBI
74
76
  printn(string)
75
77
  end
76
78
 
77
- sig { params(file: File).void }
78
- def visit_file(file)
79
- file.accept_printer(self)
80
- end
81
-
82
- sig { override.params(node: T.nilable(Node)).void }
83
- def visit(node)
84
- return unless node
85
-
86
- node.accept_printer(self)
87
- end
88
-
89
79
  sig { override.params(nodes: T::Array[Node]).void }
90
80
  def visit_all(nodes)
91
81
  previous_node = @previous_node
@@ -96,783 +86,695 @@ module RBI
96
86
  end
97
87
  @previous_node = previous_node
98
88
  end
99
- end
100
-
101
- class File
102
- extend T::Sig
103
89
 
104
- sig { params(v: Printer).void }
105
- def accept_printer(v)
106
- strictness = self.strictness
90
+ sig { override.params(file: File).void }
91
+ def visit_file(file)
92
+ strictness = file.strictness
107
93
  if strictness
108
- v.printl("# typed: #{strictness}")
94
+ printl("# typed: #{strictness}")
109
95
  end
110
- unless comments.empty?
111
- v.printn if strictness
112
- v.visit_all(comments)
96
+ unless file.comments.empty?
97
+ printn if strictness
98
+ visit_all(file.comments)
113
99
  end
114
100
 
115
- unless root.empty? && root.comments.empty?
116
- v.printn if strictness || !comments.empty?
117
- v.visit(root)
101
+ unless file.root.empty? && file.root.comments.empty?
102
+ printn if strictness || !file.comments.empty?
103
+ visit(file.root)
118
104
  end
119
105
  end
120
106
 
121
- sig do
122
- params(
123
- out: T.any(IO, StringIO),
124
- indent: Integer,
125
- print_locs: T::Boolean,
126
- max_line_length: T.nilable(Integer),
127
- ).void
128
- end
129
- def print(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
130
- p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
131
- p.visit_file(self)
132
- end
133
-
134
- sig { params(indent: Integer, print_locs: T::Boolean, max_line_length: T.nilable(Integer)).returns(String) }
135
- def string(indent: 0, print_locs: false, max_line_length: nil)
136
- out = StringIO.new
137
- print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
138
- out.string
139
- end
140
- end
141
-
142
- class Node
143
- extend T::Sig
144
-
145
- sig { abstract.params(v: Printer).void }
146
- def accept_printer(v); end
147
-
148
- sig do
149
- params(
150
- out: T.any(IO, StringIO),
151
- indent: Integer,
152
- print_locs: T::Boolean,
153
- max_line_length: T.nilable(Integer),
154
- ).void
155
- end
156
- def print(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
157
- p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
158
- p.visit(self)
159
- end
160
-
161
- sig { params(indent: Integer, print_locs: T::Boolean, max_line_length: T.nilable(Integer)).returns(String) }
162
- def string(indent: 0, print_locs: false, max_line_length: nil)
163
- out = StringIO.new
164
- print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
165
- out.string
166
- end
167
-
168
- sig { params(v: Printer).void }
169
- def print_blank_line_before(v)
170
- previous_node = v.previous_node
171
- return unless previous_node
172
- return if previous_node.is_a?(BlankLine)
173
- return if previous_node.oneline? && oneline?
174
-
175
- v.printn
176
- end
177
-
178
- sig { returns(T::Boolean) }
179
- def oneline?
180
- true
181
- end
182
- end
183
-
184
- class NodeWithComments
185
- extend T::Sig
186
-
187
- sig { override.returns(T::Boolean) }
188
- def oneline?
189
- comments.empty?
190
- end
191
- end
192
-
193
- class Comment
194
- extend T::Sig
107
+ private
195
108
 
196
- sig { override.params(v: Printer).void }
197
- def accept_printer(v)
198
- lines = text.lines
109
+ sig { override.params(node: Comment).void }
110
+ def visit_comment(node)
111
+ lines = node.text.lines
199
112
 
200
113
  if lines.empty?
201
- v.printl("#")
114
+ printl("#")
202
115
  end
203
116
 
204
117
  lines.each do |line|
205
118
  text = line.rstrip
206
- v.printt("#")
207
- v.print(" #{text}") unless text.empty?
208
- v.printn
119
+ printt("#")
120
+ print(" #{text}") unless text.empty?
121
+ printn
209
122
  end
210
123
  end
211
- end
212
124
 
213
- class BlankLine
214
- extend T::Sig
215
-
216
- sig { override.params(v: Printer).void }
217
- def accept_printer(v)
218
- v.printn
125
+ sig { override.params(node: BlankLine).void }
126
+ def visit_blank_line(node)
127
+ printn
219
128
  end
220
- end
221
-
222
- class Tree
223
- extend T::Sig
224
129
 
225
- sig { override.params(v: Printer).void }
226
- def accept_printer(v)
227
- v.visit_all(comments)
228
- v.printn if !comments.empty? && !empty?
229
- v.visit_all(nodes)
130
+ sig { override.params(node: Tree).void }
131
+ def visit_tree(node)
132
+ visit_all(node.comments)
133
+ printn if !node.comments.empty? && !node.empty?
134
+ visit_all(node.nodes)
230
135
  end
231
136
 
232
- sig { override.returns(T::Boolean) }
233
- def oneline?
234
- comments.empty? && empty?
137
+ sig { override.params(node: Module).void }
138
+ def visit_module(node)
139
+ visit_scope(node)
235
140
  end
236
- end
237
-
238
- class Scope
239
- extend T::Sig
240
-
241
- sig { override.params(v: Printer).void }
242
- def accept_printer(v)
243
- print_blank_line_before(v)
244
141
 
245
- v.printl("# #{loc}") if loc && v.print_locs
246
- v.visit_all(comments)
247
-
248
- print_header(v)
249
- print_body(v)
142
+ sig { override.params(node: Class).void }
143
+ def visit_class(node)
144
+ visit_scope(node)
250
145
  end
251
146
 
252
- sig { abstract.params(v: Printer).void }
253
- def print_header(v); end
147
+ sig { override.params(node: Struct).void }
148
+ def visit_struct(node)
149
+ visit_scope(node)
150
+ end
254
151
 
255
- sig { params(v: Printer).void }
256
- def print_body(v)
257
- unless empty?
258
- v.indent
259
- v.visit_all(nodes)
260
- v.dedent
261
- v.printl("end")
262
- end
152
+ sig { override.params(node: SingletonClass).void }
153
+ def visit_singleton_class(node)
154
+ visit_scope(node)
263
155
  end
264
- end
265
156
 
266
- class Module
267
- extend T::Sig
157
+ sig { params(node: Scope).void }
158
+ def visit_scope(node)
159
+ print_blank_line_before(node)
160
+ print_loc(node)
161
+ visit_all(node.comments)
268
162
 
269
- sig { override.params(v: Printer).void }
270
- def print_header(v)
271
- v.printt("module #{name}")
272
- if empty?
273
- v.printn("; end")
274
- else
275
- v.printn
276
- end
163
+ visit_scope_header(node)
164
+ visit_scope_body(node)
277
165
  end
278
- end
279
166
 
280
- class Class
281
- extend T::Sig
282
-
283
- sig { override.params(v: Printer).void }
284
- def print_header(v)
285
- v.printt("class #{name}")
286
- superclass = superclass_name
287
- v.print(" < #{superclass}") if superclass
288
- if empty?
289
- v.printn("; end")
167
+ sig { params(node: Scope).void }
168
+ def visit_scope_header(node)
169
+ case node
170
+ when Module
171
+ printt("module #{node.name}")
172
+ when Class
173
+ printt("class #{node.name}")
174
+ superclass = node.superclass_name
175
+ print(" < #{superclass}") if superclass
176
+ when Struct
177
+ printt("#{node.name} = ::Struct.new")
178
+ if !node.members.empty? || node.keyword_init
179
+ print("(")
180
+ args = node.members.map { |member| ":#{member}" }
181
+ args << "keyword_init: true" if node.keyword_init
182
+ print(args.join(", "))
183
+ print(")")
184
+ end
185
+ when SingletonClass
186
+ printt("class << self")
187
+ when TStruct
188
+ printt("class #{node.name} < T::Struct")
189
+ when TEnum
190
+ printt("class #{node.name} < T::Enum")
290
191
  else
291
- v.printn
192
+ raise PrinterError, "Unhandled node: #{node.class}"
292
193
  end
194
+ if node.empty? && !node.is_a?(Struct)
195
+ print("; end")
196
+ elsif !node.empty? && node.is_a?(Struct)
197
+ print(" do")
198
+ end
199
+ printn
293
200
  end
294
- end
295
201
 
296
- class Struct
297
- extend T::Sig
202
+ sig { params(node: Scope).void }
203
+ def visit_scope_body(node)
204
+ return if node.empty?
298
205
 
299
- sig { override.params(v: Printer).void }
300
- def print_header(v)
301
- v.printt("#{name} = ::Struct.new")
302
- if !members.empty? || keyword_init
303
- v.print("(")
304
- args = members.map { |member| ":#{member}" }
305
- args << "keyword_init: true" if keyword_init
306
- v.print(args.join(", "))
307
- v.print(")")
308
- end
309
- if empty?
310
- v.printn
311
- else
312
- v.printn(" do")
313
- end
206
+ indent
207
+ visit_all(node.nodes)
208
+ dedent
209
+ printl("end")
314
210
  end
315
- end
316
211
 
317
- class SingletonClass
318
- extend T::Sig
212
+ sig { override.params(node: Const).void }
213
+ def visit_const(node)
214
+ print_blank_line_before(node)
215
+ print_loc(node)
216
+ visit_all(node.comments)
319
217
 
320
- sig { override.params(v: Printer).void }
321
- def print_header(v)
322
- v.printt("class << self")
323
- if empty?
324
- v.printn("; end")
325
- else
326
- v.printn
327
- end
218
+ printl("#{node.name} = #{node.value}")
328
219
  end
329
- end
330
220
 
331
- class Const
332
- extend T::Sig
221
+ sig { override.params(node: AttrAccessor).void }
222
+ def visit_attr_accessor(node)
223
+ visit_attr(node)
224
+ end
333
225
 
334
- sig { override.params(v: Printer).void }
335
- def accept_printer(v)
336
- print_blank_line_before(v)
226
+ sig { override.params(node: AttrReader).void }
227
+ def visit_attr_reader(node)
228
+ visit_attr(node)
229
+ end
337
230
 
338
- v.printl("# #{loc}") if loc && v.print_locs
339
- v.visit_all(comments)
340
- v.printl("#{name} = #{value}")
231
+ sig { override.params(node: AttrWriter).void }
232
+ def visit_attr_writer(node)
233
+ visit_attr(node)
341
234
  end
342
- end
343
235
 
344
- class Attr
345
- extend T::Sig
236
+ sig { params(node: Attr).void }
237
+ def visit_attr(node)
238
+ print_blank_line_before(node)
239
+
240
+ visit_all(node.comments)
241
+ node.sigs.each { |sig| visit(sig) }
346
242
 
347
- sig { override.params(v: Printer).void }
348
- def accept_printer(v)
349
- print_blank_line_before(v)
350
-
351
- v.visit_all(comments)
352
- sigs.each { |sig| v.visit(sig) }
353
- v.printl("# #{loc}") if loc && v.print_locs
354
- v.printt
355
- unless v.in_visibility_group || visibility.public?
356
- v.print(visibility.visibility.to_s)
357
- v.print(" ")
243
+ print_loc(node)
244
+ printt
245
+ unless in_visibility_group || node.visibility.public?
246
+ self.print(node.visibility.visibility.to_s)
247
+ print(" ")
358
248
  end
359
- case self
249
+ case node
360
250
  when AttrAccessor
361
- v.print("attr_accessor")
251
+ print("attr_accessor")
362
252
  when AttrReader
363
- v.print("attr_reader")
253
+ print("attr_reader")
364
254
  when AttrWriter
365
- v.print("attr_writer")
255
+ print("attr_writer")
366
256
  end
367
- unless names.empty?
368
- v.print(" ")
369
- v.print(names.map { |name| ":#{name}" }.join(", "))
257
+ unless node.names.empty?
258
+ print(" ")
259
+ print(node.names.map { |name| ":#{name}" }.join(", "))
370
260
  end
371
- v.printn
261
+ printn
372
262
  end
373
263
 
374
- sig { override.returns(T::Boolean) }
375
- def oneline?
376
- comments.empty? && sigs.empty?
377
- end
378
- end
379
-
380
- class Method
381
- extend T::Sig
264
+ sig { override.params(node: Method).void }
265
+ def visit_method(node)
266
+ print_blank_line_before(node)
267
+ visit_all(node.comments)
268
+ visit_all(node.sigs)
382
269
 
383
- sig { override.params(v: Printer).void }
384
- def accept_printer(v)
385
- print_blank_line_before(v)
386
-
387
- v.visit_all(comments)
388
- v.visit_all(sigs)
389
- v.printl("# #{loc}") if loc && v.print_locs
390
- v.printt
391
- unless v.in_visibility_group || visibility.public?
392
- v.print(visibility.visibility.to_s)
393
- v.print(" ")
270
+ print_loc(node)
271
+ printt
272
+ unless in_visibility_group || node.visibility.public?
273
+ self.print(node.visibility.visibility.to_s)
274
+ print(" ")
394
275
  end
395
- v.print("def ")
396
- v.print("self.") if is_singleton
397
- v.print(name)
398
- unless params.empty?
399
- v.print("(")
400
- if inline_params?
401
- params.each_with_index do |param, index|
402
- v.print(", ") if index > 0
403
- v.visit(param)
276
+ print("def ")
277
+ print("self.") if node.is_singleton
278
+ print(node.name)
279
+ unless node.params.empty?
280
+ print("(")
281
+ if node.params.all? { |p| p.comments.empty? }
282
+ node.params.each_with_index do |param, index|
283
+ print(", ") if index > 0
284
+ visit(param)
404
285
  end
405
286
  else
406
- v.printn
407
- v.indent
408
- params.each_with_index do |param, pindex|
409
- v.printt
410
- v.visit(param)
411
- v.print(",") if pindex < params.size - 1
412
-
413
- param.comments_lines.each_with_index do |comment, cindex|
287
+ printn
288
+ indent
289
+ node.params.each_with_index do |param, pindex|
290
+ printt
291
+ visit(param)
292
+ print(",") if pindex < node.params.size - 1
293
+
294
+ comment_lines = param.comments.flat_map { |comment| comment.text.lines.map(&:rstrip) }
295
+ comment_lines.each_with_index do |comment, cindex|
414
296
  if cindex > 0
415
- param.print_comment_leading_space(v, last: pindex == params.size - 1)
297
+ print_param_comment_leading_space(param, last: pindex == node.params.size - 1)
416
298
  else
417
- v.print(" ")
299
+ print(" ")
418
300
  end
419
- v.print("# #{comment}")
301
+ print("# #{comment}")
420
302
  end
421
- v.printn
303
+ printn
422
304
  end
423
- v.dedent
305
+ dedent
424
306
  end
425
- v.print(")")
307
+ print(")")
426
308
  end
427
- v.print("; end")
428
- v.printn
309
+ print("; end")
310
+ printn
429
311
  end
430
312
 
431
- sig { override.returns(T::Boolean) }
432
- def oneline?
433
- comments.empty? && sigs.empty? && inline_params?
313
+ sig { override.params(node: ReqParam).void }
314
+ def visit_req_param(node)
315
+ print(node.name)
434
316
  end
435
317
 
436
- sig { returns(T::Boolean) }
437
- def inline_params?
438
- params.all? { |p| p.comments.empty? }
318
+ sig { override.params(node: OptParam).void }
319
+ def visit_opt_param(node)
320
+ print("#{node.name} = #{node.value}")
439
321
  end
440
- end
441
322
 
442
- class Param
443
- extend T::Sig
323
+ sig { override.params(node: RestParam).void }
324
+ def visit_rest_param(node)
325
+ print("*#{node.name}")
326
+ end
444
327
 
445
- sig { override.params(v: Printer).void }
446
- def accept_printer(v)
447
- v.print(name.to_s)
328
+ sig { override.params(node: KwParam).void }
329
+ def visit_kw_param(node)
330
+ print("#{node.name}:")
448
331
  end
449
332
 
450
- sig { params(v: Printer, last: T::Boolean).void }
451
- def print_comment_leading_space(v, last:)
452
- v.printn
453
- v.printt
454
- v.print(" " * (name.size + 1))
455
- v.print(" ") unless last
333
+ sig { override.params(node: KwOptParam).void }
334
+ def visit_kw_opt_param(node)
335
+ print("#{node.name}: #{node.value}")
456
336
  end
457
337
 
458
- sig { returns(T::Array[String]) }
459
- def comments_lines
460
- comments.flat_map { |comment| comment.text.lines.map(&:rstrip) }
338
+ sig { override.params(node: KwRestParam).void }
339
+ def visit_kw_rest_param(node)
340
+ print("**#{node.name}")
461
341
  end
462
- end
463
342
 
464
- class OptParam
465
- extend T::Sig
343
+ sig { override.params(node: BlockParam).void }
344
+ def visit_block_param(node)
345
+ print("&#{node.name}")
346
+ end
466
347
 
467
- sig { override.params(v: Printer).void }
468
- def accept_printer(v)
469
- v.print("#{name} = #{value}")
348
+ sig { override.params(node: Include).void }
349
+ def visit_include(node)
350
+ visit_mixin(node)
470
351
  end
471
352
 
472
- sig { override.params(v: Printer, last: T::Boolean).void }
473
- def print_comment_leading_space(v, last:)
474
- super
475
- v.print(" " * (value.size + 3))
353
+ sig { override.params(node: Extend).void }
354
+ def visit_extend(node)
355
+ visit_mixin(node)
476
356
  end
477
- end
478
357
 
479
- class RestParam
480
- extend T::Sig
358
+ sig { params(node: Mixin).void }
359
+ def visit_mixin(node)
360
+ print_blank_line_before(node)
361
+ print_loc(node)
362
+ visit_all(node.comments)
481
363
 
482
- sig { override.params(v: Printer).void }
483
- def accept_printer(v)
484
- v.print("*#{name}")
364
+ case node
365
+ when Include
366
+ printt("include")
367
+ when Extend
368
+ printt("extend")
369
+ when MixesInClassMethods
370
+ printt("mixes_in_class_methods")
371
+ end
372
+ printn(" #{node.names.join(", ")}")
485
373
  end
486
374
 
487
- sig { override.params(v: Printer, last: T::Boolean).void }
488
- def print_comment_leading_space(v, last:)
489
- super
490
- v.print(" ")
375
+ sig { override.params(node: Public).void }
376
+ def visit_public(node)
377
+ visit_visibility(node)
491
378
  end
492
- end
493
-
494
- class KwParam
495
- extend T::Sig
496
379
 
497
- sig { override.params(v: Printer).void }
498
- def accept_printer(v)
499
- v.print("#{name}:")
380
+ sig { override.params(node: Protected).void }
381
+ def visit_protected(node)
382
+ visit_visibility(node)
500
383
  end
501
384
 
502
- sig { override.params(v: Printer, last: T::Boolean).void }
503
- def print_comment_leading_space(v, last:)
504
- super
505
- v.print(" ")
385
+ sig { override.params(node: Private).void }
386
+ def visit_private(node)
387
+ visit_visibility(node)
506
388
  end
507
- end
508
389
 
509
- class KwOptParam
510
- extend T::Sig
390
+ sig { params(node: Visibility).void }
391
+ def visit_visibility(node)
392
+ print_blank_line_before(node)
393
+ print_loc(node)
394
+ visit_all(node.comments)
511
395
 
512
- sig { override.params(v: Printer).void }
513
- def accept_printer(v)
514
- v.print("#{name}: #{value}")
396
+ printl(node.visibility.to_s)
515
397
  end
516
398
 
517
- sig { override.params(v: Printer, last: T::Boolean).void }
518
- def print_comment_leading_space(v, last:)
519
- super
520
- v.print(" " * (value.size + 2))
521
- end
522
- end
399
+ sig { override.params(node: Send).void }
400
+ def visit_send(node)
401
+ print_blank_line_before(node)
402
+ print_loc(node)
403
+ visit_all(node.comments)
523
404
 
524
- class KwRestParam
525
- extend T::Sig
405
+ printt(node.method)
406
+ unless node.args.empty?
407
+ print(" ")
408
+ node.args.each_with_index do |arg, index|
409
+ visit(arg)
410
+ print(", ") if index < node.args.size - 1
411
+ end
412
+ end
413
+ printn
414
+ end
526
415
 
527
- sig { override.params(v: Printer).void }
528
- def accept_printer(v)
529
- v.print("**#{name}")
416
+ sig { override.params(node: Arg).void }
417
+ def visit_arg(node)
418
+ print(node.value)
530
419
  end
531
420
 
532
- sig { override.params(v: Printer, last: T::Boolean).void }
533
- def print_comment_leading_space(v, last:)
534
- super
535
- v.print(" ")
421
+ sig { override.params(node: KwArg).void }
422
+ def visit_kw_arg(node)
423
+ print("#{node.keyword}: #{node.value}")
536
424
  end
537
- end
538
425
 
539
- class BlockParam
540
- extend T::Sig
426
+ sig { override.params(node: Sig).void }
427
+ def visit_sig(node)
428
+ print_loc(node)
541
429
 
542
- sig { override.params(v: Printer).void }
543
- def accept_printer(v)
544
- v.print("&#{name}")
430
+ max_line_length = self.max_line_length
431
+ if oneline?(node) && max_line_length.nil?
432
+ print_sig_as_line(node)
433
+ elsif max_line_length
434
+ line = node.string(indent: current_indent)
435
+ if line.length <= max_line_length
436
+ print(line)
437
+ else
438
+ print_sig_as_block(node)
439
+ end
440
+ else
441
+ print_sig_as_block(node)
442
+ end
545
443
  end
546
444
 
547
- sig { override.params(v: Printer, last: T::Boolean).void }
548
- def print_comment_leading_space(v, last:)
549
- super
550
- v.print(" ")
445
+ sig { override.params(node: SigParam).void }
446
+ def visit_sig_param(node)
447
+ print("#{node.name}: #{node.type}")
551
448
  end
552
- end
553
449
 
554
- class Mixin
555
- extend T::Sig
450
+ sig { override.params(node: TStruct).void }
451
+ def visit_tstruct(node)
452
+ visit_scope(node)
453
+ end
556
454
 
557
- sig { override.params(v: Printer).void }
558
- def accept_printer(v)
559
- print_blank_line_before(v)
455
+ sig { override.params(node: TStructConst).void }
456
+ def visit_tstruct_const(node)
457
+ visit_t_struct_field(node)
458
+ end
560
459
 
561
- v.printl("# #{loc}") if loc && v.print_locs
562
- v.visit_all(comments)
563
- case self
564
- when Include
565
- v.printt("include")
566
- when Extend
567
- v.printt("extend")
568
- when MixesInClassMethods
569
- v.printt("mixes_in_class_methods")
570
- end
571
- v.printn(" #{names.join(", ")}")
460
+ sig { override.params(node: TStructProp).void }
461
+ def visit_tstruct_prop(node)
462
+ visit_t_struct_field(node)
572
463
  end
573
- end
574
464
 
575
- class Visibility
576
- extend T::Sig
465
+ sig { params(node: TStructField).void }
466
+ def visit_t_struct_field(node)
467
+ print_blank_line_before(node)
468
+ print_loc(node)
469
+ visit_all(node.comments)
577
470
 
578
- sig { override.params(v: Printer).void }
579
- def accept_printer(v)
580
- print_blank_line_before(v)
471
+ case node
472
+ when TStructProp
473
+ printt("prop")
474
+ when TStructConst
475
+ printt("const")
476
+ end
477
+ print(" :#{node.name}, #{node.type}")
478
+ default = node.default
479
+ print(", default: #{default}") if default
480
+ printn
481
+ end
581
482
 
582
- v.printl("# #{loc}") if loc && v.print_locs
583
- v.visit_all(comments)
584
- v.printl(visibility.to_s)
483
+ sig { override.params(node: TEnum).void }
484
+ def visit_tenum(node)
485
+ visit_scope(node)
585
486
  end
586
- end
587
487
 
588
- class Send
589
- extend T::Sig
488
+ sig { override.params(node: TEnumBlock).void }
489
+ def visit_tenum_block(node)
490
+ print_loc(node)
491
+ visit_all(node.comments)
590
492
 
591
- sig { override.params(v: Printer).void }
592
- def accept_printer(v)
593
- print_blank_line_before(v)
594
-
595
- v.printl("# #{loc}") if loc && v.print_locs
596
- v.visit_all(comments)
597
- v.printt(method)
598
- unless args.empty?
599
- v.print(" ")
600
- args.each_with_index do |arg, index|
601
- v.visit(arg)
602
- v.print(", ") if index < args.size - 1
603
- end
493
+ printl("enums do")
494
+ indent
495
+ node.names.each do |name|
496
+ printl("#{name} = new")
604
497
  end
605
- v.printn
498
+ dedent
499
+ printl("end")
606
500
  end
607
- end
608
501
 
609
- class Arg
610
- extend T::Sig
502
+ sig { override.params(node: TypeMember).void }
503
+ def visit_type_member(node)
504
+ print_blank_line_before(node)
505
+ print_loc(node)
506
+ visit_all(node.comments)
611
507
 
612
- sig { override.params(v: Printer).void }
613
- def accept_printer(v)
614
- v.print(value)
508
+ printl("#{node.name} = #{node.value}")
615
509
  end
616
- end
617
510
 
618
- class KwArg
619
- extend T::Sig
511
+ sig { override.params(node: Helper).void }
512
+ def visit_helper(node)
513
+ print_blank_line_before(node)
514
+ print_loc(node)
515
+ visit_all(node.comments)
620
516
 
621
- sig { override.params(v: Printer).void }
622
- def accept_printer(v)
623
- v.print(keyword)
624
- v.print(": ")
625
- v.print(value)
517
+ printl("#{node.name}!")
626
518
  end
627
- end
628
519
 
629
- class Sig
630
- extend T::Sig
520
+ sig { override.params(node: MixesInClassMethods).void }
521
+ def visit_mixes_in_class_methods(node)
522
+ visit_mixin(node)
523
+ end
631
524
 
632
- sig { override.params(v: Printer).void }
633
- def accept_printer(v)
634
- v.printl("# #{loc}") if loc && v.print_locs
635
- max_line_length = v.max_line_length
636
- if oneline? && max_line_length.nil?
637
- print_as_line(v)
638
- elsif max_line_length
639
- line = string(indent: v.current_indent)
640
- if line.length <= max_line_length
641
- v.print(line)
642
- else
643
- print_as_block(v)
644
- end
525
+ sig { override.params(node: Group).void }
526
+ def visit_group(node)
527
+ printn unless previous_node.nil?
528
+ visit_all(node.nodes)
529
+ end
530
+
531
+ sig { override.params(node: VisibilityGroup).void }
532
+ def visit_visibility_group(node)
533
+ self.in_visibility_group = true
534
+ if node.visibility.public?
535
+ printn unless previous_node.nil?
645
536
  else
646
- print_as_block(v)
537
+ visit(node.visibility)
538
+ printn
647
539
  end
540
+ visit_all(node.nodes)
541
+ self.in_visibility_group = false
648
542
  end
649
543
 
650
- sig { override.returns(T::Boolean) }
651
- def oneline?
652
- inline_params?
544
+ sig { override.params(node: RequiresAncestor).void }
545
+ def visit_requires_ancestor(node)
546
+ print_blank_line_before(node)
547
+ print_loc(node)
548
+ visit_all(node.comments)
549
+
550
+ printl("requires_ancestor { #{node.name} }")
653
551
  end
654
552
 
655
- sig { returns(T::Boolean) }
656
- def inline_params?
657
- params.all? { |p| p.comments.empty? }
553
+ sig { override.params(node: ConflictTree).void }
554
+ def visit_conflict_tree(node)
555
+ printl("<<<<<<< #{node.left_name}")
556
+ visit(node.left)
557
+ printl("=======")
558
+ visit(node.right)
559
+ printl(">>>>>>> #{node.right_name}")
658
560
  end
659
561
 
660
- private
562
+ sig { override.params(node: ScopeConflict).void }
563
+ def visit_scope_conflict(node)
564
+ print_blank_line_before(node)
565
+ print_loc(node)
566
+ visit_all(node.comments)
661
567
 
662
- sig { returns(T::Array[String]) }
663
- def sig_modifiers
664
- modifiers = T.let([], T::Array[String])
665
- modifiers << "abstract" if is_abstract
666
- modifiers << "override" if is_override
667
- modifiers << "overridable" if is_overridable
668
- modifiers << "type_parameters(#{type_params.map { |type| ":#{type}" }.join(", ")})" if type_params.any?
669
- modifiers << "checked(:#{checked})" if checked
670
- modifiers
568
+ printl("<<<<<<< #{node.left_name}")
569
+ visit_scope_header(node.left)
570
+ printl("=======")
571
+ visit_scope_header(node.right)
572
+ printl(">>>>>>> #{node.right_name}")
573
+ visit_scope_body(node.left)
574
+ end
575
+
576
+ sig { params(node: Node).void }
577
+ def print_blank_line_before(node)
578
+ previous_node = self.previous_node
579
+ return unless previous_node
580
+ return if previous_node.is_a?(BlankLine)
581
+ return if oneline?(previous_node) && oneline?(node)
582
+
583
+ printn
584
+ end
585
+
586
+ sig { params(node: Node).void }
587
+ def print_loc(node)
588
+ loc = node.loc
589
+ printl("# #{loc}") if loc && print_locs
671
590
  end
672
591
 
673
- sig { params(v: Printer).void }
674
- def print_as_line(v)
675
- v.printt("sig")
676
- v.print("(:final)") if is_final
677
- v.print(" { ")
678
- sig_modifiers.each do |modifier|
679
- v.print("#{modifier}.")
592
+ sig { params(node: Param, last: T::Boolean).void }
593
+ def print_param_comment_leading_space(node, last:)
594
+ printn
595
+ printt
596
+ print(" " * (node.name.size + 1))
597
+ print(" ") unless last
598
+ case node
599
+ when OptParam
600
+ print(" " * (node.value.size + 3))
601
+ when RestParam, KwParam, BlockParam
602
+ print(" ")
603
+ when KwRestParam
604
+ print(" ")
605
+ when KwOptParam
606
+ print(" " * (node.value.size + 2))
680
607
  end
681
- unless params.empty?
682
- v.print("params(")
683
- params.each_with_index do |param, index|
684
- v.print(", ") if index > 0
685
- v.visit(param)
608
+ end
609
+
610
+ sig { params(node: SigParam, last: T::Boolean).void }
611
+ def print_sig_param_comment_leading_space(node, last:)
612
+ printn
613
+ printt
614
+ print(" " * (node.name.size + node.type.size + 3))
615
+ print(" ") unless last
616
+ end
617
+
618
+ sig { params(node: Node).returns(T::Boolean) }
619
+ def oneline?(node)
620
+ case node
621
+ when ScopeConflict
622
+ oneline?(node.left)
623
+ when Tree
624
+ node.comments.empty? && node.empty?
625
+ when Attr
626
+ node.comments.empty? && node.sigs.empty?
627
+ when Method
628
+ node.comments.empty? && node.sigs.empty? && node.params.all? { |p| p.comments.empty? }
629
+ when Sig
630
+ node.params.all? { |p| p.comments.empty? }
631
+ when NodeWithComments
632
+ node.comments.empty?
633
+ when VisibilityGroup
634
+ false
635
+ else
636
+ true
637
+ end
638
+ end
639
+
640
+ sig { params(node: Sig).void }
641
+ def print_sig_as_line(node)
642
+ printt("sig")
643
+ print("(:final)") if node.is_final
644
+ print(" { ")
645
+ sig_modifiers(node).each do |modifier|
646
+ print("#{modifier}.")
647
+ end
648
+ unless node.params.empty?
649
+ print("params(")
650
+ node.params.each_with_index do |param, index|
651
+ print(", ") if index > 0
652
+ visit(param)
686
653
  end
687
- v.print(").")
654
+ print(").")
688
655
  end
689
- if return_type && return_type != "void"
690
- v.print("returns(#{return_type})")
656
+ return_type = node.return_type
657
+ if node.return_type && node.return_type != "void"
658
+ print("returns(#{return_type})")
691
659
  else
692
- v.print("void")
660
+ print("void")
693
661
  end
694
- v.printn(" }")
662
+ printn(" }")
695
663
  end
696
664
 
697
- sig { params(v: Printer).void }
698
- def print_as_block(v)
699
- modifiers = sig_modifiers
665
+ sig { params(node: Sig).void }
666
+ def print_sig_as_block(node)
667
+ modifiers = sig_modifiers(node)
700
668
 
701
- v.printl("sig do")
702
- v.indent
669
+ printt("sig")
670
+ print("(:final)") if node.is_final
671
+ printn(" do")
672
+ indent
703
673
  if modifiers.any?
704
- v.printl(T.must(modifiers.first))
705
- v.indent
674
+ printl(T.must(modifiers.first))
675
+ indent
706
676
  modifiers[1..]&.each do |modifier|
707
- v.printl(".#{modifier}")
677
+ printl(".#{modifier}")
708
678
  end
709
679
  end
710
680
 
681
+ params = node.params
711
682
  if params.any?
712
- v.printt
713
- v.print(".") if modifiers.any?
714
- v.printn("params(")
715
- v.indent
683
+ printt
684
+ print(".") if modifiers.any?
685
+ printn("params(")
686
+ indent
716
687
  params.each_with_index do |param, pindex|
717
- v.printt
718
- v.visit(param)
719
- v.print(",") if pindex < params.size - 1
720
- param.comments_lines.each_with_index do |comment, cindex|
688
+ printt
689
+ visit(param)
690
+ print(",") if pindex < params.size - 1
691
+
692
+ comment_lines = param.comments.flat_map { |comment| comment.text.lines.map(&:rstrip) }
693
+ comment_lines.each_with_index do |comment, cindex|
721
694
  if cindex == 0
722
- v.print(" ")
695
+ print(" ")
723
696
  else
724
- param.print_comment_leading_space(v, last: pindex == params.size - 1)
697
+ print_sig_param_comment_leading_space(param, last: pindex == params.size - 1)
725
698
  end
726
- v.print("# #{comment}")
699
+ print("# #{comment}")
727
700
  end
728
- v.printn
701
+ printn
729
702
  end
730
- v.dedent
731
- v.printt(")")
703
+ dedent
704
+ printt(")")
732
705
  end
733
- v.printt if params.empty?
734
- v.print(".") if modifiers.any? || params.any?
706
+ printt if params.empty?
707
+ print(".") if modifiers.any? || params.any?
708
+
709
+ return_type = node.return_type
735
710
  if return_type && return_type != "void"
736
- v.print("returns(#{return_type})")
711
+ print("returns(#{return_type})")
737
712
  else
738
- v.print("void")
713
+ print("void")
739
714
  end
740
- v.printn
741
- v.dedent
742
- v.dedent if modifiers.any?
743
- v.printl("end")
715
+ printn
716
+ dedent
717
+ dedent if modifiers.any?
718
+ printl("end")
744
719
  end
745
- end
746
-
747
- class SigParam
748
- extend T::Sig
749
720
 
750
- sig { override.params(v: Printer).void }
751
- def accept_printer(v)
752
- v.print("#{name}: #{type}")
753
- end
754
-
755
- sig { params(v: Printer, last: T::Boolean).void }
756
- def print_comment_leading_space(v, last:)
757
- v.printn
758
- v.printt
759
- v.print(" " * (name.size + type.size + 3))
760
- v.print(" ") unless last
761
- end
762
-
763
- sig { returns(T::Array[String]) }
764
- def comments_lines
765
- comments.flat_map { |comment| comment.text.lines.map(&:rstrip) }
766
- end
767
- end
768
-
769
- class TStructField
770
- extend T::Sig
771
-
772
- sig { override.params(v: Printer).void }
773
- def accept_printer(v)
774
- print_blank_line_before(v)
775
-
776
- v.printl("# #{loc}") if loc && v.print_locs
777
- v.visit_all(comments)
778
- case self
779
- when TStructProp
780
- v.printt("prop")
781
- when TStructConst
782
- v.printt("const")
783
- end
784
- v.print(" :#{name}, #{type}")
785
- default = self.default
786
- v.print(", default: #{default}") if default
787
- v.printn
788
- end
789
- end
790
-
791
- class TEnumBlock
792
- extend T::Sig
793
-
794
- sig { override.params(v: Printer).void }
795
- def accept_printer(v)
796
- v.printl("# #{loc}") if loc && v.print_locs
797
- v.visit_all(comments)
798
- v.printl("enums do")
799
- v.indent
800
- names.each do |name|
801
- v.printl("#{name} = new")
802
- end
803
- v.dedent
804
- v.printl("end")
721
+ sig { params(node: Sig).returns(T::Array[String]) }
722
+ def sig_modifiers(node)
723
+ modifiers = T.let([], T::Array[String])
724
+ modifiers << "abstract" if node.is_abstract
725
+ modifiers << "override" if node.is_override
726
+ modifiers << "overridable" if node.is_overridable
727
+ modifiers << "type_parameters(#{node.type_params.map { |type| ":#{type}" }.join(", ")})" if node.type_params.any?
728
+ modifiers << "checked(:#{node.checked})" if node.checked
729
+ modifiers
805
730
  end
806
731
  end
807
732
 
808
- class TypeMember
733
+ class File
809
734
  extend T::Sig
810
735
 
811
- sig { override.params(v: Printer).void }
812
- def accept_printer(v)
813
- print_blank_line_before(v)
814
-
815
- v.printl("# #{loc}") if loc && v.print_locs
816
- v.visit_all(comments)
817
- v.printl("#{name} = #{value}")
736
+ sig do
737
+ params(
738
+ out: T.any(IO, StringIO),
739
+ indent: Integer,
740
+ print_locs: T::Boolean,
741
+ max_line_length: T.nilable(Integer),
742
+ ).void
818
743
  end
819
- end
820
-
821
- class Helper
822
- extend T::Sig
823
-
824
- sig { override.params(v: Printer).void }
825
- def accept_printer(v)
826
- print_blank_line_before(v)
827
-
828
- v.printl("# #{loc}") if loc && v.print_locs
829
- v.visit_all(comments)
830
- v.printl("#{name}!")
744
+ def print(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
745
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
746
+ p.visit_file(self)
831
747
  end
832
- end
833
748
 
834
- class Group
835
- extend T::Sig
836
-
837
- sig { override.params(v: Printer).void }
838
- def accept_printer(v)
839
- v.printn unless v.previous_node.nil?
840
- v.visit_all(nodes)
749
+ sig { params(indent: Integer, print_locs: T::Boolean, max_line_length: T.nilable(Integer)).returns(String) }
750
+ def string(indent: 0, print_locs: false, max_line_length: nil)
751
+ out = StringIO.new
752
+ print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
753
+ out.string
841
754
  end
842
755
  end
843
756
 
844
- class VisibilityGroup
757
+ class Node
845
758
  extend T::Sig
846
759
 
847
- sig { override.params(v: Printer).void }
848
- def accept_printer(v)
849
- v.in_visibility_group = true
850
- if visibility.public?
851
- v.printn unless v.previous_node.nil?
852
- else
853
- v.visit(visibility)
854
- v.printn
855
- end
856
- v.visit_all(nodes)
857
- v.in_visibility_group = false
760
+ sig do
761
+ params(
762
+ out: T.any(IO, StringIO),
763
+ indent: Integer,
764
+ print_locs: T::Boolean,
765
+ max_line_length: T.nilable(Integer),
766
+ ).void
858
767
  end
859
-
860
- sig { override.returns(T::Boolean) }
861
- def oneline?
862
- false
768
+ def print(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
769
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
770
+ p.visit(self)
863
771
  end
864
- end
865
772
 
866
- class RequiresAncestor
867
- extend T::Sig
868
-
869
- sig { override.params(v: Printer).void }
870
- def accept_printer(v)
871
- print_blank_line_before(v)
872
-
873
- v.printl("# #{loc}") if loc && v.print_locs
874
- v.visit_all(comments)
875
- v.printl("requires_ancestor { #{name} }")
773
+ sig { params(indent: Integer, print_locs: T::Boolean, max_line_length: T.nilable(Integer)).returns(String) }
774
+ def string(indent: 0, print_locs: false, max_line_length: nil)
775
+ out = StringIO.new
776
+ print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
777
+ out.string
876
778
  end
877
779
  end
878
780
  end