ripper_ruby_parser 0.0.1 → 0.0.2
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/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
|