ripper_ruby_parser 0.0.1
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.
- data/README.rdoc +76 -0
- data/Rakefile +24 -0
- data/lib/ripper_ruby_parser/parser.rb +18 -0
- data/lib/ripper_ruby_parser/sexp_ext.rb +14 -0
- data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +23 -0
- data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +15 -0
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +80 -0
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +49 -0
- data/lib/ripper_ruby_parser/sexp_handlers/conditionals.rb +64 -0
- data/lib/ripper_ruby_parser/sexp_handlers/hashes.rb +27 -0
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +49 -0
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +83 -0
- data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +11 -0
- data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +47 -0
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +38 -0
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +41 -0
- data/lib/ripper_ruby_parser/sexp_handlers.rb +35 -0
- data/lib/ripper_ruby_parser/sexp_processor.rb +150 -0
- data/lib/ripper_ruby_parser/version.rb +3 -0
- data/lib/ripper_ruby_parser.rb +5 -0
- data/test/end_to_end/comparison_test.rb +56 -0
- data/test/end_to_end/lib_comparison_test.rb +29 -0
- data/test/end_to_end/test_comparison_test.rb +33 -0
- data/test/test_helper.rb +12 -0
- data/test/unit/parser_test.rb +623 -0
- data/test/unit/sexp_processor_test.rb +309 -0
- data/test/unit/version_test.rb +5 -0
- metadata +137 -0
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'ripper_ruby_parser/sexp_handlers/helper_methods'
|
2
|
+
|
3
|
+
require 'ripper_ruby_parser/sexp_handlers/arguments'
|
4
|
+
require 'ripper_ruby_parser/sexp_handlers/arrays'
|
5
|
+
require 'ripper_ruby_parser/sexp_handlers/assignment'
|
6
|
+
require 'ripper_ruby_parser/sexp_handlers/blocks'
|
7
|
+
require 'ripper_ruby_parser/sexp_handlers/conditionals'
|
8
|
+
require 'ripper_ruby_parser/sexp_handlers/hashes'
|
9
|
+
require 'ripper_ruby_parser/sexp_handlers/literals'
|
10
|
+
require 'ripper_ruby_parser/sexp_handlers/loops'
|
11
|
+
require 'ripper_ruby_parser/sexp_handlers/method_calls'
|
12
|
+
require 'ripper_ruby_parser/sexp_handlers/methods'
|
13
|
+
require 'ripper_ruby_parser/sexp_handlers/operators'
|
14
|
+
|
15
|
+
module RipperRubyParser
|
16
|
+
module SexpHandlers
|
17
|
+
def self.included base
|
18
|
+
base.class_eval do
|
19
|
+
include HelperMethods
|
20
|
+
|
21
|
+
include Arguments
|
22
|
+
include Arrays
|
23
|
+
include Assignment
|
24
|
+
include Blocks
|
25
|
+
include Conditionals
|
26
|
+
include Hashes
|
27
|
+
include Literals
|
28
|
+
include Loops
|
29
|
+
include MethodCalls
|
30
|
+
include Methods
|
31
|
+
include Operators
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'sexp_processor'
|
2
|
+
require 'ripper_ruby_parser/sexp_handlers'
|
3
|
+
require 'ripper_ruby_parser/sexp_ext'
|
4
|
+
|
5
|
+
module RipperRubyParser
|
6
|
+
# Processes the sexp created by Ripper to what RubyParser would produce.
|
7
|
+
class SexpProcessor < ::SexpProcessor
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
# TODO: Find these automatically
|
11
|
+
@processors[:@int] = :process_at_int
|
12
|
+
@processors[:@const] = :process_at_const
|
13
|
+
@processors[:@ident] = :process_at_ident
|
14
|
+
@processors[:@gvar] = :process_at_gvar
|
15
|
+
@processors[:@ivar] = :process_at_ivar
|
16
|
+
@processors[:@kw] = :process_at_kw
|
17
|
+
@processors[:@backref] = :process_at_backref
|
18
|
+
|
19
|
+
@processors[:@tstring_content] = :process_at_tstring_content
|
20
|
+
end
|
21
|
+
|
22
|
+
def process exp
|
23
|
+
return nil if exp.nil?
|
24
|
+
exp.fix_empty_type
|
25
|
+
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
include SexpHandlers
|
30
|
+
|
31
|
+
def process_program exp
|
32
|
+
_, content = exp.shift 2
|
33
|
+
|
34
|
+
if content.length == 1
|
35
|
+
process(content.first)
|
36
|
+
else
|
37
|
+
statements = content.map { |sub_exp| process(sub_exp) }
|
38
|
+
s(:block, *statements)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def process_module exp
|
43
|
+
_, const_ref, body = exp.shift 3
|
44
|
+
const = const_node_to_symbol const_ref[1]
|
45
|
+
s(:module, const, class_or_module_body(body))
|
46
|
+
end
|
47
|
+
|
48
|
+
def process_class exp
|
49
|
+
_, const_ref, parent, body = exp.shift 4
|
50
|
+
const = const_node_to_symbol const_ref[1]
|
51
|
+
parent = process(parent)
|
52
|
+
s(:class, const, parent, class_or_module_body(body))
|
53
|
+
end
|
54
|
+
|
55
|
+
def process_bodystmt exp
|
56
|
+
_, body, _, _, _ = exp.shift 5
|
57
|
+
body = body.
|
58
|
+
map { |sub_exp| process(sub_exp) }.
|
59
|
+
reject { |sub_exp| sub_exp.sexp_type == :void_stmt }
|
60
|
+
s(:scope, s(:block, *body))
|
61
|
+
end
|
62
|
+
|
63
|
+
def process_var_ref exp
|
64
|
+
_, contents = exp.shift 2
|
65
|
+
process(contents)
|
66
|
+
end
|
67
|
+
|
68
|
+
def process_var_field exp
|
69
|
+
_, contents = exp.shift 2
|
70
|
+
process(contents)
|
71
|
+
end
|
72
|
+
|
73
|
+
def process_const_path_ref exp
|
74
|
+
_, left, right = exp.shift 3
|
75
|
+
s(:colon2, process(left), const_node_to_symbol(right))
|
76
|
+
end
|
77
|
+
|
78
|
+
def process_top_const_ref exp
|
79
|
+
_, ref = exp.shift 2
|
80
|
+
s(:colon3, const_node_to_symbol(ref))
|
81
|
+
end
|
82
|
+
|
83
|
+
def process_paren exp
|
84
|
+
_, body = exp.shift 2
|
85
|
+
process(body)
|
86
|
+
end
|
87
|
+
|
88
|
+
def process_at_int exp
|
89
|
+
_, val, _ = exp.shift 3
|
90
|
+
s(:lit, val.to_i)
|
91
|
+
end
|
92
|
+
|
93
|
+
# symbol-like sexps
|
94
|
+
def process_at_const exp
|
95
|
+
s(:const, extract_node_symbol(exp))
|
96
|
+
end
|
97
|
+
|
98
|
+
def process_at_gvar exp
|
99
|
+
s(:gvar, extract_node_symbol(exp))
|
100
|
+
end
|
101
|
+
|
102
|
+
def process_at_ivar exp
|
103
|
+
s(:ivar, extract_node_symbol(exp))
|
104
|
+
end
|
105
|
+
|
106
|
+
def process_at_ident exp
|
107
|
+
s(:lvar, extract_node_symbol(exp))
|
108
|
+
end
|
109
|
+
|
110
|
+
def process_at_kw exp
|
111
|
+
sym = extract_node_symbol(exp)
|
112
|
+
if sym == :__FILE__
|
113
|
+
s(:str, "(string)")
|
114
|
+
else
|
115
|
+
s(sym)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def process_at_backref exp
|
120
|
+
_, str, _ = exp.shift 3
|
121
|
+
s(:nth_ref, str[1..-1].to_i)
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def const_node_to_symbol exp
|
127
|
+
assert_type exp, :@const
|
128
|
+
_, ident, _ = exp.shift 3
|
129
|
+
|
130
|
+
ident.to_sym
|
131
|
+
end
|
132
|
+
|
133
|
+
def extract_node_symbol exp
|
134
|
+
_, ident, _ = exp.shift 3
|
135
|
+
|
136
|
+
ident.to_sym
|
137
|
+
end
|
138
|
+
|
139
|
+
def class_or_module_body exp
|
140
|
+
scope = process exp
|
141
|
+
block = scope[1]
|
142
|
+
block.shift
|
143
|
+
if block.length <= 1
|
144
|
+
s(:scope, *block)
|
145
|
+
else
|
146
|
+
s(:scope, s(:block, *block))
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
2
|
+
require 'ruby_parser'
|
3
|
+
|
4
|
+
describe "Using RipperRubyParser and RubyParser" do
|
5
|
+
let :newparser do
|
6
|
+
RipperRubyParser::Parser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
let :oldparser do
|
10
|
+
RubyParser.new
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "for a simple well known program" do
|
14
|
+
let :program do
|
15
|
+
"puts 'Hello World'"
|
16
|
+
end
|
17
|
+
|
18
|
+
it "gives the same result" do
|
19
|
+
original = oldparser.parse program
|
20
|
+
imitation = newparser.parse program
|
21
|
+
|
22
|
+
imitation.must_equal original
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "for a more complex program" do
|
27
|
+
let :program do
|
28
|
+
<<-END
|
29
|
+
module Quux
|
30
|
+
class Foo
|
31
|
+
def bar
|
32
|
+
baz = 3
|
33
|
+
qux baz
|
34
|
+
end
|
35
|
+
def qux it
|
36
|
+
if it == 3
|
37
|
+
[1,2,3].map {|i| 2*i}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
Quux::Foo.new.bar
|
44
|
+
END
|
45
|
+
end
|
46
|
+
|
47
|
+
it "gives the same result" do
|
48
|
+
original = oldparser.parse program
|
49
|
+
imitation = newparser.parse program
|
50
|
+
|
51
|
+
imitation.must_equal original
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
2
|
+
require 'ruby_parser'
|
3
|
+
|
4
|
+
describe "Using RipperRubyParser and RubyParser" do
|
5
|
+
let :newparser do
|
6
|
+
RipperRubyParser::Parser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
let :oldparser do
|
10
|
+
RubyParser.new
|
11
|
+
end
|
12
|
+
|
13
|
+
Dir.glob("lib/**/*.rb").each do |file|
|
14
|
+
describe "for #{file}" do
|
15
|
+
let :program do
|
16
|
+
File.read file
|
17
|
+
end
|
18
|
+
|
19
|
+
it "gives the same result" do
|
20
|
+
original = oldparser.parse program
|
21
|
+
imitation = newparser.parse program
|
22
|
+
|
23
|
+
formatted(imitation).must_equal formatted(original)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path('../test_helper.rb', File.dirname(__FILE__))
|
2
|
+
require 'ruby_parser'
|
3
|
+
|
4
|
+
describe "Using RipperRubyParser and RubyParser" do
|
5
|
+
let :newparser do
|
6
|
+
RipperRubyParser::Parser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
let :oldparser do
|
10
|
+
RubyParser.new
|
11
|
+
end
|
12
|
+
|
13
|
+
Dir.glob("test/**/*.rb").each do |file|
|
14
|
+
describe "for #{file}" do
|
15
|
+
let :program do
|
16
|
+
File.read file
|
17
|
+
end
|
18
|
+
|
19
|
+
it "gives the same result" do
|
20
|
+
# Clone string because ruby_parser destroys it when there's a heredoc
|
21
|
+
# inside.
|
22
|
+
copy = program.clone
|
23
|
+
original = oldparser.parse program
|
24
|
+
imitation = newparser.parse copy
|
25
|
+
|
26
|
+
formatted(imitation).must_equal formatted(original)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
require 'minitest/spec'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
|
8
|
+
require 'ripper_ruby_parser'
|
9
|
+
|
10
|
+
def formatted exp
|
11
|
+
exp.to_s.gsub /\), /, "),\n"
|
12
|
+
end
|