to_source 0.2.15 → 0.2.16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/.gitignore +6 -6
  2. data/Changelog.md +4 -0
  3. data/README.md +1 -1
  4. data/bin/to_source +1 -0
  5. data/config/flay.yml +1 -1
  6. data/config/flog.yml +1 -1
  7. data/config/roodi.yml +4 -4
  8. data/config/site.reek +5 -2
  9. data/config/yardstick.yml +1 -1
  10. data/lib/to_source.rb +1 -1
  11. data/lib/to_source/command.rb +63 -1
  12. data/lib/to_source/emitter.rb +221 -32
  13. data/lib/to_source/emitter/access.rb +8 -0
  14. data/lib/to_source/emitter/actual_arguments.rb +51 -8
  15. data/lib/to_source/emitter/alias.rb +11 -2
  16. data/lib/to_source/emitter/assignment.rb +62 -22
  17. data/lib/to_source/emitter/attribute_assignment.rb +11 -2
  18. data/lib/to_source/emitter/begin.rb +34 -14
  19. data/lib/to_source/emitter/binary_operator.rb +34 -17
  20. data/lib/to_source/emitter/binary_operator_method.rb +36 -17
  21. data/lib/to_source/emitter/block.rb +7 -0
  22. data/lib/to_source/emitter/block_argument.rb +7 -0
  23. data/lib/to_source/emitter/block_pass.rb +7 -0
  24. data/lib/to_source/emitter/case.rb +85 -0
  25. data/lib/to_source/emitter/class.rb +21 -6
  26. data/lib/to_source/emitter/concat_arguments.rb +11 -3
  27. data/lib/to_source/emitter/default_arguments.rb +7 -0
  28. data/lib/to_source/emitter/define.rb +46 -8
  29. data/lib/to_source/emitter/defined.rb +7 -0
  30. data/lib/to_source/emitter/element_assignment.rb +10 -1
  31. data/lib/to_source/emitter/element_reference.rb +10 -1
  32. data/lib/to_source/emitter/empty_body.rb +9 -0
  33. data/lib/to_source/emitter/ensure.rb +34 -7
  34. data/lib/to_source/emitter/ensure_body.rb +14 -5
  35. data/lib/to_source/emitter/execute_string.rb +9 -0
  36. data/lib/to_source/emitter/formal_arguments.rb +131 -39
  37. data/lib/to_source/emitter/if.rb +59 -14
  38. data/lib/to_source/emitter/iter.rb +10 -3
  39. data/lib/to_source/emitter/keyword_value.rb +28 -4
  40. data/lib/to_source/emitter/literal.rb +99 -14
  41. data/lib/to_source/emitter/literal/dynamic.rb +88 -13
  42. data/lib/to_source/emitter/loop.rb +14 -11
  43. data/lib/to_source/emitter/match3.rb +7 -0
  44. data/lib/to_source/emitter/module.rb +10 -3
  45. data/lib/to_source/emitter/multiple_assignment.rb +19 -0
  46. data/lib/to_source/emitter/nth_ref.rb +7 -0
  47. data/lib/to_source/emitter/op_assign1.rb +7 -0
  48. data/lib/to_source/emitter/op_assign2.rb +7 -0
  49. data/lib/to_source/emitter/pattern_arguments.rb +7 -0
  50. data/lib/to_source/emitter/rescue.rb +10 -4
  51. data/lib/to_source/emitter/rescue_condition.rb +40 -3
  52. data/lib/to_source/emitter/scope.rb +7 -0
  53. data/lib/to_source/emitter/scope_name.rb +7 -0
  54. data/lib/to_source/emitter/scoped_name.rb +7 -0
  55. data/lib/to_source/emitter/send.rb +71 -5
  56. data/lib/to_source/emitter/send_with_arguments.rb +53 -7
  57. data/lib/to_source/emitter/singleton_class.rb +17 -5
  58. data/lib/to_source/emitter/splat.rb +7 -0
  59. data/lib/to_source/emitter/splat_when.rb +7 -0
  60. data/lib/to_source/emitter/static.rb +19 -0
  61. data/lib/to_source/emitter/super.rb +49 -4
  62. data/lib/to_source/emitter/to_array.rb +7 -0
  63. data/lib/to_source/emitter/to_string.rb +7 -0
  64. data/lib/to_source/emitter/toplevel.rb +9 -0
  65. data/lib/to_source/emitter/unary_operator_method.rb +7 -0
  66. data/lib/to_source/emitter/unless.rb +23 -4
  67. data/lib/to_source/emitter/util.rb +8 -0
  68. data/lib/to_source/emitter/when.rb +28 -3
  69. data/lib/to_source/emitter/yield.rb +9 -0
  70. data/lib/to_source/emitter/z_super.rb +7 -0
  71. data/lib/to_source/state.rb +95 -11
  72. data/spec/unit/to_source/class_methods/run_spec.rb +13 -0
  73. data/to_source.gemspec +1 -1
  74. metadata +3 -4
  75. data/lib/to_source/buffer.rb +0 -40
  76. data/lib/to_source/emitter/receiver_case.rb +0 -35
data/.gitignore CHANGED
@@ -1,6 +1,6 @@
1
- *.gem
2
- .bundle
3
- Gemfile.lock
4
- pkg/*
5
- .rbx
6
- *.rbc
1
+ /*.gem
2
+ /.bundle
3
+ /Gemfile.lock
4
+ /pkg/*
5
+ /.rbx
6
+ /tmp
@@ -1,3 +1,7 @@
1
+ # v0.2.15 2013-01-25
2
+
3
+ * [fixed] Handle Rubinius::AST::Case
4
+
1
5
  # v0.2.15 2013-01-24
2
6
 
3
7
  * [fixed] Emit dynamic regexp literals with split groups correctly
data/README.md CHANGED
@@ -7,7 +7,7 @@ to_source
7
7
 
8
8
  Reverse parser to generate source code from the Rubinius AST. Also works well under MRI using the mutant-melbourne gem.
9
9
 
10
- Currently only support 1.9 mode!
10
+ Currently only support for 1.9 mode!
11
11
 
12
12
  Installation
13
13
  ------------
@@ -11,6 +11,7 @@ ARGV.each do |path|
11
11
  $stdout.puts(ToSource.to_source(ast))
12
12
  rescue
13
13
  ast.ascii_graph
14
+ $stderr.puts("Error in: #{path}")
14
15
  raise
15
16
  end
16
17
  end
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  threshold: 40
3
- total_score: 619
3
+ total_score: 719
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 22.2
2
+ threshold: 21.4
@@ -5,17 +5,17 @@ AssignmentInConditionalCheck: {}
5
5
  CaseMissingElseCheck: {}
6
6
  ClassLineCountCheck:
7
7
  line_count: 324
8
- ClassNameCheck:
9
- pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
8
+ #ClassNameCheck:
9
+ # pattern: !ruby/regexp /\A(?:[A-Z]+|[A-Z][a-z](?:[A-Z]?[a-z])+)\z/
10
10
  ClassVariableCheck: {}
11
11
  CyclomaticComplexityBlockCheck:
12
12
  complexity: 2
13
13
  CyclomaticComplexityMethodCheck:
14
- complexity: 4
14
+ complexity: 5
15
15
  EmptyRescueBodyCheck: {}
16
16
  ForLoopCheck: {}
17
17
  MethodLineCountCheck:
18
- line_count: 9
18
+ line_count: 11
19
19
  MethodNameCheck:
20
20
  pattern: !ruby/regexp /\A(?:[a-z\d](?:_?[a-z\d])+[?!=]?|\[\]=?|==|<=>|<<|[+*&|-])\z/
21
21
  ModuleLineCountCheck:
@@ -1,4 +1,7 @@
1
1
  ---
2
+ UnusedParameters:
3
+ exclude:
4
+ - ToSource::Command#run
2
5
  UncommunicativeParameterName:
3
6
  accept: []
4
7
  exclude: []
@@ -8,7 +11,7 @@ UncommunicativeParameterName:
8
11
  - !ruby/regexp /[0-9]$/
9
12
  - !ruby/regexp /[A-Z]/
10
13
  LargeClass:
11
- max_methods: 11
14
+ max_methods: 14 # TODO move down to 10
12
15
  exclude: []
13
16
  enabled: true
14
17
  max_instance_variables: 3
@@ -53,7 +56,7 @@ NestedIterators:
53
56
  enabled: true
54
57
  max_allowed_nesting: 1
55
58
  LongMethod:
56
- max_statements: 7
59
+ max_statements: 8 # TODO bring down to 5-6
57
60
  exclude: []
58
61
  enabled: true
59
62
  Duplication:
@@ -1,2 +1,2 @@
1
1
  ---
2
- threshold: 63.4
2
+ threshold: 100
@@ -45,7 +45,7 @@ require 'to_source/emitter/element_assignment'
45
45
  require 'to_source/emitter/if'
46
46
  require 'to_source/emitter/loop'
47
47
  require 'to_source/emitter/ensure'
48
- require 'to_source/emitter/receiver_case'
48
+ require 'to_source/emitter/case'
49
49
  require 'to_source/emitter/when'
50
50
  require 'to_source/emitter/splat_when'
51
51
  require 'to_source/emitter/unless'
@@ -1,44 +1,106 @@
1
1
  module ToSource
2
+ # Abstract base class for emitter command
2
3
  class Command
3
4
  include Adamantium::Flat
4
5
 
6
+ # A null command
5
7
  NULL = Class.new(self) do
8
+
9
+ # Run command
10
+ #
11
+ # @param [State] _state
12
+ #
13
+ # @return [self]
14
+ #
15
+ # @api private
16
+ #
6
17
  def run(_state)
18
+ self
7
19
  end
8
20
  end.new.freeze
9
21
 
22
+ # Command that emits token
10
23
  class Token < self
24
+
25
+ # Return token content
26
+ #
27
+ # @return [String]
28
+ #
29
+ # @api private
30
+ #
11
31
  attr_reader :content
12
32
 
33
+ # Run command
34
+ #
35
+ # @param [State] state
36
+ #
37
+ # @return [self]
38
+ #
39
+ # @api private
40
+ #
13
41
  def run(state)
14
42
  state.push(self)
43
+ self
15
44
  end
16
45
 
17
46
  private
18
47
 
48
+ # Initialize object
49
+ #
50
+ # @param [String] content
51
+ #
52
+ # @return [undefined]
53
+ #
54
+ # @api private
55
+ #
19
56
  def initialize(content)
20
57
  @content = content
21
58
  end
59
+
22
60
  end
23
61
 
62
+ # Command that does a shift
24
63
  class Shift < self
25
64
  include Equalizer.new(:width)
26
65
 
66
+ # Return shift width
67
+ #
68
+ # @return [Fixnum]
69
+ #
70
+ # @api private
71
+ #
27
72
  attr_reader :width
28
73
 
74
+ # Run command
75
+ #
76
+ # @param [State] state
77
+ #
78
+ # @return [self]
79
+ #
80
+ # @api private
81
+ #
29
82
  def run(state)
30
83
  state.shift(width)
84
+ self
31
85
  end
32
86
 
33
87
  private
34
88
 
89
+ # Initialize command
90
+ #
91
+ # @param [Fixnum] width
92
+ #
93
+ # @return [undefined]
94
+ #
95
+ # @api private
96
+ #
35
97
  def initialize(width)
36
98
  @width = width
37
99
  end
38
100
 
39
101
  INDENT = Shift.new( 2)
40
102
  UNINDENT = Shift.new(-2)
41
-
42
103
  end
104
+
43
105
  end
44
106
  end
@@ -1,89 +1,278 @@
1
1
  module ToSource
2
+ # Abstract base class for emitter
2
3
  class Emitter
3
4
  include Adamantium::Flat, Equalizer.new(:node)
4
5
 
6
+ # The emitter registry
5
7
  REGISTRY = {}
6
8
 
7
- def self.handle(node_class)
8
- REGISTRY[node_class]=self
9
- end
10
-
9
+ # Build emitter for node
10
+ #
11
+ # @param [Rubinius::AST::Node] node
12
+ # @param [Array] buffer
13
+ #
14
+ # @return [Emitter]
15
+ #
16
+ # @api private
17
+ #
11
18
  def self.build(node, buffer = [])
12
19
  REGISTRY.fetch(node.class).new(node, buffer)
13
20
  end
14
21
 
22
+ # Run emitter for node
23
+ #
24
+ # @param [Rubinius::AST::Node] node
25
+ #
26
+ # @return [String]
27
+ #
28
+ # @api private
29
+ #
15
30
  def self.run(node)
16
31
  build(node).source
17
32
  end
18
33
 
34
+ # Declare predicates
35
+ #
36
+ # @return [undefined]
37
+ #
38
+ # @api private
39
+ #
40
+ def self.predicate(*names)
41
+ names.each do |name|
42
+ define_predicate(name)
43
+ end
44
+ end
19
45
 
20
- def source
21
- state = State.new
22
- buffer.each do |command|
23
- state.execute(command)
46
+ private_class_method :predicate
47
+
48
+ # Declare node delegators
49
+ #
50
+ # @return [undefined]
51
+ #
52
+ # @api private
53
+ #
54
+ def self.delegate(*names)
55
+ names.each do |name|
56
+ define_delegator(name)
24
57
  end
25
- state.source
26
58
  end
27
59
 
60
+ private_class_method :delegate
61
+
62
+ # Register emitter for node class
63
+ #
64
+ # @param [Class:Rubinius::AST::Node] node_class
65
+ #
66
+ # @return [undefined]
67
+ #
68
+ # @api private
69
+ #
70
+ def self.handle(node_class)
71
+ REGISTRY[node_class]=self
72
+ end
73
+
74
+ private_class_method :handle
75
+
76
+ # Define node delegator
77
+ #
78
+ # @param [Symbol] name
79
+ #
80
+ # @return [undefined]
81
+ #
82
+ # @api private
83
+ #
84
+ def self.define_delegator(name)
85
+ define_method(name) do
86
+ node.public_send(name)
87
+ end
88
+ private(name)
89
+ end
90
+
91
+ private_class_method :define_delegator
92
+
93
+ # Define predicate
94
+ #
95
+ # @param [Symbol] name
96
+ #
97
+ # @return [undefined]
98
+ #
99
+ # @api private
100
+ #
101
+ def self.define_predicate(name)
102
+ predicate = :"#{name}?"
103
+ define_method(predicate) do
104
+ !!send(name)
105
+ end
106
+ private(predicate)
107
+ end
108
+
109
+ private_class_method :define_delegator
110
+
111
+ # Return buffer
112
+ #
113
+ # @return [Array<Command>]
114
+ #
115
+ # @api private
116
+ #
117
+ attr_reader :buffer
118
+
119
+ # Return node
120
+ #
121
+ # @return [Rubinius::AST::Node]
122
+ #
123
+ # @api private
124
+ #
28
125
  attr_reader :node
29
126
 
127
+ # Initialize object
128
+ #
129
+ # @param [Rubinius::AST::Node] node
130
+ # @param [Array<Command>] buffer
131
+ #
132
+ # @return [undefined]
133
+ #
134
+ # @api private
135
+ #
136
+ def initialize(node, buffer)
137
+ @node, @buffer = node, buffer
138
+ dispatch
139
+ end
140
+
141
+ # Return source
142
+ #
143
+ # @return [String]
144
+ #
145
+ # @api private
146
+ #
147
+ def source
148
+ buffer.each_with_object(State.new) do |command, state|
149
+ state.execute(command)
150
+ end.source
151
+ end
152
+
30
153
  private
31
154
 
155
+ # Push command
156
+ #
157
+ # @param [Command] command
158
+ #
159
+ # @return [undefined]
160
+ #
161
+ # @api private
162
+ #
32
163
  def push(command)
33
164
  buffer.push(command)
34
165
  end
35
166
 
167
+ # Emit new line
168
+ #
169
+ # @return [undefined]
170
+ #
171
+ # @api private
172
+ #
36
173
  def new_line
37
174
  emit("\n")
38
175
  end
39
176
 
177
+ # Emit single whitespace
178
+ #
179
+ # @return [undefined]
180
+ #
181
+ # @api private
182
+ #
40
183
  def space
41
184
  emit(' ')
42
185
  end
43
186
 
187
+ # Emit end keyword
188
+ #
189
+ # @return [undefined]
190
+ #
191
+ # @api private
192
+ #
44
193
  def emit_end
45
194
  emit(:end)
46
195
  end
47
196
 
197
+ # Push indent command
198
+ #
199
+ # @return [undefined]
200
+ #
201
+ # @api private
202
+ #
48
203
  def indent
49
204
  push(Command::Shift::INDENT)
50
205
  end
51
206
 
207
+ # Push unindent command
208
+ #
209
+ # @return [undefined]
210
+ #
211
+ # @api private
212
+ #
52
213
  def unindent
53
214
  push(Command::Shift::UNINDENT)
54
215
  end
55
216
 
56
- def emit(name)
57
- push(Command::Token.new(name))
217
+ # Push token with content
218
+ #
219
+ # @param [String] content
220
+ #
221
+ # @return [undefined]
222
+ #
223
+ # @api private
224
+ #
225
+ def emit(content)
226
+ push(Command::Token.new(content))
58
227
  end
59
228
 
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)
229
+ # Run block indented
230
+ #
231
+ # @return [undefined]
232
+ #
233
+ # @api private
234
+ #
235
+ def indented
236
+ indent
237
+ yield
238
+ unindent
66
239
  end
67
240
 
68
- def self.delegate(*names)
69
- names.each do |name|
70
- define_delegator(name)
71
- end
241
+ # Run block in parantheses
242
+ #
243
+ # @return [undefined]
244
+ #
245
+ # @api private
246
+ #
247
+ def parantheses
248
+ emit('(')
249
+ yield
250
+ emit(')')
72
251
  end
73
252
 
74
- def self.define_delegator(name)
75
- define_method(name) do
76
- node.public_send(name)
77
- end
78
- private name
253
+ # Visit descendant node
254
+ #
255
+ # @param [Rubinius::AST::Node] node
256
+ #
257
+ # @return [undefined]
258
+ #
259
+ # @api private
260
+ #
261
+ def visit(node)
262
+ self.class.build(node, buffer)
79
263
  end
80
264
 
81
- attr_reader :buffer
82
-
83
- def initialize(node, buffer)
84
- @node, @buffer = node, buffer
85
- dispatch
265
+ # Run emitter on buffer
266
+ #
267
+ # @param [Class:Emitter] emitter
268
+ # @param [Rubinius::AST::Node] node
269
+ #
270
+ # @return [undefined]
271
+ #
272
+ # @api private
273
+ #
274
+ def run(emitter, node = self.node)
275
+ emitter.new(node, buffer)
86
276
  end
87
-
88
277
  end
89
278
  end