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.
@@ -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