ripper_ruby_parser 0.0.8 → 1.0.0
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.
- 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
|