prettyrb 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ea94d815e156b5294c602a74176b57ad6d7f368dbba00e9f5435fec4921c5bb5
4
- data.tar.gz: 5e58bd43571e3565dc88bf97fa5f36204f09edd68b7aa15190e1a58a2c9aa6b8
3
+ metadata.gz: 6cdbfca887166eb0de5bb781abd2203f4b888459a49a7248462898cb002a368c
4
+ data.tar.gz: 57e3b5eb278aeb405f19a4aa77ac2eec0cd6f3fc824fcb7da0780b9403b500bb
5
5
  SHA512:
6
- metadata.gz: 002b78f6a4ad5b5f94c05ac6fd78e685bddc9901b8dc6d29e5170da65933b3159c04c76d5d38a2a4ec645b5936bcb44cc8fae273a39dafbef8a4fd7d1d691100
7
- data.tar.gz: ba85b4cc39ace86efe1639e83e7e307ea2a7b22e0b8574fcc490e9ed848bb71dacab2040592729fe0b24c6962a9eab4031f5ccf96a78bcf35f30ebc5387642d6
6
+ metadata.gz: 83d80892f95ed1b7c081a2325f36aa5462bd065e4b8d6e636b65bf0cd77a2b7566da1c7f1d119995281da6dbaa33897ae76b41e0429a2d71276ac25ad5e1a2bc
7
+ data.tar.gz: 61a4e582bd7eb20f409b96fbb69f559d645bb9563d22cf07cd4b2a69e54664814e256cf8241a6fe7d8ab10f1e07bb81d7fb08d3239c726fcf2441bf25d9ca1d2
data/.gitignore CHANGED
@@ -6,3 +6,4 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ coverage
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.7.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- prettyrb (0.1.0)
4
+ prettyrb (0.2.0)
5
5
  parser (~> 2.7.0.5)
6
6
  thor
7
7
 
@@ -10,10 +10,15 @@ GEM
10
10
  specs:
11
11
  ast (2.4.0)
12
12
  byebug (11.1.1)
13
+ docile (1.3.2)
13
14
  minitest (5.14.0)
14
15
  parser (2.7.0.5)
15
16
  ast (~> 2.4.0)
16
17
  rake (12.3.3)
18
+ simplecov (0.18.5)
19
+ docile (~> 1.1)
20
+ simplecov-html (~> 0.11)
21
+ simplecov-html (0.12.2)
17
22
  thor (1.0.1)
18
23
 
19
24
  PLATFORMS
@@ -25,6 +30,7 @@ DEPENDENCIES
25
30
  minitest (~> 5.0)
26
31
  prettyrb!
27
32
  rake (~> 12.3.3)
33
+ simplecov (~> 0.18)
28
34
 
29
35
  BUNDLED WITH
30
36
  1.17.2
@@ -2,18 +2,15 @@ module Prettyrb
2
2
  MAX_LINE_LENGTH = 100
3
3
 
4
4
  class Formatter
5
- def self.for(node)
6
- end
7
-
8
5
  def initialize(code)
9
6
  @code = code
10
7
  end
11
8
 
12
9
  def format
13
- root_node, comments = Parser::CurrentRuby.parse_with_comments(@code)
10
+ root_node, _comments = Parser::CurrentRuby.parse_with_comments(@code)
14
11
 
15
12
  visitor = Visitor.new
16
- visitor.visit(root_node)
13
+ visitor.visit(root_node, nil)
17
14
 
18
15
  visitor.output
19
16
  end
@@ -1,3 +1,3 @@
1
1
  module Prettyrb
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -1,6 +1,37 @@
1
1
  module Prettyrb
2
2
  class Visitor
3
3
  MAX_LENGTH = 100
4
+ SINGLE_LINE = "single_line"
5
+ MULTI_LINE = "multi_line"
6
+
7
+ FNAMES = [
8
+ "..",
9
+ "|",
10
+ "ˆ",
11
+ "&",
12
+ "<=>",
13
+ "==",
14
+ "===",
15
+ "=˜",
16
+ ">",
17
+ ">=",
18
+ "<",
19
+ "<=",
20
+ "+",
21
+ "-",
22
+ "*",
23
+ "/",
24
+ "%",
25
+ "**",
26
+ "<<",
27
+ ">>",
28
+ "~",
29
+ "+@",
30
+ "-@",
31
+ "[]",
32
+ "[]="
33
+ ]
34
+ VALID_SYMBOLS = FNAMES + ["!", "!="]
4
35
 
5
36
  attr_reader :output
6
37
 
@@ -10,7 +41,8 @@ module Prettyrb
10
41
 
11
42
  @newline = true
12
43
  @multiline_conditional_level = 0
13
- @__current_node = nil
44
+ @previous_node = nil
45
+ @current_line = ''
14
46
  end
15
47
 
16
48
  def indents
@@ -27,10 +59,14 @@ module Prettyrb
27
59
 
28
60
  def indent(&block)
29
61
  old_indent_level = @indent_level
62
+ old_previous_node = @previous_node
30
63
 
64
+ @previous_node = nil
31
65
  @indent_level += 1
32
- yield
66
+ value = yield
33
67
  @indent_level = old_indent_level
68
+ @previous_node = old_previous_node
69
+ value
34
70
  end
35
71
 
36
72
  def multiline_conditional_level
@@ -48,7 +84,9 @@ module Prettyrb
48
84
  def capture(&block)
49
85
  old_newline = @newline
50
86
  old_output = @output
87
+ old_current_line = @current_line
51
88
 
89
+ @current_line = ""
52
90
  @output = ""
53
91
 
54
92
  yield
@@ -56,109 +94,115 @@ module Prettyrb
56
94
  @output.tap do |output|
57
95
  @output = old_output
58
96
  @newline = old_newline
97
+ @current_line = old_current_line
59
98
  end
60
99
  end
61
100
 
62
101
  def newline
63
102
  @output << "\n"
64
103
  @newline = true
104
+ @current_line = ''
65
105
  end
66
106
 
67
107
  def write(input)
68
108
  if @newline
69
109
  @output << indents
110
+ @current_line << indents
70
111
  end
71
112
  @newline = false
72
113
  @output << input
114
+ @current_line << input
73
115
  end
74
116
 
75
- def visit(node)
76
- @previous_node = @__current_node
77
- @__current_node = node
78
-
117
+ def visit(node, parent_node)
79
118
  case node.type
80
119
  when :module
81
120
  write "module "
82
- visit node.children[0]
121
+ visit node.children[0], node
83
122
  newline
84
123
 
85
124
  indent do
86
- visit node.children[1]
125
+ visit node.children[1], node
87
126
  end
88
127
 
89
128
  write "end"
90
129
  newline
91
130
  when :class
131
+ newline unless @previous_node.nil?
92
132
  write "class "
93
- visit node.children[0]
133
+ visit node.children[0], node
94
134
  newline
95
135
  # TODO handle children[1] which is inheritance
96
136
 
97
137
  indent do
98
- visit node.children[2]
138
+ visit node.children[2], node
99
139
  end
100
140
 
101
141
  newline unless @output.end_with?("\n")
102
142
  write "end"
103
143
  newline
104
144
  when :const
145
+ visit node.children[0] if node.children[0]
105
146
  write node.children[1].to_s
106
147
  when :casgn
107
148
  write node.children[1].to_s
108
149
  write " = "
109
- visit node.children[2]
150
+ visit node.children[2], node
110
151
  when :block
111
- visit node.children[0]
152
+ newline unless @previous_node.nil?
153
+ visit node.children[0], node
112
154
  write " do"
113
155
 
114
156
  if node.children[1].children.length > 0
115
157
  write " |"
116
- visit node.children[1]
158
+ visit node.children[1], node
117
159
  write "|"
118
160
  end
119
161
 
120
162
  newline
121
163
 
122
164
  indent do
123
- visit node.children[2]
165
+ visit node.children[2], node
124
166
  end
125
167
 
126
168
  newline
127
169
 
128
170
  write "end"
129
- newline
130
171
  when :send
131
- if [:!=, :==, :+, :-, :*, :/, :<<].include?(node.children[1])
132
- visit node.children[0]
133
- write " "
134
- write node.children[1].to_s
135
- write " "
136
- visit node.children[2]
137
- elsif node.children[1] == :[]
138
- visit node.children[0]
139
- write "["
140
- visit node.children[2]
141
- write "]"
142
- elsif node.children[1] == :!
143
- write "!"
144
- visit node.children[0]
145
- elsif node.children[0] == nil
172
+ newline if parent_node&.type == :begin && @previous_node && @previous_node&.type != :send
173
+ if node.children[0] == nil
146
174
  write node.children[1].to_s
147
175
 
148
176
  # TODO possible > MAX via `capture`
149
177
  arguments = node.children[2..-1]
150
178
  if arguments.length > 0
151
179
  write "("
152
- arguments.each_with_index do |node, index|
153
- visit node
154
- write ", " unless index == arguments.length - 1
180
+ indent do
181
+ if splittable_separated_map(node, arguments) == MULTI_LINE
182
+ newline
183
+ end
155
184
  end
156
185
  write ")"
157
186
  end
158
187
 
159
- newline if @previous_node.type == :class
188
+ newline if @previous_node&.type == :class
189
+ elsif node.children[1] == :[]
190
+ visit node.children[0], node
191
+ write "["
192
+ visit node.children[2], node
193
+ write "]"
194
+ elsif node.children[1] == :!
195
+ write "!"
196
+ visit node.children[0], node
197
+ elsif !node.children[1].to_s.match?(/[a-zA-Z]/)
198
+ # if [:!=, :==, :+, :-, :*, :/, :<<, :<].include?(node.children[1])
199
+ visit node.children[0], node
200
+ write " "
201
+ write node.children[1].to_s
202
+ write " "
203
+ visit node.children[2], node
160
204
  else
161
- visit node.children[0]
205
+ visit node.children[0], node
162
206
  write "."
163
207
  write node.children[1].to_s
164
208
 
@@ -166,123 +210,166 @@ module Prettyrb
166
210
  arguments = node.children[2..-1]
167
211
  if arguments.length > 0
168
212
  write "("
169
- arguments.each_with_index do |node, index|
170
- visit node
213
+ arguments.each_with_index do |child_node, index|
214
+ visit child_node, node
171
215
  write ", " unless index == arguments.length - 1
172
216
  end
173
217
  write ")"
174
218
  end
175
219
  end
176
220
  when :if
177
- write "if"
178
- indent do
221
+ newline if @previous_node && parent_node&.type != :if
222
+
223
+ if parent_node&.type == :if
224
+ conditions_node = node.children[0]
225
+ body_node = node.children[1]
226
+ else_body_node = node.children[2]
227
+
228
+ write "elsif"
229
+
179
230
  conditions = capture do
180
- visit node.children[0]
231
+ visit conditions_node, node
181
232
  end
182
233
 
183
234
  if !conditions.start_with?("\n")
184
235
  write(" ")
185
236
  end
237
+
186
238
  write conditions
239
+ newline
240
+
241
+ if body_node.type == :if
242
+ visit body_node, node
243
+ else
244
+ indent do
245
+ visit body_node, node
246
+ end
247
+ end
187
248
 
188
249
  newline
189
250
 
190
- if node.children[1]
191
- visit node.children[1]
251
+ if else_body_node&.type == :if
252
+ visit else_body_node, node
253
+ elsif else_body_node
254
+ write "else"
192
255
  newline
256
+ indent do
257
+ visit else_body_node, node
258
+ end
193
259
  end
194
- end
260
+ else
261
+ is_unless = node.children[1].nil? && node.children[2]&.type != :if
262
+ conditions = node.children[0]
195
263
 
196
- if node.children[2]
197
- if node.children[2] == :if
198
- write "elsif"
199
- visit node.children[2]
264
+ if is_unless
265
+ write "unless"
266
+ body_node = node.children[2]
267
+ else_body_node = nil
200
268
  else
201
- write "else"
269
+ write "if" unless parent_node&.type == :if
270
+ body_node = node.children[1]
271
+ else_body_node = node.children[2]
272
+ end
273
+
274
+ indent do
275
+ conditions = capture do
276
+ visit node.children[0], node
277
+ end
278
+
279
+ if !conditions.start_with?("\n")
280
+ write(" ")
281
+ end
282
+
283
+ write conditions
202
284
  newline
203
285
 
204
- indent do
205
- visit node.children[2]
286
+ if body_node
287
+ visit body_node, node
288
+ newline
206
289
  end
207
290
  end
208
- newline
209
- end
210
291
 
211
- write "end"
292
+ if else_body_node
293
+ if else_body_node.type == :if
294
+ visit else_body_node, node
295
+ else
296
+ write "else"
297
+ newline
298
+
299
+ indent do
300
+ visit else_body_node, node
301
+ end
302
+ end
303
+ newline
304
+ end
305
+
306
+ write "end" unless parent_node&.type == :if
307
+ end
212
308
  when :true
213
309
  write "true"
214
310
  when :false
215
311
  write "false"
216
312
  when :nil
217
313
  write "nil"
218
- when :int
314
+ when :int, :float
219
315
  write node.children[0].to_s
220
316
  when :array
221
- possible_output = capture do
222
- write "["
223
- node.children.each_with_index do |child, index|
224
- visit(child)
225
- write ", " unless index == node.children.length - 1
226
- end
227
- write "]"
228
- end
229
-
230
- if possible_output.length > MAX_LENGTH
317
+ if node.children[0].type == :splat
318
+ visit node.children[0], node
319
+ else
231
320
  write "["
232
- newline
233
-
234
321
  indent do
235
- node.children.map do |child|
236
- visit(child)
237
- write ","
238
- newline
239
- end
322
+ result = splittable_separated_map(node, node.children)
323
+ newline if result == MULTI_LINE
240
324
  end
241
-
242
325
  write "]"
243
- else
244
- write possible_output.lstrip
245
326
  end
246
327
  when :str
247
328
  write '"'
248
- write node.children[0].gsub("\n", "\\n")
329
+ write format_string(node)
249
330
  write '"'
250
331
  when :dstr
251
332
  write "\""
252
333
  node.children.map do |child|
253
334
  if child.type == :str
254
- write child.children[0]
255
- write child.children[0].gsub("\n", "\\n")
335
+ write child.children[0] # TODO better handling
256
336
  else
257
337
  write '#{'
258
- visit child
338
+ visit child, node
259
339
  write '}'
260
340
  end
261
341
  end
262
342
  write "\""
263
343
  when :begin
264
- if @previous_node.type == :or || @previous_node.type == :and
344
+ if @previous_node&.type == :or || @previous_node&.type == :and
265
345
  write "("
266
- node.children.map { |child| visit child }
346
+ @previous_node = nil
347
+ node.children.map do |child|
348
+ visit child, node
349
+ @previous_node = child
350
+ end
351
+ @previous_node = nil
267
352
  write ")"
268
353
  else
354
+ @previous_node = nil
269
355
  node.children.each_with_index do |child, index|
270
- visit child
356
+ visit child, node
271
357
  newline unless index == node.children.length - 1
358
+ @previous_node = child
272
359
  end
360
+ @previous_node = nil
273
361
  end
274
362
  when :or, :and
363
+ write "(" if parent_node&.type == :begin
275
364
  possible_output = capture do
276
- visit node.children[0]
365
+ visit node.children[0], node
277
366
  if node.type == :or
278
367
  write " || "
279
368
  elsif node.type == :and
280
369
  write " && "
281
370
  end
282
- visit node.children[1]
371
+ visit node.children[1], node
283
372
  end
284
-
285
-
286
373
  if @multiline_conditional_level > 0 # TODO track and check currently level
287
374
  write_multiline_conditional(node)
288
375
  elsif possible_output.length > MAX_LENGTH
@@ -298,41 +385,72 @@ module Prettyrb
298
385
  else
299
386
  write possible_output
300
387
  end
301
- when :def
302
- write "def "
303
- write node.children[0].to_s
304
- if node.children[1].children.length > 0
388
+ write ")" if parent_node&.type == :begin
389
+ when :def, :defs
390
+ newline unless @previous_node&.type.nil?
391
+ if node.type == :defs
392
+ write "def self."
393
+ method_name_node = node.children[1]
394
+ arguments_node = node.children[2]
395
+ body_node = node.children[3]
396
+ else
397
+ write "def "
398
+ method_name_node = node.children[0]
399
+ arguments_node = node.children[1]
400
+ body_node = node.children[2]
401
+ end
402
+
403
+ write method_name_node.to_s
404
+
405
+ if arguments_node.children.length > 0 || arguments_node.type != :args
305
406
  write "("
306
- visit node.children[1]
407
+ visit arguments_node, node
307
408
  write ")"
308
409
  end
309
410
  newline
310
411
 
311
- indent do
312
- visit node.children[2]
412
+ if body_node
413
+ indent do
414
+ visit body_node, node
415
+ end
416
+
417
+ newline
313
418
  end
314
419
 
315
- newline
316
420
  write "end"
317
421
  when :args
318
422
  node.children.each_with_index do |child, index|
319
- visit child
423
+ visit child, node
320
424
  write ", " unless index == node.children.length - 1
321
425
  end
322
426
  when :arg
323
427
  write node.children[0].to_s
324
- when :lvar
428
+ when :lvar, :gvar
325
429
  write node.children[0].to_s
326
430
  when :self
327
431
  "self"
328
432
  when :sym
329
- write ":"
330
- write node.children[0].to_s
433
+ content = node.children[0].to_s
434
+
435
+ # TODO handle already quoted symbols
436
+ if !VALID_SYMBOLS.include?(content) && !content.match?(/\A[a-zA-Z_]{1}[a-zA-Z0-9_!?]*\z/)
437
+ content = "'#{content}'"
438
+ write ":"
439
+ write content
440
+ else
441
+ if parent_node&.type == :pair
442
+ write content
443
+ write ": "
444
+ else
445
+ write ":"
446
+ write content
447
+ end
448
+ end
331
449
  when :return
332
450
  write "return"
333
451
 
334
452
  possible_output = capture do
335
- visit node.children[0]
453
+ visit node.children[0], node
336
454
  end
337
455
 
338
456
  if !possible_output.start_with?("\n")
@@ -340,63 +458,193 @@ module Prettyrb
340
458
  end
341
459
  when :case
342
460
  write "case "
343
- visit node.children[0]
461
+ visit node.children[0], node
344
462
  newline
345
463
  node.children[1..-1].each do |child|
346
- if child.type != :when
464
+ if child && child.type != :when
347
465
  write "else"
348
466
  newline
349
467
 
350
468
  indent do
351
- visit child
469
+ visit child, node
352
470
  end
353
471
  else
354
- visit child
355
- newline
472
+ if child
473
+ visit child, node
474
+ newline
475
+ end
356
476
  end
357
477
  end
358
478
  write "end"
479
+ when :regexp
480
+ write '/'
481
+ node.children[0...-1].map do |child_node|
482
+ if child_node.type == :str
483
+ write child_node.children[0].to_s
484
+ else
485
+ visit child_node, node
486
+ end
487
+ end
488
+ write '/'
489
+ visit node.children[-1], node
490
+ when :regopt
491
+ node.children.map { |child| child.to_s }.join('')
359
492
  when :when
360
- write "when "
361
- visit node.children[0]
493
+ write "when"
494
+
495
+ indent do
496
+ splittable_separated_map(node, node.children[0..-2], skip_last_multiline_separator: true, write_space_if_single_line: true)
497
+ end
498
+
362
499
  newline
363
500
  indent do
364
- visit node.children[1]
501
+ visit node.children[-1], node
502
+ end
503
+ when :or_asgn, :and_asgn
504
+ newline if @previous_node && ![:ivasgn, :or_asgn, :lvasgn, :op_asgn].include?(@previous_node.type)
505
+ visit node.children[0], node
506
+ if node.type == :or_asgn
507
+ write " ||= " # TODO handle long lines here too
508
+ elsif node.type == :and_asgn
509
+ write " &&= " # TODO handle long lines here too
365
510
  end
366
- when :or_asgn
367
- visit node.children[0]
368
- write " ||= " # TODO handle long lines here too
369
- visit node.children[1]
511
+ visit node.children[1], node
370
512
  when :ivasgn
513
+ newline if @previous_node && ![:ivasgn, :or_asgn, :lvasgn, :op_asgn].include?(@previous_node.type)
371
514
  write node.children[0].to_s
515
+
516
+ if node.children[1]
517
+ write " = "
518
+ visit node.children[1], node
519
+ end
520
+ when :csend
521
+ visit node.children[0], node
522
+ write "&."
523
+ write node.children[1].to_s
372
524
  when :ivar
373
525
  write node.children[0].to_s
374
526
  when :blockarg
527
+ write '&'
375
528
  write node.children[0].to_s
376
529
  when :yield
530
+ newline unless @previous_node.nil? || [:op_asgn, :lvasgn, :or_asgn, :and_asgn].include?(@previous_node.type)
377
531
  write "yield"
378
532
  when :op_asgn
379
- visit node.children[0]
533
+ newline if @previous_node && ![:ivasgn, :or_asgn, :lvasgn, :op_asgn].include?(@previous_node.type)
534
+ visit node.children[0], node
380
535
  write " "
381
536
  write node.children[1].to_s
537
+ write "="
382
538
  write " "
383
- visit node.children[2]
539
+ visit node.children[2], node
384
540
  when :lvasgn
541
+ newline if @previous_node && ![:ivasgn, :or_asgn, :lvasgn, :op_asgn].include?(@previous_node.type)
385
542
  write node.children[0].to_s
386
- write " = "
387
-
388
- visit node.children[1]
543
+ if node.children[1]
544
+ write " = "
545
+ visit node.children[1], node
546
+ end
389
547
  when :irange
390
- visit node.children[0]
548
+ visit node.children[0], node unless node.children[0].nil?
391
549
  write ".."
392
- visit node.children[1]
550
+ visit node.children[1], node unless node.children[1].nil?
551
+ when :erange
552
+ visit node.children[0], node unless node.children[0].nil?
553
+ write "..."
554
+ visit node.children[1], node unless node.children[1].nil?
555
+ when :hash
556
+ if node.children.length == 0
557
+ write "{}"
558
+ else
559
+ write "{"
560
+
561
+ result = indent do
562
+ splittable_separated_map(node, node.children, write_space_if_single_line: true)
563
+ end
564
+
565
+ if result == MULTI_LINE
566
+ newline
567
+ write "}"
568
+ else
569
+ write " }"
570
+ end
571
+ end
572
+ when :pair
573
+ visit node.children[0], node
574
+ if node.children[0].type != :sym
575
+ write " => "
576
+ end
577
+ visit node.children[1], node
578
+ when :splat
579
+ write "*"
580
+ visit node.children[0], node
581
+ when :defined?
582
+ write "defined?("
583
+ visit node.children[0], node
584
+ write ")"
585
+ when :complex,
586
+ :dsym,
587
+ :xstr,
588
+ :'nth-ref',
589
+ :'back-ref',
590
+ :gvasgn,
591
+ :mlhs,
592
+ :procarg0,
593
+ :shadowarg
594
+ raise "implement me, #{node.inspect}"
595
+ when :sclass
596
+ write "class << "
597
+ visit node.children[0], node
598
+ newline
599
+
600
+ indent do
601
+ visit node.children[1], node if node.children[1]
602
+ end
603
+
604
+ newline if node.children[1]
605
+ write "end"
606
+ when :undef
607
+ write "undef "
608
+ node.children.each_with_index do |child_node, index|
609
+ visit child_node, node
610
+ write ", " unless index == node.children.length - 1
611
+ end
612
+ when :alias
613
+ write 'alias '
614
+ visit node.children[0], node
615
+ write ' '
616
+ visit node.children[1], node
617
+ when :restarg
618
+ write "*"
619
+ write node.children[0].to_s
620
+ when :optarg
621
+ write node.children[0].to_s
622
+ write " = "
623
+ visit node.children[1], node
624
+ when :kwsplat
625
+ write "**"
626
+ visit node.children[0], node
627
+ when :kwarg
628
+ write node.children[0].to_s
629
+ write ":"
630
+ when :forward_args, :forwarded_args
631
+ write "..."
632
+ when :kwoptarg
633
+ write node.children[0].to_s
634
+ write ": "
635
+ visit node.children[1], node
636
+ when :kwrestarg
637
+ write "**"
638
+ write node.children[0].to_s if node.children[0]
639
+ when :kwnilarg
640
+ write "**nil"
393
641
  else
394
642
  raise "unhandled node type `#{node.type}`\nnode: #{node}"
395
643
  end
396
644
  end
397
645
 
398
646
  def write_multiline_conditional(node)
399
- visit node.children[0]
647
+ visit node.children[0], node
400
648
 
401
649
  if node.type == :or
402
650
  write " ||"
@@ -406,7 +654,40 @@ module Prettyrb
406
654
 
407
655
  newline
408
656
 
409
- visit node.children[1]
657
+ visit node.children[1], node
658
+ end
659
+
660
+ def format_string(string)
661
+ raw_content = string.loc.expression.source
662
+ content = raw_content[1...-1]
663
+
664
+ if raw_content[0] == "'"
665
+ content.gsub('"', '\\"').gsub('#{', '\\#{')
666
+ else
667
+ content.gsub("\\", "\\\\")
668
+ end
669
+ end
670
+
671
+ def splittable_separated_map(current_node, mappable, separator: ", ", skip_last_multiline_separator: false, write_space_if_single_line: false)
672
+ one_line = capture do
673
+ mappable.each_with_index do |child_node, index|
674
+ visit child_node, current_node
675
+ write separator unless index == mappable.length - 1
676
+ end
677
+ end
678
+
679
+ if @current_line.length + one_line.length > MAX_LENGTH
680
+ mappable.each_with_index do |child_node, index|
681
+ newline
682
+ visit child_node, current_node
683
+ write separator.rstrip unless skip_last_multiline_separator && index == mappable.length - 1
684
+ end
685
+ MULTI_LINE
686
+ else
687
+ write ' ' if write_space_if_single_line
688
+ write one_line
689
+ SINGLE_LINE
690
+ end
410
691
  end
411
692
  end
412
693
  end
data/prettyrb.gemspec CHANGED
@@ -39,4 +39,5 @@ Gem::Specification.new do |spec|
39
39
  spec.add_development_dependency "rake", "~> 12.3.3"
40
40
  spec.add_development_dependency "minitest", "~> 5.0"
41
41
  spec.add_development_dependency "byebug", "~> 11.1"
42
+ spec.add_development_dependency "simplecov", "~> 0.18"
42
43
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prettyrb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Williams
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-29 00:00:00.000000000 Z
11
+ date: 2020-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '11.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.18'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.18'
97
111
  description: Ruby source code formatter
98
112
  email:
99
113
  - blake@blakewilliams.me
@@ -104,6 +118,7 @@ extra_rdoc_files: []
104
118
  files:
105
119
  - ".github/workflows/ruby.yml"
106
120
  - ".gitignore"
121
+ - ".ruby-version"
107
122
  - ".travis.yml"
108
123
  - Gemfile
109
124
  - Gemfile.lock
@@ -139,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
139
154
  - !ruby/object:Gem::Version
140
155
  version: '0'
141
156
  requirements: []
142
- rubygems_version: 3.0.1
157
+ rubygems_version: 3.1.2
143
158
  signing_key:
144
159
  specification_version: 4
145
160
  summary: Ruby source code formatter