ripper_ruby_parser 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ripper_ruby_parser/commenting_sexp_builder.rb +48 -0
- data/lib/ripper_ruby_parser/parser.rb +4 -3
- data/lib/ripper_ruby_parser/sexp_handlers/arguments.rb +6 -2
- data/lib/ripper_ruby_parser/sexp_handlers/arrays.rb +1 -1
- data/lib/ripper_ruby_parser/sexp_handlers/assignment.rb +72 -19
- data/lib/ripper_ruby_parser/sexp_handlers/blocks.rb +68 -4
- data/lib/ripper_ruby_parser/sexp_handlers/helper_methods.rb +42 -14
- data/lib/ripper_ruby_parser/sexp_handlers/literals.rb +41 -25
- data/lib/ripper_ruby_parser/sexp_handlers/loops.rb +20 -0
- data/lib/ripper_ruby_parser/sexp_handlers/method_calls.rb +17 -21
- data/lib/ripper_ruby_parser/sexp_handlers/methods.rb +28 -4
- data/lib/ripper_ruby_parser/sexp_handlers/operators.rb +39 -10
- data/lib/ripper_ruby_parser/sexp_processor.rb +109 -38
- data/lib/ripper_ruby_parser/version.rb +1 -1
- data/test/end_to_end/comments_test.rb +73 -0
- data/test/end_to_end/comparison_test.rb +60 -0
- data/test/end_to_end/line_numbering_test.rb +63 -0
- data/test/test_helper.rb +16 -4
- data/test/unit/commenting_sexp_builder_test.rb +75 -0
- data/test/unit/parser_test.rb +810 -15
- data/test/unit/sexp_processor_test.rb +23 -5
- metadata +19 -12
@@ -5,6 +5,26 @@ module RipperRubyParser
|
|
5
5
|
_, cond, block = exp.shift 3
|
6
6
|
s(:until, process(cond), handle_statement_list(block), true)
|
7
7
|
end
|
8
|
+
|
9
|
+
def process_until_mod exp
|
10
|
+
_, cond, block = exp.shift 3
|
11
|
+
|
12
|
+
check_at_start = block.sexp_type != :begin
|
13
|
+
|
14
|
+
s(:until, process(cond), process(block), check_at_start)
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_while exp
|
18
|
+
_, cond, block = exp.shift 3
|
19
|
+
s(:while, process(cond), handle_statement_list(block), true)
|
20
|
+
end
|
21
|
+
|
22
|
+
def process_for exp
|
23
|
+
_, var, coll, block = exp.shift 4
|
24
|
+
s(:for, process(coll),
|
25
|
+
s(:lasgn, process(var)[1]),
|
26
|
+
handle_statement_list(block))
|
27
|
+
end
|
8
28
|
end
|
9
29
|
end
|
10
30
|
end
|
@@ -3,43 +3,39 @@ module RipperRubyParser
|
|
3
3
|
module MethodCalls
|
4
4
|
def process_method_add_arg exp
|
5
5
|
_, call, parens = exp.shift 3
|
6
|
-
call = process
|
7
|
-
|
6
|
+
call = process(call)
|
7
|
+
call[3] = process(parens) unless parens.empty?
|
8
|
+
call
|
8
9
|
end
|
9
10
|
|
10
11
|
def process_call exp
|
11
|
-
_, receiver, _,
|
12
|
-
|
12
|
+
_, receiver, _, ident = exp.shift 4
|
13
|
+
with_position_from_node_symbol(ident) {|method|
|
14
|
+
s(:call, process(receiver), method, s(:arglist)) }
|
13
15
|
end
|
14
16
|
|
15
17
|
def process_command exp
|
16
18
|
_, ident, arglist = exp.shift 3
|
17
|
-
|
18
|
-
|
19
|
-
arglist = process arglist
|
20
|
-
|
21
|
-
s(:call, nil, ident, arglist)
|
19
|
+
with_position_from_node_symbol(ident) {|method|
|
20
|
+
s(:call, nil, method, process(arglist)) }
|
22
21
|
end
|
23
22
|
|
24
23
|
def process_command_call exp
|
25
|
-
_, receiver, _,
|
26
|
-
|
27
|
-
process(receiver),
|
28
|
-
identifier_node_to_symbol(method),
|
29
|
-
process(arguments))
|
24
|
+
_, receiver, _, ident, arguments = exp.shift 5
|
25
|
+
with_position_from_node_symbol(ident) {|method|
|
26
|
+
s(:call, process(receiver), method, process(arguments)) }
|
30
27
|
end
|
31
28
|
|
32
29
|
def process_vcall exp
|
33
|
-
_, ident = exp.shift
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
s(:call, nil, ident, s(:arglist))
|
30
|
+
_, ident = exp.shift 2
|
31
|
+
with_position_from_node_symbol(ident) {|method|
|
32
|
+
s(:call, nil, method, s(:arglist)) }
|
38
33
|
end
|
39
34
|
|
40
35
|
def process_fcall exp
|
41
|
-
_,
|
42
|
-
|
36
|
+
_, ident = exp.shift 2
|
37
|
+
with_position_from_node_symbol(ident) {|method|
|
38
|
+
s(:call, nil, method, s(:arglist)) }
|
43
39
|
end
|
44
40
|
end
|
45
41
|
end
|
@@ -3,21 +3,34 @@ module RipperRubyParser
|
|
3
3
|
module Methods
|
4
4
|
def process_def exp
|
5
5
|
_, ident, params, body = exp.shift 4
|
6
|
-
ident =
|
7
|
-
|
6
|
+
ident, pos = extract_node_symbol_with_position ident
|
7
|
+
with_position(pos,
|
8
|
+
s(:defn, ident, process(params), method_body(body)))
|
8
9
|
end
|
9
10
|
|
10
11
|
def process_defs exp
|
11
12
|
_, receiver, _, method, args, body = exp.shift 6
|
12
13
|
s(:defs, process(receiver),
|
13
|
-
|
14
|
+
extract_node_symbol(method),
|
14
15
|
process(args), process(body))
|
15
16
|
end
|
16
17
|
|
17
18
|
def process_return exp
|
18
19
|
_, arglist = exp.shift 2
|
20
|
+
|
19
21
|
arglist = process(arglist)
|
20
|
-
|
22
|
+
args = arglist[1..-1]
|
23
|
+
|
24
|
+
if args.length == 1
|
25
|
+
arg = args[0]
|
26
|
+
if arg.sexp_type == :splat
|
27
|
+
s(:return, s(:svalue, arg))
|
28
|
+
else
|
29
|
+
s(:return, arg)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
s(:return, s(:array, *args))
|
33
|
+
end
|
21
34
|
end
|
22
35
|
|
23
36
|
def process_return0 exp
|
@@ -25,6 +38,17 @@ module RipperRubyParser
|
|
25
38
|
s(:return)
|
26
39
|
end
|
27
40
|
|
41
|
+
def process_yield exp
|
42
|
+
_, arglist = exp.shift 2
|
43
|
+
arglist = process arglist
|
44
|
+
s(:yield, *arglist[1..-1])
|
45
|
+
end
|
46
|
+
|
47
|
+
def process_yield0 exp
|
48
|
+
_ = exp.shift
|
49
|
+
s(:yield)
|
50
|
+
end
|
51
|
+
|
28
52
|
def method_body exp
|
29
53
|
scope = process exp
|
30
54
|
block = scope[1]
|
@@ -1,28 +1,52 @@
|
|
1
1
|
module RipperRubyParser
|
2
2
|
module SexpHandlers
|
3
3
|
module Operators
|
4
|
-
|
4
|
+
BINARY_OPERTOR_MAP = {
|
5
5
|
"&&".to_sym => :and,
|
6
|
-
"||".to_sym => :or
|
6
|
+
"||".to_sym => :or,
|
7
|
+
:and => :and,
|
8
|
+
:or => :or
|
9
|
+
}
|
10
|
+
|
11
|
+
UNARY_OPERATOR_MAP = {
|
12
|
+
:"!" => :not,
|
13
|
+
:not => :not
|
7
14
|
}
|
8
15
|
|
9
16
|
def process_binary exp
|
10
17
|
_, left, op, right = exp.shift 4
|
11
|
-
|
12
|
-
|
13
|
-
|
18
|
+
if op == :=~
|
19
|
+
if left.sexp_type == :regexp_literal
|
20
|
+
s(:match2, process(left), process(right))
|
21
|
+
elsif right.sexp_type == :regexp_literal
|
22
|
+
s(:match3, process(right), process(left))
|
23
|
+
else
|
24
|
+
s(:call, process(left), op, s(:arglist, process(right)))
|
25
|
+
end
|
26
|
+
elsif op == :"!="
|
27
|
+
s(:not, s(:call, process(left), :==, s(:arglist, process(right))))
|
14
28
|
else
|
15
|
-
|
29
|
+
mapped = BINARY_OPERTOR_MAP[op]
|
30
|
+
if mapped
|
31
|
+
s(mapped, process(left), process(right))
|
32
|
+
else
|
33
|
+
s(:call, process(left), op, s(:arglist, process(right)))
|
34
|
+
end
|
16
35
|
end
|
17
36
|
end
|
18
37
|
|
19
38
|
def process_unary exp
|
20
|
-
_,
|
39
|
+
_, op, arg = exp.shift 3
|
21
40
|
arg = process(arg)
|
22
|
-
|
23
|
-
|
41
|
+
mapped = UNARY_OPERATOR_MAP[op]
|
42
|
+
if mapped
|
43
|
+
s(mapped, arg)
|
24
44
|
else
|
25
|
-
|
45
|
+
if is_literal? arg
|
46
|
+
s(:lit, arg[1].send(op))
|
47
|
+
else
|
48
|
+
s(:call, arg, op, s(:arglist))
|
49
|
+
end
|
26
50
|
end
|
27
51
|
end
|
28
52
|
|
@@ -36,6 +60,11 @@ module RipperRubyParser
|
|
36
60
|
s(:dot2, left, right)
|
37
61
|
end
|
38
62
|
end
|
63
|
+
|
64
|
+
def process_ifop exp
|
65
|
+
_, cond, truepart, falsepart = exp.shift 4
|
66
|
+
s(:if, process(cond), process(truepart), process(falsepart))
|
67
|
+
end
|
39
68
|
end
|
40
69
|
end
|
41
70
|
end
|
@@ -7,10 +7,15 @@ module RipperRubyParser
|
|
7
7
|
class SexpProcessor < ::SexpProcessor
|
8
8
|
def initialize
|
9
9
|
super
|
10
|
+
|
10
11
|
# TODO: Find these automatically
|
12
|
+
|
11
13
|
@processors[:@int] = :process_at_int
|
14
|
+
@processors[:@float] = :process_at_float
|
15
|
+
|
12
16
|
@processors[:@const] = :process_at_const
|
13
17
|
@processors[:@ident] = :process_at_ident
|
18
|
+
@processors[:@cvar] = :process_at_cvar
|
14
19
|
@processors[:@gvar] = :process_at_gvar
|
15
20
|
@processors[:@ivar] = :process_at_ivar
|
16
21
|
@processors[:@kw] = :process_at_kw
|
@@ -23,7 +28,9 @@ module RipperRubyParser
|
|
23
28
|
return nil if exp.nil?
|
24
29
|
exp.fix_empty_type
|
25
30
|
|
26
|
-
super
|
31
|
+
result = super
|
32
|
+
trickle_up_line_numbers result
|
33
|
+
trickle_down_line_numbers result
|
27
34
|
end
|
28
35
|
|
29
36
|
include SexpHandlers
|
@@ -41,23 +48,39 @@ module RipperRubyParser
|
|
41
48
|
|
42
49
|
def process_module exp
|
43
50
|
_, const_ref, body = exp.shift 3
|
44
|
-
const =
|
45
|
-
|
51
|
+
const, line = const_ref_to_const_with_line_number const_ref
|
52
|
+
with_line_number(line,
|
53
|
+
s(:module, const, class_or_module_body(body)))
|
46
54
|
end
|
47
55
|
|
48
56
|
def process_class exp
|
49
57
|
_, const_ref, parent, body = exp.shift 4
|
50
|
-
const =
|
58
|
+
const, line = const_ref_to_const_with_line_number const_ref
|
51
59
|
parent = process(parent)
|
52
|
-
|
60
|
+
with_line_number(line,
|
61
|
+
s(:class, const, parent, class_or_module_body(body)))
|
53
62
|
end
|
54
63
|
|
55
64
|
def process_bodystmt exp
|
56
|
-
_, body,
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
65
|
+
_, body, rescue_block, _, ensure_block = exp.shift 5
|
66
|
+
|
67
|
+
body = map_body body
|
68
|
+
|
69
|
+
unless rescue_block or ensure_block
|
70
|
+
return s(:scope, s(:block, *body))
|
71
|
+
end
|
72
|
+
|
73
|
+
body = wrap_in_block(body)
|
74
|
+
|
75
|
+
if rescue_block
|
76
|
+
body = s(:rescue, body, process(rescue_block))
|
77
|
+
end
|
78
|
+
|
79
|
+
if ensure_block
|
80
|
+
body = s(:ensure, body, process(ensure_block))
|
81
|
+
end
|
82
|
+
|
83
|
+
s(:scope, body)
|
61
84
|
end
|
62
85
|
|
63
86
|
def process_var_ref exp
|
@@ -72,68 +95,93 @@ module RipperRubyParser
|
|
72
95
|
|
73
96
|
def process_const_path_ref exp
|
74
97
|
_, left, right = exp.shift 3
|
75
|
-
s(:colon2, process(left),
|
98
|
+
s(:colon2, process(left), extract_node_symbol(right))
|
99
|
+
end
|
100
|
+
|
101
|
+
def process_const_ref exp
|
102
|
+
_, ref = exp.shift 3
|
103
|
+
process(ref)
|
76
104
|
end
|
77
105
|
|
78
106
|
def process_top_const_ref exp
|
79
107
|
_, ref = exp.shift 2
|
80
|
-
s(:colon3,
|
108
|
+
s(:colon3, extract_node_symbol(ref))
|
81
109
|
end
|
82
110
|
|
83
111
|
def process_paren exp
|
84
112
|
_, body = exp.shift 2
|
85
|
-
|
113
|
+
if body.size == 0
|
114
|
+
s()
|
115
|
+
elsif body.first.is_a? Symbol
|
116
|
+
process body
|
117
|
+
else
|
118
|
+
process body[0]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def process_comment exp
|
123
|
+
_, comment, inner = exp.shift 3
|
124
|
+
sexp = process(inner)
|
125
|
+
sexp.comments = comment
|
126
|
+
sexp
|
86
127
|
end
|
87
128
|
|
129
|
+
# number literals
|
88
130
|
def process_at_int exp
|
89
|
-
_, val,
|
90
|
-
s(:lit, val.to_i)
|
131
|
+
_, val, pos = exp.shift 3
|
132
|
+
with_position(pos, s(:lit, val.to_i))
|
133
|
+
end
|
134
|
+
|
135
|
+
def process_at_float exp
|
136
|
+
_, val, pos = exp.shift 3
|
137
|
+
with_position(pos, s(:lit, val.to_f))
|
91
138
|
end
|
92
139
|
|
93
140
|
# symbol-like sexps
|
94
141
|
def process_at_const exp
|
95
|
-
|
142
|
+
make_identifier(:const, exp)
|
143
|
+
end
|
144
|
+
|
145
|
+
def process_at_cvar exp
|
146
|
+
make_identifier(:cvar, exp)
|
96
147
|
end
|
97
148
|
|
98
149
|
def process_at_gvar exp
|
99
|
-
|
150
|
+
make_identifier(:gvar, exp)
|
100
151
|
end
|
101
152
|
|
102
153
|
def process_at_ivar exp
|
103
|
-
|
154
|
+
make_identifier(:ivar, exp)
|
104
155
|
end
|
105
156
|
|
106
157
|
def process_at_ident exp
|
107
|
-
|
158
|
+
make_identifier(:lvar, exp)
|
108
159
|
end
|
109
160
|
|
110
161
|
def process_at_kw exp
|
111
|
-
sym =
|
112
|
-
if sym == :__FILE__
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
162
|
+
sym, pos = extract_node_symbol_with_position(exp)
|
163
|
+
result = if sym == :__FILE__
|
164
|
+
s(:str, "(string)")
|
165
|
+
else
|
166
|
+
s(sym)
|
167
|
+
end
|
168
|
+
with_position(pos, result)
|
117
169
|
end
|
118
170
|
|
119
171
|
def process_at_backref exp
|
120
|
-
_, str,
|
121
|
-
s(:nth_ref, str[1..-1].to_i)
|
172
|
+
_, str, pos = exp.shift 3
|
173
|
+
with_position(pos, s(:nth_ref, str[1..-1].to_i))
|
122
174
|
end
|
123
175
|
|
124
176
|
private
|
125
177
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
def extract_node_symbol exp
|
134
|
-
_, ident, _ = exp.shift 3
|
135
|
-
|
136
|
-
ident.to_sym
|
178
|
+
def const_ref_to_const_with_line_number const_ref
|
179
|
+
const = process(const_ref)
|
180
|
+
line = const.line
|
181
|
+
if const.sexp_type == :const
|
182
|
+
const = const[1]
|
183
|
+
end
|
184
|
+
return const, line
|
137
185
|
end
|
138
186
|
|
139
187
|
def class_or_module_body exp
|
@@ -146,5 +194,28 @@ module RipperRubyParser
|
|
146
194
|
s(:scope, s(:block, *block))
|
147
195
|
end
|
148
196
|
end
|
197
|
+
|
198
|
+
def make_identifier(type, exp)
|
199
|
+
with_position_from_node_symbol(exp) {|ident|
|
200
|
+
s(type, ident) }
|
201
|
+
end
|
202
|
+
|
203
|
+
def trickle_up_line_numbers exp
|
204
|
+
exp.each do |sub_exp|
|
205
|
+
if sub_exp.is_a? Sexp
|
206
|
+
trickle_up_line_numbers sub_exp
|
207
|
+
exp.line ||= sub_exp.line
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def trickle_down_line_numbers exp
|
213
|
+
exp.each do |sub_exp|
|
214
|
+
if sub_exp.is_a? Sexp
|
215
|
+
sub_exp.line ||= exp.line
|
216
|
+
trickle_down_line_numbers sub_exp
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
149
220
|
end
|
150
221
|
end
|