prettier 0.12.3 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1682,6 +1682,10 @@ var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/;
1682
1682
  var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i;
1683
1683
  var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i;
1684
1684
 
1685
+ function _class(obj) {
1686
+ return Object.prototype.toString.call(obj);
1687
+ }
1688
+
1685
1689
  function is_EOL(c) {
1686
1690
  return c === 0x0A
1687
1691
  /* LF */
@@ -1985,7 +1989,31 @@ function mergeMappings(state, destination, source, overridableKeys) {
1985
1989
  }
1986
1990
 
1987
1991
  function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, startLine, startPos) {
1988
- var index, quantity;
1992
+ var index, quantity; // The output is a plain object here, so keys can only be strings.
1993
+ // We need to convert keyNode to a string, but doing so can hang the process
1994
+ // (deeply nested arrays that explode exponentially using aliases).
1995
+
1996
+ if (Array.isArray(keyNode)) {
1997
+ keyNode = Array.prototype.slice.call(keyNode);
1998
+
1999
+ for (index = 0, quantity = keyNode.length; index < quantity; index += 1) {
2000
+ if (Array.isArray(keyNode[index])) {
2001
+ throwError(state, 'nested arrays are not supported inside keys');
2002
+ }
2003
+
2004
+ if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') {
2005
+ keyNode[index] = '[object Object]';
2006
+ }
2007
+ }
2008
+ } // Avoid code execution in load() via toString property
2009
+ // (still use its own toString for arrays, timestamps,
2010
+ // and whatever user schema extensions happen to have @@toStringTag)
2011
+
2012
+
2013
+ if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') {
2014
+ keyNode = '[object Object]';
2015
+ }
2016
+
1989
2017
  keyNode = String(keyNode);
1990
2018
 
1991
2019
  if (_result === null) {
@@ -3480,6 +3508,7 @@ function encodeHex(character) {
3480
3508
  function State$1(options) {
3481
3509
  this.schema = options['schema'] || default_full;
3482
3510
  this.indent = Math.max(1, options['indent'] || 2);
3511
+ this.noArrayIndent = options['noArrayIndent'] || false;
3483
3512
  this.skipInvalid = options['skipInvalid'] || false;
3484
3513
  this.flowLevel = common.isNothing(options['flowLevel']) ? -1 : options['flowLevel'];
3485
3514
  this.styleMap = compileStyleMap(this.schema, options['styles'] || null);
@@ -4080,14 +4109,16 @@ function writeNode(state, level, object, block, compact, iskey) {
4080
4109
  }
4081
4110
  }
4082
4111
  } else if (type === '[object Array]') {
4112
+ var arrayLevel = state.noArrayIndent && level > 0 ? level - 1 : level;
4113
+
4083
4114
  if (block && state.dump.length !== 0) {
4084
- writeBlockSequence(state, level, state.dump, compact);
4115
+ writeBlockSequence(state, arrayLevel, state.dump, compact);
4085
4116
 
4086
4117
  if (duplicate) {
4087
4118
  state.dump = '&ref_' + duplicateIndex + state.dump;
4088
4119
  }
4089
4120
  } else {
4090
- writeFlowSequence(state, level, state.dump);
4121
+ writeFlowSequence(state, arrayLevel, state.dump);
4091
4122
 
4092
4123
  if (duplicate) {
4093
4124
  state.dump = '&ref_' + duplicateIndex + ' ' + state.dump;
@@ -1,12 +1,11 @@
1
1
  {
2
2
  "name": "@prettier/plugin-ruby",
3
- "version": "0.12.3",
3
+ "version": "0.13.0",
4
4
  "description": "prettier plugin for the Ruby programming language",
5
5
  "main": "src/ruby.js",
6
6
  "scripts": {
7
7
  "lint": "eslint --cache .",
8
8
  "print": "prettier --plugin=.",
9
- "rubocop": "run() { prettier --plugin=. $@ | bundle exec rubocop --stdin $1; }; run",
10
9
  "test": "jest"
11
10
  },
12
11
  "repository": {
@@ -24,9 +23,9 @@
24
23
  },
25
24
  "devDependencies": {
26
25
  "all-contributors-cli": "^6.1.2",
27
- "eslint": "^5.15.0",
26
+ "eslint": "^6.0.1",
28
27
  "eslint-config-airbnb-base": "^13.1.0",
29
- "eslint-config-prettier": "^4.3.0",
28
+ "eslint-config-prettier": "^6.0.0",
30
29
  "eslint-plugin-import": "^2.16.0",
31
30
  "jest": "^24.0.0"
32
31
  },
@@ -78,8 +78,9 @@ module.exports = {
78
78
  const isInner = index !== assocNodes.length - 1;
79
79
  const valueNode = assocNode.body[1];
80
80
 
81
- const isStraightHeredoc = valueNode.type === "heredoc";
81
+ const isStraightHeredoc = valueNode && valueNode.type === "heredoc";
82
82
  const isSquigglyHeredoc =
83
+ valueNode &&
83
84
  valueNode.type === "string_literal" &&
84
85
  valueNode.body[0].type === "heredoc";
85
86
 
@@ -10,6 +10,15 @@ require 'json' unless defined?(JSON)
10
10
  require 'ripper'
11
11
 
12
12
  class RipperJS < Ripper
13
+ attr_reader :lines, :__end__
14
+
15
+ def initialize(source, *args)
16
+ super(source, *args)
17
+
18
+ @lines = source.split("\n")
19
+ @__end__ = nil
20
+ end
21
+
13
22
  private
14
23
 
15
24
  # Scanner events occur when the lexer hits a new token, like a keyword or an
@@ -99,44 +108,239 @@ class RipperJS < Ripper
99
108
  end
100
109
  )
101
110
 
111
+ # For each node, we need to attach where it came from in order to be able to
112
+ # support placing the cursor correctly before and after formatting.
113
+ #
102
114
  # For most nodes, it's enough to look at the child nodes to determine the
103
115
  # start of the parent node. However, for some nodes it's necessary to keep
104
116
  # track of the keywords as they come in from the lexer and to modify the start
105
- # node once we have it. We need accurate start and end lines so that we can
106
- # embed block comments into the right kind of node.
117
+ # node once we have it.
107
118
  prepend(
108
119
  Module.new do
109
- events = %i[begin else elsif ensure if rescue until while]
120
+ def initialize(source, *args)
121
+ super(source, *args)
110
122
 
111
- def initialize(*args)
112
- super(*args)
113
- @keywords = []
123
+ @scanner_events = []
124
+ @line_counts = [0]
125
+
126
+ source.split("\n").each do |line|
127
+ line_counts << line_counts.last + line.size + 1
128
+ end
114
129
  end
115
130
 
116
131
  def self.prepended(base)
117
- base.attr_reader :keywords
132
+ base.attr_reader :scanner_events, :line_counts
118
133
  end
119
134
 
120
135
  private
121
136
 
122
- def find_start(body)
123
- keywords[keywords.rindex { |keyword| keyword[:body] == body }][:start]
137
+ def char_pos
138
+ line_counts[lineno - 1] + column
124
139
  end
125
140
 
126
- events.each do |event|
127
- keyword = event.to_s
141
+ def char_start_for(body)
142
+ children = body.length == 1 && body[0].is_a?(Array) ? body[0] : body
143
+ char_starts =
144
+ children.map { |part| part[:char_start] if part.is_a?(Hash) }.compact
145
+
146
+ char_starts.min || char_pos
147
+ end
128
148
 
149
+ def find_scanner_event(type, body = :any)
150
+ index =
151
+ scanner_events.rindex do |scanner_event|
152
+ scanner_event[:type] == type &&
153
+ (body == :any || (scanner_event[:body] == body))
154
+ end
155
+
156
+ scanner_events.delete_at(index)
157
+ end
158
+
159
+ # :backref, :const, :embdoc, :embdoc_beg, :embdoc_end,
160
+ # :embexpr_beg, :embexpr_end, :embvar, :heredoc_beg, :heredoc_end,
161
+ # :ident, :lbrace, :lbracket, :lparen, :op, :period, :regexp_beg,
162
+ # :regexp_end, :rparen, :symbeg, :symbols_beg, :tlambda, :tlambeg,
163
+ # :tstring_beg, :tstring_content, :tstring_end
164
+
165
+ events = {
166
+ BEGIN: [:@kw, 'BEGIN'],
167
+ END: [:@kw, 'END'],
168
+ alias: [:@kw, 'alias'],
169
+ assoc_splat: [:@op, '**'],
170
+ arg_paren: :@lparen,
171
+ args_add_star: [:@op, '*'],
172
+ begin: [:@kw, 'begin'],
173
+ blockarg: [:@op, '&'],
174
+ brace_block: :@lbrace,
175
+ break: [:@kw, 'break'],
176
+ case: [:@kw, 'case'],
177
+ class: [:@kw, 'class'],
178
+ def: [:@kw, 'def'],
179
+ defined: [:@kw, 'defined?'],
180
+ defs: [:@kw, 'def'],
181
+ do_block: [:@kw, 'do'],
182
+ else: [:@kw, 'else'],
183
+ elsif: [:@kw, 'elsif'],
184
+ ensure: [:@kw, 'ensure'],
185
+ excessed_comma: :@comma,
186
+ for: [:@kw, 'for'],
187
+ hash: :@lbrace,
188
+ if: [:@kw, 'if'],
189
+ kwrest_param: [:@op, '**'],
190
+ lambda: :@tlambda,
191
+ mlhs_paren: :@lparen,
192
+ mrhs_add_star: [:@op, '*'],
193
+ module: [:@kw, 'module'],
194
+ next: [:@kw, 'next'],
195
+ paren: :@lparen,
196
+ qsymbols_new: :@qsymbols_beg,
197
+ qwords_new: :@qwords_beg,
198
+ redo: [:@kw, 'redo'],
199
+ regexp_literal: :@regexp_beg,
200
+ rescue: [:@kw, 'rescue'],
201
+ rest_param: [:@op, '*'],
202
+ retry: [:@kw, 'retry'],
203
+ return0: [:@kw, 'return'],
204
+ return: [:@kw, 'return'],
205
+ sclass: [:@kw, 'class'],
206
+ string_dvar: :@embvar,
207
+ string_embexpr: :@embexpr_beg,
208
+ super: [:@kw, 'super'],
209
+ symbols_new: :@symbols_beg,
210
+ top_const_field: [:@op, '::'],
211
+ top_const_ref: [:@op, '::'],
212
+ undef: [:@kw, 'undef'],
213
+ unless: [:@kw, 'unless'],
214
+ until: [:@kw, 'until'],
215
+ var_alias: [:@kw, 'alias'],
216
+ when: [:@kw, 'when'],
217
+ while: [:@kw, 'while'],
218
+ words_new: :@words_beg,
219
+ xstring_literal: :@backtick,
220
+ yield0: [:@kw, 'yield'],
221
+ yield: [:@kw, 'yield'],
222
+ zsuper: [:@kw, 'super']
223
+ }
224
+
225
+ events.each do |event, (type, scanned)|
129
226
  define_method(:"on_#{event}") do |*body|
130
- super(*body).tap { |sexp| sexp.merge!(start: find_start(keyword)) }
227
+ node = find_scanner_event(type, scanned || :any)
228
+
229
+ super(*body).merge!(
230
+ start: node[:start],
231
+ char_start: node[:char_start],
232
+ char_end: char_pos
233
+ )
131
234
  end
132
235
  end
133
236
 
134
- def on_kw(body)
135
- super(body).tap { |sexp| keywords << sexp }
237
+ # Array nodes can contain a myriad of subnodes because of the special
238
+ # array literal syntax like %w and %i. As a result, we may be looking for
239
+ # an left bracket, or we may be just looking at the children.
240
+ def on_array(*body)
241
+ if body[0] && %i[args args_add_star].include?(body[0][:type])
242
+ node = find_scanner_event(:@lbracket)
243
+
244
+ super(*body).merge!(
245
+ start: node[:start],
246
+ char_start: node[:char_start],
247
+ char_end: char_pos
248
+ )
249
+ else
250
+ super(*body).merge!(
251
+ char_start: char_start_for(body), char_end: char_pos
252
+ )
253
+ end
254
+ end
255
+
256
+ # Params have a somewhat interesting structure in that they are an array
257
+ # of arrays where the position in the top-level array indicates the type
258
+ # of param and the subarray is the list of parameters of that type. We
259
+ # therefore have to flatten them down to get to the location.
260
+ def on_params(*body)
261
+ super(*body).merge!(
262
+ char_start: char_start_for(body.flatten(1)), char_end: char_pos
263
+ )
264
+ end
265
+
266
+ # String literals and either contain string parts or a heredoc. If it
267
+ # contains a heredoc we can just go directly to the child nodes, otherwise
268
+ # we need to look for a `tstring_beg`.
269
+ def on_string_literal(*body)
270
+ if body[0][:type] == :heredoc
271
+ super(*body).merge!(
272
+ char_start: char_start_for(body), char_end: char_pos
273
+ )
274
+ else
275
+ node = find_scanner_event(:@tstring_beg)
276
+
277
+ super(*body).merge!(
278
+ start: node[:start],
279
+ char_start: node[:char_start],
280
+ char_end: char_pos
281
+ )
282
+ end
283
+ end
284
+
285
+ # Technically, the `not` operator is a unary operator but is reported as
286
+ # a keyword and not an operator. Because of the inconsistency, we have to
287
+ # manually look for the correct scanner event here.
288
+ def on_unary(*body)
289
+ node =
290
+ if body[0] == :not
291
+ find_scanner_event(:@kw, 'not')
292
+ else
293
+ find_scanner_event(:@op)
294
+ end
295
+
296
+ super(*body).merge!(
297
+ start: node[:start], char_start: node[:char_start], char_end: char_pos
298
+ )
299
+ end
300
+
301
+ # Symbols don't necessarily have to have a @symbeg event fired before they
302
+ # start. For example, you can have symbol literals inside an `alias` node
303
+ # if you're just using bare words, as in: `alias foo bar`. So this is a
304
+ # special case in which if there is a `:@symbeg` event we can hook on to
305
+ # then we use it, otherwise we just look at the beginning of the first
306
+ # child node.
307
+ %i[dyna_symbol symbol_literal].each do |event|
308
+ define_method(:"on_#{event}") do |*body|
309
+ char_start =
310
+ if scanner_events.any? { |sevent| sevent[:type] == :@symbeg }
311
+ find_scanner_event(:@symbeg)[:char_start]
312
+ else
313
+ char_start_for(body)
314
+ end
315
+
316
+ super(*body).merge!(char_start: char_start, char_end: char_pos)
317
+ end
136
318
  end
137
319
 
138
320
  def on_program(*body)
139
- super(*body).tap { |sexp| sexp.merge!(start: 1) }
321
+ super(*body).merge!(start: 1, char_start: 0, char_end: char_pos)
322
+ end
323
+
324
+ defined =
325
+ private_instance_methods(false).grep(/\Aon_/) { $'.to_sym } +
326
+ %i[embdoc embdoc_beg embdoc_end heredoc_beg heredoc_end]
327
+
328
+ (SCANNER_EVENTS - defined).each do |event|
329
+ define_method(:"on_#{event}") do |body|
330
+ super(body).tap do |node|
331
+ node.merge!(char_start: char_pos, char_end: char_pos + body.size)
332
+
333
+ scanner_events << node
334
+ end
335
+ end
336
+ end
337
+
338
+ (PARSER_EVENTS - defined).each do |event|
339
+ define_method(:"on_#{event}") do |*body|
340
+ super(*body).merge!(
341
+ char_start: char_start_for(body), char_end: char_pos
342
+ )
343
+ end
140
344
  end
141
345
  end
142
346
  )
@@ -153,6 +357,7 @@ class RipperJS < Ripper
153
357
  aref: [:body, 1],
154
358
  args_add_block: [:body, 0],
155
359
  break: [:body, 0],
360
+ call: [:body, 0],
156
361
  command: [:body, 1],
157
362
  command_call: [:body, 3],
158
363
  regexp_literal: [:body, 0],
@@ -238,15 +443,15 @@ class RipperJS < Ripper
238
443
  def on_comment(body)
239
444
  sexp = { type: :@comment, body: body.chomp, start: lineno, end: lineno }
240
445
 
241
- case RipperJS.lex_state_name(state)
242
- when 'EXPR_END', 'EXPR_ARG|EXPR_LABELED', 'EXPR_ENDFN'
446
+ case RipperJS.lex_state_name(state).gsub('EXPR_', '')
447
+ when 'END', 'ARG|LABELED', 'ENDFN'
243
448
  last_sexp.merge!(comments: [sexp])
244
- when 'EXPR_CMDARG', 'EXPR_END|EXPR_ENDARG', 'EXPR_ENDARG', 'EXPR_ARG',
245
- 'EXPR_FNAME|EXPR_FITEM', 'EXPR_CLASS', 'EXPR_END|EXPR_LABEL'
449
+ when 'CMDARG', 'END|ENDARG', 'ENDARG', 'ARG', 'FNAME|FITEM', 'CLASS',
450
+ 'END|LABEL'
246
451
  inline_comments << sexp
247
- when 'EXPR_BEG|EXPR_LABEL', 'EXPR_MID'
452
+ when 'BEG|LABEL', 'MID'
248
453
  inline_comments << sexp.merge!(break: true)
249
- when 'EXPR_DOT'
454
+ when 'DOT'
250
455
  last_sexp.merge!(comments: [sexp.merge!(break: true)])
251
456
  end
252
457
 
@@ -255,7 +460,7 @@ class RipperJS < Ripper
255
460
 
256
461
  defined = private_instance_methods(false).grep(/\Aon_/) { $'.to_sym }
257
462
 
258
- (Ripper::PARSER_EVENTS - defined).each do |event|
463
+ (PARSER_EVENTS - defined).each do |event|
259
464
  define_method(:"on_#{event}") do |*body|
260
465
  super(*body).tap do |sexp|
261
466
  @last_sexp = sexp
@@ -327,7 +532,8 @@ class RipperJS < Ripper
327
532
 
328
533
  def on_comment(body)
329
534
  super(body).tap do |sexp|
330
- block_comments << sexp if RipperJS.lex_state_name(state) == 'EXPR_BEG'
535
+ lex_state = RipperJS.lex_state_name(state).gsub('EXPR_', '')
536
+ block_comments << sexp if lex_state == 'BEG'
331
537
  end
332
538
  end
333
539
 
@@ -410,62 +616,40 @@ class RipperJS < Ripper
410
616
  end
411
617
  )
412
618
 
413
- # These are the event types that contain _actual_ string content. If there is
414
- # an encoding magic comment at the top of the file, ripper will actually
415
- # change into that encoding for the storage of the string. This will break
416
- # everything, so we need to force the encoding back into UTF-8 so that
417
- # the JSON library won't break.
418
619
  prepend(
419
620
  Module.new do
420
621
  private
421
622
 
623
+ # These are the event types that contain _actual_ string content. If
624
+ # there is an encoding magic comment at the top of the file, ripper will
625
+ # actually change into that encoding for the storage of the string. This
626
+ # will break everything, so we need to force the encoding back into UTF-8
627
+ # so that the JSON library won't break.
422
628
  %w[comment ident tstring_content].each do |event|
423
629
  define_method(:"on_#{event}") do |body|
424
630
  super(body.force_encoding('UTF-8'))
425
631
  end
426
632
  end
427
- end
428
- )
429
-
430
- # Handles __END__ syntax, which allows individual scripts to keep content
431
- # after the main ruby code that can be read through DATA. Which looks like:
432
- #
433
- # foo.bar
434
- #
435
- # __END__
436
- # some other content that isn't read by ripper normally
437
- prepend(
438
- Module.new do
439
- def initialize(source, *args)
440
- super(source, *args)
441
- @source = source
442
- @ending = nil
443
- end
444
-
445
- def self.prepended(base)
446
- base.attr_reader :source, :ending
447
- end
448
-
449
- private
450
633
 
634
+ # Handles __END__ syntax, which allows individual scripts to keep content
635
+ # after the main ruby code that can be read through DATA. It looks like:
636
+ #
637
+ # foo.bar
638
+ #
639
+ # __END__
640
+ # some other content that isn't normally read by ripper
451
641
  def on___end__(body)
452
- @ending = super(source.split("\n")[lineno..-1].join("\n"))
642
+ @__end__ = super(lines[lineno..-1].join("\n"))
453
643
  end
454
644
 
455
645
  def on_program(*body)
456
- super(*body).tap { |sexp| sexp[:body][0][:body] << ending if ending }
646
+ super(*body).tap { |node| node[:body][0][:body] << __end__ if __end__ }
457
647
  end
458
- end
459
- )
460
-
461
- # Adds the used quote type onto string nodes. This is necessary because we're
462
- # going to have to stick to whatever quote the user chose if there are escape
463
- # sequences within the string. For example, if you have '\n' we can't switch
464
- # to double quotes without changing what it means.
465
- prepend(
466
- Module.new do
467
- private
468
648
 
649
+ # Adds the used quote type onto string nodes. This is necessary because
650
+ # we're going to have to stick to whatever quote the user chose if there
651
+ # are escape sequences within the string. For example, if you have '\n'
652
+ # we can't switch to double quotes without changing what it means.
469
653
  def on_tstring_end(quote)
470
654
  last_sexp.merge!(quote: quote)
471
655
  end
@@ -473,66 +657,45 @@ class RipperJS < Ripper
473
657
  def on_label_end(quote)
474
658
  last_sexp.merge!(quote: quote[0]) # quote is ": or ':
475
659
  end
476
- end
477
- )
478
-
479
- # Normally access controls are reported as vcall nodes. This module creates a
480
- # new node type to explicitly track those nodes instead, so that the printer
481
- # can add new lines as necessary.
482
- prepend(
483
- Module.new do
484
- KEYWORDS = %w[private protected public].freeze
485
-
486
- def initialize(source, *args)
487
- super(source, *args)
488
- @lines = source.split("\n")
489
- end
490
-
491
- def self.prepended(base)
492
- base.attr_reader :lines
493
- end
494
-
495
- private
496
660
 
661
+ # Normally access controls are reported as vcall nodes. This creates a
662
+ # new node type to explicitly track those nodes instead, so that the
663
+ # printer can add new lines as necessary.
497
664
  def on_vcall(ident)
498
- super(ident).tap do |sexp|
499
- if !KEYWORDS.include?(ident[:body]) ||
665
+ @access_controls ||= %w[private protected public].freeze
666
+
667
+ super(ident).tap do |node|
668
+ if !@access_controls.include?(ident[:body]) ||
500
669
  ident[:body] != lines[lineno - 1].strip
501
670
  next
502
671
  end
503
672
 
504
- sexp.merge!(type: :access_ctrl)
673
+ node.merge!(type: :access_ctrl)
505
674
  end
506
675
  end
507
- end
508
- )
509
-
510
- # When the only statement inside of a `def` node is a `begin` node, then you
511
- # can safely replace the body of the `def` with the body of the `begin`. For
512
- # example:
513
- #
514
- # def foo
515
- # begin
516
- # try_something
517
- # rescue SomeError => error
518
- # handle_error(error)
519
- # end
520
- # end
521
- #
522
- # can get transformed into:
523
- #
524
- # def foo
525
- # try_something
526
- # rescue SomeError => error
527
- # handle_error(error)
528
- # end
529
- #
530
- # This module handles this by hoisting up the `bodystmt` node from the inner
531
- # `begin` up to the `def`.
532
- prepend(
533
- Module.new do
534
- private
535
676
 
677
+ # When the only statement inside of a `def` node is a `begin` node, then
678
+ # you can safely replace the body of the `def` with the body of the
679
+ # `begin`. For example:
680
+ #
681
+ # def foo
682
+ # begin
683
+ # try_something
684
+ # rescue SomeError => error
685
+ # handle_error(error)
686
+ # end
687
+ # end
688
+ #
689
+ # can get transformed into:
690
+ #
691
+ # def foo
692
+ # try_something
693
+ # rescue SomeError => error
694
+ # handle_error(error)
695
+ # end
696
+ #
697
+ # This module handles this by hoisting up the `bodystmt` node from the
698
+ # inner `begin` up to the `def`.
536
699
  def on_def(ident, params, bodystmt)
537
700
  def_bodystmt = bodystmt
538
701
  stmts, *other_parts = bodystmt[:body]
@@ -544,17 +707,11 @@ class RipperJS < Ripper
544
707
 
545
708
  super(ident, params, def_bodystmt)
546
709
  end
547
- end
548
- )
549
-
550
- # By default, Ripper parses the expression `lambda { foo }` as a
551
- # `method_add_block` node, so we can't turn it back into `-> { foo }`. This
552
- # module overrides that behavior and reports it back as a `lambda` node
553
- # instead.
554
- prepend(
555
- Module.new do
556
- private
557
710
 
711
+ # By default, Ripper parses the expression `lambda { foo }` as a
712
+ # `method_add_block` node, so we can't turn it back into `-> { foo }`.
713
+ # This module overrides that behavior and reports it back as a `lambda`
714
+ # node instead.
558
715
  def on_method_add_block(invocation, block)
559
716
  # It's possible to hit a `method_add_block` node without going through
560
717
  # `method_add_arg` node, ex: `super {}`. In that case we're definitely