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
@@ -5,6 +5,7 @@ module Unparser
5
5
 
6
6
  # Emitter for postconditions
7
7
  class Post < self
8
+ include Unterminated
8
9
 
9
10
  handle :while_post, :until_post
10
11
 
@@ -32,6 +33,7 @@ module Unparser
32
33
 
33
34
  # Base class for while and until emitters
34
35
  class Repetition < self
36
+ include Terminated
35
37
 
36
38
  MAP = {
37
39
  while: K_WHILE,
@@ -87,7 +89,7 @@ module Unparser
87
89
  #
88
90
  def emit_normal
89
91
  emit_keyword
90
- visit_terminated(condition)
92
+ visit(condition)
91
93
  emit_body
92
94
  k_end
93
95
  end
@@ -99,10 +101,10 @@ module Unparser
99
101
  # @api private
100
102
  #
101
103
  def emit_postcontrol
102
- visit(body)
104
+ visit_plain(body)
103
105
  ws
104
106
  emit_keyword
105
- visit(condition)
107
+ visit_plain(condition)
106
108
  end
107
109
 
108
110
  end # Repetition
@@ -19,8 +19,8 @@ module Unparser
19
19
  # @api private
20
20
  #
21
21
  def dispatch
22
- write(K_RESCUE)
23
- parentheses { visit(body) }
22
+ write(K_RESCUE, WS)
23
+ visit_plain(body)
24
24
  end
25
25
 
26
26
  # Emit exception
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for rescue nodes
6
6
  class Rescue < self
7
+ include Unterminated
7
8
 
8
9
  handle :rescue
9
10
 
@@ -56,7 +57,7 @@ module Unparser
56
57
  # @api private
57
58
  #
58
59
  def emit_standalone
59
- visit(body)
60
+ visit_plain(body)
60
61
  ws
61
62
  run(Resbody::Standalone, rescue_body)
62
63
  end
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for retry nodes
6
6
  class Retry < self
7
+ include Terminated
7
8
 
8
9
  handle :retry
9
10
 
@@ -16,17 +16,8 @@ module Unparser
16
16
 
17
17
  children :receiver, :selector
18
18
 
19
- # Test for terminated expression
20
- #
21
- # @return [Boolean]
22
- #
23
- # @api private
24
- #
25
19
  def terminated?
26
- [
27
- Index::Reference,
28
- Regular
29
- ].include?(effective_emitter)
20
+ effective_emitter.terminated?
30
21
  end
31
22
 
32
23
  private
@@ -38,16 +29,26 @@ module Unparser
38
29
  # @api private
39
30
  #
40
31
  def dispatch
41
- effective_emitter.new(node, parent).write_to_buffer
32
+ effective_emitter.write_to_buffer
42
33
  end
43
34
 
44
35
  # Return effective emitter
45
36
  #
46
- # @return [Class:Emitter]
37
+ # @return [Emitter]
47
38
  #
48
39
  # @api private
49
40
  #
50
41
  def effective_emitter
42
+ effective_emitter_class.new(node, parent)
43
+ end
44
+
45
+ # Return effective emitter
46
+ #
47
+ # @return [Class:Emitter]
48
+ #
49
+ # @api private
50
+ #
51
+ def effective_emitter_class
51
52
  case selector
52
53
  when INDEX_REFERENCE
53
54
  Index::Reference
@@ -57,7 +58,6 @@ module Unparser
57
58
  non_index_emitter
58
59
  end
59
60
  end
60
- memoize :effective_emitter
61
61
 
62
62
  # Return non index emitter
63
63
  #
@@ -86,7 +86,6 @@ module Unparser
86
86
  def string_selector
87
87
  selector.to_s
88
88
  end
89
- memoize :string_selector
90
89
 
91
90
  # Test for unary operator implemented as method
92
91
  #
@@ -3,7 +3,6 @@
3
3
  module Unparser
4
4
  class Emitter
5
5
  class Send
6
-
7
6
  # Emitter for arguments of send nodes
8
7
  class Arguments < Emitter
9
8
 
@@ -19,7 +18,7 @@ module Unparser
19
18
  return if children.empty?
20
19
 
21
20
  parentheses do
22
- delimited(effective_arguments)
21
+ delimited_plain(effective_arguments)
23
22
  end
24
23
  end
25
24
 
@@ -5,6 +5,7 @@ module Unparser
5
5
  class Send
6
6
  # Emitter for send as attribute assignment
7
7
  class AttributeAssignment < self
8
+ include Unterminated
8
9
 
9
10
  # Perform regular dispatch
10
11
  #
@@ -16,7 +17,7 @@ module Unparser
16
17
  emit_receiver
17
18
  emit_attribute
18
19
  emit_operator
19
- visit_terminated(arguments.first)
20
+ visit(arguments.first)
20
21
  end
21
22
 
22
23
  private
@@ -28,7 +29,7 @@ module Unparser
28
29
  # @api private
29
30
  #
30
31
  def emit_receiver
31
- visit_terminated(receiver)
32
+ visit(receiver)
32
33
  write(T_DOT)
33
34
  end
34
35
 
@@ -5,6 +5,7 @@ module Unparser
5
5
  class Send
6
6
  # Emitter for binary sends
7
7
  class Binary < self
8
+ include Unterminated
8
9
 
9
10
  private
10
11
 
@@ -15,7 +16,7 @@ module Unparser
15
16
  # @api private
16
17
  #
17
18
  def dispatch
18
- visit_terminated(receiver)
19
+ visit(receiver)
19
20
  emit_operator
20
21
  emit_right
21
22
  end
@@ -47,7 +48,7 @@ module Unparser
47
48
  # @api private
48
49
  #
49
50
  def emit_right
50
- visit_terminated(right_node)
51
+ visit(right_node)
51
52
  end
52
53
 
53
54
  end # Binary
@@ -26,11 +26,12 @@ module Unparser
26
26
  # @api private
27
27
  #
28
28
  def emit_receiver
29
- visit_terminated(first_child)
29
+ visit(first_child)
30
30
  end
31
31
 
32
32
  # Emitter for index reference nodes
33
33
  class Reference < self
34
+ include Terminated
34
35
 
35
36
  private
36
37
 
@@ -42,13 +43,26 @@ module Unparser
42
43
  #
43
44
  def emit_operation
44
45
  parentheses(*INDEX_PARENS) do
45
- delimited(arguments)
46
+ delimited_plain(arguments)
46
47
  end
47
48
  end
48
49
  end # Reference
49
50
 
50
51
  # Emitter for assign to index nodes
51
52
  class Assign < self
53
+ include Unterminated
54
+
55
+ # Test if assign will be emitted terminated
56
+ #
57
+ # @return [Boolean]
58
+ #
59
+ # @api private
60
+ #
61
+ def terminated?
62
+ mlhs?
63
+ end
64
+
65
+ private
52
66
 
53
67
  define_group(:indices, 2..-2)
54
68
  define_child(:value, -1)
@@ -5,6 +5,7 @@ module Unparser
5
5
  class Send
6
6
  # Emitter for "regular" receiver.selector(arguments...) case
7
7
  class Regular < self
8
+ include Terminated
8
9
 
9
10
  private
10
11
 
@@ -28,7 +29,7 @@ module Unparser
28
29
  #
29
30
  def emit_receiver
30
31
  return unless first_child
31
- visit_terminated(receiver)
32
+ visit(receiver)
32
33
  write(T_DOT)
33
34
  end
34
35
 
@@ -5,6 +5,7 @@ module Unparser
5
5
  class Send
6
6
  # Emitter for unary sends
7
7
  class Unary < self
8
+ include Unterminated
8
9
 
9
10
  private
10
11
 
@@ -26,7 +27,7 @@ module Unparser
26
27
  write('+')
27
28
  end
28
29
 
29
- visit_terminated(receiver)
30
+ visit(receiver)
30
31
  end
31
32
 
32
33
  end # Unary
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for splats
6
6
  class KwSplat < self
7
+ include Terminated
7
8
 
8
9
  handle :kwsplat
9
10
 
@@ -25,6 +26,7 @@ module Unparser
25
26
 
26
27
  # Emitter for splats
27
28
  class Splat < self
29
+ include Terminated
28
30
 
29
31
  handle :splat
30
32
 
@@ -5,6 +5,7 @@ module Unparser
5
5
 
6
6
  # Emitter for zsuper nodes
7
7
  class ZSuper < self
8
+ include Terminated
8
9
 
9
10
  handle :zsuper
10
11
 
@@ -24,6 +25,7 @@ module Unparser
24
25
 
25
26
  # Emitter for super nodes
26
27
  class Super < self
28
+ include Terminated
27
29
 
28
30
  handle :super
29
31
 
@@ -4,6 +4,7 @@ module Unparser
4
4
  class Emitter
5
5
  # Emitter for undef nodes
6
6
  class Undef < self
7
+ include Unterminated
7
8
 
8
9
  handle :undef
9
10
 
@@ -5,6 +5,7 @@ module Unparser
5
5
 
6
6
  # Emitter for various variable accesses
7
7
  class Variable < self
8
+ include Terminated
8
9
 
9
10
  handle :ivar, :lvar, :cvar, :gvar, :back_ref
10
11
 
@@ -26,6 +27,7 @@ module Unparser
26
27
 
27
28
  # Emitter for constant access
28
29
  class Const < self
30
+ include Terminated
29
31
 
30
32
  handle :const
31
33
 
@@ -59,6 +61,8 @@ module Unparser
59
61
 
60
62
  # Emitter for nth_ref nodes (regexp captures)
61
63
  class NthRef < self
64
+ include Terminated
65
+
62
66
  PREFIX = '$'.freeze
63
67
  handle :nth_ref
64
68
 
@@ -5,6 +5,7 @@ module Unparser
5
5
 
6
6
  # Emitter for yield node
7
7
  class Yield < self
8
+ include Terminated
8
9
 
9
10
  handle :yield
10
11
 
@@ -3,7 +3,7 @@
3
3
  module Unparser
4
4
  # Preprocessor to normalize AST generated by parser
5
5
  class Preprocessor
6
- include Adamantium::Flat, NodeHelpers, AbstractType, Concord.new(:node), Procto.call(:result)
6
+ include Adamantium::Flat, NodeHelpers, AbstractType, Concord.new(:node, :parent_type), Procto.call(:result)
7
7
 
8
8
  # Return preprocessor result
9
9
  #
@@ -23,10 +23,10 @@ module Unparser
23
23
  #
24
24
  # @api private
25
25
  #
26
- def self.run(node)
26
+ def self.run(node, parent_type = nil)
27
27
  return EMPTY if node.nil?
28
28
  REGISTRY.fetch(node.type, [Noop]).reduce(node) do |current, processor|
29
- processor.call(current)
29
+ processor.call(current, parent_type)
30
30
  end
31
31
  end
32
32
 
@@ -49,14 +49,14 @@ module Unparser
49
49
 
50
50
  # Visit node
51
51
  #
52
- # @param [Parser::AST::Node]
52
+ # @param [Parser::AST::Node] child
53
53
  #
54
54
  # @return [undefined]
55
55
  #
56
56
  # @api private
57
57
  #
58
- def visit(node)
59
- self.class.run(node)
58
+ def visit(child)
59
+ self.class.run(child, node.type)
60
60
  end
61
61
 
62
62
  # Return children
@@ -77,7 +77,7 @@ module Unparser
77
77
  #
78
78
  def visited_children
79
79
  children.map do |node|
80
- if node.kind_of?(Parser::AST::Node)
80
+ if node.is_a?(Parser::AST::Node)
81
81
  visit(node)
82
82
  else
83
83
  node
@@ -155,6 +155,12 @@ module Unparser
155
155
  class CompactDSTR < self
156
156
 
157
157
  register :dstr
158
+ register :dsym
159
+
160
+ MAP = IceNine.deep_freeze(
161
+ dstr: :str,
162
+ dsym: :sym
163
+ )
158
164
 
159
165
  # Return preprocessor result
160
166
  #
@@ -163,8 +169,8 @@ module Unparser
163
169
  # @api private
164
170
  #
165
171
  def result
166
- if children.all? { |child| child.type.equal?(:str) }
167
- node.updated(:str, [children.map { |child| child.children.first }.join])
172
+ if children.any? && children.all? { |child| child.type.equal?(:str) }
173
+ node.updated(MAP.fetch(node.type), [children.map { |child| child.children.first }.join])
168
174
  else
169
175
  node
170
176
  end
@@ -201,7 +207,8 @@ module Unparser
201
207
 
202
208
  # Preprocessor for begin nodes. Removes begin nodes with one child.
203
209
  #
204
- # These superflownosely currently get generated by unparser.
210
+ # This reduces the amount of complex logic needed inside unparser to emit "nice" syntax with minimal
211
+ # tokens.
205
212
  #
206
213
  class Begin < self
207
214
 
@@ -214,10 +221,10 @@ module Unparser
214
221
  # @api private
215
222
  #
216
223
  def result
217
- if children.one?
224
+ if children.one? && !parent_type.equal?(:regexp)
218
225
  visit(children.first)
219
226
  else
220
- Noop.call(node)
227
+ Noop.call(node, parent_type)
221
228
  end
222
229
  end
223
230