unparser 0.0.1

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 (77) hide show
  1. checksums.yaml +7 -0
  2. data/.circle.yml +4 -0
  3. data/.gitignore +2 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +16 -0
  6. data/Changelog.md +3 -0
  7. data/Gemfile +6 -0
  8. data/Gemfile.devtools +60 -0
  9. data/Guardfile +18 -0
  10. data/README.md +41 -0
  11. data/Rakefile +24 -0
  12. data/TODO +1 -0
  13. data/config/devtools.yml +2 -0
  14. data/config/flay.yml +3 -0
  15. data/config/flog.yml +2 -0
  16. data/config/mutant.yml +3 -0
  17. data/config/reek.yml +107 -0
  18. data/config/yardstick.yml +2 -0
  19. data/lib/unparser/buffer.rb +93 -0
  20. data/lib/unparser/constants.rb +87 -0
  21. data/lib/unparser/emitter/alias.rb +27 -0
  22. data/lib/unparser/emitter/argument.rb +154 -0
  23. data/lib/unparser/emitter/assignment.rb +140 -0
  24. data/lib/unparser/emitter/begin.rb +179 -0
  25. data/lib/unparser/emitter/binary.rb +52 -0
  26. data/lib/unparser/emitter/block.rb +53 -0
  27. data/lib/unparser/emitter/break.rb +28 -0
  28. data/lib/unparser/emitter/case.rb +97 -0
  29. data/lib/unparser/emitter/cbase.rb +22 -0
  30. data/lib/unparser/emitter/class.rb +72 -0
  31. data/lib/unparser/emitter/def.rb +107 -0
  32. data/lib/unparser/emitter/defined.rb +27 -0
  33. data/lib/unparser/emitter/for.rb +50 -0
  34. data/lib/unparser/emitter/hookexe.rb +42 -0
  35. data/lib/unparser/emitter/if.rb +85 -0
  36. data/lib/unparser/emitter/literal/composed.rb +64 -0
  37. data/lib/unparser/emitter/literal/dynamic.rb +54 -0
  38. data/lib/unparser/emitter/literal/dynamic_body.rb +109 -0
  39. data/lib/unparser/emitter/literal/execute_string.rb +38 -0
  40. data/lib/unparser/emitter/literal/primitive.rb +49 -0
  41. data/lib/unparser/emitter/literal/range.rb +33 -0
  42. data/lib/unparser/emitter/literal/regexp.rb +96 -0
  43. data/lib/unparser/emitter/literal/singleton.rb +24 -0
  44. data/lib/unparser/emitter/literal.rb +7 -0
  45. data/lib/unparser/emitter/module.rb +37 -0
  46. data/lib/unparser/emitter/next.rb +22 -0
  47. data/lib/unparser/emitter/not.rb +25 -0
  48. data/lib/unparser/emitter/op_assign.rb +63 -0
  49. data/lib/unparser/emitter/redo.rb +22 -0
  50. data/lib/unparser/emitter/repetition.rb +33 -0
  51. data/lib/unparser/emitter/retry.rb +22 -0
  52. data/lib/unparser/emitter/return.rb +38 -0
  53. data/lib/unparser/emitter/root.rb +7 -0
  54. data/lib/unparser/emitter/send/binary.rb +100 -0
  55. data/lib/unparser/emitter/send/index.rb +82 -0
  56. data/lib/unparser/emitter/send/unary.rb +29 -0
  57. data/lib/unparser/emitter/send.rb +273 -0
  58. data/lib/unparser/emitter/splat.rb +24 -0
  59. data/lib/unparser/emitter/super.rb +46 -0
  60. data/lib/unparser/emitter/undef.rb +25 -0
  61. data/lib/unparser/emitter/variable.rb +83 -0
  62. data/lib/unparser/emitter/yield.rb +28 -0
  63. data/lib/unparser/emitter.rb +308 -0
  64. data/lib/unparser.rb +87 -0
  65. data/spec/integration/unparser/spike_spec.rb +914 -0
  66. data/spec/spec_helper.rb +13 -0
  67. data/spec/unit/unparser/buffer/append_spec.rb +23 -0
  68. data/spec/unit/unparser/buffer/content_spec.rb +38 -0
  69. data/spec/unit/unparser/buffer/indent_spec.rb +18 -0
  70. data/spec/unit/unparser/buffer/nl_spec.rb +16 -0
  71. data/spec/unit/unparser/buffer/unindent_spec.rb +18 -0
  72. data/spec/unit/unparser/class_methods/unparse_spec.rb +16 -0
  73. data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +17 -0
  74. data/spec/unit/unparser/emitter/class_methods/visit_spec.rb +37 -0
  75. data/spec/unit/unparser/emitter/source_map/class_methods/emit_spec.rb +20 -0
  76. data/unparser.gemspec +24 -0
  77. metadata +201 -0
@@ -0,0 +1,96 @@
1
+ module Unparser
2
+ class Emitter
3
+ class Literal
4
+
5
+ # Emitter for regexp literals
6
+ class Regexp < self
7
+ DELIMITER = '/'.freeze
8
+
9
+ handle :regexp
10
+
11
+ private
12
+
13
+ # Perform dispatch
14
+ #
15
+ # @return [undefined]
16
+ #
17
+ # @api private
18
+ #
19
+ def dispatch
20
+ parentheses(DELIMITER, DELIMITER) do
21
+ visit(dynamic_body)
22
+ end
23
+ visit(children.last)
24
+ end
25
+
26
+ # Return dynamic body
27
+ #
28
+ # @return [undefined]
29
+ #
30
+ # @api private
31
+ #
32
+ def dynamic_body
33
+ Parser::AST::Node.new(:dyn_regexp_body, dynamic_body_children)
34
+ end
35
+
36
+ # Return dynamic body children
37
+ #
38
+ # @return [Enumerable<Parser::AST::Node>]
39
+ #
40
+ # @api private
41
+ #
42
+ def dynamic_body_children
43
+ children[0..-2].map do |child|
44
+ escape(child)
45
+ end
46
+ end
47
+
48
+ # Return escaped child
49
+ #
50
+ # @return [Parser::AST::Node]
51
+ #
52
+ # @api private
53
+ #
54
+ def escape(child)
55
+ return child unless child.type == :str
56
+ source = child.children.first
57
+ Parser::AST::Node.new(:str, [Unparser.transquote(source, delimiter, DELIMITER)])
58
+ end
59
+
60
+ # Return closing delimiter
61
+ #
62
+ # @return [String]
63
+ #
64
+ # @api private
65
+ #
66
+ def delimiter
67
+ location = node.location
68
+ return DELIMITER unless location
69
+ location.expression.source[-1]
70
+ end
71
+ memoize :delimiter
72
+
73
+ end # Regexp
74
+
75
+ # Emitter for regexp options
76
+ class Regopt < self
77
+
78
+ handle :regopt
79
+
80
+ private
81
+
82
+ # Perform dispatch
83
+ #
84
+ # @return [undefined]
85
+ #
86
+ # @api private
87
+ #
88
+ def dispatch
89
+ write(children.map(&:to_s).join)
90
+ end
91
+
92
+ end # Regopt
93
+
94
+ end # Literal
95
+ end # Emitter
96
+ end # Unparser
@@ -0,0 +1,24 @@
1
+ module Unparser
2
+ class Emitter
3
+ class Literal
4
+ # Emiter for literal singletons
5
+ class Singleton < self
6
+
7
+ handle :self, :true, :false, :nil
8
+
9
+ private
10
+
11
+ # Perform dispatco
12
+ #
13
+ # @return [undefined]
14
+ #
15
+ # @api private
16
+ #
17
+ def dispatch
18
+ buffer.append(node.type.to_s)
19
+ end
20
+
21
+ end # Singleton
22
+ end # Literal
23
+ end # Emitter
24
+ end # Unparser
@@ -0,0 +1,7 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Namespace class for literal emiters
4
+ class Literal < self
5
+ end # Literal
6
+ end # Emitter
7
+ end # Unparser
@@ -0,0 +1,37 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for module nodes
4
+ class Module < self
5
+
6
+ handle :module
7
+
8
+ children :name, :body
9
+
10
+ private
11
+
12
+ # Perform dispatch
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ write(K_MODULE, WS)
20
+ visit(name)
21
+ emit_body
22
+ k_end
23
+ end
24
+
25
+ # Emit body
26
+ #
27
+ # @return [undefined]
28
+ #
29
+ # @api private
30
+ #
31
+ def emit_body
32
+ emit_non_nil_body(body)
33
+ end
34
+
35
+ end # Module
36
+ end # Emitter
37
+ end # Unparser
@@ -0,0 +1,22 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for next nodes
4
+ class Next < self
5
+
6
+ handle :next
7
+
8
+ private
9
+
10
+ # Perform dispatch
11
+ #
12
+ # @return [undefined]
13
+ #
14
+ # @api private
15
+ #
16
+ def dispatch
17
+ write(K_NEXT)
18
+ end
19
+
20
+ end # Next
21
+ end # Emitter
22
+ end # Unparser
@@ -0,0 +1,25 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for 1.8 only not node
4
+ class Not < self
5
+
6
+ handle :not
7
+
8
+ children :body
9
+
10
+ private
11
+
12
+ # Perform dispatch
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ write(O_NEG)
20
+ visit(body)
21
+ end
22
+
23
+ end # Not
24
+ end # Emitter
25
+ end # Unparser
@@ -0,0 +1,63 @@
1
+ module Unparser
2
+ class Emitter
3
+
4
+ # Base class for and and or op-assign
5
+ class BinaryAssign < self
6
+
7
+ children :target, :expression
8
+
9
+ MAP = IceNine.deep_freeze(
10
+ :and_asgn => '&&=',
11
+ :or_asgn => '||='
12
+ )
13
+
14
+ handle *MAP.keys
15
+
16
+ private
17
+
18
+ # Perform dispatch
19
+ #
20
+ # @return [undefined]
21
+ #
22
+ # @api private
23
+ #
24
+ def dispatch
25
+ visit(target)
26
+ write(WS, MAP.fetch(node.type), WS)
27
+ visit(expression)
28
+ end
29
+
30
+ end # BinaryAssign
31
+
32
+ # Emitter for op assign
33
+ class OpAssign < self
34
+
35
+ handle :op_asgn
36
+
37
+ private
38
+
39
+ # Perform dispatch
40
+ #
41
+ # @return [undefined]
42
+ #
43
+ # @api private
44
+ #
45
+ def dispatch
46
+ visit(first_child)
47
+ emit_operator
48
+ visit(children[2])
49
+ end
50
+
51
+ # Emit operator
52
+ #
53
+ # @return [undefined]
54
+ #
55
+ # @api private
56
+ #
57
+ def emit_operator
58
+ write(WS, children[1].to_s, O_ASN, WS)
59
+ end
60
+
61
+ end # OpAssign
62
+ end # Emitte
63
+ end # Unparser
@@ -0,0 +1,22 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for redo nodes
4
+ class Redo < self
5
+
6
+ handle :redo
7
+
8
+ private
9
+
10
+ # Perform dispatch
11
+ #
12
+ # @return [undefined]
13
+ #
14
+ # @api private
15
+ #
16
+ def dispatch
17
+ write(K_REDO)
18
+ end
19
+
20
+ end # Redo
21
+ end # Emitter
22
+ end # Unparser
@@ -0,0 +1,33 @@
1
+ module Unparser
2
+ class Emitter
3
+
4
+ # Base class for while and until emitters
5
+ class Repetition < self
6
+
7
+ MAP = {
8
+ :while => K_WHILE,
9
+ :until => K_UNTIL
10
+ }.freeze
11
+
12
+ handle *MAP.keys
13
+
14
+ children :condition, :body
15
+
16
+ private
17
+
18
+ # Perform dispatch
19
+ #
20
+ # @return [undefined]
21
+ #
22
+ # @api private
23
+ #
24
+ def dispatch
25
+ write(MAP.fetch(node.type), WS)
26
+ visit(condition)
27
+ indented { visit(body) }
28
+ k_end
29
+ end
30
+
31
+ end # Repetition
32
+ end # Emitter
33
+ end # Unparser
@@ -0,0 +1,22 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for retry nodes
4
+ class Retry < self
5
+
6
+ handle :retry
7
+
8
+ private
9
+
10
+ # Perform dispatch
11
+ #
12
+ # @return [undefined]
13
+ #
14
+ # @api private
15
+ #
16
+ def dispatch
17
+ write(K_RETRY)
18
+ end
19
+
20
+ end # Break
21
+ end # Emitter
22
+ end # Unparser
@@ -0,0 +1,38 @@
1
+ module Unparser
2
+ class Emitter
3
+ # Emitter for return nodes
4
+ class Return < self
5
+
6
+ handle :return
7
+
8
+ children :argument
9
+
10
+ private
11
+
12
+ # Perform dispatch
13
+ #
14
+ # @return [undefined]
15
+ #
16
+ # @api private
17
+ #
18
+ def dispatch
19
+ write(K_RETURN)
20
+ emit_argument
21
+ end
22
+
23
+ # Emit argument
24
+ #
25
+ # @return [undefined]
26
+ #
27
+ # @api private
28
+ #
29
+ def emit_argument
30
+ return unless argument
31
+ parentheses do
32
+ visit(argument)
33
+ end
34
+ end
35
+
36
+ end # Return
37
+ end # Emitter
38
+ end # Unparser
@@ -0,0 +1,7 @@
1
+ module Unparser
2
+ class Emitter
3
+ Root = ::Class.new(self) do
4
+ def initialize(); end
5
+ end.send(:new)
6
+ end
7
+ end
@@ -0,0 +1,100 @@
1
+ module Unparser
2
+ class Emitter
3
+ class Send
4
+ # Emitter for binary sends
5
+ class Binary < self
6
+
7
+ private
8
+
9
+ # Return undefined
10
+ #
11
+ # @return [undefined]
12
+ #
13
+ # @api private
14
+ #
15
+ def dispatch
16
+ emit_receiver
17
+ emit_operator
18
+ emit_right
19
+ end
20
+
21
+ # Emit receiver
22
+ #
23
+ # @return [undefined]
24
+ #
25
+ # @api private
26
+ #
27
+ def emit_receiver
28
+ emit_unambiguous_receiver
29
+ write(O_DOT) if parentheses?
30
+ end
31
+
32
+ # Emit operator
33
+ #
34
+ # @return [undefined]
35
+ #
36
+ # @api private
37
+ #
38
+ def emit_operator
39
+ parens = parentheses? ? EMPTY_STRING : WS
40
+ parentheses(parens, parens) { write(selector) }
41
+ end
42
+
43
+ # Return right node
44
+ #
45
+ # @return [Parser::AST::Node]
46
+ #
47
+ # @api private
48
+ #
49
+ def right_node
50
+ children[2]
51
+ end
52
+
53
+ # Test for splat argument
54
+ #
55
+ # @return [true]
56
+ # if first argument is a splat
57
+ #
58
+ # @return [false]
59
+ # otherwise
60
+ #
61
+ # @api private
62
+ #
63
+ def splat?
64
+ right_node.type == :splat
65
+ end
66
+
67
+ # Test if parentheses are needed
68
+ #
69
+ # @return [true]
70
+ # if parenthes are needed
71
+ #
72
+ # @return [false]
73
+ # otherwise
74
+ #
75
+ # @api private
76
+ #
77
+ def parentheses?
78
+ splat? || children.length >= 4
79
+ end
80
+ memoize :parentheses?
81
+
82
+ # Emit right
83
+ #
84
+ # @return [undefined]
85
+ #
86
+ # @api private
87
+ #
88
+ def emit_right
89
+ node = right_node
90
+ if parentheses?
91
+ parentheses { delimited(children[2..-1]) }
92
+ return
93
+ end
94
+ visit(node)
95
+ end
96
+
97
+ end # Binary
98
+ end # Send
99
+ end # Emitter
100
+ end # Unparser
@@ -0,0 +1,82 @@
1
+ module Unparser
2
+ class Emitter
3
+ class Send
4
+ # Emitter for send to index references
5
+ class Index < self
6
+
7
+ private
8
+
9
+ # Perform dispatch
10
+ #
11
+ # @return [undefined]
12
+ #
13
+ # @api private
14
+ #
15
+ def dispatch
16
+ emit_receiver
17
+ emit_arguments
18
+ end
19
+
20
+ # Emit block within parentheses
21
+ #
22
+ # @return [undefined]
23
+ #
24
+ # @api private
25
+ #
26
+ def parentheses(&block)
27
+ super(*INDEX_PARENS, &block)
28
+ end
29
+
30
+ # Emit receiver
31
+ #
32
+ # @return [undefined]
33
+ #
34
+ # @api private
35
+ #
36
+ def emit_receiver
37
+ visit(first_child)
38
+ end
39
+
40
+ # Emitter for index reference nodes
41
+ class Reference < self
42
+
43
+ private
44
+
45
+ # Emit arguments
46
+ #
47
+ # @return [undefined]
48
+ #
49
+ # @api private
50
+ #
51
+ def emit_arguments
52
+ parentheses do
53
+ delimited(arguments)
54
+ end
55
+ end
56
+ end # Reference
57
+
58
+ # Emitter for assign to index nodes
59
+ class Assign < self
60
+
61
+ # Emit arguments
62
+ #
63
+ # @return [undefined]
64
+ #
65
+ # @api private
66
+ #
67
+ def emit_arguments
68
+ index, *assignment = arguments
69
+ parentheses do
70
+ delimited([index])
71
+ end
72
+ return if assignment.empty? # mlhs
73
+ write(WS, O_ASN, WS)
74
+ delimited(assignment)
75
+ end
76
+
77
+ end # Assign
78
+
79
+ end # Index
80
+ end # Send
81
+ end # Emitter
82
+ end # Unparser
@@ -0,0 +1,29 @@
1
+ module Unparser
2
+ class Emitter
3
+ class Send
4
+ # Emitter for unary sends
5
+ class Unary < self
6
+
7
+ private
8
+
9
+ MAP = IceNine.deep_freeze(
10
+ '-@' => '-',
11
+ '+@' => '+'
12
+ )
13
+
14
+ # Perform dispatch
15
+ #
16
+ # @return [undefined]
17
+ #
18
+ # @api private
19
+ #
20
+ def dispatch
21
+ name = selector
22
+ write(MAP.fetch(name, name))
23
+ emit_unambiguous_receiver
24
+ end
25
+
26
+ end # Unary
27
+ end # Send
28
+ end # Emitter
29
+ end # Unparser