unparser 0.1.5 → 0.1.6
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/.gitignore +38 -2
- data/.travis.yml +3 -6
- data/Changelog.md +7 -0
- data/Gemfile +1 -0
- data/Gemfile.devtools +22 -17
- data/README.md +3 -4
- data/TODO +3 -2
- data/bin/unparser +10 -0
- data/circle.yml +2 -0
- data/config/flay.yml +1 -1
- data/config/flog.yml +1 -1
- data/config/reek.yml +10 -0
- data/config/rubocop.yml +9 -17
- data/lib/unparser.rb +8 -1
- data/lib/unparser/buffer.rb +2 -0
- data/lib/unparser/cli.rb +113 -0
- data/lib/unparser/cli/differ.rb +30 -0
- data/lib/unparser/cli/preprocessor.rb +196 -0
- data/lib/unparser/cli/source.rb +118 -0
- data/lib/unparser/comments.rb +64 -23
- data/lib/unparser/constants.rb +19 -7
- data/lib/unparser/emitter.rb +23 -25
- data/lib/unparser/emitter/alias.rb +2 -0
- data/lib/unparser/emitter/argument.rb +2 -0
- data/lib/unparser/emitter/assignment.rb +3 -1
- data/lib/unparser/emitter/begin.rb +3 -6
- data/lib/unparser/emitter/binary.rb +2 -0
- data/lib/unparser/emitter/block.rb +2 -0
- data/lib/unparser/emitter/break.rb +4 -5
- data/lib/unparser/emitter/case.rb +2 -0
- data/lib/unparser/emitter/cbase.rb +2 -0
- data/lib/unparser/emitter/class.rb +4 -3
- data/lib/unparser/emitter/def.rb +2 -0
- data/lib/unparser/emitter/defined.rb +2 -0
- data/lib/unparser/emitter/empty.rb +2 -0
- data/lib/unparser/emitter/ensure.rb +2 -0
- data/lib/unparser/emitter/flipflop.rb +2 -0
- data/lib/unparser/emitter/for.rb +2 -0
- data/lib/unparser/emitter/hookexe.rb +2 -0
- data/lib/unparser/emitter/if.rb +2 -0
- data/lib/unparser/emitter/literal.rb +2 -0
- data/lib/unparser/emitter/literal/array.rb +33 -0
- data/lib/unparser/emitter/literal/dynamic.rb +21 -1
- data/lib/unparser/emitter/literal/dynamic_body.rb +9 -5
- data/lib/unparser/emitter/literal/execute_string.rb +2 -0
- data/lib/unparser/emitter/literal/hash.rb +136 -0
- data/lib/unparser/emitter/literal/primitive.rb +4 -2
- data/lib/unparser/emitter/literal/range.rb +2 -0
- data/lib/unparser/emitter/literal/regexp.rb +4 -2
- data/lib/unparser/emitter/literal/singleton.rb +2 -0
- data/lib/unparser/emitter/match.rb +2 -0
- data/lib/unparser/emitter/module.rb +2 -3
- data/lib/unparser/emitter/next.rb +2 -0
- data/lib/unparser/emitter/op_assign.rb +3 -1
- data/lib/unparser/emitter/redo.rb +2 -0
- data/lib/unparser/emitter/repetition.rb +2 -0
- data/lib/unparser/emitter/resbody.rb +2 -0
- data/lib/unparser/emitter/rescue.rb +2 -0
- data/lib/unparser/emitter/retry.rb +2 -0
- data/lib/unparser/emitter/return.rb +19 -4
- data/lib/unparser/emitter/root.rb +13 -0
- data/lib/unparser/emitter/send.rb +26 -22
- data/lib/unparser/emitter/send/arguments.rb +46 -0
- data/lib/unparser/emitter/send/attribute_assignment.rb +35 -0
- data/lib/unparser/emitter/send/binary.rb +2 -0
- data/lib/unparser/emitter/send/index.rb +2 -0
- data/lib/unparser/emitter/send/regular.rb +4 -2
- data/lib/unparser/emitter/send/unary.rb +3 -1
- data/lib/unparser/emitter/splat.rb +2 -0
- data/lib/unparser/emitter/super.rb +2 -0
- data/lib/unparser/emitter/undef.rb +2 -0
- data/lib/unparser/emitter/variable.rb +2 -0
- data/lib/unparser/emitter/yield.rb +2 -0
- data/lib/unparser/finalize.rb +2 -0
- data/lib/unparser/node_helpers.rb +19 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/unit/unparser/buffer/append_spec.rb +2 -0
- data/spec/unit/unparser/buffer/append_without_prefix_spec.rb +2 -0
- data/spec/unit/unparser/buffer/capture_content_spec.rb +2 -0
- data/spec/unit/unparser/buffer/content_spec.rb +3 -1
- data/spec/unit/unparser/buffer/fresh_line_spec.rb +2 -0
- data/spec/unit/unparser/buffer/indent_spec.rb +3 -1
- data/spec/unit/unparser/buffer/nl_spec.rb +2 -0
- data/spec/unit/unparser/buffer/unindent_spec.rb +2 -0
- data/spec/unit/unparser/comments/consume_spec.rb +2 -1
- data/spec/unit/unparser/comments/take_all_spec.rb +2 -1
- data/spec/unit/unparser/comments/take_before_spec.rb +6 -5
- data/spec/unit/unparser/comments/take_eol_comments_spec.rb +2 -1
- data/spec/unit/unparser/emitter/class_methods/handle_spec.rb +2 -0
- data/spec/unit/unparser_spec.rb +110 -57
- data/unparser.gemspec +5 -4
- metadata +32 -12
- data/bin/test-unparser +0 -26
- data/lib/unparser/emitter/literal/composed.rb +0 -64
- data/spec/unit/unparser/comments/skip_eol_comment_spec.rb +0 -29
data/lib/unparser/constants.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
# All unparser constants maybe included in other libraries.
|
3
5
|
module Constants
|
4
6
|
|
7
|
+
# All unary operators of the ruby language
|
5
8
|
UNARY_OPERATORS = %w(
|
6
9
|
! ~ -@ +@
|
7
10
|
).map(&:to_sym).to_set
|
8
11
|
|
12
|
+
# All binary operators of the ruby language
|
9
13
|
BINARY_OPERATORS = %w(
|
10
14
|
+ - * / & | && || << >> ==
|
11
15
|
=== != <= < <=> > >= =~ !~ ^
|
12
16
|
** %
|
13
17
|
).map(&:to_sym).to_set
|
14
18
|
|
15
|
-
COMMENT = '#'
|
19
|
+
COMMENT = '#'
|
16
20
|
|
17
21
|
WS = ' '
|
18
22
|
NL = "\n"
|
@@ -34,6 +38,10 @@ module Unparser
|
|
34
38
|
M_PO = '('
|
35
39
|
M_PC = ')'
|
36
40
|
|
41
|
+
SNGL_QUOTE = "'"
|
42
|
+
DBL_QUOTE = '"'
|
43
|
+
|
44
|
+
# Keywords
|
37
45
|
K_DO = 'do'
|
38
46
|
K_DEF = 'def'
|
39
47
|
K_END = 'end'
|
@@ -77,12 +85,16 @@ module Unparser
|
|
77
85
|
K_FILE = '__FILE__'
|
78
86
|
K_THEN = 'then'
|
79
87
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
88
|
+
# Nodes that can be emitted in tokens that terminate their expression.
|
89
|
+
#
|
90
|
+
# These nodes dont require parentheses to be exactly reproduced in context of a more complex expression.
|
91
|
+
#
|
92
|
+
TERMINATED = %w(
|
93
|
+
int float self kwbegin const regexp args lvar
|
94
|
+
ivar gvar cvar if case module class sclass super
|
95
|
+
yield zsuper break next defined? str block while loop until
|
96
|
+
def defs true false nil array hash sym return
|
97
|
+
).map(&:to_sym).to_set
|
86
98
|
|
87
99
|
KEYWORDS = constants.each_with_object([]) do |name, keywords|
|
88
100
|
value = const_get(name).freeze
|
data/lib/unparser/emitter.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
|
3
5
|
# Emitter base class
|
4
6
|
class Emitter
|
5
|
-
include Adamantium::Flat, AbstractType, Constants
|
7
|
+
include Adamantium::Flat, AbstractType, Constants, NodeHelpers
|
6
8
|
include Concord.new(:node, :parent)
|
7
9
|
|
8
10
|
# Registry for node emitters
|
@@ -14,6 +16,16 @@ module Unparser
|
|
14
16
|
|
15
17
|
CURLY_BRACKETS = IceNine.deep_freeze(%w({ }))
|
16
18
|
|
19
|
+
# Return node type
|
20
|
+
#
|
21
|
+
# @return [Symbol]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
#
|
25
|
+
def node_type
|
26
|
+
node.type
|
27
|
+
end
|
28
|
+
|
17
29
|
# Define remaining children
|
18
30
|
#
|
19
31
|
# @param [Enumerable<Symbol>] names
|
@@ -201,7 +213,6 @@ module Unparser
|
|
201
213
|
conditional_parentheses(!emitter.terminated?) do
|
202
214
|
emitter.write_to_buffer
|
203
215
|
end
|
204
|
-
emitter.write_to_buffer
|
205
216
|
end
|
206
217
|
|
207
218
|
# Visit within parentheses
|
@@ -256,10 +267,12 @@ module Unparser
|
|
256
267
|
# @api private
|
257
268
|
#
|
258
269
|
def delimited(nodes, delimiter = DEFAULT_DELIMITER)
|
259
|
-
|
260
|
-
|
270
|
+
return if nodes.empty?
|
271
|
+
head, *tail = nodes
|
272
|
+
visit(head)
|
273
|
+
tail.each do |node|
|
274
|
+
write(delimiter)
|
261
275
|
visit(node)
|
262
|
-
write(delimiter) if index < max
|
263
276
|
end
|
264
277
|
end
|
265
278
|
|
@@ -456,34 +469,19 @@ module Unparser
|
|
456
469
|
# @api private
|
457
470
|
#
|
458
471
|
def parent_type
|
459
|
-
parent
|
472
|
+
parent.node_type
|
460
473
|
end
|
461
474
|
|
462
|
-
#
|
475
|
+
# Delegate to emitter
|
463
476
|
#
|
464
|
-
# @param [
|
465
|
-
#
|
466
|
-
# @return [Parser::AST::Node]
|
467
|
-
#
|
468
|
-
# @api private
|
469
|
-
#
|
470
|
-
def s(type, *children)
|
471
|
-
Parser::AST::Node.new(type, *children)
|
472
|
-
end
|
473
|
-
|
474
|
-
# Helper to introduce an end-of-line comment
|
477
|
+
# @param [Class:Emitter] emitter
|
475
478
|
#
|
476
479
|
# @return [undefined]
|
477
480
|
#
|
478
481
|
# @api private
|
479
482
|
#
|
480
|
-
def
|
481
|
-
|
482
|
-
comment = buffer.capture_content do
|
483
|
-
write(COMMENT, WS)
|
484
|
-
yield
|
485
|
-
end
|
486
|
-
comments.skip_eol_comment(comment)
|
483
|
+
def run(emitter, node = node)
|
484
|
+
emitter.new(node, self).write_to_buffer
|
487
485
|
end
|
488
486
|
|
489
487
|
end # Emitter
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
|
@@ -15,12 +17,7 @@ module Unparser
|
|
15
17
|
# @api private
|
16
18
|
#
|
17
19
|
def emit_inner
|
18
|
-
|
19
|
-
max = childs.length - 1
|
20
|
-
childs.each_with_index do |child, index|
|
21
|
-
visit(child)
|
22
|
-
nl if index < max
|
23
|
-
end
|
20
|
+
delimited(children, NL)
|
24
21
|
end
|
25
22
|
|
26
23
|
# Emitter for implicit begins
|
@@ -1,12 +1,12 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
# Emitter for break nodes
|
4
|
-
class Break <
|
6
|
+
class Break < Return
|
5
7
|
|
6
8
|
handle :break
|
7
9
|
|
8
|
-
children :arguments
|
9
|
-
|
10
10
|
private
|
11
11
|
|
12
12
|
# Perform dispatch
|
@@ -18,8 +18,7 @@ module Unparser
|
|
18
18
|
def dispatch
|
19
19
|
conditional_parentheses(parent_type == :or || parent_type == :and) do
|
20
20
|
write(K_BREAK)
|
21
|
-
|
22
|
-
visit_parentheses(arguments)
|
21
|
+
emit_break_return_arguments
|
23
22
|
end
|
24
23
|
end
|
25
24
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
# Emitter for class nodes
|
@@ -21,9 +23,6 @@ module Unparser
|
|
21
23
|
emit_superclass
|
22
24
|
emit_body
|
23
25
|
k_end
|
24
|
-
unless parent_type == :send
|
25
|
-
eol_comment { visit(name) }
|
26
|
-
end
|
27
26
|
end
|
28
27
|
|
29
28
|
# Emit superclass
|
@@ -47,6 +46,8 @@ module Unparser
|
|
47
46
|
|
48
47
|
children :object, :body
|
49
48
|
|
49
|
+
private
|
50
|
+
|
50
51
|
# Perform dispatch
|
51
52
|
#
|
52
53
|
# @return [undefined]
|
data/lib/unparser/emitter/def.rb
CHANGED
data/lib/unparser/emitter/for.rb
CHANGED
data/lib/unparser/emitter/if.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Unparser
|
4
|
+
class Emitter
|
5
|
+
class Literal
|
6
|
+
|
7
|
+
# Array literal emitter
|
8
|
+
class Array < self
|
9
|
+
OPEN = '['.freeze
|
10
|
+
CLOSE = ']'.freeze
|
11
|
+
DELIMITER = ', '.freeze
|
12
|
+
|
13
|
+
handle :array
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
# Perform dispatch
|
18
|
+
#
|
19
|
+
# @return [undefined]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
#
|
23
|
+
def dispatch
|
24
|
+
parentheses(OPEN, CLOSE) do
|
25
|
+
delimited(children, DELIMITER)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end # Array
|
30
|
+
|
31
|
+
end # Literal
|
32
|
+
end # Emitter
|
33
|
+
end # Unparser
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
class Literal
|
@@ -15,7 +17,25 @@ module Unparser
|
|
15
17
|
#
|
16
18
|
def dispatch
|
17
19
|
util = self.class
|
18
|
-
|
20
|
+
if interpolation?
|
21
|
+
visit_parentheses(dynamic_body, util::OPEN, util::CLOSE)
|
22
|
+
else
|
23
|
+
delimited(children, WS)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Test for interpolation
|
28
|
+
#
|
29
|
+
# @return [true]
|
30
|
+
# if dynamic component was interpolated
|
31
|
+
#
|
32
|
+
# @return [false]
|
33
|
+
# otherwise
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
#
|
37
|
+
def interpolation?
|
38
|
+
children.any? { |child| child.type != :str }
|
19
39
|
end
|
20
40
|
|
21
41
|
# Return dynamic body
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
module Unparser
|
2
4
|
class Emitter
|
3
5
|
class Literal
|
@@ -61,9 +63,11 @@ module Unparser
|
|
61
63
|
emit_interpolated_segment(node)
|
62
64
|
end
|
63
65
|
|
64
|
-
|
65
|
-
"
|
66
|
-
|
66
|
+
pairs = Parser::Lexer::ESCAPES.invert.map do |key, value|
|
67
|
+
[key, "\\#{value}"] unless key == WS
|
68
|
+
end.compact
|
69
|
+
|
70
|
+
ESCAPES = ::Hash[pairs]
|
67
71
|
|
68
72
|
REPLACEMENTS = ::Regexp.union(ESCAPES.keys)
|
69
73
|
|
@@ -79,8 +83,8 @@ module Unparser
|
|
79
83
|
util = self.class
|
80
84
|
string = node.children.first
|
81
85
|
segment = string
|
82
|
-
.gsub(util::DELIMITER, util::REPLACEMENT)
|
83
86
|
.gsub(REPLACEMENTS, ESCAPES)
|
87
|
+
.gsub(util::DELIMITER, util::REPLACEMENT)
|
84
88
|
write(segment)
|
85
89
|
end
|
86
90
|
|
@@ -112,7 +116,7 @@ module Unparser
|
|
112
116
|
handle :dyn_regexp_body
|
113
117
|
|
114
118
|
DELIMITER = '/'.freeze
|
115
|
-
REPLACEMENT = '
|
119
|
+
REPLACEMENT = '\/'.freeze
|
116
120
|
|
117
121
|
end # Regexp
|
118
122
|
|