prettier 2.0.0.pre.rc3 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -4
  3. data/dist/haml/parser.rb +6 -0
  4. data/dist/parser/getInfo.js +9 -2
  5. data/dist/parser/parseSync.js +53 -16
  6. data/dist/parser/server.rb +6 -2
  7. data/dist/rbs/parser.rb +59 -2
  8. data/dist/rbs/printer.js +14 -6
  9. data/dist/ruby/embed.js +10 -5
  10. data/dist/ruby/location.js +19 -0
  11. data/dist/ruby/nodes/alias.js +6 -5
  12. data/dist/ruby/nodes/aref.js +4 -6
  13. data/dist/ruby/nodes/args.js +29 -56
  14. data/dist/ruby/nodes/arrays.js +31 -35
  15. data/dist/ruby/nodes/assign.js +19 -23
  16. data/dist/ruby/nodes/blocks.js +18 -15
  17. data/dist/ruby/nodes/calls.js +33 -30
  18. data/dist/ruby/nodes/case.js +8 -8
  19. data/dist/ruby/nodes/class.js +13 -13
  20. data/dist/ruby/nodes/commands.js +36 -22
  21. data/dist/ruby/nodes/conditionals.js +56 -52
  22. data/dist/ruby/nodes/constants.js +10 -13
  23. data/dist/ruby/nodes/flow.js +39 -46
  24. data/dist/ruby/nodes/hashes.js +26 -30
  25. data/dist/ruby/nodes/heredocs.js +9 -9
  26. data/dist/ruby/nodes/hooks.js +2 -2
  27. data/dist/ruby/nodes/ints.js +5 -5
  28. data/dist/ruby/nodes/lambdas.js +7 -6
  29. data/dist/ruby/nodes/loops.js +26 -24
  30. data/dist/ruby/nodes/massign.js +22 -35
  31. data/dist/ruby/nodes/methods.js +20 -40
  32. data/dist/ruby/nodes/operators.js +26 -28
  33. data/dist/ruby/nodes/params.js +31 -25
  34. data/dist/ruby/nodes/patterns.js +52 -42
  35. data/dist/ruby/nodes/regexp.js +6 -6
  36. data/dist/ruby/nodes/rescue.js +28 -24
  37. data/dist/ruby/nodes/return.js +61 -36
  38. data/dist/ruby/nodes/statements.js +24 -25
  39. data/dist/ruby/nodes/strings.js +36 -34
  40. data/dist/ruby/nodes/super.js +6 -10
  41. data/dist/ruby/nodes/undef.js +19 -14
  42. data/dist/ruby/nodes.js +47 -21
  43. data/dist/ruby/parser.js +3 -2
  44. data/dist/ruby/parser.rb +8470 -2972
  45. data/dist/ruby/printer.js +9 -71
  46. data/dist/ruby/toProc.js +33 -35
  47. data/dist/types.js +5 -1
  48. data/dist/utils/containsAssignment.js +5 -2
  49. data/dist/utils/getChildNodes.js +305 -0
  50. data/dist/utils/inlineEnsureParens.js +1 -1
  51. data/dist/utils/isEmptyBodyStmt.js +1 -1
  52. data/dist/utils/isEmptyParams.js +12 -0
  53. data/dist/utils/isEmptyStmts.js +1 -1
  54. data/dist/utils/makeCall.js +5 -4
  55. data/dist/utils/printEmptyCollection.js +3 -1
  56. data/dist/utils/skipAssignIndent.js +6 -2
  57. data/dist/utils.js +5 -3
  58. data/exe/rbprettier +1 -2
  59. data/lib/prettier.rb +37 -5
  60. data/node_modules/prettier/bin-prettier.js +48 -18924
  61. data/node_modules/prettier/cli.js +12335 -0
  62. data/node_modules/prettier/doc.js +1306 -4755
  63. data/node_modules/prettier/index.js +37468 -57614
  64. data/node_modules/prettier/package.json +3 -2
  65. data/node_modules/prettier/parser-angular.js +2 -66
  66. data/node_modules/prettier/parser-babel.js +27 -22
  67. data/node_modules/prettier/parser-espree.js +26 -22
  68. data/node_modules/prettier/parser-flow.js +26 -22
  69. data/node_modules/prettier/parser-glimmer.js +27 -1
  70. data/node_modules/prettier/parser-graphql.js +15 -1
  71. data/node_modules/prettier/parser-html.js +21 -117
  72. data/node_modules/prettier/parser-markdown.js +61 -19
  73. data/node_modules/prettier/parser-meriyah.js +19 -22
  74. data/node_modules/prettier/parser-postcss.js +76 -22
  75. data/node_modules/prettier/parser-typescript.js +280 -22
  76. data/node_modules/prettier/parser-yaml.js +150 -15
  77. data/node_modules/prettier/third-party.js +8660 -11030
  78. data/package.json +8 -8
  79. data/rubocop.yml +9 -3
  80. metadata +9 -5
@@ -3,51 +3,51 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printRestParam = exports.printKeywordRestParam = exports.printArgsForward = exports.printParams = void 0;
6
+ exports.printExcessedComma = exports.printRestParam = exports.printKeywordRestParam = exports.printArgsForward = exports.printParams = void 0;
7
7
  const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
8
  const { group, hardline, join, indent, line, lineSuffix, softline } = prettier_1.default;
10
9
  function printRestParamSymbol(symbol) {
11
10
  return function printRestParamWithSymbol(path, opts, print) {
12
- return path.getValue().body[0]
13
- ? [symbol, path.call(print, "body", 0)]
14
- : symbol;
11
+ const node = path.getValue();
12
+ return node.name ? [symbol, path.call(print, "name")] : symbol;
15
13
  };
16
14
  }
17
15
  const printParams = (path, opts, print) => {
18
- const [reqs, optls, rest, post, kwargs, kwargRest, block] = path.getValue().body;
16
+ const node = path.getValue();
19
17
  let parts = [];
20
- if (reqs) {
18
+ if (node.reqs) {
21
19
  path.each((reqPath) => {
22
20
  // For some very strange reason, if you have a comment attached to a
23
21
  // rest_param, it shows up here in the list of required params.
24
22
  if (reqPath.getValue().type !== "rest_param") {
25
23
  parts.push(print(reqPath));
26
24
  }
27
- }, "body", 0);
25
+ }, "reqs");
28
26
  }
29
- if (optls) {
30
- parts = parts.concat(path.map((optlPath) => join(" = ", optlPath.map(print)), "body", 1));
27
+ if (node.opts) {
28
+ parts = parts.concat(path.map((optlPath) => join(" = ", optlPath.map(print)), "opts"));
31
29
  }
32
- if (rest && rest.type !== "excessed_comma") {
33
- parts.push(path.call(print, "body", 2));
30
+ if (node.rest && node.rest.type !== "excessed_comma") {
31
+ parts.push(path.call(print, "rest"));
34
32
  }
35
- if (post) {
36
- parts = parts.concat(path.map(print, "body", 3));
33
+ if (node.posts) {
34
+ parts = parts.concat(path.map(print, "posts"));
37
35
  }
38
- if (kwargs) {
36
+ if (node.keywords) {
39
37
  parts = parts.concat(path.map((kwargPath) => {
40
- if (!kwargPath.getValue()[1]) {
41
- return kwargPath.call(print, 0);
38
+ const kwarg = kwargPath.getValue();
39
+ const keyDoc = kwargPath.call(print, 0);
40
+ if (kwarg[1]) {
41
+ return group([keyDoc, " ", kwargPath.call(print, 1)]);
42
42
  }
43
- return group(join(" ", kwargPath.map(print)));
44
- }, "body", 4));
43
+ return keyDoc;
44
+ }, "keywords"));
45
45
  }
46
- if (kwargRest) {
47
- parts.push(kwargRest === "nil" ? "**nil" : path.call(print, "body", 5));
46
+ if (node.kwrest) {
47
+ parts.push(node.kwrest === "nil" ? "**nil" : path.call(print, "kwrest"));
48
48
  }
49
- if (block) {
50
- parts.push(path.call(print, "body", 6));
49
+ if (node.block) {
50
+ parts.push(path.call(print, "block"));
51
51
  }
52
52
  const contents = [join([",", line], parts)];
53
53
  // You can put an extra comma at the end of block args between pipes to
@@ -59,7 +59,8 @@ const printParams = (path, opts, print) => {
59
59
  // In ruby 2.5, the excessed comma is indicated by having a 0 in the rest
60
60
  // param position. In ruby 2.6+ it's indicated by having an "excessed_comma"
61
61
  // node in the rest position. Seems odd, but it's true.
62
- if (rest === 0 || (rest && rest.type === "excessed_comma")) {
62
+ if (node.rest === 0 ||
63
+ (node.rest && node.rest.type === "excessed_comma")) {
63
64
  contents.push(",");
64
65
  }
65
66
  // If the parent node is a paren then we skipped printing the parentheses so
@@ -84,6 +85,11 @@ const printParams = (path, opts, print) => {
84
85
  return group(contents);
85
86
  };
86
87
  exports.printParams = printParams;
87
- exports.printArgsForward = (0, utils_1.literal)("...");
88
+ const printArgsForward = (path) => path.getValue().value;
89
+ exports.printArgsForward = printArgsForward;
88
90
  exports.printKeywordRestParam = printRestParamSymbol("**");
89
91
  exports.printRestParam = printRestParamSymbol("*");
92
+ const printExcessedComma = (path, opts, print) => {
93
+ return path.call(print, "value");
94
+ };
95
+ exports.printExcessedComma = printExcessedComma;
@@ -18,48 +18,60 @@ const printPatternArg = (path, opts, print) => {
18
18
  return path.call(print);
19
19
  };
20
20
  const printAryPtn = (path, opts, print) => {
21
- const [constant, preargs, splatarg, postargs] = path.getValue().body;
22
- let args = [];
23
- if (preargs) {
24
- args = args.concat(path.map((argPath) => printPatternArg(argPath, opts, print), "body", 1));
21
+ const node = path.getValue();
22
+ let argDocs = [];
23
+ if (node.reqs.length > 0) {
24
+ argDocs = argDocs.concat(path.map((argPath) => printPatternArg(argPath, opts, print), "reqs"));
25
25
  }
26
- if (splatarg) {
27
- args.push(["*", path.call(print, "body", 2)]);
26
+ if (node.rest) {
27
+ argDocs.push(["*", path.call(print, "rest")]);
28
28
  }
29
- if (postargs) {
30
- args = args.concat(path.map(print, "body", 3));
29
+ if (node.posts.length > 0) {
30
+ argDocs = argDocs.concat(path.map(print, "posts"));
31
31
  }
32
- args = group(join([",", line], args));
33
- if (constant || patterns.includes(path.getParentNode().type)) {
34
- args = ["[", args, "]"];
32
+ let argDoc = group(join([",", line], argDocs));
33
+ // There are a couple of cases where we _must_ use brackets. They include:
34
+ //
35
+ // * When the number of arguments inside the array pattern is one 1, then we
36
+ // have to include them, otherwise it matches the whole array. Consider the
37
+ // difference between `in [elem]` and `in elem`.
38
+ // * If we have a wrapping constant, then we definitely need the brackets.
39
+ // Consider the difference between `in Const[elem]` and `in Const elem`
40
+ // * If we're nested inside a parent pattern, then we have to have brackets.
41
+ // Consider the difference between `in key: first, second` and
42
+ // `in key: [first, second]`.
43
+ if (argDocs.length === 1 ||
44
+ node.constant ||
45
+ patterns.includes(path.getParentNode().type)) {
46
+ argDoc = ["[", argDoc, "]"];
35
47
  }
36
- if (constant) {
37
- return [path.call(print, "body", 0), args];
48
+ if (node.constant) {
49
+ return [path.call(print, "constant"), argDoc];
38
50
  }
39
- return args;
51
+ return argDoc;
40
52
  };
41
53
  exports.printAryPtn = printAryPtn;
42
54
  const printFndPtn = (path, opts, print) => {
43
- const [constant] = path.getValue().body;
55
+ const node = path.getValue();
44
56
  const docs = [
45
57
  "[",
46
58
  group(join([",", line], [
47
- ["*", path.call(print, "body", 1)],
48
- ...path.map(print, "body", 2),
49
- ["*", path.call(print, "body", 3)]
59
+ ["*", path.call(print, "left")],
60
+ ...path.map(print, "values"),
61
+ ["*", path.call(print, "right")]
50
62
  ])),
51
63
  "]"
52
64
  ];
53
- if (constant) {
54
- return [path.call(print, "body", 0), docs];
65
+ if (node.constant) {
66
+ return [path.call(print, "constant"), docs];
55
67
  }
56
68
  return docs;
57
69
  };
58
70
  exports.printFndPtn = printFndPtn;
59
71
  const printHshPtn = (path, opts, print) => {
60
- const [constant, keyValuePairs, keyValueRest] = path.getValue().body;
72
+ const node = path.getValue();
61
73
  let args = [];
62
- if (keyValuePairs.length > 0) {
74
+ if (node.keywords.length > 0) {
63
75
  const printPair = (pairPath) => {
64
76
  const parts = [pairPath.call(print, 0)];
65
77
  if (pairPath.getValue()[1]) {
@@ -67,43 +79,41 @@ const printHshPtn = (path, opts, print) => {
67
79
  }
68
80
  return parts;
69
81
  };
70
- args = args.concat(path.map(printPair, "body", 1));
82
+ args = args.concat(path.map(printPair, "keywords"));
71
83
  }
72
- if (keyValueRest) {
73
- args.push(["**", path.call(print, "body", 2)]);
84
+ if (node.kwrest) {
85
+ args.push(["**", path.call(print, "kwrest")]);
74
86
  }
75
87
  args = group(join([",", line], args));
76
- if (constant) {
88
+ if (node.constant) {
77
89
  args = ["[", args, "]"];
78
90
  }
79
91
  else if (patterns.includes(path.getParentNode().type)) {
80
92
  args = ["{ ", args, " }"];
81
93
  }
82
- if (constant) {
83
- return [path.call(print, "body", 0), args];
94
+ if (node.constant) {
95
+ return [path.call(print, "constant"), args];
84
96
  }
85
97
  return args;
86
98
  };
87
99
  exports.printHshPtn = printHshPtn;
88
100
  const printIn = (path, opts, print) => {
101
+ const keyword = "in ";
89
102
  const parts = [
90
- "in ",
91
- align("in ".length, path.call((valuePath) => printPatternArg(valuePath, opts, print), "body", 0)),
92
- indent([hardline, path.call(print, "body", 1)])
103
+ keyword,
104
+ align(keyword.length, path.call((valuePath) => printPatternArg(valuePath, opts, print), "pattern")),
105
+ indent([hardline, path.call(print, "stmts")])
93
106
  ];
94
- if (path.getValue().body[2]) {
95
- parts.push(hardline, path.call(print, "body", 2));
107
+ if (path.getValue().cons) {
108
+ parts.push(hardline, path.call(print, "cons"));
96
109
  }
97
110
  return group(parts);
98
111
  };
99
112
  exports.printIn = printIn;
100
- const printRAssign = (path, opts, print) => {
101
- const { keyword } = path.getValue();
102
- const [leftDoc, rightDoc] = path.map(print, "body");
103
- return group([
104
- leftDoc,
105
- keyword ? " in" : " =>",
106
- group(indent([line, rightDoc]))
107
- ]);
108
- };
113
+ const printRAssign = (path, opts, print) => group([
114
+ path.call(print, "value"),
115
+ " ",
116
+ path.call(print, "op"),
117
+ group(indent([line, path.call(print, "pattern")]))
118
+ ]);
109
119
  exports.printRAssign = printRAssign;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.printRegexpLiteral = void 0;
4
4
  const utils_1 = require("../../utils");
5
5
  function hasContent(node, pattern) {
6
- return node.body.some((child) => child.type === "@tstring_content" && pattern.test(child.body));
6
+ return node.parts.some((part) => part.type === "tstring_content" && pattern.test(part.value));
7
7
  }
8
8
  // If the first part of this regex is plain string content, we have a space
9
9
  // or an =, and we're contained within a command or command_call node, then we
@@ -11,10 +11,10 @@ function hasContent(node, pattern) {
11
11
  // operator, e.g. foo / bar/ or foo /=bar/
12
12
  function forwardSlashIsAmbiguous(path) {
13
13
  const node = path.getValue();
14
- const firstChildNode = node.body[0];
15
- return (firstChildNode &&
16
- firstChildNode.type === "@tstring_content" &&
17
- [" ", "="].includes(firstChildNode.body[0]) &&
14
+ const firstPart = node.parts[0];
15
+ return (firstPart &&
16
+ firstPart.type === "tstring_content" &&
17
+ [" ", "="].includes(firstPart.value[0]) &&
18
18
  (0, utils_1.hasAncestor)(path, ["command", "command_call"]));
19
19
  }
20
20
  // This function is responsible for printing out regexp_literal nodes. They can
@@ -26,7 +26,7 @@ function forwardSlashIsAmbiguous(path) {
26
26
  // itself. In that case we switch over to using %r with braces.
27
27
  const printRegexpLiteral = (path, opts, print) => {
28
28
  const node = path.getValue();
29
- const docs = path.map(print, "body");
29
+ const docs = path.map(print, "parts");
30
30
  // We should use braces if using a forward slash would be ambiguous in the
31
31
  // current context or if there's a forward slash in the content of the regexp.
32
32
  const useBraces = forwardSlashIsAmbiguous(path) || hasContent(node, /\//);
@@ -5,12 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.printRetry = exports.printRedo = exports.printRescueMod = exports.printRescueEx = exports.printRescue = exports.printEnsure = exports.printBegin = void 0;
7
7
  const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
8
  const { align, group, hardline, indent, join, line } = prettier_1.default;
10
9
  const printBegin = (path, opts, print) => {
11
10
  return [
12
11
  "begin",
13
- indent([hardline, path.map(print, "body")]),
12
+ indent([hardline, path.call(print, "bodystmt")]),
14
13
  hardline,
15
14
  "end"
16
15
  ];
@@ -18,15 +17,16 @@ const printBegin = (path, opts, print) => {
18
17
  exports.printBegin = printBegin;
19
18
  const printEnsure = (path, opts, print) => {
20
19
  return [
21
- path.call(print, "body", 0),
22
- indent([hardline, path.call(print, "body", 1)])
20
+ path.call(print, "keyword"),
21
+ indent([hardline, path.call(print, "stmts")])
23
22
  ];
24
23
  };
25
24
  exports.printEnsure = printEnsure;
26
25
  const printRescue = (path, opts, print) => {
26
+ const node = path.getValue();
27
27
  const parts = ["rescue"];
28
- if (path.getValue().body[0]) {
29
- parts.push(align("rescue ".length, path.call(print, "body", 0)));
28
+ if (node.extn) {
29
+ parts.push(align("rescue ".length, path.call(print, "extn")));
30
30
  }
31
31
  else {
32
32
  // If you don't specify an error to rescue in a `begin/rescue` block, then
@@ -34,14 +34,14 @@ const printRescue = (path, opts, print) => {
34
34
  // just going to explicitly add it.
35
35
  parts.push(" StandardError");
36
36
  }
37
- const bodystmt = path.call(print, "body", 1);
38
- if (bodystmt.length > 0) {
39
- parts.push(indent([hardline, bodystmt]));
37
+ const stmtsDoc = path.call(print, "stmts");
38
+ if (stmtsDoc.length > 0) {
39
+ parts.push(indent([hardline, stmtsDoc]));
40
40
  }
41
41
  // This is the next clause on the `begin` statement, either another
42
42
  // `rescue`, and `ensure`, or an `else` clause.
43
- if (path.getValue().body[2]) {
44
- parts.push([hardline, path.call(print, "body", 2)]);
43
+ if (node.cons) {
44
+ parts.push([hardline, path.call(print, "cons")]);
45
45
  }
46
46
  return group(parts);
47
47
  };
@@ -49,34 +49,38 @@ exports.printRescue = printRescue;
49
49
  // This is a container node that we're adding into the AST that isn't present in
50
50
  // Ripper solely so that we have a nice place to attach inline comments.
51
51
  const printRescueEx = (path, opts, print) => {
52
- const [exception, variable] = path.getValue().body;
52
+ const node = path.getValue();
53
53
  const parts = [];
54
- if (exception) {
55
- let exceptionDoc = path.call(print, "body", 0);
56
- if (Array.isArray(exceptionDoc)) {
57
- const joiner = [",", line];
58
- exceptionDoc = group(join(joiner, exceptionDoc));
54
+ if (node.extns) {
55
+ // If there's just one exception being rescued, then it's just going to be a
56
+ // single doc node.
57
+ let exceptionDoc = path.call(print, "extns");
58
+ // If there are multiple exceptions being rescued, then we're going to have
59
+ // multiple doc nodes returned as an array that we need to join together.
60
+ if (["mrhs", "mrhs_add_star", "mrhs_new_from_args"].includes(node.extns.type)) {
61
+ exceptionDoc = group(join([",", line], exceptionDoc));
59
62
  }
60
63
  parts.push(" ", exceptionDoc);
61
64
  }
62
- if (variable) {
63
- parts.push(" => ", path.call(print, "body", 1));
65
+ if (node.var) {
66
+ parts.push(" => ", path.call(print, "var"));
64
67
  }
65
68
  return group(parts);
66
69
  };
67
70
  exports.printRescueEx = printRescueEx;
68
71
  const printRescueMod = (path, opts, print) => {
69
- const [statementDoc, valueDoc] = path.map(print, "body");
70
72
  return [
71
73
  "begin",
72
- indent([hardline, statementDoc]),
74
+ indent([hardline, path.call(print, "stmt")]),
73
75
  hardline,
74
76
  "rescue StandardError",
75
- indent([hardline, valueDoc]),
77
+ indent([hardline, path.call(print, "value")]),
76
78
  hardline,
77
79
  "end"
78
80
  ];
79
81
  };
80
82
  exports.printRescueMod = printRescueMod;
81
- exports.printRedo = (0, utils_1.literal)("redo");
82
- exports.printRetry = (0, utils_1.literal)("retry");
83
+ const printRedo = (path) => path.getValue().value;
84
+ exports.printRedo = printRedo;
85
+ const printRetry = (path) => path.getValue().value;
86
+ exports.printRetry = printRetry;
@@ -5,12 +5,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.printReturn0 = exports.printReturn = void 0;
7
7
  const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
8
  const { group, ifBreak, indent, line, join, softline } = prettier_1.default;
10
9
  // You can't skip the parentheses if you have comments or certain operators with
11
10
  // lower precedence than the return keyword.
12
- function canSkipParens(args) {
13
- const stmts = args.body[0].body[0];
11
+ function canSkipParens(paren) {
12
+ const stmts = paren.cnts;
13
+ // return(
14
+ // foo
15
+ // bar
16
+ // )
17
+ if (stmts.body.length !== 1) {
18
+ return false;
19
+ }
14
20
  // return(
15
21
  // # a
16
22
  // b
@@ -20,49 +26,67 @@ function canSkipParens(args) {
20
26
  }
21
27
  const stmt = stmts.body[0];
22
28
  // return (a or b)
23
- if (stmt.type === "binary" && ["and", "or"].includes(stmt.body[1])) {
29
+ if (stmt.type === "binary" && ["and", "or"].includes(stmt.op)) {
24
30
  return false;
25
31
  }
26
32
  // return (not a)
27
- if (stmt.type === "unary" && stmt.oper === "not") {
33
+ if (stmt.type === "not") {
28
34
  return false;
29
35
  }
30
36
  return true;
31
37
  }
32
38
  const printReturn = (path, opts, print) => {
33
- let args = path.getValue().body[0].body[0];
34
- let steps = ["body", 0, "body", 0];
35
- if (args.body.length === 1) {
36
- // If the body of the return contains parens, then just skip directly to the
37
- // content of the parens so that we can skip printing parens if we don't
38
- // want them.
39
- if (args.body[0] && args.body[0].type === "paren" && canSkipParens(args)) {
40
- args = args.body[0].body[0];
41
- steps = steps.concat("body", 0, "body", 0);
42
- }
43
- // If we're returning an array literal that isn't a special array, single
44
- // element array, or an empty array, then we want to grab the arguments so
45
- // that we can print them out as if they were normal return arguments.
46
- if (args.body[0] &&
47
- args.body[0].type === "array" &&
48
- args.body[0].body[0] &&
49
- args.body[0].body[0].body.length > 1 &&
50
- ["args", "args_add_star"].includes(args.body[0].body[0].type)) {
51
- steps = steps.concat("body", 0, "body", 0);
39
+ const node = path.getValue();
40
+ let parts = "";
41
+ let joining = false;
42
+ if (node.args.type === "args_add_block") {
43
+ const args = node.args.args;
44
+ const steps = ["args", "args"];
45
+ if (args.type === "args" && args.parts.length === 1 && args.parts[0]) {
46
+ // This is the first and only argument being passed to the return keyword.
47
+ let arg = args.parts[0];
48
+ steps.push("parts", 0);
49
+ // If the body of the return contains parens, then just skip directly to
50
+ // the content of the parens so that we can skip printing parens if we
51
+ // don't want them.
52
+ if (arg.type === "paren") {
53
+ // If we can't skip over the parentheses, then we know we can just bail
54
+ // out here and print the only argument as normal since it's a paren.
55
+ if (!canSkipParens(arg)) {
56
+ return ["return", path.call(print, "args")];
57
+ }
58
+ arg = arg.cnts.body[0];
59
+ steps.push("cnts", "body", 0);
60
+ }
61
+ // If we're returning an array literal that isn't a special array that has
62
+ // at least 2 elements, then we want to grab the arguments so that we can
63
+ // print them out as if they were normal return arguments.
64
+ if (arg.type === "array" && arg.cnts) {
65
+ const contents = arg.cnts;
66
+ if (contents.type === "args" && contents.parts.length > 1) {
67
+ // If we have just regular arguments and we have more than 1.
68
+ steps.push("cnts");
69
+ }
70
+ }
52
71
  }
72
+ // We're doing this weird dance with the steps variable because it's
73
+ // possible that you're printing an array nested under some parentheses, in
74
+ // which case we still want to descend down that far. For example,
75
+ // return([1, 2, 3]) should print as return 1, 2, 3.
76
+ parts = path.call((targetPath) => {
77
+ const target = targetPath.getValue();
78
+ joining = target.type === "args" || target.type === "args_add_block";
79
+ return print(targetPath);
80
+ }, ...steps);
53
81
  }
54
- // Now that we've established which actual node is the arguments to return,
55
- // we grab it out of the path by diving down the steps that we've set up.
56
- const parts = path.call(print, ...steps);
57
- const useBrackets = Array.isArray(parts) && parts.length > 1;
58
- // If we got the value straight out of the parens, then `parts` would only
59
- // be a singular doc as opposed to an array.
60
- const value = Array.isArray(parts) ? join([",", line], parts) : parts;
61
- // We only get here if we have comments somewhere that would prevent us from
62
- // skipping the parentheses.
63
- if (args.body.length === 1 && args.body[0].type === "paren") {
64
- return ["return", value];
82
+ // If we didn't hit any of our special cases, then just print out the
83
+ // arguments normally here.
84
+ if (parts === "") {
85
+ parts = path.call(print, "args");
86
+ joining = true;
65
87
  }
88
+ const useBrackets = Array.isArray(parts) && parts.length > 1;
89
+ const value = joining ? join([",", line], parts) : parts;
66
90
  return group([
67
91
  "return",
68
92
  ifBreak(useBrackets ? " [" : "(", " "),
@@ -72,4 +96,5 @@ const printReturn = (path, opts, print) => {
72
96
  ]);
73
97
  };
74
98
  exports.printReturn = printReturn;
75
- exports.printReturn0 = (0, utils_1.literal)("return");
99
+ const printReturn0 = (path) => path.getValue().value;
100
+ exports.printReturn0 = printReturn0;
@@ -3,40 +3,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printStmts = exports.printProgram = exports.printComment = exports.printEndContent = exports.printParen = exports.printBodyStmt = void 0;
6
+ exports.printStatements = exports.printProgram = exports.printComment = exports.printEndContent = exports.printParen = exports.printBodyStmt = void 0;
7
7
  const prettier_1 = __importDefault(require("../../prettier"));
8
8
  const utils_1 = require("../../utils");
9
+ const location_1 = require("../location");
9
10
  const { breakParent, dedent, group, hardline, indent, join, line, literalline, softline, trim } = prettier_1.default;
10
11
  const printBodyStmt = (path, opts, print) => {
11
- const [stmts, rescue, elseClause, ensure] = path.getValue().body;
12
+ const node = path.getValue();
12
13
  const parts = [];
13
- if (!(0, utils_1.isEmptyStmts)(stmts)) {
14
- parts.push(path.call(print, "body", 0));
14
+ if (!(0, utils_1.isEmptyStmts)(node.stmts)) {
15
+ parts.push(path.call(print, "stmts"));
15
16
  }
16
- if (rescue) {
17
- parts.push(dedent([hardline, path.call(print, "body", 1)]));
17
+ if (node.rsc) {
18
+ parts.push(dedent([hardline, path.call(print, "rsc")]));
18
19
  }
19
- if (elseClause) {
20
+ if (node.els) {
20
21
  // Before Ruby 2.6, this piece of bodystmt was an explicit "else" node
21
22
  /* istanbul ignore next */
22
- const stmts = elseClause.type === "else"
23
- ? path.call(print, "body", 2, "body", 0)
24
- : path.call(print, "body", 2);
23
+ const stmts = node.els.type === "else"
24
+ ? path.call(print, "els", "body", 0)
25
+ : path.call(print, "els");
25
26
  parts.push([dedent([hardline, "else"]), hardline, stmts]);
26
27
  }
27
- if (ensure) {
28
- parts.push(dedent([hardline, path.call(print, "body", 3)]));
28
+ if (node.ens) {
29
+ parts.push(dedent([hardline, path.call(print, "ens")]));
29
30
  }
30
31
  return group(parts);
31
32
  };
32
33
  exports.printBodyStmt = printBodyStmt;
33
- const argNodeTypes = ["args", "args_add_star", "args_add_block"];
34
+ const argNodeTypes = ["args", "args_add_block"];
34
35
  const printParen = (path, opts, print) => {
35
- const contentNode = path.getValue().body[0];
36
+ const contentNode = path.getValue().cnts;
36
37
  if (!contentNode) {
37
38
  return [path.call(print, "lparen"), ")"];
38
39
  }
39
- let contentDoc = path.call(print, "body", 0);
40
+ let contentDoc = path.call(print, "cnts");
40
41
  // If the content is params, we're going to let it handle its own parentheses
41
42
  // so that it breaks nicely.
42
43
  if (contentNode.type === "params") {
@@ -56,19 +57,17 @@ const printParen = (path, opts, print) => {
56
57
  };
57
58
  exports.printParen = printParen;
58
59
  const printEndContent = (path) => {
59
- const { body } = path.getValue();
60
- return [trim, "__END__", literalline, body];
60
+ const node = path.getValue();
61
+ return [trim, "__END__", literalline, node.value];
61
62
  };
62
63
  exports.printEndContent = printEndContent;
63
64
  const printComment = (path, opts) => {
64
65
  return opts.printer.printComment(path, opts);
65
66
  };
66
67
  exports.printComment = printComment;
67
- const printProgram = (path, opts, print) => {
68
- return [join(hardline, path.map(print, "body")), hardline];
69
- };
68
+ const printProgram = (path, opts, print) => [path.call(print, "stmts"), hardline];
70
69
  exports.printProgram = printProgram;
71
- const printStmts = (path, opts, print) => {
70
+ const printStatements = (path, opts, print) => {
72
71
  const stmts = path.getValue().body;
73
72
  // This is a special case where we have only comments inside a statement
74
73
  // list. In this case we want to avoid doing any kind of line number
@@ -93,19 +92,19 @@ const printStmts = (path, opts, print) => {
93
92
  if (lineNo === null) {
94
93
  parts.push(printed);
95
94
  }
96
- else if (stmt.sl - lineNo > 1 ||
95
+ else if ((0, location_1.getStartLine)(stmt.loc) - lineNo > 1 ||
97
96
  [stmt.type, stmts[index - 1].type].includes("access_ctrl")) {
98
97
  parts.push(hardline, hardline, printed);
99
98
  }
100
- else if (stmt.sl !== lineNo ||
99
+ else if ((0, location_1.getStartLine)(stmt.loc) !== lineNo ||
101
100
  path.getParentNode().type !== "string_embexpr") {
102
101
  parts.push(hardline, printed);
103
102
  }
104
103
  else {
105
104
  parts.push("; ", printed);
106
105
  }
107
- lineNo = stmt.el;
106
+ lineNo = (0, location_1.getEndLine)(stmt.loc);
108
107
  });
109
108
  return parts;
110
109
  };
111
- exports.printStmts = printStmts;
110
+ exports.printStatements = printStatements;