to_source 0.0.1 → 0.1.3

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.
data/Readme.md CHANGED
@@ -18,7 +18,14 @@ transform themselves into source code. It's the reverse of Rubinius' builtin
18
18
 
19
19
  to_source needs Rubinius 2.0 to run, in either 1.8 or 1.9 mode.
20
20
 
21
- Put this in your Gemfile:
21
+ To install it as a gem:
22
+
23
+ $ gem install to_source
24
+
25
+ And `require 'to_source'` from your code. Automatically, your AST nodes respond
26
+ to the `#to_source` method.
27
+
28
+ But if you're using Bundler, just put this in your Gemfile:
22
29
 
23
30
  gem 'to_source'
24
31
 
@@ -9,8 +9,11 @@ module Rubinius
9
9
  #
10
10
  # Returns nothing.
11
11
  def lazy_visit(visitor, parent=nil, indent=false)
12
- args = [self.node_name, self, parent]
13
- args.push true if indent
12
+ name = node_name
13
+ name = "#{name}_def" if %w[ class module ].include?(name)
14
+
15
+ args = [name, self, parent]
16
+ args << true if indent
14
17
 
15
18
  visitor.__send__ *args
16
19
  end
@@ -1,3 +1,3 @@
1
1
  module ToSource
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -17,6 +17,42 @@ module ToSource
17
17
  ' ' * @indentation
18
18
  end
19
19
 
20
+ def class_def(node, parent)
21
+ emit "class %s" % node.name.name
22
+
23
+ superclass = node.superclass
24
+ unless superclass.is_a?(Rubinius::AST::NilLiteral)
25
+ emit " < %s" % superclass.name
26
+ end
27
+
28
+ node.body.lazy_visit self, node, true
29
+
30
+ emit "\n"
31
+ emit "end"
32
+ end
33
+
34
+ def module_def(node, parent)
35
+ emit "module %s" % node.name.name
36
+
37
+ node.body.lazy_visit self, node, true
38
+
39
+ emit "\n"
40
+ emit "end"
41
+ end
42
+
43
+ def empty_body(*)
44
+ # do nothing
45
+ end
46
+
47
+ def class_scope(node, parent, indent)
48
+ emit "\n"
49
+ @indentation += 1 if indent
50
+ node.body.lazy_visit self, node, indent
51
+ ensure
52
+ @indentation -= 1 if indent
53
+ end
54
+ alias module_scope class_scope
55
+
20
56
  def local_variable_assignment(node, parent)
21
57
  emit "%s = " % node.name
22
58
  node.value.lazy_visit self, node
@@ -26,6 +62,15 @@ module ToSource
26
62
  emit node.name
27
63
  end
28
64
 
65
+ def instance_variable_assignment(node, parent)
66
+ emit "%s = " % node.name
67
+ node.value.lazy_visit self, node
68
+ end
69
+
70
+ def instance_variable_access(node, parent)
71
+ emit node.name
72
+ end
73
+
29
74
  def fixnum_literal(node, parent)
30
75
  emit node.value.to_s
31
76
  end
@@ -87,6 +132,12 @@ module ToSource
87
132
  node.finish.lazy_visit self, node
88
133
  end
89
134
 
135
+ def range_exclude(node, parent)
136
+ node.start.lazy_visit self, node
137
+ emit '...'
138
+ node.finish.lazy_visit self, node
139
+ end
140
+
90
141
  def regex_literal(node, parent)
91
142
  emit '/'
92
143
  emit node.source
@@ -207,6 +258,11 @@ module ToSource
207
258
  node.right.lazy_visit self, node
208
259
  end
209
260
 
261
+ def toplevel_constant(node, parent)
262
+ emit "::"
263
+ emit node.name
264
+ end
265
+
210
266
  def constant_access(node, parent)
211
267
  emit node.name
212
268
  end
@@ -217,6 +273,90 @@ module ToSource
217
273
  emit node.name
218
274
  end
219
275
 
276
+ def if(node, parent)
277
+ body, else_body = node.body, node.else
278
+ keyword = 'if'
279
+
280
+ if node.body.is_a?(Rubinius::AST::NilLiteral) && !node.else.is_a?(Rubinius::AST::NilLiteral)
281
+
282
+ body, else_body = else_body, body
283
+ keyword = 'unless'
284
+ end
285
+
286
+ emit keyword << ' '
287
+ node.condition.lazy_visit self, node
288
+ emit "\n"
289
+
290
+ @indentation += 1
291
+
292
+ if body.is_a?(Rubinius::AST::Block)
293
+ body.lazy_visit self, parent, true
294
+ else
295
+ emit current_indentation
296
+ body.lazy_visit self, parent
297
+ end
298
+
299
+ emit "\n"
300
+
301
+ if else_body.is_a?(Rubinius::AST::NilLiteral)
302
+ emit 'end'
303
+ return
304
+ end
305
+
306
+ emit "else\n"
307
+
308
+ if else_body.is_a?(Rubinius::AST::Block)
309
+ else_body.lazy_visit self, parent, true
310
+ else
311
+ emit current_indentation
312
+ else_body.lazy_visit self, parent
313
+ end
314
+
315
+ emit "\n"
316
+ emit 'end'
317
+ end
318
+
319
+ def while(node, parent)
320
+ emit 'while '
321
+ node.condition.lazy_visit self, node
322
+ emit "\n"
323
+
324
+ @indentation += 1
325
+
326
+ if node.body.is_a?(Rubinius::AST::Block)
327
+ node.body.lazy_visit self, parent, true
328
+ else
329
+ emit current_indentation
330
+ node.body.lazy_visit self, parent
331
+ end
332
+
333
+ emit "\n"
334
+ emit "end"
335
+ end
336
+
337
+ def until(node, parent)
338
+ emit 'until '
339
+ node.condition.lazy_visit self, node
340
+ emit "\n"
341
+
342
+ @indentation += 1
343
+
344
+ if node.body.is_a?(Rubinius::AST::Block)
345
+ node.body.lazy_visit self, parent, true
346
+ else
347
+ emit current_indentation
348
+ node.body.lazy_visit self, parent
349
+ end
350
+
351
+ emit "\n"
352
+ emit "end"
353
+ end
354
+
355
+ def return(node, parent)
356
+ emit 'return '
357
+ node.value.lazy_visit self, parent
358
+ end
359
+
220
360
  private
221
361
 
222
362
  def process_binary_operator(node, parent)
@@ -15,14 +15,46 @@ module ToSource
15
15
  assert_equal expected, visit(code)
16
16
  end
17
17
 
18
+ def test_class
19
+ assert_source "class TestClass\nend"
20
+ end
21
+
22
+ def test_class_with_superclass
23
+ assert_source "class TestClass < Object\nend"
24
+ end
25
+
26
+ def test_class_with_body
27
+ assert_source "class TestClass\n 1\nend"
28
+ end
29
+
30
+ def test_module
31
+ assert_source "module TestModule\nend"
32
+ end
33
+
34
+ def test_module_with_body
35
+ assert_source "module TestModule\n 1\nend"
36
+ end
37
+
18
38
  def test_local_assignment
19
39
  assert_source "foo = 1"
20
40
  end
21
41
 
42
+ def test_ivar_assignment
43
+ assert_source "@foo = 1"
44
+ end
45
+
22
46
  def test_local_access
23
47
  assert_source "foo = 1\nfoo"
24
48
  end
25
49
 
50
+ def test_ivar_access
51
+ assert_source "@foo"
52
+ end
53
+
54
+ def test_toplevel_constant_access
55
+ assert_source "::Rubinius"
56
+ end
57
+
26
58
  def test_constant_access
27
59
  assert_source "Rubinius"
28
60
  end
@@ -71,6 +103,10 @@ module ToSource
71
103
  assert_source '20..34'
72
104
  end
73
105
 
106
+ def test_range_exclude
107
+ assert_source '20...34'
108
+ end
109
+
74
110
  def test_regex
75
111
  assert_source '/.*/'
76
112
  end
@@ -122,5 +158,45 @@ module ToSource
122
158
  assert_source "!1"
123
159
  assert_source "!!1"
124
160
  end
161
+
162
+ def test_if
163
+ assert_source "if 3\n 9\nend"
164
+ end
165
+
166
+ def test_if_with_multiple_blocks
167
+ assert_source "if 3\n 9\n 8\nend"
168
+ end
169
+
170
+ def test_else
171
+ assert_source "if 3\n 9\nelse\n 9\nend"
172
+ end
173
+
174
+ def test_else_with_multiple_blocks
175
+ assert_source "if 3\n 9\n 8\nelse\n 9\n 8\nend"
176
+ end
177
+
178
+ def test_unless
179
+ assert_source "unless 3\n 9\nend"
180
+ end
181
+
182
+ def test_while
183
+ assert_source "while false\n 3\nend"
184
+ end
185
+
186
+ def test_while_with_multiple_blocks
187
+ assert_source "while false\n 3\n 5\nend"
188
+ end
189
+
190
+ def test_until
191
+ assert_source "until false\n 3\nend"
192
+ end
193
+
194
+ def test_until_with_multiple_blocks
195
+ assert_source "while false\n 3\n 5\nend"
196
+ end
197
+
198
+ def test_return
199
+ assert_source "return 9"
200
+ end
125
201
  end
126
202
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: to_source
3
3
  version: !ruby/object:Gem::Version
4
+ version: 0.1.3
4
5
  prerelease:
5
- version: 0.0.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Josep M. Bach
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-23 00:00:00.000000000 Z
12
+ date: 2012-04-12 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Transform your Rubinius AST nodes back to source code. Reverse parsing!
15
15
  email:
@@ -37,17 +37,17 @@ rdoc_options: []
37
37
  require_paths:
38
38
  - lib
39
39
  required_ruby_version: !ruby/object:Gem::Requirement
40
- none: false
41
40
  requirements:
42
41
  - - ! '>='
43
42
  - !ruby/object:Gem::Version
44
43
  version: '0'
45
- required_rubygems_version: !ruby/object:Gem::Requirement
46
44
  none: false
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
46
  requirements:
48
47
  - - ! '>='
49
48
  - !ruby/object:Gem::Version
50
49
  version: '0'
50
+ none: false
51
51
  requirements: []
52
52
  rubyforge_project:
53
53
  rubygems_version: 1.8.12