prettier 1.2.0 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +61 -1
  3. data/CONTRIBUTING.md +2 -2
  4. data/README.md +12 -88
  5. data/lib/prettier.rb +2 -2
  6. data/node_modules/prettier/index.js +54 -54
  7. data/package.json +2 -3
  8. data/rubocop.yml +26 -0
  9. data/src/{ruby.js → plugin.js} +2 -2
  10. data/src/prettier.js +1 -0
  11. data/src/{embed.js → ruby/embed.js} +6 -2
  12. data/src/{nodes.js → ruby/nodes.js} +0 -0
  13. data/src/{nodes → ruby/nodes}/alias.js +1 -1
  14. data/src/{nodes → ruby/nodes}/aref.js +8 -1
  15. data/src/{nodes → ruby/nodes}/args.js +2 -2
  16. data/src/{nodes → ruby/nodes}/arrays.js +2 -3
  17. data/src/{nodes → ruby/nodes}/assign.js +7 -7
  18. data/src/ruby/nodes/blocks.js +90 -0
  19. data/src/{nodes → ruby/nodes}/calls.js +18 -11
  20. data/src/ruby/nodes/case.js +65 -0
  21. data/src/{nodes → ruby/nodes}/class.js +1 -1
  22. data/src/ruby/nodes/commands.js +131 -0
  23. data/src/{nodes → ruby/nodes}/conditionals.js +3 -3
  24. data/src/{nodes → ruby/nodes}/constants.js +2 -2
  25. data/src/{nodes → ruby/nodes}/flow.js +2 -2
  26. data/src/{nodes → ruby/nodes}/hashes.js +32 -10
  27. data/src/{nodes → ruby/nodes}/heredocs.js +2 -2
  28. data/src/ruby/nodes/hooks.js +34 -0
  29. data/src/{nodes → ruby/nodes}/ints.js +0 -0
  30. data/src/{nodes → ruby/nodes}/lambdas.js +2 -2
  31. data/src/{nodes → ruby/nodes}/loops.js +10 -7
  32. data/src/{nodes → ruby/nodes}/massign.js +8 -1
  33. data/src/{nodes → ruby/nodes}/methods.js +24 -7
  34. data/src/{nodes → ruby/nodes}/operators.js +2 -2
  35. data/src/{nodes → ruby/nodes}/params.js +31 -16
  36. data/src/{nodes → ruby/nodes}/patterns.js +39 -17
  37. data/src/{nodes → ruby/nodes}/regexp.js +2 -2
  38. data/src/{nodes → ruby/nodes}/rescue.js +2 -2
  39. data/src/ruby/nodes/return.js +94 -0
  40. data/src/{nodes → ruby/nodes}/statements.js +6 -9
  41. data/src/{nodes → ruby/nodes}/strings.js +27 -36
  42. data/src/{nodes → ruby/nodes}/super.js +2 -2
  43. data/src/{nodes → ruby/nodes}/undef.js +1 -1
  44. data/src/{parser.js → ruby/parser.js} +4 -3
  45. data/src/{parser.rb → ruby/parser.rb} +462 -508
  46. data/src/{printer.js → ruby/printer.js} +33 -1
  47. data/src/{toProc.js → ruby/toProc.js} +4 -8
  48. data/src/utils.js +10 -93
  49. data/src/utils/containsAssignment.js +11 -0
  50. data/src/utils/getTrailingComma.js +5 -0
  51. data/src/utils/hasAncestor.js +17 -0
  52. data/src/utils/literal.js +7 -0
  53. data/src/utils/makeCall.js +14 -0
  54. data/src/utils/noIndent.js +11 -0
  55. data/src/utils/skipAssignIndent.js +10 -0
  56. metadata +49 -41
  57. data/src/nodes/blocks.js +0 -85
  58. data/src/nodes/case.js +0 -61
  59. data/src/nodes/commands.js +0 -91
  60. data/src/nodes/hooks.js +0 -44
  61. data/src/nodes/return.js +0 -72
@@ -1,5 +1,5 @@
1
- const { concat } = require("../prettier");
2
- const { hasAncestor } = require("../utils");
1
+ const { concat } = require("../../prettier");
2
+ const { hasAncestor } = require("../../utils");
3
3
 
4
4
  function hasContent(node, pattern) {
5
5
  return node.body.some(
@@ -6,8 +6,8 @@ const {
6
6
  indent,
7
7
  join,
8
8
  line
9
- } = require("../prettier");
10
- const { literal } = require("../utils");
9
+ } = require("../../prettier");
10
+ const { literal } = require("../../utils");
11
11
 
12
12
  function printBegin(path, opts, print) {
13
13
  return concat([
@@ -0,0 +1,94 @@
1
+ const {
2
+ concat,
3
+ group,
4
+ ifBreak,
5
+ indent,
6
+ line,
7
+ join,
8
+ softline
9
+ } = require("../../prettier");
10
+ const { literal } = require("../../utils");
11
+
12
+ // You can't skip the parentheses if you have comments or certain operators with
13
+ // lower precedence than the return keyword.
14
+ const canSkipParens = (args) => {
15
+ const stmts = args.body[0].body[0];
16
+
17
+ // return(
18
+ // # a
19
+ // b
20
+ // )
21
+ if (stmts.comments) {
22
+ return false;
23
+ }
24
+
25
+ const stmt = stmts.body[0];
26
+
27
+ // return (a or b)
28
+ if (stmt.type === "binary" && ["and", "or"].includes(stmt.body[1])) {
29
+ return false;
30
+ }
31
+
32
+ // return (not a)
33
+ if (stmt.type === "unary" && stmt.oper === "not") {
34
+ return false;
35
+ }
36
+
37
+ return true;
38
+ };
39
+
40
+ const printReturn = (path, opts, print) => {
41
+ let args = path.getValue().body[0].body[0];
42
+ let steps = ["body", 0, "body", 0];
43
+
44
+ if (args.body.length === 1) {
45
+ // If the body of the return contains parens, then just skip directly to the
46
+ // content of the parens so that we can skip printing parens if we don't
47
+ // want them.
48
+ if (args.body[0] && args.body[0].type === "paren" && canSkipParens(args)) {
49
+ args = args.body[0].body[0];
50
+ steps = steps.concat("body", 0, "body", 0);
51
+ }
52
+
53
+ // If we're returning an array literal that isn't a special array, single
54
+ // element array, or an empty array, then we want to grab the arguments so
55
+ // that we can print them out as if they were normal return arguments.
56
+ if (
57
+ args.body[0] &&
58
+ args.body[0].type === "array" &&
59
+ args.body[0].body[0] &&
60
+ args.body[0].body[0].body.length > 1 &&
61
+ ["args", "args_add_star"].includes(args.body[0].body[0].type)
62
+ ) {
63
+ steps = steps.concat("body", 0, "body", 0);
64
+ }
65
+ }
66
+
67
+ // Now that we've established which actual node is the arguments to return,
68
+ // we grab it out of the path by diving down the steps that we've set up.
69
+ const parts = path.call.apply(path, [print].concat(steps));
70
+
71
+ // If we got the value straight out of the parens, then `parts` would only
72
+ // be a singular doc as opposed to an array.
73
+ const value = Array.isArray(parts) ? join(concat([",", line]), parts) : parts;
74
+
75
+ // We only get here if we have comments somewhere that would prevent us from
76
+ // skipping the parentheses.
77
+ if (args.body.length === 1 && args.body[0].type === "paren") {
78
+ return concat(["return", value]);
79
+ }
80
+
81
+ return group(
82
+ concat([
83
+ "return",
84
+ ifBreak(parts.length > 1 ? " [" : "(", " "),
85
+ indent(concat([softline, value])),
86
+ concat([softline, ifBreak(parts.length > 1 ? "]" : ")", "")])
87
+ ])
88
+ );
89
+ };
90
+
91
+ module.exports = {
92
+ return: printReturn,
93
+ return0: literal("return")
94
+ };
@@ -10,7 +10,7 @@ const {
10
10
  literalline,
11
11
  softline,
12
12
  trim
13
- } = require("../prettier");
13
+ } = require("../../prettier");
14
14
 
15
15
  function printBodyStmt(path, opts, print) {
16
16
  const [stmts, rescue, elseClause, ensure] = path.getValue().body;
@@ -30,6 +30,7 @@ function printBodyStmt(path, opts, print) {
30
30
 
31
31
  if (elseClause) {
32
32
  // Before Ruby 2.6, this piece of bodystmt was an explicit "else" node
33
+ /* istanbul ignore next */
33
34
  const stmts =
34
35
  elseClause.type === "else"
35
36
  ? path.call(print, "body", 2, "body", 0)
@@ -69,11 +70,7 @@ function printParen(path, opts, print) {
69
70
  }
70
71
 
71
72
  return group(
72
- concat([
73
- "(",
74
- indent(concat([softline, contentDoc])),
75
- concat([softline, ")"])
76
- ])
73
+ concat(["(", indent(concat([softline, contentDoc])), softline, ")"])
77
74
  );
78
75
  }
79
76
 
@@ -123,12 +120,12 @@ module.exports = {
123
120
  if (lineNo === null) {
124
121
  parts.push(printed);
125
122
  } else if (
126
- stmt.start - lineNo > 1 ||
123
+ stmt.sl - lineNo > 1 ||
127
124
  [stmt.type, stmts[index - 1].type].includes("access_ctrl")
128
125
  ) {
129
126
  parts.push(hardline, hardline, printed);
130
127
  } else if (
131
- stmt.start !== lineNo ||
128
+ stmt.sl !== lineNo ||
132
129
  path.getParentNode().type !== "string_embexpr"
133
130
  ) {
134
131
  parts.push(hardline, printed);
@@ -136,7 +133,7 @@ module.exports = {
136
133
  parts.push("; ", printed);
137
134
  }
138
135
 
139
- lineNo = stmt.end;
136
+ lineNo = stmt.el;
140
137
  });
141
138
 
142
139
  return concat(parts);
@@ -6,7 +6,7 @@ const {
6
6
  literalline,
7
7
  softline,
8
8
  join
9
- } = require("../prettier");
9
+ } = require("../../prettier");
10
10
 
11
11
  // If there is some part of this string that matches an escape sequence or that
12
12
  // contains the interpolation pattern ("#{"), then we are locked into whichever
@@ -31,17 +31,10 @@ function isSingleQuotable(node) {
31
31
 
32
32
  const quotePattern = new RegExp("\\\\([\\s\\S])|(['\"])", "g");
33
33
 
34
- function normalizeQuotes(content, enclosingQuote, originalQuote) {
35
- const replaceOther = originalQuote === '"';
36
- const otherQuote = enclosingQuote === '"' ? "'" : '"';
37
-
34
+ function normalizeQuotes(content, enclosingQuote) {
38
35
  // Escape and unescape single and double quotes as needed to be able to
39
36
  // enclose `content` with `enclosingQuote`.
40
37
  return content.replace(quotePattern, (match, escaped, quote) => {
41
- if (replaceOther && escaped === otherQuote) {
42
- return escaped;
43
- }
44
-
45
38
  if (quote === enclosingQuote) {
46
39
  return `\\${quote}`;
47
40
  }
@@ -97,12 +90,34 @@ function printDynaSymbol(path, opts, print) {
97
90
  return concat([":", quote].concat(path.map(print, "body")).concat(quote));
98
91
  }
99
92
 
93
+ function printStringConcat(path, opts, print) {
94
+ const [leftDoc, rightDoc] = path.map(print, "body");
95
+
96
+ return group(concat([leftDoc, " \\", indent(concat([hardline, rightDoc]))]));
97
+ }
98
+
100
99
  // Prints out an interpolated variable in the string by converting it into an
101
100
  // embedded expression.
102
101
  function printStringDVar(path, opts, print) {
103
102
  return concat(["#{", path.call(print, "body", 0), "}"]);
104
103
  }
105
104
 
105
+ function printStringEmbExpr(path, opts, print) {
106
+ const parts = path.call(print, "body", 0);
107
+
108
+ // If the interpolated expression is inside of a heredoc or an xstring
109
+ // literal (a string that gets sent to the command line) then we don't want
110
+ // to automatically indent, as this can lead to some very odd looking
111
+ // expressions
112
+ if (["heredoc", "xstring_literal"].includes(path.getParentNode().type)) {
113
+ return concat(["#{", parts, "}"]);
114
+ }
115
+
116
+ return group(
117
+ concat(["#{", indent(concat([softline, parts])), concat([softline, "}"])])
118
+ );
119
+ }
120
+
106
121
  // Prints out a literal string. This function does its best to respect the
107
122
  // wishes of the user with regards to single versus double quotes, but if the
108
123
  // string contains any escape expressions then it will just keep the original
@@ -131,10 +146,7 @@ function printStringLiteral(path, { rubySingleQuote }, print) {
131
146
  }
132
147
 
133
148
  // In this case, the part of the string is just regular string content
134
- return join(
135
- literalline,
136
- normalizeQuotes(part.body, quote, node.quote).split("\n")
137
- );
149
+ return join(literalline, normalizeQuotes(part.body, quote).split("\n"));
138
150
  });
139
151
 
140
152
  return concat([quote].concat(parts).concat(getClosingQuote(quote)));
@@ -155,30 +167,9 @@ function printXStringLiteral(path, opts, print) {
155
167
  module.exports = {
156
168
  "@CHAR": printChar,
157
169
  dyna_symbol: printDynaSymbol,
158
- string_concat: (path, opts, print) =>
159
- group(
160
- concat([
161
- path.call(print, "body", 0),
162
- " \\",
163
- indent(concat([hardline, path.call(print, "body", 1)]))
164
- ])
165
- ),
170
+ string_concat: printStringConcat,
166
171
  string_dvar: printStringDVar,
167
- string_embexpr: (path, opts, print) => {
168
- const parts = path.call(print, "body", 0);
169
-
170
- // If the interpolated expression is inside of a heredoc or an xstring
171
- // literal (a string that gets sent to the command line) then we don't want
172
- // to automatically indent, as this can lead to some very odd looking
173
- // expressions
174
- if (["heredoc", "xstring_literal"].includes(path.getParentNode().type)) {
175
- return concat(["#{", parts, "}"]);
176
- }
177
-
178
- return group(
179
- concat(["#{", indent(concat([softline, parts])), concat([softline, "}"])])
180
- );
181
- },
172
+ string_embexpr: printStringEmbExpr,
182
173
  string_literal: printStringLiteral,
183
174
  symbol_literal: printSymbolLiteral,
184
175
  xstring_literal: printXStringLiteral
@@ -1,5 +1,5 @@
1
- const { align, concat, group, join, line } = require("../prettier");
2
- const { literal } = require("../utils");
1
+ const { align, concat, group, join, line } = require("../../prettier");
2
+ const { literal } = require("../../utils");
3
3
 
4
4
  function printSuper(path, opts, print) {
5
5
  const args = path.getValue().body[0];
@@ -5,7 +5,7 @@ const {
5
5
  group,
6
6
  join,
7
7
  line
8
- } = require("../prettier");
8
+ } = require("../../prettier");
9
9
 
10
10
  function printUndefSymbol(path, opts, print) {
11
11
  const node = path.getValue();
@@ -4,6 +4,7 @@ const path = require("path");
4
4
  // In order to properly parse ruby code, we need to tell the ruby process to
5
5
  // parse using UTF-8. Unfortunately, the way that you accomplish this looks
6
6
  // differently depending on your platform.
7
+ /* istanbul ignore next */
7
8
  const LANG = (() => {
8
9
  const { env, platform } = process;
9
10
  const envValue = env.LC_ALL || env.LC_CTYPE || env.LANG;
@@ -42,7 +43,7 @@ function parse(text, _parsers, _opts) {
42
43
  {
43
44
  env: Object.assign({}, process.env, { LANG }),
44
45
  input: text,
45
- maxBuffer: 10 * 1024 * 1024 // 10MB
46
+ maxBuffer: 15 * 1024 * 1024 // 15MB
46
47
  }
47
48
  );
48
49
 
@@ -67,14 +68,14 @@ function hasPragma(text) {
67
68
  // for returning the index of the character within the source string that is the
68
69
  // beginning of the given node.
69
70
  function locStart(node) {
70
- return node.char_start;
71
+ return node.sc;
71
72
  }
72
73
 
73
74
  // This function is critical for comments and cursor support, and is responsible
74
75
  // for returning the index of the character within the source string that is the
75
76
  // ending of the given node.
76
77
  function locEnd(node) {
77
- return node.char_end;
78
+ return node.ec;
78
79
  }
79
80
 
80
81
  module.exports = {
@@ -63,14 +63,14 @@ class Prettier::Parser < Ripper
63
63
  # would happen to be the innermost keyword). Then the outer one would only be
64
64
  # able to grab the first one. In this way all of the scanner events act as
65
65
  # their own stack.
66
- def find_scanner_event(type, body = :any)
66
+ def find_scanner_event(type, body = :any, consume: true)
67
67
  index =
68
68
  scanner_events.rindex do |scanner_event|
69
69
  scanner_event[:type] == type &&
70
70
  (body == :any || (scanner_event[:body] == body))
71
71
  end
72
72
 
73
- scanner_events.delete_at(index)
73
+ consume ? scanner_events.delete_at(index) : (index && scanner_events[index])
74
74
  end
75
75
 
76
76
  # Scanner events occur when the lexer hits a new token, like a keyword or an
@@ -89,14 +89,14 @@ class Prettier::Parser < Ripper
89
89
 
90
90
  (SCANNER_EVENTS - defined).each do |event|
91
91
  define_method(:"on_#{event}") do |value|
92
- char_end = char_pos + value.size
92
+ ec = char_pos + value.size
93
93
  node = {
94
94
  type: :"@#{event}",
95
95
  body: value,
96
- start: lineno,
97
- end: lineno,
98
- char_start: char_pos,
99
- char_end: char_end
96
+ sl: lineno,
97
+ el: lineno,
98
+ sc: char_pos,
99
+ ec: ec
100
100
  }
101
101
 
102
102
  scanner_events << node
@@ -118,10 +118,10 @@ class Prettier::Parser < Ripper
118
118
  @comments << {
119
119
  type: :@comment,
120
120
  value: value[1..-1].chomp.force_encoding('UTF-8'),
121
- start: lineno,
122
- end: lineno,
123
- char_start: char_pos,
124
- char_end: char_pos + value.length - 1
121
+ sl: lineno,
122
+ el: lineno,
123
+ sc: char_pos,
124
+ ec: char_pos + value.length - 1
125
125
  }
126
126
  end
127
127
 
@@ -138,10 +138,10 @@ class Prettier::Parser < Ripper
138
138
  {
139
139
  type: :ignored_nl,
140
140
  body: nil,
141
- start: lineno,
142
- end: lineno,
143
- char_start: char_pos,
144
- char_end: char_pos
141
+ sl: lineno,
142
+ el: lineno,
143
+ sc: char_pos,
144
+ ec: char_pos
145
145
  }
146
146
  end
147
147
 
@@ -186,16 +186,13 @@ class Prettier::Parser < Ripper
186
186
  beging = find_scanner_event(:@lbrace)
187
187
  ending = find_scanner_event(:@rbrace)
188
188
 
189
- stmts.bind(
190
- find_next_statement_start(beging[:char_end]),
191
- ending[:char_start]
192
- )
189
+ stmts.bind(find_next_statement_start(beging[:ec]), ending[:sc])
193
190
 
194
191
  find_scanner_event(:@kw, 'BEGIN').merge!(
195
192
  type: :BEGIN,
196
193
  body: [beging, stmts],
197
- end: ending[:end],
198
- char_end: ending[:char_end]
194
+ el: ending[:el],
195
+ ec: ending[:ec]
199
196
  )
200
197
  end
201
198
 
@@ -213,16 +210,13 @@ class Prettier::Parser < Ripper
213
210
  beging = find_scanner_event(:@lbrace)
214
211
  ending = find_scanner_event(:@rbrace)
215
212
 
216
- stmts.bind(
217
- find_next_statement_start(beging[:char_end]),
218
- ending[:char_start]
219
- )
213
+ stmts.bind(find_next_statement_start(beging[:ec]), ending[:sc])
220
214
 
221
215
  find_scanner_event(:@kw, 'END').merge!(
222
216
  type: :END,
223
217
  body: [beging, stmts],
224
- end: ending[:end],
225
- char_end: ending[:char_end]
218
+ el: ending[:el],
219
+ ec: ending[:ec]
226
220
  )
227
221
  end
228
222
 
@@ -234,16 +228,16 @@ class Prettier::Parser < Ripper
234
228
  def on_alias(left, right)
235
229
  beging = find_scanner_event(:@kw, 'alias')
236
230
 
237
- paren = source[beging[:char_end]...left[:char_start]].include?('(')
231
+ paren = source[beging[:ec]...left[:sc]].include?('(')
238
232
  ending = paren ? find_scanner_event(:@rparen) : right
239
233
 
240
234
  {
241
235
  type: :alias,
242
236
  body: [left, right],
243
- start: beging[:start],
244
- char_start: beging[:char_start],
245
- end: ending[:end],
246
- char_end: ending[:char_end]
237
+ sl: beging[:sl],
238
+ sc: beging[:sc],
239
+ el: ending[:el],
240
+ ec: ending[:ec]
247
241
  }
248
242
  end
249
243
 
@@ -268,10 +262,10 @@ class Prettier::Parser < Ripper
268
262
  {
269
263
  type: :aref,
270
264
  body: [collection, index],
271
- start: collection[:start],
272
- char_start: collection[:char_start],
273
- end: ending[:end],
274
- char_end: ending[:char_end]
265
+ sl: collection[:sl],
266
+ sc: collection[:sc],
267
+ el: ending[:el],
268
+ ec: ending[:ec]
275
269
  }
276
270
  end
277
271
 
@@ -284,10 +278,10 @@ class Prettier::Parser < Ripper
284
278
  {
285
279
  type: :aref_field,
286
280
  body: [collection, index],
287
- start: collection[:start],
288
- char_start: collection[:char_start],
289
- end: ending[:end],
290
- char_end: ending[:char_end]
281
+ sl: collection[:sl],
282
+ sc: collection[:sc],
283
+ el: ending[:el],
284
+ ec: ending[:ec]
291
285
  }
292
286
  end
293
287
 
@@ -298,10 +292,10 @@ class Prettier::Parser < Ripper
298
292
  {
299
293
  type: :args,
300
294
  body: [],
301
- start: lineno,
302
- char_start: char_pos,
303
- end: lineno,
304
- char_end: char_pos
295
+ sl: lineno,
296
+ sc: char_pos,
297
+ el: lineno,
298
+ ec: char_pos
305
299
  }
306
300
  end
307
301
 
@@ -313,11 +307,7 @@ class Prettier::Parser < Ripper
313
307
  if args[:body].empty?
314
308
  arg.merge(type: :args, body: [arg])
315
309
  else
316
- args.merge!(
317
- body: args[:body] << arg,
318
- end: arg[:end],
319
- char_end: arg[:char_end]
320
- )
310
+ args.merge!(body: args[:body] << arg, el: arg[:el], ec: arg[:ec])
321
311
  end
322
312
  end
323
313
 
@@ -330,8 +320,8 @@ class Prettier::Parser < Ripper
330
320
  args.merge(
331
321
  type: :args_add_block,
332
322
  body: [args, block],
333
- end: ending[:end],
334
- char_end: ending[:char_end]
323
+ el: ending[:el],
324
+ ec: ending[:ec]
335
325
  )
336
326
  end
337
327
 
@@ -345,10 +335,10 @@ class Prettier::Parser < Ripper
345
335
  {
346
336
  type: :args_add_star,
347
337
  body: [args, part],
348
- start: beging[:start],
349
- char_start: beging[:char_start],
350
- end: ending[:end],
351
- char_end: ending[:char_end]
338
+ sl: beging[:sl],
339
+ sc: beging[:sc],
340
+ el: ending[:el],
341
+ ec: ending[:ec]
352
342
  }
353
343
  end
354
344
 
@@ -367,15 +357,15 @@ class Prettier::Parser < Ripper
367
357
  # If the arguments exceed the ending of the parentheses, then we know we
368
358
  # have a heredoc in the arguments, and we need to use the bounds of the
369
359
  # arguments to determine how large the arg_paren is.
370
- ending = (args && args[:end] > rparen[:end]) ? args : rparen
360
+ ending = (args && args[:el] > rparen[:el]) ? args : rparen
371
361
 
372
362
  {
373
363
  type: :arg_paren,
374
364
  body: [args],
375
- start: beging[:start],
376
- char_start: beging[:char_start],
377
- end: ending[:end],
378
- char_end: ending[:char_end]
365
+ sl: beging[:sl],
366
+ sc: beging[:sc],
367
+ el: ending[:el],
368
+ ec: ending[:ec]
379
369
  }
380
370
  end
381
371
 
@@ -391,20 +381,20 @@ class Prettier::Parser < Ripper
391
381
  {
392
382
  type: :array,
393
383
  body: [contents],
394
- start: beging[:start],
395
- char_start: beging[:char_start],
396
- end: ending[:end],
397
- char_end: ending[:char_end]
384
+ sl: beging[:sl],
385
+ sc: beging[:sc],
386
+ el: ending[:el],
387
+ ec: ending[:ec]
398
388
  }
399
389
  else
400
390
  ending = find_scanner_event(:@tstring_end)
401
- contents[:char_end] = ending[:char_end]
391
+ contents[:ec] = ending[:ec]
402
392
 
403
393
  ending.merge!(
404
394
  type: :array,
405
395
  body: [contents],
406
- start: contents[:start],
407
- char_start: contents[:char_start]
396
+ sl: contents[:sl],
397
+ sc: contents[:sc]
408
398
  )
409
399
  end
410
400
  end
@@ -417,10 +407,10 @@ class Prettier::Parser < Ripper
417
407
  {
418
408
  type: :aryptn,
419
409
  body: [const, preargs, splatarg, postargs],
420
- start: pieces[0][:start],
421
- char_start: pieces[0][:char_start],
422
- end: pieces[-1][:end],
423
- char_end: pieces[-1][:char_end]
410
+ sl: pieces[0][:sl],
411
+ sc: pieces[0][:sc],
412
+ el: pieces[-1][:el],
413
+ ec: pieces[-1][:ec]
424
414
  }
425
415
  end
426
416
 
@@ -431,8 +421,8 @@ class Prettier::Parser < Ripper
431
421
  left.merge(
432
422
  type: :assign,
433
423
  body: [left, right],
434
- end: right[:end],
435
- char_end: right[:char_end]
424
+ el: right[:el],
425
+ ec: right[:ec]
436
426
  )
437
427
  end
438
428
 
@@ -443,10 +433,10 @@ class Prettier::Parser < Ripper
443
433
  {
444
434
  type: :assoc_new,
445
435
  body: [key, value],
446
- start: key[:start],
447
- char_start: key[:char_start],
448
- end: value[:end],
449
- char_end: value[:char_end]
436
+ sl: key[:sl],
437
+ sc: key[:sc],
438
+ el: value[:el],
439
+ ec: value[:ec]
450
440
  }
451
441
  end
452
442
 
@@ -456,8 +446,8 @@ class Prettier::Parser < Ripper
456
446
  find_scanner_event(:@op, '**').merge!(
457
447
  type: :assoc_splat,
458
448
  body: [contents],
459
- end: contents[:end],
460
- char_end: contents[:char_end]
449
+ el: contents[:el],
450
+ ec: contents[:ec]
461
451
  )
462
452
  end
463
453
 
@@ -469,10 +459,10 @@ class Prettier::Parser < Ripper
469
459
  {
470
460
  type: :assoclist_from_args,
471
461
  body: assocs,
472
- start: assocs[0][:start],
473
- char_start: assocs[0][:char_start],
474
- end: assocs[-1][:end],
475
- char_end: assocs[-1][:char_end]
462
+ sl: assocs[0][:sl],
463
+ sc: assocs[0][:sc],
464
+ el: assocs[-1][:el],
465
+ ec: assocs[-1][:ec]
476
466
  }
477
467
  end
478
468
 
@@ -484,10 +474,10 @@ class Prettier::Parser < Ripper
484
474
  {
485
475
  type: :bare_assoc_hash,
486
476
  body: assoc_news,
487
- start: assoc_news[0][:start],
488
- char_start: assoc_news[0][:char_start],
489
- end: assoc_news[-1][:end],
490
- char_end: assoc_news[-1][:char_end]
477
+ sl: assoc_news[0][:sl],
478
+ sc: assoc_news[0][:sc],
479
+ el: assoc_news[-1][:el],
480
+ ec: assoc_news[-1][:ec]
491
481
  }
492
482
  end
493
483
 
@@ -495,20 +485,20 @@ class Prettier::Parser < Ripper
495
485
  # It includes a bodystmt event that has all of the consequent clauses.
496
486
  def on_begin(bodystmt)
497
487
  beging = find_scanner_event(:@kw, 'begin')
498
- char_end =
488
+ ec =
499
489
  if bodystmt[:body][1..-1].any?
500
- bodystmt[:char_end]
490
+ bodystmt[:ec]
501
491
  else
502
- find_scanner_event(:@kw, 'end')[:char_end]
492
+ find_scanner_event(:@kw, 'end')[:ec]
503
493
  end
504
494
 
505
- bodystmt.bind(beging[:char_end], char_end)
495
+ bodystmt.bind(beging[:ec], ec)
506
496
 
507
497
  beging.merge!(
508
498
  type: :begin,
509
499
  body: [bodystmt],
510
- end: bodystmt[:end],
511
- char_end: bodystmt[:char_end]
500
+ el: bodystmt[:el],
501
+ ec: bodystmt[:ec]
512
502
  )
513
503
  end
514
504
 
@@ -518,10 +508,10 @@ class Prettier::Parser < Ripper
518
508
  {
519
509
  type: :binary,
520
510
  body: [left, oper, right],
521
- start: left[:start],
522
- char_start: left[:char_start],
523
- end: right[:end],
524
- char_end: right[:char_end]
511
+ sl: left[:sl],
512
+ sc: left[:sc],
513
+ el: right[:el],
514
+ ec: right[:ec]
525
515
  }
526
516
  end
527
517
 
@@ -531,7 +521,7 @@ class Prettier::Parser < Ripper
531
521
  index =
532
522
  scanner_events.rindex do |event|
533
523
  event[:type] == :@op && %w[| ||].include?(event[:body]) &&
534
- event[:char_start] < params[:char_start]
524
+ event[:sc] < params[:sc]
535
525
  end
536
526
 
537
527
  beging = scanner_events[index]
@@ -540,10 +530,10 @@ class Prettier::Parser < Ripper
540
530
  {
541
531
  type: :block_var,
542
532
  body: [params, locals],
543
- start: beging[:start],
544
- char_start: beging[:char_start],
545
- end: ending[:end],
546
- char_end: ending[:char_end]
533
+ sl: beging[:sl],
534
+ sc: beging[:sc],
535
+ el: ending[:el],
536
+ ec: ending[:ec]
547
537
  }
548
538
  end
549
539
 
@@ -553,8 +543,8 @@ class Prettier::Parser < Ripper
553
543
  find_scanner_event(:@op, '&').merge!(
554
544
  type: :blockarg,
555
545
  body: [ident],
556
- end: ident[:end],
557
- char_end: ident[:char_end]
546
+ el: ident[:el],
547
+ ec: ident[:ec]
558
548
  )
559
549
  end
560
550
 
@@ -562,21 +552,18 @@ class Prettier::Parser < Ripper
562
552
  # doesn't necessarily know where it started. So the parent node needs to
563
553
  # report back down into this one where it goes.
564
554
  class BodyStmt < SimpleDelegator
565
- def bind(char_start, char_end)
566
- merge!(char_start: char_start, char_end: char_end)
555
+ def bind(sc, ec)
556
+ merge!(sc: sc, ec: ec)
567
557
  parts = self[:body]
568
558
 
569
559
  # Here we're going to determine the bounds for the stmts
570
560
  consequent = parts[1..-1].compact.first
571
- self[:body][0].bind(
572
- char_start,
573
- consequent ? consequent[:char_start] : char_end
574
- )
561
+ self[:body][0].bind(sc, consequent ? consequent[:sc] : ec)
575
562
 
576
563
  # Next we're going to determine the rescue clause if there is one
577
564
  if parts[1]
578
565
  consequent = parts[2..-1].compact.first
579
- self[:body][1].bind_end(consequent ? consequent[:char_start] : char_end)
566
+ self[:body][1].bind_end(consequent ? consequent[:sc] : ec)
580
567
  end
581
568
  end
582
569
  end
@@ -587,10 +574,10 @@ class Prettier::Parser < Ripper
587
574
  BodyStmt.new(
588
575
  type: :bodystmt,
589
576
  body: [stmts, rescued, ensured, elsed],
590
- start: lineno,
591
- char_start: char_pos,
592
- end: lineno,
593
- char_end: char_pos
577
+ sl: lineno,
578
+ sc: char_pos,
579
+ el: lineno,
580
+ ec: char_pos
594
581
  )
595
582
  end
596
583
 
@@ -602,15 +589,15 @@ class Prettier::Parser < Ripper
602
589
  beging = find_scanner_event(:@lbrace)
603
590
  ending = find_scanner_event(:@rbrace)
604
591
 
605
- stmts.bind((block_var || beging)[:char_end], ending[:char_start])
592
+ stmts.bind((block_var || beging)[:ec], ending[:sc])
606
593
 
607
594
  {
608
595
  type: :brace_block,
609
596
  body: [block_var, stmts],
610
- start: beging[:start],
611
- char_start: beging[:char_start],
612
- end: ending[:end],
613
- char_end: ending[:char_end]
597
+ sl: beging[:sl],
598
+ sc: beging[:sc],
599
+ el: ending[:el],
600
+ ec: ending[:ec]
614
601
  }
615
602
  end
616
603
 
@@ -630,8 +617,8 @@ class Prettier::Parser < Ripper
630
617
  beging.merge!(
631
618
  type: :break,
632
619
  body: [args_add_block],
633
- end: args_add_block[:end],
634
- char_end: args_add_block[:char_end]
620
+ el: args_add_block[:el],
621
+ ec: args_add_block[:ec]
635
622
  )
636
623
  end
637
624
 
@@ -647,10 +634,6 @@ class Prettier::Parser < Ripper
647
634
  # foo.(1, 2, 3)
648
635
  #
649
636
  def on_call(receiver, oper, sending)
650
- # Make sure we take the operator out of the scanner events so that it
651
- # doesn't get confused for a unary operator later.
652
- scanner_events.delete(oper)
653
-
654
637
  ending = sending
655
638
 
656
639
  if sending == :call
@@ -664,10 +647,10 @@ class Prettier::Parser < Ripper
664
647
  {
665
648
  type: :call,
666
649
  body: [receiver, oper, sending],
667
- start: receiver[:start],
668
- char_start: receiver[:char_start],
669
- end: ending[:end],
670
- char_end: ending[:char_end]
650
+ sl: receiver[:sl],
651
+ sc: receiver[:sc],
652
+ el: ending[:el],
653
+ ec: ending[:ec]
671
654
  }
672
655
  end
673
656
 
@@ -675,11 +658,18 @@ class Prettier::Parser < Ripper
675
658
  # It accepts as arguments the switch of the case and the consequent
676
659
  # clause.
677
660
  def on_case(switch, consequent)
678
- find_scanner_event(:@kw, 'case').merge!(
679
- type: :case,
661
+ beging =
662
+ if event = find_scanner_event(:@kw, 'case', consume: false)
663
+ scanner_events.delete(event).merge!(type: :case)
664
+ else
665
+ keyword = find_scanner_event(:@kw, 'in', consume: false)
666
+ switch.merge(type: :rassign, keyword: keyword)
667
+ end
668
+
669
+ beging.merge!(
680
670
  body: [switch, consequent],
681
- end: consequent[:end],
682
- char_end: consequent[:char_end]
671
+ el: consequent[:el],
672
+ ec: consequent[:ec]
683
673
  )
684
674
  end
685
675
 
@@ -713,17 +703,17 @@ class Prettier::Parser < Ripper
713
703
  ending = find_scanner_event(:@kw, 'end')
714
704
 
715
705
  bodystmt.bind(
716
- find_next_statement_start((superclass || const)[:char_end]),
717
- ending[:char_start]
706
+ find_next_statement_start((superclass || const)[:ec]),
707
+ ending[:sc]
718
708
  )
719
709
 
720
710
  {
721
711
  type: :class,
722
712
  body: [const, superclass, bodystmt],
723
- start: beging[:start],
724
- char_start: beging[:char_start],
725
- end: ending[:end],
726
- char_end: ending[:char_end]
713
+ sl: beging[:sl],
714
+ sc: beging[:sc],
715
+ el: ending[:el],
716
+ ec: ending[:ec]
727
717
  }
728
718
  end
729
719
 
@@ -734,10 +724,10 @@ class Prettier::Parser < Ripper
734
724
  {
735
725
  type: :command,
736
726
  body: [ident, args],
737
- start: ident[:start],
738
- char_start: ident[:char_start],
739
- end: args[:end],
740
- char_end: args[:char_end]
727
+ sl: ident[:sl],
728
+ sc: ident[:sc],
729
+ el: args[:el],
730
+ ec: args[:ec]
741
731
  }
742
732
  end
743
733
 
@@ -751,10 +741,10 @@ class Prettier::Parser < Ripper
751
741
  {
752
742
  type: :command_call,
753
743
  body: [receiver, oper, ident, args],
754
- start: receiver[:start],
755
- char_start: receiver[:char_start],
756
- end: ending[:end],
757
- char_end: ending[:char_end]
744
+ sl: receiver[:sl],
745
+ sc: receiver[:sc],
746
+ el: ending[:el],
747
+ ec: ending[:ec]
758
748
  }
759
749
  end
760
750
 
@@ -768,10 +758,10 @@ class Prettier::Parser < Ripper
768
758
  {
769
759
  type: :const_path_field,
770
760
  body: [left, const],
771
- start: left[:start],
772
- char_start: left[:char_start],
773
- end: const[:end],
774
- char_end: const[:char_end]
761
+ sl: left[:sl],
762
+ sc: left[:sc],
763
+ el: const[:el],
764
+ ec: const[:ec]
775
765
  }
776
766
  end
777
767
 
@@ -785,10 +775,10 @@ class Prettier::Parser < Ripper
785
775
  {
786
776
  type: :const_path_ref,
787
777
  body: [left, const],
788
- start: left[:start],
789
- char_start: left[:char_start],
790
- end: const[:end],
791
- char_end: const[:char_end]
778
+ sl: left[:sl],
779
+ sc: left[:sc],
780
+ el: const[:el],
781
+ ec: const[:ec]
792
782
  }
793
783
  end
794
784
 
@@ -832,39 +822,36 @@ class Prettier::Parser < Ripper
832
822
  # and normal method definitions.
833
823
  beging = find_scanner_event(:@kw, 'def')
834
824
 
835
- # If there is not a params node, then we have a single-line method
836
- unless params
825
+ # If we don't have a bodystmt node, then we have a single-line method
826
+ if bodystmt[:type] != :bodystmt
837
827
  return(
838
828
  {
839
829
  type: :defsl,
840
- body: [ident, bodystmt],
841
- start: beging[:start],
842
- char_start: beging[:char_start],
843
- end: bodystmt[:end],
844
- char_end: bodystmt[:char_end]
830
+ body: [ident, params, bodystmt],
831
+ sl: beging[:sl],
832
+ sc: beging[:sc],
833
+ el: bodystmt[:el],
834
+ ec: bodystmt[:ec]
845
835
  }
846
836
  )
847
837
  end
848
838
 
849
839
  if params[:type] == :params && !params[:body].any?
850
- location = ident[:char_end]
851
- params.merge!(char_start: location, char_end: location)
840
+ location = ident[:ec]
841
+ params.merge!(sc: location, ec: location)
852
842
  end
853
843
 
854
844
  ending = find_scanner_event(:@kw, 'end')
855
845
 
856
- bodystmt.bind(
857
- find_next_statement_start(params[:char_end]),
858
- ending[:char_start]
859
- )
846
+ bodystmt.bind(find_next_statement_start(params[:ec]), ending[:sc])
860
847
 
861
848
  {
862
849
  type: :def,
863
850
  body: [ident, params, bodystmt],
864
- start: beging[:start],
865
- char_start: beging[:char_start],
866
- end: ending[:end],
867
- char_end: ending[:char_end]
851
+ sl: beging[:sl],
852
+ sc: beging[:sc],
853
+ el: ending[:el],
854
+ ec: ending[:ec]
868
855
  }
869
856
  end
870
857
 
@@ -889,25 +876,22 @@ class Prettier::Parser < Ripper
889
876
  scanner_events.delete(ident)
890
877
 
891
878
  if params[:type] == :params && !params[:body].any?
892
- location = ident[:char_end]
893
- params.merge!(char_start: location, char_end: location)
879
+ location = ident[:ec]
880
+ params.merge!(sc: location, ec: location)
894
881
  end
895
882
 
896
883
  beging = find_scanner_event(:@kw, 'def')
897
884
  ending = find_scanner_event(:@kw, 'end')
898
885
 
899
- bodystmt.bind(
900
- find_next_statement_start(params[:char_end]),
901
- ending[:char_start]
902
- )
886
+ bodystmt.bind(find_next_statement_start(params[:ec]), ending[:sc])
903
887
 
904
888
  {
905
889
  type: :defs,
906
890
  body: [target, oper, ident, params, bodystmt],
907
- start: beging[:start],
908
- char_start: beging[:char_start],
909
- end: ending[:end],
910
- char_end: ending[:char_end]
891
+ sl: beging[:sl],
892
+ sc: beging[:sc],
893
+ el: ending[:el],
894
+ ec: ending[:ec]
911
895
  }
912
896
  end
913
897
 
@@ -918,14 +902,14 @@ class Prettier::Parser < Ripper
918
902
  def on_defined(value)
919
903
  beging = find_scanner_event(:@kw, 'defined?')
920
904
 
921
- paren = source[beging[:char_end]...value[:char_start]].include?('(')
905
+ paren = source[beging[:ec]...value[:sc]].include?('(')
922
906
  ending = paren ? find_scanner_event(:@rparen) : value
923
907
 
924
908
  beging.merge!(
925
909
  type: :defined,
926
910
  body: [value],
927
- end: ending[:end],
928
- char_end: ending[:char_end]
911
+ el: ending[:el],
912
+ ec: ending[:ec]
929
913
  )
930
914
  end
931
915
 
@@ -937,15 +921,15 @@ class Prettier::Parser < Ripper
937
921
  beging = find_scanner_event(:@kw, 'do')
938
922
  ending = find_scanner_event(:@kw, 'end')
939
923
 
940
- bodystmt.bind((block_var || beging)[:char_end], ending[:char_start])
924
+ bodystmt.bind((block_var || beging)[:ec], ending[:sc])
941
925
 
942
926
  {
943
927
  type: :do_block,
944
928
  body: [block_var, bodystmt],
945
- start: beging[:start],
946
- char_start: beging[:char_start],
947
- end: ending[:end],
948
- char_end: ending[:char_end]
929
+ sl: beging[:sl],
930
+ sc: beging[:sc],
931
+ el: ending[:el],
932
+ ec: ending[:ec]
949
933
  }
950
934
  end
951
935
 
@@ -961,10 +945,10 @@ class Prettier::Parser < Ripper
961
945
  {
962
946
  type: :dot2,
963
947
  body: [left, right],
964
- start: beging[:start],
965
- char_start: beging[:char_start],
966
- end: ending[:end],
967
- char_end: ending[:char_end]
948
+ sl: beging[:sl],
949
+ sc: beging[:sc],
950
+ el: ending[:el],
951
+ ec: ending[:ec]
968
952
  }
969
953
  end
970
954
 
@@ -980,10 +964,10 @@ class Prettier::Parser < Ripper
980
964
  {
981
965
  type: :dot3,
982
966
  body: [left, right],
983
- start: beging[:start],
984
- char_start: beging[:char_start],
985
- end: ending[:end],
986
- char_end: ending[:char_end]
967
+ sl: beging[:sl],
968
+ sc: beging[:sc],
969
+ el: ending[:el],
970
+ ec: ending[:ec]
987
971
  }
988
972
  end
989
973
 
@@ -1006,7 +990,7 @@ class Prettier::Parser < Ripper
1006
990
  #
1007
991
  # which would be the same symbol as above.
1008
992
  def on_dyna_symbol(string)
1009
- if scanner_events.any? { |event| event[:type] == :@symbeg }
993
+ if find_scanner_event(:@symbeg, consume: false)
1010
994
  # A normal dynamic symbol
1011
995
  beging = find_scanner_event(:@symbeg)
1012
996
  ending = find_scanner_event(:@tstring_end)
@@ -1015,8 +999,8 @@ class Prettier::Parser < Ripper
1015
999
  type: :dyna_symbol,
1016
1000
  quote: beging[:body][1],
1017
1001
  body: string[:body],
1018
- end: ending[:end],
1019
- char_end: ending[:char_end]
1002
+ el: ending[:el],
1003
+ ec: ending[:ec]
1020
1004
  )
1021
1005
  else
1022
1006
  # A dynamic symbol as a hash key
@@ -1026,10 +1010,10 @@ class Prettier::Parser < Ripper
1026
1010
  string.merge!(
1027
1011
  type: :dyna_symbol,
1028
1012
  quote: ending[:body][0],
1029
- start: beging[:start],
1030
- char_start: beging[:char_start],
1031
- end: ending[:end],
1032
- char_end: ending[:char_end]
1013
+ sl: beging[:sl],
1014
+ sc: beging[:sc],
1015
+ el: ending[:el],
1016
+ ec: ending[:ec]
1033
1017
  )
1034
1018
  end
1035
1019
  end
@@ -1054,15 +1038,15 @@ class Prettier::Parser < Ripper
1054
1038
  beging = find_scanner_event(:@kw, 'else')
1055
1039
  ending = find_else_ending
1056
1040
 
1057
- stmts.bind(beging[:char_end], ending[:char_start])
1041
+ stmts.bind(beging[:ec], ending[:sc])
1058
1042
 
1059
1043
  {
1060
1044
  type: :else,
1061
1045
  body: [stmts],
1062
- start: beging[:start],
1063
- char_start: beging[:char_start],
1064
- end: ending[:end],
1065
- char_end: ending[:char_end]
1046
+ sl: beging[:sl],
1047
+ sc: beging[:sc],
1048
+ el: ending[:el],
1049
+ ec: ending[:ec]
1066
1050
  }
1067
1051
  end
1068
1052
 
@@ -1074,15 +1058,15 @@ class Prettier::Parser < Ripper
1074
1058
  beging = find_scanner_event(:@kw, 'elsif')
1075
1059
  ending = consequent || find_scanner_event(:@kw, 'end')
1076
1060
 
1077
- stmts.bind(predicate[:char_end], ending[:char_start])
1061
+ stmts.bind(predicate[:ec], ending[:sc])
1078
1062
 
1079
1063
  {
1080
1064
  type: :elsif,
1081
1065
  body: [predicate, stmts, consequent],
1082
- start: beging[:start],
1083
- char_start: beging[:char_start],
1084
- end: ending[:end],
1085
- char_end: ending[:char_end]
1066
+ sl: beging[:sl],
1067
+ sc: beging[:sc],
1068
+ el: ending[:el],
1069
+ ec: ending[:ec]
1086
1070
  }
1087
1071
  end
1088
1072
 
@@ -1092,12 +1076,7 @@ class Prettier::Parser < Ripper
1092
1076
  # and add to it as we get content. It always starts with this scanner
1093
1077
  # event, so here we'll initialize the current embdoc.
1094
1078
  def on_embdoc_beg(value)
1095
- @embdoc = {
1096
- type: :@embdoc,
1097
- value: value,
1098
- start: lineno,
1099
- char_start: char_pos
1100
- }
1079
+ @embdoc = { type: :@embdoc, value: value, sl: lineno, sc: char_pos }
1101
1080
  end
1102
1081
 
1103
1082
  # This is a scanner event that gets hit when we're inside an embdoc and
@@ -1116,8 +1095,8 @@ class Prettier::Parser < Ripper
1116
1095
  @comments <<
1117
1096
  @embdoc.merge!(
1118
1097
  value: @embdoc[:value] << value.chomp,
1119
- end: lineno,
1120
- char_end: char_pos + value.length - 1
1098
+ el: lineno,
1099
+ ec: char_pos + value.length - 1
1121
1100
  )
1122
1101
 
1123
1102
  @embdoc = nil
@@ -1136,18 +1115,15 @@ class Prettier::Parser < Ripper
1136
1115
  end
1137
1116
 
1138
1117
  ending = scanner_events[index]
1139
- stmts.bind(
1140
- find_next_statement_start(beging[:char_end]),
1141
- ending[:char_start]
1142
- )
1118
+ stmts.bind(find_next_statement_start(beging[:ec]), ending[:sc])
1143
1119
 
1144
1120
  {
1145
1121
  type: :ensure,
1146
1122
  body: [beging, stmts],
1147
- start: beging[:start],
1148
- char_start: beging[:char_start],
1149
- end: ending[:end],
1150
- char_end: ending[:char_end]
1123
+ sl: beging[:sl],
1124
+ sc: beging[:sc],
1125
+ el: ending[:el],
1126
+ ec: ending[:ec]
1151
1127
  }
1152
1128
  end
1153
1129
 
@@ -1175,10 +1151,10 @@ class Prettier::Parser < Ripper
1175
1151
  {
1176
1152
  type: :field,
1177
1153
  body: [left, oper, right],
1178
- start: left[:start],
1179
- char_start: left[:char_start],
1180
- end: right[:end],
1181
- char_end: right[:char_end]
1154
+ sl: left[:sl],
1155
+ sc: left[:sc],
1156
+ el: right[:el],
1157
+ ec: right[:ec]
1182
1158
  }
1183
1159
  end
1184
1160
 
@@ -1188,15 +1164,13 @@ class Prettier::Parser < Ripper
1188
1164
  beging = const || find_scanner_event(:@lbracket)
1189
1165
  ending = find_scanner_event(:@rbracket)
1190
1166
 
1191
- pieces = [const, presplat, *args, postsplat].compact
1192
-
1193
1167
  {
1194
1168
  type: :fndptn,
1195
1169
  body: [const, presplat, args, postsplat],
1196
- start: beging[:start],
1197
- char_start: beging[:char_start],
1198
- end: ending[:end],
1199
- char_end: ending[:char_end]
1170
+ sl: beging[:sl],
1171
+ sc: beging[:sc],
1172
+ el: ending[:el],
1173
+ ec: ending[:ec]
1200
1174
  }
1201
1175
  end
1202
1176
 
@@ -1208,15 +1182,15 @@ class Prettier::Parser < Ripper
1208
1182
  beging = find_scanner_event(:@kw, 'for')
1209
1183
  ending = find_scanner_event(:@kw, 'end')
1210
1184
 
1211
- stmts.bind(enumerable[:char_end], ending[:char_start])
1185
+ stmts.bind(enumerable[:ec], ending[:sc])
1212
1186
 
1213
1187
  {
1214
1188
  type: :for,
1215
1189
  body: [ident, enumerable, stmts],
1216
- start: beging[:start],
1217
- char_start: beging[:char_start],
1218
- end: ending[:end],
1219
- char_end: ending[:char_end]
1190
+ sl: beging[:sl],
1191
+ sc: beging[:sc],
1192
+ el: ending[:el],
1193
+ ec: ending[:ec]
1220
1194
  }
1221
1195
  end
1222
1196
 
@@ -1230,19 +1204,16 @@ class Prettier::Parser < Ripper
1230
1204
  if assoclist_from_args
1231
1205
  # Here we're going to expand out the location information for the assocs
1232
1206
  # node so that it can grab up any remaining comments inside the hash.
1233
- assoclist_from_args.merge!(
1234
- char_start: beging[:char_end],
1235
- char_end: ending[:char_start]
1236
- )
1207
+ assoclist_from_args.merge!(sc: beging[:ec], ec: ending[:sc])
1237
1208
  end
1238
1209
 
1239
1210
  {
1240
1211
  type: :hash,
1241
1212
  body: [assoclist_from_args],
1242
- start: beging[:start],
1243
- char_start: beging[:char_start],
1244
- end: ending[:end],
1245
- char_end: ending[:char_end]
1213
+ sl: beging[:sl],
1214
+ sc: beging[:sc],
1215
+ el: ending[:el],
1216
+ ec: ending[:ec]
1246
1217
  }
1247
1218
  end
1248
1219
 
@@ -1254,10 +1225,10 @@ class Prettier::Parser < Ripper
1254
1225
  # printer through our embed function.
1255
1226
  def on_heredoc_beg(beging)
1256
1227
  location = {
1257
- start: lineno,
1258
- end: lineno,
1259
- char_start: char_pos,
1260
- char_end: char_pos + beging.length + 1
1228
+ sl: lineno,
1229
+ el: lineno,
1230
+ sc: char_pos,
1231
+ ec: char_pos + beging.length + 1
1261
1232
  }
1262
1233
 
1263
1234
  # Here we're going to artificially create an extra node type so that if
@@ -1279,7 +1250,7 @@ class Prettier::Parser < Ripper
1279
1250
 
1280
1251
  # This is a scanner event that represents the end of the heredoc.
1281
1252
  def on_heredoc_end(ending)
1282
- @heredocs[-1].merge!(ending: ending.chomp, end: lineno, char_end: char_pos)
1253
+ @heredocs[-1].merge!(ending: ending.chomp, el: lineno, ec: char_pos)
1283
1254
  end
1284
1255
 
1285
1256
  # hshptn is a parser event that represents matching against a hash pattern
@@ -1290,10 +1261,10 @@ class Prettier::Parser < Ripper
1290
1261
  {
1291
1262
  type: :hshptn,
1292
1263
  body: [const, kw, kwrest],
1293
- start: pieces[0][:start],
1294
- char_start: pieces[0][:char_start],
1295
- end: pieces[-1][:end],
1296
- char_end: pieces[-1][:char_end]
1264
+ sl: pieces[0][:sl],
1265
+ sc: pieces[0][:sc],
1266
+ el: pieces[-1][:el],
1267
+ ec: pieces[-1][:ec]
1297
1268
  }
1298
1269
  end
1299
1270
 
@@ -1304,15 +1275,15 @@ class Prettier::Parser < Ripper
1304
1275
  beging = find_scanner_event(:@kw, 'if')
1305
1276
  ending = consequent || find_scanner_event(:@kw, 'end')
1306
1277
 
1307
- stmts.bind(predicate[:char_end], ending[:char_start])
1278
+ stmts.bind(predicate[:ec], ending[:sc])
1308
1279
 
1309
1280
  {
1310
1281
  type: :if,
1311
1282
  body: [predicate, stmts, consequent],
1312
- start: beging[:start],
1313
- char_start: beging[:char_start],
1314
- end: ending[:end],
1315
- char_end: ending[:char_end]
1283
+ sl: beging[:sl],
1284
+ sc: beging[:sc],
1285
+ el: ending[:el],
1286
+ ec: ending[:ec]
1316
1287
  }
1317
1288
  end
1318
1289
 
@@ -1323,8 +1294,8 @@ class Prettier::Parser < Ripper
1323
1294
  predicate.merge(
1324
1295
  type: :ifop,
1325
1296
  body: [predicate, truthy, falsy],
1326
- end: falsy[:end],
1327
- char_end: falsy[:char_end]
1297
+ el: falsy[:el],
1298
+ ec: falsy[:ec]
1328
1299
  )
1329
1300
  end
1330
1301
 
@@ -1337,26 +1308,30 @@ class Prettier::Parser < Ripper
1337
1308
  {
1338
1309
  type: :if_mod,
1339
1310
  body: [predicate, statement],
1340
- start: statement[:start],
1341
- char_start: statement[:char_start],
1342
- end: predicate[:end],
1343
- char_end: predicate[:char_end]
1311
+ sl: statement[:sl],
1312
+ sc: statement[:sc],
1313
+ el: predicate[:el],
1314
+ ec: predicate[:ec]
1344
1315
  }
1345
1316
  end
1346
1317
 
1347
1318
  # in is a parser event that represents using the in keyword within the
1348
- # Ruby 2.7+ pattern matching syntax.
1319
+ # Ruby 2.7+ pattern matching syntax. Alternatively in Ruby 3+ it is also used
1320
+ # to handle rightward assignment for pattern matching.
1349
1321
  def on_in(pattern, stmts, consequent)
1322
+ # Here we have a rightward assignment
1323
+ return pattern unless stmts
1324
+
1350
1325
  beging = find_scanner_event(:@kw, 'in')
1351
1326
  ending = consequent || find_scanner_event(:@kw, 'end')
1352
1327
 
1353
- stmts.bind(beging[:char_end], ending[:char_start])
1328
+ stmts.bind(beging[:ec], ending[:sc])
1354
1329
 
1355
1330
  beging.merge!(
1356
1331
  type: :in,
1357
1332
  body: [pattern, stmts, consequent],
1358
- end: ending[:end],
1359
- char_end: ending[:char_end]
1333
+ el: ending[:el],
1334
+ ec: ending[:ec]
1360
1335
  )
1361
1336
  end
1362
1337
 
@@ -1369,8 +1344,8 @@ class Prettier::Parser < Ripper
1369
1344
  oper.merge!(
1370
1345
  type: :kwrest_param,
1371
1346
  body: [ident],
1372
- end: ident[:end],
1373
- char_end: ident[:char_end]
1347
+ el: ident[:el],
1348
+ ec: ident[:ec]
1374
1349
  )
1375
1350
  end
1376
1351
 
@@ -1384,23 +1359,23 @@ class Prettier::Parser < Ripper
1384
1359
  def on_lambda(params, stmts)
1385
1360
  beging = find_scanner_event(:@tlambda)
1386
1361
 
1387
- if scanner_events.any? { |event| event[:type] == :@tlambeg }
1388
- opening = find_scanner_event(:@tlambeg)
1362
+ if event = find_scanner_event(:@tlambeg, consume: false)
1363
+ opening = scanner_events.delete(event)
1389
1364
  closing = find_scanner_event(:@rbrace)
1390
1365
  else
1391
1366
  opening = find_scanner_event(:@kw, 'do')
1392
1367
  closing = find_scanner_event(:@kw, 'end')
1393
1368
  end
1394
1369
 
1395
- stmts.bind(opening[:char_end], closing[:char_start])
1370
+ stmts.bind(opening[:ec], closing[:sc])
1396
1371
 
1397
1372
  {
1398
1373
  type: :lambda,
1399
1374
  body: [params, stmts],
1400
- start: beging[:start],
1401
- char_start: beging[:char_start],
1402
- end: closing[:end],
1403
- char_end: closing[:char_end]
1375
+ sl: beging[:sl],
1376
+ sc: beging[:sc],
1377
+ el: closing[:el],
1378
+ ec: closing[:ec]
1404
1379
  }
1405
1380
  end
1406
1381
 
@@ -1422,17 +1397,15 @@ class Prettier::Parser < Ripper
1422
1397
  # in which case we need to explicitly track the comma and add it onto the
1423
1398
  # child node.
1424
1399
  def on_massign(left, right)
1425
- if source[left[:char_end]...right[:char_start]].strip.start_with?(',')
1426
- left[:comma] = true
1427
- end
1400
+ left[:comma] = true if source[left[:ec]...right[:sc]].strip.start_with?(',')
1428
1401
 
1429
1402
  {
1430
1403
  type: :massign,
1431
1404
  body: [left, right],
1432
- start: left[:start],
1433
- char_start: left[:char_start],
1434
- end: right[:end],
1435
- char_end: right[:char_end]
1405
+ sl: left[:sl],
1406
+ sc: left[:sc],
1407
+ el: right[:el],
1408
+ ec: right[:ec]
1436
1409
  }
1437
1410
  end
1438
1411
 
@@ -1451,10 +1424,10 @@ class Prettier::Parser < Ripper
1451
1424
  {
1452
1425
  type: :method_add_arg,
1453
1426
  body: [fcall, arg_paren],
1454
- start: fcall[:start],
1455
- char_start: fcall[:char_start],
1456
- end: arg_paren[:end],
1457
- char_end: arg_paren[:char_end]
1427
+ sl: fcall[:sl],
1428
+ sc: fcall[:sc],
1429
+ el: arg_paren[:el],
1430
+ ec: arg_paren[:ec]
1458
1431
  }
1459
1432
  end
1460
1433
 
@@ -1465,10 +1438,10 @@ class Prettier::Parser < Ripper
1465
1438
  {
1466
1439
  type: :method_add_block,
1467
1440
  body: [method_add_arg, block],
1468
- start: method_add_arg[:start],
1469
- char_start: method_add_arg[:char_start],
1470
- end: block[:end],
1471
- char_end: block[:char_end]
1441
+ sl: method_add_arg[:sl],
1442
+ sc: method_add_arg[:sc],
1443
+ el: block[:el],
1444
+ ec: block[:ec]
1472
1445
  }
1473
1446
  end
1474
1447
 
@@ -1479,10 +1452,10 @@ class Prettier::Parser < Ripper
1479
1452
  {
1480
1453
  type: :mlhs,
1481
1454
  body: [],
1482
- start: lineno,
1483
- char_start: char_pos,
1484
- end: lineno,
1485
- char_end: char_pos
1455
+ sl: lineno,
1456
+ sc: char_pos,
1457
+ el: lineno,
1458
+ ec: char_pos
1486
1459
  }
1487
1460
  end
1488
1461
 
@@ -1493,11 +1466,7 @@ class Prettier::Parser < Ripper
1493
1466
  if mlhs[:body].empty?
1494
1467
  part.merge(type: :mlhs, body: [part])
1495
1468
  else
1496
- mlhs.merge!(
1497
- body: mlhs[:body] << part,
1498
- end: part[:end],
1499
- char_end: part[:char_end]
1500
- )
1469
+ mlhs.merge!(body: mlhs[:body] << part, el: part[:el], ec: part[:ec])
1501
1470
  end
1502
1471
  end
1503
1472
 
@@ -1510,8 +1479,8 @@ class Prettier::Parser < Ripper
1510
1479
  mlhs_add_star.merge(
1511
1480
  type: :mlhs_add_post,
1512
1481
  body: [mlhs_add_star, mlhs],
1513
- end: mlhs[:end],
1514
- char_end: mlhs[:char_end]
1482
+ el: mlhs[:el],
1483
+ ec: mlhs[:ec]
1515
1484
  )
1516
1485
  end
1517
1486
 
@@ -1526,10 +1495,10 @@ class Prettier::Parser < Ripper
1526
1495
  {
1527
1496
  type: :mlhs_add_star,
1528
1497
  body: [mlhs, part],
1529
- start: beging[:start],
1530
- char_start: beging[:char_start],
1531
- end: ending[:end],
1532
- char_end: ending[:char_end]
1498
+ sl: beging[:sl],
1499
+ sc: beging[:sc],
1500
+ el: ending[:el],
1501
+ ec: ending[:ec]
1533
1502
  }
1534
1503
  end
1535
1504
 
@@ -1541,17 +1510,17 @@ class Prettier::Parser < Ripper
1541
1510
  beging = find_scanner_event(:@lparen)
1542
1511
  ending = find_scanner_event(:@rparen)
1543
1512
 
1544
- if source[beging[:char_end]...ending[:char_start]].strip.end_with?(',')
1513
+ if source[beging[:ec]...ending[:sc]].strip.end_with?(',')
1545
1514
  contents[:comma] = true
1546
1515
  end
1547
1516
 
1548
1517
  {
1549
1518
  type: :mlhs_paren,
1550
1519
  body: [contents],
1551
- start: beging[:start],
1552
- char_start: beging[:char_start],
1553
- end: ending[:end],
1554
- char_end: ending[:char_end]
1520
+ sl: beging[:sl],
1521
+ sc: beging[:sc],
1522
+ el: ending[:el],
1523
+ ec: ending[:ec]
1555
1524
  }
1556
1525
  end
1557
1526
 
@@ -1562,18 +1531,15 @@ class Prettier::Parser < Ripper
1562
1531
  beging = find_scanner_event(:@kw, 'module')
1563
1532
  ending = find_scanner_event(:@kw, 'end')
1564
1533
 
1565
- bodystmt.bind(
1566
- find_next_statement_start(const[:char_end]),
1567
- ending[:char_start]
1568
- )
1534
+ bodystmt.bind(find_next_statement_start(const[:ec]), ending[:sc])
1569
1535
 
1570
1536
  {
1571
1537
  type: :module,
1572
1538
  body: [const, bodystmt],
1573
- start: beging[:start],
1574
- char_start: beging[:char_start],
1575
- end: ending[:end],
1576
- char_end: ending[:char_end]
1539
+ sl: beging[:sl],
1540
+ sc: beging[:sc],
1541
+ el: ending[:el],
1542
+ ec: ending[:ec]
1577
1543
  }
1578
1544
  end
1579
1545
 
@@ -1585,10 +1551,10 @@ class Prettier::Parser < Ripper
1585
1551
  {
1586
1552
  type: :mrhs,
1587
1553
  body: [],
1588
- start: lineno,
1589
- char_start: char_pos,
1590
- end: lineno,
1591
- char_end: char_pos
1554
+ sl: lineno,
1555
+ sc: char_pos,
1556
+ el: lineno,
1557
+ ec: char_pos
1592
1558
  }
1593
1559
  end
1594
1560
 
@@ -1598,11 +1564,7 @@ class Prettier::Parser < Ripper
1598
1564
  if mrhs[:body].empty?
1599
1565
  part.merge(type: :mrhs, body: [part])
1600
1566
  else
1601
- mrhs.merge!(
1602
- body: mrhs[:body] << part,
1603
- end: part[:end],
1604
- char_end: part[:char_end]
1605
- )
1567
+ mrhs.merge!(body: mrhs[:body] << part, el: part[:el], ec: part[:ec])
1606
1568
  end
1607
1569
  end
1608
1570
 
@@ -1616,10 +1578,10 @@ class Prettier::Parser < Ripper
1616
1578
  {
1617
1579
  type: :mrhs_add_star,
1618
1580
  body: [mrhs, part],
1619
- start: beging[:start],
1620
- char_start: beging[:char_start],
1621
- end: ending[:end],
1622
- char_end: ending[:char_end]
1581
+ sl: beging[:sl],
1582
+ sc: beging[:sc],
1583
+ el: ending[:el],
1584
+ ec: ending[:ec]
1623
1585
  }
1624
1586
  end
1625
1587
 
@@ -1642,8 +1604,8 @@ class Prettier::Parser < Ripper
1642
1604
  find_scanner_event(:@kw, 'next').merge!(
1643
1605
  type: :next,
1644
1606
  body: [args_add_block],
1645
- end: args_add_block[:end],
1646
- char_end: args_add_block[:char_end]
1607
+ el: args_add_block[:el],
1608
+ ec: args_add_block[:ec]
1647
1609
  )
1648
1610
  end
1649
1611
 
@@ -1655,8 +1617,8 @@ class Prettier::Parser < Ripper
1655
1617
  left.merge(
1656
1618
  type: :opassign,
1657
1619
  body: [left, oper, right],
1658
- end: right[:end],
1659
- char_end: right[:char_end]
1620
+ el: right[:el],
1621
+ ec: right[:ec]
1660
1622
  )
1661
1623
  end
1662
1624
 
@@ -1670,13 +1632,13 @@ class Prettier::Parser < Ripper
1670
1632
  location =
1671
1633
  if flattened.any?
1672
1634
  {
1673
- start: flattened[0][:start],
1674
- char_start: flattened[0][:char_start],
1675
- end: flattened[-1][:end],
1676
- char_end: flattened[-1][:char_end]
1635
+ sl: flattened[0][:sl],
1636
+ sc: flattened[0][:sc],
1637
+ el: flattened[-1][:el],
1638
+ ec: flattened[-1][:ec]
1677
1639
  }
1678
1640
  else
1679
- { start: lineno, char_start: char_pos, end: lineno, char_end: char_pos }
1641
+ { sl: lineno, sc: char_pos, el: lineno, ec: char_pos }
1680
1642
  end
1681
1643
 
1682
1644
  location.merge!(type: :params, body: types)
@@ -1686,13 +1648,18 @@ class Prettier::Parser < Ripper
1686
1648
  # anywhere in a Ruby program. It accepts as arguments the contents, which
1687
1649
  # can be either params or statements.
1688
1650
  def on_paren(contents)
1651
+ beging = find_scanner_event(:@lparen)
1689
1652
  ending = find_scanner_event(:@rparen)
1690
1653
 
1691
- find_scanner_event(:@lparen).merge!(
1654
+ if contents && contents[:type] == :params
1655
+ contents.merge!(sc: beging[:ec], ec: ending[:sc])
1656
+ end
1657
+
1658
+ beging.merge!(
1692
1659
  type: :paren,
1693
1660
  body: [contents],
1694
- end: ending[:end],
1695
- char_end: ending[:char_end]
1661
+ el: ending[:el],
1662
+ ec: ending[:ec]
1696
1663
  )
1697
1664
  end
1698
1665
 
@@ -1701,12 +1668,7 @@ class Prettier::Parser < Ripper
1701
1668
  # source string. We'll also attach on the __END__ content if there was
1702
1669
  # some found at the end of the source string.
1703
1670
  def on_program(stmts)
1704
- range = {
1705
- start: 1,
1706
- end: lines.length,
1707
- char_start: 0,
1708
- char_end: source.length
1709
- }
1671
+ range = { sl: 1, el: lines.length, sc: 0, ec: source.length }
1710
1672
 
1711
1673
  stmts[:body] << @__end__ if @__end__
1712
1674
  stmts.bind(0, source.length)
@@ -1728,8 +1690,8 @@ class Prettier::Parser < Ripper
1728
1690
  def on_qsymbols_add(qsymbols, tstring_content)
1729
1691
  qsymbols.merge!(
1730
1692
  body: qsymbols[:body] << tstring_content,
1731
- end: tstring_content[:end],
1732
- char_end: tstring_content[:char_end]
1693
+ el: tstring_content[:el],
1694
+ ec: tstring_content[:ec]
1733
1695
  )
1734
1696
  end
1735
1697
 
@@ -1747,8 +1709,8 @@ class Prettier::Parser < Ripper
1747
1709
  def on_qwords_add(qwords, tstring_content)
1748
1710
  qwords.merge!(
1749
1711
  body: qwords[:body] << tstring_content,
1750
- end: tstring_content[:end],
1751
- char_end: tstring_content[:char_end]
1712
+ el: tstring_content[:el],
1713
+ ec: tstring_content[:ec]
1752
1714
  )
1753
1715
  end
1754
1716
 
@@ -1773,8 +1735,8 @@ class Prettier::Parser < Ripper
1773
1735
  def on_regexp_add(regexp, piece)
1774
1736
  regexp.merge!(
1775
1737
  body: regexp[:body] << piece,
1776
- end: regexp[:end],
1777
- char_end: regexp[:char_end]
1738
+ el: regexp[:el],
1739
+ ec: regexp[:ec]
1778
1740
  )
1779
1741
  end
1780
1742
 
@@ -1786,8 +1748,8 @@ class Prettier::Parser < Ripper
1786
1748
  regexp.merge!(
1787
1749
  type: :regexp_literal,
1788
1750
  ending: ending[:body],
1789
- end: ending[:end],
1790
- char_end: ending[:char_end]
1751
+ el: ending[:el],
1752
+ ec: ending[:ec]
1791
1753
  )
1792
1754
  end
1793
1755
 
@@ -1796,17 +1758,17 @@ class Prettier::Parser < Ripper
1796
1758
  # determine its ending. Therefore it relies on its parent bodystmt node to
1797
1759
  # report its ending to it.
1798
1760
  class Rescue < SimpleDelegator
1799
- def bind_end(char_end)
1800
- merge!(char_end: char_end)
1761
+ def bind_end(ec)
1762
+ merge!(ec: ec)
1801
1763
 
1802
1764
  stmts = self[:body][2]
1803
1765
  consequent = self[:body][3]
1804
1766
 
1805
1767
  if consequent
1806
- consequent.bind_end(char_end)
1807
- stmts.bind_end(consequent[:char_start])
1768
+ consequent.bind_end(ec)
1769
+ stmts.bind_end(consequent[:sc])
1808
1770
  else
1809
- stmts.bind_end(char_end)
1771
+ stmts.bind_end(ec)
1810
1772
  end
1811
1773
  end
1812
1774
  end
@@ -1819,14 +1781,14 @@ class Prettier::Parser < Ripper
1819
1781
  last_exception = exceptions.is_a?(Array) ? exceptions[-1] : exceptions
1820
1782
  last_node = variable || last_exception || beging
1821
1783
 
1822
- stmts.bind(find_next_statement_start(last_node[:char_end]), char_pos)
1784
+ stmts.bind(find_next_statement_start(last_node[:ec]), char_pos)
1823
1785
 
1824
1786
  Rescue.new(
1825
1787
  beging.merge!(
1826
1788
  type: :rescue,
1827
1789
  body: [exceptions, variable, stmts, consequent],
1828
- end: lineno,
1829
- char_end: char_pos
1790
+ el: lineno,
1791
+ ec: char_pos
1830
1792
  )
1831
1793
  )
1832
1794
  end
@@ -1840,10 +1802,10 @@ class Prettier::Parser < Ripper
1840
1802
  {
1841
1803
  type: :rescue_mod,
1842
1804
  body: [statement, rescued],
1843
- start: statement[:start],
1844
- char_start: statement[:char_start],
1845
- end: rescued[:end],
1846
- char_end: rescued[:char_end]
1805
+ sl: statement[:sl],
1806
+ sc: statement[:sc],
1807
+ el: rescued[:el],
1808
+ ec: rescued[:ec]
1847
1809
  }
1848
1810
  end
1849
1811
 
@@ -1858,8 +1820,8 @@ class Prettier::Parser < Ripper
1858
1820
  oper.merge!(
1859
1821
  type: :rest_param,
1860
1822
  body: [ident],
1861
- end: ident[:end],
1862
- char_end: ident[:char_end]
1823
+ el: ident[:el],
1824
+ ec: ident[:ec]
1863
1825
  )
1864
1826
  end
1865
1827
 
@@ -1876,8 +1838,8 @@ class Prettier::Parser < Ripper
1876
1838
  find_scanner_event(:@kw, 'return').merge!(
1877
1839
  type: :return,
1878
1840
  body: [args_add_block],
1879
- end: args_add_block[:end],
1880
- char_end: args_add_block[:char_end]
1841
+ el: args_add_block[:el],
1842
+ ec: args_add_block[:ec]
1881
1843
  )
1882
1844
  end
1883
1845
 
@@ -1903,18 +1865,15 @@ class Prettier::Parser < Ripper
1903
1865
  beging = find_scanner_event(:@kw, 'class')
1904
1866
  ending = find_scanner_event(:@kw, 'end')
1905
1867
 
1906
- bodystmt.bind(
1907
- find_next_statement_start(target[:char_end]),
1908
- ending[:char_start]
1909
- )
1868
+ bodystmt.bind(find_next_statement_start(target[:ec]), ending[:sc])
1910
1869
 
1911
1870
  {
1912
1871
  type: :sclass,
1913
1872
  body: [target, bodystmt],
1914
- start: beging[:start],
1915
- char_start: beging[:char_start],
1916
- end: ending[:end],
1917
- char_end: ending[:char_end]
1873
+ sl: beging[:sl],
1874
+ sc: beging[:sc],
1875
+ el: ending[:el],
1876
+ ec: ending[:ec]
1918
1877
  }
1919
1878
  end
1920
1879
 
@@ -1926,23 +1885,23 @@ class Prettier::Parser < Ripper
1926
1885
  # propagate that onto void_stmt nodes inside the stmts in order to make sure
1927
1886
  # all comments get printed appropriately.
1928
1887
  class Stmts < SimpleDelegator
1929
- def bind(char_start, char_end)
1930
- merge!(char_start: char_start, char_end: char_end)
1888
+ def bind(sc, ec)
1889
+ merge!(sc: sc, ec: ec)
1931
1890
 
1932
1891
  if self[:body][0][:type] == :void_stmt
1933
- self[:body][0].merge!(char_start: char_start, char_end: char_start)
1892
+ self[:body][0].merge!(sc: sc, ec: sc)
1934
1893
  end
1935
1894
  end
1936
1895
 
1937
- def bind_end(char_end)
1938
- merge!(char_end: char_end)
1896
+ def bind_end(ec)
1897
+ merge!(ec: ec)
1939
1898
  end
1940
1899
 
1941
1900
  def <<(statement)
1942
1901
  if self[:body].any?
1943
- merge!(statement.slice(:end, :char_end))
1902
+ merge!(statement.slice(:el, :ec))
1944
1903
  else
1945
- merge!(statement.slice(:start, :end, :char_start, :char_end))
1904
+ merge!(statement.slice(:sl, :el, :sc, :ec))
1946
1905
  end
1947
1906
 
1948
1907
  self[:body] << statement
@@ -1957,10 +1916,10 @@ class Prettier::Parser < Ripper
1957
1916
  Stmts.new(
1958
1917
  type: :stmts,
1959
1918
  body: [],
1960
- start: lineno,
1961
- end: lineno,
1962
- char_start: char_pos,
1963
- char_end: char_pos
1919
+ sl: lineno,
1920
+ el: lineno,
1921
+ sc: char_pos,
1922
+ ec: char_pos
1964
1923
  )
1965
1924
  end
1966
1925
 
@@ -1982,10 +1941,10 @@ class Prettier::Parser < Ripper
1982
1941
  {
1983
1942
  type: :string_concat,
1984
1943
  body: [left, right],
1985
- start: left[:start],
1986
- char_start: left[:char_start],
1987
- end: right[:end],
1988
- char_end: right[:char_end]
1944
+ sl: left[:sl],
1945
+ sc: left[:sc],
1946
+ el: right[:el],
1947
+ ec: right[:ec]
1989
1948
  }
1990
1949
  end
1991
1950
 
@@ -1998,10 +1957,10 @@ class Prettier::Parser < Ripper
1998
1957
  {
1999
1958
  type: :string,
2000
1959
  body: [],
2001
- start: lineno,
2002
- end: lineno,
2003
- char_start: char_pos,
2004
- char_end: char_pos
1960
+ sl: lineno,
1961
+ el: lineno,
1962
+ sc: char_pos,
1963
+ ec: char_pos
2005
1964
  }
2006
1965
  end
2007
1966
 
@@ -2010,11 +1969,7 @@ class Prettier::Parser < Ripper
2010
1969
  # It accepts as arguments the parent string node as well as the additional
2011
1970
  # piece of the string.
2012
1971
  def on_string_add(string, piece)
2013
- string.merge!(
2014
- body: string[:body] << piece,
2015
- end: piece[:end],
2016
- char_end: piece[:char_end]
2017
- )
1972
+ string.merge!(body: string[:body] << piece, el: piece[:el], ec: piece[:ec])
2018
1973
  end
2019
1974
 
2020
1975
  # string_dvar is a parser event that represents a very special kind of
@@ -2026,8 +1981,8 @@ class Prettier::Parser < Ripper
2026
1981
  find_scanner_event(:@embvar).merge!(
2027
1982
  type: :string_dvar,
2028
1983
  body: [var_ref],
2029
- end: var_ref[:end],
2030
- char_end: var_ref[:char_end]
1984
+ el: var_ref[:el],
1985
+ ec: var_ref[:ec]
2031
1986
  )
2032
1987
  end
2033
1988
 
@@ -2039,15 +1994,15 @@ class Prettier::Parser < Ripper
2039
1994
  beging = find_scanner_event(:@embexpr_beg)
2040
1995
  ending = find_scanner_event(:@embexpr_end)
2041
1996
 
2042
- stmts.bind(beging[:char_end], ending[:char_start])
1997
+ stmts.bind(beging[:ec], ending[:sc])
2043
1998
 
2044
1999
  {
2045
2000
  type: :string_embexpr,
2046
2001
  body: [stmts],
2047
- start: beging[:start],
2048
- char_start: beging[:char_start],
2049
- end: ending[:end],
2050
- char_end: ending[:char_end]
2002
+ sl: beging[:sl],
2003
+ sc: beging[:sc],
2004
+ el: ending[:el],
2005
+ ec: ending[:ec]
2051
2006
  }
2052
2007
  end
2053
2008
 
@@ -2066,10 +2021,10 @@ class Prettier::Parser < Ripper
2066
2021
  type: :string_literal,
2067
2022
  body: string[:body],
2068
2023
  quote: beging[:body],
2069
- start: beging[:start],
2070
- char_start: beging[:char_start],
2071
- end: ending[:end],
2072
- char_end: ending[:char_end]
2024
+ sl: beging[:sl],
2025
+ sc: beging[:sc],
2026
+ el: ending[:el],
2027
+ ec: ending[:ec]
2073
2028
  }
2074
2029
  end
2075
2030
  end
@@ -2082,8 +2037,8 @@ class Prettier::Parser < Ripper
2082
2037
  find_scanner_event(:@kw, 'super').merge!(
2083
2038
  type: :super,
2084
2039
  body: [contents],
2085
- end: contents[:end],
2086
- char_end: contents[:char_end]
2040
+ el: contents[:el],
2041
+ ec: contents[:ec]
2087
2042
  )
2088
2043
  end
2089
2044
 
@@ -2114,7 +2069,7 @@ class Prettier::Parser < Ripper
2114
2069
  contents.merge(type: :symbol_literal, body: [contents])
2115
2070
  else
2116
2071
  beging = find_scanner_event(:@symbeg)
2117
- contents.merge!(type: :symbol_literal, char_start: beging[:char_start])
2072
+ contents.merge!(type: :symbol_literal, sc: beging[:sc])
2118
2073
  end
2119
2074
  end
2120
2075
 
@@ -2133,8 +2088,8 @@ class Prettier::Parser < Ripper
2133
2088
  def on_symbols_add(symbols, word_add)
2134
2089
  symbols.merge!(
2135
2090
  body: symbols[:body] << word_add,
2136
- end: word_add[:end],
2137
- char_end: word_add[:char_end]
2091
+ el: word_add[:el],
2092
+ ec: word_add[:ec]
2138
2093
  )
2139
2094
  end
2140
2095
 
@@ -2145,8 +2100,7 @@ class Prettier::Parser < Ripper
2145
2100
  def find_colon2_before(const)
2146
2101
  index =
2147
2102
  scanner_events.rindex do |event|
2148
- event[:type] == :@op && event[:body] == '::' &&
2149
- event[:char_start] < const[:char_start]
2103
+ event[:type] == :@op && event[:body] == '::' && event[:sc] < const[:sc]
2150
2104
  end
2151
2105
 
2152
2106
  scanner_events[index]
@@ -2163,8 +2117,8 @@ class Prettier::Parser < Ripper
2163
2117
  const.merge(
2164
2118
  type: :top_const_field,
2165
2119
  body: [const],
2166
- start: beging[:start],
2167
- char_start: beging[:char_start]
2120
+ sl: beging[:sl],
2121
+ sc: beging[:sc]
2168
2122
  )
2169
2123
  end
2170
2124
 
@@ -2179,8 +2133,8 @@ class Prettier::Parser < Ripper
2179
2133
  const.merge(
2180
2134
  type: :top_const_ref,
2181
2135
  body: [const],
2182
- start: beging[:start],
2183
- char_start: beging[:char_start]
2136
+ sl: beging[:sl],
2137
+ sc: beging[:sc]
2184
2138
  )
2185
2139
  end
2186
2140
 
@@ -2192,15 +2146,15 @@ class Prettier::Parser < Ripper
2192
2146
  if oper == :not
2193
2147
  node = find_scanner_event(:@kw, 'not')
2194
2148
 
2195
- paren = source[node[:char_end]...value[:char_start]].include?('(')
2149
+ paren = source[node[:ec]...value[:sc]].include?('(')
2196
2150
  ending = paren ? find_scanner_event(:@rparen) : value
2197
2151
 
2198
2152
  node.merge!(
2199
2153
  type: :unary,
2200
2154
  oper: oper,
2201
2155
  body: [value],
2202
- end: ending[:end],
2203
- char_end: ending[:char_end],
2156
+ el: ending[:el],
2157
+ ec: ending[:ec],
2204
2158
  paren: paren
2205
2159
  )
2206
2160
  else
@@ -2210,7 +2164,7 @@ class Prettier::Parser < Ripper
2210
2164
  # stack. So we need to explicitly disallow those operators.
2211
2165
  index =
2212
2166
  scanner_events.rindex do |scanner_event|
2213
- scanner_event[:type] == :@op &&
2167
+ scanner_event[:type] == :@op && scanner_event[:sc] < value[:sc] &&
2214
2168
  !%w[.. ...].include?(scanner_event[:body])
2215
2169
  end
2216
2170
 
@@ -2219,8 +2173,8 @@ class Prettier::Parser < Ripper
2219
2173
  type: :unary,
2220
2174
  oper: oper[0],
2221
2175
  body: [value],
2222
- end: value[:end],
2223
- char_end: value[:char_end]
2176
+ el: value[:el],
2177
+ ec: value[:ec]
2224
2178
  )
2225
2179
  end
2226
2180
  end
@@ -2235,8 +2189,8 @@ class Prettier::Parser < Ripper
2235
2189
  find_scanner_event(:@kw, 'undef').merge!(
2236
2190
  type: :undef,
2237
2191
  body: symbol_literals,
2238
- end: last[:end],
2239
- char_end: last[:char_end]
2192
+ el: last[:el],
2193
+ ec: last[:ec]
2240
2194
  )
2241
2195
  end
2242
2196
 
@@ -2248,15 +2202,15 @@ class Prettier::Parser < Ripper
2248
2202
  beging = find_scanner_event(:@kw, 'unless')
2249
2203
  ending = consequent || find_scanner_event(:@kw, 'end')
2250
2204
 
2251
- stmts.bind(predicate[:char_end], ending[:char_start])
2205
+ stmts.bind(predicate[:ec], ending[:sc])
2252
2206
 
2253
2207
  {
2254
2208
  type: :unless,
2255
2209
  body: [predicate, stmts, consequent],
2256
- start: beging[:start],
2257
- char_start: beging[:char_start],
2258
- end: ending[:end],
2259
- char_end: ending[:char_end]
2210
+ sl: beging[:sl],
2211
+ sc: beging[:sc],
2212
+ el: ending[:el],
2213
+ ec: ending[:ec]
2260
2214
  }
2261
2215
  end
2262
2216
 
@@ -2269,10 +2223,10 @@ class Prettier::Parser < Ripper
2269
2223
  {
2270
2224
  type: :unless_mod,
2271
2225
  body: [predicate, statement],
2272
- start: statement[:start],
2273
- char_start: statement[:char_start],
2274
- end: predicate[:end],
2275
- char_end: predicate[:char_end]
2226
+ sl: statement[:sl],
2227
+ sc: statement[:sc],
2228
+ el: predicate[:el],
2229
+ ec: predicate[:ec]
2276
2230
  }
2277
2231
  end
2278
2232
 
@@ -2283,15 +2237,22 @@ class Prettier::Parser < Ripper
2283
2237
  beging = find_scanner_event(:@kw, 'until')
2284
2238
  ending = find_scanner_event(:@kw, 'end')
2285
2239
 
2286
- stmts.bind(predicate[:char_end], ending[:char_start])
2240
+ # Consume the do keyword if it exists so that it doesn't get confused for
2241
+ # some other block
2242
+ do_event = find_scanner_event(:@kw, 'do', consume: false)
2243
+ if do_event && do_event[:sc] > predicate[:ec] && do_event[:ec] < ending[:sc]
2244
+ scanner_events.delete(do_event)
2245
+ end
2246
+
2247
+ stmts.bind(predicate[:ec], ending[:sc])
2287
2248
 
2288
2249
  {
2289
2250
  type: :until,
2290
2251
  body: [predicate, stmts],
2291
- start: beging[:start],
2292
- char_start: beging[:char_start],
2293
- end: ending[:end],
2294
- char_end: ending[:char_end]
2252
+ sl: beging[:sl],
2253
+ sc: beging[:sc],
2254
+ el: ending[:el],
2255
+ ec: ending[:ec]
2295
2256
  }
2296
2257
  end
2297
2258
 
@@ -2304,10 +2265,10 @@ class Prettier::Parser < Ripper
2304
2265
  {
2305
2266
  type: :until_mod,
2306
2267
  body: [predicate, statement],
2307
- start: statement[:start],
2308
- char_start: statement[:char_start],
2309
- end: predicate[:end],
2310
- char_end: predicate[:char_end]
2268
+ sl: statement[:sl],
2269
+ sc: statement[:sc],
2270
+ el: predicate[:el],
2271
+ ec: predicate[:ec]
2311
2272
  }
2312
2273
  end
2313
2274
 
@@ -2318,16 +2279,16 @@ class Prettier::Parser < Ripper
2318
2279
  def on_var_alias(left, right)
2319
2280
  beging = find_scanner_event(:@kw, 'alias')
2320
2281
 
2321
- paren = source[beging[:char_end]...left[:char_start]].include?('(')
2282
+ paren = source[beging[:ec]...left[:sc]].include?('(')
2322
2283
  ending = paren ? find_scanner_event(:@rparen) : right
2323
2284
 
2324
2285
  {
2325
2286
  type: :var_alias,
2326
2287
  body: [left, right],
2327
- start: beging[:start],
2328
- char_start: beging[:char_start],
2329
- end: ending[:end],
2330
- char_end: ending[:char_end]
2288
+ sl: beging[:sl],
2289
+ sc: beging[:sc],
2290
+ el: ending[:el],
2291
+ ec: ending[:ec]
2331
2292
  }
2332
2293
  end
2333
2294
 
@@ -2379,13 +2340,7 @@ class Prettier::Parser < Ripper
2379
2340
  # block of code. It often will have comments attached to it, so it requires
2380
2341
  # some special handling.
2381
2342
  def on_void_stmt
2382
- {
2383
- type: :void_stmt,
2384
- start: lineno,
2385
- end: lineno,
2386
- char_start: char_pos,
2387
- char_end: char_pos
2388
- }
2343
+ { type: :void_stmt, sl: lineno, el: lineno, sc: char_pos, ec: char_pos }
2389
2344
  end
2390
2345
 
2391
2346
  # when is a parser event that represents another clause in a case chain.
@@ -2396,15 +2351,15 @@ class Prettier::Parser < Ripper
2396
2351
  beging = find_scanner_event(:@kw, 'when')
2397
2352
  ending = consequent || find_scanner_event(:@kw, 'end')
2398
2353
 
2399
- stmts.bind(predicate[:char_end], ending[:char_start])
2354
+ stmts.bind(predicate[:ec], ending[:sc])
2400
2355
 
2401
2356
  {
2402
2357
  type: :when,
2403
2358
  body: [predicate, stmts, consequent],
2404
- start: beging[:start],
2405
- char_start: beging[:char_start],
2406
- end: ending[:end],
2407
- char_end: ending[:char_end]
2359
+ sl: beging[:sl],
2360
+ sc: beging[:sc],
2361
+ el: ending[:el],
2362
+ ec: ending[:ec]
2408
2363
  }
2409
2364
  end
2410
2365
 
@@ -2415,15 +2370,22 @@ class Prettier::Parser < Ripper
2415
2370
  beging = find_scanner_event(:@kw, 'while')
2416
2371
  ending = find_scanner_event(:@kw, 'end')
2417
2372
 
2418
- stmts.bind(predicate[:char_end], ending[:char_start])
2373
+ # Consume the do keyword if it exists so that it doesn't get confused for
2374
+ # some other block
2375
+ do_event = find_scanner_event(:@kw, 'do', consume: false)
2376
+ if do_event && do_event[:sc] > predicate[:ec] && do_event[:ec] < ending[:sc]
2377
+ scanner_events.delete(do_event)
2378
+ end
2379
+
2380
+ stmts.bind(predicate[:ec], ending[:sc])
2419
2381
 
2420
2382
  {
2421
2383
  type: :while,
2422
2384
  body: [predicate, stmts],
2423
- start: beging[:start],
2424
- char_start: beging[:char_start],
2425
- end: ending[:end],
2426
- char_end: ending[:char_end]
2385
+ sl: beging[:sl],
2386
+ sc: beging[:sc],
2387
+ el: ending[:el],
2388
+ ec: ending[:ec]
2427
2389
  }
2428
2390
  end
2429
2391
 
@@ -2436,10 +2398,10 @@ class Prettier::Parser < Ripper
2436
2398
  {
2437
2399
  type: :while_mod,
2438
2400
  body: [predicate, statement],
2439
- start: statement[:start],
2440
- char_start: statement[:char_start],
2441
- end: predicate[:end],
2442
- char_end: predicate[:char_end]
2401
+ sl: statement[:sl],
2402
+ sc: statement[:sc],
2403
+ el: predicate[:el],
2404
+ ec: predicate[:ec]
2443
2405
  }
2444
2406
  end
2445
2407
 
@@ -2469,11 +2431,7 @@ class Prettier::Parser < Ripper
2469
2431
  # location information from the first piece.
2470
2432
  piece.merge(type: :word, body: [piece])
2471
2433
  else
2472
- word.merge!(
2473
- body: word[:body] << piece,
2474
- end: piece[:end],
2475
- char_end: piece[:char_end]
2476
- )
2434
+ word.merge!(body: word[:body] << piece, el: piece[:el], ec: piece[:ec])
2477
2435
  end
2478
2436
  end
2479
2437
 
@@ -2492,8 +2450,8 @@ class Prettier::Parser < Ripper
2492
2450
  def on_words_add(words, word_add)
2493
2451
  words.merge!(
2494
2452
  body: words[:body] << word_add,
2495
- end: word_add[:end],
2496
- char_end: word_add[:char_end]
2453
+ el: word_add[:el],
2454
+ ec: word_add[:ec]
2497
2455
  )
2498
2456
  end
2499
2457
 
@@ -2526,8 +2484,8 @@ class Prettier::Parser < Ripper
2526
2484
  def on_xstring_add(xstring, piece)
2527
2485
  xstring.merge!(
2528
2486
  body: xstring[:body] << piece,
2529
- end: piece[:end],
2530
- char_end: piece[:char_end]
2487
+ el: piece[:el],
2488
+ ec: piece[:ec]
2531
2489
  )
2532
2490
  end
2533
2491
 
@@ -2552,11 +2510,7 @@ class Prettier::Parser < Ripper
2552
2510
  heredoc.merge!(body: xstring[:body])
2553
2511
  else
2554
2512
  ending = find_scanner_event(:@tstring_end)
2555
- xstring.merge!(
2556
- type: :xstring_literal,
2557
- end: ending[:end],
2558
- char_end: ending[:char_end]
2559
- )
2513
+ xstring.merge!(type: :xstring_literal, el: ending[:el], ec: ending[:ec])
2560
2514
  end
2561
2515
  end
2562
2516
 
@@ -2567,8 +2521,8 @@ class Prettier::Parser < Ripper
2567
2521
  find_scanner_event(:@kw, 'yield').merge!(
2568
2522
  type: :yield,
2569
2523
  body: [args_add_block],
2570
- end: args_add_block[:end],
2571
- char_end: args_add_block[:char_end]
2524
+ el: args_add_block[:el],
2525
+ ec: args_add_block[:ec]
2572
2526
  )
2573
2527
  end
2574
2528