rbi 0.1.13 → 0.2.0

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,694 @@ 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
129
 
222
- class Tree
223
- extend T::Sig
224
-
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
141
 
241
- sig { override.params(v: Printer).void }
242
- def accept_printer(v)
243
- print_blank_line_before(v)
244
-
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 TEnum
173
+ printt("class #{node.name} < T::Enum")
174
+ when TStruct
175
+ printt("class #{node.name} < T::Struct")
176
+ when Class
177
+ printt("class #{node.name}")
178
+ superclass = node.superclass_name
179
+ print(" < #{superclass}") if superclass
180
+ when Struct
181
+ printt("#{node.name} = ::Struct.new")
182
+ if !node.members.empty? || node.keyword_init
183
+ print("(")
184
+ args = node.members.map { |member| ":#{member}" }
185
+ args << "keyword_init: true" if node.keyword_init
186
+ print(args.join(", "))
187
+ print(")")
188
+ end
189
+ when SingletonClass
190
+ printt("class << self")
290
191
  else
291
- v.printn
192
+ raise PrinterError, "Unhandled node: #{node.class}"
193
+ end
194
+ if node.empty? && !node.is_a?(Struct)
195
+ print("; end")
196
+ elsif !node.empty? && node.is_a?(Struct)
197
+ print(" do")
292
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)
346
239
 
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(" ")
240
+ visit_all(node.comments)
241
+ node.sigs.each { |sig| visit(sig) }
242
+
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))
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)
404
+
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
521
414
  end
522
- end
523
415
 
524
- class KwRestParam
525
- extend T::Sig
416
+ sig { override.params(node: Arg).void }
417
+ def visit_arg(node)
418
+ print(node.value)
419
+ end
526
420
 
527
- sig { override.params(v: Printer).void }
528
- def accept_printer(v)
529
- v.print("**#{name}")
421
+ sig { override.params(node: KwArg).void }
422
+ def visit_kw_arg(node)
423
+ print("#{node.keyword}: #{node.value}")
530
424
  end
531
425
 
532
- sig { override.params(v: Printer, last: T::Boolean).void }
533
- def print_comment_leading_space(v, last:)
534
- super
535
- v.print(" ")
426
+ sig { override.params(node: Sig).void }
427
+ def visit_sig(node)
428
+ print_loc(node)
429
+ visit_all(node.comments)
430
+
431
+ max_line_length = self.max_line_length
432
+ if oneline?(node) && max_line_length.nil?
433
+ print_sig_as_line(node)
434
+ elsif max_line_length
435
+ line = node.string(indent: current_indent)
436
+ if line.length <= max_line_length
437
+ print(line)
438
+ else
439
+ print_sig_as_block(node)
440
+ end
441
+ else
442
+ print_sig_as_block(node)
443
+ end
536
444
  end
537
- end
538
445
 
539
- class BlockParam
540
- extend T::Sig
446
+ sig { override.params(node: SigParam).void }
447
+ def visit_sig_param(node)
448
+ print("#{node.name}: #{node.type}")
449
+ end
541
450
 
542
- sig { override.params(v: Printer).void }
543
- def accept_printer(v)
544
- v.print("&#{name}")
451
+ sig { override.params(node: TStruct).void }
452
+ def visit_tstruct(node)
453
+ visit_scope(node)
545
454
  end
546
455
 
547
- sig { override.params(v: Printer, last: T::Boolean).void }
548
- def print_comment_leading_space(v, last:)
549
- super
550
- v.print(" ")
456
+ sig { override.params(node: TStructConst).void }
457
+ def visit_tstruct_const(node)
458
+ visit_t_struct_field(node)
551
459
  end
552
- end
553
460
 
554
- class Mixin
555
- extend T::Sig
461
+ sig { override.params(node: TStructProp).void }
462
+ def visit_tstruct_prop(node)
463
+ visit_t_struct_field(node)
464
+ end
556
465
 
557
- sig { override.params(v: Printer).void }
558
- def accept_printer(v)
559
- print_blank_line_before(v)
466
+ sig { params(node: TStructField).void }
467
+ def visit_t_struct_field(node)
468
+ print_blank_line_before(node)
469
+ print_loc(node)
470
+ visit_all(node.comments)
560
471
 
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")
472
+ case node
473
+ when TStructProp
474
+ printt("prop")
475
+ when TStructConst
476
+ printt("const")
570
477
  end
571
- v.printn(" #{names.join(", ")}")
478
+ print(" :#{node.name}, #{node.type}")
479
+ default = node.default
480
+ print(", default: #{default}") if default
481
+ printn
572
482
  end
573
- end
574
483
 
575
- class Visibility
576
- extend T::Sig
484
+ sig { override.params(node: TEnum).void }
485
+ def visit_tenum(node)
486
+ visit_scope(node)
487
+ end
577
488
 
578
- sig { override.params(v: Printer).void }
579
- def accept_printer(v)
580
- print_blank_line_before(v)
489
+ sig { override.params(node: TEnumBlock).void }
490
+ def visit_tenum_block(node)
491
+ print_loc(node)
492
+ visit_all(node.comments)
581
493
 
582
- v.printl("# #{loc}") if loc && v.print_locs
583
- v.visit_all(comments)
584
- v.printl(visibility.to_s)
494
+ printl("enums do")
495
+ indent
496
+ visit_all(node.nodes)
497
+ dedent
498
+ printl("end")
585
499
  end
586
- end
587
500
 
588
- class Send
589
- extend T::Sig
501
+ sig { override.params(node: TypeMember).void }
502
+ def visit_type_member(node)
503
+ print_blank_line_before(node)
504
+ print_loc(node)
505
+ visit_all(node.comments)
590
506
 
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
604
- end
605
- v.printn
507
+ printl("#{node.name} = #{node.value}")
606
508
  end
607
- end
608
509
 
609
- class Arg
610
- extend T::Sig
510
+ sig { override.params(node: Helper).void }
511
+ def visit_helper(node)
512
+ print_blank_line_before(node)
513
+ print_loc(node)
514
+ visit_all(node.comments)
611
515
 
612
- sig { override.params(v: Printer).void }
613
- def accept_printer(v)
614
- v.print(value)
516
+ printl("#{node.name}!")
615
517
  end
616
- end
617
-
618
- class KwArg
619
- extend T::Sig
620
518
 
621
- sig { override.params(v: Printer).void }
622
- def accept_printer(v)
623
- v.print(keyword)
624
- v.print(": ")
625
- v.print(value)
519
+ sig { override.params(node: MixesInClassMethods).void }
520
+ def visit_mixes_in_class_methods(node)
521
+ visit_mixin(node)
626
522
  end
627
- end
628
523
 
629
- class Sig
630
- extend T::Sig
524
+ sig { override.params(node: Group).void }
525
+ def visit_group(node)
526
+ printn unless previous_node.nil?
527
+ visit_all(node.nodes)
528
+ end
631
529
 
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
530
+ sig { override.params(node: VisibilityGroup).void }
531
+ def visit_visibility_group(node)
532
+ self.in_visibility_group = true
533
+ if node.visibility.public?
534
+ printn unless previous_node.nil?
645
535
  else
646
- print_as_block(v)
536
+ visit(node.visibility)
537
+ printn
647
538
  end
539
+ visit_all(node.nodes)
540
+ self.in_visibility_group = false
648
541
  end
649
542
 
650
- sig { override.returns(T::Boolean) }
651
- def oneline?
652
- inline_params?
543
+ sig { override.params(node: RequiresAncestor).void }
544
+ def visit_requires_ancestor(node)
545
+ print_blank_line_before(node)
546
+ print_loc(node)
547
+ visit_all(node.comments)
548
+
549
+ printl("requires_ancestor { #{node.name} }")
653
550
  end
654
551
 
655
- sig { returns(T::Boolean) }
656
- def inline_params?
657
- params.all? { |p| p.comments.empty? }
552
+ sig { override.params(node: ConflictTree).void }
553
+ def visit_conflict_tree(node)
554
+ printl("<<<<<<< #{node.left_name}")
555
+ visit(node.left)
556
+ printl("=======")
557
+ visit(node.right)
558
+ printl(">>>>>>> #{node.right_name}")
658
559
  end
659
560
 
660
- private
561
+ sig { override.params(node: ScopeConflict).void }
562
+ def visit_scope_conflict(node)
563
+ print_blank_line_before(node)
564
+ print_loc(node)
565
+ visit_all(node.comments)
661
566
 
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
567
+ printl("<<<<<<< #{node.left_name}")
568
+ visit_scope_header(node.left)
569
+ printl("=======")
570
+ visit_scope_header(node.right)
571
+ printl(">>>>>>> #{node.right_name}")
572
+ visit_scope_body(node.left)
573
+ end
574
+
575
+ sig { params(node: Node).void }
576
+ def print_blank_line_before(node)
577
+ previous_node = self.previous_node
578
+ return unless previous_node
579
+ return if previous_node.is_a?(BlankLine)
580
+ return if oneline?(previous_node) && oneline?(node)
581
+
582
+ printn
671
583
  end
672
584
 
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}.")
585
+ sig { params(node: Node).void }
586
+ def print_loc(node)
587
+ loc = node.loc
588
+ printl("# #{loc}") if loc && print_locs
589
+ end
590
+
591
+ sig { params(node: Param, last: T::Boolean).void }
592
+ def print_param_comment_leading_space(node, last:)
593
+ printn
594
+ printt
595
+ print(" " * (node.name.size + 1))
596
+ print(" ") unless last
597
+ case node
598
+ when OptParam
599
+ print(" " * (node.value.size + 3))
600
+ when RestParam, KwParam, BlockParam
601
+ print(" ")
602
+ when KwRestParam
603
+ print(" ")
604
+ when KwOptParam
605
+ print(" " * (node.value.size + 2))
680
606
  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)
607
+ end
608
+
609
+ sig { params(node: SigParam, last: T::Boolean).void }
610
+ def print_sig_param_comment_leading_space(node, last:)
611
+ printn
612
+ printt
613
+ print(" " * (node.name.size + node.type.to_s.size + 3))
614
+ print(" ") unless last
615
+ end
616
+
617
+ sig { params(node: Node).returns(T::Boolean) }
618
+ def oneline?(node)
619
+ case node
620
+ when ScopeConflict
621
+ oneline?(node.left)
622
+ when Tree
623
+ node.comments.empty? && node.empty?
624
+ when Attr
625
+ node.comments.empty? && node.sigs.empty?
626
+ when Method
627
+ node.comments.empty? && node.sigs.empty? && node.params.all? { |p| p.comments.empty? }
628
+ when Sig
629
+ node.params.all? { |p| p.comments.empty? }
630
+ when NodeWithComments
631
+ node.comments.empty?
632
+ when VisibilityGroup
633
+ false
634
+ else
635
+ true
636
+ end
637
+ end
638
+
639
+ sig { params(node: Sig).void }
640
+ def print_sig_as_line(node)
641
+ printt("sig")
642
+ print("(:final)") if node.is_final
643
+ print(" { ")
644
+ sig_modifiers(node).each do |modifier|
645
+ print("#{modifier}.")
646
+ end
647
+ unless node.params.empty?
648
+ print("params(")
649
+ node.params.each_with_index do |param, index|
650
+ print(", ") if index > 0
651
+ visit(param)
686
652
  end
687
- v.print(").")
653
+ print(").")
688
654
  end
689
- if return_type && return_type != "void"
690
- v.print("returns(#{return_type})")
655
+ return_type = node.return_type
656
+ if node.return_type.to_s == "void"
657
+ print("void")
691
658
  else
692
- v.print("void")
659
+ print("returns(#{return_type})")
693
660
  end
694
- v.printn(" }")
661
+ printn(" }")
695
662
  end
696
663
 
697
- sig { params(v: Printer).void }
698
- def print_as_block(v)
699
- modifiers = sig_modifiers
664
+ sig { params(node: Sig).void }
665
+ def print_sig_as_block(node)
666
+ modifiers = sig_modifiers(node)
700
667
 
701
- v.printl("sig do")
702
- v.indent
668
+ printt("sig")
669
+ print("(:final)") if node.is_final
670
+ printn(" do")
671
+ indent
703
672
  if modifiers.any?
704
- v.printl(T.must(modifiers.first))
705
- v.indent
673
+ printl(T.must(modifiers.first))
674
+ indent
706
675
  modifiers[1..]&.each do |modifier|
707
- v.printl(".#{modifier}")
676
+ printl(".#{modifier}")
708
677
  end
709
678
  end
710
679
 
680
+ params = node.params
711
681
  if params.any?
712
- v.printt
713
- v.print(".") if modifiers.any?
714
- v.printn("params(")
715
- v.indent
682
+ printt
683
+ print(".") if modifiers.any?
684
+ printn("params(")
685
+ indent
716
686
  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|
687
+ printt
688
+ visit(param)
689
+ print(",") if pindex < params.size - 1
690
+
691
+ comment_lines = param.comments.flat_map { |comment| comment.text.lines.map(&:rstrip) }
692
+ comment_lines.each_with_index do |comment, cindex|
721
693
  if cindex == 0
722
- v.print(" ")
694
+ print(" ")
723
695
  else
724
- param.print_comment_leading_space(v, last: pindex == params.size - 1)
696
+ print_sig_param_comment_leading_space(param, last: pindex == params.size - 1)
725
697
  end
726
- v.print("# #{comment}")
698
+ print("# #{comment}")
727
699
  end
728
- v.printn
700
+ printn
729
701
  end
730
- v.dedent
731
- v.printt(")")
732
- end
733
- v.printt if params.empty?
734
- v.print(".") if modifiers.any? || params.any?
735
- if return_type && return_type != "void"
736
- v.print("returns(#{return_type})")
737
- else
738
- v.print("void")
702
+ dedent
703
+ printt(")")
739
704
  end
740
- v.printn
741
- v.dedent
742
- v.dedent if modifiers.any?
743
- v.printl("end")
744
- end
745
- end
746
-
747
- class SigParam
748
- extend T::Sig
749
-
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
705
+ printt if params.empty?
706
+ print(".") if modifiers.any? || params.any?
762
707
 
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")
708
+ return_type = node.return_type
709
+ if return_type.to_s == "void"
710
+ print("void")
711
+ else
712
+ print("returns(#{return_type})")
783
713
  end
784
- v.print(" :#{name}, #{type}")
785
- default = self.default
786
- v.print(", default: #{default}") if default
787
- v.printn
714
+ printn
715
+ dedent
716
+ dedent if modifiers.any?
717
+ printl("end")
788
718
  end
789
- end
790
-
791
- class TEnumBlock
792
- extend T::Sig
793
719
 
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")
720
+ sig { params(node: Sig).returns(T::Array[String]) }
721
+ def sig_modifiers(node)
722
+ modifiers = T.let([], T::Array[String])
723
+ modifiers << "abstract" if node.is_abstract
724
+ modifiers << "override" if node.is_override
725
+ modifiers << "overridable" if node.is_overridable
726
+ modifiers << "type_parameters(#{node.type_params.map { |type| ":#{type}" }.join(", ")})" if node.type_params.any?
727
+ modifiers << "checked(:#{node.checked})" if node.checked
728
+ modifiers
805
729
  end
806
730
  end
807
731
 
808
- class TypeMember
732
+ class File
809
733
  extend T::Sig
810
734
 
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}")
735
+ sig do
736
+ params(
737
+ out: T.any(IO, StringIO),
738
+ indent: Integer,
739
+ print_locs: T::Boolean,
740
+ max_line_length: T.nilable(Integer),
741
+ ).void
818
742
  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}!")
743
+ def print(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
744
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
745
+ p.visit_file(self)
831
746
  end
832
- end
833
747
 
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)
748
+ sig { params(indent: Integer, print_locs: T::Boolean, max_line_length: T.nilable(Integer)).returns(String) }
749
+ def string(indent: 0, print_locs: false, max_line_length: nil)
750
+ out = StringIO.new
751
+ print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
752
+ out.string
841
753
  end
842
754
  end
843
755
 
844
- class VisibilityGroup
756
+ class Node
845
757
  extend T::Sig
846
758
 
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
759
+ sig do
760
+ params(
761
+ out: T.any(IO, StringIO),
762
+ indent: Integer,
763
+ print_locs: T::Boolean,
764
+ max_line_length: T.nilable(Integer),
765
+ ).void
858
766
  end
859
-
860
- sig { override.returns(T::Boolean) }
861
- def oneline?
862
- false
767
+ def print(out: $stdout, indent: 0, print_locs: false, max_line_length: nil)
768
+ p = Printer.new(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
769
+ p.visit(self)
863
770
  end
864
- end
865
771
 
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} }")
772
+ sig { params(indent: Integer, print_locs: T::Boolean, max_line_length: T.nilable(Integer)).returns(String) }
773
+ def string(indent: 0, print_locs: false, max_line_length: nil)
774
+ out = StringIO.new
775
+ print(out: out, indent: indent, print_locs: print_locs, max_line_length: max_line_length)
776
+ out.string
876
777
  end
877
778
  end
878
779
  end