ripper_ruby_parser 1.6.0 → 1.8.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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/README.md +8 -25
  4. data/lib/ripper_ruby_parser.rb +2 -2
  5. data/lib/ripper_ruby_parser/commenting_ripper_parser.rb +54 -23
  6. data/lib/ripper_ruby_parser/parser.rb +3 -3
  7. data/lib/ripper_ruby_parser/sexp_handlers.rb +11 -9
  8. data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +10 -11
  9. data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +48 -63
  10. data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +17 -19
  11. data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +35 -2
  12. data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +15 -242
  13. data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +4 -2
  14. data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +1 -1
  15. data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +24 -24
  16. data/lib/ripper_ruby_parser/sexp_handlers/string_literals.rb +266 -0
  17. data/lib/ripper_ruby_parser/sexp_processor.rb +47 -78
  18. data/lib/ripper_ruby_parser/unescape.rb +79 -50
  19. data/lib/ripper_ruby_parser/version.rb +1 -1
  20. metadata +115 -78
  21. data/Rakefile +0 -33
  22. data/test/end_to_end/comments_test.rb +0 -59
  23. data/test/end_to_end/comparison_test.rb +0 -104
  24. data/test/end_to_end/lib_comparison_test.rb +0 -29
  25. data/test/end_to_end/line_numbering_test.rb +0 -64
  26. data/test/end_to_end/samples_comparison_test.rb +0 -13
  27. data/test/end_to_end/test_comparison_test.rb +0 -32
  28. data/test/pt_testcase/pt_test.rb +0 -44
  29. data/test/ripper_ruby_parser/commenting_ripper_parser_test.rb +0 -190
  30. data/test/ripper_ruby_parser/parser_test.rb +0 -469
  31. data/test/ripper_ruby_parser/sexp_handlers/assignment_test.rb +0 -649
  32. data/test/ripper_ruby_parser/sexp_handlers/blocks_test.rb +0 -661
  33. data/test/ripper_ruby_parser/sexp_handlers/conditionals_test.rb +0 -536
  34. data/test/ripper_ruby_parser/sexp_handlers/literals_test.rb +0 -1117
  35. data/test/ripper_ruby_parser/sexp_handlers/loops_test.rb +0 -209
  36. data/test/ripper_ruby_parser/sexp_handlers/method_calls_test.rb +0 -267
  37. data/test/ripper_ruby_parser/sexp_handlers/methods_test.rb +0 -427
  38. data/test/ripper_ruby_parser/sexp_handlers/operators_test.rb +0 -399
  39. data/test/ripper_ruby_parser/sexp_processor_test.rb +0 -303
  40. data/test/ripper_ruby_parser/version_test.rb +0 -7
  41. data/test/samples/assignment.rb +0 -17
  42. data/test/samples/comments.rb +0 -13
  43. data/test/samples/conditionals.rb +0 -23
  44. data/test/samples/loops.rb +0 -36
  45. data/test/samples/misc.rb +0 -278
  46. data/test/samples/number.rb +0 -7
  47. data/test/samples/operators.rb +0 -18
  48. data/test/samples/strings.rb +0 -140
  49. data/test/test_helper.rb +0 -79
data/Rakefile DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'rake/clean'
4
- require 'bundler/gem_tasks'
5
- require 'rake/testtask'
6
-
7
- namespace :test do
8
- Rake::TestTask.new(:unit) do |t|
9
- t.libs = ['lib']
10
- t.test_files = FileList['test/ripper_ruby_parser/**/*_test.rb']
11
- t.warning = true
12
- end
13
-
14
- Rake::TestTask.new(:end_to_end) do |t|
15
- t.libs = ['lib']
16
- t.test_files = FileList['test/end_to_end/*_test.rb']
17
- t.warning = true
18
- end
19
-
20
- Rake::TestTask.new(:pt_testcase) do |t|
21
- t.libs = ['lib']
22
- t.test_files = FileList['test/pt_testcase/*_test.rb']
23
- t.warning = true
24
- end
25
-
26
- desc 'Run all three test suites'
27
- task run: [:unit, :end_to_end, :pt_testcase]
28
- end
29
-
30
- desc 'Alias to test:run'
31
- task test: 'test:run'
32
-
33
- task default: :test
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
- require 'ruby_parser'
5
-
6
- describe 'Using RipperRubyParser and RubyParser' do
7
- let :newparser do
8
- RipperRubyParser::Parser.new
9
- end
10
-
11
- let :oldparser do
12
- RubyParser.for_current_ruby
13
- end
14
-
15
- describe 'for a program with quite some comments' do
16
- let :program do
17
- <<-END
18
- # Foo
19
- class Foo
20
- # The foo
21
- # method
22
- def foo
23
- bar # bar
24
- # internal comment
25
- end
26
-
27
- def bar
28
- baz
29
- end
30
- end
31
- # Quux
32
- module Qux
33
- class Quux
34
- def bar
35
- end
36
- def baz
37
- end
38
- end
39
- end
40
- END
41
- end
42
-
43
- let :original do
44
- oldparser.parse program
45
- end
46
-
47
- let :imitation do
48
- newparser.parse program
49
- end
50
-
51
- it 'gives the same result' do
52
- imitation.must_equal original
53
- end
54
-
55
- it 'gives the same result with comments' do
56
- to_comments(imitation).must_equal to_comments(original)
57
- end
58
- end
59
- end
@@ -1,104 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
- require 'ruby_parser'
5
-
6
- describe 'Using RipperRubyParser and RubyParser' do
7
- describe 'for a simple well known program' do
8
- let :program do
9
- "puts 'Hello World'"
10
- end
11
-
12
- it 'gives the same result' do
13
- program.must_be_parsed_as_before
14
- end
15
- end
16
-
17
- describe 'for a more complex program' do
18
- let :program do
19
- <<-END
20
- module Quux
21
- class Foo
22
- def bar
23
- baz = 3
24
- qux baz
25
- end
26
- def qux it
27
- if it == 3
28
- [1,2,3].map {|i| 2*i}
29
- end
30
- end
31
- end
32
- end
33
-
34
- Quux::Foo.new.bar
35
- END
36
- end
37
-
38
- it 'gives the same result' do
39
- program.must_be_parsed_as_before
40
- end
41
- end
42
-
43
- describe 'for an example with yield from Reek' do
44
- let :program do
45
- 'def fred() yield(3) if block_given?; end'
46
- end
47
-
48
- it 'gives the same result' do
49
- program.must_be_parsed_as_before
50
- end
51
- end
52
-
53
- describe 'for an example with floats from Reek' do
54
- let :program do
55
- <<-END
56
- def total_envy
57
- fred = @item
58
- total = 0
59
- total += fred.price
60
- total += fred.tax
61
- total *= 1.15
62
- end
63
- END
64
- end
65
-
66
- it 'gives the same result' do
67
- program.must_be_parsed_as_before
68
- end
69
- end
70
-
71
- describe 'for an example with operators and explicit block parameter from Reek' do
72
- let :program do
73
- <<-END
74
- def parse(arg, argv, &error)
75
- if !(val = arg) and (argv.empty? or /\\A-/ =~ (val = argv[0]))
76
- return nil, block, nil
77
- end
78
- opt = (val = parse_arg(val, &error))[1]
79
- val = conv_arg(*val)
80
- if opt and !arg
81
- argv.shift
82
- else
83
- val[0] = nil
84
- end
85
- val
86
- end
87
- END
88
- end
89
-
90
- it 'gives the same result' do
91
- program.must_be_parsed_as_before
92
- end
93
- end
94
-
95
- describe 'for an example of a complex regular expression from Reek' do
96
- let :program do
97
- "/(\#{@types})\\s*(\\w+)\\s*\\(([^)]*)\\)/"
98
- end
99
-
100
- it 'gives the same result' do
101
- program.must_be_parsed_as_before
102
- end
103
- end
104
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
- require 'ruby_parser'
5
-
6
- describe 'Using RipperRubyParser and RubyParser' do
7
- let :newparser do
8
- RipperRubyParser::Parser.new
9
- end
10
-
11
- let :oldparser do
12
- RubyParser.for_current_ruby
13
- end
14
-
15
- Dir.glob('lib/**/*.rb').each do |file|
16
- describe "for #{file}" do
17
- let :program do
18
- File.read file
19
- end
20
-
21
- it 'gives the same result' do
22
- original = oldparser.parse program
23
- imitation = newparser.parse program
24
-
25
- formatted(imitation).must_equal formatted(original)
26
- end
27
- end
28
- end
29
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
- require 'ruby_parser'
5
-
6
- describe 'Using RipperRubyParser and RubyParser' do
7
- def to_line_numbers(exp)
8
- exp.map! do |sub_exp|
9
- if sub_exp.is_a? Sexp
10
- to_line_numbers sub_exp
11
- else
12
- sub_exp
13
- end
14
- end
15
-
16
- if exp.sexp_type == :scope
17
- exp
18
- else
19
- s(:line_number, exp.line, exp)
20
- end
21
- end
22
-
23
- let :newparser do
24
- RipperRubyParser::Parser.new
25
- end
26
-
27
- let :oldparser do
28
- RubyParser.for_current_ruby
29
- end
30
-
31
- describe 'for a multi-line program' do
32
- let :program do
33
- <<-END
34
- class Foo
35
- def foo()
36
- bar()
37
- baz(qux)
38
- end
39
- end
40
-
41
- module Bar
42
- @@baz = {}
43
- end
44
- END
45
- end
46
-
47
- let :original do
48
- oldparser.parse program
49
- end
50
-
51
- let :imitation do
52
- newparser.parse program
53
- end
54
-
55
- it 'gives the same result' do
56
- imitation.must_equal original
57
- end
58
-
59
- it 'gives the same result with line numbers' do
60
- formatted(to_line_numbers(imitation)).
61
- must_equal formatted(to_line_numbers(original))
62
- end
63
- end
64
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
- require 'ruby_parser'
5
-
6
- describe 'Using RipperRubyParser and RubyParser' do
7
- Dir.glob(File.expand_path('../samples/*.rb', File.dirname(__FILE__))).each do |file|
8
- it "gives the same result for #{file}" do
9
- program = File.read file
10
- program.must_be_parsed_as_before
11
- end
12
- end
13
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
- require 'ruby_parser'
5
-
6
- describe 'Using RipperRubyParser and RubyParser' do
7
- let :newparser do
8
- RipperRubyParser::Parser.new
9
- end
10
-
11
- let :oldparser do
12
- RubyParser.for_current_ruby
13
- end
14
-
15
- Dir.glob('test/ripper_ruby_parser/**/*.rb').each do |file|
16
- describe "for #{file}" do
17
- let :program do
18
- File.read file
19
- end
20
-
21
- it 'gives the same result' do
22
- # Clone string because ruby_parser destroys it when there's a heredoc
23
- # inside.
24
- copy = program.clone
25
- original = oldparser.parse program
26
- imitation = newparser.parse copy
27
-
28
- formatted(imitation).must_equal formatted(original)
29
- end
30
- end
31
- end
32
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
- require 'pt_testcase'
5
-
6
- class TestParser < RipperRubyParser::Parser
7
- def process(input)
8
- parse input
9
- end
10
- end
11
-
12
- SKIPPED_TESTS = ['dstr_heredoc_windoze_sucks'].freeze
13
-
14
- class RubyParserTestCase < ParseTreeTestCase
15
- def self.previous(_key)
16
- 'Ruby'
17
- end
18
-
19
- def self.generate_test(klass, node, data, input_name, _output_name)
20
- if data['Ruby'].is_a? Array
21
- klass.send :define_method, "test_#{node}" do
22
- skip 'Not a parser test'
23
- end
24
- return
25
- end
26
-
27
- if SKIPPED_TESTS.include? node
28
- klass.send :define_method, "test_#{node}" do
29
- skip "Can't or won't fix this difference"
30
- end
31
- return
32
- end
33
-
34
- super klass, node, data, input_name, 'ParseTree'
35
- end
36
- end
37
-
38
- class TestRuby19Parser < RubyParserTestCase
39
- def setup
40
- super
41
-
42
- self.processor = TestParser.new
43
- end
44
- end
@@ -1,190 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
4
-
5
- describe RipperRubyParser::CommentingRipperParser do
6
- def parse_with_builder(str)
7
- builder = RipperRubyParser::CommentingRipperParser.new str
8
- builder.parse
9
- end
10
-
11
- def empty_params_list
12
- @empty_params_list ||= s(:params, *([nil] * 7))
13
- end
14
-
15
- describe 'handling comments' do
16
- it 'produces a comment node surrounding a commented def' do
17
- result = parse_with_builder "# Foo\ndef foo; end"
18
- result.must_equal s(:program,
19
- s(:stmts,
20
- s(:comment,
21
- "# Foo\n",
22
- s(:def,
23
- s(:@ident, 'foo', s(2, 4)),
24
- empty_params_list,
25
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
26
- end
27
-
28
- it 'produces a blank comment node surrounding a def that has no comment' do
29
- result = parse_with_builder 'def foo; end'
30
- result.must_equal s(:program,
31
- s(:stmts,
32
- s(:comment,
33
- '',
34
- s(:def,
35
- s(:@ident, 'foo', s(1, 4)),
36
- empty_params_list,
37
- s(:bodystmt, s(:stmts, 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(:stmts,
44
- s(:comment,
45
- "# Foo\n",
46
- s(:class,
47
- s(:const_ref, s(:@const, 'Foo', s(2, 6))),
48
- nil,
49
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
50
- end
51
-
52
- it 'produce a blank comment node surrounding a class that has no comment' do
53
- result = parse_with_builder 'class Foo; end'
54
- result.must_equal s(:program,
55
- s(:stmts,
56
- s(:comment,
57
- '',
58
- s(:class,
59
- s(:const_ref, s(:@const, 'Foo', s(1, 6))),
60
- nil,
61
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
62
- end
63
-
64
- it 'produces a comment node surrounding a commented module' do
65
- result = parse_with_builder "# Foo\nmodule Foo; end"
66
- result.must_equal s(:program,
67
- s(:stmts,
68
- s(:comment,
69
- "# Foo\n",
70
- s(:module,
71
- s(:const_ref, s(:@const, 'Foo', s(2, 7))),
72
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
73
- end
74
-
75
- it 'produces a blank comment node surrounding a module that has no comment' do
76
- result = parse_with_builder 'module Foo; end'
77
- result.must_equal s(:program,
78
- s(:stmts,
79
- s(:comment,
80
- '',
81
- s(:module,
82
- s(:const_ref, s(:@const, 'Foo', s(1, 7))),
83
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
84
- end
85
-
86
- it 'is not confused by a symbol containing a keyword' do
87
- result = parse_with_builder ':class; def foo; end'
88
- result.must_equal s(:program,
89
- s(:stmts,
90
- s(:symbol_literal, s(:symbol, s(:@kw, 'class', s(1, 1)))),
91
- s(:comment,
92
- '',
93
- s(:def,
94
- s(:@ident, 'foo', s(1, 12)),
95
- empty_params_list,
96
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
97
- end
98
-
99
- it 'is not confused by a dynamic symbol' do
100
- result = parse_with_builder ":'foo'; def bar; end"
101
- result.must_equal s(:program,
102
- s(:stmts,
103
- s(:dyna_symbol,
104
- s(:xstring, s(:@tstring_content, 'foo', s(1, 2), ":'"))),
105
- s(:comment,
106
- '',
107
- s(:def,
108
- s(:@ident, 'bar', s(1, 12)),
109
- empty_params_list,
110
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
111
- end
112
-
113
- it 'is not confused by a dynamic symbol containing a class definition' do
114
- result = parse_with_builder ":\"foo\#{class Bar;end}\""
115
- result.must_equal s(:program,
116
- s(:stmts,
117
- s(:dyna_symbol,
118
- s(:xstring,
119
- s(:@tstring_content, 'foo', s(1, 2), ':"'),
120
- s(:string_embexpr,
121
- s(:stmts,
122
- s(:comment,
123
- '',
124
- s(:class,
125
- s(:const_ref, s(:@const, 'Bar', s(1, 13))),
126
- nil,
127
- s(:bodystmt,
128
- s(:stmts, s(:void_stmt)),
129
- nil,
130
- nil,
131
- nil)))))))))
132
- end
133
-
134
- it 'turns an embedded document into a comment node' do
135
- result = parse_with_builder "=begin Hello\nthere\n=end\nclass Foo; end"
136
- result.must_equal s(:program,
137
- s(:stmts,
138
- s(:comment,
139
- "=begin Hello\nthere\n=end\n",
140
- s(:class,
141
- s(:const_ref, s(:@const, 'Foo', s(4, 6))),
142
- nil,
143
- s(:bodystmt, s(:stmts, s(:void_stmt)), nil, nil, nil)))))
144
- end
145
- end
146
-
147
- describe 'handling syntax errors' do
148
- it 'raises an error for an incomplete source' do
149
- proc {
150
- parse_with_builder 'def foo'
151
- }.must_raise RipperRubyParser::SyntaxError
152
- end
153
-
154
- it 'raises an error for an invalid class name' do
155
- proc {
156
- parse_with_builder 'class foo; end'
157
- }.must_raise RipperRubyParser::SyntaxError
158
- end
159
-
160
- it 'raises an error aliasing $1 as foo' do
161
- proc {
162
- parse_with_builder 'alias foo $1'
163
- }.must_raise RipperRubyParser::SyntaxError
164
- end
165
-
166
- it 'raises an error aliasing foo as $1' do
167
- proc {
168
- parse_with_builder 'alias $1 foo'
169
- }.must_raise RipperRubyParser::SyntaxError
170
- end
171
-
172
- it 'raises an error aliasing $2 as $1' do
173
- proc {
174
- parse_with_builder 'alias $1 $2'
175
- }.must_raise RipperRubyParser::SyntaxError
176
- end
177
-
178
- it 'raises an error assigning to $1' do
179
- proc {
180
- parse_with_builder '$1 = foo'
181
- }.must_raise RipperRubyParser::SyntaxError
182
- end
183
-
184
- it 'raises an error using an invalid parameter name' do
185
- proc {
186
- parse_with_builder 'def foo(BAR); end'
187
- }.must_raise RipperRubyParser::SyntaxError
188
- end
189
- end
190
- end