to_source 0.2.16 → 0.2.17

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 (42) hide show
  1. data/.rspec +1 -0
  2. data/Changelog.md +34 -1
  3. data/bin/to_source +2 -8
  4. data/config/flay.yml +1 -1
  5. data/config/site.reek +5 -0
  6. data/lib/to_source.rb +17 -3
  7. data/lib/to_source/emitter.rb +5 -1
  8. data/lib/to_source/emitter/alias.rb +23 -0
  9. data/lib/to_source/emitter/assignment.rb +23 -84
  10. data/lib/to_source/emitter/assignment/attribute.rb +52 -0
  11. data/lib/to_source/emitter/assignment/constant.rb +26 -0
  12. data/lib/to_source/emitter/assignment/element.rb +124 -0
  13. data/lib/to_source/emitter/assignment/variable.rb +29 -0
  14. data/lib/to_source/emitter/assignment_operator.rb +54 -0
  15. data/lib/to_source/emitter/back_ref.rb +23 -0
  16. data/lib/to_source/emitter/binary_operator_method.rb +38 -2
  17. data/lib/to_source/emitter/collect_splat.rb +50 -0
  18. data/lib/to_source/emitter/concat_arguments.rb +16 -1
  19. data/lib/to_source/emitter/element_reference.rb +1 -1
  20. data/lib/to_source/emitter/flip.rb +61 -0
  21. data/lib/to_source/emitter/for.rb +98 -0
  22. data/lib/to_source/emitter/iter.rb +23 -1
  23. data/lib/to_source/emitter/literal.rb +1 -18
  24. data/lib/to_source/emitter/literal/dynamic.rb +0 -23
  25. data/lib/to_source/emitter/literal/dynamic/regexp.rb +69 -0
  26. data/lib/to_source/emitter/literal/regexp.rb +27 -0
  27. data/lib/to_source/emitter/literal/regexp/options.rb +71 -0
  28. data/lib/to_source/emitter/match.rb +21 -0
  29. data/lib/to_source/emitter/match2.rb +25 -0
  30. data/lib/to_source/emitter/multiple_assignment.rb +43 -4
  31. data/lib/to_source/emitter/op_assign1.rb +37 -5
  32. data/lib/to_source/emitter/push_args.rb +42 -0
  33. data/lib/to_source/emitter/send.rb +21 -16
  34. data/lib/to_source/emitter/splat.rb +40 -1
  35. data/lib/to_source/emitter/static.rb +32 -0
  36. data/lib/to_source/emitter/toplevel.rb +2 -1
  37. data/lib/to_source/emitter/undef.rb +26 -0
  38. data/spec/unit/to_source/class_methods/run_spec.rb +245 -20
  39. data/to_source.gemspec +1 -1
  40. metadata +18 -4
  41. data/lib/to_source/emitter/attribute_assignment.rb +0 -28
  42. data/lib/to_source/emitter/element_assignment.rb +0 -29
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --fail-fast
@@ -1,11 +1,44 @@
1
- # v0.2.15 2013-01-25
1
+ # v0.2.17 2013-01-26
2
+
3
+ * [fixed] Fix op assign 1 operators with implicit index array[] ||= etc
4
+ * [fixed] Fix op assign 1 operators with explicit index array[foo] ||= etc
5
+ * [fixed] Add support regexp in if statements with implicit haystack (Rubinius::AST::Match)
6
+ * [fixed] Add support for Rubionius::AST::Flip{2,3} (flip flops)
7
+ * [fixed] Add support for Rubionius::AST::VAlias
8
+ * [fixed] Fix multiple edge cases with array literals and splats
9
+ * [fixed] Add support for mixed splat arguments
10
+ * [fixed] Add support for __ENCODING__
11
+ * [fixed] Fix emit of splat arguments to binary method operators
12
+ * [fixed] Fix multiple assigments when assigning to element with splat index
13
+ * [fixed] Add support for retry
14
+ * [fixed] Add support for redo
15
+ * [fixed] Add support rubinius specific type constant
16
+ * [fixed] Add support for dynamic once literal
17
+ * [fixed] Emit regexp options for single and dynamic literals
18
+ * [fixed] Add support for undef keyword
19
+ * [fixed] Add support toplevel module name
20
+ * [fixed] Fix regexp emitter for edge cases
21
+ * [fixed] Fix element reference with splat arguments
22
+ * [fixed] Add support for construct
23
+ * [fixed] Add support splat assigmnent in multiple assignment
24
+ * [fixed] Add support for /s/ =~ foo (Rubinius::AST::Match2)
25
+ * [fixed] Add support for $` (Rubinius::AST::BackRef)
26
+ * [fixed] Support multiple assignments also for attribute and element assignments
27
+
28
+ [Compare v0.2.16..v0.2.17](https://github.com/mbj/to_source/compare/v0.2.16...v0.2.17)
29
+
30
+ # v0.2.16 2013-01-25
2
31
 
3
32
  * [fixed] Handle Rubinius::AST::Case
4
33
 
34
+ [Compare v0.2.15..v0.2.16](https://github.com/mbj/to_source/compare/v0.2.15...v0.2.16)
35
+
5
36
  # v0.2.15 2013-01-24
6
37
 
7
38
  * [fixed] Emit dynamic regexp literals with split groups correctly
8
39
 
40
+ [Compare v0.2.14..v0.2.15](https://github.com/mbj/to_source/compare/v0.2.14...v0.2.15)
41
+
9
42
  # v0.2.14 2013-01-09
10
43
 
11
44
  * [fixed] Emit send with arguments and body correctly
@@ -3,15 +3,9 @@
3
3
  require 'to_source'
4
4
 
5
5
  ARGV.each do |path|
6
+ $stderr.puts(path)
6
7
  source = File.read(path)
7
8
  ast = source.to_ast
8
9
  next if ast.nil? # When file only has comments
9
- $stderr.puts(path)
10
- begin
11
- $stdout.puts(ToSource.to_source(ast))
12
- rescue
13
- ast.ascii_graph
14
- $stderr.puts("Error in: #{path}")
15
- raise
16
- end
10
+ $stderr.puts(ToSource.to_source(ast))
17
11
  end
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 40
3
- total_score: 719
3
+ total_score: 882
@@ -42,6 +42,11 @@ IrresponsibleModule:
42
42
  enabled: false
43
43
  UncommunicativeModuleName:
44
44
  accept:
45
+ - ToSource::Emitter::Match2
46
+ - ToSource::Emitter::Iter19
47
+ - ToSource::Emitter::Flip::Flip2
48
+ - ToSource::Emitter::Flip::Flip3
49
+ - ToSource::Emitter::For19
45
50
  - ToSource::Emitter::Match3
46
51
  - ToSource::Emitter::OpAssign1
47
52
  - ToSource::Emitter::OpAssign2
@@ -8,12 +8,20 @@ require 'to_source/state'
8
8
  require 'to_source/emitter'
9
9
  require 'to_source/emitter/literal'
10
10
  require 'to_source/emitter/literal/dynamic'
11
+ require 'to_source/emitter/literal/dynamic/regexp'
12
+ require 'to_source/emitter/literal/regexp'
13
+ require 'to_source/emitter/literal/regexp/options'
11
14
  require 'to_source/emitter/access'
12
15
  require 'to_source/emitter/formal_arguments'
13
16
  require 'to_source/emitter/actual_arguments'
14
17
  require 'to_source/emitter/scope'
15
18
  require 'to_source/emitter/define'
16
19
  require 'to_source/emitter/assignment'
20
+ require 'to_source/emitter/assignment/element'
21
+ require 'to_source/emitter/assignment/variable'
22
+ require 'to_source/emitter/assignment/attribute'
23
+ require 'to_source/emitter/assignment/constant'
24
+ require 'to_source/emitter/assignment_operator'
17
25
  require 'to_source/emitter/static'
18
26
  require 'to_source/emitter/block'
19
27
  require 'to_source/emitter/toplevel'
@@ -32,6 +40,7 @@ require 'to_source/emitter/send_with_arguments'
32
40
  require 'to_source/emitter/block_pass'
33
41
  require 'to_source/emitter/block_argument'
34
42
  require 'to_source/emitter/iter'
43
+ require 'to_source/emitter/for'
35
44
  require 'to_source/emitter/pattern_arguments'
36
45
  require 'to_source/emitter/unary_operator_method'
37
46
  require 'to_source/emitter/binary_operator_method'
@@ -40,15 +49,19 @@ require 'to_source/emitter/element_reference'
40
49
  require 'to_source/emitter/to_array'
41
50
  require 'to_source/emitter/to_string'
42
51
  require 'to_source/emitter/defined'
43
- require 'to_source/emitter/attribute_assignment'
44
- require 'to_source/emitter/element_assignment'
52
+ require 'to_source/emitter/undef'
45
53
  require 'to_source/emitter/if'
54
+ require 'to_source/emitter/back_ref'
46
55
  require 'to_source/emitter/loop'
47
56
  require 'to_source/emitter/ensure'
48
57
  require 'to_source/emitter/case'
49
58
  require 'to_source/emitter/when'
59
+ require 'to_source/emitter/splat'
60
+ require 'to_source/emitter/push_args'
50
61
  require 'to_source/emitter/splat_when'
62
+ require 'to_source/emitter/collect_splat'
51
63
  require 'to_source/emitter/unless'
64
+ require 'to_source/emitter/flip'
52
65
  require 'to_source/emitter/class'
53
66
  require 'to_source/emitter/module'
54
67
  require 'to_source/emitter/op_assign2'
@@ -58,10 +71,11 @@ require 'to_source/emitter/default_arguments'
58
71
  require 'to_source/emitter/multiple_assignment'
59
72
  require 'to_source/emitter/concat_arguments'
60
73
  require 'to_source/emitter/super'
74
+ require 'to_source/emitter/match'
75
+ require 'to_source/emitter/match2'
61
76
  require 'to_source/emitter/match3'
62
77
  require 'to_source/emitter/yield'
63
78
  require 'to_source/emitter/alias'
64
- require 'to_source/emitter/splat'
65
79
  require 'to_source/emitter/begin'
66
80
  require 'to_source/emitter/util'
67
81
 
@@ -16,7 +16,11 @@ module ToSource
16
16
  # @api private
17
17
  #
18
18
  def self.build(node, buffer = [])
19
- REGISTRY.fetch(node.class).new(node, buffer)
19
+ klass = node.class
20
+ emitter = REGISTRY.fetch(klass) do
21
+ raise RuntimeError, "No emmitter for: #{klass} at line: #{node.line}"
22
+ end
23
+ emitter.new(node, buffer)
20
24
  end
21
25
 
22
26
  # Run emitter for node
@@ -1,5 +1,28 @@
1
1
  module ToSource
2
2
  class Emitter
3
+ class VAlias < self
4
+
5
+ handle(Rubinius::AST::VAlias)
6
+
7
+ private
8
+
9
+ delegate(:to, :from)
10
+
11
+ # Perform dispatch
12
+ #
13
+ # @return [undefined]
14
+ #
15
+ # @api private
16
+ #
17
+ def dispatch
18
+ emit('alias ')
19
+ emit(to)
20
+ space
21
+ emit(from)
22
+ end
23
+
24
+ end
25
+
3
26
  # Emiter for alias node
4
27
  class Alias < self
5
28
 
@@ -2,10 +2,23 @@ module ToSource
2
2
  class Emitter
3
3
  # Base class for various assignment nodes
4
4
  class Assignment < self
5
+ include AbstractType
5
6
 
6
7
  private
7
8
 
8
- delegate :value
9
+ predicate(:value)
10
+
11
+ # Return value to assign
12
+ #
13
+ # @return [Rubinius::AST::Node]
14
+ # if present
15
+ #
16
+ # @return [nil]
17
+ # otherwise
18
+ #
19
+ # @api private
20
+ #
21
+ abstract_method :value
9
22
 
10
23
  # Perform dispatch
11
24
  #
@@ -15,105 +28,31 @@ module ToSource
15
28
  #
16
29
  def dispatch
17
30
  emit_target
18
- val = value
19
-
20
- if val
21
- emit(' = ')
22
- visit(val)
23
- end
24
- end
25
-
26
- # Emitter for constant assignments
27
- class Constant < self
28
-
29
- handle(Rubinius::AST::ConstantAssignment)
30
-
31
- private
32
-
33
- # Emit name
34
- #
35
- # @return [undefined]
36
- #
37
- # @api private
38
- #
39
- def emit_target
40
- visit(node.constant)
31
+ if value?
32
+ emit_operator
33
+ emit_value
41
34
  end
42
-
43
35
  end
44
36
 
45
- # Emitter for various variabe assignments
46
- class Variable < self
47
-
48
- handle(Rubinius::AST::LocalVariableAssignment)
49
- handle(Rubinius::AST::InstanceVariableAssignment)
50
- handle(Rubinius::AST::GlobalVariableAssignment)
51
- handle(Rubinius::AST::ClassVariableAssignment)
52
-
53
- private
54
-
55
- # Emit target
56
- #
57
- # @return [undefined]
58
- #
59
- # @api private
60
- #
61
- def emit_target
62
- emit(node.name)
63
- end
64
-
65
- end
66
- end
67
-
68
- # Base class for assignment operators
69
- class AssignmentOperator < self
70
-
71
- private
72
-
73
- delegate(:left, :right)
74
-
75
- # Perform dispatch
37
+ # Emit value
76
38
  #
77
39
  # @return [undefined]
78
40
  #
79
41
  # @api private
80
42
  #
81
- def dispatch
82
- parantheses do
83
- visit(left)
84
- emit(" #{self.class::SYMBOL} ")
85
- emit_right
86
- end
43
+ def emit_value
44
+ visit(value)
87
45
  end
88
46
 
89
- # Emit right
47
+ # Emit operator
90
48
  #
91
49
  # @return [undefined]
92
50
  #
93
51
  # @api private
94
52
  #
95
- def emit_right
96
- parantheses do
97
- visit(right.value)
98
- end
53
+ def emit_operator
54
+ emit(' = ')
99
55
  end
100
-
101
- # Emitter for or assigmnent operator
102
- class Or < self
103
-
104
- handle(Rubinius::AST::OpAssignOr19)
105
- SYMBOL = :'||='
106
-
107
- end
108
-
109
- # Emitter for and assigmnent operator
110
- class And < self
111
-
112
- handle(Rubinius::AST::OpAssignAnd)
113
- SYMBOL = :'&&='
114
-
115
- end
116
-
117
56
  end
118
57
  end
119
58
  end
@@ -0,0 +1,52 @@
1
+ module ToSource
2
+ class Emitter
3
+ class Assignment
4
+ # Emitter for attribute assignments
5
+ class Attribute < self
6
+
7
+ handle(Rubinius::AST::AttributeAssignment)
8
+
9
+ private
10
+
11
+ delegate(:receiver)
12
+
13
+ # Return name
14
+ #
15
+ # @return [Symbol]
16
+ #
17
+ # @api private
18
+ #
19
+ def name
20
+ node.name.to_s.gsub(/=\z/,'').to_sym
21
+ end
22
+
23
+ # Emit target
24
+ #
25
+ # @return [self]
26
+ #
27
+ # @api private
28
+ #
29
+ def emit_target
30
+ visit(receiver)
31
+ emit('.')
32
+ emit(name)
33
+ end
34
+
35
+ # Return value
36
+ #
37
+ # @return [Rubinius::AST::Node]
38
+ # if value is present
39
+ #
40
+ # @return [nil]
41
+ # otherwise
42
+ #
43
+ # @api private
44
+ #
45
+ def value
46
+ node.arguments.array.first
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,26 @@
1
+ module ToSource
2
+ class Emitter
3
+ class Assignment
4
+ # Emitter for constant assignments
5
+ class Constant < self
6
+
7
+ handle(Rubinius::AST::ConstantAssignment)
8
+
9
+ private
10
+
11
+ delegate(:value)
12
+
13
+ # Emit name
14
+ #
15
+ # @return [undefined]
16
+ #
17
+ # @api private
18
+ #
19
+ def emit_target
20
+ visit(node.constant)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,124 @@
1
+ module ToSource
2
+ class Emitter
3
+ class Assignment
4
+
5
+ class ElementDispatcher < Emitter
6
+
7
+ handle(Rubinius::AST::ElementAssignment)
8
+
9
+ private
10
+
11
+ # Perform dispatch
12
+ #
13
+ # @return [undefined]
14
+ #
15
+ # @api private
16
+ #
17
+ def dispatch
18
+ case node.arguments
19
+ when Rubinius::AST::ActualArguments
20
+ run(Element::Argument)
21
+ when Rubinius::AST::PushActualArguments
22
+ run(Element::Push)
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ # Emitter for element assignments
29
+ class Element < self
30
+
31
+ private
32
+
33
+ delegate(:receiver, :arguments)
34
+
35
+ # Emit target
36
+ #
37
+ # @return [undefined]
38
+ #
39
+ # @api private
40
+ #
41
+ def emit_target
42
+ visit(receiver)
43
+ emit('[')
44
+ emit_index
45
+ emit(']')
46
+ end
47
+
48
+ class Argument < self
49
+
50
+ private
51
+
52
+ # Return arguments array
53
+ #
54
+ # @return [Array]
55
+ #
56
+ # @api private
57
+ #
58
+ def array
59
+ arguments.array
60
+ end
61
+
62
+ # Emit index
63
+ #
64
+ # @return [undefined]
65
+ #
66
+ # @api private
67
+ #
68
+ def emit_index
69
+ splat = arguments.splat
70
+ if splat
71
+ visit(splat)
72
+ else
73
+ visit(array[0])
74
+ end
75
+ end
76
+
77
+ # Return value
78
+ #
79
+ # @return [Rubinius::AST::Node]
80
+ # if value is present
81
+ #
82
+ # @return [nil]
83
+ # otherwise
84
+ #
85
+ def value
86
+ array[1]
87
+ end
88
+
89
+ end
90
+
91
+ class Push < self
92
+
93
+ # Emit index
94
+ #
95
+ # @return [undefined]
96
+ #
97
+ # @api private
98
+ #
99
+ def emit_index
100
+ # FIXME: Add reader
101
+ visit(arguments.instance_variable_get(:@arguments))
102
+ end
103
+
104
+ # Return value
105
+ #
106
+ # @return [Rubinius::AST::Node]
107
+ # if value is present
108
+ #
109
+ # @return [nil]
110
+ # otherwise
111
+ #
112
+ # @api private
113
+ #
114
+ def value
115
+ # FIXME: Add reader
116
+ arguments.instance_variable_get(:@value)
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end