to_source 0.2.9 → 0.2.11

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.
Files changed (71) hide show
  1. data/Changelog.md +13 -0
  2. data/LICENSE +21 -0
  3. data/README.md +6 -22
  4. data/TODO +3 -3
  5. data/lib/to_source.rb +68 -3
  6. data/lib/to_source/buffer.rb +40 -0
  7. data/lib/to_source/command.rb +44 -0
  8. data/lib/to_source/emitter.rb +76 -0
  9. data/lib/to_source/emitter/access.rb +20 -0
  10. data/lib/to_source/emitter/actual_arguments.rb +46 -0
  11. data/lib/to_source/emitter/alias.rb +18 -0
  12. data/lib/to_source/emitter/assignment.rb +77 -0
  13. data/lib/to_source/emitter/attribute_assignment.rb +19 -0
  14. data/lib/to_source/emitter/begin.rb +51 -0
  15. data/lib/to_source/emitter/binary_operator.rb +36 -0
  16. data/lib/to_source/emitter/binary_operator_method.rb +29 -0
  17. data/lib/to_source/emitter/block.rb +22 -0
  18. data/lib/to_source/emitter/block_argument.rb +16 -0
  19. data/lib/to_source/emitter/block_pass.rb +16 -0
  20. data/lib/to_source/emitter/class.rb +29 -0
  21. data/lib/to_source/emitter/concat_arguments.rb +20 -0
  22. data/lib/to_source/emitter/default_arguments.rb +15 -0
  23. data/lib/to_source/emitter/define.rb +61 -0
  24. data/lib/to_source/emitter/defined.rb +17 -0
  25. data/lib/to_source/emitter/element_assignment.rb +20 -0
  26. data/lib/to_source/emitter/element_reference.rb +16 -0
  27. data/lib/to_source/emitter/empty_body.rb +12 -0
  28. data/lib/to_source/emitter/ensure.rb +23 -0
  29. data/lib/to_source/emitter/ensure_body.rb +18 -0
  30. data/lib/to_source/emitter/execute_string.rb +13 -0
  31. data/lib/to_source/emitter/formal_arguments.rb +120 -0
  32. data/lib/to_source/emitter/if.rb +51 -0
  33. data/lib/to_source/emitter/iter.rb +20 -0
  34. data/lib/to_source/emitter/keyword_value.rb +43 -0
  35. data/lib/to_source/emitter/literal.rb +239 -0
  36. data/lib/to_source/emitter/match3.rb +17 -0
  37. data/lib/to_source/emitter/module.rb +21 -0
  38. data/lib/to_source/emitter/multiple_assignment.rb +23 -0
  39. data/lib/to_source/emitter/nth_ref.rb +15 -0
  40. data/lib/to_source/emitter/op_assign1.rb +19 -0
  41. data/lib/to_source/emitter/op_assign2.rb +19 -0
  42. data/lib/to_source/emitter/pattern_arguments.rb +17 -0
  43. data/lib/to_source/emitter/receiver_case.rb +35 -0
  44. data/lib/to_source/emitter/rescue.rb +21 -0
  45. data/lib/to_source/emitter/rescue_condition.rb +56 -0
  46. data/lib/to_source/emitter/scope.rb +17 -0
  47. data/lib/to_source/emitter/scope_name.rb +16 -0
  48. data/lib/to_source/emitter/scoped_name.rb +17 -0
  49. data/lib/to_source/emitter/send.rb +47 -0
  50. data/lib/to_source/emitter/send_with_arguments.rb +62 -0
  51. data/lib/to_source/emitter/singleton_class.rb +23 -0
  52. data/lib/to_source/emitter/splat.rb +17 -0
  53. data/lib/to_source/emitter/splat_when.rb +16 -0
  54. data/lib/to_source/emitter/static.rb +33 -0
  55. data/lib/to_source/emitter/super.rb +47 -0
  56. data/lib/to_source/emitter/to_array.rb +15 -0
  57. data/lib/to_source/emitter/to_string.rb +17 -0
  58. data/lib/to_source/emitter/toplevel.rb +15 -0
  59. data/lib/to_source/emitter/unary_operator_method.rb +20 -0
  60. data/lib/to_source/emitter/unless.rb +16 -0
  61. data/lib/to_source/emitter/until.rb +20 -0
  62. data/lib/to_source/emitter/util.rb +19 -0
  63. data/lib/to_source/emitter/when.rb +38 -0
  64. data/lib/to_source/emitter/while.rb +20 -0
  65. data/lib/to_source/emitter/yield.rb +19 -0
  66. data/lib/to_source/emitter/z_super.rb +17 -0
  67. data/lib/to_source/state.rb +60 -0
  68. data/spec/unit/to_source/{visitor/class_methods → class_methods}/run_spec.rb +84 -33
  69. data/to_source.gemspec +14 -12
  70. metadata +106 -11
  71. data/lib/to_source/visitor.rb +0 -1890
data/Changelog.md CHANGED
@@ -1,3 +1,16 @@
1
+ # v0.2.11 2013-01-9
2
+
3
+ * [fixed] Allow all nodes to be entrypoints
4
+
5
+ [Compare v0.2.10..v0.2.11](https://github.com/mbj/to_source/compare/v0.2.9...v0.2.11)
6
+
7
+ # v0.2.10 2013-01-7
8
+
9
+ * [Changed] Rewrote internals compleatly, no outer API change
10
+ * [fixed] Emit indentation of complex nested structures with rescue statements correctly
11
+
12
+ [Compare v0.2.9..v0.2.10](https://github.com/mbj/to_source/compare/v0.2.9...v0.2.10)
13
+
1
14
  # v0.2.9 2013-01-4
2
15
 
3
16
  * [fixed] Handle regexp literals containing slashes in non shash delimiters %r(/) correctly
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2013 Markus Schirp (mbj)
2
+ 2012 Josep M. Bach (Txus)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md CHANGED
@@ -5,7 +5,9 @@ to_source
5
5
  [![Dependency Status](https://gemnasium.com/mbj/to_source.png)](https://gemnasium.com/mbj/to_source)
6
6
  [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/mbj/to_source)
7
7
 
8
- Reverse parser to generate source code from the Rubinius AST. Also works well under MRI.
8
+ Reverse parser to generate source code from the Rubinius AST. Also works well under MRI using the mutant-melbourne gem.
9
+
10
+ Currently only support 1.9 mode!
9
11
 
10
12
  Installation
11
13
  ------------
@@ -29,8 +31,9 @@ ast.to_source
29
31
  Credits
30
32
  -------
31
33
 
32
- * [Josep M. Bach (Txus)](http://txustice.me), [@txustice](http://twitter.com/txustice) on twitter
33
34
  * [Markus Schirp (mbj)](https://github.com/mbj), [@_m_b_j_](http://twitter.com/_m_b_j_) on twitter
35
+ * [Josep M. Bach (Txus)](http://txustice.me), [@txustice](http://twitter.com/txustice) on twitter
36
+
34
37
 
35
38
  Contributing
36
39
  -------------
@@ -46,23 +49,4 @@ Contributing
46
49
  License
47
50
  -------
48
51
 
49
- Copyright (c) 2012 Josep M. Bach (Txus), Markus Schirp (mbj)
50
-
51
- Permission is hereby granted, free of charge, to any person obtaining
52
- a copy of this software and associated documentation files (the
53
- "Software"), to deal in the Software without restriction, including
54
- without limitation the rights to use, copy, modify, merge, publish,
55
- distribute, sublicense, and/or sell copies of the Software, and to
56
- permit persons to whom the Software is furnished to do so, subject to
57
- the following conditions:
58
-
59
- The above copyright notice and this permission notice shall be
60
- included in all copies or substantial portions of the Software.
61
-
62
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
63
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
64
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
65
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
66
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
67
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
68
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52
+ See LICENSE
data/TODO CHANGED
@@ -1,8 +1,8 @@
1
1
  * Do not emit parantheses around non keywords in binary operations (this will beautify source again)
2
- * Rewrite this library it is ultra hacky and adhoc
2
+ * Add YARD coverage again
3
+ * Fix all dm2 metric tools issues
4
+ * Mutation coverage!
3
5
  * Fix parsing errors from ruby parser
4
6
  It breaks on def $keyword.
5
- * Do a metric driven refactor once flay flog and friends work.
6
7
  * Report bug about missing Rubinius::AST::SClass#body
7
8
  * Decide about to support 18-mode or not
8
- * Fix emit of nested boolean uperators and parantheses!
data/lib/to_source.rb CHANGED
@@ -1,9 +1,73 @@
1
1
  require 'set'
2
2
  require 'melbourne'
3
- require 'to_source/visitor'
3
+ require 'adamantium'
4
+ require 'abstract_type'
5
+ require 'equalizer'
6
+ require 'to_source/command'
7
+ require 'to_source/state'
8
+ require 'to_source/emitter'
9
+ require 'to_source/emitter/literal'
10
+ require 'to_source/emitter/access'
11
+ require 'to_source/emitter/formal_arguments'
12
+ require 'to_source/emitter/actual_arguments'
13
+ require 'to_source/emitter/scope'
14
+ require 'to_source/emitter/define'
15
+ require 'to_source/emitter/assignment'
16
+ require 'to_source/emitter/static'
17
+ require 'to_source/emitter/block'
18
+ require 'to_source/emitter/toplevel'
19
+ require 'to_source/emitter/keyword_value'
20
+ require 'to_source/emitter/execute_string'
21
+ require 'to_source/emitter/singleton_class'
22
+ require 'to_source/emitter/empty_body'
23
+ require 'to_source/emitter/rescue_condition'
24
+ require 'to_source/emitter/rescue'
25
+ require 'to_source/emitter/ensure_body'
26
+ require 'to_source/emitter/scope_name'
27
+ require 'to_source/emitter/nth_ref'
28
+ require 'to_source/emitter/scoped_name'
29
+ require 'to_source/emitter/send'
30
+ require 'to_source/emitter/send_with_arguments'
31
+ require 'to_source/emitter/block_pass'
32
+ require 'to_source/emitter/iter'
33
+ require 'to_source/emitter/pattern_arguments'
34
+ require 'to_source/emitter/block_argument'
35
+ require 'to_source/emitter/unary_operator_method'
36
+ require 'to_source/emitter/binary_operator_method'
37
+ require 'to_source/emitter/binary_operator'
38
+ require 'to_source/emitter/element_reference'
39
+ require 'to_source/emitter/to_array'
40
+ require 'to_source/emitter/to_string'
41
+ require 'to_source/emitter/defined'
42
+ require 'to_source/emitter/attribute_assignment'
43
+ require 'to_source/emitter/element_assignment'
44
+ require 'to_source/emitter/if'
45
+ require 'to_source/emitter/while'
46
+ require 'to_source/emitter/ensure'
47
+ require 'to_source/emitter/receiver_case'
48
+ require 'to_source/emitter/when'
49
+ require 'to_source/emitter/splat_when'
50
+ require 'to_source/emitter/unless'
51
+ require 'to_source/emitter/until'
52
+ require 'to_source/emitter/class'
53
+ require 'to_source/emitter/module'
54
+ require 'to_source/emitter/op_assign2'
55
+ require 'to_source/emitter/op_assign1'
56
+ require 'to_source/emitter/z_super'
57
+ require 'to_source/emitter/default_arguments'
58
+ require 'to_source/emitter/multiple_assignment'
59
+ require 'to_source/emitter/concat_arguments'
60
+ require 'to_source/emitter/super'
61
+ require 'to_source/emitter/match3'
62
+ require 'to_source/emitter/yield'
63
+ require 'to_source/emitter/alias'
64
+ require 'to_source/emitter/splat'
65
+ require 'to_source/emitter/begin'
66
+ require 'to_source/emitter/util'
4
67
 
5
- # Namespace of library
68
+ # Library namespace
6
69
  module ToSource
70
+
7
71
  # Convert node to string
8
72
  #
9
73
  # @param [Rubinius::AST::Node] node
@@ -13,6 +77,7 @@ module ToSource
13
77
  # @api private
14
78
  #
15
79
  def self.to_source(node)
16
- Visitor.run(node)
80
+ Emitter.run(node)
17
81
  end
82
+
18
83
  end
@@ -0,0 +1,40 @@
1
+ module ToSource
2
+ class Buffer
3
+ include Adamantium::Flat
4
+
5
+ attr_reader :lines
6
+
7
+ def initialize(lines = [])
8
+ @lines = lines
9
+ end
10
+
11
+ def to_s
12
+ @lines.join("\n")
13
+ end
14
+
15
+ def indent
16
+ new(lines.map { |line| " #{line}" })
17
+ end
18
+
19
+ def body(body)
20
+ self
21
+ end
22
+
23
+ def class_open(name, superclass)
24
+ push('class')
25
+ end
26
+
27
+ def push(token)
28
+ new(lines.dup << token)
29
+ end
30
+
31
+ def end
32
+ push('end')
33
+ end
34
+
35
+ def new(*args)
36
+ self.class.new(*args)
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,44 @@
1
+ module ToSource
2
+ class Command
3
+ include Adamantium::Flat
4
+
5
+ NULL = Class.new(self) do
6
+ def run(_state)
7
+ end
8
+ end.new.freeze
9
+
10
+ class Token < self
11
+ attr_reader :content
12
+
13
+ def run(state)
14
+ state.push(self)
15
+ end
16
+
17
+ private
18
+
19
+ def initialize(content)
20
+ @content = content
21
+ end
22
+ end
23
+
24
+ class Shift < self
25
+ include Equalizer.new(:width)
26
+
27
+ attr_reader :width
28
+
29
+ def run(state)
30
+ state.shift(width)
31
+ end
32
+
33
+ private
34
+
35
+ def initialize(width)
36
+ @width = width
37
+ end
38
+
39
+ INDENT = Shift.new( 2)
40
+ UNINDENT = Shift.new(-2)
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,76 @@
1
+ module ToSource
2
+ class Emitter
3
+ include Adamantium::Flat, Equalizer.new(:node)
4
+
5
+ REGISTRY = {}
6
+
7
+ def self.handle(node_class)
8
+ REGISTRY[node_class]=self
9
+ end
10
+
11
+ def self.build(node, buffer = [])
12
+ REGISTRY.fetch(node.class).new(node, buffer)
13
+ end
14
+
15
+ def self.run(node)
16
+ build(node).source
17
+ end
18
+
19
+
20
+ def source
21
+ state = State.new
22
+ buffer.each do |command|
23
+ state.execute(command)
24
+ end
25
+ state.source
26
+ end
27
+
28
+ attr_reader :node
29
+
30
+ private
31
+
32
+ def push(command)
33
+ buffer.push(command)
34
+ end
35
+
36
+ def new_line
37
+ emit("\n")
38
+ end
39
+
40
+ def space
41
+ emit(' ')
42
+ end
43
+
44
+ def emit_end
45
+ emit(:end)
46
+ end
47
+
48
+ def indent
49
+ push(Command::Shift::INDENT)
50
+ end
51
+
52
+ def unindent
53
+ push(Command::Shift::UNINDENT)
54
+ end
55
+
56
+ def emit(name)
57
+ push(Command::Token.new(name))
58
+ end
59
+
60
+ def visit(node)
61
+ self.class.build(node, buffer)
62
+ end
63
+
64
+ def run(emitter, node = self.node)
65
+ emitter.new(node, buffer)
66
+ end
67
+
68
+ attr_reader :buffer
69
+
70
+ def initialize(node, buffer)
71
+ @node, @buffer = node, buffer
72
+ dispatch
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,20 @@
1
+ module ToSource
2
+ class Emitter
3
+ class Access < self
4
+
5
+ handle(Rubinius::AST::ConstantAccess)
6
+ handle(Rubinius::AST::InstanceVariableAccess)
7
+ handle(Rubinius::AST::LocalVariableAccess)
8
+ handle(Rubinius::AST::ClassVariableAccess)
9
+ handle(Rubinius::AST::GlobalVariableAccess)
10
+ handle(Rubinius::AST::PatternVariable)
11
+
12
+ private
13
+
14
+ def dispatch
15
+ emit(node.name)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,46 @@
1
+ module ToSource
2
+ class Emitter
3
+ class ActualArguments < self
4
+
5
+ handle(Rubinius::AST::ActualArguments)
6
+
7
+ def any?
8
+ normal? or splat?
9
+ end
10
+
11
+ private
12
+
13
+ def dispatch
14
+ emit_normal
15
+ emit_splat
16
+ end
17
+
18
+ def array
19
+ node.array
20
+ end
21
+
22
+ def splat?
23
+ !!splat
24
+ end
25
+
26
+ def normal?
27
+ !array.empty?
28
+ end
29
+
30
+ def splat
31
+ node.splat
32
+ end
33
+
34
+ def emit_normal
35
+ run(Util::DelimitedBody, array)
36
+ end
37
+
38
+ def emit_splat
39
+ return unless splat?
40
+ emit(', ') if normal?
41
+ visit(splat)
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,18 @@
1
+ module ToSource
2
+ class Emitter
3
+ class Alias < self
4
+
5
+ handle(Rubinius::AST::Alias)
6
+
7
+ private
8
+
9
+ def dispatch
10
+ emit('alias ')
11
+ emit(node.to.value)
12
+ space
13
+ emit(node.from.value)
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,77 @@
1
+ module ToSource
2
+ class Emitter
3
+ class Assignment < self
4
+
5
+ private
6
+
7
+ def dispatch
8
+ emit_name
9
+ val = value
10
+
11
+ if val
12
+ emit(' = ')
13
+ visit(val)
14
+ end
15
+ end
16
+
17
+ def value
18
+ node.value
19
+ end
20
+
21
+ class Constant < self
22
+
23
+ handle(Rubinius::AST::ConstantAssignment)
24
+
25
+ def emit_name
26
+ visit(node.constant)
27
+ end
28
+
29
+ end
30
+
31
+ class Variable < self
32
+
33
+ handle(Rubinius::AST::LocalVariableAssignment)
34
+ handle(Rubinius::AST::InstanceVariableAssignment)
35
+ handle(Rubinius::AST::GlobalVariableAssignment)
36
+ handle(Rubinius::AST::ClassVariableAssignment)
37
+
38
+ def emit_name
39
+ emit(node.name)
40
+ end
41
+
42
+ def name
43
+ node.name
44
+ end
45
+
46
+ end
47
+ end
48
+
49
+ class AssignmentOperator < self
50
+
51
+ def dispatch
52
+ visit(node.left)
53
+ space
54
+ emit(self.class::SYMBOL)
55
+ space
56
+ emit('(')
57
+ visit(node.right.value)
58
+ emit(')')
59
+ end
60
+
61
+ class Or < self
62
+
63
+ SYMBOL = :'||='
64
+ handle(Rubinius::AST::OpAssignOr19)
65
+
66
+ end
67
+
68
+ class And < self
69
+
70
+ SYMBOL = :'&&='
71
+ handle(Rubinius::AST::OpAssignAnd)
72
+
73
+ end
74
+
75
+ end
76
+ end
77
+ end