parser 1.1.0 → 1.2.0

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.
Files changed (48) hide show
  1. checksums.yaml +7 -7
  2. data/.gitignore +0 -1
  3. data/README.md +4 -2
  4. data/bin/{parse → ruby-parse} +2 -2
  5. data/bin/ruby-rewrite +6 -0
  6. data/{AST_FORMAT.md → doc/AST_FORMAT.md} +45 -29
  7. data/doc/CUSTOMIZATION.md +37 -0
  8. data/doc/INTERNALS.md +21 -0
  9. data/lib/parser.rb +14 -3
  10. data/lib/parser/ast/node.rb +6 -0
  11. data/lib/parser/ast/processor.rb +216 -0
  12. data/lib/parser/builders/default.rb +613 -215
  13. data/lib/parser/compatibility/slop.rb +12 -0
  14. data/lib/parser/lexer.rl +30 -10
  15. data/lib/parser/lexer/explanation.rb +1 -1
  16. data/lib/parser/lexer/literal.rb +5 -6
  17. data/lib/parser/ruby18.y +31 -24
  18. data/lib/parser/ruby19.y +26 -19
  19. data/lib/parser/ruby20.y +27 -20
  20. data/lib/parser/ruby21.y +27 -20
  21. data/lib/parser/runner.rb +198 -0
  22. data/lib/parser/runner/ruby_parse.rb +87 -0
  23. data/lib/parser/runner/ruby_rewrite.rb +13 -0
  24. data/lib/parser/source/buffer.rb +1 -0
  25. data/lib/parser/source/map.rb +20 -0
  26. data/lib/parser/source/map/block.rb +16 -0
  27. data/lib/parser/source/map/collection.rb +16 -0
  28. data/lib/parser/source/map/condition.rb +19 -0
  29. data/lib/parser/source/map/constant.rb +27 -0
  30. data/lib/parser/source/map/definition.rb +21 -0
  31. data/lib/parser/source/map/for.rb +17 -0
  32. data/lib/parser/source/map/keyword.rb +18 -0
  33. data/lib/parser/source/map/rescue_body.rb +19 -0
  34. data/lib/parser/source/map/send.rb +29 -0
  35. data/lib/parser/source/map/ternary.rb +16 -0
  36. data/lib/parser/source/map/variable.rb +26 -0
  37. data/lib/parser/source/range.rb +25 -24
  38. data/lib/parser/version.rb +3 -0
  39. data/parser.gemspec +4 -2
  40. data/test/parse_helper.rb +13 -10
  41. data/test/test_lexer.rb +32 -11
  42. data/test/test_parse_helper.rb +1 -0
  43. data/test/test_parser.rb +176 -128
  44. data/test/test_source_range.rb +18 -6
  45. metadata +161 -91
  46. data/bin/benchmark +0 -47
  47. data/bin/explain-parse +0 -14
  48. data/lib/parser/source/map/variable_assignment.rb +0 -15
@@ -9,85 +9,128 @@ module Parser
9
9
 
10
10
  # Singletons
11
11
 
12
- def nil(token); t(token, :nil); end
13
- def true(token); t(token, :true); end
14
- def false(token); t(token, :false); end
12
+ def nil(nil_t)
13
+ n0(:nil,
14
+ token_map(nil_t))
15
+ end
16
+
17
+ def true(true_t)
18
+ n0(:true,
19
+ token_map(true_t))
20
+ end
21
+
22
+ def false(false_t)
23
+ n0(:false,
24
+ token_map(false_t))
25
+ end
15
26
 
16
27
  # Numerics
17
28
 
18
- def integer(token, negate=false)
19
- val = value(token)
29
+ def integer(integer_t, negate=false)
30
+ val = value(integer_t)
20
31
  val = -val if negate
21
32
 
22
- t(token, :int, val)
33
+ n(:int, [ val ],
34
+ numeric_map(integer_t, negate))
23
35
  end
24
36
 
25
- def __LINE__(token)
26
- t(token, :__LINE__)
37
+ def __LINE__(__LINE__t)
38
+ n0(:__LINE__,
39
+ token_map(__LINE__t))
27
40
  end
28
41
 
29
- def float(token, negate=false)
30
- val = value(token)
42
+ def float(float_t, negate=false)
43
+ val = value(float_t)
31
44
  val = -val if negate
32
45
 
33
- t(token, :float, val)
46
+ n(:float, [ val ],
47
+ numeric_map(float_t, negate))
34
48
  end
35
49
 
36
50
  # Strings
37
51
 
38
- def string(token)
39
- t(token, :str, value(token))
52
+ def string(string_t)
53
+ n(:str, [ value(string_t) ],
54
+ string_part_map(string_t))
40
55
  end
41
56
 
42
57
  def string_compose(begin_t, parts, end_t)
43
58
  if collapse_string_parts?(parts)
44
- parts.first
59
+ if begin_t.nil? && end_t.nil?
60
+ parts.first
61
+ else
62
+ n(:str, parts.first.children,
63
+ collection_map(begin_t, parts, end_t))
64
+ end
45
65
  else
46
- s(:dstr, *parts)
66
+ n(:dstr, [ *parts ],
67
+ collection_map(begin_t, parts, end_t))
47
68
  end
48
69
  end
49
70
 
50
- def __FILE__(token)
51
- t(token, :__FILE__)
71
+ def __FILE__(__FILE__t)
72
+ n0(:__FILE__,
73
+ token_map(__FILE__t))
52
74
  end
53
75
 
54
76
  # Symbols
55
77
 
56
- def symbol(token)
57
- t(token, :sym, value(token).to_sym)
78
+ def symbol(symbol_t)
79
+ n(:sym, [ value(symbol_t).to_sym ],
80
+ unquoted_symbol_map(symbol_t))
58
81
  end
59
82
 
60
83
  def symbol_compose(begin_t, parts, end_t)
61
- s(:dsym, *parts)
84
+ if collapse_string_parts?(parts)
85
+ str = parts.first
86
+
87
+ n(:sym, [ str.children.first.to_sym ],
88
+ collection_map(begin_t, str.src.expression, end_t))
89
+ elsif @parser.version == 18 && parts.empty?
90
+ diagnostic(:error, ERRORS[:empty_symbol], loc(begin_t).join(loc(end_t)))
91
+ else
92
+ n(:dsym, [ *parts ],
93
+ collection_map(begin_t, parts, end_t))
94
+ end
62
95
  end
63
96
 
64
97
  # Executable strings
65
98
 
66
99
  def xstring_compose(begin_t, parts, end_t)
67
- s(:xstr, *parts)
100
+ n(:xstr, [ *parts ],
101
+ collection_map(begin_t, parts, end_t))
68
102
  end
69
103
 
70
104
  # Regular expressions
71
105
 
72
- def regexp_options(token)
73
- t(token, :regopt, *value(token).each_char.sort.uniq.map(&:to_sym))
106
+ def regexp_options(regopt_t)
107
+ options = value(regopt_t).
108
+ each_char.sort.uniq.
109
+ map(&:to_sym)
110
+
111
+ n(:regopt, options,
112
+ token_map(regopt_t))
74
113
  end
75
114
 
76
115
  def regexp_compose(begin_t, parts, end_t, options)
77
- s(:regexp, *(parts << options))
116
+ n(:regexp, (parts << options),
117
+ regexp_map(begin_t, end_t, options))
78
118
  end
79
119
 
80
120
  # Arrays
81
121
 
82
122
  def array(begin_t, elements, end_t)
83
- s(:array, *elements)
123
+ n(:array, elements,
124
+ collection_map(begin_t, elements, end_t))
84
125
  end
85
126
 
86
127
  def splat(star_t, arg=nil)
87
128
  if arg.nil?
88
- s(:splat)
129
+ n0(:splat,
130
+ unary_op_map(star_t))
89
131
  else
90
- s(:splat, arg)
132
+ n(:splat, [ arg ],
133
+ unary_op_map(star_t, arg))
91
134
  end
92
135
  end
93
136
 
@@ -95,12 +138,14 @@ module Parser
95
138
  if collapse_string_parts?(parts)
96
139
  parts.first
97
140
  else
98
- s(:dstr, *parts)
141
+ n(:dstr, [ *parts ],
142
+ collection_map(nil, parts, nil))
99
143
  end
100
144
  end
101
145
 
102
146
  def words_compose(begin_t, parts, end_t)
103
- s(:array, *parts)
147
+ n(:array, [ *parts ],
148
+ collection_map(begin_t, parts, end_t))
104
149
  end
105
150
 
106
151
  def symbols_compose(begin_t, parts, end_t)
@@ -116,82 +161,104 @@ module Parser
116
161
  end
117
162
  end
118
163
 
119
- s(:array, *parts)
164
+ n(:array, [ *parts ],
165
+ collection_map(begin_t, parts, end_t))
120
166
  end
121
167
 
122
168
  # Hashes
123
169
 
124
170
  def pair(key, assoc_t, value)
125
- s(:pair, key, value)
171
+ n(:pair, [ key, value ],
172
+ binary_op_map(key, assoc_t, value))
126
173
  end
127
174
 
128
175
  def pair_list_18(list)
129
176
  if list.size % 2 != 0
130
- # TODO better location info here
131
177
  message = ERRORS[:odd_hash]
132
178
  diagnostic :error, message, list.last.src.expression
133
179
  else
134
180
  list.
135
181
  each_slice(2).map do |key, value|
136
- s(:pair, key, value)
182
+ n(:pair, [ key, value ],
183
+ binary_op_map(key, nil, value))
137
184
  end
138
185
  end
139
186
  end
140
187
 
141
188
  def associate(begin_t, pairs, end_t)
142
- s(:hash, *pairs)
189
+ n(:hash, [ *pairs ],
190
+ collection_map(begin_t, pairs, end_t))
143
191
  end
144
192
 
145
193
  def kwsplat(dstar_t, arg)
146
- s(:kwsplat, arg)
194
+ n(:kwsplat, [ arg ],
195
+ unary_op_map(dstar_t, arg))
147
196
  end
148
197
 
149
198
  # Ranges
150
199
 
151
- def range_inclusive(lhs, token, rhs)
152
- s(:irange, lhs, rhs)
200
+ def range_inclusive(lhs, dot2_t, rhs)
201
+ n(:irange, [ lhs, rhs ],
202
+ binary_op_map(lhs, dot2_t, rhs))
153
203
  end
154
204
 
155
- def range_exclusive(lhs, token, rhs)
156
- s(:erange, lhs, rhs)
205
+ def range_exclusive(lhs, dot3_t, rhs)
206
+ n(:erange, [ lhs, rhs ],
207
+ binary_op_map(lhs, dot3_t, rhs))
157
208
  end
158
209
 
159
210
  #
160
- # Expression grouping
211
+ # Access
161
212
  #
162
213
 
163
- def parenthesize(begin_t, expr, end_t)
164
- if expr.nil?
165
- s(:nil)
166
- else
167
- expr
168
- end
214
+ def self(token)
215
+ n0(:self,
216
+ token_map(token))
169
217
  end
170
218
 
171
- #
172
- # Access
173
- #
219
+ def ident(token)
220
+ n(:ident, [ value(token).to_sym ],
221
+ variable_map(token))
222
+ end
223
+
224
+ def ivar(token)
225
+ n(:ivar, [ value(token).to_sym ],
226
+ variable_map(token))
227
+ end
174
228
 
175
- def self(token); t(token, :self); end
229
+ def gvar(token)
230
+ n(:gvar, [ value(token).to_sym ],
231
+ variable_map(token))
232
+ end
233
+
234
+ def cvar(token)
235
+ n(:cvar, [ value(token).to_sym ],
236
+ variable_map(token))
237
+ end
176
238
 
177
- def ident(token); t(token, :ident, value(token).to_sym); end
178
- def ivar(token); t(token, :ivar, value(token).to_sym); end
179
- def gvar(token); t(token, :gvar, value(token).to_sym); end
180
- def cvar(token); t(token, :cvar, value(token).to_sym); end
239
+ def back_ref(token)
240
+ n(:back_ref, [ value(token).to_sym ],
241
+ token_map(token))
242
+ end
181
243
 
182
- def back_ref(token); t(token, :back_ref, value(token).to_sym); end
183
- def nth_ref(token); t(token, :nth_ref, value(token)); end
244
+ def nth_ref(token)
245
+ n(:nth_ref, [ value(token) ],
246
+ token_map(token))
247
+ end
184
248
 
185
249
  def accessible(node)
186
250
  case node.type
187
251
  when :__FILE__
188
- node.updated(:str, [ node.src.expression.source_buffer.name ])
252
+ n(:str, [ node.src.expression.source_buffer.name ],
253
+ node.src)
189
254
 
190
255
  when :__LINE__
191
- node.updated(:int, [ node.src.expression.line ])
256
+ n(:int, [ node.src.expression.line ],
257
+ node.src)
192
258
 
193
259
  when :__ENCODING__
194
- s(:const, s(:const, nil, :Encoding), :UTF_8)
260
+ n(:const, [ n(:const, [ nil, :Encoding], nil), :UTF_8 ],
261
+ node.src)
195
262
 
196
263
  when :ident
197
264
  name, = *node
@@ -200,7 +267,8 @@ module Parser
200
267
  node.updated(:lvar)
201
268
  else
202
269
  name, = *node
203
- node.updated(:send, [ nil, name ])
270
+ n(:send, [ nil, name ],
271
+ var_send_map(node))
204
272
  end
205
273
 
206
274
  else
@@ -208,20 +276,26 @@ module Parser
208
276
  end
209
277
  end
210
278
 
211
- def const(token)
212
- t(token, :const, nil, value(token).to_sym)
279
+ def const(name_t)
280
+ n(:const, [ nil, value(name_t).to_sym ],
281
+ constant_map(nil, nil, name_t))
213
282
  end
214
283
 
215
- def const_global(t_colon3, token)
216
- s(:const, s(:cbase), value(token).to_sym)
284
+ def const_global(t_colon3, name_t)
285
+ cbase = n0(:cbase, token_map(t_colon3))
286
+
287
+ n(:const, [ cbase, value(name_t).to_sym ],
288
+ constant_map(cbase, t_colon3, name_t))
217
289
  end
218
290
 
219
- def const_fetch(scope, t_colon2, token)
220
- s(:const, scope, value(token).to_sym)
291
+ def const_fetch(scope, t_colon2, name_t)
292
+ n(:const, [ scope, value(name_t).to_sym ],
293
+ constant_map(scope, t_colon2, name_t))
221
294
  end
222
295
 
223
- def __ENCODING__(token)
224
- t(token, :__ENCODING__)
296
+ def __ENCODING__(__ENCODING__t)
297
+ n0(:__ENCODING__,
298
+ token_map(__ENCODING__t))
225
299
  end
226
300
 
227
301
  #
@@ -271,35 +345,31 @@ module Parser
271
345
  end
272
346
  end
273
347
 
274
- def assign(lhs, token, rhs)
275
- case lhs.type
276
- when :lvasgn, :masgn, :gvasgn, :ivasgn, :cvdecl,
277
- :cvasgn, :cdecl,
278
- :send
279
- lhs << rhs
280
-
281
- when :const
282
- (lhs << rhs).updated(:cdecl)
283
-
284
- else
285
- raise NotImplementedError, "build assign #{lhs.inspect}"
286
- end
348
+ def assign(lhs, eql_t, rhs)
349
+ (lhs << rhs).updated(nil, nil,
350
+ :source_map => lhs.src.
351
+ with_operator(loc(eql_t)).
352
+ with_expression(join_exprs(lhs, rhs)))
287
353
  end
288
354
 
289
- def op_assign(lhs, operator_t, rhs)
355
+ def op_assign(lhs, op_t, rhs)
290
356
  case lhs.type
291
357
  when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :cvdecl,
292
358
  :cdecl,
293
359
  :send
294
- operator = value(operator_t)[0..-1].to_sym
360
+
361
+ operator = value(op_t)[0..-1].to_sym
362
+ source_map = lhs.src.
363
+ with_operator(loc(op_t)).
364
+ with_expression(join_exprs(lhs, rhs))
295
365
 
296
366
  case operator
297
367
  when :'&&'
298
- s(:and_asgn, lhs, rhs)
368
+ n(:and_asgn, [ lhs, rhs ], source_map)
299
369
  when :'||'
300
- s(:or_asgn, lhs, rhs)
370
+ n(:or_asgn, [ lhs, rhs ], source_map)
301
371
  else
302
- s(:op_asgn, lhs, operator, rhs)
372
+ n(:op_asgn, [ lhs, operator, rhs ], source_map)
303
373
  end
304
374
 
305
375
  when :back_ref, :nth_ref
@@ -312,11 +382,13 @@ module Parser
312
382
  end
313
383
 
314
384
  def multi_lhs(begin_t, items, end_t)
315
- s(:mlhs, *items)
385
+ n(:mlhs, [ *items ],
386
+ collection_map(begin_t, items, end_t))
316
387
  end
317
388
 
318
389
  def multi_assign(lhs, eql_t, rhs)
319
- s(:masgn, lhs, rhs)
390
+ n(:masgn, [ lhs, rhs ],
391
+ binary_op_map(lhs, eql_t, rhs))
320
392
  end
321
393
 
322
394
  #
@@ -326,68 +398,56 @@ module Parser
326
398
  def def_class(class_t, name,
327
399
  lt_t, superclass,
328
400
  body, end_t)
329
- s(:class, name, superclass, body)
401
+ n(:class, [ name, superclass, body ],
402
+ definition_map(class_t, lt_t, nil, end_t))
330
403
  end
331
404
 
332
405
  def def_sclass(class_t, lshft_t, expr,
333
406
  body, end_t)
334
- s(:sclass, expr, body)
407
+ n(:sclass, [ expr, body ],
408
+ definition_map(class_t, lshft_t, nil, end_t))
335
409
  end
336
410
 
337
411
  def def_module(module_t, name,
338
412
  body, end_t)
339
- s(:module, name, body)
413
+ n(:module, [ name, body ],
414
+ definition_map(module_t, nil, nil, end_t))
340
415
  end
341
416
 
342
417
  #
343
418
  # Method (un)definition
344
419
  #
345
420
 
346
- def def_method(def_t, name, args,
421
+ def def_method(def_t, name_t, args,
347
422
  body, end_t, comments)
348
- s(:def, value(name).to_sym, args, body)
423
+ n(:def, [ value(name_t).to_sym, args, body ],
424
+ definition_map(def_t, nil, name_t, end_t))
349
425
  end
350
426
 
351
427
  def def_singleton(def_t, definee, dot_t,
352
- name, args,
428
+ name_t, args,
353
429
  body, end_t, comments)
354
430
  case definee.type
355
431
  when :int, :str, :dstr, :sym, :dsym,
356
432
  :regexp, :array, :hash
357
433
 
358
434
  message = ERRORS[:singleton_literal]
359
- diagnostic :error, message, nil # TODO definee.src.expression
435
+ diagnostic :error, message, definee.src.expression
360
436
 
361
437
  else
362
- s(:defs, definee, value(name).to_sym, args, body)
438
+ n(:defs, [ definee, value(name_t).to_sym, args, body ],
439
+ definition_map(def_t, dot_t, name_t, end_t))
363
440
  end
364
441
  end
365
442
 
366
- def undef_method(token, names)
367
- s(:undef, *names)
368
- end
369
-
370
- #
371
- # Aliasing
372
- #
373
-
374
- def alias(token, to, from)
375
- t(token, :alias, to, from)
443
+ def undef_method(undef_t, names)
444
+ n(:undef, [ *names ],
445
+ keyword_map(undef_t, nil, names, nil))
376
446
  end
377
447
 
378
- def keyword_cmd(type, token, lparen_t=nil, args=[], rparen_t=nil)
379
- case type
380
- when :return,
381
- :break, :next, :redo,
382
- :retry,
383
- :super, :zsuper, :yield,
384
- :defined?
385
-
386
- t(token, type, *args)
387
-
388
- else
389
- raise NotImplementedError, "build_keyword_cmd #{type} #{args.inspect}"
390
- end
448
+ def alias(alias_t, to, from)
449
+ n(:alias, [ to, from ],
450
+ keyword_map(alias_t, nil, [to, from], nil))
391
451
  end
392
452
 
393
453
  #
@@ -395,47 +455,60 @@ module Parser
395
455
  #
396
456
 
397
457
  def args(begin_t, args, end_t)
398
- s(:args, *check_duplicate_args(args))
458
+ n(:args, [ *check_duplicate_args(args) ],
459
+ collection_map(begin_t, args, end_t))
399
460
  end
400
461
 
401
462
  def arg(name_t)
402
- t(name_t, :arg, value(name_t).to_sym)
463
+ n(:arg, [ value(name_t).to_sym ],
464
+ variable_map(name_t))
403
465
  end
404
466
 
405
467
  def optarg(name_t, eql_t, value)
406
- s(:optarg, value(name_t).to_sym, value)
468
+ n(:optarg, [ value(name_t).to_sym, value ],
469
+ variable_map(name_t).
470
+ with_operator(loc(eql_t)).
471
+ with_expression(loc(name_t).join(value.src.expression)))
407
472
  end
408
473
 
409
474
  def restarg(star_t, name_t=nil)
410
475
  if name_t
411
- s(:restarg, value(name_t).to_sym)
476
+ n(:restarg, [ value(name_t).to_sym ],
477
+ arg_prefix_map(star_t, name_t))
412
478
  else
413
- t(star_t, :restarg)
479
+ n0(:restarg,
480
+ arg_prefix_map(star_t))
414
481
  end
415
482
  end
416
483
 
417
484
  def kwarg(name_t)
418
- s(:kwarg, value(name_t).to_sym)
485
+ n(:kwarg, [ value(name_t).to_sym ],
486
+ kwarg_map(name_t))
419
487
  end
420
488
 
421
489
  def kwoptarg(name_t, value)
422
- s(:kwoptarg, value(name_t).to_sym, value)
490
+ n(:kwoptarg, [ value(name_t).to_sym, value ],
491
+ kwarg_map(name_t, value))
423
492
  end
424
493
 
425
494
  def kwrestarg(dstar_t, name_t=nil)
426
495
  if name_t
427
- s(:kwrestarg, value(name_t).to_sym)
496
+ n(:kwrestarg, [ value(name_t).to_sym ],
497
+ arg_prefix_map(dstar_t, name_t))
428
498
  else
429
- t(dstar_t, :kwrestarg)
499
+ n0(:kwrestarg,
500
+ arg_prefix_map(dstar_t))
430
501
  end
431
502
  end
432
503
 
433
- def shadowarg(token)
434
- s(:shadowarg, value(token).to_sym)
504
+ def shadowarg(name_t)
505
+ n(:shadowarg, [ value(name_t).to_sym ],
506
+ variable_map(name_t))
435
507
  end
436
508
 
437
- def blockarg(amper_t, token)
438
- s(:blockarg, value(token).to_sym)
509
+ def blockarg(amper_t, name_t)
510
+ n(:blockarg, [ value(name_t).to_sym ],
511
+ arg_prefix_map(amper_t, name_t))
439
512
  end
440
513
 
441
514
  # Ruby 1.8 block arguments
@@ -444,17 +517,19 @@ module Parser
444
517
  if expr.type == :lvasgn
445
518
  expr.updated(:arg)
446
519
  else
447
- s(:arg_expr, expr)
520
+ n(:arg_expr, [ expr ],
521
+ expr.src)
448
522
  end
449
523
  end
450
524
 
451
525
  def restarg_expr(star_t, expr=nil)
452
526
  if expr.nil?
453
- t(star_t, :restarg)
527
+ n0(:restarg, token_map(star_t))
454
528
  elsif expr.type == :lvasgn
455
529
  expr.updated(:restarg)
456
530
  else
457
- s(:restarg_expr, expr)
531
+ n(:restarg_expr, [ expr ],
532
+ expr.src)
458
533
  end
459
534
  end
460
535
 
@@ -462,7 +537,8 @@ module Parser
462
537
  if expr.type == :lvasgn
463
538
  expr.updated(:blockarg)
464
539
  else
465
- s(:blockarg_expr, expr)
540
+ n(:blockarg_expr, [ expr ],
541
+ expr.src)
466
542
  end
467
543
  end
468
544
 
@@ -471,16 +547,19 @@ module Parser
471
547
  #
472
548
 
473
549
  def call_method(receiver, dot_t, selector_t,
474
- begin_t=nil, args=[], end_t=nil)
550
+ lparen_t=nil, args=[], rparen_t=nil)
475
551
  if selector_t.nil?
476
- s(:send, receiver, :call, *args)
552
+ n(:send, [ receiver, :call, *args ],
553
+ send_map(receiver, nil, lparen_t, args, rparen_t))
477
554
  else
478
- s(:send, receiver, value(selector_t).to_sym, *args)
555
+ n(:send, [ receiver, value(selector_t).to_sym, *args ],
556
+ send_map(receiver, selector_t, lparen_t, args, rparen_t))
479
557
  end
480
558
  end
481
559
 
482
560
  def call_lambda(lambda_t)
483
- s(:send, nil, :lambda)
561
+ n(:send, [ nil, :lambda ],
562
+ send_map(nil, lambda_t))
484
563
  end
485
564
 
486
565
  def block(method_call, begin_t, args, body, end_t)
@@ -488,68 +567,83 @@ module Parser
488
567
  last_arg = call_args.last
489
568
 
490
569
  if last_arg && last_arg.type == :block_pass
491
- # TODO uncomment when source maps are ready
492
- # diagnostic :error, :block_and_blockarg,
493
- # last_arg.src.expression
494
-
495
570
  diagnostic :error, ERRORS[:block_and_blockarg],
496
- last_arg.children.last.src.expression
571
+ last_arg.src.expression
497
572
  end
498
573
 
499
- s(:block, method_call, args, body)
574
+ n(:block, [ method_call, args, body ],
575
+ block_map(method_call.src.expression, begin_t, end_t))
500
576
  end
501
577
 
502
578
  def block_pass(amper_t, arg)
503
- s(:block_pass, arg)
579
+ n(:block_pass, [ arg ],
580
+ unary_op_map(amper_t, arg))
504
581
  end
505
582
 
506
583
  def attr_asgn(receiver, dot_t, selector_t)
507
584
  method_name = (value(selector_t) + '=').to_sym
508
585
 
509
586
  # Incomplete method call.
510
- s(:send, receiver, method_name)
587
+ n(:send, [ receiver, method_name ],
588
+ send_map(receiver, selector_t))
511
589
  end
512
590
 
513
591
  def index(receiver, lbrack_t, indexes, rbrack_t)
514
- s(:send, receiver, :[], *indexes)
592
+ n(:send, [ receiver, :[], *indexes ],
593
+ send_index_map(receiver, lbrack_t, rbrack_t))
515
594
  end
516
595
 
517
596
  def index_asgn(receiver, lbrack_t, indexes, rbrack_t)
518
597
  # Incomplete method call.
519
- s(:send, receiver, :[]=, *indexes)
598
+ n(:send, [ receiver, :[]=, *indexes ],
599
+ send_index_map(receiver, lbrack_t, rbrack_t))
520
600
  end
521
601
 
522
- def binary_op(receiver, token, arg)
602
+ def binary_op(receiver, operator_t, arg)
603
+ source_map = send_binary_op_map(receiver, operator_t, arg)
604
+
523
605
  if @parser.version == 18
524
- if value(token) == '!='
525
- return s(:not, s(:send, receiver, :==, arg))
526
- elsif value(token) == '!~'
527
- return s(:not, s(:send, receiver, :=~, arg))
606
+ operator = value(operator_t)
607
+
608
+ if operator == '!='
609
+ method_call = n(:send, [ receiver, :==, arg ], source_map)
610
+ elsif operator == '!~'
611
+ method_call = n(:send, [ receiver, :=~, arg ], source_map)
612
+ end
613
+
614
+ if %w(!= !~).include?(operator)
615
+ return n(:not, [ method_call ],
616
+ expr_map(source_map.expression))
528
617
  end
529
618
  end
530
619
 
531
- s(:send, receiver, value(token).to_sym, arg)
620
+ n(:send, [ receiver, value(operator_t).to_sym, arg ],
621
+ source_map)
532
622
  end
533
623
 
534
- def unary_op(token, receiver)
535
- case value(token)
624
+ def unary_op(op_t, receiver)
625
+ case value(op_t)
536
626
  when '+', '-'
537
- method = value(token) + '@'
627
+ method = value(op_t) + '@'
538
628
  else
539
- method = value(token)
629
+ method = value(op_t)
540
630
  end
541
631
 
542
- s(:send, receiver, method.to_sym)
632
+ n(:send, [ receiver, method.to_sym ],
633
+ send_unary_op_map(op_t, receiver))
543
634
  end
544
635
 
545
- def not_op(token, receiver=nil)
636
+ def not_op(not_t, receiver=nil)
546
637
  if @parser.version == 18
547
- s(:not, receiver)
638
+ n(:not, [ receiver ],
639
+ unary_op_map(not_t, receiver))
548
640
  else
549
641
  if receiver.nil?
550
- s(:send, s(:nil), :'!')
642
+ n(:send, [ n0(:nil, nil), :'!' ],
643
+ send_unary_op_map(not_t, nil))
551
644
  else
552
- s(:send, receiver, :'!')
645
+ n(:send, [ receiver, :'!' ],
646
+ send_unary_op_map(not_t, receiver))
553
647
  end
554
648
  end
555
649
  end
@@ -560,60 +654,87 @@ module Parser
560
654
 
561
655
  # Logical operations: and, or
562
656
 
563
- def logical_op(type, lhs, token, rhs)
564
- s(type, check_condition(lhs), check_condition(rhs))
657
+ def logical_op(type, lhs, op_t, rhs)
658
+ n(type, [ check_condition(lhs), check_condition(rhs) ],
659
+ binary_op_map(lhs, op_t, rhs))
565
660
  end
566
661
 
567
662
  # Conditionals
568
663
 
569
664
  def condition(cond_t, cond, then_t,
570
665
  if_true, else_t, if_false, end_t)
571
- s(:if, check_condition(cond), if_true, if_false)
666
+ n(:if, [ check_condition(cond), if_true, if_false ],
667
+ condition_map(cond_t, then_t, if_true, else_t, if_false, end_t))
572
668
  end
573
669
 
574
670
  def condition_mod(if_true, if_false, cond_t, cond)
575
- s(:if, check_condition(cond), if_true, if_false)
671
+ n(:if, [ check_condition(cond), if_true, if_false ],
672
+ keyword_mod_map(if_true || if_false, cond_t, cond))
576
673
  end
577
674
 
578
675
  def ternary(cond, question_t, if_true, colon_t, if_false)
579
- s(:if, check_condition(cond), if_true, if_false)
676
+ n(:if, [ check_condition(cond), if_true, if_false ],
677
+ ternary_map(cond, question_t, if_true, colon_t, if_false))
580
678
  end
581
679
 
582
680
  # Case matching
583
681
 
584
682
  def when(when_t, patterns, then_t, body)
585
- s(:when, *(patterns << body))
683
+ children = patterns << body
684
+ n(:when, children,
685
+ keyword_map(when_t, then_t, children, nil))
586
686
  end
587
687
 
588
- def case(case_t, expr, body, end_t)
589
- s(:case, expr, *body)
688
+ def case(case_t, expr, when_bodies, else_t, else_body, end_t)
689
+ n(:case, [ expr, *(when_bodies << else_body)],
690
+ condition_map(case_t, nil, nil, else_t, else_body, end_t))
590
691
  end
591
692
 
592
693
  # Loops
593
694
 
594
- def loop(loop_t, cond, do_t, body, end_t)
595
- s(value(loop_t).to_sym, check_condition(cond), body)
695
+ def loop(type, keyword_t, cond, do_t, body, end_t)
696
+ n(type, [ check_condition(cond), body ],
697
+ keyword_map(keyword_t, do_t, nil, end_t))
596
698
  end
597
699
 
598
- def loop_mod(body, loop_t, cond)
599
- s(value(loop_t).to_sym, check_condition(cond), body)
700
+ def loop_mod(type, body, keyword_t, cond)
701
+ n(type, [ check_condition(cond), body ],
702
+ keyword_mod_map(body, keyword_t, cond))
600
703
  end
601
704
 
602
705
  def for(for_t, iterator, in_t, iteratee,
603
706
  do_t, body, end_t)
604
- s(:for, iterator, iteratee, body)
707
+ n(:for, [ iterator, iteratee, body ],
708
+ for_map(for_t, in_t, do_t, end_t))
605
709
  end
606
710
 
607
- # Exception handling
711
+ # Keywords
608
712
 
609
- def begin(begin_t, body, end_t)
610
- body
713
+ def keyword_cmd(type, keyword_t, lparen_t=nil, args=[], rparen_t=nil)
714
+ n(type, args,
715
+ keyword_map(keyword_t, lparen_t, args, rparen_t))
716
+ end
717
+
718
+ # BEGIN, END
719
+
720
+ def preexe(preexe_t, lbrace_t, compstmt, rbrace_t)
721
+ n(:preexe, [ compstmt ],
722
+ block_map(loc(preexe_t), lbrace_t, rbrace_t))
723
+ end
724
+
725
+ def postexe(postexe_t, lbrace_t, compstmt, rbrace_t)
726
+ n(:postexe, [ compstmt ],
727
+ block_map(loc(postexe_t), lbrace_t, rbrace_t))
611
728
  end
612
729
 
730
+ # Exception handling
731
+
613
732
  def rescue_body(rescue_t,
614
733
  exc_list, assoc_t, exc_var,
615
734
  then_t, compound_stmt)
616
- s(:resbody, exc_list, exc_var, compound_stmt)
735
+ n(:resbody, [ exc_list, exc_var, compound_stmt ],
736
+ rescue_body_map(rescue_t, exc_list, assoc_t,
737
+ exc_var, then_t, compound_stmt))
617
738
  end
618
739
 
619
740
  def begin_body(compound_stmt, rescue_bodies=[],
@@ -621,49 +742,75 @@ module Parser
621
742
  ensure_t=nil, ensure_=nil)
622
743
  if rescue_bodies.any?
623
744
  if else_t
624
- compound_stmt = s(:rescue, compound_stmt,
625
- *(rescue_bodies << else_))
745
+ compound_stmt =
746
+ n(:rescue,
747
+ [ compound_stmt, *(rescue_bodies + [ else_ ]) ],
748
+ eh_keyword_map(compound_stmt, nil, rescue_bodies, else_t, else_))
626
749
  else
627
- compound_stmt = s(:rescue, compound_stmt,
628
- *(rescue_bodies << nil))
750
+ compound_stmt =
751
+ n(:rescue,
752
+ [ compound_stmt, *(rescue_bodies + [ nil ]) ],
753
+ eh_keyword_map(compound_stmt, nil, rescue_bodies, nil, nil))
629
754
  end
630
755
  end
631
756
 
632
757
  if ensure_t
633
- compound_stmt = s(:ensure, compound_stmt, ensure_)
758
+ compound_stmt =
759
+ n(:ensure,
760
+ [ compound_stmt, ensure_ ],
761
+ eh_keyword_map(compound_stmt, ensure_t, [ ensure_ ], nil, nil))
634
762
  end
635
763
 
636
764
  compound_stmt
637
765
  end
638
766
 
767
+ #
768
+ # Expression grouping
769
+ #
770
+
639
771
  def compstmt(statements)
640
772
  case
641
773
  when statements.one?
642
774
  statements.first
643
775
  when statements.none?
644
- s(:nil)
776
+ n0(:nil, expr_map(nil))
645
777
  else
646
- s(:begin, *statements)
778
+ n(:begin, statements,
779
+ collection_map(nil, statements, nil))
647
780
  end
648
781
  end
649
782
 
650
- # BEGIN, END
651
-
652
- def preexe(preexe_t, lbrace_t, compstmt, rbrace_t)
653
- s(:preexe, compstmt)
783
+ def begin(begin_t, body, end_t)
784
+ if body.nil? || synthesized_nil?(body)
785
+ # A nil expression, or a synthesized (nil) from compstmt
786
+ # without any inner statements.
787
+ n0(:nil,
788
+ expr_map(loc(begin_t).join(loc(end_t))))
789
+ elsif body.type == :mlhs ||
790
+ (body.type == :begin &&
791
+ body.src.begin.nil? && body.src.end.nil?)
792
+ # Synthesized (begin) from compstmt "a; b" or (mlhs)
793
+ # from multi_lhs "(a, b) = *foo".
794
+ n(body.type, body.children,
795
+ collection_map(begin_t, body.children, end_t))
796
+ else
797
+ n(:begin, [ body ],
798
+ collection_map(begin_t, [ body ], end_t))
799
+ end
654
800
  end
655
801
 
656
- def postexe(postexe_t, lbrace_t, compstmt, rbrace_t)
657
- s(:postexe, compstmt)
658
- end
802
+ private
659
803
 
660
- protected
804
+ #
805
+ # VERIFICATION
806
+ #
661
807
 
662
808
  def check_condition(cond)
663
809
  if cond.type == :masgn
664
- # TODO source maps
665
810
  diagnostic :error, ERRORS[:masgn_as_condition],
666
- nil #cond.src.expression
811
+ cond.src.expression
812
+ elsif cond.type == :begin
813
+ check_condition(cond.children.last)
667
814
  end
668
815
 
669
816
  cond
@@ -684,9 +831,8 @@ module Parser
684
831
  if that_arg.nil?
685
832
  map[this_name] = this_arg
686
833
  elsif arg_name_collides?(this_name, that_name)
687
- # TODO reenable when source maps are done
688
834
  diagnostic :error, ERRORS[:duplicate_argument],
689
- nil # this_arg.src.expression, [ that_arg.src.expression ]
835
+ this_arg.src.name, [ that_arg.src.name ]
690
836
  end
691
837
 
692
838
  when :mlhs
@@ -710,31 +856,283 @@ module Parser
710
856
  end
711
857
  end
712
858
 
713
- def collapse_string_parts?(parts)
714
- parts.one? &&
715
- [:str, :dstr].include?(parts.first.type)
859
+ #
860
+ # SOURCE MAPS
861
+ #
862
+
863
+ def n(type, children, map)
864
+ AST::Node.new(type, children, :source_map => map)
716
865
  end
717
866
 
718
- def t(token, type, *args)
719
- s(type, *(args << { :source_map => Source::Map.new(location(token)) }))
867
+ def n0(type, map)
868
+ n(type, [], map)
720
869
  end
721
870
 
722
- def value(token)
723
- token[0]
871
+ def join_exprs(left_expr, right_expr)
872
+ left_expr.src.expression.
873
+ join(right_expr.src.expression)
874
+ end
875
+
876
+ def token_map(token)
877
+ Source::Map.new(loc(token))
878
+ end
879
+
880
+ def numeric_map(num_t, negate)
881
+ if negate
882
+ num_range = loc(num_t)
883
+ range = Source::Range.new(num_range.source_buffer,
884
+ num_range.begin_pos - 1,
885
+ num_range.end_pos)
886
+
887
+ Source::Map.new(range)
888
+ else
889
+ token_map(num_t)
890
+ end
891
+ end
892
+
893
+ def string_part_map(string_t)
894
+ Source::Map::Collection.new(loc(string_t).begin, loc(string_t).end,
895
+ loc(string_t))
724
896
  end
725
897
 
726
- def location(token)
727
- token[1]
898
+ def unquoted_symbol_map(symbol_t)
899
+ Source::Map::Collection.new(nil, nil,
900
+ loc(symbol_t))
728
901
  end
729
902
 
730
- def s(type, *args)
731
- if Hash === args.last
732
- metadata = args.pop
903
+ def expr_map(loc)
904
+ Source::Map.new(loc)
905
+ end
906
+
907
+ def collection_map(begin_t, parts, end_t)
908
+ if begin_t.nil? || end_t.nil?
909
+ if parts.any?
910
+ expr_l = join_exprs(parts.first, parts.last)
911
+ end
912
+ else
913
+ expr_l = loc(begin_t).join(loc(end_t))
914
+ end
915
+
916
+ Source::Map::Collection.new(loc(begin_t), loc(end_t), expr_l)
917
+ end
918
+
919
+ def regexp_map(begin_t, end_t, options_e)
920
+ Source::Map::Collection.new(loc(begin_t), loc(end_t),
921
+ loc(begin_t).join(options_e.src.expression))
922
+ end
923
+
924
+ def constant_map(scope, colon2_t, name_t)
925
+ if scope.nil?
926
+ expr_l = loc(name_t)
927
+ else
928
+ expr_l = scope.src.expression.join(loc(name_t))
929
+ end
930
+
931
+ Source::Map::Constant.new(loc(colon2_t), loc(name_t), expr_l)
932
+ end
933
+
934
+ def variable_map(name_t)
935
+ Source::Map::Variable.new(loc(name_t))
936
+ end
937
+
938
+ def binary_op_map(left_e, op_t, right_e)
939
+ Source::Map::Operator.new(loc(op_t), join_exprs(left_e, right_e))
940
+ end
941
+
942
+ def unary_op_map(op_t, arg_e=nil)
943
+ if arg_e.nil?
944
+ expr_l = loc(op_t)
945
+ else
946
+ expr_l = loc(op_t).join(arg_e.src.expression)
947
+ end
948
+
949
+ Source::Map::Operator.new(loc(op_t), expr_l)
950
+ end
951
+
952
+ def arg_prefix_map(op_t, name_t=nil)
953
+ if name_t.nil?
954
+ expr_l = loc(op_t)
733
955
  else
734
- metadata = {}
956
+ expr_l = loc(op_t).join(loc(name_t))
735
957
  end
736
958
 
737
- AST::Node.new(type, args, metadata)
959
+ Source::Map::Variable.new(loc(name_t), expr_l)
960
+ end
961
+
962
+ def kwarg_map(name_t, value_e=nil)
963
+ label_range = loc(name_t)
964
+ name_range = Source::Range.new(label_range.source_buffer,
965
+ label_range.begin_pos,
966
+ label_range.end_pos - 1)
967
+
968
+ if value_e
969
+ expr_l = loc(name_t).join(value_e.src.expression)
970
+ else
971
+ expr_l = loc(name_t)
972
+ end
973
+
974
+ Source::Map::Variable.new(name_range, expr_l)
975
+ end
976
+
977
+ def definition_map(keyword_t, operator_t, name_t, end_t)
978
+ Source::Map::Definition.new(loc(keyword_t),
979
+ loc(operator_t), loc(name_t),
980
+ loc(end_t))
981
+ end
982
+
983
+ def send_map(receiver_e, selector_t, begin_t=nil, args=[], end_t=nil)
984
+ if receiver_e
985
+ begin_l = receiver_e.src.expression
986
+ elsif selector_t
987
+ begin_l = loc(selector_t)
988
+ end
989
+
990
+ if end_t
991
+ end_l = loc(end_t)
992
+ elsif args.any?
993
+ end_l = args.last.src.expression
994
+ elsif selector_t
995
+ end_l = loc(selector_t)
996
+ end
997
+
998
+ Source::Map::Send.new(loc(selector_t), loc(begin_t), loc(end_t),
999
+ begin_l.join(end_l))
1000
+ end
1001
+
1002
+ def var_send_map(variable_e)
1003
+ Source::Map::Send.new(variable_e.src.expression, nil, nil,
1004
+ variable_e.src.expression)
1005
+ end
1006
+
1007
+ def send_binary_op_map(lhs_e, selector_t, rhs_e)
1008
+ Source::Map::Send.new(loc(selector_t), nil, nil,
1009
+ join_exprs(lhs_e, rhs_e))
1010
+ end
1011
+
1012
+ def send_unary_op_map(selector_t, arg_e)
1013
+ if arg_e.nil?
1014
+ expr_l = loc(selector_t)
1015
+ else
1016
+ expr_l = loc(selector_t).join(arg_e.src.expression)
1017
+ end
1018
+
1019
+ Source::Map::Send.new(loc(selector_t), nil, nil,
1020
+ expr_l)
1021
+ end
1022
+
1023
+ def send_index_map(receiver_e, lbrack_t, rbrack_t)
1024
+ Source::Map::Send.new(loc(lbrack_t).join(loc(rbrack_t)), nil, nil,
1025
+ receiver_e.src.expression.join(loc(rbrack_t)))
1026
+ end
1027
+
1028
+ def block_map(receiver_l, begin_t, end_t)
1029
+ Source::Map::Block.new(loc(begin_t), loc(end_t),
1030
+ receiver_l.join(loc(end_t)))
1031
+ end
1032
+
1033
+ def keyword_map(keyword_t, begin_t, args, end_t)
1034
+ args ||= []
1035
+
1036
+ if end_t
1037
+ end_l = loc(end_t)
1038
+ elsif args.any? && !synthesized_nil?(args.last)
1039
+ end_l = args.last.src.expression
1040
+ elsif args.any? && args.count > 1
1041
+ end_l = args[-2].src.expression
1042
+ else
1043
+ end_l = loc(keyword_t)
1044
+ end
1045
+
1046
+ Source::Map::Keyword.new(loc(keyword_t), loc(begin_t), loc(end_t),
1047
+ loc(keyword_t).join(end_l))
1048
+ end
1049
+
1050
+ def keyword_mod_map(pre_e, keyword_t, post_e)
1051
+ Source::Map::Keyword.new(loc(keyword_t), nil, nil,
1052
+ join_exprs(pre_e, post_e))
1053
+ end
1054
+
1055
+ def condition_map(keyword_t, begin_t, body_e, else_t, else_e, end_t)
1056
+ if end_t
1057
+ end_l = loc(end_t)
1058
+ elsif else_e && else_e.src.expression
1059
+ end_l = else_e.src.expression
1060
+ elsif else_t
1061
+ end_l = loc(else_t)
1062
+ elsif body_e.src.expression
1063
+ end_l = body_e.src.expression
1064
+ else
1065
+ end_l = loc(begin_t)
1066
+ end
1067
+
1068
+ Source::Map::Condition.new(loc(keyword_t),
1069
+ loc(begin_t), loc(else_t), loc(end_t),
1070
+ loc(keyword_t).join(end_l))
1071
+ end
1072
+
1073
+ def ternary_map(begin_e, question_t, mid_e, colon_t, end_e)
1074
+ Source::Map::Ternary.new(loc(question_t), loc(colon_t),
1075
+ join_exprs(begin_e, end_e))
1076
+ end
1077
+
1078
+ def for_map(keyword_t, in_t, begin_t, end_t)
1079
+ Source::Map::For.new(loc(keyword_t), loc(in_t),
1080
+ loc(begin_t), loc(end_t),
1081
+ loc(keyword_t).join(loc(end_t)))
1082
+ end
1083
+
1084
+ def rescue_body_map(keyword_t, exc_list_e, assoc_t,
1085
+ exc_var_e, then_t,
1086
+ compstmt_e)
1087
+ end_l = compstmt_e.src.expression ||
1088
+ loc(then_t) ||
1089
+ exc_var_e.src.expression ||
1090
+ exc_list_e.src.expression ||
1091
+ loc(keyword_t)
1092
+
1093
+ Source::Map::RescueBody.new(loc(keyword_t), loc(assoc_t), loc(then_t),
1094
+ loc(keyword_t).join(end_l))
1095
+ end
1096
+
1097
+ def eh_keyword_map(compstmt_e, keyword_t, body_es,
1098
+ else_t, else_e)
1099
+ if synthesized_nil?(compstmt_e)
1100
+ begin_l = loc(keyword_t)
1101
+ else
1102
+ begin_l = compstmt_e.src.expression
1103
+ end
1104
+
1105
+ if else_t
1106
+ end_l = else_e.src.expression
1107
+ elsif !synthesized_nil?(body_es.last)
1108
+ end_l = body_es.last.src.expression
1109
+ else
1110
+ end_l = loc(keyword_t)
1111
+ end
1112
+
1113
+ Source::Map::Condition.new(loc(keyword_t), nil, loc(else_t), nil,
1114
+ begin_l.join(end_l))
1115
+ end
1116
+
1117
+ #
1118
+ # HELPERS
1119
+ #
1120
+
1121
+ def collapse_string_parts?(parts)
1122
+ parts.one? &&
1123
+ [:str, :dstr].include?(parts.first.type)
1124
+ end
1125
+
1126
+ def synthesized_nil?(node)
1127
+ node.type == :nil && node.src.expression.nil?
1128
+ end
1129
+
1130
+ def value(token)
1131
+ token[0]
1132
+ end
1133
+
1134
+ def loc(token)
1135
+ token[1] if token
738
1136
  end
739
1137
 
740
1138
  def diagnostic(type, message, location, highlights=[])