prettier 0.12.3 → 0.13.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.
@@ -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