ripper_ruby_parser 0.0.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/{README.rdoc → README.md} +17 -17
- data/Rakefile +3 -1
- data/lib/ripper_ruby_parser/{commenting_sexp_builder.rb → commenting_ripper_parser.rb} +22 -6
- data/lib/ripper_ruby_parser/parser.rb +3 -18
- data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +2 -1
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +6 -10
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +37 -60
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +31 -25
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +18 -8
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +22 -18
- data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +12 -23
- data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +16 -8
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +41 -15
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +40 -23
- data/lib/ripper_ruby_parser/sexp_processor.rb +38 -19
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/test/pt_testcase/pt_test.rb +15 -1
- data/test/test_helper.rb +6 -3
- data/test/unit/commenting_ripper_parser_test.rb +121 -0
- data/test/unit/parser_assignment_test.rb +23 -24
- data/test/unit/parser_blocks_test.rb +207 -35
- data/test/unit/parser_conditionals_test.rb +251 -9
- data/test/unit/parser_literals_test.rb +348 -8
- data/test/unit/parser_loops_test.rb +20 -21
- data/test/unit/parser_method_calls_test.rb +132 -8
- data/test/unit/parser_operators_test.rb +97 -7
- data/test/unit/parser_test.rb +631 -1231
- data/test/unit/sexp_processor_test.rb +26 -28
- metadata +28 -38
- data/test/unit/commenting_sexp_builder_test.rb +0 -113
@@ -49,14 +49,14 @@ module RipperRubyParser
|
|
49
49
|
_, content = exp.shift 2
|
50
50
|
|
51
51
|
statements = content.map { |sub_exp| process(sub_exp) }
|
52
|
-
|
52
|
+
safe_wrap_in_block statements
|
53
53
|
end
|
54
54
|
|
55
55
|
def process_module exp
|
56
56
|
_, const_ref, body = exp.shift 3
|
57
57
|
const, line = const_ref_to_const_with_line_number const_ref
|
58
58
|
with_line_number(line,
|
59
|
-
s(:module, const, class_or_module_body(body)))
|
59
|
+
s(:module, const, *class_or_module_body(body)))
|
60
60
|
end
|
61
61
|
|
62
62
|
def process_class exp
|
@@ -64,12 +64,12 @@ module RipperRubyParser
|
|
64
64
|
const, line = const_ref_to_const_with_line_number const_ref
|
65
65
|
parent = process(parent)
|
66
66
|
with_line_number(line,
|
67
|
-
s(:class, const, parent, class_or_module_body(body)))
|
67
|
+
s(:class, const, parent, *class_or_module_body(body)))
|
68
68
|
end
|
69
69
|
|
70
70
|
def process_sclass exp
|
71
71
|
_, klass, block = exp.shift 3
|
72
|
-
s(:sclass, process(klass), class_or_module_body(block))
|
72
|
+
s(:sclass, process(klass), *class_or_module_body(block))
|
73
73
|
end
|
74
74
|
|
75
75
|
def process_var_ref exp
|
@@ -82,6 +82,11 @@ module RipperRubyParser
|
|
82
82
|
process(contents)
|
83
83
|
end
|
84
84
|
|
85
|
+
def process_var_alias exp
|
86
|
+
_, left, right = exp.shift 3
|
87
|
+
s(:valias, left[1].to_sym, right[1].to_sym)
|
88
|
+
end
|
89
|
+
|
85
90
|
def process_const_path_ref exp
|
86
91
|
_, left, right = exp.shift 3
|
87
92
|
s(:colon2, process(left), extract_node_symbol(right))
|
@@ -112,7 +117,8 @@ module RipperRubyParser
|
|
112
117
|
elsif body.first.is_a? Symbol
|
113
118
|
process body
|
114
119
|
else
|
115
|
-
process
|
120
|
+
body.map! {|it| convert_void_stmt_to_nil process it }
|
121
|
+
safe_wrap_in_block body
|
116
122
|
end
|
117
123
|
end
|
118
124
|
|
@@ -123,6 +129,16 @@ module RipperRubyParser
|
|
123
129
|
sexp
|
124
130
|
end
|
125
131
|
|
132
|
+
def process_BEGIN exp
|
133
|
+
_, body = exp.shift 2
|
134
|
+
s(:iter, s(:preexe), s(:args), *map_body(body))
|
135
|
+
end
|
136
|
+
|
137
|
+
def process_END exp
|
138
|
+
_, body = exp.shift 2
|
139
|
+
s(:iter, s(:postexe), s(:args), *map_body(body))
|
140
|
+
end
|
141
|
+
|
126
142
|
# number literals
|
127
143
|
def process_at_int exp
|
128
144
|
make_literal(exp) {|val| Integer(val) }
|
@@ -134,13 +150,8 @@ module RipperRubyParser
|
|
134
150
|
|
135
151
|
# character literals
|
136
152
|
def process_at_CHAR exp
|
137
|
-
|
138
|
-
|
139
|
-
val[1].ord
|
140
|
-
else
|
141
|
-
val[1]
|
142
|
-
end
|
143
|
-
end
|
153
|
+
_, val, pos = exp.shift 3
|
154
|
+
with_position(pos, s(:str, unescape(val[1..-1])))
|
144
155
|
end
|
145
156
|
|
146
157
|
def process_at_label exp
|
@@ -209,14 +220,14 @@ module RipperRubyParser
|
|
209
220
|
end
|
210
221
|
|
211
222
|
def class_or_module_body exp
|
212
|
-
|
213
|
-
|
214
|
-
block
|
215
|
-
|
216
|
-
|
217
|
-
else
|
218
|
-
s(:scope, s(:block, *block))
|
223
|
+
body = process(exp)
|
224
|
+
|
225
|
+
if body.length == 1 && body.first.sexp_type == :block
|
226
|
+
body = body.first
|
227
|
+
body.shift
|
219
228
|
end
|
229
|
+
|
230
|
+
body
|
220
231
|
end
|
221
232
|
|
222
233
|
def make_identifier(type, exp)
|
@@ -246,5 +257,13 @@ module RipperRubyParser
|
|
246
257
|
end
|
247
258
|
end
|
248
259
|
end
|
260
|
+
|
261
|
+
def convert_void_stmt_to_nil sexp
|
262
|
+
if sexp == s(:void_stmt)
|
263
|
+
s(:nil)
|
264
|
+
else
|
265
|
+
sexp
|
266
|
+
end
|
267
|
+
end
|
249
268
|
end
|
250
269
|
end
|
data/test/pt_testcase/pt_test.rb
CHANGED
@@ -7,13 +7,27 @@ class RipperRubyParser::Parser
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
+
SKIPPED_TESTS = ["dstr_heredoc_windoze_sucks"]
|
11
|
+
|
10
12
|
class RubyParserTestCase < ParseTreeTestCase
|
11
13
|
def self.previous key
|
12
14
|
"Ruby"
|
13
15
|
end
|
14
16
|
|
15
17
|
def self.generate_test klass, node, data, input_name, output_name
|
16
|
-
|
18
|
+
if data['Ruby'].is_a? Array
|
19
|
+
klass.send :define_method, "test_#{node}" do
|
20
|
+
skip "Not a parser test"
|
21
|
+
end
|
22
|
+
return
|
23
|
+
end
|
24
|
+
|
25
|
+
if SKIPPED_TESTS.include? node
|
26
|
+
klass.send :define_method, "test_#{node}" do
|
27
|
+
skip "Can't or won't fix this difference"
|
28
|
+
end
|
29
|
+
return
|
30
|
+
end
|
17
31
|
|
18
32
|
output_name = "ParseTree"
|
19
33
|
|
data/test/test_helper.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
-
|
1
|
+
begin
|
2
2
|
require 'simplecov'
|
3
|
-
SimpleCov.start
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter "/test/"
|
5
|
+
end
|
6
|
+
rescue LoadError
|
4
7
|
end
|
5
|
-
|
8
|
+
|
6
9
|
require 'minitest/autorun'
|
7
10
|
|
8
11
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe RipperRubyParser::CommentingRipperParser do
|
4
|
+
def parse_with_builder str
|
5
|
+
builder = RipperRubyParser::CommentingRipperParser.new str
|
6
|
+
builder.parse
|
7
|
+
end
|
8
|
+
|
9
|
+
def empty_params_list
|
10
|
+
@empty_params_list ||= begin
|
11
|
+
num_params = RUBY_VERSION < "2.0.0" ? 5 : 7
|
12
|
+
s(:params, *([nil] * num_params))
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "handling comments" do
|
18
|
+
it "produces a comment node surrounding a commented def" do
|
19
|
+
result = parse_with_builder "# Foo\ndef foo; end"
|
20
|
+
result.must_equal s(:program,
|
21
|
+
s(s(:comment,
|
22
|
+
"# Foo\n",
|
23
|
+
s(:def,
|
24
|
+
s(:@ident, "foo", s(2, 4)),
|
25
|
+
empty_params_list,
|
26
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
27
|
+
end
|
28
|
+
|
29
|
+
it "produces a blank comment node surrounding a def that has no comment" do
|
30
|
+
result = parse_with_builder "def foo; end"
|
31
|
+
result.must_equal s(:program,
|
32
|
+
s(s(:comment,
|
33
|
+
"",
|
34
|
+
s(:def,
|
35
|
+
s(:@ident, "foo", s(1, 4)),
|
36
|
+
empty_params_list,
|
37
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
38
|
+
end
|
39
|
+
|
40
|
+
it "produces a comment node surrounding a commented class" do
|
41
|
+
result = parse_with_builder "# Foo\nclass Foo; end"
|
42
|
+
result.must_equal s(:program,
|
43
|
+
s(s(:comment,
|
44
|
+
"# Foo\n",
|
45
|
+
s(:class,
|
46
|
+
s(:const_ref, s(:@const, "Foo", s(2, 6))),
|
47
|
+
nil,
|
48
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
49
|
+
end
|
50
|
+
|
51
|
+
it "produce a blank comment node surrounding a class that has no comment" do
|
52
|
+
result = parse_with_builder "class Foo; end"
|
53
|
+
result.must_equal s(:program,
|
54
|
+
s(s(:comment,
|
55
|
+
"",
|
56
|
+
s(:class,
|
57
|
+
s(:const_ref, s(:@const, "Foo", s(1, 6))),
|
58
|
+
nil,
|
59
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "produces a comment node surrounding a commented module" do
|
63
|
+
result = parse_with_builder "# Foo\nmodule Foo; end"
|
64
|
+
result.must_equal s(:program,
|
65
|
+
s(s(:comment,
|
66
|
+
"# Foo\n",
|
67
|
+
s(:module,
|
68
|
+
s(:const_ref, s(:@const, "Foo", s(2, 7))),
|
69
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
70
|
+
end
|
71
|
+
|
72
|
+
it "produces a blank comment node surrounding a module that has no comment" do
|
73
|
+
result = parse_with_builder "module Foo; end"
|
74
|
+
result.must_equal s(:program,
|
75
|
+
s(s(:comment,
|
76
|
+
"",
|
77
|
+
s(:module,
|
78
|
+
s(:const_ref, s(:@const, "Foo", s(1, 7))),
|
79
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
80
|
+
end
|
81
|
+
|
82
|
+
it "is not confused by a symbol containing a keyword" do
|
83
|
+
result = parse_with_builder ":class; def foo; end"
|
84
|
+
result.must_equal s(:program,
|
85
|
+
s(s(:symbol_literal, s(:symbol, s(:@kw, "class", s(1, 1)))),
|
86
|
+
s(:comment,
|
87
|
+
"",
|
88
|
+
s(:def,
|
89
|
+
s(:@ident, "foo", s(1, 12)),
|
90
|
+
empty_params_list,
|
91
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
92
|
+
end
|
93
|
+
|
94
|
+
it "is not confused by a dynamic symbol" do
|
95
|
+
result = parse_with_builder ":'foo'; def bar; end"
|
96
|
+
result.must_equal s(:program,
|
97
|
+
s(s(:dyna_symbol, s(s(:@tstring_content, "foo", s(1, 2)))),
|
98
|
+
s(:comment,
|
99
|
+
"",
|
100
|
+
s(:def,
|
101
|
+
s(:@ident, "bar", s(1, 12)),
|
102
|
+
empty_params_list,
|
103
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))
|
104
|
+
end
|
105
|
+
|
106
|
+
it "is not confused by a dynamic symbol containing a class definition" do
|
107
|
+
result = parse_with_builder ":\"foo\#{class Bar;end}\""
|
108
|
+
result.must_equal s(:program,
|
109
|
+
s(s(:dyna_symbol,
|
110
|
+
s(s(:@tstring_content, "foo", s(1, 2)),
|
111
|
+
s(:string_embexpr,
|
112
|
+
s(s(:comment,
|
113
|
+
"",
|
114
|
+
s(:class,
|
115
|
+
s(:const_ref, s(:@const, "Bar", s(1, 13))),
|
116
|
+
nil,
|
117
|
+
s(:bodystmt, s(s(:void_stmt)), nil, nil, nil)))))))))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
@@ -7,14 +7,14 @@ describe RipperRubyParser::Parser do
|
|
7
7
|
"Foo::Bar = baz".
|
8
8
|
must_be_parsed_as s(:cdecl,
|
9
9
|
s(:colon2, s(:const, :Foo), :Bar),
|
10
|
-
s(:call, nil, :baz
|
10
|
+
s(:call, nil, :baz))
|
11
11
|
end
|
12
12
|
|
13
13
|
it "works when assigning to constant in the root namespace" do
|
14
14
|
"::Foo = bar".
|
15
15
|
must_be_parsed_as s(:cdecl,
|
16
16
|
s(:colon3, :Foo),
|
17
|
-
s(:call, nil, :bar
|
17
|
+
s(:call, nil, :bar))
|
18
18
|
end
|
19
19
|
|
20
20
|
describe "with a right-hand splat" do
|
@@ -23,7 +23,7 @@ describe RipperRubyParser::Parser do
|
|
23
23
|
must_be_parsed_as s(:lasgn, :foo,
|
24
24
|
s(:svalue,
|
25
25
|
s(:splat,
|
26
|
-
s(:call, nil, :bar
|
26
|
+
s(:call, nil, :bar))))
|
27
27
|
end
|
28
28
|
|
29
29
|
specify do
|
@@ -31,9 +31,9 @@ describe RipperRubyParser::Parser do
|
|
31
31
|
must_be_parsed_as s(:lasgn, :foo,
|
32
32
|
s(:svalue,
|
33
33
|
s(:array,
|
34
|
-
s(:call, nil, :bar
|
34
|
+
s(:call, nil, :bar),
|
35
35
|
s(:splat,
|
36
|
-
s(:call, nil, :baz
|
36
|
+
s(:call, nil, :baz)))))
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -43,8 +43,8 @@ describe RipperRubyParser::Parser do
|
|
43
43
|
must_be_parsed_as s(:lasgn, :foo,
|
44
44
|
s(:svalue,
|
45
45
|
s(:array,
|
46
|
-
s(:call, nil, :bar
|
47
|
-
s(:call, nil, :baz
|
46
|
+
s(:call, nil, :bar),
|
47
|
+
s(:call, nil, :baz))))
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
@@ -53,8 +53,8 @@ describe RipperRubyParser::Parser do
|
|
53
53
|
"foo = [bar, baz]".
|
54
54
|
must_be_parsed_as s(:lasgn, :foo,
|
55
55
|
s(:array,
|
56
|
-
s(:call, nil, :bar
|
57
|
-
s(:call, nil, :baz
|
56
|
+
s(:call, nil, :bar),
|
57
|
+
s(:call, nil, :baz)))
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -64,7 +64,7 @@ describe RipperRubyParser::Parser do
|
|
64
64
|
"foo, * = bar".
|
65
65
|
must_be_parsed_as s(:masgn,
|
66
66
|
s(:array, s(:lasgn, :foo), s(:splat)),
|
67
|
-
s(:to_ary, s(:call, nil, :bar
|
67
|
+
s(:to_ary, s(:call, nil, :bar)))
|
68
68
|
end
|
69
69
|
|
70
70
|
specify do
|
@@ -73,7 +73,7 @@ describe RipperRubyParser::Parser do
|
|
73
73
|
s(:array,
|
74
74
|
s(:lasgn, :foo),
|
75
75
|
s(:splat, s(:lasgn, :bar))),
|
76
|
-
s(:to_ary, s(:call, nil, :baz
|
76
|
+
s(:to_ary, s(:call, nil, :baz)))
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -81,12 +81,11 @@ describe RipperRubyParser::Parser do
|
|
81
81
|
it "handles multiple indices" do
|
82
82
|
"foo[bar, baz] = qux".
|
83
83
|
must_be_parsed_as s(:attrasgn,
|
84
|
-
s(:call, nil, :foo
|
84
|
+
s(:call, nil, :foo),
|
85
85
|
:[]=,
|
86
|
-
s(:
|
87
|
-
|
88
|
-
|
89
|
-
s(:call, nil, :qux, s(:arglist))))
|
86
|
+
s(:call, nil, :bar),
|
87
|
+
s(:call, nil, :baz),
|
88
|
+
s(:call, nil, :qux))
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
@@ -95,18 +94,18 @@ describe RipperRubyParser::Parser do
|
|
95
94
|
it "handles multiple indices" do
|
96
95
|
"foo[bar, baz] += qux".
|
97
96
|
must_be_parsed_as s(:op_asgn1,
|
98
|
-
s(:call, nil, :foo
|
97
|
+
s(:call, nil, :foo),
|
99
98
|
s(:arglist,
|
100
|
-
s(:call, nil, :bar
|
101
|
-
s(:call, nil, :baz
|
99
|
+
s(:call, nil, :bar),
|
100
|
+
s(:call, nil, :baz)),
|
102
101
|
:+,
|
103
|
-
s(:call, nil, :qux
|
102
|
+
s(:call, nil, :qux))
|
104
103
|
end
|
105
104
|
|
106
105
|
it "works with &&=" do
|
107
106
|
"foo &&= bar".
|
108
107
|
must_be_parsed_as s(:op_asgn_and,
|
109
|
-
s(:lvar, :foo), s(:lasgn, :foo, s(:call, nil, :bar
|
108
|
+
s(:lvar, :foo), s(:lasgn, :foo, s(:call, nil, :bar)))
|
110
109
|
end
|
111
110
|
end
|
112
111
|
end
|
@@ -117,15 +116,15 @@ describe RipperRubyParser::Parser do
|
|
117
116
|
"foo, bar = *baz".
|
118
117
|
must_be_parsed_as s(:masgn,
|
119
118
|
s(:array, s(:lasgn, :foo), s(:lasgn, :bar)),
|
120
|
-
s(:splat, s(:call, nil, :baz
|
119
|
+
s(:splat, s(:call, nil, :baz)))
|
121
120
|
end
|
122
121
|
specify do
|
123
122
|
"foo, bar = baz, *qux".
|
124
123
|
must_be_parsed_as s(:masgn,
|
125
124
|
s(:array, s(:lasgn, :foo), s(:lasgn, :bar)),
|
126
125
|
s(:array,
|
127
|
-
s(:call, nil, :baz
|
128
|
-
s(:splat, s(:call, nil, :qux
|
126
|
+
s(:call, nil, :baz),
|
127
|
+
s(:splat, s(:call, nil, :qux))))
|
129
128
|
end
|
130
129
|
end
|
131
130
|
end
|
@@ -6,88 +6,252 @@ describe RipperRubyParser::Parser do
|
|
6
6
|
specify do
|
7
7
|
"foo do |(bar, baz)| end".
|
8
8
|
must_be_parsed_as s(:iter,
|
9
|
-
s(:call, nil, :foo
|
10
|
-
s(:
|
11
|
-
s(:
|
12
|
-
s(:lasgn, :bar),
|
13
|
-
s(:lasgn, :baz))))
|
9
|
+
s(:call, nil, :foo),
|
10
|
+
s(:args,
|
11
|
+
s(:masgn, :bar, :baz)))
|
14
12
|
end
|
15
13
|
|
16
14
|
specify do
|
17
15
|
"foo do |(bar, *baz)| end".
|
18
16
|
must_be_parsed_as s(:iter,
|
19
|
-
s(:call, nil, :foo
|
20
|
-
s(:
|
21
|
-
s(:
|
22
|
-
s(:lasgn, :bar),
|
23
|
-
s(:splat, s(:lasgn, :baz)))))
|
17
|
+
s(:call, nil, :foo),
|
18
|
+
s(:args,
|
19
|
+
s(:masgn, :bar, :"*baz")))
|
24
20
|
end
|
25
21
|
|
26
22
|
specify do
|
27
23
|
"foo do |bar,*| end".
|
28
24
|
must_be_parsed_as s(:iter,
|
29
|
-
s(:call, nil, :foo
|
30
|
-
s(:
|
25
|
+
s(:call, nil, :foo),
|
26
|
+
s(:args, :bar, :"*"))
|
31
27
|
end
|
32
28
|
|
33
29
|
specify do
|
34
30
|
"foo do |bar, &baz| end".
|
35
31
|
must_be_parsed_as s(:iter,
|
36
|
-
s(:call, nil, :foo
|
37
|
-
s(:
|
38
|
-
s(:array,
|
39
|
-
s(:lasgn, :bar),
|
40
|
-
s(:lasgn, :"&baz"))))
|
32
|
+
s(:call, nil, :foo),
|
33
|
+
s(:args, :bar, :"&baz"))
|
41
34
|
end
|
42
35
|
|
43
|
-
it "
|
36
|
+
it "handles empty parameter specs" do
|
37
|
+
"foo do ||; bar; end".
|
38
|
+
must_be_parsed_as s(:iter,
|
39
|
+
s(:call, nil, :foo),
|
40
|
+
0,
|
41
|
+
s(:call, nil, :bar))
|
42
|
+
end
|
43
|
+
|
44
|
+
it "ignores a trailing comma in the block parameters" do
|
44
45
|
"foo do |bar, | end".
|
45
46
|
must_be_parsed_as s(:iter,
|
46
|
-
s(:call, nil, :foo
|
47
|
-
s(:
|
47
|
+
s(:call, nil, :foo),
|
48
|
+
s(:args, :bar))
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
|
-
describe "for rescue/else
|
52
|
+
describe "for rescue/else" do
|
52
53
|
it "works for a block with multiple rescue statements" do
|
53
54
|
"begin foo; rescue; bar; rescue; baz; end".
|
54
55
|
must_be_parsed_as s(:rescue,
|
55
|
-
s(:call, nil, :foo
|
56
|
+
s(:call, nil, :foo),
|
56
57
|
s(:resbody,
|
57
58
|
s(:array),
|
58
|
-
s(:call, nil, :bar
|
59
|
+
s(:call, nil, :bar)),
|
59
60
|
s(:resbody,
|
60
61
|
s(:array),
|
61
|
-
s(:call, nil, :baz
|
62
|
+
s(:call, nil, :baz)))
|
62
63
|
end
|
63
64
|
|
64
65
|
it "works for a block with rescue and else" do
|
65
66
|
"begin; foo; rescue; bar; else; baz; end".
|
66
67
|
must_be_parsed_as s(:rescue,
|
67
|
-
s(:call, nil, :foo
|
68
|
+
s(:call, nil, :foo),
|
68
69
|
s(:resbody,
|
69
70
|
s(:array),
|
70
|
-
s(:call, nil, :bar
|
71
|
-
s(:call, nil, :baz
|
71
|
+
s(:call, nil, :bar)),
|
72
|
+
s(:call, nil, :baz))
|
72
73
|
end
|
73
74
|
|
74
75
|
it "works for a block with only else" do
|
75
76
|
"begin; foo; else; bar; end".
|
76
77
|
must_be_parsed_as s(:block,
|
77
|
-
s(:call, nil, :foo
|
78
|
-
s(:call, nil, :bar
|
78
|
+
s(:call, nil, :foo),
|
79
|
+
s(:call, nil, :bar))
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
82
|
-
describe "for rescue" do
|
83
|
+
describe "for the rescue statement" do
|
83
84
|
it "works with assignment to an error variable" do
|
84
85
|
"begin; foo; rescue => bar; baz; end".
|
85
86
|
must_be_parsed_as s(:rescue,
|
86
|
-
s(:call, nil, :foo
|
87
|
+
s(:call, nil, :foo),
|
87
88
|
s(:resbody,
|
88
89
|
s(:array,
|
89
90
|
s(:lasgn, :bar, s(:gvar, :$!))),
|
90
|
-
s(:call, nil, :baz
|
91
|
+
s(:call, nil, :baz)))
|
92
|
+
end
|
93
|
+
|
94
|
+
it "works with assignment of the exception to an instance variable" do
|
95
|
+
"begin; foo; rescue => @bar; baz; end".
|
96
|
+
must_be_parsed_as s(:rescue,
|
97
|
+
s(:call, nil, :foo),
|
98
|
+
s(:resbody,
|
99
|
+
s(:array,
|
100
|
+
s(:iasgn, :@bar, s(:gvar, :$!))),
|
101
|
+
s(:call, nil, :baz)))
|
102
|
+
end
|
103
|
+
|
104
|
+
it "works with empty main and rescue bodies" do
|
105
|
+
"begin; rescue; end".
|
106
|
+
must_be_parsed_as s(:rescue,
|
107
|
+
s(:resbody, s(:array), nil))
|
108
|
+
end
|
109
|
+
|
110
|
+
it "works with single statement main and rescue bodies" do
|
111
|
+
"begin; foo; rescue; bar; end".
|
112
|
+
must_be_parsed_as s(:rescue,
|
113
|
+
s(:call, nil, :foo),
|
114
|
+
s(:resbody,
|
115
|
+
s(:array),
|
116
|
+
s(:call, nil, :bar)))
|
117
|
+
end
|
118
|
+
|
119
|
+
it "works with multi-statement main and rescue bodies" do
|
120
|
+
"begin; foo; bar; rescue; baz; qux; end".
|
121
|
+
must_be_parsed_as s(:rescue,
|
122
|
+
s(:block,
|
123
|
+
s(:call, nil, :foo),
|
124
|
+
s(:call, nil, :bar)),
|
125
|
+
s(:resbody,
|
126
|
+
s(:array),
|
127
|
+
s(:call, nil, :baz),
|
128
|
+
s(:call, nil, :qux)))
|
129
|
+
end
|
130
|
+
|
131
|
+
it "works with assignment to an error variable" do
|
132
|
+
"begin; foo; rescue => e; bar; end".
|
133
|
+
must_be_parsed_as s(:rescue,
|
134
|
+
s(:call, nil, :foo),
|
135
|
+
s(:resbody,
|
136
|
+
s(:array, s(:lasgn, :e, s(:gvar, :$!))),
|
137
|
+
s(:call, nil, :bar)))
|
138
|
+
end
|
139
|
+
|
140
|
+
it "works with filtering of the exception type" do
|
141
|
+
"begin; foo; rescue Bar; baz; end".
|
142
|
+
must_be_parsed_as s(:rescue,
|
143
|
+
s(:call, nil, :foo),
|
144
|
+
s(:resbody,
|
145
|
+
s(:array, s(:const, :Bar)),
|
146
|
+
s(:call, nil, :baz)))
|
147
|
+
end
|
148
|
+
|
149
|
+
it "works with filtering of the exception type and assignment to an error variable" do
|
150
|
+
"begin; foo; rescue Bar => e; baz; end".
|
151
|
+
must_be_parsed_as s(:rescue,
|
152
|
+
s(:call, nil, :foo),
|
153
|
+
s(:resbody,
|
154
|
+
s(:array,
|
155
|
+
s(:const, :Bar),
|
156
|
+
s(:lasgn, :e, s(:gvar, :$!))),
|
157
|
+
s(:call, nil, :baz)))
|
158
|
+
end
|
159
|
+
|
160
|
+
it "works rescuing multiple exception types" do
|
161
|
+
"begin; foo; rescue Bar, Baz; qux; end".
|
162
|
+
must_be_parsed_as s(:rescue,
|
163
|
+
s(:call, nil, :foo),
|
164
|
+
s(:resbody,
|
165
|
+
s(:array, s(:const, :Bar), s(:const, :Baz)),
|
166
|
+
s(:call, nil, :qux)))
|
167
|
+
end
|
168
|
+
|
169
|
+
it "works in the postfix case" do
|
170
|
+
"foo rescue bar".
|
171
|
+
must_be_parsed_as s(:rescue,
|
172
|
+
s(:call, nil, :foo),
|
173
|
+
s(:resbody,
|
174
|
+
s(:array),
|
175
|
+
s(:call, nil, :bar)))
|
176
|
+
end
|
177
|
+
|
178
|
+
it "works in a plain method body" do
|
179
|
+
"def foo; bar; rescue; baz; end".
|
180
|
+
must_be_parsed_as s(:defn,
|
181
|
+
:foo,
|
182
|
+
s(:args),
|
183
|
+
s(:rescue,
|
184
|
+
s(:call, nil, :bar),
|
185
|
+
s(:resbody,
|
186
|
+
s(:array),
|
187
|
+
s(:call, nil, :baz))))
|
188
|
+
end
|
189
|
+
|
190
|
+
it "works in a method body inside begin..end" do
|
191
|
+
"def foo; bar; begin; baz; rescue; qux; end; quuz; end".
|
192
|
+
must_be_parsed_as s(:defn,
|
193
|
+
:foo,
|
194
|
+
s(:args),
|
195
|
+
s(:call, nil, :bar),
|
196
|
+
s(:rescue,
|
197
|
+
s(:call, nil, :baz),
|
198
|
+
s(:resbody, s(:array), s(:call, nil, :qux))),
|
199
|
+
s(:call, nil, :quuz))
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe "for the ensure statement" do
|
204
|
+
it "works with single statement main and ensure bodies" do
|
205
|
+
"begin; foo; ensure; bar; end".
|
206
|
+
must_be_parsed_as s(:ensure,
|
207
|
+
s(:call, nil, :foo),
|
208
|
+
s(:call, nil, :bar))
|
209
|
+
end
|
210
|
+
|
211
|
+
it "works with multi-statement main and ensure bodies" do
|
212
|
+
"begin; foo; bar; ensure; baz; qux; end".
|
213
|
+
must_be_parsed_as s(:ensure,
|
214
|
+
s(:block,
|
215
|
+
s(:call, nil, :foo),
|
216
|
+
s(:call, nil, :bar)),
|
217
|
+
s(:block,
|
218
|
+
s(:call, nil, :baz),
|
219
|
+
s(:call, nil, :qux)))
|
220
|
+
end
|
221
|
+
|
222
|
+
it "works together with rescue" do
|
223
|
+
"begin; foo; rescue; bar; ensure; baz; end".
|
224
|
+
must_be_parsed_as s(:ensure,
|
225
|
+
s(:rescue,
|
226
|
+
s(:call, nil, :foo),
|
227
|
+
s(:resbody,
|
228
|
+
s(:array),
|
229
|
+
s(:call, nil, :bar))),
|
230
|
+
s(:call, nil, :baz))
|
231
|
+
end
|
232
|
+
|
233
|
+
it "works with empty main and ensure bodies" do
|
234
|
+
"begin; ensure; end".
|
235
|
+
must_be_parsed_as s(:ensure, s(:nil))
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
describe "for lists of consecutive statments" do
|
240
|
+
it "removes extra blocks for grouped statements at the start of the list" do
|
241
|
+
"(foo; bar); baz".
|
242
|
+
must_be_parsed_as s(:block,
|
243
|
+
s(:call, nil, :foo),
|
244
|
+
s(:call, nil, :bar),
|
245
|
+
s(:call, nil, :baz))
|
246
|
+
end
|
247
|
+
|
248
|
+
it "keeps extra blocks for grouped statements at the end of the list" do
|
249
|
+
"foo; (bar; baz)".
|
250
|
+
must_be_parsed_as s(:block,
|
251
|
+
s(:call, nil, :foo),
|
252
|
+
s(:block,
|
253
|
+
s(:call, nil, :bar),
|
254
|
+
s(:call, nil, :baz)))
|
91
255
|
end
|
92
256
|
end
|
93
257
|
|
@@ -95,9 +259,17 @@ describe RipperRubyParser::Parser do
|
|
95
259
|
it "works in the simple case" do
|
96
260
|
"->(foo) { bar }".
|
97
261
|
must_be_parsed_as s(:iter,
|
98
|
-
s(:call, nil, :lambda
|
99
|
-
s(:
|
100
|
-
s(:call, nil, :bar
|
262
|
+
s(:call, nil, :lambda),
|
263
|
+
s(:args, :foo),
|
264
|
+
s(:call, nil, :bar))
|
265
|
+
end
|
266
|
+
|
267
|
+
it "works when there are no arguments" do
|
268
|
+
"-> { bar }".
|
269
|
+
must_be_parsed_as s(:iter,
|
270
|
+
s(:call, nil, :lambda),
|
271
|
+
0,
|
272
|
+
s(:call, nil, :bar))
|
101
273
|
end
|
102
274
|
end
|
103
275
|
end
|