parser 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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=[])