unparser 0.4.9 → 0.5.4

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 (107) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +19 -4
  3. data/bin/unparser +1 -1
  4. data/lib/unparser.rb +115 -61
  5. data/lib/unparser/ast.rb +0 -1
  6. data/lib/unparser/ast/local_variable_scope.rb +6 -76
  7. data/lib/unparser/buffer.rb +19 -16
  8. data/lib/unparser/cli.rb +26 -39
  9. data/lib/unparser/color.rb +0 -3
  10. data/lib/unparser/comments.rb +0 -26
  11. data/lib/unparser/constants.rb +4 -53
  12. data/lib/unparser/diff.rb +0 -17
  13. data/lib/unparser/dsl.rb +0 -32
  14. data/lib/unparser/emitter.rb +23 -425
  15. data/lib/unparser/emitter/alias.rb +2 -8
  16. data/lib/unparser/emitter/args.rb +45 -0
  17. data/lib/unparser/emitter/argument.rb +8 -166
  18. data/lib/unparser/emitter/array.rb +27 -0
  19. data/lib/unparser/emitter/array_pattern.rb +29 -0
  20. data/lib/unparser/emitter/assignment.rb +36 -127
  21. data/lib/unparser/emitter/begin.rb +9 -84
  22. data/lib/unparser/emitter/binary.rb +7 -20
  23. data/lib/unparser/emitter/block.rb +57 -41
  24. data/lib/unparser/emitter/case.rb +6 -48
  25. data/lib/unparser/emitter/case_guard.rb +27 -0
  26. data/lib/unparser/emitter/case_match.rb +40 -0
  27. data/lib/unparser/emitter/cbase.rb +1 -3
  28. data/lib/unparser/emitter/class.rb +6 -26
  29. data/lib/unparser/emitter/const_pattern.rb +24 -0
  30. data/lib/unparser/emitter/def.rb +7 -51
  31. data/lib/unparser/emitter/defined.rb +2 -12
  32. data/lib/unparser/emitter/dstr.rb +22 -0
  33. data/lib/unparser/emitter/dsym.rb +41 -0
  34. data/lib/unparser/emitter/flipflop.rb +11 -10
  35. data/lib/unparser/emitter/float.rb +29 -0
  36. data/lib/unparser/emitter/flow_modifier.rb +11 -55
  37. data/lib/unparser/emitter/for.rb +5 -19
  38. data/lib/unparser/emitter/hash.rb +74 -0
  39. data/lib/unparser/emitter/hash_pattern.rb +67 -0
  40. data/lib/unparser/emitter/hookexe.rb +5 -11
  41. data/lib/unparser/emitter/if.rb +15 -71
  42. data/lib/unparser/emitter/in_match.rb +21 -0
  43. data/lib/unparser/emitter/in_pattern.rb +34 -0
  44. data/lib/unparser/emitter/index.rb +21 -88
  45. data/lib/unparser/emitter/kwbegin.rb +31 -0
  46. data/lib/unparser/emitter/lambda.rb +0 -8
  47. data/lib/unparser/emitter/masgn.rb +20 -0
  48. data/lib/unparser/emitter/match.rb +3 -17
  49. data/lib/unparser/emitter/match_alt.rb +23 -0
  50. data/lib/unparser/emitter/match_as.rb +21 -0
  51. data/lib/unparser/emitter/match_rest.rb +26 -0
  52. data/lib/unparser/emitter/match_var.rb +19 -0
  53. data/lib/unparser/emitter/mlhs.rb +40 -0
  54. data/lib/unparser/emitter/module.rb +3 -9
  55. data/lib/unparser/emitter/op_assign.rb +12 -27
  56. data/lib/unparser/emitter/pin.rb +19 -0
  57. data/lib/unparser/emitter/primitive.rb +93 -0
  58. data/lib/unparser/emitter/range.rb +35 -0
  59. data/lib/unparser/emitter/regexp.rb +35 -0
  60. data/lib/unparser/emitter/repetition.rb +17 -57
  61. data/lib/unparser/emitter/rescue.rb +1 -97
  62. data/lib/unparser/emitter/root.rb +17 -1
  63. data/lib/unparser/emitter/send.rb +10 -219
  64. data/lib/unparser/emitter/simple.rb +33 -0
  65. data/lib/unparser/emitter/splat.rb +2 -18
  66. data/lib/unparser/emitter/super.rb +1 -29
  67. data/lib/unparser/emitter/undef.rb +1 -9
  68. data/lib/unparser/emitter/variable.rb +1 -31
  69. data/lib/unparser/emitter/xstr.rb +72 -0
  70. data/lib/unparser/emitter/yield.rb +1 -9
  71. data/lib/unparser/generation.rb +250 -0
  72. data/lib/unparser/node_details.rb +21 -0
  73. data/lib/unparser/node_details/send.rb +62 -0
  74. data/lib/unparser/node_helpers.rb +46 -6
  75. data/lib/unparser/validation.rb +58 -35
  76. data/lib/unparser/writer.rb +15 -0
  77. data/lib/unparser/writer/binary.rb +99 -0
  78. data/lib/unparser/writer/dynamic_string.rb +233 -0
  79. data/lib/unparser/writer/resbody.rb +40 -0
  80. data/lib/unparser/writer/rescue.rb +39 -0
  81. data/lib/unparser/writer/send.rb +124 -0
  82. data/lib/unparser/{emitter → writer}/send/attribute_assignment.rb +11 -26
  83. data/lib/unparser/writer/send/binary.rb +27 -0
  84. data/lib/unparser/writer/send/conditional.rb +25 -0
  85. data/lib/unparser/writer/send/regular.rb +33 -0
  86. data/lib/unparser/{emitter → writer}/send/unary.rb +10 -17
  87. metadata +66 -34
  88. data/lib/unparser/emitter/empty.rb +0 -23
  89. data/lib/unparser/emitter/ensure.rb +0 -37
  90. data/lib/unparser/emitter/literal.rb +0 -10
  91. data/lib/unparser/emitter/literal/array.rb +0 -29
  92. data/lib/unparser/emitter/literal/dynamic.rb +0 -53
  93. data/lib/unparser/emitter/literal/dynamic_body.rb +0 -132
  94. data/lib/unparser/emitter/literal/execute_string.rb +0 -38
  95. data/lib/unparser/emitter/literal/hash.rb +0 -156
  96. data/lib/unparser/emitter/literal/primitive.rb +0 -145
  97. data/lib/unparser/emitter/literal/range.rb +0 -36
  98. data/lib/unparser/emitter/literal/regexp.rb +0 -114
  99. data/lib/unparser/emitter/literal/singleton.rb +0 -26
  100. data/lib/unparser/emitter/meta.rb +0 -16
  101. data/lib/unparser/emitter/redo.rb +0 -25
  102. data/lib/unparser/emitter/resbody.rb +0 -76
  103. data/lib/unparser/emitter/retry.rb +0 -25
  104. data/lib/unparser/emitter/send/binary.rb +0 -57
  105. data/lib/unparser/emitter/send/conditional.rb +0 -40
  106. data/lib/unparser/emitter/send/regular.rb +0 -40
  107. data/lib/unparser/preprocessor.rb +0 -159
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for explicit begins
6
+ class KWBegin < self
7
+ handle :kwbegin
8
+
9
+ private
10
+
11
+ def dispatch
12
+ write('begin')
13
+
14
+ if children.one?
15
+ emit_body_ensure_rescue(children.first)
16
+ else
17
+ indented do
18
+ emit_multiple_body
19
+ end
20
+ end
21
+
22
+ k_end
23
+ end
24
+
25
+ def emit_multiple_body
26
+ emit_join(children, method(:emit_body_member), method(:nl))
27
+ end
28
+
29
+ end # KWBegin
30
+ end # Emitter
31
+ end # Unparser
@@ -4,18 +4,10 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for lambda nodes
6
6
  class Lambda < self
7
- include Terminated
8
-
9
7
  handle :lambda
10
8
 
11
9
  private
12
10
 
13
- # Perform dispatch
14
- #
15
- # @return [undefined]
16
- #
17
- # @api private
18
- #
19
11
  def dispatch
20
12
  write('->')
21
13
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for multiple assignment nodes
6
+ class MASGN < self
7
+ handle :masgn
8
+
9
+ children :target, :source
10
+
11
+ private
12
+
13
+ def dispatch
14
+ visit(target)
15
+ write(' = ')
16
+ visit(source)
17
+ end
18
+ end # MLHS
19
+ end # Emitter
20
+ end # Unaprser
@@ -5,10 +5,6 @@ module Unparser
5
5
 
6
6
  # Base class for special match node emitters
7
7
  class Match < self
8
- include Unterminated
9
-
10
- OPERATOR = '=~'.freeze
11
-
12
8
  # Emitter for match with local variable assignment
13
9
  class Lvasgn < self
14
10
  handle :match_with_lvasgn
@@ -17,15 +13,9 @@ module Unparser
17
13
 
18
14
  private
19
15
 
20
- # Perform dispatch
21
- #
22
- # @return [undefined]
23
- #
24
- # @api private
25
- #
26
16
  def dispatch
27
17
  visit(regexp)
28
- write(WS, OPERATOR, WS)
18
+ write(' =~ ')
29
19
  visit(lvasgn)
30
20
  end
31
21
 
@@ -37,12 +27,8 @@ module Unparser
37
27
 
38
28
  children :regexp
39
29
 
40
- # Perform dispatch
41
- #
42
- # @return [undefined]
43
- #
44
- # @api private
45
- #
30
+ private
31
+
46
32
  def dispatch
47
33
  visit(regexp)
48
34
  end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for in pattern nodes
6
+ class MatchAlt < self
7
+
8
+ handle :match_alt
9
+
10
+ children :left, :right
11
+
12
+ private
13
+
14
+ def dispatch
15
+ visit(left)
16
+ ws
17
+ write('|')
18
+ ws
19
+ visit(right)
20
+ end
21
+ end # MatchAlt
22
+ end # Emitter
23
+ end # Unparser
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for in pattern nodes
6
+ class MatchAs < self
7
+
8
+ handle :match_as
9
+
10
+ children :left, :right
11
+
12
+ private
13
+
14
+ def dispatch
15
+ visit(left)
16
+ write(' => ')
17
+ visit(right)
18
+ end
19
+ end # MatchAs
20
+ end # Emitter
21
+ end # Unparser
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emiter for match rest nodes
6
+ class MatchRest < self
7
+ children :match_var
8
+
9
+ def emit_array_pattern
10
+ write('*')
11
+ emit_match_var
12
+ end
13
+
14
+ def emit_hash_pattern
15
+ write('**')
16
+ emit_match_var
17
+ end
18
+
19
+ private
20
+
21
+ def emit_match_var
22
+ visit(match_var) if match_var
23
+ end
24
+ end # MatchRest
25
+ end # Emitter
26
+ end # Unparser
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for in pattern nodes
6
+ class MatchVar < self
7
+
8
+ handle :match_var
9
+
10
+ children :name
11
+
12
+ private
13
+
14
+ def dispatch
15
+ write(name.to_s)
16
+ end
17
+ end # MatchVar
18
+ end # Emitter
19
+ end # Unparser
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for multiple assignment left hand side
6
+ class MLHS < self
7
+ handle :mlhs
8
+
9
+ NO_COMMA = %i[arg splat mlhs restarg].freeze
10
+
11
+ private_constant(*constants(false))
12
+
13
+ private
14
+
15
+ def dispatch
16
+ if children.one?
17
+ emit_one_child_mlhs
18
+ else
19
+ emit_many
20
+ end
21
+ end
22
+
23
+ def emit_one_child_mlhs
24
+ child = children.first
25
+ parentheses do
26
+ emitter(child).emit_mlhs
27
+ write(',') unless NO_COMMA.include?(child.type)
28
+ end
29
+ end
30
+
31
+ def emit_many
32
+ parentheses do
33
+ delimited(children) do |node|
34
+ emitter(node).emit_mlhs
35
+ end
36
+ end
37
+ end
38
+ end # MLHS
39
+ end # Emitter
40
+ end # Unaprser
@@ -4,7 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for module nodes
6
6
  class Module < self
7
- include LocalVariableRoot, Terminated
7
+ include LocalVariableRoot
8
8
 
9
9
  handle :module
10
10
 
@@ -12,16 +12,10 @@ module Unparser
12
12
 
13
13
  private
14
14
 
15
- # Perform dispatch
16
- #
17
- # @return [undefined]
18
- #
19
- # @api private
20
- #
21
15
  def dispatch
22
- write(K_MODULE, WS)
16
+ write('module ')
23
17
  visit(name)
24
- emit_body
18
+ emit_optional_body(body)
25
19
  k_end
26
20
  end
27
21
 
@@ -5,8 +5,6 @@ module Unparser
5
5
 
6
6
  # Base class for and and or op-assign
7
7
  class BinaryAssign < self
8
- include Unterminated
9
-
10
8
  children :target, :expression
11
9
 
12
10
  MAP = IceNine.deep_freeze(
@@ -16,17 +14,16 @@ module Unparser
16
14
 
17
15
  handle(*MAP.keys)
18
16
 
17
+ def emit_heredoc_reminders
18
+ emitter(target).emit_heredoc_reminders
19
+ emitter(expression).emit_heredoc_reminders
20
+ end
21
+
19
22
  private
20
23
 
21
- # Perform dispatch
22
- #
23
- # @return [undefined]
24
- #
25
- # @api private
26
- #
27
24
  def dispatch
28
- visit(target)
29
- write(WS, MAP.fetch(node.type), WS)
25
+ emitter(target).emit_mlhs
26
+ write(' ', MAP.fetch(node.type), ' ')
30
27
  visit(expression)
31
28
  end
32
29
 
@@ -34,32 +31,20 @@ module Unparser
34
31
 
35
32
  # Emitter for op assign
36
33
  class OpAssign < self
37
- include Unterminated
38
-
39
34
  handle :op_asgn
40
35
 
36
+ children :target, :operator, :value
37
+
41
38
  private
42
39
 
43
- # Perform dispatch
44
- #
45
- # @return [undefined]
46
- #
47
- # @api private
48
- #
49
40
  def dispatch
50
- visit(first_child)
41
+ emitter(first_child).emit_mlhs
51
42
  emit_operator
52
- visit(children[2])
43
+ visit(value)
53
44
  end
54
45
 
55
- # Emit operator
56
- #
57
- # @return [undefined]
58
- #
59
- # @api private
60
- #
61
46
  def emit_operator
62
- write(WS, children[1].to_s, T_ASN, WS)
47
+ write(' ', operator.to_s, '= ')
63
48
  end
64
49
 
65
50
  end # OpAssign
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for pin nodes
6
+ class Pin < self
7
+ handle :pin
8
+
9
+ children :target
10
+
11
+ private
12
+
13
+ def dispatch
14
+ write('^')
15
+ visit(target)
16
+ end
17
+ end # Pin
18
+ end # Emitter
19
+ end # Unparser
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Base class for primitive emitters
6
+ class Primitive < self
7
+
8
+ children :value
9
+
10
+ # Emitter for primitives based on Object#inspect
11
+ class Inspect < self
12
+
13
+ handle :sym, :str
14
+
15
+ private
16
+
17
+ def dispatch
18
+ write(value.inspect)
19
+ end
20
+
21
+ end # Inspect
22
+
23
+ # Emitter for complex literals
24
+ class Complex < self
25
+
26
+ handle :complex
27
+
28
+ RATIONAL_FORMAT = 'i'.freeze
29
+
30
+ MAP =
31
+ IceNine.deep_freeze(
32
+ ::Float => :float,
33
+ ::Rational => :rational,
34
+ ::Integer => :int
35
+ )
36
+
37
+ private
38
+
39
+ def dispatch
40
+ emit_imaginary
41
+ write(RATIONAL_FORMAT)
42
+ end
43
+
44
+ def emit_imaginary
45
+ visit(imaginary_node)
46
+ end
47
+
48
+ def imaginary_node
49
+ imaginary = value.imaginary
50
+ s(MAP.fetch(imaginary.class), imaginary)
51
+ end
52
+
53
+ end # Rational
54
+
55
+ # Emitter for rational literals
56
+ class Rational < self
57
+
58
+ handle :rational
59
+
60
+ RATIONAL_FORMAT = 'r'.freeze
61
+
62
+ private
63
+
64
+ # rubocop:disable Lint/FloatComparison
65
+ def dispatch
66
+ integer = Integer(value)
67
+ float = value.to_f
68
+
69
+ write_rational(integer.to_f.equal?(float) ? integer : float)
70
+ end
71
+ # rubocop:enable Lint/FloatComparison
72
+
73
+ def write_rational(value)
74
+ write(value.to_s, RATIONAL_FORMAT)
75
+ end
76
+
77
+ end # Rational
78
+
79
+ # Emiter for numeric literals
80
+ class Numeric < self
81
+
82
+ handle :int
83
+
84
+ private
85
+
86
+ def dispatch
87
+ write(value.inspect)
88
+ end
89
+
90
+ end # Numeric
91
+ end # Primitive
92
+ end # Emitter
93
+ end # Unparser