unparser 0.3.0 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +32 -8
- data/Changelog.md +5 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +26 -20
- data/README.md +21 -21
- data/config/flay.yml +1 -1
- data/config/reek.yml +9 -48
- data/lib/unparser.rb +62 -2
- data/lib/unparser/ast.rb +1 -1
- data/lib/unparser/cli/differ.rb +1 -1
- data/lib/unparser/cli/source.rb +2 -15
- data/lib/unparser/constants.rb +4 -2
- data/lib/unparser/emitter.rb +0 -14
- data/lib/unparser/emitter/argument.rb +62 -0
- data/lib/unparser/emitter/assignment.rb +4 -16
- data/lib/unparser/emitter/block.rb +29 -4
- data/lib/unparser/emitter/hookexe.rb +1 -1
- data/lib/unparser/emitter/index.rb +136 -0
- data/lib/unparser/emitter/lambda.rb +25 -0
- data/lib/unparser/emitter/literal/array.rb +1 -4
- data/lib/unparser/emitter/meta.rb +2 -2
- data/lib/unparser/emitter/rescue.rb +1 -1
- data/lib/unparser/emitter/send.rb +14 -28
- data/lib/unparser/emitter/send/attribute_assignment.rb +10 -24
- data/spec/spec_helper.rb +0 -11
- data/spec/unit/unparser/comments/consume_spec.rb +1 -1
- data/spec/unit/unparser/comments/take_all_spec.rb +1 -1
- data/spec/unit/unparser/comments/take_before_spec.rb +2 -2
- data/spec/unit/unparser/comments/take_eol_comments_spec.rb +6 -6
- data/spec/unit/unparser_spec.rb +365 -248
- data/unparser.gemspec +1 -1
- metadata +5 -6
- data/lib/unparser/emitter/send/index.rb +0 -127
- data/spec/support/parser_class_generator.rb +0 -21
data/lib/unparser/cli/differ.rb
CHANGED
data/lib/unparser/cli/source.rb
CHANGED
@@ -182,7 +182,7 @@ module Unparser
|
|
182
182
|
# @api private
|
183
183
|
#
|
184
184
|
def generated_ast
|
185
|
-
generated.success? && Preprocessor.run(parse(generated.source))
|
185
|
+
generated.success? && Preprocessor.run(Unparser.parse(generated.source))
|
186
186
|
rescue Parser::SyntaxError
|
187
187
|
nil
|
188
188
|
end
|
@@ -195,25 +195,12 @@ module Unparser
|
|
195
195
|
# @api private
|
196
196
|
#
|
197
197
|
def original_ast
|
198
|
-
Preprocessor.run(parse(original_source))
|
198
|
+
Preprocessor.run(Unparser.parse(original_source))
|
199
199
|
rescue Parser::SyntaxError
|
200
200
|
nil
|
201
201
|
end
|
202
202
|
memoize :original_ast
|
203
203
|
|
204
|
-
# Parse source with current ruby
|
205
|
-
#
|
206
|
-
# @param [String] source
|
207
|
-
#
|
208
|
-
# @return [Parser::AST::Node]
|
209
|
-
#
|
210
|
-
# @api private
|
211
|
-
#
|
212
|
-
# ignore :reek:UtilityFunction
|
213
|
-
def parse(source)
|
214
|
-
Parser::CurrentRuby.parse(source)
|
215
|
-
end
|
216
|
-
|
217
204
|
# CLI source from string
|
218
205
|
class String < self
|
219
206
|
include Concord.new(:original_source)
|
data/lib/unparser/constants.rb
CHANGED
@@ -22,6 +22,10 @@ module Unparser
|
|
22
22
|
end
|
23
23
|
private_class_method :symbol_set
|
24
24
|
|
25
|
+
BRACKETS_CURLY = IceNine.deep_freeze(%w[{ }])
|
26
|
+
BRACKETS_ROUND = IceNine.deep_freeze(%w[( )])
|
27
|
+
BRACKETS_SQUARE = IceNine.deep_freeze(%w([ ]))
|
28
|
+
|
25
29
|
# All unary operators of the ruby language
|
26
30
|
UNARY_OPERATORS = symbol_set %w[
|
27
31
|
! ~ -@ +@
|
@@ -105,8 +109,6 @@ module Unparser
|
|
105
109
|
|
106
110
|
DEFAULT_DELIMITER = ', '.freeze
|
107
111
|
|
108
|
-
CURLY_BRACKETS = IceNine.deep_freeze(%w[{ }])
|
109
|
-
|
110
112
|
KEYWORDS = constants.each_with_object([]) do |name, keywords|
|
111
113
|
value = const_get(name).freeze
|
112
114
|
next unless name.to_s.start_with?('K_')
|
data/lib/unparser/emitter.rb
CHANGED
@@ -17,10 +17,6 @@ module Unparser
|
|
17
17
|
|
18
18
|
NOINDENT = %i[rescue ensure].to_set.freeze
|
19
19
|
|
20
|
-
DEFAULT_DELIMITER = ', '.freeze
|
21
|
-
|
22
|
-
CURLY_BRACKETS = IceNine.deep_freeze(%w[{ }])
|
23
|
-
|
24
20
|
module Unterminated
|
25
21
|
def terminated?
|
26
22
|
false
|
@@ -111,16 +107,6 @@ module Unparser
|
|
111
107
|
end
|
112
108
|
memoize :write_to_buffer
|
113
109
|
|
114
|
-
# Emit node
|
115
|
-
#
|
116
|
-
# @return [self]
|
117
|
-
#
|
118
|
-
# @api private
|
119
|
-
#
|
120
|
-
def self.emit(*arguments)
|
121
|
-
new(*arguments).write_to_buffer
|
122
|
-
end
|
123
|
-
|
124
110
|
# Return emitter
|
125
111
|
#
|
126
112
|
# @return [Emitter]
|
@@ -30,6 +30,7 @@ module Unparser
|
|
30
30
|
handle :args
|
31
31
|
|
32
32
|
SHADOWARGS = ->(node) { node.type.equal?(:shadowarg) }.freeze
|
33
|
+
ARG = ->(node) { node.type.equal?(:arg) }.freeze
|
33
34
|
|
34
35
|
private
|
35
36
|
|
@@ -41,12 +42,35 @@ module Unparser
|
|
41
42
|
#
|
42
43
|
def dispatch
|
43
44
|
delimited(normal_arguments)
|
45
|
+
|
46
|
+
write(', ') if procarg_disambiguator?
|
47
|
+
|
44
48
|
return if shadowargs.empty?
|
45
49
|
|
46
50
|
write('; ')
|
47
51
|
delimited(shadowargs)
|
48
52
|
end
|
49
53
|
|
54
|
+
# Test for procarg_disambiguator
|
55
|
+
#
|
56
|
+
# @return [Boolean]
|
57
|
+
#
|
58
|
+
# @api private
|
59
|
+
#
|
60
|
+
def procarg_disambiguator?
|
61
|
+
regular_block? && normal_arguments.all?(&ARG) && normal_arguments.one?
|
62
|
+
end
|
63
|
+
|
64
|
+
# Test for regular block
|
65
|
+
#
|
66
|
+
# @return [Boolean]
|
67
|
+
#
|
68
|
+
# @api private
|
69
|
+
#
|
70
|
+
def regular_block?
|
71
|
+
parent_type.equal?(:block) && !parent.node.children.first.type.equal?(:lambda)
|
72
|
+
end
|
73
|
+
|
50
74
|
# Return normal arguments
|
51
75
|
#
|
52
76
|
# @return [Enumerable<Parser::AST::Node>]
|
@@ -56,6 +80,7 @@ module Unparser
|
|
56
80
|
def normal_arguments
|
57
81
|
children.reject(&SHADOWARGS)
|
58
82
|
end
|
83
|
+
memoize :normal_arguments
|
59
84
|
|
60
85
|
# Return shadow args
|
61
86
|
#
|
@@ -209,6 +234,43 @@ module Unparser
|
|
209
234
|
|
210
235
|
end # Argument
|
211
236
|
|
237
|
+
# Progarg emitter
|
238
|
+
class Procarg < self
|
239
|
+
include Terminated
|
240
|
+
|
241
|
+
handle :procarg0
|
242
|
+
|
243
|
+
children :first_argument
|
244
|
+
|
245
|
+
private
|
246
|
+
|
247
|
+
# Perform dispatch
|
248
|
+
#
|
249
|
+
# @return [undefined]
|
250
|
+
#
|
251
|
+
# @api private
|
252
|
+
#
|
253
|
+
def dispatch
|
254
|
+
if first_argument.instance_of?(Symbol)
|
255
|
+
write(first_argument.to_s)
|
256
|
+
else
|
257
|
+
emit_multiple_children
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
# Emit multiple children
|
262
|
+
#
|
263
|
+
# @return [undefined]
|
264
|
+
#
|
265
|
+
# @api private
|
266
|
+
#
|
267
|
+
def emit_multiple_children
|
268
|
+
parentheses do
|
269
|
+
delimited(children)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
212
274
|
# Block pass node emitter
|
213
275
|
class BlockPass < self
|
214
276
|
include Terminated
|
@@ -29,7 +29,7 @@ module Unparser
|
|
29
29
|
# @api private
|
30
30
|
#
|
31
31
|
def terminated?
|
32
|
-
|
32
|
+
right.nil?
|
33
33
|
end
|
34
34
|
|
35
35
|
private
|
@@ -41,7 +41,6 @@ module Unparser
|
|
41
41
|
# @api private
|
42
42
|
#
|
43
43
|
def emit_right
|
44
|
-
right = right_node
|
45
44
|
return unless right
|
46
45
|
|
47
46
|
write(WS, T_ASN, WS)
|
@@ -55,7 +54,7 @@ module Unparser
|
|
55
54
|
|
56
55
|
handle :lvasgn, :ivasgn, :cvasgn, :gvasgn
|
57
56
|
|
58
|
-
children :name, :
|
57
|
+
children :name, :right
|
59
58
|
|
60
59
|
private
|
61
60
|
|
@@ -76,7 +75,7 @@ module Unparser
|
|
76
75
|
|
77
76
|
handle :casgn
|
78
77
|
|
79
|
-
children :base, :name, :
|
78
|
+
children :base, :name, :right
|
80
79
|
|
81
80
|
private
|
82
81
|
|
@@ -103,8 +102,6 @@ module Unparser
|
|
103
102
|
|
104
103
|
handle :masgn
|
105
104
|
|
106
|
-
PARENS = IceNine.deep_freeze(%w([ ]))
|
107
|
-
|
108
105
|
private
|
109
106
|
|
110
107
|
# Emit left
|
@@ -125,16 +122,7 @@ module Unparser
|
|
125
122
|
#
|
126
123
|
def emit_right
|
127
124
|
write(WS, T_ASN, WS)
|
128
|
-
|
129
|
-
case right.type
|
130
|
-
when :array
|
131
|
-
children = right.children
|
132
|
-
parentheses(*PARENS) do
|
133
|
-
delimited(children)
|
134
|
-
end
|
135
|
-
else
|
136
|
-
visit(right)
|
137
|
-
end
|
125
|
+
visit(children.last)
|
138
126
|
end
|
139
127
|
|
140
128
|
end # Multiple
|
@@ -4,12 +4,14 @@ module Unparser
|
|
4
4
|
class Emitter
|
5
5
|
|
6
6
|
# Block emitter
|
7
|
+
#
|
8
|
+
# ignore :reek:RepeatedConditional
|
7
9
|
class Block < self
|
8
10
|
include Terminated
|
9
11
|
|
10
12
|
handle :block
|
11
13
|
|
12
|
-
children :
|
14
|
+
children :target, :arguments, :body
|
13
15
|
|
14
16
|
private
|
15
17
|
|
@@ -20,14 +22,37 @@ module Unparser
|
|
20
22
|
# @api private
|
21
23
|
#
|
22
24
|
def dispatch
|
23
|
-
|
25
|
+
emit_target
|
24
26
|
write(WS, K_DO)
|
25
|
-
|
26
|
-
emit_block_arguments
|
27
|
+
emit_block_arguments unless stabby_lambda?
|
27
28
|
emit_body
|
28
29
|
k_end
|
29
30
|
end
|
30
31
|
|
32
|
+
# Emit target
|
33
|
+
#
|
34
|
+
# @return [undefined]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
#
|
38
|
+
def emit_target
|
39
|
+
visit(target)
|
40
|
+
|
41
|
+
if stabby_lambda?
|
42
|
+
parentheses { visit(arguments) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Test if we are emitting a stabby lambda
|
47
|
+
#
|
48
|
+
# @return [Boolean]
|
49
|
+
#
|
50
|
+
# @api private
|
51
|
+
#
|
52
|
+
def stabby_lambda?
|
53
|
+
target.type.equal?(:lambda)
|
54
|
+
end
|
55
|
+
|
31
56
|
# Emit arguments
|
32
57
|
#
|
33
58
|
# @return [undefined]
|
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Unparser
|
4
|
+
class Emitter
|
5
|
+
# Emitter for send to index references
|
6
|
+
#
|
7
|
+
# ignore :reek:RepeatedConditional
|
8
|
+
class Index < self
|
9
|
+
|
10
|
+
# Perform dispatch
|
11
|
+
#
|
12
|
+
# @return [undefined]
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
#
|
16
|
+
def dispatch
|
17
|
+
emit_receiver
|
18
|
+
emit_operation
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Emit receiver
|
24
|
+
#
|
25
|
+
# @return [undefined]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
#
|
29
|
+
def emit_receiver
|
30
|
+
visit(first_child)
|
31
|
+
end
|
32
|
+
|
33
|
+
# Test for mlhs
|
34
|
+
#
|
35
|
+
# @return [Boolean]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
#
|
39
|
+
def mlhs?
|
40
|
+
parent_type.equal?(:mlhs)
|
41
|
+
end
|
42
|
+
|
43
|
+
class Reference < self
|
44
|
+
include Terminated
|
45
|
+
|
46
|
+
define_group(:indices, 1..-1)
|
47
|
+
|
48
|
+
handle :index
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
# Emit arguments
|
53
|
+
#
|
54
|
+
# @return [undefined]
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
#
|
58
|
+
def emit_operation
|
59
|
+
parentheses(*BRACKETS_SQUARE) do
|
60
|
+
delimited_plain(indices)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end # Reference
|
64
|
+
|
65
|
+
# Emitter for assign to index nodes
|
66
|
+
class Assign < self
|
67
|
+
|
68
|
+
handle :indexasgn
|
69
|
+
|
70
|
+
VALUE_RANGE = (1..-2).freeze
|
71
|
+
NO_VALUE_PARENT = IceNine.deep_freeze(%i[and_asgn op_asgn or_asgn].to_set)
|
72
|
+
|
73
|
+
# Test if assign will be emitted terminated
|
74
|
+
#
|
75
|
+
# @return [Boolean]
|
76
|
+
#
|
77
|
+
# @api private
|
78
|
+
#
|
79
|
+
def terminated?
|
80
|
+
!emit_value?
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Emit arguments
|
86
|
+
#
|
87
|
+
# @return [undefined]
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
#
|
91
|
+
def emit_operation
|
92
|
+
parentheses(*BRACKETS_SQUARE) do
|
93
|
+
delimited_plain(indices)
|
94
|
+
end
|
95
|
+
|
96
|
+
if emit_value?
|
97
|
+
write(WS, T_ASN, WS)
|
98
|
+
visit(children.last)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# The indices
|
103
|
+
#
|
104
|
+
# @return [Array<Parser::AST::Node>]
|
105
|
+
#
|
106
|
+
def indices
|
107
|
+
if emit_value?
|
108
|
+
children[VALUE_RANGE]
|
109
|
+
else
|
110
|
+
children.drop(1)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Test if value should be emitted
|
115
|
+
#
|
116
|
+
# @return [Boolean]
|
117
|
+
#
|
118
|
+
# @api private
|
119
|
+
#
|
120
|
+
def emit_value?
|
121
|
+
!mlhs? && !no_value_parent?
|
122
|
+
end
|
123
|
+
|
124
|
+
# Test for no value parent
|
125
|
+
#
|
126
|
+
# @return [Boolean]
|
127
|
+
#
|
128
|
+
# @api private
|
129
|
+
#
|
130
|
+
def no_value_parent?
|
131
|
+
NO_VALUE_PARENT.include?(parent_type)
|
132
|
+
end
|
133
|
+
end # Assign
|
134
|
+
end # Index
|
135
|
+
end # Emitter
|
136
|
+
end # Unparser
|