unparser 0.0.18 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -0
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/reek.yml +1 -1
- data/lib/unparser.rb +2 -2
- data/lib/unparser/constants.rb +5 -0
- data/lib/unparser/emitter.rb +61 -32
- data/lib/unparser/emitter/begin.rb +1 -19
- data/lib/unparser/emitter/binary.rb +11 -22
- data/lib/unparser/emitter/flipflop.rb +2 -2
- data/lib/unparser/emitter/literal/range.rb +2 -2
- data/lib/unparser/emitter/root.rb +6 -5
- data/lib/unparser/emitter/send.rb +44 -93
- data/lib/unparser/emitter/send/binary.rb +2 -12
- data/lib/unparser/emitter/send/index.rb +1 -1
- data/lib/unparser/emitter/send/regular.rb +36 -0
- data/lib/unparser/emitter/send/unary.rb +1 -1
- data/lib/unparser/emitter/variable.rb +6 -6
- data/spec/unit/unparser_spec.rb +21 -22
- data/unparser.gemspec +1 -1
- metadata +20 -12
- checksums.yaml +0 -7
- data/lib/unparser/emitter/not.rb +0 -25
- data/spec/unit/unparser/class_methods/unparse_spec.rb +0 -16
- data/spec/unit/unparser/emitter/class_methods/visit_spec.rb +0 -37
data/README.md
CHANGED
@@ -11,6 +11,8 @@ This library is in early development stage and still has some bugs/missing featu
|
|
11
11
|
Nevertheless it is able to regenerate it own source and serves well for
|
12
12
|
[mutant](https://github.cm/mbj/mutant) mutators and the in-memory vendoring for self hosting mutant.
|
13
13
|
|
14
|
+
This library dropped the reproduction of 1.8 syntax in the 0.1.0 release.
|
15
|
+
|
14
16
|
Usage
|
15
17
|
-----
|
16
18
|
|
data/config/flay.yml
CHANGED
data/config/flog.yml
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
---
|
2
|
-
threshold:
|
2
|
+
threshold: 13.1
|
data/config/reek.yml
CHANGED
@@ -37,7 +37,7 @@ FeatureEnvy:
|
|
37
37
|
exclude:
|
38
38
|
- Unparser::Emitter::Literal::Regexp#escape # TODO Fixme!
|
39
39
|
- Unparser::Emitter::Send#binary_receiver?
|
40
|
-
- Unparser::Emitter
|
40
|
+
- Unparser::Emitter#visit_terminated
|
41
41
|
enabled: true
|
42
42
|
ClassVariable:
|
43
43
|
exclude: []
|
data/lib/unparser.rb
CHANGED
@@ -20,7 +20,7 @@ module Unparser
|
|
20
20
|
node = Parser::AST::Node.new(:empty)
|
21
21
|
end
|
22
22
|
buffer = Buffer.new
|
23
|
-
Emitter.
|
23
|
+
Emitter.emitter(node, Emitter::Root.new(buffer)).write_to_buffer
|
24
24
|
buffer.content
|
25
25
|
end
|
26
26
|
|
@@ -57,6 +57,7 @@ require 'unparser/emitter/send'
|
|
57
57
|
require 'unparser/emitter/send/unary'
|
58
58
|
require 'unparser/emitter/send/binary'
|
59
59
|
require 'unparser/emitter/send/index'
|
60
|
+
require 'unparser/emitter/send/regular'
|
60
61
|
require 'unparser/emitter/block'
|
61
62
|
require 'unparser/emitter/assignment'
|
62
63
|
require 'unparser/emitter/variable'
|
@@ -80,7 +81,6 @@ require 'unparser/emitter/next'
|
|
80
81
|
require 'unparser/emitter/if'
|
81
82
|
require 'unparser/emitter/alias'
|
82
83
|
require 'unparser/emitter/yield'
|
83
|
-
require 'unparser/emitter/not'
|
84
84
|
require 'unparser/emitter/binary'
|
85
85
|
require 'unparser/emitter/case'
|
86
86
|
require 'unparser/emitter/for'
|
data/lib/unparser/constants.rb
CHANGED
@@ -75,6 +75,10 @@ module Unparser
|
|
75
75
|
K_FILE = '__FILE__'
|
76
76
|
K_THEN = 'then'
|
77
77
|
|
78
|
+
TERMINATED = [
|
79
|
+
:int, :float, :self, :kwbegin, :const, :regexp
|
80
|
+
].to_set
|
81
|
+
|
78
82
|
KEYWORDS = constants.each_with_object([]) do |name, keywords|
|
79
83
|
value = const_get(name).freeze
|
80
84
|
if name.to_s.start_with?('K_')
|
@@ -82,5 +86,6 @@ module Unparser
|
|
82
86
|
end
|
83
87
|
end.to_set.freeze
|
84
88
|
|
89
|
+
|
85
90
|
end # Constants
|
86
91
|
end # Unparser
|
data/lib/unparser/emitter.rb
CHANGED
@@ -3,7 +3,7 @@ module Unparser
|
|
3
3
|
# Emitter base class
|
4
4
|
class Emitter
|
5
5
|
include Adamantium::Flat, AbstractType, Constants
|
6
|
-
include
|
6
|
+
include Concord.new(:node, :parent)
|
7
7
|
|
8
8
|
# Registry for node emitters
|
9
9
|
REGISTRY = {}
|
@@ -77,49 +77,40 @@ module Unparser
|
|
77
77
|
end
|
78
78
|
private_class_method :handle
|
79
79
|
|
80
|
-
#
|
80
|
+
# Trigger write to buffer
|
81
81
|
#
|
82
82
|
# @return [self]
|
83
83
|
#
|
84
84
|
# @api private
|
85
85
|
#
|
86
|
-
def
|
87
|
-
|
86
|
+
def write_to_buffer
|
87
|
+
dispatch
|
88
88
|
self
|
89
89
|
end
|
90
|
+
memoize :write_to_buffer
|
90
91
|
|
91
|
-
#
|
92
|
-
#
|
93
|
-
# @param [Parser::AST::Node] node
|
94
|
-
# @param [Buffer] buffer
|
92
|
+
# Emit node
|
95
93
|
#
|
96
|
-
# @return [
|
94
|
+
# @return [self]
|
97
95
|
#
|
98
96
|
# @api private
|
99
97
|
#
|
100
|
-
def
|
101
|
-
|
102
|
-
dispatch
|
98
|
+
def self.emit(*arguments)
|
99
|
+
new(*arguments).write_to_buffer
|
103
100
|
end
|
104
101
|
|
105
|
-
|
106
|
-
|
107
|
-
# Visit node
|
108
|
-
#
|
109
|
-
# @param [Parser::AST::Node] node
|
110
|
-
# @param [Buffer] buffer
|
102
|
+
# Return emitter
|
111
103
|
#
|
112
104
|
# @return [Emitter]
|
113
105
|
#
|
114
106
|
# @api private
|
115
107
|
#
|
116
|
-
def self.
|
108
|
+
def self.emitter(node, parent)
|
117
109
|
type = node.type
|
118
|
-
|
110
|
+
klass = REGISTRY.fetch(type) do
|
119
111
|
raise ArgumentError, "No emitter for node: #{type.inspect}"
|
120
112
|
end
|
121
|
-
|
122
|
-
self
|
113
|
+
klass.new(node, parent)
|
123
114
|
end
|
124
115
|
|
125
116
|
# Dispatch node
|
@@ -138,23 +129,31 @@ module Unparser
|
|
138
129
|
#
|
139
130
|
attr_reader :node
|
140
131
|
|
141
|
-
#
|
132
|
+
# Test if node is emitted as terminated expression
|
142
133
|
#
|
143
|
-
# @return [
|
134
|
+
# @return [false]
|
135
|
+
# if emitted node is unambigous
|
136
|
+
#
|
137
|
+
# @return [true]
|
144
138
|
#
|
145
139
|
# @api private
|
146
140
|
#
|
147
|
-
|
148
|
-
|
141
|
+
def terminated?
|
142
|
+
TERMINATED.include?(node.type)
|
143
|
+
end
|
144
|
+
|
145
|
+
protected
|
149
146
|
|
150
|
-
# Return
|
147
|
+
# Return buffer
|
151
148
|
#
|
152
|
-
# @return [
|
149
|
+
# @return [Buffer] buffer
|
153
150
|
#
|
154
151
|
# @api private
|
155
152
|
#
|
156
|
-
|
157
|
-
|
153
|
+
def buffer
|
154
|
+
parent.buffer
|
155
|
+
end
|
156
|
+
memoize :buffer, :freezer => :noop
|
158
157
|
|
159
158
|
private
|
160
159
|
|
@@ -180,7 +179,7 @@ module Unparser
|
|
180
179
|
SourceMap.emit(node, buffer)
|
181
180
|
end
|
182
181
|
|
183
|
-
#
|
182
|
+
# Visit node
|
184
183
|
#
|
185
184
|
# @param [Parser::AST::Node] node
|
186
185
|
#
|
@@ -189,7 +188,37 @@ module Unparser
|
|
189
188
|
# @api private
|
190
189
|
#
|
191
190
|
def visit(node)
|
192
|
-
|
191
|
+
emitter = emitter(node)
|
192
|
+
emitter.write_to_buffer
|
193
|
+
end
|
194
|
+
|
195
|
+
# Visit unambigous node
|
196
|
+
#
|
197
|
+
# @param [Parser::AST::Node] node
|
198
|
+
#
|
199
|
+
# @return [undefined]
|
200
|
+
#
|
201
|
+
# @api private
|
202
|
+
#
|
203
|
+
def visit_terminated(node)
|
204
|
+
emitter = emitter(node)
|
205
|
+
unless emitter.terminated?
|
206
|
+
parentheses { emitter.write_to_buffer }
|
207
|
+
return
|
208
|
+
end
|
209
|
+
emitter.write_to_buffer
|
210
|
+
end
|
211
|
+
|
212
|
+
# Return emitter for node
|
213
|
+
#
|
214
|
+
# @param [Parser::AST::Node] node
|
215
|
+
#
|
216
|
+
# @return [Emitter]
|
217
|
+
#
|
218
|
+
# @api private
|
219
|
+
#
|
220
|
+
def emitter(node)
|
221
|
+
self.class.emitter(node, self)
|
193
222
|
end
|
194
223
|
|
195
224
|
# Emit delimited body
|
@@ -37,25 +37,7 @@ module Unparser
|
|
37
37
|
# @api private
|
38
38
|
#
|
39
39
|
def dispatch
|
40
|
-
|
41
|
-
parentheses { emit_inner }
|
42
|
-
else
|
43
|
-
emit_inner
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# Test if begin node needs to be enclosed within parentheses
|
48
|
-
#
|
49
|
-
# @return [true]
|
50
|
-
# if parentheses are needed
|
51
|
-
#
|
52
|
-
# @return [false]
|
53
|
-
# otherwise
|
54
|
-
#
|
55
|
-
# @api private
|
56
|
-
#
|
57
|
-
def parentheses?
|
58
|
-
children.length == 1 && children.first.type == :send && BINARY_OPERATORS.include?(children.first.children[1])
|
40
|
+
emit_inner
|
59
41
|
end
|
60
42
|
|
61
43
|
end # Implicit
|
@@ -3,7 +3,6 @@ module Unparser
|
|
3
3
|
# Base class for binary emitters
|
4
4
|
class Binary < self
|
5
5
|
|
6
|
-
handle :or, :and
|
7
6
|
children :left, :right
|
8
7
|
|
9
8
|
MAP = {
|
@@ -11,40 +10,30 @@ module Unparser
|
|
11
10
|
:and => T_AND
|
12
11
|
}.freeze
|
13
12
|
|
14
|
-
|
13
|
+
handle *MAP.keys
|
15
14
|
|
16
|
-
#
|
15
|
+
# Test if expression is terminated
|
17
16
|
#
|
18
|
-
# @return [
|
17
|
+
# @return [false]
|
19
18
|
#
|
20
19
|
# @api private
|
21
20
|
#
|
22
|
-
def
|
23
|
-
|
24
|
-
emit_left
|
25
|
-
write(WS, MAP.fetch(node.type), WS)
|
26
|
-
emit_right
|
27
|
-
end
|
21
|
+
def terminated?
|
22
|
+
false
|
28
23
|
end
|
29
24
|
|
30
|
-
|
31
|
-
#
|
32
|
-
# @return [undefined]
|
33
|
-
#
|
34
|
-
# @api private
|
35
|
-
#
|
36
|
-
def emit_left
|
37
|
-
parentheses { visit(left) }
|
38
|
-
end
|
25
|
+
private
|
39
26
|
|
40
|
-
#
|
27
|
+
# Perform dispatch
|
41
28
|
#
|
42
29
|
# @return [undefined]
|
43
30
|
#
|
44
31
|
# @api private
|
45
32
|
#
|
46
|
-
def
|
47
|
-
|
33
|
+
def dispatch
|
34
|
+
visit_terminated(left)
|
35
|
+
write(WS, MAP.fetch(node.type), WS)
|
36
|
+
visit_terminated(right)
|
48
37
|
end
|
49
38
|
|
50
39
|
end # Binary
|
@@ -16,140 +16,91 @@ module Unparser
|
|
16
16
|
|
17
17
|
children :receiver, :selector
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
# Perform dispatch
|
22
|
-
#
|
23
|
-
# @return [undefined]
|
19
|
+
# Test for terminated expression
|
24
20
|
#
|
25
|
-
# @
|
26
|
-
#
|
27
|
-
def dispatch
|
28
|
-
case selector
|
29
|
-
when INDEX_REFERENCE
|
30
|
-
run(Index::Reference)
|
31
|
-
when INDEX_ASSIGN
|
32
|
-
run(Index::Assign)
|
33
|
-
else
|
34
|
-
non_index_dispatch
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Return string selector
|
21
|
+
# @return [true]
|
22
|
+
# if send is terminated
|
39
23
|
#
|
40
|
-
# @return [
|
24
|
+
# @return [false]
|
25
|
+
# otherwise
|
41
26
|
#
|
42
27
|
# @api private
|
43
28
|
#
|
44
|
-
def
|
45
|
-
|
29
|
+
def terminated?
|
30
|
+
[
|
31
|
+
Unary,
|
32
|
+
Index::Reference,
|
33
|
+
Regular
|
34
|
+
].include?(effective_emitter)
|
46
35
|
end
|
47
|
-
memoize :string_selector
|
48
36
|
|
49
|
-
|
50
|
-
#
|
51
|
-
# @return [undefined]
|
52
|
-
#
|
53
|
-
# @api private
|
54
|
-
#
|
55
|
-
def emit_unambiguous_receiver
|
56
|
-
receiver = effective_receiver
|
57
|
-
if AMBIGOUS.include?(receiver.type) or binary_receiver?
|
58
|
-
parentheses { visit(receiver) }
|
59
|
-
return
|
60
|
-
end
|
61
|
-
|
62
|
-
visit(receiver)
|
63
|
-
end
|
37
|
+
private
|
64
38
|
|
65
|
-
#
|
39
|
+
# Perform dispatch
|
66
40
|
#
|
67
|
-
# @return [
|
41
|
+
# @return [undefined]
|
68
42
|
#
|
69
43
|
# @api private
|
70
44
|
#
|
71
|
-
def
|
72
|
-
|
73
|
-
children = receiver.children
|
74
|
-
if receiver.type == :begin && children.length == 1
|
75
|
-
receiver = children.first
|
76
|
-
end
|
77
|
-
receiver
|
45
|
+
def dispatch
|
46
|
+
run(effective_emitter)
|
78
47
|
end
|
79
48
|
|
80
|
-
#
|
49
|
+
# Return effective emitter
|
81
50
|
#
|
82
|
-
# @return [
|
83
|
-
# if receiver is a binary operation implemented by a method
|
84
|
-
#
|
85
|
-
# @return [false]
|
86
|
-
# otherwise
|
51
|
+
# @return [Class:Emitter]
|
87
52
|
#
|
88
53
|
# @api private
|
89
54
|
#
|
90
|
-
def
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
BINARY_OPERATORS.include?(receiver.children[1])
|
55
|
+
def effective_emitter
|
56
|
+
case selector
|
57
|
+
when INDEX_REFERENCE
|
58
|
+
Index::Reference
|
59
|
+
when INDEX_ASSIGN
|
60
|
+
Index::Assign
|
97
61
|
else
|
98
|
-
|
62
|
+
non_index_emitter
|
99
63
|
end
|
100
64
|
end
|
65
|
+
memoize :effective_emitter
|
101
66
|
|
102
|
-
#
|
103
|
-
#
|
104
|
-
# @param [Class:Emitter] emitter
|
67
|
+
# Return non index emitter
|
105
68
|
#
|
106
|
-
# @return [
|
69
|
+
# @return [Class:Emitter]
|
107
70
|
#
|
108
71
|
# @api private
|
109
72
|
#
|
110
|
-
def
|
111
|
-
emitter.emit(node, buffer, self)
|
112
|
-
end
|
113
|
-
|
114
|
-
# Perform non index dispatch
|
115
|
-
#
|
116
|
-
# @return [undefined]
|
117
|
-
#
|
118
|
-
# @api private
|
119
|
-
#
|
120
|
-
def non_index_dispatch
|
73
|
+
def non_index_emitter
|
121
74
|
if binary?
|
122
|
-
|
123
|
-
return
|
75
|
+
Binary
|
124
76
|
elsif unary?
|
125
|
-
|
126
|
-
|
77
|
+
Unary
|
78
|
+
else
|
79
|
+
Regular
|
127
80
|
end
|
128
|
-
regular_dispatch
|
129
81
|
end
|
130
82
|
|
131
|
-
#
|
83
|
+
# Return string selector
|
132
84
|
#
|
133
|
-
# @return [
|
85
|
+
# @return [String]
|
134
86
|
#
|
135
87
|
# @api private
|
136
88
|
#
|
137
|
-
def
|
138
|
-
|
139
|
-
emit_selector
|
140
|
-
emit_arguments
|
89
|
+
def string_selector
|
90
|
+
selector.to_s
|
141
91
|
end
|
92
|
+
memoize :string_selector
|
142
93
|
|
143
|
-
#
|
94
|
+
# Delegate to emitter
|
144
95
|
#
|
145
|
-
# @
|
96
|
+
# @param [Class:Emitter] emitter
|
97
|
+
#
|
98
|
+
# @return [undefined]
|
146
99
|
#
|
147
100
|
# @api private
|
148
101
|
#
|
149
|
-
def
|
150
|
-
|
151
|
-
emit_unambiguous_receiver
|
152
|
-
write(T_DOT)
|
102
|
+
def run(emitter)
|
103
|
+
emitter.new(node, self).write_to_buffer
|
153
104
|
end
|
154
105
|
|
155
106
|
# Test for unary operator implemented as method
|
@@ -13,21 +13,11 @@ module Unparser
|
|
13
13
|
# @api private
|
14
14
|
#
|
15
15
|
def dispatch
|
16
|
-
|
16
|
+
visit_terminated(receiver)
|
17
17
|
emit_operator
|
18
18
|
emit_right
|
19
19
|
end
|
20
20
|
|
21
|
-
# Emit receiver
|
22
|
-
#
|
23
|
-
# @return [undefined]
|
24
|
-
#
|
25
|
-
# @api private
|
26
|
-
#
|
27
|
-
def emit_receiver
|
28
|
-
emit_unambiguous_receiver
|
29
|
-
end
|
30
|
-
|
31
21
|
# Emit operator
|
32
22
|
#
|
33
23
|
# @return [undefined]
|
@@ -55,7 +45,7 @@ module Unparser
|
|
55
45
|
# @api private
|
56
46
|
#
|
57
47
|
def emit_right
|
58
|
-
|
48
|
+
visit_terminated(right_node)
|
59
49
|
end
|
60
50
|
|
61
51
|
end # Binary
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Unparser
|
2
|
+
class Emitter
|
3
|
+
class Send
|
4
|
+
# Emitter for "regular" receiver.selector(arguments...) case
|
5
|
+
class Regular < self
|
6
|
+
|
7
|
+
private
|
8
|
+
|
9
|
+
# Perform regular dispatch
|
10
|
+
#
|
11
|
+
# @return [undefined]
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
#
|
15
|
+
def dispatch
|
16
|
+
emit_receiver
|
17
|
+
emit_selector
|
18
|
+
emit_arguments
|
19
|
+
end
|
20
|
+
|
21
|
+
# Return receiver
|
22
|
+
#
|
23
|
+
# @return [Parser::AST::Node]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
#
|
27
|
+
def emit_receiver
|
28
|
+
return unless first_child
|
29
|
+
visit_terminated(receiver)
|
30
|
+
write(T_DOT)
|
31
|
+
end
|
32
|
+
|
33
|
+
end # Regular
|
34
|
+
end # Send
|
35
|
+
end # Emitter
|
36
|
+
end # Unparser
|
@@ -27,7 +27,7 @@ module Unparser
|
|
27
27
|
|
28
28
|
handle :const
|
29
29
|
|
30
|
-
children :
|
30
|
+
children :scope, :name
|
31
31
|
|
32
32
|
private
|
33
33
|
|
@@ -38,7 +38,7 @@ module Unparser
|
|
38
38
|
# @api private
|
39
39
|
#
|
40
40
|
def dispatch
|
41
|
-
|
41
|
+
emit_scope
|
42
42
|
write(name.to_s)
|
43
43
|
end
|
44
44
|
|
@@ -48,10 +48,10 @@ module Unparser
|
|
48
48
|
#
|
49
49
|
# @api private
|
50
50
|
#
|
51
|
-
def
|
52
|
-
return unless
|
53
|
-
visit(
|
54
|
-
if
|
51
|
+
def emit_scope
|
52
|
+
return unless scope
|
53
|
+
visit(scope)
|
54
|
+
if scope.type != :cbase
|
55
55
|
write(T_DCL)
|
56
56
|
end
|
57
57
|
end
|
data/spec/unit/unparser_spec.rb
CHANGED
@@ -4,7 +4,6 @@ describe Unparser do
|
|
4
4
|
describe '.unparse' do
|
5
5
|
|
6
6
|
PARSERS = IceNine.deep_freeze(
|
7
|
-
'1.8' => Parser::Ruby18,
|
8
7
|
'1.9' => Parser::Ruby19,
|
9
8
|
'2.0' => Parser::Ruby20,
|
10
9
|
'2.1' => Parser::Ruby21
|
@@ -88,8 +87,7 @@ describe Unparser do
|
|
88
87
|
assert_generates '0x1', '1'
|
89
88
|
assert_generates '1_000', '1000'
|
90
89
|
assert_generates '1e10', '10000000000.0'
|
91
|
-
assert_generates '?c', '"c"'
|
92
|
-
assert_generates '?c', '99', %w(1.8)
|
90
|
+
assert_generates '?c', '"c"'
|
93
91
|
end
|
94
92
|
|
95
93
|
context 'string' do
|
@@ -163,8 +161,8 @@ describe Unparser do
|
|
163
161
|
assert_source '[1]'
|
164
162
|
assert_source '[]'
|
165
163
|
assert_source '[1, *@foo]'
|
166
|
-
assert_source '[*@foo, 1]'
|
167
|
-
assert_source '[*@foo, *@baz]'
|
164
|
+
assert_source '[*@foo, 1]'
|
165
|
+
assert_source '[*@foo, *@baz]'
|
168
166
|
assert_generates '%w(foo bar)', %q(["foo", "bar"])
|
169
167
|
end
|
170
168
|
|
@@ -213,7 +211,7 @@ describe Unparser do
|
|
213
211
|
end
|
214
212
|
|
215
213
|
context 'magic keywords' do
|
216
|
-
assert_generates '__ENCODING__', 'Encoding::UTF_8'
|
214
|
+
assert_generates '__ENCODING__', 'Encoding::UTF_8'
|
217
215
|
assert_source '__FILE__'
|
218
216
|
assert_source '__LINE__'
|
219
217
|
end
|
@@ -321,10 +319,11 @@ describe Unparser do
|
|
321
319
|
|
322
320
|
# Special cases
|
323
321
|
assert_source '(1..2).max'
|
322
|
+
assert_source '(a = b).bar'
|
324
323
|
|
325
324
|
assert_source 'foo.bar(*args)'
|
326
|
-
assert_source 'foo.bar(*arga, foo, *argb)'
|
327
|
-
assert_source 'foo.bar(*args, foo)'
|
325
|
+
assert_source 'foo.bar(*arga, foo, *argb)'
|
326
|
+
assert_source 'foo.bar(*args, foo)'
|
328
327
|
assert_source 'foo.bar(foo, *args)'
|
329
328
|
assert_source 'foo.bar(foo, *args, &block)'
|
330
329
|
assert_source <<-RUBY
|
@@ -894,31 +893,30 @@ describe Unparser do
|
|
894
893
|
|
895
894
|
context 'binary operator methods' do
|
896
895
|
%w(+ - * / & | << >> == === != <= < <=> > >= =~ !~ ^ **).each do |operator|
|
897
|
-
|
898
|
-
assert_source "
|
899
|
-
assert_source "left.#{operator}(
|
900
|
-
assert_source "
|
901
|
-
assert_source "
|
902
|
-
assert_source "a #{operator} b"
|
903
|
-
assert_source "(a #{operator} b).foo", rubies
|
896
|
+
assert_source "1 #{operator} 2"
|
897
|
+
assert_source "left.#{operator}(*foo)"
|
898
|
+
assert_source "left.#{operator}(a, b)"
|
899
|
+
assert_source "self #{operator} b"
|
900
|
+
assert_source "a #{operator} b"
|
901
|
+
assert_source "(a #{operator} b).foo"
|
904
902
|
end
|
905
903
|
end
|
906
904
|
|
907
905
|
context 'nested binary operators' do
|
908
906
|
assert_source '(a + b) / (c - d)'
|
909
|
-
assert_source '(a + b) /
|
910
|
-
assert_source '(a + b) /
|
907
|
+
assert_source '(a + b) / c.-(e, f)'
|
908
|
+
assert_source '(a + b) / c.-(*f)'
|
911
909
|
end
|
912
910
|
|
913
911
|
context 'binary operator' do
|
914
|
-
assert_source '
|
915
|
-
assert_source '(
|
916
|
-
assert_source '(
|
917
|
-
assert_source '
|
912
|
+
assert_source 'a || (break(foo))'
|
913
|
+
assert_source '(break(foo)) || (a)'
|
914
|
+
assert_source '(a || b).foo'
|
915
|
+
assert_source 'a || (b || c)'
|
918
916
|
end
|
919
917
|
|
920
918
|
{ :or => :'||', :and => :'&&' }.each do |word, symbol|
|
921
|
-
assert_generates "a #{word} break foo", "
|
919
|
+
assert_generates "a #{word} break foo", "a #{symbol} (break(foo))"
|
922
920
|
end
|
923
921
|
|
924
922
|
context 'expansion of shortcuts' do
|
@@ -1028,6 +1026,7 @@ describe Unparser do
|
|
1028
1026
|
context 'unary operators' do
|
1029
1027
|
assert_source '!1'
|
1030
1028
|
assert_source '!!1'
|
1029
|
+
assert_source '!(!1).baz'
|
1031
1030
|
assert_source '~a'
|
1032
1031
|
assert_source '-a'
|
1033
1032
|
assert_source '+a'
|
data/unparser.gemspec
CHANGED
metadata
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unparser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Markus Schirp
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
12
|
+
date: 2013-09-05 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: parser
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
19
|
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
@@ -20,6 +22,7 @@ dependencies:
|
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
27
|
- - ~>
|
25
28
|
- !ruby/object:Gem::Version
|
@@ -27,6 +30,7 @@ dependencies:
|
|
27
30
|
- !ruby/object:Gem::Dependency
|
28
31
|
name: concord
|
29
32
|
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
30
34
|
requirements:
|
31
35
|
- - ~>
|
32
36
|
- !ruby/object:Gem::Version
|
@@ -34,6 +38,7 @@ dependencies:
|
|
34
38
|
type: :runtime
|
35
39
|
prerelease: false
|
36
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
37
42
|
requirements:
|
38
43
|
- - ~>
|
39
44
|
- !ruby/object:Gem::Version
|
@@ -41,6 +46,7 @@ dependencies:
|
|
41
46
|
- !ruby/object:Gem::Dependency
|
42
47
|
name: adamantium
|
43
48
|
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
44
50
|
requirements:
|
45
51
|
- - ~>
|
46
52
|
- !ruby/object:Gem::Version
|
@@ -48,6 +54,7 @@ dependencies:
|
|
48
54
|
type: :runtime
|
49
55
|
prerelease: false
|
50
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
51
58
|
requirements:
|
52
59
|
- - ~>
|
53
60
|
- !ruby/object:Gem::Version
|
@@ -55,6 +62,7 @@ dependencies:
|
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: equalizer
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
58
66
|
requirements:
|
59
67
|
- - ~>
|
60
68
|
- !ruby/object:Gem::Version
|
@@ -62,6 +70,7 @@ dependencies:
|
|
62
70
|
type: :runtime
|
63
71
|
prerelease: false
|
64
72
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
65
74
|
requirements:
|
66
75
|
- - ~>
|
67
76
|
- !ruby/object:Gem::Version
|
@@ -69,6 +78,7 @@ dependencies:
|
|
69
78
|
- !ruby/object:Gem::Dependency
|
70
79
|
name: abstract_type
|
71
80
|
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
72
82
|
requirements:
|
73
83
|
- - ~>
|
74
84
|
- !ruby/object:Gem::Version
|
@@ -76,6 +86,7 @@ dependencies:
|
|
76
86
|
type: :runtime
|
77
87
|
prerelease: false
|
78
88
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
79
90
|
requirements:
|
80
91
|
- - ~>
|
81
92
|
- !ruby/object:Gem::Version
|
@@ -141,7 +152,6 @@ files:
|
|
141
152
|
- lib/unparser/emitter/match.rb
|
142
153
|
- lib/unparser/emitter/module.rb
|
143
154
|
- lib/unparser/emitter/next.rb
|
144
|
-
- lib/unparser/emitter/not.rb
|
145
155
|
- lib/unparser/emitter/op_assign.rb
|
146
156
|
- lib/unparser/emitter/redo.rb
|
147
157
|
- lib/unparser/emitter/repetition.rb
|
@@ -153,6 +163,7 @@ files:
|
|
153
163
|
- lib/unparser/emitter/send.rb
|
154
164
|
- lib/unparser/emitter/send/binary.rb
|
155
165
|
- lib/unparser/emitter/send/index.rb
|
166
|
+
- lib/unparser/emitter/send/regular.rb
|
156
167
|
- lib/unparser/emitter/send/unary.rb
|
157
168
|
- lib/unparser/emitter/splat.rb
|
158
169
|
- lib/unparser/emitter/super.rb
|
@@ -166,35 +177,34 @@ files:
|
|
166
177
|
- spec/unit/unparser/buffer/indent_spec.rb
|
167
178
|
- spec/unit/unparser/buffer/nl_spec.rb
|
168
179
|
- spec/unit/unparser/buffer/unindent_spec.rb
|
169
|
-
- spec/unit/unparser/class_methods/unparse_spec.rb
|
170
180
|
- spec/unit/unparser/emitter/class_methods/handle_spec.rb
|
171
|
-
- spec/unit/unparser/emitter/class_methods/visit_spec.rb
|
172
181
|
- spec/unit/unparser/emitter/source_map/class_methods/emit_spec.rb
|
173
182
|
- spec/unit/unparser_spec.rb
|
174
183
|
- unparser.gemspec
|
175
184
|
homepage: http://github.com/mbj/unparser
|
176
185
|
licenses:
|
177
186
|
- MIT
|
178
|
-
metadata: {}
|
179
187
|
post_install_message:
|
180
188
|
rdoc_options: []
|
181
189
|
require_paths:
|
182
190
|
- lib
|
183
191
|
required_ruby_version: !ruby/object:Gem::Requirement
|
192
|
+
none: false
|
184
193
|
requirements:
|
185
|
-
- - '>='
|
194
|
+
- - ! '>='
|
186
195
|
- !ruby/object:Gem::Version
|
187
196
|
version: '0'
|
188
197
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
198
|
+
none: false
|
189
199
|
requirements:
|
190
|
-
- - '>='
|
200
|
+
- - ! '>='
|
191
201
|
- !ruby/object:Gem::Version
|
192
202
|
version: '0'
|
193
203
|
requirements: []
|
194
204
|
rubyforge_project:
|
195
|
-
rubygems_version:
|
205
|
+
rubygems_version: 1.8.23
|
196
206
|
signing_key:
|
197
|
-
specification_version:
|
207
|
+
specification_version: 3
|
198
208
|
summary: Generate equivalent source for parser gem AST nodes
|
199
209
|
test_files:
|
200
210
|
- spec/spec_helper.rb
|
@@ -203,9 +213,7 @@ test_files:
|
|
203
213
|
- spec/unit/unparser/buffer/indent_spec.rb
|
204
214
|
- spec/unit/unparser/buffer/nl_spec.rb
|
205
215
|
- spec/unit/unparser/buffer/unindent_spec.rb
|
206
|
-
- spec/unit/unparser/class_methods/unparse_spec.rb
|
207
216
|
- spec/unit/unparser/emitter/class_methods/handle_spec.rb
|
208
|
-
- spec/unit/unparser/emitter/class_methods/visit_spec.rb
|
209
217
|
- spec/unit/unparser/emitter/source_map/class_methods/emit_spec.rb
|
210
218
|
- spec/unit/unparser_spec.rb
|
211
219
|
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: e2fb94d62a7e99d2533e6507b8190ee433449b64
|
4
|
-
data.tar.gz: 6f3c81cd1f8a171c37ad49c4d1a135d4c8f2c49b
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 2a2a1ea342bee0e438770a92969087574aa086dd0ddce040b0e51d29fafefd7898b38b59661d7f71af297cb806b70c743ed4ff640cca0e66384e469caa120f51
|
7
|
-
data.tar.gz: fb25c1000ec5f4719a149ad85b260b2274d8bc87a5f1b55f0103f8e8be12a4a176ab89a74f4be514dd9116d3e2c6dd084b3b4f3ed4e3782d5804a5a329fe9749
|
data/lib/unparser/emitter/not.rb
DELETED
@@ -1,25 +0,0 @@
|
|
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(T_NEG)
|
20
|
-
visit(body)
|
21
|
-
end
|
22
|
-
|
23
|
-
end # Not
|
24
|
-
end # Emitter
|
25
|
-
end # Unparser
|
@@ -1,16 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Unparser, '.unparse' do
|
4
|
-
subject { described_class.unparse(node) }
|
5
|
-
|
6
|
-
let(:node) { double('Node') }
|
7
|
-
|
8
|
-
before do
|
9
|
-
described_class::Emitter.should_receive(:visit) do |node, buffer|
|
10
|
-
node.should be(node)
|
11
|
-
buffer.append('foo')
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
it { should eql('foo') }
|
16
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Unparser::Emitter, '.visit' do
|
4
|
-
subject { object.visit(node, buffer) }
|
5
|
-
let(:object) { described_class }
|
6
|
-
|
7
|
-
let(:node) { double('Node', :type => type, :source_map => nil) }
|
8
|
-
let(:buffer) { Unparser::Buffer.new }
|
9
|
-
|
10
|
-
before do
|
11
|
-
stub_const('Unparser::Emitter::REGISTRY', { :dummy => Dummy })
|
12
|
-
end
|
13
|
-
|
14
|
-
class Dummy < Unparser::Emitter
|
15
|
-
def self.emit(node, buffer, parent)
|
16
|
-
buffer.append('foo')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context 'when handler for type is registred' do
|
21
|
-
let(:type) { :dummy }
|
22
|
-
it_should_behave_like 'a command method'
|
23
|
-
|
24
|
-
it 'should call emitter' do
|
25
|
-
subject
|
26
|
-
buffer.content.should eql('foo')
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
context 'when handler for type is NOT registred' do
|
31
|
-
let(:type) { :unknown }
|
32
|
-
|
33
|
-
it 'should raise error' do
|
34
|
-
expect { subject }.to raise_error(ArgumentError, 'No emitter for node: :unknown')
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|