ripper_ruby_parser 1.6.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
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