unparser 0.1.15 → 0.1.16

Sign up to get free protection for your applications and to get access to all the features.
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