ripper_ruby_parser 1.6.1 → 1.7.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 +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
|