prettier 0.21.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -1
- data/CONTRIBUTING.md +3 -3
- data/README.md +4 -0
- data/package.json +3 -3
- data/src/embed.js +20 -5
- data/src/nodes.js +5 -2
- data/src/nodes/alias.js +29 -31
- data/src/nodes/aref.js +26 -26
- data/src/nodes/args.js +56 -28
- data/src/nodes/arrays.js +142 -104
- data/src/nodes/assign.js +30 -30
- data/src/nodes/blocks.js +8 -3
- data/src/nodes/calls.js +108 -53
- data/src/nodes/class.js +74 -0
- data/src/nodes/commands.js +36 -31
- data/src/nodes/conditionals.js +42 -28
- data/src/nodes/constants.js +39 -21
- data/src/nodes/flow.js +11 -1
- data/src/nodes/hashes.js +60 -87
- data/src/nodes/heredocs.js +34 -0
- data/src/nodes/hooks.js +16 -19
- data/src/nodes/ints.js +33 -20
- data/src/nodes/lambdas.js +15 -12
- data/src/nodes/loops.js +6 -2
- data/src/nodes/massign.js +87 -65
- data/src/nodes/methods.js +46 -73
- data/src/nodes/operators.js +66 -46
- data/src/nodes/params.js +12 -14
- data/src/nodes/patterns.js +108 -33
- data/src/nodes/regexp.js +22 -13
- data/src/nodes/rescue.js +72 -59
- data/src/nodes/statements.js +23 -1
- data/src/nodes/strings.js +89 -80
- data/src/nodes/super.js +35 -0
- data/src/nodes/undef.js +42 -0
- data/src/parser.js +71 -0
- data/src/parser.rb +2269 -625
- data/src/printer.js +88 -0
- data/src/ruby.js +4 -20
- data/src/toProc.js +2 -2
- data/src/utils.js +10 -86
- data/src/utils/literalLineNoBreak.js +7 -0
- metadata +9 -5
- data/src/nodes/scopes.js +0 -61
- data/src/parse.js +0 -37
- data/src/print.js +0 -23
data/src/nodes/operators.js
CHANGED
@@ -1,52 +1,72 @@
|
|
1
1
|
const { concat, group, indent, line, softline } = require("../prettier");
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
return group(
|
9
|
-
concat([
|
10
|
-
group(path.call(print, "body", 0)),
|
11
|
-
indent(
|
12
|
-
concat([
|
13
|
-
useNoSpace ? "" : " ",
|
14
|
-
group(
|
15
|
-
concat([
|
16
|
-
operator,
|
17
|
-
useNoSpace ? softline : line,
|
18
|
-
path.call(print, "body", 2)
|
19
|
-
])
|
20
|
-
)
|
21
|
-
])
|
22
|
-
)
|
23
|
-
])
|
24
|
-
);
|
25
|
-
},
|
26
|
-
dot2: (path, opts, print) =>
|
27
|
-
concat([
|
28
|
-
path.call(print, "body", 0),
|
29
|
-
"..",
|
30
|
-
path.getValue().body[1] ? path.call(print, "body", 1) : ""
|
31
|
-
]),
|
32
|
-
dot3: (path, opts, print) =>
|
3
|
+
function printBinary(path, opts, print) {
|
4
|
+
const operator = path.getValue().body[1];
|
5
|
+
const useNoSpace = operator === "**";
|
6
|
+
|
7
|
+
return group(
|
33
8
|
concat([
|
34
|
-
path.call(print, "body", 0),
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
9
|
+
group(path.call(print, "body", 0)),
|
10
|
+
indent(
|
11
|
+
concat([
|
12
|
+
useNoSpace ? "" : " ",
|
13
|
+
group(
|
14
|
+
concat([
|
15
|
+
operator,
|
16
|
+
useNoSpace ? softline : line,
|
17
|
+
path.call(print, "body", 2)
|
18
|
+
])
|
19
|
+
)
|
20
|
+
])
|
21
|
+
)
|
22
|
+
])
|
23
|
+
);
|
24
|
+
}
|
25
|
+
|
26
|
+
// dot2 nodes are used with ranges (or flip-flops). They can optionally drop
|
27
|
+
// their left side for beginless ranges or their right side for endless ranges.
|
28
|
+
function printDot2(path, opts, print) {
|
29
|
+
const [leftNode, rightNode] = path.getValue().body;
|
30
|
+
|
31
|
+
return concat([
|
32
|
+
leftNode ? path.call(print, "body", 0) : "",
|
33
|
+
"..",
|
34
|
+
rightNode ? path.call(print, "body", 1) : ""
|
35
|
+
]);
|
36
|
+
}
|
37
|
+
|
38
|
+
// dot3 nodes are used with ranges (or flip-flops). They can optionally drop
|
39
|
+
// their left side for beginless ranges or their right side for endless ranges.
|
40
|
+
function printDot3(path, opts, print) {
|
41
|
+
const [leftNode, rightNode] = path.getValue().body;
|
49
42
|
|
50
|
-
|
43
|
+
return concat([
|
44
|
+
leftNode ? path.call(print, "body", 0) : "",
|
45
|
+
"...",
|
46
|
+
rightNode ? path.call(print, "body", 1) : ""
|
47
|
+
]);
|
48
|
+
}
|
49
|
+
|
50
|
+
function printUnary(path, opts, print) {
|
51
|
+
const node = path.getValue();
|
52
|
+
const contentsDoc = path.call(print, "body", 0);
|
53
|
+
|
54
|
+
if (node.oper === "not") {
|
55
|
+
// Here we defer to the original source, as it's kind of difficult to
|
56
|
+
// determine if we can actually remove the parentheses being used.
|
57
|
+
if (node.paren) {
|
58
|
+
return concat(["not", "(", contentsDoc, ")"]);
|
59
|
+
} else {
|
60
|
+
return concat(["not", " ", contentsDoc]);
|
61
|
+
}
|
51
62
|
}
|
63
|
+
|
64
|
+
return concat([node.oper, contentsDoc]);
|
65
|
+
}
|
66
|
+
|
67
|
+
module.exports = {
|
68
|
+
binary: printBinary,
|
69
|
+
dot2: printDot2,
|
70
|
+
dot3: printDot3,
|
71
|
+
unary: printUnary
|
52
72
|
};
|
data/src/nodes/params.js
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
const { concat, group, join, line } = require("../prettier");
|
2
2
|
const { literal } = require("../utils");
|
3
3
|
|
4
|
-
|
5
|
-
path
|
6
|
-
|
7
|
-
|
4
|
+
function printRestParam(symbol) {
|
5
|
+
return function printRestParamWithSymbol(path, opts, print) {
|
6
|
+
return path.getValue().body[0]
|
7
|
+
? concat([symbol, path.call(print, "body", 0)])
|
8
|
+
: symbol;
|
9
|
+
};
|
10
|
+
}
|
8
11
|
|
9
|
-
|
12
|
+
function printParams(path, opts, print) {
|
10
13
|
const [
|
11
14
|
reqs,
|
12
15
|
optls,
|
@@ -73,16 +76,11 @@ const printParams = (path, opts, print) => {
|
|
73
76
|
const comma = rest === 0 || (rest && rest.type === "excessed_comma");
|
74
77
|
|
75
78
|
return group(concat([join(concat([",", line]), parts), comma ? "," : ""]));
|
76
|
-
}
|
77
|
-
|
78
|
-
const paramError = () => {
|
79
|
-
throw new Error("formal argument cannot be a global variable");
|
80
|
-
};
|
79
|
+
}
|
81
80
|
|
82
81
|
module.exports = {
|
83
82
|
args_forward: literal("..."),
|
84
|
-
kwrest_param:
|
85
|
-
rest_param:
|
86
|
-
params: printParams
|
87
|
-
param_error: paramError
|
83
|
+
kwrest_param: printRestParam("**"),
|
84
|
+
rest_param: printRestParam("*"),
|
85
|
+
params: printParams
|
88
86
|
};
|
data/src/nodes/patterns.js
CHANGED
@@ -1,43 +1,118 @@
|
|
1
1
|
const { concat, group, hardline, indent, join, line } = require("../prettier");
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
function printPatternArg(path, opts, print) {
|
4
|
+
// Pinning is a really special syntax in pattern matching that's not really
|
5
|
+
// all that well supported in ripper. Here we're just going to the original
|
6
|
+
// source to see if the variable is pinned.
|
7
|
+
if (
|
8
|
+
opts.originalText &&
|
9
|
+
opts.originalText[opts.locStart(path.getValue()) - 1] === "^"
|
10
|
+
) {
|
11
|
+
return concat(["^", path.call(print)]);
|
12
|
+
}
|
7
13
|
|
8
|
-
|
9
|
-
|
10
|
-
}
|
14
|
+
return path.call(print);
|
15
|
+
}
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
function printAryPtn(path, opts, print) {
|
18
|
+
const [constant, preargs, splatarg, postargs] = path.getValue().body;
|
19
|
+
let args = [];
|
15
20
|
|
16
|
-
|
17
|
-
|
18
|
-
|
21
|
+
if (preargs) {
|
22
|
+
args = args.concat(
|
23
|
+
path.map((argPath) => printPatternArg(argPath, opts, print), "body", 1)
|
24
|
+
);
|
25
|
+
}
|
19
26
|
|
20
|
-
|
27
|
+
if (splatarg) {
|
28
|
+
args.push(concat(["*", path.call(print, "body", 2)]));
|
29
|
+
}
|
21
30
|
|
22
|
-
|
23
|
-
|
24
|
-
|
31
|
+
if (postargs) {
|
32
|
+
args = args.concat(path.map(print, "body", 3));
|
33
|
+
}
|
25
34
|
|
26
|
-
|
27
|
-
return concat([path.call(print, "body", 0), args]);
|
28
|
-
}
|
35
|
+
args = group(join(concat([",", line]), args));
|
29
36
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
concat([
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
if (
|
38
|
+
constant ||
|
39
|
+
["aryptn", "binary", "hshptn"].includes(path.getParentNode().type)
|
40
|
+
) {
|
41
|
+
args = concat(["[", args, "]"]);
|
42
|
+
}
|
43
|
+
|
44
|
+
if (constant) {
|
45
|
+
return concat([path.call(print, "body", 0), args]);
|
46
|
+
}
|
47
|
+
|
48
|
+
return args;
|
49
|
+
}
|
50
|
+
|
51
|
+
function printHshPtn(path, opts, print) {
|
52
|
+
const [constant, keyValuePairs, keyValueRest] = path.getValue().body;
|
53
|
+
let args = [];
|
54
|
+
|
55
|
+
if (keyValuePairs) {
|
56
|
+
const printPair = (pairPath) => {
|
57
|
+
const parts = [pairPath.call(print, 0)];
|
58
|
+
|
59
|
+
if (pairPath.getValue()[1]) {
|
60
|
+
parts.push(
|
61
|
+
" ",
|
62
|
+
pairPath.call(
|
63
|
+
(pairValuePath) => printPatternArg(pairValuePath, opts, print),
|
64
|
+
1
|
65
|
+
)
|
66
|
+
);
|
67
|
+
}
|
68
|
+
|
69
|
+
return concat(parts);
|
70
|
+
};
|
71
|
+
|
72
|
+
args = args.concat(path.map(printPair, "body", 1));
|
73
|
+
}
|
74
|
+
|
75
|
+
if (keyValueRest) {
|
76
|
+
args.push(concat(["**", path.call(print, "body", 2)]));
|
77
|
+
}
|
78
|
+
|
79
|
+
args = group(join(concat([",", line]), args));
|
80
|
+
|
81
|
+
if (constant) {
|
82
|
+
args = concat(["[", args, "]"]);
|
83
|
+
} else if (
|
84
|
+
["aryptn", "binary", "hshptn"].includes(path.getParentNode().type)
|
85
|
+
) {
|
86
|
+
args = concat(["{", args, "}"]);
|
87
|
+
}
|
88
|
+
|
89
|
+
if (constant) {
|
90
|
+
return concat([path.call(print, "body", 0), args]);
|
91
|
+
}
|
92
|
+
|
93
|
+
return args;
|
94
|
+
}
|
95
|
+
|
96
|
+
function printIn(path, opts, print) {
|
97
|
+
const parts = [
|
98
|
+
"in ",
|
99
|
+
path.call(
|
100
|
+
(valuePath) => printPatternArg(valuePath, opts, print),
|
101
|
+
"body",
|
102
|
+
0
|
103
|
+
),
|
104
|
+
indent(concat([hardline, path.call(print, "body", 1)]))
|
105
|
+
];
|
106
|
+
|
107
|
+
if (path.getValue().body[2]) {
|
108
|
+
parts.push(hardline, path.call(print, "body", 2));
|
109
|
+
}
|
110
|
+
|
111
|
+
return group(concat(parts));
|
112
|
+
}
|
113
|
+
|
114
|
+
module.exports = {
|
115
|
+
aryptn: printAryPtn,
|
116
|
+
hshptn: printHshPtn,
|
117
|
+
in: printIn
|
43
118
|
};
|
data/src/nodes/regexp.js
CHANGED
@@ -1,18 +1,27 @@
|
|
1
1
|
const { concat } = require("../prettier");
|
2
|
-
const { makeList } = require("../utils");
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
// This function is responsible for printing out regexp_literal nodes. They can
|
4
|
+
// either use the special %r literal syntax or they can use forward slashes. At
|
5
|
+
// the end of either of those they can have modifiers like m or x that have
|
6
|
+
// special meaning for the regex engine.
|
7
|
+
//
|
8
|
+
// We favor the use of forward slashes unless the regex contains a forward slash
|
9
|
+
// itself. In that case we switch over to using %r with braces.
|
10
|
+
function printRegexpLiteral(path, opts, print) {
|
11
|
+
const { ending } = path.getValue();
|
12
|
+
const contents = path.map(print, "body");
|
13
|
+
|
14
|
+
const useBraces = contents.some(
|
15
|
+
(content) => typeof content === "string" && content.includes("/")
|
16
|
+
);
|
8
17
|
|
9
|
-
|
10
|
-
|
11
|
-
);
|
12
|
-
const parts = [useBraces ? "%r{" : "/"]
|
13
|
-
.concat(contents)
|
14
|
-
.concat([useBraces ? "}" : "/", ending.slice(1)]);
|
18
|
+
const parts = [useBraces ? "%r{" : "/"]
|
19
|
+
.concat(contents)
|
20
|
+
.concat([useBraces ? "}" : "/", ending.slice(1)]);
|
15
21
|
|
16
|
-
|
17
|
-
|
22
|
+
return concat(parts);
|
23
|
+
}
|
24
|
+
|
25
|
+
module.exports = {
|
26
|
+
regexp_literal: printRegexpLiteral
|
18
27
|
};
|
data/src/nodes/rescue.js
CHANGED
@@ -9,73 +9,86 @@ const {
|
|
9
9
|
} = require("../prettier");
|
10
10
|
const { literal } = require("../utils");
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
ensure: (path, opts, print) =>
|
21
|
-
concat([
|
22
|
-
"ensure",
|
23
|
-
indent(concat([hardline, concat(path.map(print, "body"))]))
|
24
|
-
]),
|
25
|
-
redo: literal("redo"),
|
26
|
-
rescue: (path, opts, print) => {
|
27
|
-
const [exception, variable, _stmts, addition] = path.getValue().body;
|
28
|
-
const parts = ["rescue"];
|
12
|
+
function printBegin(path, opts, print) {
|
13
|
+
return concat([
|
14
|
+
"begin",
|
15
|
+
indent(concat([hardline, concat(path.map(print, "body"))])),
|
16
|
+
hardline,
|
17
|
+
"end"
|
18
|
+
]);
|
19
|
+
}
|
29
20
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
} else {
|
37
|
-
// Here we have multiple exceptions from which we're rescuing, so we
|
38
|
-
// need to align them and join them together.
|
39
|
-
const joiner = concat([",", line]);
|
40
|
-
const exceptions = group(join(joiner, path.call(print, "body", 0)));
|
21
|
+
function printEnsure(path, opts, print) {
|
22
|
+
return concat([
|
23
|
+
"ensure",
|
24
|
+
indent(concat([hardline, concat(path.map(print, "body"))]))
|
25
|
+
]);
|
26
|
+
}
|
41
27
|
|
42
|
-
|
43
|
-
|
44
|
-
|
28
|
+
function printRescue(path, opts, print) {
|
29
|
+
const [exception, variable, _stmts, addition] = path.getValue().body;
|
30
|
+
const parts = ["rescue"];
|
31
|
+
|
32
|
+
if (exception || variable) {
|
33
|
+
if (exception) {
|
34
|
+
if (Array.isArray(exception)) {
|
35
|
+
// In this case, it's actually only the one exception (it's an array
|
36
|
+
// of length 1).
|
37
|
+
parts.push(" ", path.call(print, "body", 0, 0));
|
38
|
+
} else {
|
39
|
+
// Here we have multiple exceptions from which we're rescuing, so we
|
40
|
+
// need to align them and join them together.
|
41
|
+
const joiner = concat([",", line]);
|
42
|
+
const exceptions = group(join(joiner, path.call(print, "body", 0)));
|
45
43
|
|
46
|
-
|
47
|
-
parts.push(" => ", path.call(print, "body", 1));
|
44
|
+
parts.push(" ", align("rescue ".length, exceptions));
|
48
45
|
}
|
49
|
-
} else {
|
50
|
-
// If you don't specify an error to rescue in a `begin/rescue` block, then
|
51
|
-
// implicitly you're rescuing from `StandardError`. In this case, we're
|
52
|
-
// just going to explicitly add it.
|
53
|
-
parts.push(" StandardError");
|
54
46
|
}
|
55
47
|
|
56
|
-
|
57
|
-
|
58
|
-
if (rescueBody.parts.length > 0) {
|
59
|
-
parts.push(indent(concat([hardline, rescueBody])));
|
48
|
+
if (variable) {
|
49
|
+
parts.push(" => ", path.call(print, "body", 1));
|
60
50
|
}
|
51
|
+
} else {
|
52
|
+
// If you don't specify an error to rescue in a `begin/rescue` block, then
|
53
|
+
// implicitly you're rescuing from `StandardError`. In this case, we're
|
54
|
+
// just going to explicitly add it.
|
55
|
+
parts.push(" StandardError");
|
56
|
+
}
|
61
57
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
58
|
+
const rescueBody = path.call(print, "body", 2);
|
59
|
+
|
60
|
+
if (rescueBody.parts.length > 0) {
|
61
|
+
parts.push(indent(concat([hardline, rescueBody])));
|
62
|
+
}
|
67
63
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
concat([
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
64
|
+
// This is the next clause on the `begin` statement, either another
|
65
|
+
// `rescue`, and `ensure`, or an `else` clause.
|
66
|
+
if (addition) {
|
67
|
+
parts.push(concat([hardline, path.call(print, "body", 3)]));
|
68
|
+
}
|
69
|
+
|
70
|
+
return group(concat(parts));
|
71
|
+
}
|
72
|
+
|
73
|
+
function printRescueMod(path, opts, print) {
|
74
|
+
const [statementDoc, valueDoc] = path.map(print, "body");
|
75
|
+
|
76
|
+
return concat([
|
77
|
+
"begin",
|
78
|
+
indent(concat([hardline, statementDoc])),
|
79
|
+
hardline,
|
80
|
+
"rescue StandardError",
|
81
|
+
indent(concat([hardline, valueDoc])),
|
82
|
+
hardline,
|
83
|
+
"end"
|
84
|
+
]);
|
85
|
+
}
|
86
|
+
|
87
|
+
module.exports = {
|
88
|
+
begin: printBegin,
|
89
|
+
ensure: printEnsure,
|
90
|
+
redo: literal("redo"),
|
91
|
+
rescue: printRescue,
|
92
|
+
rescue_mod: printRescueMod,
|
80
93
|
retry: literal("retry")
|
81
94
|
};
|