to_source 0.2.16 → 0.2.17

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.
Files changed (42) hide show
  1. data/.rspec +1 -0
  2. data/Changelog.md +34 -1
  3. data/bin/to_source +2 -8
  4. data/config/flay.yml +1 -1
  5. data/config/site.reek +5 -0
  6. data/lib/to_source.rb +17 -3
  7. data/lib/to_source/emitter.rb +5 -1
  8. data/lib/to_source/emitter/alias.rb +23 -0
  9. data/lib/to_source/emitter/assignment.rb +23 -84
  10. data/lib/to_source/emitter/assignment/attribute.rb +52 -0
  11. data/lib/to_source/emitter/assignment/constant.rb +26 -0
  12. data/lib/to_source/emitter/assignment/element.rb +124 -0
  13. data/lib/to_source/emitter/assignment/variable.rb +29 -0
  14. data/lib/to_source/emitter/assignment_operator.rb +54 -0
  15. data/lib/to_source/emitter/back_ref.rb +23 -0
  16. data/lib/to_source/emitter/binary_operator_method.rb +38 -2
  17. data/lib/to_source/emitter/collect_splat.rb +50 -0
  18. data/lib/to_source/emitter/concat_arguments.rb +16 -1
  19. data/lib/to_source/emitter/element_reference.rb +1 -1
  20. data/lib/to_source/emitter/flip.rb +61 -0
  21. data/lib/to_source/emitter/for.rb +98 -0
  22. data/lib/to_source/emitter/iter.rb +23 -1
  23. data/lib/to_source/emitter/literal.rb +1 -18
  24. data/lib/to_source/emitter/literal/dynamic.rb +0 -23
  25. data/lib/to_source/emitter/literal/dynamic/regexp.rb +69 -0
  26. data/lib/to_source/emitter/literal/regexp.rb +27 -0
  27. data/lib/to_source/emitter/literal/regexp/options.rb +71 -0
  28. data/lib/to_source/emitter/match.rb +21 -0
  29. data/lib/to_source/emitter/match2.rb +25 -0
  30. data/lib/to_source/emitter/multiple_assignment.rb +43 -4
  31. data/lib/to_source/emitter/op_assign1.rb +37 -5
  32. data/lib/to_source/emitter/push_args.rb +42 -0
  33. data/lib/to_source/emitter/send.rb +21 -16
  34. data/lib/to_source/emitter/splat.rb +40 -1
  35. data/lib/to_source/emitter/static.rb +32 -0
  36. data/lib/to_source/emitter/toplevel.rb +2 -1
  37. data/lib/to_source/emitter/undef.rb +26 -0
  38. data/spec/unit/to_source/class_methods/run_spec.rb +245 -20
  39. data/to_source.gemspec +1 -1
  40. metadata +18 -4
  41. data/lib/to_source/emitter/attribute_assignment.rb +0 -28
  42. data/lib/to_source/emitter/element_assignment.rb +0 -29
@@ -11,6 +11,7 @@ module ToSource
11
11
  private
12
12
 
13
13
  delegate(:block, :name, :receiver)
14
+ predicate(:block)
14
15
 
15
16
  # Perform dispatch
16
17
  #
@@ -19,14 +20,32 @@ module ToSource
19
20
  # @api private
20
21
  #
21
22
  def dispatch
22
- if unary_operator_method?
23
- run(UnaryOperatorMethod, node)
23
+ case
24
+ when unary_operator_method?
25
+ run(UnaryOperatorMethod)
26
+ return
27
+ when for?
28
+ run(For)
24
29
  return
25
30
  end
26
31
 
27
32
  normal_dispatch
28
33
  end
29
34
 
35
+ # Test for for node
36
+ #
37
+ # @return [true]
38
+ # if for node is detected
39
+ #
40
+ # @return [false]
41
+ # otherwise
42
+ #
43
+ # @api private
44
+ #
45
+ def for?
46
+ block.kind_of?(Rubinius::AST::For19)
47
+ end
48
+
30
49
  # Test for unary operator method
31
50
  #
32
51
  # @return [true]
@@ -54,20 +73,6 @@ module ToSource
54
73
  emit_block
55
74
  end
56
75
 
57
- # Test for block
58
- #
59
- # @return [true]
60
- # if block is present
61
- #
62
- # @return [false]
63
- # otherwise
64
- #
65
- # @api private
66
- #
67
- def block?
68
- !!block
69
- end
70
-
71
76
  # Test for block pass
72
77
  #
73
78
  # @return [true]
@@ -8,6 +8,8 @@ module ToSource
8
8
 
9
9
  private
10
10
 
11
+ delegate(:value)
12
+
11
13
  # Perform dispatch
12
14
  #
13
15
  # @return [undefined]
@@ -16,9 +18,46 @@ module ToSource
16
18
  #
17
19
  def dispatch
18
20
  emit('*')
19
- visit(node.value)
21
+ emit_value
22
+ end
23
+
24
+ # Emit value
25
+ #
26
+ # @return [undefined]
27
+ #
28
+ # @api private
29
+ #
30
+ def emit_value
31
+ visit(value)
20
32
  end
21
33
 
34
+ # Emitter for empty splat
35
+ class Empty < self
36
+
37
+ handle(Rubinius::AST::EmptySplat)
38
+
39
+ private
40
+
41
+ # Perform dispatch
42
+ #
43
+ # @return [undefined]
44
+ #
45
+ # @api private
46
+ #
47
+ def dispatch
48
+ emit('*')
49
+ end
50
+
51
+ # Return value
52
+ #
53
+ # @return [nil]
54
+ #
55
+ # @api private
56
+ #
57
+ def value
58
+ end
59
+
60
+ end
22
61
  end
23
62
  end
24
63
  end
@@ -39,6 +39,14 @@ module ToSource
39
39
 
40
40
  end
41
41
 
42
+ # Emitter for encoding node
43
+ class Encoding < self
44
+
45
+ handle(Rubinius::AST::Encoding)
46
+ SYMBOL = :__ENCODING__
47
+
48
+ end
49
+
42
50
  # Emitter for file node
43
51
  class File < self
44
52
 
@@ -47,6 +55,30 @@ module ToSource
47
55
 
48
56
  end
49
57
 
58
+ # Emitter for redo node
59
+ class Redo < self
60
+
61
+ handle(Rubinius::AST::Redo)
62
+ SYMBOL = :redo
63
+
64
+ end
65
+
66
+ # Emitter for retry node
67
+ class Retry < self
68
+
69
+ handle(Rubinius::AST::Retry)
70
+ SYMBOL = :retry
71
+
72
+ end
73
+
74
+ # Emitter for rubinius specific type constant
75
+ class TypeConstant < self
76
+
77
+ handle(Rubinius::AST::TypeConstant)
78
+ SYMBOL = 'Rubinius::Type'
79
+
80
+ end
81
+
50
82
  end
51
83
  end
52
84
  end
@@ -1,9 +1,10 @@
1
1
  module ToSource
2
2
  class Emitter
3
- # Emitter for toplevel constants or classes
3
+ # Emitter for toplevel constants, classes and modules
4
4
  class Toplevel < self
5
5
 
6
6
  handle(Rubinius::AST::ToplevelClassName)
7
+ handle(Rubinius::AST::ToplevelModuleName)
7
8
  handle(Rubinius::AST::ToplevelConstant)
8
9
 
9
10
  private
@@ -0,0 +1,26 @@
1
+ module ToSource
2
+ class Emitter
3
+
4
+ # Emitter for undef nodes
5
+ class Undef < self
6
+
7
+ handle(Rubinius::AST::Undef)
8
+ SYMBOL = :undef
9
+
10
+ private
11
+
12
+ # Perform dispatch
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ emit(:undef)
20
+ space
21
+ visit(node.name)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -48,10 +48,10 @@ describe ToSource,'.to_source' do
48
48
  it_should_behave_like 'a source generation method'
49
49
  end
50
50
 
51
- def self.assert_converts(converted, source)
52
- let(:node) { source.to_ast }
53
- let(:source) { source }
54
- let(:expected_source) { converted }
51
+ def self.assert_converts(target, original)
52
+ let(:node) { original.to_ast }
53
+ let(:source) { original }
54
+ let(:expected_source) { target }
55
55
  it_should_behave_like 'a source generation method'
56
56
  end
57
57
 
@@ -192,7 +192,27 @@ describe ToSource,'.to_source' do
192
192
 
193
193
 
194
194
  context 'element assignment' do
195
- assert_source 'array[index] = value'
195
+ context 'simpe' do
196
+ assert_source 'array[index] = value'
197
+ end
198
+
199
+ context 'splat index' do
200
+ assert_source 'array[*index] = value'
201
+ end
202
+
203
+ context 'with assignment operator' do
204
+ %w(+ - * / % & | || &&).each do |operator|
205
+ context "with #{operator}" do
206
+ context 'explicit index' do
207
+ assert_source "array[index] #{operator}= 2"
208
+ end
209
+
210
+ context 'implicit index' do
211
+ assert_source "array[] #{operator}= 2"
212
+ end
213
+ end
214
+ end
215
+ end
196
216
  end
197
217
 
198
218
  context 'multiple assignment' do
@@ -200,10 +220,34 @@ describe ToSource,'.to_source' do
200
220
  assert_source 'a, b = 1, 2'
201
221
  end
202
222
 
223
+ context 'to local and splat var' do
224
+ assert_source 'a, *foo = 1, 2'
225
+ end
226
+
227
+ context 'with empty splat' do
228
+ assert_source 'a, * = 1, 2'
229
+ end
230
+
231
+ context 'to splat var' do
232
+ assert_source '*foo = 1, 2'
233
+ end
234
+
203
235
  context 'to instance variable' do
204
236
  assert_source '@a, @b = 1, 2'
205
237
  end
206
238
 
239
+ context 'to attribute reference' do
240
+ assert_source 'a.foo, a.bar = 1, 2'
241
+ end
242
+
243
+ context 'to element' do
244
+ assert_source 'a[0], a[1] = 1, 2'
245
+ end
246
+
247
+ context 'to spat element' do
248
+ assert_source 'a[*foo], a[1] = 1, 2'
249
+ end
250
+
207
251
  context 'to class variable' do
208
252
  assert_source '@@a, @@b = 1, 2'
209
253
  end
@@ -247,6 +291,10 @@ describe ToSource,'.to_source' do
247
291
  assert_source '$1'
248
292
  end
249
293
 
294
+ context 'on back ref global variable' do
295
+ assert_source '$`'
296
+ end
297
+
250
298
  context 'on global variable' do
251
299
  assert_source '$foo'
252
300
  end
@@ -269,6 +317,10 @@ describe ToSource,'.to_source' do
269
317
  end
270
318
 
271
319
  context 'literal' do
320
+ context 'number' do
321
+ assert_source '12379813738877118345'
322
+ end
323
+
272
324
  context 'fixnum' do
273
325
  assert_source '1'
274
326
  end
@@ -314,9 +366,17 @@ describe ToSource,'.to_source' do
314
366
  assert_source '[1, 2, 3]'
315
367
  end
316
368
 
317
- context 'with splat' do
369
+ context 'with splat in the end' do
318
370
  assert_source '[1, *foo]'
319
371
  end
372
+
373
+ context 'with splat in the beginning' do
374
+ assert_source '[*foo, 1]'
375
+ end
376
+
377
+ context 'with splat in the beginning and end' do
378
+ assert_source '[*foo, *baz]'
379
+ end
320
380
  end
321
381
 
322
382
  context 'empty hash' do
@@ -340,6 +400,42 @@ describe ToSource,'.to_source' do
340
400
  assert_source '/.*/'
341
401
  end
342
402
 
403
+ context 'with character classes' do
404
+ assert_source %q(/[^-+',.\/:@[:alnum:]\[\]\x80-\xff]+/)
405
+ end
406
+
407
+ context 'with options' do
408
+
409
+ context 'case insensitive' do
410
+ assert_source '//i'
411
+ end
412
+
413
+ context 'ignore comments and whitespace' do
414
+ assert_source '//x'
415
+ end
416
+
417
+ context 'assci encoding' do
418
+ assert_source '//n'
419
+ end
420
+
421
+ context 'windows-31j encoding' do
422
+ assert_source '//s'
423
+ end
424
+
425
+ context 'euc-jp encoding' do
426
+ assert_source '//e'
427
+ end
428
+
429
+ context 'utf-8 encoding' do
430
+ assert_source '//u'
431
+ end
432
+
433
+ context 'multiline' do
434
+ assert_source '//m'
435
+ end
436
+
437
+ end
438
+
343
439
  context 'with escapes' do
344
440
  assert_source '/\//'
345
441
  end
@@ -408,6 +504,14 @@ describe ToSource,'.to_source' do
408
504
  assert_source '/foo#{bar}baz/'
409
505
  end
410
506
 
507
+ context 'with flags' do
508
+ assert_source '/foo#{bar}/i'
509
+ assert_source '/foo#{bar}/m'
510
+ assert_source '/foo#{bar}/im'
511
+ assert_source '/foo#{bar}/imx'
512
+ assert_source '/foo#{bar}/x'
513
+ end
514
+
411
515
  context 'split groups' do
412
516
  assert_source '/(#{foo})*/'
413
517
  end
@@ -423,14 +527,42 @@ describe ToSource,'.to_source' do
423
527
  context 'with dynamic segment in the end' do
424
528
  assert_source '/foo#{bar}/'
425
529
  end
530
+
531
+ context 'with o flag' do
532
+ assert_source '/foo#{bar}/o'
533
+ end
534
+
535
+ context 'with o and other flags' do
536
+ assert_source '/foo#{bar}/oim'
537
+ end
426
538
  end
427
539
  end
428
540
 
541
+ context 'END' do
542
+ original = <<-RUBY
543
+ END {
544
+ foo
545
+ }
546
+ RUBY
547
+
548
+ target = <<-RUBY
549
+ at_exit do
550
+ foo
551
+ end
552
+ RUBY
553
+
554
+ assert_converts target, original
555
+ end
556
+
429
557
  context 'send' do
430
558
  context 'as element reference' do
431
559
  assert_source 'foo[index]'
432
560
  end
433
561
 
562
+ context 'as element reference with splat' do
563
+ assert_source 'self[*foo]'
564
+ end
565
+
434
566
  context 'as element reference on self' do
435
567
  assert_source 'self[foo]'
436
568
  end
@@ -515,6 +647,14 @@ describe ToSource,'.to_source' do
515
647
  assert_source 'foo.bar(*args)'
516
648
  end
517
649
 
650
+ context 'with formal splat and formal argument' do
651
+ assert_source 'foo.bar(*arga, foo, *argb)'
652
+ end
653
+
654
+ context 'with splat and formal argument' do
655
+ assert_source 'foo.bar(*args, foo)'
656
+ end
657
+
518
658
  context 'with formal and splat argument' do
519
659
  assert_source 'foo.bar(foo, *args)'
520
660
  end
@@ -545,11 +685,11 @@ describe ToSource,'.to_source' do
545
685
 
546
686
  context 'attribute assignment' do
547
687
  context 'on foreign object' do
548
- assert_source 'foo.bar= :baz'
688
+ assert_source 'foo.bar = :baz'
549
689
  end
550
690
 
551
691
  context 'on self' do
552
- assert_source 'self.foo= :bar'
692
+ assert_source 'self.foo = :bar'
553
693
  end
554
694
  end
555
695
  end
@@ -628,16 +768,54 @@ describe ToSource,'.to_source' do
628
768
  assert_source 'break(a)'
629
769
  end
630
770
 
771
+ context 'retry' do
772
+ assert_source 'retry'
773
+ end
774
+
775
+ context 'redo' do
776
+ assert_source 'redo'
777
+ end
778
+
631
779
  context 'next' do
632
780
  assert_source 'next'
633
781
  end
634
782
 
635
- context 'match operator' do
783
+ context 'match2 operator' do
784
+ assert_source <<-RUBY
785
+ /bar/ =~ foo
786
+ RUBY
787
+ end
788
+
789
+ context 'match3 operator' do
636
790
  assert_source <<-RUBY
637
791
  foo =~ /bar/
638
792
  RUBY
639
793
  end
640
794
 
795
+ context 'flip flops' do
796
+ context 'flip2' do
797
+ assert_source <<-RUBY
798
+ if (((i) == (4)))..(((i) == (4)))
799
+ foo
800
+ end
801
+ RUBY
802
+ end
803
+
804
+ context 'flip3' do
805
+ assert_source <<-RUBY
806
+ if (((i) == (4)))...(((i) == (4)))
807
+ foo
808
+ end
809
+ RUBY
810
+ end
811
+ end
812
+
813
+ context 'valias' do
814
+ assert_source <<-RUBY
815
+ alias $foo $bar
816
+ RUBY
817
+ end
818
+
641
819
  context 'alias' do
642
820
  assert_source <<-RUBY
643
821
  alias foo bar
@@ -659,11 +837,15 @@ describe ToSource,'.to_source' do
659
837
  end
660
838
 
661
839
  context 'binary operators methods' do
662
- %w(+ - * / & | && || << >> == === != <= < <=> > >= =~ !~ ^ **).each do |operator|
840
+ %w(+ - * / & | << >> == === != <= < <=> > >= =~ !~ ^ **).each do |operator|
663
841
  context "on literals #{operator}" do
664
842
  assert_source "((1) #{operator} (2))"
665
843
  end
666
844
 
845
+ context "#{operator} with splat args" do
846
+ assert_source "((left).#{operator}(*foo))"
847
+ end
848
+
667
849
  context "on self #{operator}" do
668
850
  assert_source "((self) #{operator} (b))"
669
851
  end
@@ -672,19 +854,21 @@ describe ToSource,'.to_source' do
672
854
  assert_source "((a) #{operator} (b))"
673
855
  end
674
856
  end
857
+ end
675
858
 
676
- context 'binary operator and keywords' do
677
- assert_source '((a) || (break(foo)))'
678
- end
859
+ context 'binary operator' do
860
+ context 'and keywords' do
861
+ assert_source '((a) || (break(foo)))'
862
+ end
679
863
 
680
- context 'sending methods to result of binary operator' do
681
- assert_source '((a) || (b)).foo'
682
- end
864
+ context 'sending methods to result' do
865
+ assert_source '((a) || (b)).foo'
866
+ end
683
867
 
684
- context 'nested binary operators' do
685
- assert_source '((a) || (((b) || (c))))'
686
- end
687
- end
868
+ context 'nested' do
869
+ assert_source '((a) || (((b) || (c))))'
870
+ end
871
+ end
688
872
 
689
873
  { :or => :'||', :and => :'&&' }.each do |word, symbol|
690
874
  context "word form form equivalency of #{word} and #{symbol}" do
@@ -751,6 +935,13 @@ describe ToSource,'.to_source' do
751
935
  end
752
936
 
753
937
  context 'if statement' do
938
+ context 'when matching regexp' do
939
+ assert_source <<-RUBY
940
+ if /foo/
941
+ bar
942
+ end
943
+ RUBY
944
+ end
754
945
  context 'without else branch' do
755
946
  context 'single statement in branch' do
756
947
  assert_source <<-RUBY
@@ -868,6 +1059,32 @@ describe ToSource,'.to_source' do
868
1059
  end
869
1060
  end
870
1061
 
1062
+ context 'for' do
1063
+ context 'single assignment' do
1064
+ assert_source <<-RUBY
1065
+ for a in bar do
1066
+ baz
1067
+ end
1068
+ RUBY
1069
+ end
1070
+
1071
+ context 'splat assignment' do
1072
+ assert_source <<-RUBY
1073
+ for a, *b in bar do
1074
+ baz
1075
+ end
1076
+ RUBY
1077
+ end
1078
+
1079
+ context 'multiple assignment' do
1080
+ assert_source <<-RUBY
1081
+ for a, b in bar do
1082
+ baz
1083
+ end
1084
+ RUBY
1085
+ end
1086
+ end
1087
+
871
1088
  context 'loop' do
872
1089
  assert_source <<-RUBY
873
1090
  loop do
@@ -1089,6 +1306,10 @@ describe ToSource,'.to_source' do
1089
1306
  end
1090
1307
  end
1091
1308
 
1309
+ context '__ENCODING__' do
1310
+ assert_source '__ENCODING__'
1311
+ end
1312
+
1092
1313
  context '__FILE__' do
1093
1314
  assert_source '__FILE__'
1094
1315
  end
@@ -1113,6 +1334,10 @@ describe ToSource,'.to_source' do
1113
1334
  end
1114
1335
  end
1115
1336
 
1337
+ context 'undef' do
1338
+ assert_source 'undef :foo'
1339
+ end
1340
+
1116
1341
  context 'define' do
1117
1342
  context 'on instance' do
1118
1343
  context 'without arguments' do