to_source 0.2.9 → 0.2.11

Sign up to get free protection for your applications and to get access to all the features.
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