ripper_ruby_parser 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +4 -23
- data/Rakefile +12 -12
- data/lib/ripper_ruby_parser.rb +2 -2
- data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +9 -9
- data/lib/ripper_ruby_parser/parser.rb +3 -3
- data/lib/ripper_ruby_parser/sexp_handlers.rb +9 -9
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +3 -9
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +19 -24
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +14 -18
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +3 -3
- data/lib/ripper_ruby_parser/sexp_processor.rb +4 -4
- data/lib/ripper_ruby_parser/unescape.rb +11 -11
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/test/end_to_end/comments_test.rb +10 -10
- data/test/end_to_end/comparison_test.rb +28 -28
- data/test/end_to_end/lib_comparison_test.rb +6 -6
- data/test/end_to_end/line_numbering_test.rb +10 -10
- data/test/end_to_end/samples_comparison_test.rb +5 -5
- data/test/end_to_end/test_comparison_test.rb +6 -6
- data/test/pt_testcase/pt_test.rb +7 -7
- data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +163 -169
- data/test/ripper_ruby_parser/parser_test.rb +338 -338
- data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +475 -511
- data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +582 -564
- data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +469 -469
- data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +713 -724
- data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +155 -155
- data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +181 -181
- data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +337 -352
- data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +298 -298
- data/test/ripper_ruby_parser/sexp_processor_test.rb +119 -119
- data/test/ripper_ruby_parser/version_test.rb +2 -2
- data/test/samples/lambdas.rb +5 -0
- data/test/samples/misc.rb +3 -0
- data/test/samples/strings.rb +7 -0
- data/test/test_helper.rb +8 -6
- metadata +12 -10
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require "sexp_processor"
|
4
|
+
require "ripper_ruby_parser/sexp_handlers"
|
5
|
+
require "ripper_ruby_parser/unescape"
|
6
6
|
|
7
7
|
module RipperRubyParser
|
8
8
|
# Processes the sexp created by Ripper to what RubyParser would produce.
|
@@ -241,7 +241,7 @@ module RipperRubyParser
|
|
241
241
|
_, str, pos = exp.shift 3
|
242
242
|
name = str[1..-1]
|
243
243
|
with_position pos do
|
244
|
-
if
|
244
|
+
if /[0-9]/.match?(name)
|
245
245
|
s(:nth_ref, name.to_i)
|
246
246
|
else
|
247
247
|
s(:back_ref, name.to_sym)
|
@@ -23,15 +23,15 @@ module RipperRubyParser
|
|
23
23
|
)/x.freeze
|
24
24
|
|
25
25
|
SINGLE_LETTER_ESCAPES = {
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
26
|
+
"a" => "\a",
|
27
|
+
"b" => "\b",
|
28
|
+
"e" => "\e",
|
29
|
+
"f" => "\f",
|
30
|
+
"n" => "\n",
|
31
|
+
"r" => "\r",
|
32
|
+
"s" => "\s",
|
33
|
+
"t" => "\t",
|
34
|
+
"v" => "\v"
|
35
35
|
}.freeze
|
36
36
|
|
37
37
|
SINGLE_LETTER_ESCAPES_REGEXP =
|
@@ -61,7 +61,7 @@ module RipperRubyParser
|
|
61
61
|
string.gsub(ESCAPE_SEQUENCE_REGEXP) do
|
62
62
|
bare = Regexp.last_match[1]
|
63
63
|
if bare == "\n"
|
64
|
-
|
64
|
+
""
|
65
65
|
else
|
66
66
|
unescaped_value(bare)
|
67
67
|
end
|
@@ -88,7 +88,7 @@ module RipperRubyParser
|
|
88
88
|
bare = Regexp.last_match[1]
|
89
89
|
case bare
|
90
90
|
when "\n"
|
91
|
-
|
91
|
+
""
|
92
92
|
else
|
93
93
|
'\\\\'
|
94
94
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
4
|
-
require
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
+
require "ruby_parser"
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe "Using RipperRubyParser and RubyParser" do
|
7
7
|
let :newparser do
|
8
8
|
RipperRubyParser::Parser.new
|
9
9
|
end
|
@@ -12,9 +12,9 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
12
12
|
RubyParser.for_current_ruby
|
13
13
|
end
|
14
14
|
|
15
|
-
describe
|
15
|
+
describe "for a program with quite some comments" do
|
16
16
|
let :program do
|
17
|
-
<<-
|
17
|
+
<<-RUBY
|
18
18
|
# Foo
|
19
19
|
class Foo
|
20
20
|
# The foo
|
@@ -37,7 +37,7 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
RUBY
|
41
41
|
end
|
42
42
|
|
43
43
|
let :original do
|
@@ -48,12 +48,12 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
48
48
|
newparser.parse program
|
49
49
|
end
|
50
50
|
|
51
|
-
it
|
52
|
-
imitation.must_equal original
|
51
|
+
it "gives the same result" do
|
52
|
+
_(imitation).must_equal original
|
53
53
|
end
|
54
54
|
|
55
|
-
it
|
56
|
-
to_comments(imitation).must_equal to_comments(original)
|
55
|
+
it "gives the same result with comments" do
|
56
|
+
_(to_comments(imitation)).must_equal to_comments(original)
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
@@ -1,22 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
4
|
-
require
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
+
require "ruby_parser"
|
5
5
|
|
6
|
-
describe
|
7
|
-
describe
|
6
|
+
describe "Using RipperRubyParser and RubyParser" do
|
7
|
+
describe "for a simple well known program" do
|
8
8
|
let :program do
|
9
9
|
"puts 'Hello World'"
|
10
10
|
end
|
11
11
|
|
12
|
-
it
|
13
|
-
program.must_be_parsed_as_before with_line_numbers: true
|
12
|
+
it "gives the same result with line numbers" do
|
13
|
+
_(program).must_be_parsed_as_before with_line_numbers: true
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
describe
|
17
|
+
describe "for a more complex program" do
|
18
18
|
let :program do
|
19
|
-
<<-
|
19
|
+
<<-RUBY
|
20
20
|
module Quux
|
21
21
|
class Foo
|
22
22
|
def bar
|
@@ -32,27 +32,27 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
32
32
|
end
|
33
33
|
|
34
34
|
Quux::Foo.new.bar
|
35
|
-
|
35
|
+
RUBY
|
36
36
|
end
|
37
37
|
|
38
|
-
it
|
39
|
-
program.must_be_parsed_as_before
|
38
|
+
it "gives the same result" do
|
39
|
+
_(program).must_be_parsed_as_before
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
describe
|
43
|
+
describe "for an example with yield from Reek" do
|
44
44
|
let :program do
|
45
|
-
|
45
|
+
"def fred() yield(3) if block_given?; end"
|
46
46
|
end
|
47
47
|
|
48
|
-
it
|
49
|
-
program.must_be_parsed_as_before with_line_numbers: true
|
48
|
+
it "gives the same result with line numbers" do
|
49
|
+
_(program).must_be_parsed_as_before with_line_numbers: true
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
describe
|
53
|
+
describe "for an example with floats from Reek" do
|
54
54
|
let :program do
|
55
|
-
<<-
|
55
|
+
<<-RUBY
|
56
56
|
def total_envy
|
57
57
|
fred = @item
|
58
58
|
total = 0
|
@@ -60,17 +60,17 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
60
60
|
total += fred.tax
|
61
61
|
total *= 1.15
|
62
62
|
end
|
63
|
-
|
63
|
+
RUBY
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
67
|
-
program.must_be_parsed_as_before
|
66
|
+
it "gives the same result" do
|
67
|
+
_(program).must_be_parsed_as_before
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
describe
|
71
|
+
describe "for an example with operators and explicit block parameter from Reek" do
|
72
72
|
let :program do
|
73
|
-
<<-
|
73
|
+
<<-RUBY
|
74
74
|
def parse(arg, argv, &error)
|
75
75
|
if !(val = arg) and (argv.empty? or /\\A-/ =~ (val = argv[0]))
|
76
76
|
return nil, block, nil
|
@@ -84,21 +84,21 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
84
84
|
end
|
85
85
|
val
|
86
86
|
end
|
87
|
-
|
87
|
+
RUBY
|
88
88
|
end
|
89
89
|
|
90
|
-
it
|
91
|
-
program.must_be_parsed_as_before
|
90
|
+
it "gives the same result" do
|
91
|
+
_(program).must_be_parsed_as_before
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
describe
|
95
|
+
describe "for an example of a complex regular expression from Reek" do
|
96
96
|
let :program do
|
97
97
|
"/(\#{@types})\\s*(\\w+)\\s*\\(([^)]*)\\)/"
|
98
98
|
end
|
99
99
|
|
100
|
-
it
|
101
|
-
program.must_be_parsed_as_before with_line_numbers: true
|
100
|
+
it "gives the same result with line numbers" do
|
101
|
+
_(program).must_be_parsed_as_before with_line_numbers: true
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
4
|
-
require
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
+
require "ruby_parser"
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe "Using RipperRubyParser and RubyParser" do
|
7
7
|
let :newparser do
|
8
8
|
RipperRubyParser::Parser.new
|
9
9
|
end
|
@@ -12,17 +12,17 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
12
12
|
RubyParser.for_current_ruby
|
13
13
|
end
|
14
14
|
|
15
|
-
Dir.glob(
|
15
|
+
Dir.glob("lib/**/*.rb").each do |file|
|
16
16
|
describe "for #{file}" do
|
17
17
|
let :program do
|
18
18
|
File.read file
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it "gives the same result" do
|
22
22
|
original = oldparser.parse program
|
23
23
|
imitation = newparser.parse program
|
24
24
|
|
25
|
-
formatted(imitation).must_equal formatted(original)
|
25
|
+
_(formatted(imitation)).must_equal formatted(original)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
4
|
-
require
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
+
require "ruby_parser"
|
5
5
|
|
6
|
-
describe
|
7
|
-
describe
|
6
|
+
describe "Using RipperRubyParser and RubyParser" do
|
7
|
+
describe "for a multi-line program" do
|
8
8
|
let :program do
|
9
|
-
<<-
|
9
|
+
<<-RUBY
|
10
10
|
class Foo
|
11
11
|
def foo()
|
12
12
|
bar()
|
@@ -17,15 +17,15 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
17
17
|
module Bar
|
18
18
|
@@baz = {}
|
19
19
|
end
|
20
|
-
|
20
|
+
RUBY
|
21
21
|
end
|
22
22
|
|
23
|
-
it
|
24
|
-
program.must_be_parsed_as_before
|
23
|
+
it "gives the same result" do
|
24
|
+
_(program).must_be_parsed_as_before
|
25
25
|
end
|
26
26
|
|
27
|
-
it
|
28
|
-
program.must_be_parsed_as_before with_line_numbers: true
|
27
|
+
it "gives the same result with line numbers" do
|
28
|
+
_(program).must_be_parsed_as_before with_line_numbers: true
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
4
|
-
require
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
+
require "ruby_parser"
|
5
5
|
|
6
|
-
describe
|
7
|
-
Dir.glob(File.expand_path(
|
6
|
+
describe "Using RipperRubyParser and RubyParser" do
|
7
|
+
Dir.glob(File.expand_path("../samples/*.rb", File.dirname(__FILE__))).each do |file|
|
8
8
|
it "gives the same result for #{file}" do
|
9
9
|
program = File.read file
|
10
|
-
program.must_be_parsed_as_before
|
10
|
+
_(program).must_be_parsed_as_before
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
4
|
-
require
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
+
require "ruby_parser"
|
5
5
|
|
6
|
-
describe
|
6
|
+
describe "Using RipperRubyParser and RubyParser" do
|
7
7
|
let :newparser do
|
8
8
|
RipperRubyParser::Parser.new
|
9
9
|
end
|
@@ -12,20 +12,20 @@ describe 'Using RipperRubyParser and RubyParser' do
|
|
12
12
|
RubyParser.for_current_ruby
|
13
13
|
end
|
14
14
|
|
15
|
-
Dir.glob(
|
15
|
+
Dir.glob("test/ripper_ruby_parser/**/*.rb").each do |file|
|
16
16
|
describe "for #{file}" do
|
17
17
|
let :program do
|
18
18
|
File.read file
|
19
19
|
end
|
20
20
|
|
21
|
-
it
|
21
|
+
it "gives the same result" do
|
22
22
|
# Clone string because ruby_parser destroys it when there's a heredoc
|
23
23
|
# inside.
|
24
24
|
copy = program.clone
|
25
25
|
original = oldparser.parse program
|
26
26
|
imitation = newparser.parse copy
|
27
27
|
|
28
|
-
formatted(imitation).must_equal formatted(original)
|
28
|
+
_(formatted(imitation)).must_equal formatted(original)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/test/pt_testcase/pt_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
4
|
-
require
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
|
+
require "pt_testcase"
|
5
5
|
|
6
6
|
class TestParser < RipperRubyParser::Parser
|
7
7
|
def process(input)
|
@@ -9,17 +9,17 @@ class TestParser < RipperRubyParser::Parser
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
SKIPPED_TESTS = [
|
12
|
+
SKIPPED_TESTS = ["dstr_heredoc_windoze_sucks"].freeze
|
13
13
|
|
14
14
|
class RubyParserTestCase < ParseTreeTestCase
|
15
15
|
def self.previous(_key)
|
16
|
-
|
16
|
+
"Ruby"
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.generate_test(klass, node, data, input_name, _output_name)
|
20
|
-
if data[
|
20
|
+
if data["Ruby"].is_a? Array
|
21
21
|
klass.send :define_method, "test_#{node}" do
|
22
|
-
skip
|
22
|
+
skip "Not a parser test"
|
23
23
|
end
|
24
24
|
return
|
25
25
|
end
|
@@ -31,7 +31,7 @@ class RubyParserTestCase < ParseTreeTestCase
|
|
31
31
|
return
|
32
32
|
end
|
33
33
|
|
34
|
-
super klass, node, data, input_name,
|
34
|
+
super klass, node, data, input_name, "ParseTree"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require File.expand_path(
|
3
|
+
require File.expand_path("../test_helper.rb", File.dirname(__FILE__))
|
4
4
|
|
5
5
|
describe RipperRubyParser::CommentingRipperParser do
|
6
6
|
def parse_with_builder(str)
|
@@ -12,195 +12,189 @@ describe RipperRubyParser::CommentingRipperParser do
|
|
12
12
|
@empty_params_list ||= s(:params, *([nil] * 7))
|
13
13
|
end
|
14
14
|
|
15
|
-
describe
|
16
|
-
|
15
|
+
describe "handling comments" do
|
16
|
+
# Handle different results for dynamic symbol strings. This was changed in
|
17
|
+
# Ruby 2.6.3 and up. See https://bugs.ruby-lang.org/issues/15670
|
18
|
+
let(:dsym_string_type) { RUBY_VERSION < "2.6.3" ? :xstring : :string_content }
|
19
|
+
|
20
|
+
it "produces a comment node surrounding a commented def" do
|
17
21
|
result = parse_with_builder "# Foo\ndef foo; end"
|
18
|
-
result.must_equal s(:program,
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
it
|
31
|
-
result = parse_with_builder
|
32
|
-
result.must_equal s(:program,
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
it
|
22
|
+
_(result).must_equal s(:program,
|
23
|
+
s(:stmts,
|
24
|
+
s(:comment,
|
25
|
+
"# Foo\n",
|
26
|
+
s(:def,
|
27
|
+
s(:@ident, "foo", s(2, 4)),
|
28
|
+
empty_params_list,
|
29
|
+
s(:bodystmt,
|
30
|
+
s(:stmts, s(:void_stmt, s(2, 12))), nil, nil, nil),
|
31
|
+
s(2, 0)))))
|
32
|
+
end
|
33
|
+
|
34
|
+
it "produces a blank comment node surrounding a def that has no comment" do
|
35
|
+
result = parse_with_builder "def foo; end"
|
36
|
+
_(result).must_equal s(:program,
|
37
|
+
s(:stmts,
|
38
|
+
s(:comment,
|
39
|
+
"",
|
40
|
+
s(:def,
|
41
|
+
s(:@ident, "foo", s(1, 4)),
|
42
|
+
empty_params_list,
|
43
|
+
s(:bodystmt,
|
44
|
+
s(:stmts, s(:void_stmt, s(1, 12))), nil, nil, nil),
|
45
|
+
s(1, 0)))))
|
46
|
+
end
|
47
|
+
|
48
|
+
it "produces a comment node surrounding a commented class" do
|
45
49
|
result = parse_with_builder "# Foo\nclass Foo; end"
|
46
|
-
result.must_equal s(:program,
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
end
|
57
|
-
|
58
|
-
it
|
59
|
-
result = parse_with_builder
|
60
|
-
result.must_equal s(:program,
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
it
|
50
|
+
_(result).must_equal s(:program,
|
51
|
+
s(:stmts,
|
52
|
+
s(:comment,
|
53
|
+
"# Foo\n",
|
54
|
+
s(:class,
|
55
|
+
s(:const_ref, s(:@const, "Foo", s(2, 6))),
|
56
|
+
nil,
|
57
|
+
s(:bodystmt,
|
58
|
+
s(:stmts, s(:void_stmt, s(2, 10))), nil, nil, nil),
|
59
|
+
s(2, 0)))))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "produce a blank comment node surrounding a class that has no comment" do
|
63
|
+
result = parse_with_builder "class Foo; end"
|
64
|
+
_(result).must_equal s(:program,
|
65
|
+
s(:stmts,
|
66
|
+
s(:comment,
|
67
|
+
"",
|
68
|
+
s(:class,
|
69
|
+
s(:const_ref, s(:@const, "Foo", s(1, 6))),
|
70
|
+
nil,
|
71
|
+
s(:bodystmt,
|
72
|
+
s(:stmts, s(:void_stmt, s(1, 10))), nil, nil, nil),
|
73
|
+
s(1, 0)))))
|
74
|
+
end
|
75
|
+
|
76
|
+
it "produces a comment node surrounding a commented module" do
|
73
77
|
result = parse_with_builder "# Foo\nmodule Foo; end"
|
74
|
-
result.must_equal s(:program,
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
it
|
86
|
-
result = parse_with_builder
|
87
|
-
result.must_equal s(:program,
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
97
|
-
|
98
|
-
it
|
99
|
-
result = parse_with_builder
|
100
|
-
result.must_equal s(:program,
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
it
|
78
|
+
_(result).must_equal s(:program,
|
79
|
+
s(:stmts,
|
80
|
+
s(:comment,
|
81
|
+
"# Foo\n",
|
82
|
+
s(:module,
|
83
|
+
s(:const_ref, s(:@const, "Foo", s(2, 7))),
|
84
|
+
s(:bodystmt,
|
85
|
+
s(:stmts, s(:void_stmt, s(2, 11))), nil, nil, nil),
|
86
|
+
s(2, 0)))))
|
87
|
+
end
|
88
|
+
|
89
|
+
it "produces a blank comment node surrounding a module that has no comment" do
|
90
|
+
result = parse_with_builder "module Foo; end"
|
91
|
+
_(result).must_equal s(:program,
|
92
|
+
s(:stmts,
|
93
|
+
s(:comment,
|
94
|
+
"",
|
95
|
+
s(:module,
|
96
|
+
s(:const_ref, s(:@const, "Foo", s(1, 7))),
|
97
|
+
s(:bodystmt,
|
98
|
+
s(:stmts, s(:void_stmt, s(1, 11))), nil, nil, nil),
|
99
|
+
s(1, 0)))))
|
100
|
+
end
|
101
|
+
|
102
|
+
it "is not confused by a symbol containing a keyword" do
|
103
|
+
result = parse_with_builder ":class; def foo; end"
|
104
|
+
_(result).must_equal s(:program,
|
105
|
+
s(:stmts,
|
106
|
+
s(:symbol_literal, s(:symbol, s(:@kw, "class", s(1, 1)))),
|
107
|
+
s(:comment,
|
108
|
+
"",
|
109
|
+
s(:def,
|
110
|
+
s(:@ident, "foo", s(1, 12)),
|
111
|
+
empty_params_list,
|
112
|
+
s(:bodystmt,
|
113
|
+
s(:stmts, s(:void_stmt, s(1, 20))), nil, nil, nil),
|
114
|
+
s(1, 8)))))
|
115
|
+
end
|
116
|
+
|
117
|
+
it "is not confused by a dynamic symbol" do
|
114
118
|
result = parse_with_builder ":'foo'; def bar; end"
|
115
|
-
result.must_equal s(:program,
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
119
|
+
_(result).must_equal s(:program,
|
120
|
+
s(:stmts,
|
121
|
+
s(:dyna_symbol,
|
122
|
+
s(dsym_string_type,
|
123
|
+
s(:@tstring_content, "foo", s(1, 2), ":'"))),
|
124
|
+
s(:comment,
|
125
|
+
"",
|
126
|
+
s(:def,
|
127
|
+
s(:@ident, "bar", s(1, 12)),
|
128
|
+
empty_params_list,
|
129
|
+
s(:bodystmt,
|
130
|
+
s(:stmts, s(:void_stmt, s(1, 20))), nil, nil, nil),
|
131
|
+
s(1, 8)))))
|
132
|
+
end
|
133
|
+
|
134
|
+
it "is not confused by a dynamic symbol containing a class definition" do
|
130
135
|
result = parse_with_builder ":\"foo\#{class Bar;end}\""
|
131
|
-
result.must_equal s(:program,
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
136
|
+
_(result).must_equal s(:program,
|
137
|
+
s(:stmts,
|
138
|
+
s(:dyna_symbol,
|
139
|
+
s(dsym_string_type,
|
140
|
+
s(:@tstring_content, "foo", s(1, 2), ':"'),
|
141
|
+
s(:string_embexpr,
|
142
|
+
s(:stmts,
|
143
|
+
s(:comment,
|
144
|
+
"",
|
145
|
+
s(:class,
|
146
|
+
s(:const_ref, s(:@const, "Bar", s(1, 13))),
|
147
|
+
nil,
|
148
|
+
s(:bodystmt,
|
149
|
+
s(:stmts, s(:void_stmt, s(1, 17))),
|
150
|
+
nil, nil, nil),
|
151
|
+
s(1, 7)))))))))
|
152
|
+
end
|
153
|
+
|
154
|
+
it "turns an embedded document into a comment node" do
|
149
155
|
result = parse_with_builder "=begin Hello\nthere\n=end\nclass Foo; end"
|
150
|
-
result.must_equal s(:program,
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
156
|
+
_(result).must_equal s(:program,
|
157
|
+
s(:stmts,
|
158
|
+
s(:comment,
|
159
|
+
"=begin Hello\nthere\n=end\n",
|
160
|
+
s(:class,
|
161
|
+
s(:const_ref, s(:@const, "Foo", s(4, 6))),
|
162
|
+
nil,
|
163
|
+
s(:bodystmt,
|
164
|
+
s(:stmts, s(:void_stmt, s(4, 10))), nil, nil, nil),
|
165
|
+
s(4, 0)))))
|
160
166
|
end
|
161
167
|
end
|
162
168
|
|
163
|
-
describe
|
164
|
-
it
|
165
|
-
proc {
|
166
|
-
parse_with_builder 'def foo'
|
167
|
-
}.must_raise RipperRubyParser::SyntaxError
|
169
|
+
describe "handling syntax errors" do
|
170
|
+
it "raises an error for an incomplete source" do
|
171
|
+
_(proc { parse_with_builder "def foo" }).must_raise RipperRubyParser::SyntaxError
|
168
172
|
end
|
169
173
|
|
170
|
-
it
|
171
|
-
proc {
|
172
|
-
|
173
|
-
}.must_raise RipperRubyParser::SyntaxError
|
174
|
+
it "raises an error for an invalid class name" do
|
175
|
+
_(proc { parse_with_builder "class foo; end" })
|
176
|
+
.must_raise RipperRubyParser::SyntaxError
|
174
177
|
end
|
175
178
|
|
176
|
-
it
|
177
|
-
proc {
|
178
|
-
parse_with_builder 'alias foo $1'
|
179
|
-
}.must_raise RipperRubyParser::SyntaxError
|
179
|
+
it "raises an error aliasing $1 as foo" do
|
180
|
+
_(proc { parse_with_builder "alias foo $1" }).must_raise RipperRubyParser::SyntaxError
|
180
181
|
end
|
181
182
|
|
182
|
-
it
|
183
|
-
proc {
|
184
|
-
parse_with_builder 'alias $1 foo'
|
185
|
-
}.must_raise RipperRubyParser::SyntaxError
|
183
|
+
it "raises an error aliasing foo as $1" do
|
184
|
+
_(proc { parse_with_builder "alias $1 foo" }).must_raise RipperRubyParser::SyntaxError
|
186
185
|
end
|
187
186
|
|
188
|
-
it
|
189
|
-
proc {
|
190
|
-
parse_with_builder 'alias $1 $2'
|
191
|
-
}.must_raise RipperRubyParser::SyntaxError
|
187
|
+
it "raises an error aliasing $2 as $1" do
|
188
|
+
_(proc { parse_with_builder "alias $1 $2" }).must_raise RipperRubyParser::SyntaxError
|
192
189
|
end
|
193
190
|
|
194
|
-
it
|
195
|
-
proc {
|
196
|
-
parse_with_builder '$1 = foo'
|
197
|
-
}.must_raise RipperRubyParser::SyntaxError
|
191
|
+
it "raises an error assigning to $1" do
|
192
|
+
_(proc { parse_with_builder "$1 = foo" }).must_raise RipperRubyParser::SyntaxError
|
198
193
|
end
|
199
194
|
|
200
|
-
it
|
201
|
-
proc {
|
202
|
-
|
203
|
-
}.must_raise RipperRubyParser::SyntaxError
|
195
|
+
it "raises an error using an invalid parameter name" do
|
196
|
+
_(proc { parse_with_builder "def foo(BAR); end" })
|
197
|
+
.must_raise RipperRubyParser::SyntaxError
|
204
198
|
end
|
205
199
|
end
|
206
200
|
end
|