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.
@@ -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,3 @@
1
+ module RipperRubyParser
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,5 @@
1
+ require 'ripper_ruby_parser/version'
2
+ require 'ripper_ruby_parser/parser'
3
+
4
+ module RipperRubyParser
5
+ 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
+
@@ -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