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.
@@ -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 call
7
- s(:call, call[1], call[2], process(parens))
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, _, method = exp.shift 4
12
- s(:call, process(receiver), identifier_node_to_symbol(method), s(:arglist))
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
- ident = identifier_node_to_symbol ident
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, _, method, arguments = exp.shift 5
26
- s(:call,
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 3
34
-
35
- ident = identifier_node_to_symbol ident
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
- _, method = exp.shift 2
42
- s(:call, nil, identifier_node_to_symbol(method), s(:arglist))
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 = identifier_node_to_symbol ident
7
- s(:defn, ident, process(params), method_body(body))
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
- identifier_node_to_symbol(method),
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
- s(:return, arglist[1])
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
- OPERATOR_MAP = {
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
- mapped = OPERATOR_MAP[op]
12
- if mapped
13
- s(mapped, process(left), process(right))
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
- s(:call, process(left), op, s(:arglist, process(right)))
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
- _, _, arg = exp.shift 3
39
+ _, op, arg = exp.shift 3
21
40
  arg = process(arg)
22
- if is_literal? arg
23
- s(:lit, -arg[1])
41
+ mapped = UNARY_OPERATOR_MAP[op]
42
+ if mapped
43
+ s(mapped, arg)
24
44
  else
25
- s(:call, arg, :-@, s(:arglist))
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 = const_node_to_symbol const_ref[1]
45
- s(:module, const, class_or_module_body(body))
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 = const_node_to_symbol const_ref[1]
58
+ const, line = const_ref_to_const_with_line_number const_ref
51
59
  parent = process(parent)
52
- s(:class, const, parent, class_or_module_body(body))
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, _, _, _ = 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))
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), const_node_to_symbol(right))
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, const_node_to_symbol(ref))
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
- process(body)
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, _ = exp.shift 3
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
- s(:const, extract_node_symbol(exp))
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
- s(:gvar, extract_node_symbol(exp))
150
+ make_identifier(:gvar, exp)
100
151
  end
101
152
 
102
153
  def process_at_ivar exp
103
- s(:ivar, extract_node_symbol(exp))
154
+ make_identifier(:ivar, exp)
104
155
  end
105
156
 
106
157
  def process_at_ident exp
107
- s(:lvar, extract_node_symbol(exp))
158
+ make_identifier(:lvar, exp)
108
159
  end
109
160
 
110
161
  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
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, _ = exp.shift 3
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 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
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
@@ -1,3 +1,3 @@
1
1
  module RipperRubyParser
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end