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
@@ -4,7 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for class nodes
6
6
  class Class < self
7
- include LocalVariableRoot, Terminated
7
+ include LocalVariableRoot
8
8
 
9
9
  handle :class
10
10
 
@@ -12,30 +12,18 @@ 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_CLASS, WS)
16
+ write('class ')
23
17
  visit(name)
24
18
  emit_superclass
25
- emit_body
19
+ emit_optional_body(body)
26
20
  k_end
27
21
  end
28
22
 
29
- # Emit superclass
30
- #
31
- # @return [undefined]
32
- #
33
- # @api private
34
- #
35
23
  def emit_superclass
36
24
  return unless superclass
37
25
 
38
- write(WS, T_LT, WS)
26
+ write(' < ')
39
27
  visit(superclass)
40
28
  end
41
29
 
@@ -43,24 +31,16 @@ module Unparser
43
31
 
44
32
  # Emitter for sclass nodes
45
33
  class SClass < self
46
- include Terminated
47
-
48
34
  handle :sclass
49
35
 
50
36
  children :object, :body
51
37
 
52
38
  private
53
39
 
54
- # Perform dispatch
55
- #
56
- # @return [undefined]
57
- #
58
- # @api private
59
- #
60
40
  def dispatch
61
- write(K_CLASS, WS, T_DLT, WS)
41
+ write('class << ')
62
42
  visit(object)
63
- emit_body
43
+ emit_optional_body(body)
64
44
  k_end
65
45
  end
66
46
 
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emitter for const pattern node
6
+ class ConstPattern < self
7
+
8
+ handle :const_pattern
9
+
10
+ children :const, :pattern
11
+
12
+ private
13
+
14
+ def dispatch
15
+ visit(const)
16
+ if n_hash_pattern?(pattern)
17
+ emitter(pattern).emit_const_pattern
18
+ else
19
+ visit(pattern)
20
+ end
21
+ end
22
+ end # ConstPattern
23
+ end # Emitter
24
+ end # Unparser
@@ -4,70 +4,40 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for def node
6
6
  class Def < self
7
- include LocalVariableRoot, Terminated
7
+ include LocalVariableRoot
8
8
 
9
9
  private
10
10
 
11
- # Emit name
12
- #
13
- # @return [undefined]
14
- #
15
- # @api private
16
- #
17
11
  abstract_method :emit_name
18
12
  private :emit_name
19
13
 
20
- # Return body node
21
- #
22
- # @return [Parser::AST::Node]
23
- #
24
- # @api private
25
- #
26
14
  abstract_method :body
27
15
  private :body
28
16
 
29
- # Perform dispatch
30
- #
31
- # @return [undefined]
32
- #
33
- # @api private
34
- #
35
17
  def dispatch
36
- write(K_DEF, WS)
18
+ write('def ')
37
19
  emit_name
38
- comments.consume(node, :name)
39
20
  emit_arguments
40
- emit_body
21
+ emit_optional_body_ensure_rescue(body)
41
22
  k_end
42
23
  end
43
24
 
44
- # Emit arguments
45
- #
46
- # @return [undefined]
47
- #
48
- # @api private
49
- #
50
25
  def emit_arguments
51
26
  return if arguments.children.empty?
52
27
 
53
- visit_parentheses(arguments)
28
+ parentheses do
29
+ writer_with(Args, arguments).emit_def_arguments
30
+ end
54
31
  end
55
32
 
56
33
  # Instance def emitter
57
34
  class Instance < self
58
-
59
35
  handle :def
60
36
 
61
37
  children :name, :arguments, :body
62
38
 
63
39
  private
64
40
 
65
- # Emit name
66
- #
67
- # @return [undefined]
68
- #
69
- # @api private
70
- #
71
41
  def emit_name
72
42
  write(name.to_s)
73
43
  end
@@ -83,25 +53,13 @@ module Unparser
83
53
 
84
54
  private
85
55
 
86
- # Return mame
87
- #
88
- # @return [String]
89
- #
90
- # @api private
91
- #
92
56
  def emit_name
93
57
  conditional_parentheses(!subject_without_parens?) do
94
58
  visit(subject)
95
59
  end
96
- write(T_DOT, name.to_s)
60
+ write('.', name.to_s)
97
61
  end
98
62
 
99
- # Test if subject needs parentheses
100
- #
101
- # @return [Boolean]
102
- #
103
- # @api private
104
- #
105
63
  def subject_without_parens?
106
64
  case subject.type
107
65
  when :self
@@ -111,8 +69,6 @@ module Unparser
111
69
  when :send
112
70
  receiver, _selector, *arguments = *subject
113
71
  !receiver && arguments.empty?
114
- else
115
- false
116
72
  end
117
73
  end
118
74
 
@@ -4,25 +4,15 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for defined? nodes
6
6
  class Defined < self
7
- include Terminated
8
-
9
7
  handle :defined?
10
8
 
11
9
  children :subject
12
10
 
13
11
  private
14
12
 
15
- # Perform dispatch
16
- #
17
- # @return [undefined]
18
- #
19
- # @api private
20
- #
21
13
  def dispatch
22
- write(K_DEFINED)
23
- parentheses do
24
- visit(subject)
25
- end
14
+ write('defined?')
15
+ parentheses { visit(subject) }
26
16
  end
27
17
 
28
18
  end # Defined
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Dynamic string emitter
6
+ class DStr < self
7
+
8
+ handle :dstr
9
+
10
+ def emit_heredoc_reminders
11
+ writer_with(Writer::DynamicString, node).emit_heredoc_reminder
12
+ end
13
+
14
+ private
15
+
16
+ def dispatch
17
+ writer_with(Writer::DynamicString, node).dispatch
18
+ end
19
+
20
+ end # DStr
21
+ end # Emitter
22
+ end # Unparser
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Dynamic symbol literal emitter
6
+ class DSym < self
7
+ handle :dsym
8
+
9
+ private
10
+
11
+ def dispatch
12
+ write(':"')
13
+ children.each do |child|
14
+ case child.type
15
+ when :str
16
+ emit_str_child(child)
17
+ when :begin
18
+ emit_begin_child(child)
19
+ end
20
+ end
21
+ write('"')
22
+ end
23
+
24
+ def emit_str_child(value)
25
+ string = value.children.first
26
+ if string.end_with?("\n")
27
+ write(string.inspect[1..-4])
28
+ nl
29
+ else
30
+ write(string.inspect[1..-2])
31
+ end
32
+ end
33
+
34
+ def emit_begin_child(component)
35
+ write('#{')
36
+ visit(unwrap_single_begin(component))
37
+ write('}')
38
+ end
39
+ end # DSym
40
+ end # Emitter
41
+ end # Unparser
@@ -4,12 +4,19 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for flip flops
6
6
  class FlipFlop < self
7
- include Unterminated
8
-
9
- MAP = IceNine.deep_freeze(
7
+ MAP = {
10
8
  iflipflop: '..',
11
9
  eflipflop: '...'
12
- ).freeze
10
+ }.freeze
11
+
12
+ SYMBOLS = {
13
+ eflipflop: :tDOT3,
14
+ iflipflop: :tDOT2
15
+ }.freeze
16
+
17
+ def symbol_name
18
+ true
19
+ end
13
20
 
14
21
  handle(*MAP.keys)
15
22
 
@@ -17,12 +24,6 @@ module Unparser
17
24
 
18
25
  private
19
26
 
20
- # Perform dispatch
21
- #
22
- # @return [undefined]
23
- #
24
- # @api private
25
- #
26
27
  def dispatch
27
28
  visit(left)
28
29
  write(MAP.fetch(node.type))
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Unparser
4
+ class Emitter
5
+ # Emiter for float literals
6
+ class Float < self
7
+ handle :float
8
+
9
+ children :value
10
+
11
+ INFINITY = ::Float::INFINITY
12
+ NEG_INFINITY = -::Float::INFINITY
13
+
14
+ private
15
+
16
+ def dispatch
17
+ case value
18
+ when INFINITY
19
+ write('10e1000000000000000000')
20
+ when NEG_INFINITY
21
+ write('-10e1000000000000000000')
22
+ else
23
+ write(value.inspect)
24
+ end
25
+ end
26
+
27
+ end # Float
28
+ end # Emitter
29
+ end # Unparser
@@ -4,77 +4,30 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter control flow modifiers
6
6
  class FlowModifier < self
7
-
8
7
  MAP = {
9
- return: K_RETURN,
10
- next: K_NEXT,
11
- break: K_BREAK
8
+ return: 'return',
9
+ next: 'next',
10
+ break: 'break'
12
11
  }.freeze
13
12
 
14
- handle(*MAP.keys)
13
+ private_constant(*constants(false))
15
14
 
16
- def terminated?
17
- children.empty?
18
- end
15
+ handle(*MAP.keys)
19
16
 
20
17
  private
21
18
 
22
- # Perform dispatch
23
- #
24
- # @return [undefined]
25
- #
26
- # @api private
27
- #
28
19
  def dispatch
29
20
  write(MAP.fetch(node.type))
30
- case children.length
31
- when 0 # rubocop:disable Lint/EmptyWhen
32
- when 1
33
- emit_single_argument
34
- else
21
+
22
+ unless children.empty?
35
23
  emit_arguments
36
24
  end
37
25
  end
38
26
 
39
- # Emit break or return arguments
40
- #
41
- # @return [undefined]
42
- #
43
- # @api private
44
- #
45
27
  def emit_arguments
46
28
  ws
47
- head, *tail = children
48
- emit_argument(head)
49
- tail.each do |node|
50
- write(DEFAULT_DELIMITER)
51
- emit_argument(node)
52
- end
53
- end
54
-
55
- PARENS = %i[if case begin].to_set.freeze
56
-
57
- # Emit argument
58
- #
59
- # @param [Parser::AST::Node] node
60
- #
61
- # @api private
62
- #
63
- def emit_argument(node)
64
- visit_plain(node)
65
- end
66
-
67
- # Emit single argument
68
- #
69
- # @api private
70
- #
71
- def emit_single_argument
72
- ws
73
- conditional_parentheses(PARENS.include?(first_child.type)) do
74
- visit_plain(first_child)
75
- end
29
+ delimited(children)
76
30
  end
77
-
78
31
  end # Return
79
32
  end # Emitter
80
33
  end # Unparser