unparser 0.4.9 → 0.5.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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/bin/unparser +1 -1
  3. data/lib/unparser.rb +98 -61
  4. data/lib/unparser/ast.rb +0 -1
  5. data/lib/unparser/ast/local_variable_scope.rb +6 -76
  6. data/lib/unparser/buffer.rb +19 -16
  7. data/lib/unparser/cli.rb +26 -39
  8. data/lib/unparser/color.rb +0 -3
  9. data/lib/unparser/comments.rb +0 -26
  10. data/lib/unparser/constants.rb +4 -53
  11. data/lib/unparser/diff.rb +0 -17
  12. data/lib/unparser/dsl.rb +0 -32
  13. data/lib/unparser/emitter.rb +23 -425
  14. data/lib/unparser/emitter/alias.rb +2 -8
  15. data/lib/unparser/emitter/args.rb +45 -0
  16. data/lib/unparser/emitter/argument.rb +8 -166
  17. data/lib/unparser/emitter/array.rb +27 -0
  18. data/lib/unparser/emitter/array_pattern.rb +29 -0
  19. data/lib/unparser/emitter/assignment.rb +36 -127
  20. data/lib/unparser/emitter/begin.rb +9 -84
  21. data/lib/unparser/emitter/binary.rb +7 -20
  22. data/lib/unparser/emitter/block.rb +57 -41
  23. data/lib/unparser/emitter/case.rb +6 -48
  24. data/lib/unparser/emitter/case_guard.rb +27 -0
  25. data/lib/unparser/emitter/case_match.rb +40 -0
  26. data/lib/unparser/emitter/cbase.rb +1 -3
  27. data/lib/unparser/emitter/class.rb +6 -26
  28. data/lib/unparser/emitter/const_pattern.rb +24 -0
  29. data/lib/unparser/emitter/def.rb +7 -51
  30. data/lib/unparser/emitter/defined.rb +2 -12
  31. data/lib/unparser/emitter/dstr.rb +22 -0
  32. data/lib/unparser/emitter/dsym.rb +41 -0
  33. data/lib/unparser/emitter/flipflop.rb +11 -10
  34. data/lib/unparser/emitter/float.rb +29 -0
  35. data/lib/unparser/emitter/flow_modifier.rb +8 -55
  36. data/lib/unparser/emitter/for.rb +5 -19
  37. data/lib/unparser/emitter/hash.rb +74 -0
  38. data/lib/unparser/emitter/hash_pattern.rb +67 -0
  39. data/lib/unparser/emitter/hookexe.rb +5 -11
  40. data/lib/unparser/emitter/if.rb +9 -73
  41. data/lib/unparser/emitter/in_match.rb +21 -0
  42. data/lib/unparser/emitter/in_pattern.rb +34 -0
  43. data/lib/unparser/emitter/index.rb +21 -88
  44. data/lib/unparser/emitter/kwbegin.rb +31 -0
  45. data/lib/unparser/emitter/lambda.rb +0 -8
  46. data/lib/unparser/emitter/masgn.rb +20 -0
  47. data/lib/unparser/emitter/match.rb +3 -17
  48. data/lib/unparser/emitter/match_alt.rb +23 -0
  49. data/lib/unparser/emitter/match_as.rb +21 -0
  50. data/lib/unparser/emitter/match_rest.rb +26 -0
  51. data/lib/unparser/emitter/match_var.rb +19 -0
  52. data/lib/unparser/emitter/mlhs.rb +40 -0
  53. data/lib/unparser/emitter/module.rb +3 -9
  54. data/lib/unparser/emitter/op_assign.rb +12 -27
  55. data/lib/unparser/emitter/pin.rb +19 -0
  56. data/lib/unparser/emitter/primitive.rb +93 -0
  57. data/lib/unparser/emitter/range.rb +35 -0
  58. data/lib/unparser/emitter/regexp.rb +35 -0
  59. data/lib/unparser/emitter/repetition.rb +17 -57
  60. data/lib/unparser/emitter/rescue.rb +1 -97
  61. data/lib/unparser/emitter/root.rb +17 -1
  62. data/lib/unparser/emitter/send.rb +10 -219
  63. data/lib/unparser/emitter/simple.rb +33 -0
  64. data/lib/unparser/emitter/splat.rb +2 -18
  65. data/lib/unparser/emitter/super.rb +1 -29
  66. data/lib/unparser/emitter/undef.rb +1 -9
  67. data/lib/unparser/emitter/variable.rb +1 -31
  68. data/lib/unparser/emitter/xstr.rb +72 -0
  69. data/lib/unparser/emitter/yield.rb +1 -9
  70. data/lib/unparser/generation.rb +250 -0
  71. data/lib/unparser/node_details.rb +21 -0
  72. data/lib/unparser/node_details/send.rb +62 -0
  73. data/lib/unparser/node_helpers.rb +45 -6
  74. data/lib/unparser/validation.rb +37 -35
  75. data/lib/unparser/writer.rb +15 -0
  76. data/lib/unparser/writer/binary.rb +99 -0
  77. data/lib/unparser/writer/dynamic_string.rb +229 -0
  78. data/lib/unparser/writer/resbody.rb +40 -0
  79. data/lib/unparser/writer/rescue.rb +39 -0
  80. data/lib/unparser/writer/send.rb +124 -0
  81. data/lib/unparser/{emitter → writer}/send/attribute_assignment.rb +11 -26
  82. data/lib/unparser/writer/send/binary.rb +27 -0
  83. data/lib/unparser/writer/send/conditional.rb +25 -0
  84. data/lib/unparser/writer/send/regular.rb +33 -0
  85. data/lib/unparser/{emitter → writer}/send/unary.rb +10 -17
  86. metadata +63 -31
  87. data/lib/unparser/emitter/empty.rb +0 -23
  88. data/lib/unparser/emitter/ensure.rb +0 -37
  89. data/lib/unparser/emitter/literal.rb +0 -10
  90. data/lib/unparser/emitter/literal/array.rb +0 -29
  91. data/lib/unparser/emitter/literal/dynamic.rb +0 -53
  92. data/lib/unparser/emitter/literal/dynamic_body.rb +0 -132
  93. data/lib/unparser/emitter/literal/execute_string.rb +0 -38
  94. data/lib/unparser/emitter/literal/hash.rb +0 -156
  95. data/lib/unparser/emitter/literal/primitive.rb +0 -145
  96. data/lib/unparser/emitter/literal/range.rb +0 -36
  97. data/lib/unparser/emitter/literal/regexp.rb +0 -114
  98. data/lib/unparser/emitter/literal/singleton.rb +0 -26
  99. data/lib/unparser/emitter/meta.rb +0 -16
  100. data/lib/unparser/emitter/redo.rb +0 -25
  101. data/lib/unparser/emitter/resbody.rb +0 -76
  102. data/lib/unparser/emitter/retry.rb +0 -25
  103. data/lib/unparser/emitter/send/binary.rb +0 -57
  104. data/lib/unparser/emitter/send/conditional.rb +0 -40
  105. data/lib/unparser/emitter/send/regular.rb +0 -40
  106. data/lib/unparser/preprocessor.rb +0 -159
@@ -5,97 +5,22 @@ module Unparser
5
5
 
6
6
  # Emitter for begin nodes
7
7
  class Begin < self
8
-
8
+ handle :begin
9
9
  children :body
10
10
 
11
- private
12
-
13
- # Emit inner nodes
14
- #
15
- # @return [undefined]
16
- #
17
- # @api private
18
- #
19
- def emit_inner
20
- children.each_with_index do |child, index|
21
- visit_plain(child)
22
- write(NL) if index < children.length - 1
11
+ def emit_heredoc_reminders
12
+ children.each do |child|
13
+ emitter(child).emit_heredoc_reminders
23
14
  end
24
15
  end
25
16
 
26
- # Emitter for implicit begins
27
- class Implicit < self
28
-
29
- handle :begin
30
-
31
- # Test if begin is terminated
32
- #
33
- # @return [Boolean]
34
- #
35
- # @api private
36
- #
37
- def terminated?
38
- children.empty?
39
- end
40
-
41
- TERMINATING_PARENT = %i[root interpolated dyn_str_body].to_set.freeze
42
-
43
- private
44
-
45
- # Perform dispatch
46
- #
47
- # @return [undefined]
48
- #
49
- # @api private
50
- #
51
- def dispatch
52
- if terminated? && !TERMINATING_PARENT.include?(parent_type)
53
- write('()')
54
- else
55
- emit_inner
56
- end
57
- end
58
-
59
- end # Implicit
60
-
61
- # Emitter for explicit begins
62
- class Explicit < self
63
- include Terminated
64
-
65
- handle :kwbegin
66
-
67
- private
68
-
69
- # Perform dispatch
70
- #
71
- # @return [undefined]
72
- #
73
- # @api private
74
- #
75
- def dispatch
76
- write(K_BEGIN)
77
- emit_body
78
- k_end
79
- end
17
+ private
80
18
 
81
- # Emit body
82
- #
83
- # @return [undefined]
84
- #
85
- # @api private
86
- #
87
- def emit_body
88
- if body.nil?
89
- nl
90
- elsif NOINDENT.include?(body.type)
91
- emit_inner
92
- else
93
- indented { emit_inner }
94
- end
19
+ def dispatch
20
+ parentheses do
21
+ delimited(children, '; ')
95
22
  end
96
-
97
- end # Explicit
98
-
23
+ end
99
24
  end # Begin
100
25
  end # Emitter
101
26
  end # Unparser
@@ -2,33 +2,20 @@
2
2
 
3
3
  module Unparser
4
4
  class Emitter
5
- # Base class for binary emitters
5
+ # Non send binary operator / keyword emitter
6
6
  class Binary < self
7
- include Unterminated
8
-
9
- children :left, :right
10
-
11
- MAP = {
12
- or: T_OR,
13
- and: T_AND
14
- }.freeze
15
-
16
- handle(*MAP.keys)
7
+ handle :and, :or
17
8
 
18
9
  private
19
10
 
20
- # Perform dispatch
21
- #
22
- # @return [undefined]
23
- #
24
- # @api private
25
- #
26
11
  def dispatch
27
- visit(left)
28
- write(WS, MAP.fetch(node.type), WS)
29
- visit(right)
12
+ writer.dispatch
30
13
  end
31
14
 
15
+ def writer
16
+ writer_with(Writer::Binary, node)
17
+ end
18
+ memoize :writer
32
19
  end # Binary
33
20
  end # Emitter
34
21
  end # Unparser
@@ -4,66 +4,82 @@ module Unparser
4
4
  class Emitter
5
5
 
6
6
  # Block emitter
7
- #
8
- # ignore :reek:RepeatedConditional
9
7
  class Block < self
10
- include Terminated
11
-
12
- handle :block
8
+ handle :block, :numblock
13
9
 
14
10
  children :target, :arguments, :body
15
11
 
16
12
  private
17
13
 
18
- # Perform dispatch
19
- #
20
- # @return [undefined]
21
- #
22
- # @api private
23
- #
24
14
  def dispatch
25
15
  emit_target
26
- write(WS, K_DO)
27
- emit_block_arguments unless stabby_lambda?
28
- emit_body
29
- k_end
16
+ ws
17
+ write_open
18
+ target_writer.emit_heredoc_reminders if n_send?(target)
19
+ emit_block_arguments unless n_lambda?(target)
20
+ emit_optional_body_ensure_rescue(body)
21
+ write_close
30
22
  end
31
23
 
32
- # Emit target
33
- #
34
- # @return [undefined]
35
- #
36
- # @api private
37
- #
38
- def emit_target
39
- visit(target)
24
+ def need_do?
25
+ body && (n_rescue?(body) || n_ensure?(body))
26
+ end
27
+
28
+ def write_open
29
+ if need_do?
30
+ write('do')
31
+ else
32
+ write('{')
33
+ end
34
+ end
40
35
 
41
- if stabby_lambda?
42
- parentheses { visit(arguments) }
36
+ def write_close
37
+ if need_do?
38
+ k_end
39
+ else
40
+ write('}')
43
41
  end
44
42
  end
45
43
 
46
- # Test if we are emitting a stabby lambda
47
- #
48
- # @return [Boolean]
49
- #
50
- # @api private
51
- #
52
- def stabby_lambda?
53
- target.type.equal?(:lambda)
44
+ def target_writer
45
+ writer_with(Writer::Send::Regular, target)
46
+ end
47
+ memoize :target_writer
48
+
49
+ def emit_target
50
+ case target.type
51
+ when :send
52
+ emit_send_target
53
+ when :lambda
54
+ visit(target)
55
+ emit_lambda_arguments unless node.type.equal?(:numblock)
56
+ else
57
+ visit(target)
58
+ end
59
+ end
60
+
61
+ def emit_send_target
62
+ target_writer.emit_receiver
63
+ target_writer.emit_selector
64
+ target_writer.emit_arguments_without_heredoc_body
65
+ end
66
+
67
+ def emit_lambda_arguments
68
+ parentheses { writer_with(Args, arguments).emit_lambda_arguments }
69
+ end
70
+
71
+ def numblock?
72
+ node.type.equal?(:numblock)
54
73
  end
55
74
 
56
- # Emit arguments
57
- #
58
- # @return [undefined]
59
- #
60
- # @api private
61
- #
62
75
  def emit_block_arguments
63
- return if arguments.children.empty?
76
+ return if numblock? || arguments.children.empty?
64
77
 
65
78
  ws
66
- visit_parentheses(arguments, T_PIPE, T_PIPE)
79
+
80
+ parentheses('|', '|') do
81
+ writer_with(Args, arguments).emit_block_arguments
82
+ end
67
83
  end
68
84
 
69
85
  end # Block
@@ -4,8 +4,6 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for case nodes
6
6
  class Case < self
7
- include Terminated
8
-
9
7
  handle :case
10
8
 
11
9
  children :condition
@@ -13,89 +11,49 @@ module Unparser
13
11
 
14
12
  private
15
13
 
16
- # Perform dispatch
17
- #
18
- # @return [undefined]
19
- #
20
- # @api private
21
- #
22
14
  def dispatch
23
- write(K_CASE)
15
+ write('case')
24
16
  emit_condition
25
17
  emit_whens
26
18
  emit_else
27
19
  k_end
28
20
  end
29
21
 
30
- # Emit else
31
- #
32
- # @return [undefined]
33
- #
34
- # @api private
35
- #
36
22
  def emit_else
37
23
  else_branch = children.last
38
24
  return unless else_branch
39
25
 
40
- write(K_ELSE)
41
- visit_indented(else_branch)
26
+ write('else')
27
+ emit_body(else_branch)
42
28
  end
43
29
 
44
- # Emit whens
45
- #
46
- # @return [undefined]
47
- #
48
- # @api private
49
- #
50
30
  def emit_whens
51
31
  nl
52
32
  whens.each(&method(:visit))
53
33
  end
54
34
 
55
- # Emit condition
56
- #
57
- # @return [undefined]
58
- #
59
- # @api private
60
- #
61
35
  def emit_condition
62
36
  return unless condition
63
37
 
64
- write(WS)
38
+ ws
65
39
  visit(condition)
66
40
  end
67
-
68
41
  end # Case
69
42
 
70
43
  # Emitter for when nodes
71
44
  class When < self
72
- include Terminated
73
-
74
45
  handle :when
75
46
 
76
47
  define_group :captures, 0..-2
77
48
 
78
49
  private
79
50
 
80
- # Perform dispatch
81
- #
82
- # @return [undefined]
83
- #
84
- # @api private
85
- #
86
51
  def dispatch
87
- write(K_WHEN, WS)
52
+ write('when ')
88
53
  emit_captures
89
- body = children.last
90
- emit_body(body)
54
+ emit_optional_body(children.last)
91
55
  end
92
56
 
93
- # Emit captures
94
- #
95
- # @return [undefined]
96
- #
97
- # @api private
98
- #
99
57
  def emit_captures
100
58
  delimited(captures)
101
59
  end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for case guards
6
+ class CaseGuard < self
7
+
8
+ handle :if_guard, :unless_guard
9
+
10
+ MAP = {
11
+ if_guard: 'if',
12
+ unless_guard: 'unless'
13
+ }.freeze
14
+
15
+ children :condition
16
+
17
+ private
18
+
19
+ def dispatch
20
+ write(MAP.fetch(node_type))
21
+ ws
22
+ visit(condition)
23
+ end
24
+
25
+ end # UnlessGuard
26
+ end # Emitter
27
+ end # Unparser
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for case matches
6
+ class CaseMatch < self
7
+
8
+ handle :case_match
9
+
10
+ children :target
11
+
12
+ define_group :patterns, 1..-2
13
+
14
+ private
15
+
16
+ def else_branch
17
+ children.last
18
+ end
19
+
20
+ def dispatch
21
+ write('case ')
22
+ visit(target)
23
+ nl
24
+ patterns.each(&method(:visit))
25
+ nl unless buffer.fresh_line?
26
+ emit_else_branch
27
+ k_end
28
+ end
29
+
30
+ def emit_else_branch
31
+ if else_branch
32
+ write('else')
33
+ emit_body(else_branch) unless n_empty_else?(else_branch)
34
+ nl unless buffer.fresh_line?
35
+ end
36
+ end
37
+
38
+ end # CaseMatch
39
+ end # Emitter
40
+ end # Unparser
@@ -4,8 +4,6 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for toplevel constant reference nodes
6
6
  class CBase < self
7
- include Terminated
8
-
9
7
  handle :cbase
10
8
 
11
9
  private
@@ -17,7 +15,7 @@ module Unparser
17
15
  # @api private
18
16
  #
19
17
  def dispatch
20
- write(T_DCL)
18
+ write('::')
21
19
  end
22
20
 
23
21
  end # CBase