unparser 0.1.15 → 0.1.16

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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/Changelog.md +6 -0
  3. data/circle.yml +1 -1
  4. data/config/flay.yml +1 -1
  5. data/config/flog.yml +1 -1
  6. data/config/reek.yml +1 -0
  7. data/lib/unparser/ast.rb +1 -1
  8. data/lib/unparser/ast/local_variable_scope.rb +1 -1
  9. data/lib/unparser/cli/differ.rb +1 -1
  10. data/lib/unparser/cli/source.rb +2 -0
  11. data/lib/unparser/constants.rb +0 -11
  12. data/lib/unparser/dsl.rb +1 -1
  13. data/lib/unparser/emitter.rb +41 -13
  14. data/lib/unparser/emitter/argument.rb +22 -34
  15. data/lib/unparser/emitter/assignment.rb +29 -6
  16. data/lib/unparser/emitter/begin.rb +10 -8
  17. data/lib/unparser/emitter/binary.rb +3 -12
  18. data/lib/unparser/emitter/block.rb +1 -0
  19. data/lib/unparser/emitter/case.rb +4 -2
  20. data/lib/unparser/emitter/cbase.rb +1 -0
  21. data/lib/unparser/emitter/class.rb +2 -1
  22. data/lib/unparser/emitter/def.rb +1 -1
  23. data/lib/unparser/emitter/defined.rb +2 -1
  24. data/lib/unparser/emitter/flipflop.rb +3 -2
  25. data/lib/unparser/emitter/flow_modifier.rb +22 -5
  26. data/lib/unparser/emitter/for.rb +2 -1
  27. data/lib/unparser/emitter/if.rb +10 -3
  28. data/lib/unparser/emitter/literal.rb +1 -0
  29. data/lib/unparser/emitter/literal/dynamic_body.rb +1 -1
  30. data/lib/unparser/emitter/literal/hash.rb +1 -1
  31. data/lib/unparser/emitter/literal/primitive.rb +83 -1
  32. data/lib/unparser/emitter/literal/range.rb +3 -2
  33. data/lib/unparser/emitter/match.rb +1 -0
  34. data/lib/unparser/emitter/module.rb +1 -1
  35. data/lib/unparser/emitter/op_assign.rb +3 -1
  36. data/lib/unparser/emitter/redo.rb +1 -0
  37. data/lib/unparser/emitter/repetition.rb +5 -3
  38. data/lib/unparser/emitter/resbody.rb +2 -2
  39. data/lib/unparser/emitter/rescue.rb +2 -1
  40. data/lib/unparser/emitter/retry.rb +1 -0
  41. data/lib/unparser/emitter/send.rb +13 -14
  42. data/lib/unparser/emitter/send/arguments.rb +1 -2
  43. data/lib/unparser/emitter/send/attribute_assignment.rb +3 -2
  44. data/lib/unparser/emitter/send/binary.rb +3 -2
  45. data/lib/unparser/emitter/send/index.rb +16 -2
  46. data/lib/unparser/emitter/send/regular.rb +2 -1
  47. data/lib/unparser/emitter/send/unary.rb +2 -1
  48. data/lib/unparser/emitter/splat.rb +2 -0
  49. data/lib/unparser/emitter/super.rb +2 -0
  50. data/lib/unparser/emitter/undef.rb +1 -0
  51. data/lib/unparser/emitter/variable.rb +4 -0
  52. data/lib/unparser/emitter/yield.rb +1 -0
  53. data/lib/unparser/preprocessor.rb +19 -12
  54. data/spec/integration/unparser/corpus_spec.rb +3 -2
  55. data/spec/integrations.yml +11 -1
  56. data/spec/unit/unparser_spec.rb +190 -183
  57. data/unparser.gemspec +2 -2
  58. metadata +5 -4
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Base class for binary emitters
6
6
  class Binary < self
7
+ include Unterminated
7
8
 
8
9
  children :left, :right
9
10
 
@@ -14,16 +15,6 @@ module Unparser
14
15
 
15
16
  handle(*MAP.keys)
16
17
 
17
- # Test if expression is terminated
18
- #
19
- # @return [false]
20
- #
21
- # @api private
22
- #
23
- def terminated?
24
- false
25
- end
26
-
27
18
  private
28
19
 
29
20
  # Perform dispatch
@@ -33,9 +24,9 @@ module Unparser
33
24
  # @api private
34
25
  #
35
26
  def dispatch
36
- visit_terminated(left)
27
+ visit(left)
37
28
  write(WS, MAP.fetch(node.type), WS)
38
- visit_terminated(right)
29
+ visit(right)
39
30
  end
40
31
 
41
32
  end # Binary
@@ -5,6 +5,7 @@ module Unparser
5
5
 
6
6
  # Block emitter
7
7
  class Block < self
8
+ include Terminated
8
9
 
9
10
  handle :block
10
11
 
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for case nodes
6
6
  class Case < self
7
+ include Terminated
7
8
 
8
9
  handle :case
9
10
 
@@ -59,17 +60,18 @@ module Unparser
59
60
  def emit_condition
60
61
  return unless condition
61
62
  write(WS)
62
- visit_terminated(condition)
63
+ visit(condition)
63
64
  end
64
65
 
65
66
  end # Case
66
67
 
67
68
  # Emitter for when nodes
68
69
  class When < self
70
+ include Terminated
69
71
 
70
72
  handle :when
71
73
 
72
- define_group :captures, 0 .. -2
74
+ define_group :captures, 0..-2
73
75
 
74
76
  private
75
77
 
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for toplevel constant reference nodes
6
6
  class CBase < self
7
+ include Terminated
7
8
 
8
9
  handle :cbase
9
10
 
@@ -4,7 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for class nodes
6
6
  class Class < self
7
- include LocalVariableRoot
7
+ include LocalVariableRoot, Terminated
8
8
 
9
9
  handle :class
10
10
 
@@ -42,6 +42,7 @@ module Unparser
42
42
 
43
43
  # Emitter for sclass nodes
44
44
  class SClass < self
45
+ include Terminated
45
46
 
46
47
  handle :sclass
47
48
 
@@ -4,7 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for def node
6
6
  class Def < self
7
- include LocalVariableRoot
7
+ include LocalVariableRoot, Terminated
8
8
 
9
9
  private
10
10
 
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for defined? nodes
6
6
  class Defined < self
7
+ include Terminated
7
8
 
8
9
  handle :defined?
9
10
 
@@ -20,7 +21,7 @@ module Unparser
20
21
  def dispatch
21
22
  write(K_DEFINED)
22
23
  parentheses do
23
- visit_terminated(subject)
24
+ visit(subject)
24
25
  end
25
26
  end
26
27
 
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for flip flops
6
6
  class FlipFlop < self
7
+ include Unterminated
7
8
 
8
9
  MAP = IceNine.deep_freeze(
9
10
  iflipflop: '..',
@@ -23,9 +24,9 @@ module Unparser
23
24
  # @api private
24
25
  #
25
26
  def dispatch
26
- visit_terminated(left)
27
+ visit(left)
27
28
  write(MAP.fetch(node.type))
28
- visit_terminated(right)
29
+ visit(right)
29
30
  end
30
31
  end # FlipFLop
31
32
  end # Emitter
@@ -13,6 +13,10 @@ module Unparser
13
13
 
14
14
  handle(*MAP.keys)
15
15
 
16
+ def terminated?
17
+ children.empty?
18
+ end
19
+
16
20
  private
17
21
 
18
22
  # Perform dispatch
@@ -22,9 +26,13 @@ module Unparser
22
26
  # @api private
23
27
  #
24
28
  def dispatch
25
- conditional_parentheses((parent_type.equal?(:or) || parent_type.equal?(:and)) && children.any?) do
26
- write(MAP.fetch(node.type))
27
- emit_arguments if children.any?
29
+ write(MAP.fetch(node.type))
30
+ case children.length
31
+ when 0
32
+ when 1
33
+ emit_single_argument
34
+ else
35
+ emit_arguments
28
36
  end
29
37
  end
30
38
 
@@ -53,8 +61,17 @@ module Unparser
53
61
  # @api private
54
62
  #
55
63
  def emit_argument(node)
56
- conditional_parentheses(PARENS.include?(node.type)) do
57
- visit(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)
58
75
  end
59
76
  end
60
77
 
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for for nodes
6
6
  class For < self
7
+ include Terminated
7
8
 
8
9
  handle :for
9
10
 
@@ -31,7 +32,7 @@ module Unparser
31
32
  # @api private
32
33
  #
33
34
  def emit_condition
34
- visit(condition)
35
+ visit_plain(condition)
35
36
  write(WS, K_IN, WS)
36
37
  visit(assignment)
37
38
  write(WS, K_DO)
@@ -4,11 +4,14 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter if nodes
6
6
  class If < self
7
-
8
7
  handle :if
9
8
 
10
9
  children :condition, :if_branch, :else_branch
11
10
 
11
+ def terminated?
12
+ !postcondition?
13
+ end
14
+
12
15
  private
13
16
 
14
17
  # Perform dispatch
@@ -46,7 +49,7 @@ module Unparser
46
49
  # @api private
47
50
  #
48
51
  def emit_postcondition
49
- visit(if_branch || else_branch)
52
+ visit_plain(if_branch || else_branch)
50
53
  write(WS, keyword, WS)
51
54
  emit_condition
52
55
  end
@@ -92,7 +95,11 @@ module Unparser
92
95
  # @api private
93
96
  #
94
97
  def emit_condition
95
- visit_terminated(condition)
98
+ if condition.type.equal?(:match_current_line)
99
+ visit_plain(condition)
100
+ else
101
+ visit(condition)
102
+ end
96
103
  end
97
104
 
98
105
  # Emit if branch
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Namespace class for literal emiters
6
6
  class Literal < self
7
+ include Terminated
7
8
  end # Literal
8
9
  end # Emitter
9
10
  end # Unparser
@@ -27,7 +27,7 @@ module Unparser
27
27
  #
28
28
  def dispatch
29
29
  write(OPEN)
30
- visit(subject)
30
+ visit_plain(subject)
31
31
  write(CLOSE)
32
32
  end
33
33
 
@@ -20,7 +20,7 @@ module Unparser
20
20
  def emit_value
21
21
  value_type = value.type
22
22
  conditional_parentheses(value_type.equal?(:if)) do
23
- visit_terminated(value)
23
+ visit(value)
24
24
  end
25
25
  end
26
26
 
@@ -28,6 +28,88 @@ module Unparser
28
28
 
29
29
  end # Inspect
30
30
 
31
+ # Emitter for complex literals
32
+ class Complex < self
33
+
34
+ handle :complex
35
+
36
+ RATIONAL_FORMAT = 'i'.freeze
37
+
38
+ MAP = IceNine.deep_freeze(
39
+ Float => :float,
40
+ Rational => :rational,
41
+ Fixnum => :int,
42
+ Bignum => :int
43
+ )
44
+
45
+ private
46
+
47
+ # Dispatch value
48
+ #
49
+ # @return [undefined]
50
+ #
51
+ def dispatch
52
+ emit_imaginary
53
+ write(RATIONAL_FORMAT)
54
+ end
55
+
56
+ # Emit imaginary component
57
+ #
58
+ # @return [undefined]
59
+ #
60
+ # @api private
61
+ #
62
+ def emit_imaginary
63
+ visit(imaginary_node)
64
+ end
65
+
66
+ # Return imaginary node
67
+ #
68
+ # @return [Parser::AST::Node]
69
+ #
70
+ # @api private
71
+ #
72
+ def imaginary_node
73
+ imaginary = value.imaginary
74
+ s(MAP.fetch(imaginary.class), imaginary)
75
+ end
76
+
77
+ end # Rational
78
+
79
+ # Emitter for rational literals
80
+ class Rational < self
81
+
82
+ handle :rational
83
+
84
+ RATIONAL_FORMAT = 'r'.freeze
85
+
86
+ private
87
+
88
+ # Dispatch value
89
+ #
90
+ # @return [undefined]
91
+ #
92
+ def dispatch
93
+ integer = value.to_i
94
+ float = value.to_f
95
+
96
+ write_rational(integer.to_f.equal?(float) ? integer : float)
97
+ end
98
+
99
+ # Write rational format
100
+ #
101
+ # @param [#to_s]
102
+ #
103
+ # @return [undefined]
104
+ #
105
+ # @api private
106
+ #
107
+ def write_rational(value)
108
+ write(value.to_s, RATIONAL_FORMAT)
109
+ end
110
+
111
+ end # Rational
112
+
31
113
  # Emiter for numeric literals
32
114
  class Numeric < self
33
115
 
@@ -42,7 +124,7 @@ module Unparser
42
124
  # @api private
43
125
  #
44
126
  def dispatch
45
- conditional_parentheses(parent.kind_of?(Emitter::Send) && value < 0) do
127
+ conditional_parentheses(parent.is_a?(Emitter::Send) && value < 0) do
46
128
  write(value.inspect)
47
129
  end
48
130
  end
@@ -5,6 +5,7 @@ module Unparser
5
5
  class Literal
6
6
  # Abstract base class for literal range emitter
7
7
  class Range < self
8
+ include Unterminated
8
9
 
9
10
  TOKENS = IceNine.deep_freeze(
10
11
  irange: '..',
@@ -24,9 +25,9 @@ module Unparser
24
25
  # @api private
25
26
  #
26
27
  def dispatch
27
- visit_terminated(begin_node)
28
+ visit(begin_node)
28
29
  write(TOKENS.fetch(node.type))
29
- visit_terminated(end_node)
30
+ visit(end_node)
30
31
  end
31
32
 
32
33
  end # Range
@@ -5,6 +5,7 @@ module Unparser
5
5
 
6
6
  # Base class for special match node emitters
7
7
  class Match < self
8
+ include Unterminated
8
9
 
9
10
  OPERATOR = '=~'.freeze
10
11
 
@@ -4,7 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for module nodes
6
6
  class Module < self
7
- include LocalVariableRoot
7
+ include LocalVariableRoot, Terminated
8
8
 
9
9
  handle :module
10
10
 
@@ -5,6 +5,7 @@ module Unparser
5
5
 
6
6
  # Base class for and and or op-assign
7
7
  class BinaryAssign < self
8
+ include Unterminated
8
9
 
9
10
  children :target, :expression
10
11
 
@@ -26,13 +27,14 @@ module Unparser
26
27
  def dispatch
27
28
  visit(target)
28
29
  write(WS, MAP.fetch(node.type), WS)
29
- visit_terminated(expression)
30
+ visit(expression)
30
31
  end
31
32
 
32
33
  end # BinaryAssign
33
34
 
34
35
  # Emitter for op assign
35
36
  class OpAssign < self
37
+ include Unterminated
36
38
 
37
39
  handle :op_asgn
38
40
 
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for redo nodes
6
6
  class Redo < self
7
+ include Terminated
7
8
 
8
9
  handle :redo
9
10