unparser 0.0.6 → 0.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3273de4b72cb214d459c8519c3a3e6c3a0d06e4e
4
- data.tar.gz: dc7c765cef957d3fafcdfbf36691b56695c29443
3
+ metadata.gz: 7c9b95ccef00a5ebdeae86ae92b12af786f209ae
4
+ data.tar.gz: cab5a1dd18399aa00b3afcdd0ea371aee67dfae3
5
5
  SHA512:
6
- metadata.gz: e27666e1e5c927f64ac11777754b9e9f6df2ad61c8c62c9ca801c026ceda16b75dee95f37ae8e6b313d8ac4ac03ba273f3f7fb355f40fd03c3843a1d2ab0ea5b
7
- data.tar.gz: 7c65227ff6738eb937e677a0b17d5fd2d1908a336f187786a0ab42ca68e3c6e38c3e25e233595ad4579579b2076cdff5b7eb66c194daab369e9e2e8b6ba86279
6
+ metadata.gz: 369c2c1b754ef3d252464a84b334a0e1f8d1bdae36997c811619b9c1483db73232d8a953e08a5b2894b588bdf7d401ebe4ab667c471b1ce5e57572c4016e5809
7
+ data.tar.gz: cfc34c5e7d02ac2e58c60c41dd7f9f59c66a21eace1b1c9d42e3052a930c59067dc6c572bf7980ab4e53d0305940221424263ab8cff8b71901f7e4e572bb1573
data/Guardfile CHANGED
@@ -4,7 +4,7 @@ guard :bundler do
4
4
  watch('Gemfile')
5
5
  end
6
6
 
7
- guard :rspec, :all_on_start => false, :all_after_pass => false, :cli => '--fail-fast --backtrace' do
7
+ guard :rspec, :all_on_start => false, :all_after_pass => false, :cli => '--fail-fast --seed 1' do
8
8
  # run all specs if the spec_helper or supporting files files are modified
9
9
  watch('spec/spec_helper.rb') { 'spec/unit' }
10
10
  watch(%r{\Aspec/(?:lib|support|shared)/.+\.rb\z}) { 'spec/unit' }
data/README.md CHANGED
@@ -7,6 +7,10 @@ unparser
7
7
 
8
8
  Generate equivalent source for ASTs from whitequarks awesome [parser](https://github.com/whitequark/parser).
9
9
 
10
+ This library is in early development stage and still has some bugs/missing features.
11
+ Nevertheless it is able to regenerate it own source and serves well for
12
+ [mutant](https://github.cm/mbj/mutant) mutators and the in-memory vendoring for self hosting mutant.
13
+
10
14
  Usage
11
15
  -----
12
16
 
data/Rakefile CHANGED
@@ -1,24 +1,2 @@
1
1
  require 'devtools'
2
2
  Devtools.init_rake_tasks
3
-
4
- class Rake::Task
5
- def overwrite(&block)
6
- @actions.clear
7
- enhance(&block)
8
- end
9
- end
10
-
11
- Rake.application.load_imports
12
-
13
- Rake::Task['metrics:mutant'].overwrite do
14
- begin
15
- require 'mutant'
16
- rescue LoadError
17
- end
18
- if defined?(Mutant) and !ENV.key?('CI')
19
- status = Mutant::CLI.run(%W(--rspec-full ::Unparser))
20
- unless status.zero?
21
- fail "Not mutation covered :("
22
- end
23
- end
24
- end
data/TODO CHANGED
@@ -1,2 +1,3 @@
1
1
  * Refactor Emitter::Send, it is ugly.
2
2
  * Remove duplicated logic with empty or non empty bodies
3
+ * Handle kwbegin and begin separately
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ trap('INT') do |status|
4
+ exit! 128+status
5
+ end
6
+
7
+ require 'unparser'
8
+ require 'parser/current'
9
+
10
+ ARGV.each do |file|
11
+ source = File.read(file)
12
+ node = Parser::CurrentRuby.parse(source)
13
+ generated = Unparser.unparse(node)
14
+ unparsed = Parser::CurrentRuby.parse(generated)
15
+ unless unparsed == node
16
+ $stderr.puts "Node:"
17
+ $stderr.puts node.inspect
18
+ $stderr.puts "Unparsed-Node:"
19
+ $stderr.puts unparsed.inspect
20
+ $stderr.puts "Original:"
21
+ $stderr.puts source
22
+ $stderr.puts "Generated:"
23
+ $stderr.puts generated
24
+ fail "BUG!"
25
+ end
26
+ end
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 13
3
- total_score: 353
3
+ total_score: 363
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 11.8
2
+ threshold: 9.8
@@ -99,7 +99,8 @@ DataClump:
99
99
  max_copies: 1
100
100
  min_clump_size: 3
101
101
  ControlParameter:
102
- exclude: []
102
+ exclude:
103
+ - Unparser::Emitter#emit_body # false positive
103
104
  enabled: true
104
105
  NilCheck:
105
106
  enabled: false
@@ -8,10 +8,45 @@ module Unparser
8
8
  # Registry for node emitters
9
9
  REGISTRY = {}
10
10
 
11
+ NOINDENT = [:rescue, :ensure].to_set
12
+
11
13
  DEFAULT_DELIMITER = ', '.freeze
12
14
 
13
15
  CURLY_BRACKETS = IceNine.deep_freeze(%w({ }))
14
16
 
17
+ # Define remaining children
18
+ #
19
+ # @param [Enumerable<Symbol>] names
20
+ #
21
+ # @return [undefined]
22
+ #
23
+ # @api private
24
+ #
25
+ def self.define_remaining_children(names)
26
+ define_method(:remaining_children) do
27
+ children[names.length..-1]
28
+ end
29
+ private :remaining_children
30
+ end
31
+ private_class_method :define_remaining_children
32
+
33
+ # Define named child
34
+ #
35
+ # @param [Symbol] name
36
+ # @param [Fixnum] index
37
+ #
38
+ # @return [undefined]
39
+ #
40
+ # @api private
41
+ #
42
+ def self.define_child(name, index)
43
+ define_method(name) do
44
+ children.at(index)
45
+ end
46
+ protected name
47
+ end
48
+ private_class_method :define_child
49
+
15
50
  # Create name helpers
16
51
  #
17
52
  # @return [undefined]
@@ -19,11 +54,10 @@ module Unparser
19
54
  # @api private
20
55
  #
21
56
  def self.children(*names)
57
+ define_remaining_children(names)
58
+
22
59
  names.each_with_index do |name, index|
23
- define_method(name) do
24
- children[index]
25
- end
26
- private name
60
+ define_child(name, index)
27
61
  end
28
62
  end
29
63
  private_class_method :children
@@ -213,16 +247,6 @@ module Unparser
213
247
  end
214
248
  end
215
249
 
216
- # Write begin keyword
217
- #
218
- # @return [undefined]
219
- #
220
- # @api private
221
- #
222
- def k_begin
223
- write(K_BEGIN)
224
- end
225
-
226
250
  # Write end keyword
227
251
  #
228
252
  # @return [undefined]
@@ -278,12 +302,28 @@ module Unparser
278
302
  #
279
303
  # @api private
280
304
  #
281
- def emit_body
305
+ def emit_body(body = self.body)
282
306
  unless body
283
307
  nl
284
308
  return
285
309
  end
286
- indented { visit(body) }
310
+ visit_indented(body)
311
+ end
312
+
313
+ # Visit indented node
314
+ #
315
+ # @param [Parser::AST::Node] node
316
+ #
317
+ # @return [undefined]
318
+ #
319
+ # @api private
320
+ #
321
+ def visit_indented(node)
322
+ if NOINDENT.include?(node.type)
323
+ visit(node)
324
+ else
325
+ indented { visit(node) }
326
+ end
287
327
  end
288
328
 
289
329
  # Emitter that fully relies on parser source maps
@@ -17,56 +17,70 @@ module Unparser
17
17
  # @api private
18
18
  #
19
19
  def dispatch
20
- k_begin
21
- indented { visit(body) }
22
- children[1..-2].each do |child|
20
+ visit_indented(body)
21
+ rescue_bodies.each do |child|
23
22
  visit(child)
24
23
  end
25
- k_end
24
+ emit_else
26
25
  end
27
- end # Rescue
28
-
29
- # Emitter for enusre nodes
30
- class Ensure < self
31
-
32
- handle :ensure
33
26
 
34
- children :body, :ensure_body
35
-
36
- private
27
+ # Return rescue bodies
28
+ #
29
+ # @return [Enumerable<Parser::AST::Node>]
30
+ #
31
+ # @api private
32
+ #
33
+ def rescue_bodies
34
+ children[1..-2]
35
+ end
37
36
 
38
- # Perform dispatch
37
+ # Emit else
39
38
  #
40
39
  # @return [undefined]
41
40
  #
42
41
  # @api private
43
42
  #
44
- def dispatch
45
- k_begin
46
- emit_body
47
- write(K_ENSURE)
48
- emit_ensure_body
49
- k_end
43
+ def emit_else
44
+ return unless else_branch
45
+ write(K_ELSE)
46
+ visit_indented(else_branch)
50
47
  end
51
48
 
52
- # Emit body
49
+ # Return else body
53
50
  #
54
- # @return [undefined]
51
+ # @return [Parser::AST::Node]
52
+ # if else body is present
53
+ #
54
+ # @return [nil]
55
+ # otherwise
55
56
  #
56
57
  # @api private
57
58
  #
58
- def emit_body
59
- indented { visit(body) }
59
+ def else_branch
60
+ children.last
60
61
  end
61
62
 
62
- # Emit ensure body
63
+ end # Rescue
64
+
65
+ # Emitter for ensure nodes
66
+ class Ensure < self
67
+
68
+ handle :ensure
69
+
70
+ children :body, :ensure_body
71
+
72
+ private
73
+
74
+ # Perform dispatch
63
75
  #
64
76
  # @return [undefined]
65
77
  #
66
78
  # @api private
67
79
  #
68
- def emit_ensure_body
69
- indented { visit(ensure_body) }
80
+ def dispatch
81
+ visit_indented(body)
82
+ write(K_ENSURE)
83
+ visit_indented(ensure_body)
70
84
  end
71
85
 
72
86
  end # Ensure
@@ -90,11 +104,7 @@ module Unparser
90
104
  write(K_RESCUE)
91
105
  emit_exception
92
106
  emit_assignment
93
- if body
94
- indented { visit(body) }
95
- else
96
- nl
97
- end
107
+ emit_body
98
108
  end
99
109
 
100
110
  # Emit exception
@@ -126,40 +136,10 @@ module Unparser
126
136
  # Emitter for begin nodes
127
137
  class Begin < self
128
138
 
129
- handle :begin, :kwbegin
139
+ children :body
130
140
 
131
141
  private
132
142
 
133
- # Perform dispatch
134
- #
135
- # @return [undefined]
136
- #
137
- # @api private
138
- #
139
- def dispatch
140
- if children.length == 1 and !parent.needs_begin?
141
- visit(first_child)
142
- else
143
- emit_normal
144
- end
145
- end
146
-
147
- # Emit normal begin block
148
- #
149
- # @return [undefined]
150
- #
151
- # @api private
152
- #
153
- def emit_normal
154
- if parent.needs_begin?
155
- k_begin
156
- indented { emit_inner }
157
- k_end
158
- else
159
- emit_inner
160
- end
161
- end
162
-
163
143
  # Emit inner nodes
164
144
  #
165
145
  # @return [undefined]
@@ -175,6 +155,60 @@ module Unparser
175
155
  end
176
156
  end
177
157
 
178
- end # Body
158
+ # Emitter for implicit begins
159
+ class Implicit < self
160
+
161
+ handle :begin
162
+
163
+ private
164
+
165
+ # Perform dispatch
166
+ #
167
+ # @return [undefined]
168
+ #
169
+ # @api private
170
+ #
171
+ def dispatch
172
+ emit_inner
173
+ end
174
+
175
+ end # Implicit
176
+
177
+ # Emitter for explicit begins
178
+ class Explicit < self
179
+
180
+ handle :kwbegin
181
+
182
+ private
183
+
184
+ # Perform dispatch
185
+ #
186
+ # @return [undefined]
187
+ #
188
+ # @api private
189
+ #
190
+ def dispatch
191
+ write(K_BEGIN)
192
+ emit_body
193
+ k_end
194
+ end
195
+
196
+ # Emit body
197
+ #
198
+ # @return [undefined]
199
+ #
200
+ # @api private
201
+ #
202
+ def emit_body
203
+ if NOINDENT.include?(body.type)
204
+ emit_inner
205
+ else
206
+ indented { emit_inner }
207
+ end
208
+ end
209
+
210
+ end # Explicit
211
+
212
+ end # Begin
179
213
  end # Emitter
180
214
  end # Unparser
@@ -33,7 +33,7 @@ module Unparser
33
33
  else_branch = children.last
34
34
  return unless else_branch
35
35
  write(K_ELSE)
36
- indented { visit(else_branch) }
36
+ visit_indented(else_branch)
37
37
  end
38
38
 
39
39
  # Emit whens
@@ -80,11 +80,7 @@ module Unparser
80
80
  write(K_WHEN, WS)
81
81
  emit_captures
82
82
  body = children.last
83
- if body
84
- indented { visit(body) }
85
- else
86
- nl
87
- end
83
+ emit_body(body)
88
84
  end
89
85
 
90
86
  # Emit captures
@@ -35,16 +35,6 @@ module Unparser
35
35
  write(WS, K_DO)
36
36
  end
37
37
 
38
- # Emit body
39
- #
40
- # @return [undefined]
41
- #
42
- # @api private
43
- #
44
- def emit_body
45
- indented { visit(body) }
46
- end
47
-
48
38
  end # For
49
39
  end # Emitter
50
40
  end # Unparser
@@ -27,16 +27,6 @@ module Unparser
27
27
  end
28
28
  end
29
29
 
30
- # Emit body
31
- #
32
- # @return [undefined]
33
- #
34
- # @api private
35
- #
36
- def emit_body
37
- indented { visit(body) }
38
- end
39
-
40
30
  end # Hookexe
41
31
  end # Emitter
42
32
  end # Unparser
@@ -65,7 +65,7 @@ module Unparser
65
65
  #
66
66
  def emit_if_branch
67
67
  return unless if_branch
68
- indented { visit(if_branch) }
68
+ visit_indented(if_branch)
69
69
  end
70
70
 
71
71
  # Emit else branch
@@ -77,7 +77,7 @@ module Unparser
77
77
  def emit_else_branch
78
78
  return unless else_branch
79
79
  write(K_ELSE) unless unless?
80
- indented { visit(else_branch) }
80
+ visit_indented(else_branch)
81
81
  end
82
82
 
83
83
  end # If
@@ -354,6 +354,19 @@ describe Unparser, 'spike' do
354
354
  end
355
355
  RUBY
356
356
 
357
+ assert_source <<-RUBY
358
+ begin
359
+ begin
360
+ foo
361
+ bar
362
+ rescue
363
+ end
364
+ rescue
365
+ baz
366
+ bar
367
+ end
368
+ RUBY
369
+
357
370
  assert_source <<-RUBY
358
371
  begin
359
372
  foo
@@ -427,6 +440,15 @@ describe Unparser, 'spike' do
427
440
  end
428
441
  RUBY
429
442
 
443
+ assert_source <<-RUBY
444
+ begin
445
+ bar
446
+ rescue
447
+ else
448
+ baz
449
+ end
450
+ RUBY
451
+
430
452
  assert_source <<-RUBY
431
453
  begin
432
454
  bar
@@ -565,6 +587,22 @@ describe Unparser, 'spike' do
565
587
  end
566
588
  RUBY
567
589
 
590
+ assert_source <<-RUBY
591
+ def foo
592
+ bar
593
+ ensure
594
+ baz
595
+ end
596
+ RUBY
597
+
598
+ assert_source <<-RUBY
599
+ def foo
600
+ bar
601
+ rescue
602
+ baz
603
+ end
604
+ RUBY
605
+
568
606
  assert_source <<-RUBY
569
607
  def foo(bar)
570
608
  bar
@@ -662,7 +700,6 @@ describe Unparser, 'spike' do
662
700
  end
663
701
 
664
702
  context 'on singleton' do
665
-
666
703
  assert_source <<-RUBY
667
704
  def self.foo
668
705
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'unparser'
5
- s.version = '0.0.6'
5
+ s.version = '0.0.7'
6
6
 
7
7
  s.authors = ['Markus Schirp']
8
8
  s.email = 'mbj@schir-dso.com'
@@ -15,9 +15,9 @@ Gem::Specification.new do |s|
15
15
  s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
16
16
  s.require_paths = %w(lib)
17
17
  s.extra_rdoc_files = %w(README.md)
18
- s.executables = [ 'unparse' ]
18
+ s.executables = [ 'test-unparser' ]
19
19
 
20
- s.add_dependency('parser', '~> 2.0.0.beta9')
20
+ s.add_dependency('parser', '~> 2.0.0.beta10')
21
21
  s.add_dependency('concord', '~> 0.1.0')
22
22
  s.add_dependency('adamantium', '~> 0.0.7')
23
23
  s.add_dependency('equalizer', '~> 0.0.5')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unparser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Markus Schirp
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-28 00:00:00.000000000 Z
11
+ date: 2013-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 2.0.0.beta9
19
+ version: 2.0.0.beta10
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ~>
25
25
  - !ruby/object:Gem::Version
26
- version: 2.0.0.beta9
26
+ version: 2.0.0.beta10
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: concord
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -83,7 +83,7 @@ dependencies:
83
83
  description: Generate equivalent source for parser gem AST nodes
84
84
  email: mbj@schir-dso.com
85
85
  executables:
86
- - unparse
86
+ - test-unparser
87
87
  extensions: []
88
88
  extra_rdoc_files:
89
89
  - README.md
@@ -100,7 +100,7 @@ files:
100
100
  - README.md
101
101
  - Rakefile
102
102
  - TODO
103
- - bin/unparse
103
+ - bin/test-unparser
104
104
  - config/devtools.yml
105
105
  - config/flay.yml
106
106
  - config/flog.yml
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- trap('INT') do |status|
4
- exit! 128+status
5
- end
6
-
7
- require 'unparser'
8
- require 'parser/current'
9
-
10
- ARGV.each do |file|
11
- source = File.read(file)
12
- node = Parser::CurrentRuby.parse(source)
13
- $stderr.puts "File: #{file}"
14
- $stderr.puts node.inspect
15
- puts Unparser.unparse(node)
16
- end