prettier 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -6
- data/README.md +16 -16
- data/exe/rbprettier +2 -2
- data/lib/prettier/rake/task.rb +5 -5
- data/lib/prettier.rb +11 -11
- data/package.json +9 -23
- data/rubocop.yml +6 -6
- data/{dist/parser → src}/getInfo.js +0 -1
- data/{dist/parser → src}/netcat.js +0 -1
- data/src/parseSync.js +212 -0
- data/src/plugin.js +161 -0
- data/{dist/parser → src}/server.rb +45 -31
- metadata +94 -78
- data/bin/console +0 -7
- data/dist/haml/embed.js +0 -53
- data/dist/haml/parser.js +0 -31
- data/dist/haml/parser.rb +0 -149
- data/dist/haml/printer.js +0 -336
- data/dist/parser/parseSync.js +0 -179
- data/dist/plugin.js +0 -143
- data/dist/prettier.js +0 -15
- data/dist/rbs/parser.js +0 -34
- data/dist/rbs/parser.rb +0 -155
- data/dist/rbs/printer.js +0 -525
- data/dist/ruby/embed.js +0 -115
- data/dist/ruby/location.js +0 -19
- data/dist/ruby/nodes/alias.js +0 -60
- data/dist/ruby/nodes/aref.js +0 -51
- data/dist/ruby/nodes/args.js +0 -138
- data/dist/ruby/nodes/arrays.js +0 -122
- data/dist/ruby/nodes/assign.js +0 -37
- data/dist/ruby/nodes/blocks.js +0 -90
- data/dist/ruby/nodes/calls.js +0 -263
- data/dist/ruby/nodes/case.js +0 -50
- data/dist/ruby/nodes/class.js +0 -54
- data/dist/ruby/nodes/commands.js +0 -138
- data/dist/ruby/nodes/conditionals.js +0 -246
- data/dist/ruby/nodes/constants.js +0 -35
- data/dist/ruby/nodes/flow.js +0 -59
- data/dist/ruby/nodes/hashes.js +0 -126
- data/dist/ruby/nodes/heredocs.js +0 -30
- data/dist/ruby/nodes/hooks.js +0 -35
- data/dist/ruby/nodes/ints.js +0 -27
- data/dist/ruby/nodes/lambdas.js +0 -70
- data/dist/ruby/nodes/loops.js +0 -75
- data/dist/ruby/nodes/massign.js +0 -60
- data/dist/ruby/nodes/methods.js +0 -50
- data/dist/ruby/nodes/operators.js +0 -68
- data/dist/ruby/nodes/params.js +0 -95
- data/dist/ruby/nodes/patterns.js +0 -119
- data/dist/ruby/nodes/regexp.js +0 -45
- data/dist/ruby/nodes/rescue.js +0 -86
- data/dist/ruby/nodes/return.js +0 -100
- data/dist/ruby/nodes/statements.js +0 -110
- data/dist/ruby/nodes/strings.js +0 -220
- data/dist/ruby/nodes/super.js +0 -26
- data/dist/ruby/nodes/undef.js +0 -31
- data/dist/ruby/nodes.js +0 -177
- data/dist/ruby/parser.js +0 -35
- data/dist/ruby/parser.rb +0 -9134
- data/dist/ruby/printer.js +0 -67
- data/dist/ruby/toProc.js +0 -91
- data/dist/types/haml.js +0 -4
- data/dist/types/plugin.js +0 -3
- data/dist/types/rbs.js +0 -4
- data/dist/types/ruby.js +0 -4
- data/dist/types/utils.js +0 -2
- data/dist/types.js +0 -34
- data/dist/utils/containsAssignment.js +0 -18
- data/dist/utils/getChildNodes.js +0 -305
- data/dist/utils/getTrailingComma.js +0 -6
- data/dist/utils/hasAncestor.js +0 -15
- data/dist/utils/inlineEnsureParens.js +0 -49
- data/dist/utils/isEmptyBodyStmt.js +0 -10
- data/dist/utils/isEmptyParams.js +0 -12
- data/dist/utils/isEmptyStmts.js +0 -10
- data/dist/utils/literal.js +0 -8
- data/dist/utils/literallineWithoutBreakParent.js +0 -8
- data/dist/utils/makeCall.js +0 -14
- data/dist/utils/noIndent.js +0 -11
- data/dist/utils/printEmptyCollection.js +0 -46
- data/dist/utils/skipAssignIndent.js +0 -19
- 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;
|
data/dist/ruby/nodes/flow.js
DELETED
@@ -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;
|
data/dist/ruby/nodes/hashes.js
DELETED
@@ -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;
|
data/dist/ruby/nodes/heredocs.js
DELETED
@@ -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;
|
data/dist/ruby/nodes/hooks.js
DELETED
@@ -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");
|
data/dist/ruby/nodes/ints.js
DELETED
@@ -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;
|
data/dist/ruby/nodes/lambdas.js
DELETED
@@ -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;
|