ruby_scribe 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +1 -2
- data/lib/ruby_scribe.rb +5 -1
- data/lib/ruby_scribe/emitter.rb +94 -13
- data/lib/ruby_scribe/emitter_helpers.rb +3 -1
- data/lib/ruby_scribe/transformer.rb +15 -0
- data/lib/ruby_scribe/transformers/eachifier.rb +21 -0
- data/lib/ruby_scribe/version.rb +1 -1
- data/spec/examples/identity.rb +28 -0
- data/spec/examples/spacing.rb +21 -0
- data/spec/matchers/should_transform_to.rb +21 -0
- data/spec/ruby_scribe/emitter_spec.rb +150 -40
- data/spec/ruby_scribe/transformer_spec.rb +27 -0
- data/spec/ruby_scribe/transformers/eachifier_spec.rb +27 -0
- metadata +9 -7
- data/TODO.rdoc +0 -2
- data/lib/ruby_scribe/transformation.rb +0 -9
- data/lib/tasks/scribe.rake +0 -29
- data/spec/ruby_scribe/transformation_spec.rb +0 -7
data/README.rdoc
CHANGED
@@ -93,8 +93,7 @@ This feature is not developed yet, but is intended on presenting a standard recu
|
|
93
93
|
== Known Issues
|
94
94
|
|
95
95
|
* Since there are still some holes in the implementation, any s-expression type that is unknown will cause the following to be emitted: "## RubyScribe-UNKNOWN: :type ##". Once stable any unknown type will instead throw an exception.
|
96
|
-
* Anything involving order of operations currently much surround the expression in ( ). Will probably expand later to omit this when order of operations is implied, but this requires a context stack.
|
97
|
-
* Elsif currently does not work as you'd expect and instead embeds another if block inside of the outer one's "else". This is how if statements are presented via ruby_parser.
|
96
|
+
* Anything involving order of operations currently much surround the expression in ( ). Will probably expand later to omit this when order of operations is implied, but this requires a context stack. There may actually be other issues related to order of operations. To do this properly requires maintaining context of operations and, starting with the case for parenthesis, remove parentheses when the emitter determines that the order of operations is implied by Ruby syntax rules. Right now the emitter more or less assumes order of operations is implied and does not use parantheses, except in the cases of || and && in which case it does.
|
98
97
|
* Some of the more obscure types are not implemented.
|
99
98
|
* Only comments on methods, class, and module declarations are retained. This is actually a limitation of ruby_parser as for whatever reason
|
100
99
|
in-line comments cannot be parsed correctly.
|
data/lib/ruby_scribe.rb
CHANGED
@@ -4,5 +4,9 @@ require "ruby_parser"
|
|
4
4
|
|
5
5
|
require "ruby_scribe/emitter_helpers"
|
6
6
|
require "ruby_scribe/emitter"
|
7
|
-
require "ruby_scribe/
|
7
|
+
require "ruby_scribe/transformer"
|
8
8
|
require "ruby_scribe/ext/sexp"
|
9
|
+
|
10
|
+
Dir[File.join(File.dirname(__FILE__), "ruby_scribe/transformers/**/*.rb")].each do |file|
|
11
|
+
require file
|
12
|
+
end
|
data/lib/ruby_scribe/emitter.rb
CHANGED
@@ -5,8 +5,23 @@ module RubyScribe
|
|
5
5
|
class Emitter
|
6
6
|
include EmitterHelpers
|
7
7
|
|
8
|
-
|
9
|
-
self.methods_without_parenthesis = %w(
|
8
|
+
class_inheritable_accessor :methods_without_parenthesis
|
9
|
+
self.methods_without_parenthesis = %w(
|
10
|
+
attr_accessor attr_reader attr_writer
|
11
|
+
alias alias_method alias_attribute
|
12
|
+
gem require extend include raise
|
13
|
+
delegate autoload raise
|
14
|
+
puts
|
15
|
+
)
|
16
|
+
|
17
|
+
class_inheritable_accessor :grouped_methods
|
18
|
+
self.grouped_methods = %w(require attr_accessor autoload)
|
19
|
+
|
20
|
+
class_inheritable_accessor :long_hash_key_size
|
21
|
+
self.long_hash_key_size = 5
|
22
|
+
|
23
|
+
class_inheritable_accessor :default_indent
|
24
|
+
self.default_indent = 2
|
10
25
|
|
11
26
|
SYNTACTIC_METHODS = ['+', '-', '<<', '==', '===', '>', '<']
|
12
27
|
|
@@ -20,6 +35,8 @@ module RubyScribe
|
|
20
35
|
emit_block(e)
|
21
36
|
when :scope
|
22
37
|
emit_scope(e)
|
38
|
+
when :ensure
|
39
|
+
emit_rescue_ensure_wrapper(e)
|
23
40
|
when :rescue
|
24
41
|
emit_rescue(e)
|
25
42
|
when :resbody
|
@@ -42,6 +59,8 @@ module RubyScribe
|
|
42
59
|
emit_argument_list(e)
|
43
60
|
when :attrasgn
|
44
61
|
emit_attribute_assignment(e)
|
62
|
+
when :cvasgn, :gasgn
|
63
|
+
emit_class_variable_assignment(e)
|
45
64
|
when :masgn
|
46
65
|
emit_multiple_assignment(e)
|
47
66
|
when :cdecl
|
@@ -58,6 +77,8 @@ module RubyScribe
|
|
58
77
|
emit_for_block(e)
|
59
78
|
when :lasgn, :iasgn
|
60
79
|
emit_assignment_expression(e)
|
80
|
+
when :op_asgn1, :op_asgn2
|
81
|
+
emit_optional_assignment_expression(e)
|
61
82
|
when :op_asgn_or
|
62
83
|
emit_optional_assignment_or_expression(e)
|
63
84
|
when :op_asgn_and
|
@@ -110,6 +131,14 @@ module RubyScribe
|
|
110
131
|
return nl
|
111
132
|
end
|
112
133
|
|
134
|
+
if previous_member.kind == :call && self.class.grouped_methods.include?(previous_member.body[1].to_s) && (current_member.kind != :call || (current_member.kind == :call && current_member.body[1] != previous_member.body[1]))
|
135
|
+
return nl
|
136
|
+
end
|
137
|
+
|
138
|
+
if current_member.kind == :call && self.class.grouped_methods.include?(current_member.body[1].to_s) && (previous_member.kind != :call || (previous_member.kind == :call && previous_member.body[1] != current_member.body[1]))
|
139
|
+
return nl
|
140
|
+
end
|
141
|
+
|
113
142
|
""
|
114
143
|
end
|
115
144
|
|
@@ -117,15 +146,32 @@ module RubyScribe
|
|
117
146
|
emit(e.body[0])
|
118
147
|
end
|
119
148
|
|
120
|
-
def
|
121
|
-
|
122
|
-
|
149
|
+
def emit_rescue_ensure_wrapper(e)
|
150
|
+
rescue_sexp = e.body[0]
|
151
|
+
block = rescue_sexp.body.size == 1 ? nil : rescue_sexp.body[0]
|
152
|
+
resbody = rescue_sexp.body.size == 1 ? rescue_sexp.body[0] : rescue_sexp.body[1]
|
153
|
+
ensure_sexp = e.body[1]
|
123
154
|
|
124
155
|
"begin" + indent { nl + emit(block) } +
|
125
156
|
emit(resbody) +
|
157
|
+
nl("ensure") +
|
158
|
+
indent { nl + emit(ensure_sexp) } +
|
126
159
|
nl("end")
|
127
160
|
end
|
128
161
|
|
162
|
+
def emit_rescue(e, force_long = false)
|
163
|
+
block = e.body.size == 1 ? nil : e.body[0]
|
164
|
+
resbody = e.body.size == 1 ? e.body[0] : e.body[1]
|
165
|
+
|
166
|
+
if !force_long && e.line == resbody.line && block.kind != :block && resbody && resbody.body[1] && resbody.body[1].kind != :block
|
167
|
+
"#{emit(block)} rescue #{emit(resbody.body[1])}"
|
168
|
+
else
|
169
|
+
"begin" + indent { nl + emit(block) } +
|
170
|
+
emit(resbody) +
|
171
|
+
nl("end")
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
129
175
|
def emit_rescue_body(e)
|
130
176
|
nl("rescue ".gsub(/ $/, '')) +
|
131
177
|
indent { nl + emit(e.body[1]) }
|
@@ -141,21 +187,21 @@ module RubyScribe
|
|
141
187
|
|
142
188
|
def emit_class_definition(e)
|
143
189
|
emit_comments(e.comments) +
|
144
|
-
"#{e.kind} #{e.body[0]}" +
|
190
|
+
"#{e.kind} #{emit(e.body[0])}" +
|
145
191
|
(e.body[1] ? " < #{emit(e.body[1])}" : "") +
|
146
192
|
indent { nl + emit(e.body[2]) } +
|
147
193
|
nl("end")
|
148
194
|
end
|
149
195
|
|
150
196
|
def emit_self_class_definition(e)
|
151
|
-
"class << #{e.body[0]}" +
|
197
|
+
"class << #{emit(e.body[0])}" +
|
152
198
|
indent { nl + emit(e.body[1]) } +
|
153
199
|
nl("end")
|
154
200
|
end
|
155
201
|
|
156
202
|
def emit_module_definition(e)
|
157
203
|
emit_comments(e.comments) +
|
158
|
-
"
|
204
|
+
"module #{emit(e.body[0])}" +
|
159
205
|
indent { nl + emit(e.body[1]) } +
|
160
206
|
nl("end")
|
161
207
|
end
|
@@ -250,6 +296,10 @@ module RubyScribe
|
|
250
296
|
emit(e.body[0]) + "." + e.body[1].to_s.gsub(/=$/, "") + " = " + emit(e.body[2])
|
251
297
|
end
|
252
298
|
|
299
|
+
def emit_class_variable_assignment(e)
|
300
|
+
emit(e.body[0]) + " = " + emit(e.body[1])
|
301
|
+
end
|
302
|
+
|
253
303
|
def emit_multiple_assignment(e)
|
254
304
|
left = e.body[0].body
|
255
305
|
right = e.body[1].body
|
@@ -285,7 +335,7 @@ module RubyScribe
|
|
285
335
|
"#{emit(e.body[2])} unless #{emit(e.body[0])}"
|
286
336
|
when :block_if
|
287
337
|
"if #{emit(e.body[0])}" + indent { nl + emit(e.body[1]) } +
|
288
|
-
(e.body[2]
|
338
|
+
emit_conditional_else_block(e.body[2]) +
|
289
339
|
nl("end")
|
290
340
|
when :block_unless
|
291
341
|
"unless #{emit(e.body[0])}" + indent { nl + emit(e.body[2]) } +
|
@@ -293,6 +343,17 @@ module RubyScribe
|
|
293
343
|
end
|
294
344
|
end
|
295
345
|
|
346
|
+
def emit_conditional_else_block(e)
|
347
|
+
return "" unless e
|
348
|
+
|
349
|
+
if e.kind == :if
|
350
|
+
nl("elsif #{emit(e.body[0])}") + indent { nl + emit(e.body[1]) } +
|
351
|
+
emit_conditional_else_block(e.body[2])
|
352
|
+
else
|
353
|
+
nl("else") + indent { nl + emit(e) }
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
296
357
|
def emit_case_statement(e)
|
297
358
|
"case #{emit(e.body[0])}".gsub(/ $/, '') + e.body[1..-2].map {|c| emit(c) }.join + emit_case_else_statement(e.body[-1]) + nl("end")
|
298
359
|
end
|
@@ -329,6 +390,10 @@ module RubyScribe
|
|
329
390
|
"#{e.body[0]} = #{emit(e.body[1])}"
|
330
391
|
end
|
331
392
|
|
393
|
+
def emit_optional_assignment_expression(e)
|
394
|
+
emit(e.body[0]) + "[#{emit(e.body[1])}] #{emit(e.body[2])}= " + emit(e.body[3])
|
395
|
+
end
|
396
|
+
|
332
397
|
def emit_optional_assignment_or_expression(e)
|
333
398
|
emit(e.body[0]) + " ||= " + emit(e.body[1].body[1])
|
334
399
|
end
|
@@ -360,7 +425,7 @@ module RubyScribe
|
|
360
425
|
|
361
426
|
def emit_block_invocation_arguments(e)
|
362
427
|
if e.body[1]
|
363
|
-
"|" + emit_assignments_as_arguments(e.body[1]) + "|
|
428
|
+
"|" + emit_assignments_as_arguments(e.body[1]) + "|"
|
364
429
|
else
|
365
430
|
""
|
366
431
|
end
|
@@ -392,6 +457,8 @@ module RubyScribe
|
|
392
457
|
e.body[0].to_s
|
393
458
|
when :ivar
|
394
459
|
e.body[0].to_s
|
460
|
+
when :cvar
|
461
|
+
e.body[0].to_s
|
395
462
|
when :not
|
396
463
|
"!" + emit(e.body[0])
|
397
464
|
when :true
|
@@ -421,15 +488,23 @@ module RubyScribe
|
|
421
488
|
when :splat
|
422
489
|
"*" + emit(e.body[0])
|
423
490
|
when :colon2
|
424
|
-
"#{emit(e.body[0])}::#{e.body[1]
|
491
|
+
"#{emit(e.body[0])}::#{emit(e.body[1])}"
|
492
|
+
when :colon3
|
493
|
+
"::#{emit(e.body[0])}"
|
494
|
+
when :dot2
|
495
|
+
"#{emit(e.body[0])}..#{emit(e.body[1])}"
|
425
496
|
when :hash
|
426
497
|
"{" + emit_hash_body(e) + "}"
|
427
498
|
when :array
|
428
499
|
"[" + e.body.map {|c| emit(c)}.join(", ") + "]"
|
500
|
+
when :nth_ref, :back_ref
|
501
|
+
"$" + e.body[0].to_s
|
429
502
|
when :gvar
|
430
503
|
e.body[0].to_s
|
431
504
|
when :dstr
|
432
505
|
'"' + literalize_strings(e.body).map {|c| emit(c) }.join + '"'
|
506
|
+
when :dregx
|
507
|
+
'/' + literalize_strings(e.body).map {|c| emit(c) }.join + '/'
|
433
508
|
when :evstr
|
434
509
|
'#{' + emit(e.body[0]) + '}'
|
435
510
|
when :xstr
|
@@ -447,8 +522,14 @@ module RubyScribe
|
|
447
522
|
end
|
448
523
|
end
|
449
524
|
|
450
|
-
def emit_hash_body(e)
|
451
|
-
e.body.in_groups_of(2)
|
525
|
+
def emit_hash_body(e, force_short = false)
|
526
|
+
grouped = e.body.in_groups_of(2)
|
527
|
+
|
528
|
+
if !force_short && grouped.size >= self.class.long_hash_key_size
|
529
|
+
indent(2) { nl + grouped.map {|g| "#{emit(g[0])} => #{emit(g[1])}" }.join("," + nl) } + nl
|
530
|
+
else
|
531
|
+
grouped.map {|g| "#{emit(g[0])} => #{emit(g[1])}" }.join(", ")
|
532
|
+
end
|
452
533
|
end
|
453
534
|
|
454
535
|
def emit_unknown_expression(e)
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module RubyScribe
|
2
|
+
# Takes a raw S-expression and transforms it (replaces the node with the return value of the process method).
|
3
|
+
# This is meant to be subclassed, and in the process method you should either return a transformed version of the node,
|
4
|
+
# or just call super which will leave the node in place and iterate through the children.
|
5
|
+
#
|
6
|
+
class Transformer
|
7
|
+
def transform(sexp)
|
8
|
+
if sexp.is_a?(Sexp)
|
9
|
+
Sexp.new(*([sexp.kind] + sexp.body.map {|c| transform(c) }))
|
10
|
+
else
|
11
|
+
sexp
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RubyScribe
|
2
|
+
module Transformers
|
3
|
+
class Eachifier < Transformer
|
4
|
+
def transform(e)
|
5
|
+
if e.is_a?(Sexp) && e.kind == :for
|
6
|
+
transform_for_to_each(e)
|
7
|
+
else
|
8
|
+
super
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def transform_for_to_each(e)
|
13
|
+
s(:iter,
|
14
|
+
s(:call, e.body[0], :each, s(:arglist)),
|
15
|
+
e.body[1],
|
16
|
+
e.body[2]
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/ruby_scribe/version.rb
CHANGED
data/spec/examples/identity.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require "some_file"
|
2
|
+
|
2
3
|
$:.unshift("directory")
|
3
4
|
|
4
5
|
module RubyScribe
|
@@ -10,8 +11,35 @@ module RubyScribe
|
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
14
|
+
class Test
|
15
|
+
@@class_variable = 1
|
16
|
+
end
|
17
|
+
|
13
18
|
class MyClass < Subclass
|
14
19
|
attr_accessor :no_parathesis
|
20
|
+
|
15
21
|
call_method("Apartness")
|
22
|
+
|
23
|
+
single_line_block {|a| a.do_something }
|
24
|
+
end
|
25
|
+
|
26
|
+
if a == 1
|
27
|
+
1
|
28
|
+
elsif a > 3
|
29
|
+
2
|
30
|
+
else
|
31
|
+
3
|
32
|
+
end
|
33
|
+
|
34
|
+
if a == 1
|
35
|
+
1
|
36
|
+
else
|
37
|
+
if a > 3
|
38
|
+
2
|
39
|
+
else
|
40
|
+
3
|
41
|
+
end
|
42
|
+
|
43
|
+
do_something_now
|
16
44
|
end
|
17
45
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
RSpec::Matchers.define :transform_to do |desc, expected|
|
2
|
+
match do |actual|
|
3
|
+
actual_as_sexp = actual.is_a?(String) ? RubyParser.new.parse(actual) : actual
|
4
|
+
expected_as_sexp = expected.is_a?(String) ? RubyParser.new.parse(expected) : expected
|
5
|
+
|
6
|
+
@transformed = described_class.new.transform(actual_as_sexp)
|
7
|
+
@transformed == expected_as_sexp
|
8
|
+
end
|
9
|
+
|
10
|
+
failure_message_for_should do |actual|
|
11
|
+
"expected that:\n\n#{actual}\n\nwould transform to:\n\n#{expected}\n\nbut instead was:\n\n#{@transformed}"
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should_not do |actual|
|
15
|
+
"expected that:\n\n#{actual}\n\nwould not transform to:\n\n#{expected}\n\nbut instead was:\n\n#{@transformed}"
|
16
|
+
end
|
17
|
+
|
18
|
+
description do
|
19
|
+
"transform with to #{desc}"
|
20
|
+
end
|
21
|
+
end
|
@@ -15,15 +15,11 @@ describe RubyScribe::Emitter do
|
|
15
15
|
end
|
16
16
|
|
17
17
|
specify "namespaced class should emit itself" do
|
18
|
-
|
19
|
-
%{class Scribe::Animal\n \nend}.should emit_itself
|
20
|
-
end
|
18
|
+
%{class Scribe::Animal\n \nend}.should emit_itself
|
21
19
|
end
|
22
20
|
|
23
21
|
specify "eigenclass should emit itself" do
|
24
|
-
|
25
|
-
%{class << self\n \nend}.should emit_itself
|
26
|
-
end
|
22
|
+
%{class << self\n \nend}.should emit_itself
|
27
23
|
end
|
28
24
|
end
|
29
25
|
|
@@ -33,9 +29,7 @@ describe RubyScribe::Emitter do
|
|
33
29
|
end
|
34
30
|
|
35
31
|
specify "namespaced class should emit itself" do
|
36
|
-
|
37
|
-
%{module Scribe::Animal\n \nend}.should emit_itself
|
38
|
-
end
|
32
|
+
%{module Scribe::Animal\n \nend}.should emit_itself
|
39
33
|
end
|
40
34
|
end
|
41
35
|
|
@@ -44,144 +38,260 @@ describe RubyScribe::Emitter do
|
|
44
38
|
%{begin\n \nrescue\n \nend}.should emit_itself
|
45
39
|
end
|
46
40
|
|
41
|
+
specify "rescue all with ensure should emit itself" do
|
42
|
+
%{begin\n \nrescue\n \nensure\n nil\nend}.should emit_itself
|
43
|
+
end
|
44
|
+
|
47
45
|
specify "method-wide rescue should emit itself" do
|
48
46
|
%{def method\n \nrescue\n \nend}.should emit_itself
|
49
47
|
end
|
48
|
+
|
49
|
+
specify "dangling rescue should emit itself" do
|
50
|
+
%{do_something rescue nil}.should emit_itself
|
51
|
+
end
|
52
|
+
|
53
|
+
specify "rescuing with exception class should emit itself" do
|
54
|
+
pending do
|
55
|
+
%{begin\n \nrescue StandardError\n \nend}.should emit_itself
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
specify "rescuing with multiple exception classes should emit itself" do
|
60
|
+
pending do
|
61
|
+
%{begin\n \nrescue StandardError\n \nend}.should emit_itself
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
specify "rescuing with exception class and target variable should emit itself" do
|
66
|
+
pending do
|
67
|
+
%{begin\n \nrescue StandardError => e\n \nend}.should emit_itself
|
68
|
+
end
|
69
|
+
end
|
50
70
|
end
|
51
71
|
|
52
72
|
context "method definition" do
|
53
|
-
specify "without arguments" do
|
73
|
+
specify "without arguments should emit itself" do
|
54
74
|
%{def method\n \nend}.should emit_itself
|
55
75
|
end
|
56
76
|
|
57
|
-
specify "with one argument" do
|
77
|
+
specify "with one argument should emit itself" do
|
58
78
|
%{def method(one)\n \nend}.should emit_itself
|
59
79
|
end
|
60
80
|
|
61
|
-
specify "with multiple arguments" do
|
81
|
+
specify "with multiple arguments should emit itself" do
|
62
82
|
%{def method(one, two)\n \nend}.should emit_itself
|
63
83
|
end
|
64
84
|
|
65
|
-
specify "with optional arguments" do
|
85
|
+
specify "with optional arguments should emit itself" do
|
66
86
|
%{def method(one = 1, two = {})\n \nend}.should emit_itself
|
67
87
|
end
|
68
88
|
|
69
|
-
specify "with block argument" do
|
89
|
+
specify "with block argument should emit itself" do
|
70
90
|
%{def method(one, &two)\n \nend}.should emit_itself
|
71
91
|
end
|
72
92
|
end
|
73
93
|
|
74
94
|
context "method call" do
|
75
|
-
specify "without arguments" do
|
95
|
+
specify "without arguments should emit itself" do
|
76
96
|
%{method}.should emit_itself
|
77
97
|
end
|
78
98
|
|
79
|
-
specify "with one argument" do
|
99
|
+
specify "with one argument should emit itself" do
|
80
100
|
%{method("One")}.should emit_itself
|
81
101
|
end
|
82
102
|
|
83
|
-
specify "with multiple arguments" do
|
103
|
+
specify "with multiple arguments should emit itself" do
|
84
104
|
%{method("One", 2)}.should emit_itself
|
85
105
|
end
|
86
106
|
|
87
|
-
specify "with last argument as a hash" do
|
107
|
+
specify "with last argument as a hash should emit itself" do
|
88
108
|
%{method("One", :option => :one)}.should emit_itself
|
89
109
|
end
|
90
110
|
|
91
|
-
specify "with block" do
|
111
|
+
specify "with block should emit itself" do
|
92
112
|
%{method do\n \nend}.should emit_itself
|
93
113
|
end
|
94
114
|
end
|
95
115
|
|
96
116
|
context "case statement" do
|
97
|
-
specify "with argument" do
|
117
|
+
specify "with argument should emit itself" do
|
98
118
|
%{case something\nwhen 1\n \nend}.should emit_itself
|
99
119
|
end
|
100
120
|
|
101
|
-
specify "without argument" do
|
121
|
+
specify "without argument should emit itself" do
|
102
122
|
%{case\nwhen 1 == 1\n \nend}
|
103
123
|
end
|
104
124
|
|
105
|
-
specify "with else block" do
|
125
|
+
specify "with else block should emit itself" do
|
106
126
|
%{case something\nwhen 1\n \nelse\n 2\nend}.should emit_itself
|
107
127
|
end
|
108
128
|
end
|
109
129
|
|
110
|
-
context "
|
111
|
-
specify "to
|
130
|
+
context "assignment" do
|
131
|
+
specify "to global variable should emit itself" do
|
132
|
+
%{$variable = 1}.should emit_itself
|
133
|
+
end
|
134
|
+
|
135
|
+
specify "to simple local variable should emit itself" do
|
112
136
|
%{variable = 1}.should emit_itself
|
113
137
|
end
|
114
138
|
|
115
|
-
specify "to instance variable" do
|
139
|
+
specify "to instance variable should emit itself" do
|
116
140
|
%{@variable = 1}.should emit_itself
|
117
141
|
end
|
118
142
|
|
119
|
-
specify "to
|
143
|
+
specify "to class variable should emit itself" do
|
144
|
+
%{@@variable = 1}.should emit_itself
|
145
|
+
end
|
146
|
+
|
147
|
+
specify "to class variable inside a method should emit itself" do
|
148
|
+
%{def hi\n @@variable = 1\nend}.should emit_itself
|
149
|
+
end
|
150
|
+
|
151
|
+
specify "to multiple variables should emit itself" do
|
120
152
|
%{variable_1, variable_2 = 1, 2}.should emit_itself
|
121
153
|
end
|
122
154
|
|
123
|
-
specify "with or" do
|
155
|
+
specify "with or should emit itself" do
|
124
156
|
%{@variable ||= 1}.should emit_itself
|
125
157
|
end
|
126
158
|
|
127
|
-
specify "with and" do
|
159
|
+
specify "with and should emit itself" do
|
128
160
|
%{@variable &&= 1}.should emit_itself
|
129
161
|
end
|
162
|
+
|
163
|
+
specify "with hash should emit itself" do
|
164
|
+
%{@variable["something"] ||= 1}.should emit_itself
|
165
|
+
end
|
130
166
|
end
|
131
167
|
|
132
168
|
context "conditionals" do
|
133
|
-
specify "simple block if" do
|
169
|
+
specify "simple block if should emit itself" do
|
134
170
|
%{if true\n something\nend}.should emit_itself
|
135
171
|
end
|
136
172
|
|
137
|
-
specify "simple block unless" do
|
173
|
+
specify "simple block unless should emit itself" do
|
138
174
|
%{unless true\n something\nend}.should emit_itself
|
139
175
|
end
|
140
176
|
|
141
|
-
specify "simple block if else" do
|
177
|
+
specify "simple block if else should emit itself" do
|
142
178
|
%{if true\n something\nelse\n something_else\nend}.should emit_itself
|
143
179
|
end
|
144
180
|
|
145
|
-
specify "dangling if" do
|
181
|
+
specify "dangling if should emit itself" do
|
146
182
|
%{something if true}.should emit_itself
|
147
183
|
end
|
148
184
|
|
149
|
-
specify "dangling unless" do
|
185
|
+
specify "dangling unless should emit itself" do
|
150
186
|
%{something unless true}.should emit_itself
|
151
187
|
end
|
152
188
|
|
153
|
-
specify "ternary if" do
|
189
|
+
specify "ternary if should emit itself" do
|
154
190
|
%{something ? true : false}.should emit_itself
|
155
191
|
end
|
156
192
|
end
|
157
193
|
|
158
194
|
context "looping expression definition" do
|
159
|
-
specify "while" do
|
195
|
+
specify "while should emit itself" do
|
160
196
|
%{while true\n \nend}.should emit_itself
|
161
197
|
end
|
162
198
|
|
163
|
-
specify "until" do
|
199
|
+
specify "until should emit itself" do
|
164
200
|
%{until true\n \nend}.should emit_itself
|
165
201
|
end
|
166
202
|
|
167
|
-
specify "for in array" do
|
203
|
+
specify "for in array should emit itself" do
|
168
204
|
%{for something in array\n \nend}.should emit_itself
|
169
205
|
end
|
170
206
|
end
|
171
207
|
|
172
208
|
context "binary expressions" do
|
173
|
-
specify "||" do
|
209
|
+
specify "|| should emit itself" do
|
174
210
|
%{(one || two)}.should emit_itself
|
175
211
|
end
|
176
212
|
|
177
|
-
specify "&&" do
|
213
|
+
specify "&& should emit itself" do
|
178
214
|
%{(one && two)}.should emit_itself
|
179
215
|
end
|
180
216
|
end
|
181
217
|
|
182
218
|
context "unary expressions" do
|
183
|
-
specify "!something" do
|
219
|
+
specify "!something should emit itself" do
|
184
220
|
%{!something}.should emit_itself
|
185
221
|
end
|
186
222
|
end
|
223
|
+
|
224
|
+
context "return statement" do
|
225
|
+
specify "with no argument should emit itself" do
|
226
|
+
%{return}.should emit_itself
|
227
|
+
end
|
228
|
+
|
229
|
+
specify "with single argument should emit itself" do
|
230
|
+
%{return 1}.should emit_itself
|
231
|
+
end
|
232
|
+
|
233
|
+
specify "with multiple arguments should emit itself" do
|
234
|
+
%{return [1, 2]}.should emit_itself
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context "literals" do
|
239
|
+
specify "short string should emit itself" do
|
240
|
+
%{"my string"}.should emit_itself
|
241
|
+
end
|
242
|
+
|
243
|
+
specify "short string with interpolation should emit itself" do
|
244
|
+
'"my #{test} string"'.should emit_itself
|
245
|
+
end
|
246
|
+
|
247
|
+
specify "heredoc string should emit itself" do
|
248
|
+
pending do
|
249
|
+
%{<<EOF\n my strong\n line 2\n line 3\n line 4\nEOF}.should emit_itself
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
specify "short hash should emit itself" do
|
254
|
+
%{{:hash => :one, :another => :two}}.should emit_itself
|
255
|
+
end
|
256
|
+
|
257
|
+
specify "long hash should emit itself" do
|
258
|
+
%{{\n :key1 => :value1,\n :key2 => :value2,\n :key3 => :value3,\n :key4 => :value4,\n :key5 => :value5,\n :key6 => :value6\n}}.should emit_itself
|
259
|
+
end
|
260
|
+
|
261
|
+
specify "range with two dots should emit itself" do
|
262
|
+
%{1..10}.should emit_itself
|
263
|
+
end
|
264
|
+
|
265
|
+
specify "range with three dots should emit itself" do
|
266
|
+
%{1...10}.should emit_itself
|
267
|
+
end
|
268
|
+
|
269
|
+
specify "regular expression should emit itself" do
|
270
|
+
%{/[a-zA-Z]$/}.should emit_itself
|
271
|
+
end
|
272
|
+
|
273
|
+
specify "regular expression with interpolation should emit itself" do
|
274
|
+
'/[a-Z#{something}]/'.should emit_itself
|
275
|
+
end
|
276
|
+
|
277
|
+
specify "__FILE__ should emit itself" do
|
278
|
+
pending("requires a patch to ruby_parser which cannot parse this") do
|
279
|
+
%{__FILE__}.should emit_itself
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
specify "__LINE__ should emit itself" do
|
284
|
+
pending("requires a patch to ruby_parser which cannot parse this") do
|
285
|
+
%{__LINE__}.should emit_itself
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
specify "numeric reference should emit itself" do
|
290
|
+
%{$1}.should emit_itself
|
291
|
+
end
|
292
|
+
|
293
|
+
specify "backreference should emit itself" do
|
294
|
+
%{$&}.should emit_itself
|
295
|
+
end
|
296
|
+
end
|
187
297
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe RubyScribe::Transformer do
|
4
|
+
|
5
|
+
describe "a for block" do
|
6
|
+
subject { %{
|
7
|
+
def my_method
|
8
|
+
call_something
|
9
|
+
|
10
|
+
for element in array
|
11
|
+
do_something(element)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
}}
|
15
|
+
|
16
|
+
it { should transform_to("the same", %{
|
17
|
+
def my_method
|
18
|
+
call_something
|
19
|
+
|
20
|
+
for element in array
|
21
|
+
do_something(element)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
}) }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe RubyScribe::Transformers::Eachifier do
|
4
|
+
|
5
|
+
describe "a for block" do
|
6
|
+
subject { %{
|
7
|
+
def my_method
|
8
|
+
call_something
|
9
|
+
|
10
|
+
for element in array
|
11
|
+
do_something(element)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
}}
|
15
|
+
|
16
|
+
it { should transform_to("each", %{
|
17
|
+
def my_method
|
18
|
+
call_something
|
19
|
+
|
20
|
+
array.each do |element|
|
21
|
+
do_something(element)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
}) }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_scribe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ben Hughes
|
@@ -77,21 +77,23 @@ files:
|
|
77
77
|
- lib/ruby_scribe/emitter_helpers.rb
|
78
78
|
- lib/ruby_scribe/ext/sexp.rb
|
79
79
|
- lib/ruby_scribe/runner.rb
|
80
|
-
- lib/ruby_scribe/
|
80
|
+
- lib/ruby_scribe/transformer.rb
|
81
|
+
- lib/ruby_scribe/transformers/eachifier.rb
|
81
82
|
- lib/ruby_scribe/version.rb
|
82
83
|
- lib/ruby_scribe.rb
|
83
|
-
- lib/tasks/scribe.rake
|
84
84
|
- spec/examples/identity.rb
|
85
|
+
- spec/examples/spacing.rb
|
85
86
|
- spec/matchers/should_emit_as.rb
|
86
87
|
- spec/matchers/should_emit_itself.rb
|
88
|
+
- spec/matchers/should_transform_to.rb
|
87
89
|
- spec/ruby_scribe/emitter_examples_spec.rb
|
88
90
|
- spec/ruby_scribe/emitter_spec.rb
|
89
|
-
- spec/ruby_scribe/
|
91
|
+
- spec/ruby_scribe/transformer_spec.rb
|
92
|
+
- spec/ruby_scribe/transformers/eachifier_spec.rb
|
90
93
|
- spec/spec_helper.rb
|
91
94
|
- LICENSE
|
92
95
|
- Rakefile
|
93
96
|
- README.rdoc
|
94
|
-
- TODO.rdoc
|
95
97
|
- bin/rubyscribe
|
96
98
|
has_rdoc: true
|
97
99
|
homepage: http://github.com/rubiety/ruby_scribe
|
data/TODO.rdoc
DELETED
data/lib/tasks/scribe.rake
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
namespace :scribe do
|
2
|
-
desc "Run Scribe Examples"
|
3
|
-
task :examples do
|
4
|
-
$:.unshift(File.join(File.dirname(__FILE__), ".."))
|
5
|
-
require "ruby_parser"
|
6
|
-
require "ruby_scribe"
|
7
|
-
require "pp"
|
8
|
-
|
9
|
-
original_file = File.read(File.join(File.dirname(__FILE__), "../../spec/examples/simple_class_with_methods.rb"))
|
10
|
-
sexp = RubyParser.new.parse(original_file)
|
11
|
-
|
12
|
-
puts "Parsed S-Expresssion"
|
13
|
-
puts "======================================"
|
14
|
-
pp sexp
|
15
|
-
puts
|
16
|
-
|
17
|
-
puts "Original File"
|
18
|
-
puts "======================================"
|
19
|
-
puts original_file
|
20
|
-
|
21
|
-
puts
|
22
|
-
puts
|
23
|
-
|
24
|
-
puts "Parsed File"
|
25
|
-
puts "======================================"
|
26
|
-
parsed_file = RubyScribe::Emitter.new.emit(sexp)
|
27
|
-
puts parsed_file
|
28
|
-
end
|
29
|
-
end
|