rbi 0.1.13 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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