prettier 0.21.0 → 0.22.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 +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/class.js
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
const {
|
2
|
+
concat,
|
3
|
+
group,
|
4
|
+
hardline,
|
5
|
+
ifBreak,
|
6
|
+
indent,
|
7
|
+
line
|
8
|
+
} = require("../prettier");
|
9
|
+
|
10
|
+
function printClass(path, opts, print) {
|
11
|
+
const [_constant, superclass, bodystmt] = path.getValue().body;
|
12
|
+
const stmts = bodystmt.body[0];
|
13
|
+
|
14
|
+
const parts = ["class ", path.call(print, "body", 0)];
|
15
|
+
if (superclass) {
|
16
|
+
parts.push(" < ", path.call(print, "body", 1));
|
17
|
+
}
|
18
|
+
|
19
|
+
// If the body is empty and does not contain any comments, we can just
|
20
|
+
// replace the body with a semi-colon.
|
21
|
+
if (
|
22
|
+
stmts.body.length === 1 &&
|
23
|
+
stmts.body[0].type === "void_stmt" &&
|
24
|
+
!stmts.body[0].comments
|
25
|
+
) {
|
26
|
+
return group(concat([concat(parts), ifBreak(line, "; "), "end"]));
|
27
|
+
}
|
28
|
+
|
29
|
+
return group(
|
30
|
+
concat([
|
31
|
+
concat(parts),
|
32
|
+
indent(concat([hardline, path.call(print, "body", 2)])),
|
33
|
+
concat([hardline, "end"])
|
34
|
+
])
|
35
|
+
);
|
36
|
+
}
|
37
|
+
|
38
|
+
function printModule(path, opts, print) {
|
39
|
+
const declaration = group(concat(["module ", path.call(print, "body", 0)]));
|
40
|
+
|
41
|
+
// If the body is empty, we can replace with a ;
|
42
|
+
const stmts = path.getValue().body[1].body[0];
|
43
|
+
if (
|
44
|
+
stmts.body.length === 1 &&
|
45
|
+
stmts.body[0].type === "void_stmt" &&
|
46
|
+
!stmts.body[0].comments
|
47
|
+
) {
|
48
|
+
return group(concat([declaration, ifBreak(line, "; "), "end"]));
|
49
|
+
}
|
50
|
+
|
51
|
+
return group(
|
52
|
+
concat([
|
53
|
+
declaration,
|
54
|
+
indent(concat([hardline, path.call(print, "body", 1)])),
|
55
|
+
concat([hardline, "end"])
|
56
|
+
])
|
57
|
+
);
|
58
|
+
}
|
59
|
+
|
60
|
+
function printSClass(path, opts, print) {
|
61
|
+
return group(
|
62
|
+
concat([
|
63
|
+
concat(["class << ", path.call(print, "body", 0)]),
|
64
|
+
indent(concat([hardline, path.call(print, "body", 1)])),
|
65
|
+
concat([hardline, "end"])
|
66
|
+
])
|
67
|
+
);
|
68
|
+
}
|
69
|
+
|
70
|
+
module.exports = {
|
71
|
+
class: printClass,
|
72
|
+
module: printModule,
|
73
|
+
sclass: printSClass
|
74
|
+
};
|
data/src/nodes/commands.js
CHANGED
@@ -1,5 +1,14 @@
|
|
1
|
-
const {
|
2
|
-
|
1
|
+
const {
|
2
|
+
align,
|
3
|
+
concat,
|
4
|
+
group,
|
5
|
+
ifBreak,
|
6
|
+
indent,
|
7
|
+
join,
|
8
|
+
line,
|
9
|
+
softline
|
10
|
+
} = require("../prettier");
|
11
|
+
const { docLength, makeCall } = require("../utils");
|
3
12
|
|
4
13
|
const hasDef = (node) =>
|
5
14
|
node.body[1].type === "args_add_block" &&
|
@@ -23,32 +32,39 @@ const hasDef = (node) =>
|
|
23
32
|
const skipArgsAlign = (path) =>
|
24
33
|
["to", "not_to"].includes(path.getValue().body[2].body);
|
25
34
|
|
35
|
+
// If there is a ternary argument to a command and it's going to get broken
|
36
|
+
// into multiple lines, then we're going to have to use parentheses around the
|
37
|
+
// command in order to make sure operator precedence doesn't get messed up.
|
38
|
+
const hasTernaryArg = (path) =>
|
39
|
+
path.getValue().body[1].body[0].body.some((node) => node.type === "ifop");
|
40
|
+
|
26
41
|
module.exports = {
|
27
42
|
command: (path, opts, print) => {
|
28
43
|
const command = path.call(print, "body", 0);
|
29
|
-
const
|
44
|
+
const joinedArgs = join(concat([",", line]), path.call(print, "body", 1));
|
30
45
|
|
31
|
-
|
32
|
-
|
33
|
-
}
|
46
|
+
const hasTernary = hasTernaryArg(path);
|
47
|
+
let breakArgs;
|
34
48
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
49
|
+
if (hasTernary) {
|
50
|
+
breakArgs = indent(concat([softline, joinedArgs]));
|
51
|
+
} else if (hasDef(path.getValue())) {
|
52
|
+
breakArgs = joinedArgs;
|
53
|
+
} else {
|
54
|
+
breakArgs = align(command.length + 1, joinedArgs);
|
55
|
+
}
|
39
56
|
|
40
|
-
|
57
|
+
return group(
|
41
58
|
ifBreak(
|
42
|
-
concat([
|
59
|
+
concat([
|
60
|
+
command,
|
61
|
+
hasTernary ? "(" : " ",
|
62
|
+
breakArgs,
|
63
|
+
hasTernary ? concat([softline, ")"]) : ""
|
64
|
+
]),
|
43
65
|
concat([command, " ", joinedArgs])
|
44
66
|
)
|
45
67
|
);
|
46
|
-
|
47
|
-
if (heredocs.length === 1) {
|
48
|
-
return group(concat([commandDoc].concat(heredocs)));
|
49
|
-
}
|
50
|
-
|
51
|
-
return commandDoc;
|
52
68
|
},
|
53
69
|
command_call: (path, opts, print) => {
|
54
70
|
const parts = [
|
@@ -62,25 +78,14 @@ module.exports = {
|
|
62
78
|
}
|
63
79
|
|
64
80
|
parts.push(" ");
|
65
|
-
const { args, heredocs } = makeArgs(path, opts, print, 3);
|
66
|
-
|
67
|
-
if (heredocs.length > 1) {
|
68
|
-
return concat(parts.concat([join(", ", args)]).concat(heredocs));
|
69
|
-
}
|
70
81
|
|
71
|
-
const joinedArgs = join(concat([",", line]),
|
82
|
+
const joinedArgs = join(concat([",", line]), path.call(print, "body", 3));
|
72
83
|
const breakArgs = skipArgsAlign(path)
|
73
84
|
? joinedArgs
|
74
85
|
: align(docLength(concat(parts)), joinedArgs);
|
75
86
|
|
76
|
-
|
87
|
+
return group(
|
77
88
|
ifBreak(concat(parts.concat(breakArgs)), concat(parts.concat(joinedArgs)))
|
78
89
|
);
|
79
|
-
|
80
|
-
if (heredocs.length === 1) {
|
81
|
-
return group(concat([commandDoc].concat(heredocs)));
|
82
|
-
}
|
83
|
-
|
84
|
-
return commandDoc;
|
85
90
|
}
|
86
91
|
};
|
data/src/nodes/conditionals.js
CHANGED
@@ -9,7 +9,7 @@ const {
|
|
9
9
|
softline
|
10
10
|
} = require("../prettier");
|
11
11
|
|
12
|
-
const { containsAssignment } = require("../utils");
|
12
|
+
const { containsAssignment, isEmptyStmts } = require("../utils");
|
13
13
|
const inlineEnsureParens = require("../utils/inlineEnsureParens");
|
14
14
|
|
15
15
|
const printWithAddition = (keyword, path, print, { breaking = false } = {}) =>
|
@@ -80,36 +80,50 @@ const printTernary = (path, _opts, print) => {
|
|
80
80
|
// Prints an `if_mod` or `unless_mod` node. Because it was previously in the
|
81
81
|
// modifier form, we're guaranteed to not have an additional node, so we can
|
82
82
|
// just work with the predicate and the body.
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
concat([softline, "end"])
|
89
|
-
]);
|
83
|
+
function printSingle(keyword, modifier = false) {
|
84
|
+
return function printSingleWithKeyword(path, { inlineConditionals }, print) {
|
85
|
+
const [_predicateNode, statementsNode] = path.getValue().body;
|
86
|
+
const predicateDoc = path.call(print, "body", 0);
|
87
|
+
const statementsDoc = path.call(print, "body", 1);
|
90
88
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
89
|
+
const multilineParts = [
|
90
|
+
`${keyword} `,
|
91
|
+
align(keyword.length + 1, predicateDoc),
|
92
|
+
indent(concat([softline, statementsDoc])),
|
93
|
+
softline,
|
94
|
+
"end"
|
95
|
+
];
|
95
96
|
|
96
|
-
|
97
|
-
|
98
|
-
|
97
|
+
// If we do not allow modifier form conditionals or there are comments
|
98
|
+
// inside of the body of the conditional, then we must print in the
|
99
|
+
// multiline form.
|
100
|
+
if (!inlineConditionals || (!modifier && statementsNode.body[0].comments)) {
|
101
|
+
return concat([concat(multilineParts), breakParent]);
|
102
|
+
}
|
99
103
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
const inline = concat(
|
105
|
+
inlineEnsureParens(path, [
|
106
|
+
path.call(print, "body", 1),
|
107
|
+
` ${keyword} `,
|
108
|
+
path.call(print, "body", 0)
|
109
|
+
])
|
110
|
+
);
|
107
111
|
|
108
|
-
|
109
|
-
|
112
|
+
// An expression with a conditional modifier (expression if true), the
|
113
|
+
// conditional body is parsed before the predicate expression, meaning that
|
114
|
+
// if the parser encountered a variable declaration, it would initialize
|
115
|
+
// that variable first before evaluating the predicate expression. That
|
116
|
+
// parse order means the difference between a NameError or not. #591
|
117
|
+
// https://docs.ruby-lang.org/en/2.0.0/syntax/control_expressions_rdoc.html#label-Modifier+if+and+unless
|
118
|
+
if (modifier && containsAssignment(statementsNode)) {
|
119
|
+
return inline;
|
120
|
+
}
|
121
|
+
|
122
|
+
return group(ifBreak(concat(multilineParts), inline));
|
123
|
+
};
|
124
|
+
}
|
110
125
|
|
111
126
|
const noTernary = [
|
112
|
-
"@comment",
|
113
127
|
"alias",
|
114
128
|
"assign",
|
115
129
|
"break",
|
@@ -205,7 +219,7 @@ const printConditional = (keyword) => (path, { inlineConditionals }, print) => {
|
|
205
219
|
|
206
220
|
// If the body of the conditional is empty, then we explicitly have to use the
|
207
221
|
// block form.
|
208
|
-
if (statements
|
222
|
+
if (isEmptyStmts(statements) && !statements.body[0].comments) {
|
209
223
|
return concat([
|
210
224
|
`${keyword} `,
|
211
225
|
align(keyword.length + 1, path.call(print, "body", 0)),
|
@@ -260,7 +274,7 @@ module.exports = {
|
|
260
274
|
},
|
261
275
|
if: printConditional("if"),
|
262
276
|
ifop: printTernary,
|
263
|
-
if_mod: printSingle("if"),
|
277
|
+
if_mod: printSingle("if", true),
|
264
278
|
unless: printConditional("unless"),
|
265
|
-
unless_mod: printSingle("unless")
|
279
|
+
unless_mod: printSingle("unless", true)
|
266
280
|
};
|
data/src/nodes/constants.js
CHANGED
@@ -1,25 +1,43 @@
|
|
1
1
|
const { concat, group, indent, join, softline } = require("../prettier");
|
2
|
-
const {
|
2
|
+
const { makeCall } = require("../utils");
|
3
|
+
|
4
|
+
function printConstPath(path, opts, print) {
|
5
|
+
return join("::", path.map(print, "body"));
|
6
|
+
}
|
7
|
+
|
8
|
+
function printConstRef(path, opts, print) {
|
9
|
+
return path.call(print, "body", 0);
|
10
|
+
}
|
11
|
+
|
12
|
+
function printDefined(path, opts, print) {
|
13
|
+
return group(
|
14
|
+
concat([
|
15
|
+
"defined?(",
|
16
|
+
indent(concat([softline, path.call(print, "body", 0)])),
|
17
|
+
concat([softline, ")"])
|
18
|
+
])
|
19
|
+
);
|
20
|
+
}
|
21
|
+
|
22
|
+
function printField(path, opts, print) {
|
23
|
+
return group(
|
24
|
+
concat([
|
25
|
+
path.call(print, "body", 0),
|
26
|
+
concat([makeCall(path, opts, print), path.call(print, "body", 2)])
|
27
|
+
])
|
28
|
+
);
|
29
|
+
}
|
30
|
+
|
31
|
+
function printTopConst(path, opts, print) {
|
32
|
+
return concat(["::", path.call(print, "body", 0)]);
|
33
|
+
}
|
3
34
|
|
4
35
|
module.exports = {
|
5
|
-
const_path_field:
|
6
|
-
const_path_ref:
|
7
|
-
const_ref:
|
8
|
-
defined:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
indent(concat([softline, path.call(print, "body", 0)])),
|
13
|
-
concat([softline, ")"])
|
14
|
-
])
|
15
|
-
),
|
16
|
-
field: (path, opts, print) =>
|
17
|
-
group(
|
18
|
-
concat([
|
19
|
-
path.call(print, "body", 0),
|
20
|
-
concat([makeCall(path, opts, print), path.call(print, "body", 2)])
|
21
|
-
])
|
22
|
-
),
|
23
|
-
top_const_field: prefix("::"),
|
24
|
-
top_const_ref: prefix("::")
|
36
|
+
const_path_field: printConstPath,
|
37
|
+
const_path_ref: printConstPath,
|
38
|
+
const_ref: printConstRef,
|
39
|
+
defined: printDefined,
|
40
|
+
field: printField,
|
41
|
+
top_const_field: printTopConst,
|
42
|
+
top_const_ref: printTopConst
|
25
43
|
};
|
data/src/nodes/flow.js
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
const { concat, join } = require("../prettier");
|
2
|
-
const { literal
|
2
|
+
const { literal } = require("../utils");
|
3
|
+
|
4
|
+
const nodeDive = (node, steps) => {
|
5
|
+
let current = node;
|
6
|
+
|
7
|
+
steps.forEach((step) => {
|
8
|
+
current = current[step];
|
9
|
+
});
|
10
|
+
|
11
|
+
return current;
|
12
|
+
};
|
3
13
|
|
4
14
|
const unskippableParens = [
|
5
15
|
"if_mod",
|
data/src/nodes/hashes.js
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
const {
|
2
2
|
concat,
|
3
3
|
group,
|
4
|
+
hardline,
|
4
5
|
ifBreak,
|
5
6
|
indent,
|
6
7
|
join,
|
7
|
-
line
|
8
|
-
literalline
|
8
|
+
line
|
9
9
|
} = require("../prettier");
|
10
|
-
|
11
|
-
const { nodeDive, prefix, skipAssignIndent } = require("../utils");
|
10
|
+
const { prefix, skipAssignIndent } = require("../utils");
|
12
11
|
|
13
12
|
// When attempting to convert a hash rocket into a hash label, you need to take
|
14
13
|
// care because only certain patterns are allowed. Ruby source says that they
|
@@ -20,14 +19,14 @@ const { nodeDive, prefix, skipAssignIndent } = require("../utils");
|
|
20
19
|
//
|
21
20
|
// This function represents that check, as it determines if it can convert the
|
22
21
|
// symbol node into a hash label.
|
23
|
-
|
24
|
-
const label = symbolLiteral.body[0].body
|
22
|
+
function isValidHashLabel(symbolLiteral) {
|
23
|
+
const label = symbolLiteral.body[0].body;
|
25
24
|
return label.match(/^[_A-Za-z]/) && !label.endsWith("=");
|
26
|
-
}
|
25
|
+
}
|
27
26
|
|
28
|
-
|
29
|
-
const labelNode =
|
30
|
-
const labelDoc = path.call
|
27
|
+
function printHashKey(path, { preferHashLabels }, print) {
|
28
|
+
const labelNode = path.getValue().body[0];
|
29
|
+
const labelDoc = path.call(print, "body", 0);
|
31
30
|
|
32
31
|
switch (labelNode.type) {
|
33
32
|
case "@label":
|
@@ -37,12 +36,7 @@ const makeLabel = (path, { preferHashLabels }, print, steps) => {
|
|
37
36
|
return `:${labelDoc.slice(0, labelDoc.length - 1)} =>`;
|
38
37
|
case "symbol_literal": {
|
39
38
|
if (preferHashLabels && isValidHashLabel(labelNode)) {
|
40
|
-
|
41
|
-
|
42
|
-
return concat([
|
43
|
-
path.call.apply(path, [print].concat(symbolSteps)),
|
44
|
-
":"
|
45
|
-
]);
|
39
|
+
return concat([path.call(print, "body", 0, "body", 0), ":"]);
|
46
40
|
}
|
47
41
|
return concat([labelDoc, " =>"]);
|
48
42
|
}
|
@@ -54,94 +48,73 @@ const makeLabel = (path, { preferHashLabels }, print, steps) => {
|
|
54
48
|
default:
|
55
49
|
return concat([labelDoc, " =>"]);
|
56
50
|
}
|
57
|
-
}
|
51
|
+
}
|
52
|
+
|
53
|
+
function printAssocNew(path, opts, print) {
|
54
|
+
const valueDoc = path.call(print, "body", 1);
|
55
|
+
const parts = [printHashKey(path, opts, print)];
|
56
|
+
|
57
|
+
if (skipAssignIndent(path.getValue().body[1])) {
|
58
|
+
parts.push(" ", valueDoc);
|
59
|
+
} else {
|
60
|
+
parts.push(indent(concat([line, valueDoc])));
|
61
|
+
}
|
62
|
+
|
63
|
+
return group(concat(parts));
|
64
|
+
}
|
65
|
+
|
66
|
+
function printEmptyHashWithComments(path, opts) {
|
67
|
+
const hashNode = path.getValue();
|
68
|
+
|
69
|
+
const printComment = (commentPath, index) => {
|
70
|
+
hashNode.comments[index].printed = true;
|
71
|
+
return opts.printer.printComment(commentPath);
|
72
|
+
};
|
73
|
+
|
74
|
+
return concat([
|
75
|
+
"{",
|
76
|
+
indent(
|
77
|
+
concat([hardline, join(hardline, path.map(printComment, "comments"))])
|
78
|
+
),
|
79
|
+
line,
|
80
|
+
"}"
|
81
|
+
]);
|
82
|
+
}
|
58
83
|
|
59
|
-
function printHash(path,
|
84
|
+
function printHash(path, opts, print) {
|
60
85
|
const hashNode = path.getValue();
|
61
86
|
|
62
87
|
// Hashes normally have a single assoclist_from_args child node. If it's
|
63
88
|
// missing, then it means we're dealing with an empty hash, so we can just
|
64
89
|
// exit here and print.
|
65
90
|
if (hashNode.body[0] === null) {
|
66
|
-
return "{}";
|
67
|
-
}
|
68
|
-
|
69
|
-
// Here we get a reference to the printed assoclist_from_args child node,
|
70
|
-
// which handles printing all of the key-value pairs of the hash. We're
|
71
|
-
// wrapping it in an array in case we need to append a trailing comma.
|
72
|
-
const assocDocs = [path.call(print, "body", 0)];
|
73
|
-
|
74
|
-
// Here we get a reference to the last key-value pair's value node, in order
|
75
|
-
// to check if we're dealing with a heredoc. If we are, then the trailing
|
76
|
-
// comma printing is handled from within the assoclist_from_args node
|
77
|
-
// printing, because the trailing comma has to go after the heredoc
|
78
|
-
// declaration.
|
79
|
-
const assocNodes = hashNode.body[0].body[0];
|
80
|
-
const lastAssocValueNode = assocNodes[assocNodes.length - 1].body[1];
|
81
|
-
|
82
|
-
// If we're adding a trailing comma and the last key-value pair's value node
|
83
|
-
// is not a heredoc node, then we can safely append the extra comma if the
|
84
|
-
// hash ends up getting printed on multiple lines.
|
85
|
-
if (addTrailingCommas && lastAssocValueNode.type !== "heredoc") {
|
86
|
-
assocDocs.push(ifBreak(",", ""));
|
91
|
+
return hashNode.comments ? printEmptyHashWithComments(path, opts) : "{}";
|
87
92
|
}
|
88
93
|
|
89
94
|
return group(
|
90
95
|
concat([
|
91
96
|
"{",
|
92
|
-
indent(
|
93
|
-
|
97
|
+
indent(
|
98
|
+
concat([
|
99
|
+
line,
|
100
|
+
path.call(print, "body", 0),
|
101
|
+
opts.addTrailingCommas ? ifBreak(",", "") : ""
|
102
|
+
])
|
103
|
+
),
|
104
|
+
line,
|
105
|
+
"}"
|
94
106
|
])
|
95
107
|
);
|
96
108
|
}
|
97
109
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
const parts = [makeLabel(path, opts, print, ["body", 0])];
|
102
|
-
|
103
|
-
if (skipAssignIndent(path.getValue().body[1])) {
|
104
|
-
parts.push(" ", valueDoc);
|
105
|
-
} else {
|
106
|
-
parts.push(indent(concat([line, valueDoc])));
|
107
|
-
}
|
110
|
+
function printHashContents(path, opts, print) {
|
111
|
+
return group(join(concat([",", line]), path.map(print, "body")));
|
112
|
+
}
|
108
113
|
|
109
|
-
|
110
|
-
|
114
|
+
module.exports = {
|
115
|
+
assoc_new: printAssocNew,
|
111
116
|
assoc_splat: prefix("**"),
|
112
|
-
assoclist_from_args:
|
113
|
-
|
114
|
-
|
115
|
-
const assocNodes = path.getValue().body[0];
|
116
|
-
const assocDocs = [];
|
117
|
-
|
118
|
-
assocNodes.forEach((assocNode, index) => {
|
119
|
-
const isInner = index !== assocNodes.length - 1;
|
120
|
-
const valueNode = assocNode.body[1];
|
121
|
-
|
122
|
-
if (valueNode && valueNode.type === "heredoc") {
|
123
|
-
assocDocs.push(
|
124
|
-
makeLabel(path, opts, print, ["body", 0, index, "body", 0]),
|
125
|
-
" ",
|
126
|
-
valueNode.beging,
|
127
|
-
isInner || addTrailingCommas ? "," : "",
|
128
|
-
literalline,
|
129
|
-
concat(path.map(print, "body", 0, index, "body", 1, "body")),
|
130
|
-
valueNode.ending,
|
131
|
-
isInner ? line : ""
|
132
|
-
);
|
133
|
-
} else {
|
134
|
-
assocDocs.push(path.call(print, "body", 0, index));
|
135
|
-
|
136
|
-
if (isInner) {
|
137
|
-
assocDocs.push(concat([",", line]));
|
138
|
-
}
|
139
|
-
}
|
140
|
-
});
|
141
|
-
|
142
|
-
return group(concat(assocDocs));
|
143
|
-
},
|
144
|
-
bare_assoc_hash: (path, opts, print) =>
|
145
|
-
group(join(concat([",", line]), path.map(print, "body", 0))),
|
117
|
+
assoclist_from_args: printHashContents,
|
118
|
+
bare_assoc_hash: printHashContents,
|
146
119
|
hash: printHash
|
147
120
|
};
|