prettier 2.1.0 → 3.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -6
  3. data/README.md +17 -16
  4. data/exe/rbprettier +2 -2
  5. data/lib/prettier/rake/task.rb +5 -5
  6. data/lib/prettier.rb +11 -11
  7. data/package.json +11 -25
  8. data/rubocop.yml +32 -12
  9. data/{dist/parser → src}/getInfo.js +0 -1
  10. data/{dist/parser → src}/netcat.js +0 -1
  11. data/src/parseSync.js +216 -0
  12. data/src/plugin.js +170 -0
  13. data/{dist/parser → src}/server.rb +50 -31
  14. metadata +94 -78
  15. data/bin/console +0 -7
  16. data/dist/haml/embed.js +0 -53
  17. data/dist/haml/parser.js +0 -31
  18. data/dist/haml/parser.rb +0 -149
  19. data/dist/haml/printer.js +0 -336
  20. data/dist/parser/parseSync.js +0 -179
  21. data/dist/plugin.js +0 -143
  22. data/dist/prettier.js +0 -15
  23. data/dist/rbs/parser.js +0 -34
  24. data/dist/rbs/parser.rb +0 -155
  25. data/dist/rbs/printer.js +0 -525
  26. data/dist/ruby/embed.js +0 -115
  27. data/dist/ruby/location.js +0 -19
  28. data/dist/ruby/nodes/alias.js +0 -60
  29. data/dist/ruby/nodes/aref.js +0 -51
  30. data/dist/ruby/nodes/args.js +0 -138
  31. data/dist/ruby/nodes/arrays.js +0 -122
  32. data/dist/ruby/nodes/assign.js +0 -37
  33. data/dist/ruby/nodes/blocks.js +0 -90
  34. data/dist/ruby/nodes/calls.js +0 -263
  35. data/dist/ruby/nodes/case.js +0 -50
  36. data/dist/ruby/nodes/class.js +0 -54
  37. data/dist/ruby/nodes/commands.js +0 -138
  38. data/dist/ruby/nodes/conditionals.js +0 -246
  39. data/dist/ruby/nodes/constants.js +0 -35
  40. data/dist/ruby/nodes/flow.js +0 -59
  41. data/dist/ruby/nodes/hashes.js +0 -126
  42. data/dist/ruby/nodes/heredocs.js +0 -30
  43. data/dist/ruby/nodes/hooks.js +0 -35
  44. data/dist/ruby/nodes/ints.js +0 -27
  45. data/dist/ruby/nodes/lambdas.js +0 -70
  46. data/dist/ruby/nodes/loops.js +0 -75
  47. data/dist/ruby/nodes/massign.js +0 -60
  48. data/dist/ruby/nodes/methods.js +0 -50
  49. data/dist/ruby/nodes/operators.js +0 -68
  50. data/dist/ruby/nodes/params.js +0 -95
  51. data/dist/ruby/nodes/patterns.js +0 -119
  52. data/dist/ruby/nodes/regexp.js +0 -45
  53. data/dist/ruby/nodes/rescue.js +0 -86
  54. data/dist/ruby/nodes/return.js +0 -100
  55. data/dist/ruby/nodes/statements.js +0 -110
  56. data/dist/ruby/nodes/strings.js +0 -220
  57. data/dist/ruby/nodes/super.js +0 -26
  58. data/dist/ruby/nodes/undef.js +0 -31
  59. data/dist/ruby/nodes.js +0 -177
  60. data/dist/ruby/parser.js +0 -35
  61. data/dist/ruby/parser.rb +0 -9134
  62. data/dist/ruby/printer.js +0 -67
  63. data/dist/ruby/toProc.js +0 -91
  64. data/dist/types/haml.js +0 -4
  65. data/dist/types/plugin.js +0 -3
  66. data/dist/types/rbs.js +0 -4
  67. data/dist/types/ruby.js +0 -4
  68. data/dist/types/utils.js +0 -2
  69. data/dist/types.js +0 -34
  70. data/dist/utils/containsAssignment.js +0 -18
  71. data/dist/utils/getChildNodes.js +0 -305
  72. data/dist/utils/getTrailingComma.js +0 -6
  73. data/dist/utils/hasAncestor.js +0 -15
  74. data/dist/utils/inlineEnsureParens.js +0 -49
  75. data/dist/utils/isEmptyBodyStmt.js +0 -10
  76. data/dist/utils/isEmptyParams.js +0 -12
  77. data/dist/utils/isEmptyStmts.js +0 -10
  78. data/dist/utils/literal.js +0 -8
  79. data/dist/utils/literallineWithoutBreakParent.js +0 -8
  80. data/dist/utils/makeCall.js +0 -14
  81. data/dist/utils/noIndent.js +0 -11
  82. data/dist/utils/printEmptyCollection.js +0 -46
  83. data/dist/utils/skipAssignIndent.js +0 -19
  84. data/dist/utils.js +0 -32
@@ -1,246 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printUnlessModifier = exports.printUnless = exports.printIfModifier = exports.printIf = exports.printElsif = exports.printElse = exports.printTernary = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { align, breakParent, hardline, group, ifBreak, indent, softline } = prettier_1.default;
10
- // If the statements are just a single if/unless, in block or modifier form, or
11
- // a ternary
12
- function containsSingleConditional(stmts) {
13
- return (stmts.body.length === 1 &&
14
- ["if", "if_mod", "ifop", "unless", "unless_mod"].includes(stmts.body[0].type));
15
- }
16
- function printWithAddition(keyword, path, print, breaking) {
17
- return [
18
- `${keyword} `,
19
- align(keyword.length + 1, path.call(print, "pred")),
20
- indent([softline, path.call(print, "stmts")]),
21
- [softline, path.call(print, "cons")],
22
- [softline, "end"],
23
- breaking ? breakParent : ""
24
- ];
25
- }
26
- // For the unary `not` operator, we need to explicitly add parentheses to it in
27
- // order for it to be valid from within a ternary. Otherwise if the clause of
28
- // the ternary isn't a unary `not`, we can just pass it along.
29
- function printTernaryClause(clause) {
30
- if (Array.isArray(clause)) {
31
- const [part] = clause;
32
- if (Array.isArray(part) && part[0] === "not") {
33
- // We are inside of a statements list and the statement is a unary `not`.
34
- return ["not(", part[2], ")"];
35
- }
36
- if (clause[0] === "not") {
37
- // We are inside a ternary condition and the clause is a unary `not`.
38
- return ["not(", clause[2], ")"];
39
- }
40
- }
41
- return clause;
42
- }
43
- // The conditions for a ternary look like `foo : bar` where `foo` represents
44
- // the truthy clause and `bar` represents the falsy clause. In the case that the
45
- // parent node is an `unless`, these have to flip in order.
46
- function printTernaryClauses(keyword, truthyClause, falsyClause) {
47
- const parts = [
48
- printTernaryClause(truthyClause),
49
- " : ",
50
- printTernaryClause(falsyClause)
51
- ];
52
- return keyword === "if" ? parts : parts.reverse();
53
- }
54
- // Handles ternary nodes. If it does not fit on one line, then we break out into
55
- // an if/else statement. Otherwise we remain as a ternary.
56
- const printTernary = (path, _opts, print) => {
57
- const predicateDoc = path.call(print, "pred");
58
- const truthyDoc = path.call(print, "tthy");
59
- const falsyDoc = path.call(print, "flsy");
60
- return group(ifBreak([
61
- "if ",
62
- align(3, predicateDoc),
63
- indent([softline, truthyDoc]),
64
- [softline, "else"],
65
- indent([softline, falsyDoc]),
66
- [softline, "end"]
67
- ], [predicateDoc, " ? ", ...printTernaryClauses("if", truthyDoc, falsyDoc)]));
68
- };
69
- exports.printTernary = printTernary;
70
- function isModifier(node) {
71
- return node.type === "if_mod" || node.type === "unless_mod";
72
- }
73
- // Prints an `if_mod` or `unless_mod` node. Because it was previously in the
74
- // modifier form, we're guaranteed to not have an additional node, so we can
75
- // just work with the predicate and the body.
76
- function printSingle(keyword) {
77
- return function printSingleWithKeyword(path, { rubyModifier }, print) {
78
- const node = path.getValue();
79
- const predicateDoc = path.call(print, "pred");
80
- const statementsDoc = path.call(print, isModifier(node) ? "stmt" : "stmts");
81
- const multilineParts = [
82
- `${keyword} `,
83
- align(keyword.length + 1, predicateDoc),
84
- indent([softline, statementsDoc]),
85
- softline,
86
- "end"
87
- ];
88
- // If we do not allow modifier form conditionals or there are comments
89
- // inside of the body of the conditional, then we must print in the
90
- // multiline form.
91
- if (!rubyModifier || (!isModifier(node) && node.stmts.body[0].comments)) {
92
- return [multilineParts, breakParent];
93
- }
94
- const inline = (0, utils_1.inlineEnsureParens)(path, [
95
- statementsDoc,
96
- ` ${keyword} `,
97
- predicateDoc
98
- ]);
99
- // With an expression with a conditional modifier (expression if true), the
100
- // conditional body is parsed before the predicate expression, meaning that
101
- // if the parser encountered a variable declaration, it would initialize
102
- // that variable first before evaluating the predicate expression. That
103
- // parse order means the difference between a NameError or not. #591
104
- // https://docs.ruby-lang.org/en/2.0.0/syntax/control_expressions_rdoc.html#label-Modifier+if+and+unless
105
- if (isModifier(node) && (0, utils_1.containsAssignment)(node.stmt)) {
106
- return inline;
107
- }
108
- return group(ifBreak(multilineParts, inline));
109
- };
110
- }
111
- const noTernary = [
112
- "alias",
113
- "assign",
114
- "break",
115
- "command",
116
- "command_call",
117
- "heredoc",
118
- "if",
119
- "if_mod",
120
- "ifop",
121
- "lambda",
122
- "massign",
123
- "next",
124
- "opassign",
125
- "rescue_mod",
126
- "return",
127
- "return0",
128
- "super",
129
- "undef",
130
- "unless",
131
- "unless_mod",
132
- "until_mod",
133
- "var_alias",
134
- "void_stmt",
135
- "while_mod",
136
- "yield",
137
- "yield0",
138
- "zsuper"
139
- ];
140
- // Certain expressions cannot be reduced to a ternary without adding parens
141
- // around them. In this case we say they cannot be ternaried and default instead
142
- // to breaking them into multiple lines.
143
- function canTernaryStmts(stmts) {
144
- if (stmts.body.length !== 1) {
145
- return false;
146
- }
147
- const stmt = stmts.body[0];
148
- // If the user is using one of the lower precedence "and" or "or" operators,
149
- // then we can't use a ternary expression as it would break the flow control.
150
- if (stmt.type === "binary" && ["and", "or"].includes(stmt.op)) {
151
- return false;
152
- }
153
- // Check against the blocklist of statement types that are not allowed to be
154
- // a part of a ternary expression.
155
- return !noTernary.includes(stmt.type);
156
- }
157
- // In order for an `if` or `unless` expression to be shortened to a ternary,
158
- // there has to be one and only one "addition" (another clause attached) which
159
- // is of the "else" type. Both the body of the main node and the body of the
160
- // additional node must have only one statement, and that statement list must
161
- // pass the `canTernaryStmts` check.
162
- function canTernary(path) {
163
- const node = path.getValue();
164
- return (!["assign", "opassign", "command_call", "command"].includes(node.pred.type) &&
165
- node.cons &&
166
- node.cons.type === "else" &&
167
- canTernaryStmts(node.stmts) &&
168
- canTernaryStmts(node.cons.stmts));
169
- }
170
- // A normalized print function for both `if` and `unless` nodes.
171
- function printConditional(keyword) {
172
- return function printConditionalWithKeyword(path, opts, print) {
173
- if (canTernary(path)) {
174
- let ternaryParts = [
175
- path.call(print, "pred"),
176
- " ? ",
177
- ...printTernaryClauses(keyword, path.call(print, "stmts"), path.call(print, "cons", "stmts"))
178
- ];
179
- if (["binary", "call"].includes(path.getParentNode().type)) {
180
- ternaryParts = ["(", ...ternaryParts, ")"];
181
- }
182
- return group(ifBreak(printWithAddition(keyword, path, print, false), ternaryParts));
183
- }
184
- const node = path.getValue();
185
- // If there's an additional clause that wasn't matched earlier, we know we
186
- // can't go for the inline option.
187
- if (node.cons) {
188
- return group(printWithAddition(keyword, path, print, true));
189
- }
190
- // If the body of the conditional is empty, then we explicitly have to use
191
- // the block form.
192
- if ((0, utils_1.isEmptyStmts)(node.stmts)) {
193
- return [
194
- `${keyword} `,
195
- align(keyword.length + 1, path.call(print, "pred")),
196
- hardline,
197
- "end"
198
- ];
199
- }
200
- // Two situations in which we need to use the block form:
201
- //
202
- // 1. If the predicate of the conditional contains an assignment, then we
203
- // can't know for sure that it doesn't impact the body of the conditional.
204
- //
205
- // 2. If the conditional contains just another conditional, then collapsing
206
- // it would result in double modifiers on the same line.
207
- if ((0, utils_1.containsAssignment)(node.pred) ||
208
- containsSingleConditional(node.stmts)) {
209
- return [
210
- `${keyword} `,
211
- align(keyword.length + 1, path.call(print, "pred")),
212
- indent([hardline, path.call(print, "stmts")]),
213
- hardline,
214
- "end"
215
- ];
216
- }
217
- return printSingle(keyword)(path, opts, print);
218
- };
219
- }
220
- const printElse = (path, opts, print) => {
221
- const node = path.getValue();
222
- return [
223
- node.stmts.body.length === 1 && node.stmts.body[0].type === "command"
224
- ? breakParent
225
- : "",
226
- "else",
227
- indent([softline, path.call(print, "stmts")])
228
- ];
229
- };
230
- exports.printElse = printElse;
231
- const printElsif = (path, opts, print) => {
232
- const node = path.getValue();
233
- const parts = [
234
- group(["elsif ", align("elsif".length - 1, path.call(print, "pred"))]),
235
- indent([hardline, path.call(print, "stmts")])
236
- ];
237
- if (node.cons) {
238
- parts.push(group([hardline, path.call(print, "cons")]));
239
- }
240
- return group(parts);
241
- };
242
- exports.printElsif = printElsif;
243
- exports.printIf = printConditional("if");
244
- exports.printIfModifier = printSingle("if");
245
- exports.printUnless = printConditional("unless");
246
- exports.printUnlessModifier = printSingle("unless");
@@ -1,35 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printTopConst = exports.printField = exports.printDefined = exports.printConstRef = exports.printConstPath = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { group, indent, softline } = prettier_1.default;
10
- const printConstPath = (path, opts, print) => [path.call(print, "parent"), "::", path.call(print, "constant")];
11
- exports.printConstPath = printConstPath;
12
- const printConstRef = (path, opts, print) => path.call(print, "constant");
13
- exports.printConstRef = printConstRef;
14
- const printDefined = (path, opts, print) => {
15
- return group([
16
- "defined?(",
17
- indent([softline, path.call(print, "value")]),
18
- softline,
19
- ")"
20
- ]);
21
- };
22
- exports.printDefined = printDefined;
23
- const printField = (path, opts, print) => {
24
- return group([
25
- path.call(print, "parent"),
26
- (0, utils_1.makeCall)(path, opts, print),
27
- path.call(print, "name")
28
- ]);
29
- };
30
- exports.printField = printField;
31
- const printTopConst = (path, opts, print) => [
32
- "::",
33
- path.call(print, "constant")
34
- ];
35
- exports.printTopConst = printTopConst;
@@ -1,59 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printYield0 = exports.printYield = exports.printNext = exports.printBreak = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const { join } = prettier_1.default;
9
- // If there are parentheses around these nodes, then we can't skip printing them
10
- // without changing the semantic meaning of the statement.
11
- const unskippableParens = [
12
- "if_mod",
13
- "rescue_mod",
14
- "unless_mod",
15
- "until_mod",
16
- "while_mod"
17
- ];
18
- function printFlowControl(keyword) {
19
- return function printFlowControlWithKeyword(path, opts, print) {
20
- const node = path.getValue();
21
- // If we don't have any arguments to the keyword, then it's always going to
22
- // come in as an args node, in which case we can just print the keyword.
23
- if (node.args.type === "args") {
24
- return keyword;
25
- }
26
- // Special handling if we've got parentheses on this call to the keyword. If
27
- // we do and we can skip them, then we will. If we don't, then we'll print
28
- // them right after the keyword with no space.
29
- const paren = node.args.args.type === "args" && node.args.args.parts[0];
30
- if (paren && paren.type === "paren") {
31
- const stmts = paren.cnts.body;
32
- // Here we're checking if we can skip past the parentheses entirely.
33
- if (stmts.length === 1 && !unskippableParens.includes(stmts[0].type)) {
34
- return [
35
- `${keyword} `,
36
- path.call(print, "args", "args", "parts", 0, "cnts")
37
- ];
38
- }
39
- // Here we know we can't, so just printing out the parentheses as normal.
40
- return [keyword, path.call(print, "args", "args", "parts", 0)];
41
- }
42
- // If we didn't hit the super special handling, then we're just going to
43
- // print out the arguments to the keyword like normal.
44
- return [`${keyword} `, join(", ", path.call(print, "args"))];
45
- };
46
- }
47
- exports.printBreak = printFlowControl("break");
48
- exports.printNext = printFlowControl("next");
49
- const printYield = (path, opts, print) => {
50
- const node = path.getValue();
51
- const argsDoc = path.call(print, "args");
52
- if (node.args.type === "paren") {
53
- return ["yield", argsDoc];
54
- }
55
- return ["yield ", join(", ", argsDoc)];
56
- };
57
- exports.printYield = printYield;
58
- const printYield0 = (path) => path.getValue().value;
59
- exports.printYield0 = printYield0;
@@ -1,126 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printHash = exports.printHashContents = exports.printAssocSplat = exports.printAssoc = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { group, ifBreak, indent, join, line } = prettier_1.default;
10
- // When attempting to convert a hash rocket into a hash label, you need to take
11
- // care because only certain patterns are allowed. Ruby source says that they
12
- // have to match keyword arguments to methods, but don't specify what that is.
13
- // After some experimentation, it looks like it's:
14
- //
15
- // * Starts with a letter (either case) or an underscore
16
- // * Does not end in equal
17
- //
18
- // This function represents that check, as it determines if it can convert the
19
- // symbol node into a hash label.
20
- function isValidHashLabel(symbolLiteral) {
21
- const label = symbolLiteral.value.value;
22
- return label.match(/^[_A-Za-z]/) && !label.endsWith("=");
23
- }
24
- function canUseHashLabels(contentsNode) {
25
- return contentsNode.assocs.every((assocNode) => {
26
- if (assocNode.type === "assoc_splat") {
27
- return true;
28
- }
29
- switch (assocNode.key.type) {
30
- case "label":
31
- return true;
32
- case "symbol_literal":
33
- return isValidHashLabel(assocNode.key);
34
- case "dyna_symbol":
35
- return true;
36
- default:
37
- return false;
38
- }
39
- });
40
- }
41
- const printHashKeyLabel = (path, print) => {
42
- const node = path.getValue();
43
- switch (node.type) {
44
- case "label":
45
- return print(path);
46
- case "symbol_literal":
47
- return [path.call(print, "value"), ":"];
48
- case "dyna_symbol":
49
- return [print(path), ":"];
50
- default:
51
- // This should never happen, but keeping it here so that the two key
52
- // printers can maintain the same signature.
53
- return "";
54
- }
55
- };
56
- const printHashKeyRocket = (path, print) => {
57
- const node = path.getValue();
58
- let doc = print(path);
59
- if (node.type === "label") {
60
- const sDoc = doc; // since we know this is a label
61
- doc = [":", sDoc.slice(0, sDoc.length - 1)];
62
- }
63
- else if (node.type === "dyna_symbol") {
64
- doc = [":", doc];
65
- }
66
- return [doc, " =>"];
67
- };
68
- const printAssoc = (path, opts, print) => {
69
- const node = path.getValue();
70
- const { keyPrinter } = path.getParentNode();
71
- const parts = [path.call((keyPath) => keyPrinter(keyPath, print), "key")];
72
- const valueDoc = path.call(print, "value");
73
- // If we're printing a child hash then we want it to break along with its
74
- // parent hash, so we don't group the parts.
75
- if (node.value.type === "hash") {
76
- parts.push(" ", valueDoc);
77
- return parts;
78
- }
79
- if (!(0, utils_1.skipAssignIndent)(node.value) || node.key.comments) {
80
- parts.push(indent([line, valueDoc]));
81
- }
82
- else {
83
- parts.push(" ", valueDoc);
84
- }
85
- return group(parts);
86
- };
87
- exports.printAssoc = printAssoc;
88
- const printAssocSplat = (path, opts, print) => ["**", path.call(print, "value")];
89
- exports.printAssocSplat = printAssocSplat;
90
- const printHashContents = (path, opts, print) => {
91
- const node = path.getValue();
92
- // First determine which key printer we're going to use, so that the child
93
- // nodes can reference it when they go to get printed.
94
- node.keyPrinter =
95
- opts.rubyHashLabel && canUseHashLabels(path.getValue())
96
- ? printHashKeyLabel
97
- : printHashKeyRocket;
98
- return join([",", line], path.map(print, "assocs"));
99
- };
100
- exports.printHashContents = printHashContents;
101
- const printHash = (path, opts, print) => {
102
- const node = path.getValue();
103
- // Hashes normally have a single assoclist_from_args child node. If it's
104
- // missing, then it means we're dealing with an empty hash, so we can just
105
- // exit here and print.
106
- if (node.cnts === null) {
107
- return (0, utils_1.printEmptyCollection)(path, opts, "{", "}");
108
- }
109
- const doc = [
110
- "{",
111
- indent([
112
- line,
113
- path.call(print, "cnts"),
114
- (0, utils_1.getTrailingComma)(opts) ? ifBreak(",", "") : ""
115
- ]),
116
- line,
117
- "}"
118
- ];
119
- // If we're inside another hash, then we don't want to group our contents
120
- // because we want this hash to break along with its parent hash.
121
- if (path.getParentNode().type === "assoc") {
122
- return doc;
123
- }
124
- return group(doc);
125
- };
126
- exports.printHash = printHash;
@@ -1,30 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printHeredoc = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { group, lineSuffix, join } = prettier_1.default;
10
- const printHeredoc = (path, opts, print) => {
11
- const node = path.getValue();
12
- // Print out each part of the heredoc to its own doc node.
13
- const parts = path.map((partPath) => {
14
- const part = partPath.getValue();
15
- if (part.type !== "tstring_content") {
16
- return print(partPath);
17
- }
18
- return join(utils_1.literallineWithoutBreakParent, part.value.split(/\r?\n/));
19
- }, "parts");
20
- // We use a literalline break because matching indentation is required
21
- // for the heredoc contents and ending. If the line suffix contains a
22
- // break-parent, all ancestral groups are broken, and heredocs automatically
23
- // break lines in groups they appear in. We prefer them to appear in-line if
24
- // possible, so we use a literalline without the break-parent.
25
- return group([
26
- path.call(print, "beging"),
27
- lineSuffix(group([utils_1.literallineWithoutBreakParent, ...parts, node.ending]))
28
- ]);
29
- };
30
- exports.printHeredoc = printHeredoc;
@@ -1,35 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printEND = exports.printBEGIN = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const { group, indent, line } = prettier_1.default;
9
- // The `BEGIN` and `END` keywords are used to hook into the Ruby process. Any
10
- // `BEGIN` blocks are executed right when the process starts up, and the `END`
11
- // blocks are executed right before exiting.
12
- //
13
- // BEGIN {
14
- // # content goes here
15
- // }
16
- //
17
- // END {
18
- // # content goes here
19
- // }
20
- //
21
- // Interesting side note, you don't use `do...end` blocks with these hooks. Both
22
- // nodes contain one child which is a `stmts` node.
23
- function printHook(name) {
24
- return function printHookWithName(path, opts, print) {
25
- return group([
26
- name,
27
- " ",
28
- path.call(print, "lbrace"),
29
- indent([line, path.call(print, "stmts")]),
30
- [line, "}"]
31
- ]);
32
- };
33
- }
34
- exports.printBEGIN = printHook("BEGIN");
35
- exports.printEND = printHook("END");
@@ -1,27 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.printInt = void 0;
4
- // An @int node is any literal integer in Ruby. They can come in a number of
5
- // bases, and look like the following:
6
- //
7
- // Binary (2) - 0b0110
8
- // Octal (8) - 0o34 or 034
9
- // Decimal (10) - 159 or 0d159
10
- // Hexidecimal (16) - 0xac5
11
- //
12
- // If it's a decimal number, it can be optional separated by any number of
13
- // arbitrarily places underscores. This can be useful for dollars and cents
14
- // (34_99), dates (2020_11_30), and normal 3 digit separation (1_222_333).
15
- const printInt = (path) => {
16
- const { value } = path.getValue();
17
- // If the number is a base 10 number, is sufficiently large, and is not
18
- // already formatted with underscores, then add them in in between the
19
- // numbers every three characters starting from the right.
20
- if (!value.startsWith("0") && value.length >= 5 && !value.includes("_")) {
21
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
22
- const segments = ` ${value}`.slice((value.length + 2) % 3).match(/.{3}/g);
23
- return segments.join("_").trim();
24
- }
25
- return value;
26
- };
27
- exports.printInt = printInt;
@@ -1,70 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.printLambda = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { group, ifBreak, indent, line } = prettier_1.default;
10
- // We can have our params coming in as the first child of the main lambda node,
11
- // or if we have them wrapped in parens then they'll be one level deeper. Even
12
- // though it's possible to omit the parens if you only have one argument, we're
13
- // going to keep them in no matter what for consistency.
14
- function printLambdaParams(path, print) {
15
- let node = path.getValue().params;
16
- // In this case we had something like -> (foo) { bar } which would mean that
17
- // we're looking at a paren node, so we'll descend one level deeper to get at
18
- // the actual params node.
19
- if (node.type !== "params") {
20
- node = node.cnts;
21
- }
22
- // If we don't have any params at all, then we're just going to bail out and
23
- // print nothing. This is to avoid printing an empty set of parentheses.
24
- if ((0, utils_1.isEmptyParams)(node)) {
25
- return "";
26
- }
27
- return path.call(print, "params");
28
- }
29
- // Lambda nodes represent stabby lambda literals, which can come in a couple of
30
- // flavors. They can use either braces or do...end for their block, and their
31
- // arguments can be not present, have no parentheses for a single argument, or
32
- // have parentheses for multiple arguments. Below are a couple of examples:
33
- //
34
- // -> { 1 }
35
- // -> a { a + 1 }
36
- // ->(a) { a + 1 }
37
- // ->(a, b) { a + b }
38
- // ->(a, b = 1) { a + b }
39
- //
40
- // -> do
41
- // 1
42
- // end
43
- //
44
- // -> a do
45
- // a + 1
46
- // end
47
- //
48
- // ->(a, b) do
49
- // a + b
50
- // end
51
- //
52
- // Generally, we're going to favor do...end for the multi-line form and braces
53
- // for the single-line form. However, if we have an ancestor that is a command
54
- // or command_call node, then we'll need to use braces either way because of
55
- // operator precendence.
56
- const printLambda = (path, opts, print) => {
57
- const params = printLambdaParams(path, print);
58
- const inCommand = (0, utils_1.hasAncestor)(path, ["command", "command_call"]);
59
- const stmtsDoc = path.call(print, "stmts");
60
- return group(ifBreak([
61
- "->",
62
- params,
63
- " ",
64
- inCommand ? "{" : "do",
65
- indent([line, stmtsDoc]),
66
- line,
67
- inCommand ? "}" : "end"
68
- ], ["->", params, " { ", stmtsDoc, " }"]));
69
- };
70
- exports.printLambda = printLambda;