prettier 1.2.2 → 1.4.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 +64 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +22 -94
- data/node_modules/prettier/index.js +54 -54
- data/package.json +2 -3
- data/rubocop.yml +26 -0
- data/src/haml/embed.js +87 -0
- data/src/haml/nodes/comment.js +27 -0
- data/src/haml/nodes/doctype.js +34 -0
- data/src/haml/nodes/filter.js +16 -0
- data/src/haml/nodes/hamlComment.js +21 -0
- data/src/haml/nodes/plain.js +6 -0
- data/src/haml/nodes/root.js +8 -0
- data/src/haml/nodes/script.js +33 -0
- data/src/haml/nodes/silentScript.js +59 -0
- data/src/haml/nodes/tag.js +193 -0
- data/src/haml/parser.js +22 -0
- data/src/haml/parser.rb +138 -0
- data/src/haml/printer.js +28 -0
- data/src/parser/getLang.js +32 -0
- data/src/parser/getNetcat.js +50 -0
- data/src/parser/netcat.js +15 -0
- data/src/parser/parseSync.js +33 -0
- data/src/parser/requestParse.js +74 -0
- data/src/parser/server.rb +61 -0
- data/src/{ruby.js → plugin.js} +25 -4
- data/src/prettier.js +1 -0
- data/src/rbs/parser.js +39 -0
- data/src/rbs/parser.rb +88 -0
- data/src/rbs/printer.js +605 -0
- data/src/{embed.js → ruby/embed.js} +6 -2
- data/src/{nodes.js → ruby/nodes.js} +0 -0
- data/src/{nodes → ruby/nodes}/alias.js +1 -1
- data/src/{nodes → ruby/nodes}/aref.js +8 -1
- data/src/{nodes → ruby/nodes}/args.js +2 -2
- data/src/{nodes → ruby/nodes}/arrays.js +2 -3
- data/src/{nodes → ruby/nodes}/assign.js +7 -3
- data/src/ruby/nodes/blocks.js +90 -0
- data/src/{nodes → ruby/nodes}/calls.js +20 -47
- data/src/{nodes → ruby/nodes}/case.js +1 -1
- data/src/{nodes → ruby/nodes}/class.js +1 -1
- data/src/ruby/nodes/commands.js +131 -0
- data/src/{nodes → ruby/nodes}/conditionals.js +3 -3
- data/src/{nodes → ruby/nodes}/constants.js +2 -2
- data/src/{nodes → ruby/nodes}/flow.js +2 -2
- data/src/{nodes → ruby/nodes}/hashes.js +32 -10
- data/src/{nodes → ruby/nodes}/heredocs.js +2 -2
- data/src/ruby/nodes/hooks.js +34 -0
- data/src/{nodes → ruby/nodes}/ints.js +0 -0
- data/src/{nodes → ruby/nodes}/lambdas.js +2 -2
- data/src/{nodes → ruby/nodes}/loops.js +10 -7
- data/src/{nodes → ruby/nodes}/massign.js +8 -1
- data/src/{nodes → ruby/nodes}/methods.js +10 -9
- data/src/{nodes → ruby/nodes}/operators.js +2 -2
- data/src/{nodes → ruby/nodes}/params.js +31 -16
- data/src/{nodes → ruby/nodes}/patterns.js +17 -6
- data/src/{nodes → ruby/nodes}/regexp.js +2 -2
- data/src/{nodes → ruby/nodes}/rescue.js +34 -27
- data/src/{nodes → ruby/nodes}/return.js +21 -10
- data/src/{nodes → ruby/nodes}/statements.js +9 -9
- data/src/{nodes → ruby/nodes}/strings.js +28 -36
- data/src/{nodes → ruby/nodes}/super.js +2 -2
- data/src/{nodes → ruby/nodes}/undef.js +1 -1
- data/src/ruby/parser.js +39 -0
- data/src/{parser.rb → ruby/parser.rb} +498 -529
- data/src/{printer.js → ruby/printer.js} +1 -3
- data/src/{toProc.js → ruby/toProc.js} +4 -8
- data/src/utils.js +10 -93
- data/src/utils/containsAssignment.js +11 -0
- data/src/utils/getTrailingComma.js +5 -0
- data/src/utils/hasAncestor.js +17 -0
- data/src/utils/literal.js +7 -0
- data/src/utils/makeCall.js +14 -0
- data/src/utils/noIndent.js +11 -0
- data/src/utils/skipAssignIndent.js +10 -0
- metadata +71 -41
- data/src/nodes/blocks.js +0 -85
- data/src/nodes/commands.js +0 -91
- data/src/nodes/hooks.js +0 -44
- data/src/parser.js +0 -86
@@ -6,9 +6,9 @@ const {
|
|
6
6
|
mapDoc,
|
7
7
|
markAsRoot,
|
8
8
|
stripTrailingHardline
|
9
|
-
} = require("
|
9
|
+
} = require("../prettier");
|
10
10
|
|
11
|
-
const { literalLineNoBreak } = require("
|
11
|
+
const { literalLineNoBreak } = require("../utils");
|
12
12
|
|
13
13
|
const parsers = {
|
14
14
|
css: "css",
|
@@ -20,6 +20,10 @@ const parsers = {
|
|
20
20
|
scss: "scss"
|
21
21
|
};
|
22
22
|
|
23
|
+
// This function is in here because it handles embedded parser values. I don't
|
24
|
+
// have a test that exercises it because I'm not sure for which parser it is
|
25
|
+
// necessary, but since it's in prettier core I'm keeping it here.
|
26
|
+
/* istanbul ignore next */
|
23
27
|
const replaceNewlines = (doc) =>
|
24
28
|
mapDoc(doc, (currentDoc) =>
|
25
29
|
typeof currentDoc === "string" && currentDoc.includes("\n")
|
File without changes
|
@@ -1,4 +1,11 @@
|
|
1
|
-
const {
|
1
|
+
const {
|
2
|
+
concat,
|
3
|
+
group,
|
4
|
+
indent,
|
5
|
+
join,
|
6
|
+
line,
|
7
|
+
softline
|
8
|
+
} = require("../../prettier");
|
2
9
|
|
3
10
|
// `aref` nodes are when you're pulling a value out of a collection at a
|
4
11
|
// specific index. Put another way, it's any time you're calling the method
|
@@ -6,10 +6,10 @@ const {
|
|
6
6
|
join,
|
7
7
|
line,
|
8
8
|
softline
|
9
|
-
} = require("
|
9
|
+
} = require("../../prettier");
|
10
|
+
const { getTrailingComma } = require("../../utils");
|
10
11
|
|
11
12
|
const toProc = require("../toProc");
|
12
|
-
const { getTrailingComma } = require("../utils");
|
13
13
|
|
14
14
|
function printArgParen(path, opts, print) {
|
15
15
|
const argsNode = path.getValue().body[0];
|
@@ -6,9 +6,8 @@ const {
|
|
6
6
|
join,
|
7
7
|
line,
|
8
8
|
softline
|
9
|
-
} = require("
|
10
|
-
|
11
|
-
const { getTrailingComma, printEmptyCollection } = require("../utils");
|
9
|
+
} = require("../../prettier");
|
10
|
+
const { getTrailingComma, printEmptyCollection } = require("../../utils");
|
12
11
|
|
13
12
|
// Checks that every argument within this args node is a string_literal node
|
14
13
|
// that has no spaces or interpolations. This means we're dealing with an array
|
@@ -1,5 +1,5 @@
|
|
1
|
-
const { concat, group, indent, join, line } = require("
|
2
|
-
const {
|
1
|
+
const { concat, group, indent, join, line } = require("../../prettier");
|
2
|
+
const { skipAssignIndent } = require("../../utils");
|
3
3
|
|
4
4
|
function printAssign(path, opts, print) {
|
5
5
|
const [_targetNode, valueNode] = path.getValue().body;
|
@@ -35,9 +35,13 @@ function printVarField(path, opts, print) {
|
|
35
35
|
return path.getValue().body ? path.call(print, "body", 0) : "";
|
36
36
|
}
|
37
37
|
|
38
|
+
function printVarRef(path, opts, print) {
|
39
|
+
return path.call(print, "body", 0);
|
40
|
+
}
|
41
|
+
|
38
42
|
module.exports = {
|
39
43
|
assign: printAssign,
|
40
44
|
opassign: printOpAssign,
|
41
45
|
var_field: printVarField,
|
42
|
-
var_ref:
|
46
|
+
var_ref: printVarRef
|
43
47
|
};
|
@@ -0,0 +1,90 @@
|
|
1
|
+
const {
|
2
|
+
breakParent,
|
3
|
+
concat,
|
4
|
+
group,
|
5
|
+
ifBreak,
|
6
|
+
indent,
|
7
|
+
join,
|
8
|
+
removeLines,
|
9
|
+
softline
|
10
|
+
} = require("../../prettier");
|
11
|
+
const { hasAncestor } = require("../../utils");
|
12
|
+
|
13
|
+
function printBlockVar(path, opts, print) {
|
14
|
+
const parts = ["|", removeLines(path.call(print, "body", 0))];
|
15
|
+
|
16
|
+
// The second part of this node is a list of optional block-local variables
|
17
|
+
if (path.getValue().body[1]) {
|
18
|
+
parts.push("; ", join(", ", path.map(print, "body", 1)));
|
19
|
+
}
|
20
|
+
|
21
|
+
parts.push("| ");
|
22
|
+
return concat(parts);
|
23
|
+
}
|
24
|
+
|
25
|
+
function printBlock(braces) {
|
26
|
+
return function printBlockWithBraces(path, opts, print) {
|
27
|
+
const [variables, statements] = path.getValue().body;
|
28
|
+
const stmts =
|
29
|
+
statements.type === "stmts" ? statements.body : statements.body[0].body;
|
30
|
+
|
31
|
+
let doBlockBody = "";
|
32
|
+
if (
|
33
|
+
stmts.length !== 1 ||
|
34
|
+
stmts[0].type !== "void_stmt" ||
|
35
|
+
stmts[0].comments
|
36
|
+
) {
|
37
|
+
doBlockBody = indent(concat([softline, path.call(print, "body", 1)]));
|
38
|
+
}
|
39
|
+
|
40
|
+
// If this block is nested underneath a command or command_call node, then
|
41
|
+
// we can't use `do...end` because that will get associated with the parent
|
42
|
+
// node as opposed to the current node (because of the difference in
|
43
|
+
// operator precedence). Instead, we still use a multi-line format but
|
44
|
+
// switch to using braces instead.
|
45
|
+
const useBraces = braces && hasAncestor(path, ["command", "command_call"]);
|
46
|
+
|
47
|
+
const doBlock = concat([
|
48
|
+
useBraces ? " {" : " do",
|
49
|
+
variables ? concat([" ", path.call(print, "body", 0)]) : "",
|
50
|
+
doBlockBody,
|
51
|
+
concat([softline, useBraces ? "}" : "end"])
|
52
|
+
]);
|
53
|
+
|
54
|
+
// We can hit this next pattern if within the block the only statement is a
|
55
|
+
// comment.
|
56
|
+
if (
|
57
|
+
stmts.length === 1 &&
|
58
|
+
stmts[0].type === "void_stmt" &&
|
59
|
+
stmts[0].comments
|
60
|
+
) {
|
61
|
+
return concat([breakParent, doBlock]);
|
62
|
+
}
|
63
|
+
|
64
|
+
const blockReceiver = path.getParentNode().body[0];
|
65
|
+
|
66
|
+
// If the parent node is a command node, then there are no parentheses
|
67
|
+
// around the arguments to that command, so we need to break the block
|
68
|
+
if (["command", "command_call"].includes(blockReceiver.type)) {
|
69
|
+
return concat([breakParent, doBlock]);
|
70
|
+
}
|
71
|
+
|
72
|
+
const hasBody = stmts.some(({ type }) => type !== "void_stmt");
|
73
|
+
const braceBlock = concat([
|
74
|
+
" {",
|
75
|
+
hasBody || variables ? " " : "",
|
76
|
+
variables ? path.call(print, "body", 0) : "",
|
77
|
+
path.call(print, "body", 1),
|
78
|
+
hasBody ? " " : "",
|
79
|
+
"}"
|
80
|
+
]);
|
81
|
+
|
82
|
+
return group(ifBreak(doBlock, braceBlock));
|
83
|
+
};
|
84
|
+
}
|
85
|
+
|
86
|
+
module.exports = {
|
87
|
+
block_var: printBlockVar,
|
88
|
+
brace_block: printBlock(true),
|
89
|
+
do_block: printBlock(false)
|
90
|
+
};
|
@@ -5,8 +5,8 @@ const {
|
|
5
5
|
ifBreak,
|
6
6
|
indent,
|
7
7
|
softline
|
8
|
-
} = require("
|
9
|
-
const {
|
8
|
+
} = require("../../prettier");
|
9
|
+
const { makeCall, noIndent } = require("../../utils");
|
10
10
|
|
11
11
|
const toProc = require("../toProc");
|
12
12
|
|
@@ -24,6 +24,12 @@ function printCall(path, opts, print) {
|
|
24
24
|
// call syntax so if `call` is implicit, we don't print it out.
|
25
25
|
const messageDoc = messageNode === "call" ? "" : path.call(print, "body", 2);
|
26
26
|
|
27
|
+
// For certain left sides of the call nodes, we want to attach directly to
|
28
|
+
// the } or end.
|
29
|
+
if (noIndent.includes(receiverNode.type)) {
|
30
|
+
return concat([receiverDoc, operatorDoc, messageDoc]);
|
31
|
+
}
|
32
|
+
|
27
33
|
// The right side of the call node, as in everything including the operator
|
28
34
|
// and beyond.
|
29
35
|
const rightSideDoc = concat([
|
@@ -37,7 +43,7 @@ function printCall(path, opts, print) {
|
|
37
43
|
|
38
44
|
// If our parent node is a chained node then we're not going to group the
|
39
45
|
// right side of the expression, as we want to have a nice multi-line layout.
|
40
|
-
if (chained.includes(parentNode.type)) {
|
46
|
+
if (chained.includes(parentNode.type) && !node.comments) {
|
41
47
|
parentNode.chain = (node.chain || 0) + 1;
|
42
48
|
parentNode.callChain = (node.callChain || 0) + 1;
|
43
49
|
parentNode.breakDoc = (node.breakDoc || [receiverDoc]).concat(rightSideDoc);
|
@@ -47,18 +53,10 @@ function printCall(path, opts, print) {
|
|
47
53
|
// If we're at the top of a chain, then we're going to print out a nice
|
48
54
|
// multi-line layout if this doesn't break into multiple lines.
|
49
55
|
if (!chained.includes(parentNode.type) && (node.chain || 0) >= 3) {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
return ifBreak(group(breakDoc), concat([receiverDoc, group(rightSideDoc)]));
|
56
|
-
}
|
57
|
-
|
58
|
-
// For certain left sides of the call nodes, we want to attach directly to
|
59
|
-
// the } or end.
|
60
|
-
if (noIndent.includes(receiverNode.type)) {
|
61
|
-
return concat([receiverDoc, operatorDoc, messageDoc]);
|
56
|
+
return ifBreak(
|
57
|
+
group(indent(concat(node.breakDoc.concat(rightSideDoc)))),
|
58
|
+
concat([receiverDoc, group(rightSideDoc)])
|
59
|
+
);
|
62
60
|
}
|
63
61
|
|
64
62
|
return group(concat([receiverDoc, group(indent(rightSideDoc))]));
|
@@ -105,7 +103,7 @@ function printMethodAddArg(path, opts, print) {
|
|
105
103
|
|
106
104
|
// If our parent node is a chained node then we're not going to group the
|
107
105
|
// right side of the expression, as we want to have a nice multi-line layout.
|
108
|
-
if (chained.includes(parentNode.type)) {
|
106
|
+
if (chained.includes(parentNode.type) && !node.comments) {
|
109
107
|
parentNode.chain = (node.chain || 0) + 1;
|
110
108
|
parentNode.breakDoc = (node.breakDoc || [methodDoc]).concat(argsDoc);
|
111
109
|
parentNode.firstReceiverType = node.firstReceiverType;
|
@@ -138,41 +136,12 @@ function printMethodAddArg(path, opts, print) {
|
|
138
136
|
return concat([methodDoc, argsDoc]);
|
139
137
|
}
|
140
138
|
|
141
|
-
// Sorbet type annotations look like the following:
|
142
|
-
//
|
143
|
-
// {method_add_block
|
144
|
-
// [{method_add_arg
|
145
|
-
// [{fcall
|
146
|
-
// [{@ident "sig"}]},
|
147
|
-
// {args []}]},
|
148
|
-
// {brace_block [nil, {stmts}]}}]}
|
149
|
-
//
|
150
|
-
function isSorbetTypeAnnotation(node) {
|
151
|
-
const [callNode, blockNode] = node.body;
|
152
|
-
|
153
|
-
return (
|
154
|
-
callNode.type === "method_add_arg" &&
|
155
|
-
callNode.body[0].type === "fcall" &&
|
156
|
-
callNode.body[0].body[0].body === "sig" &&
|
157
|
-
callNode.body[1].type === "args" &&
|
158
|
-
callNode.body[1].body.length === 0 &&
|
159
|
-
blockNode
|
160
|
-
);
|
161
|
-
}
|
162
|
-
|
163
139
|
function printMethodAddBlock(path, opts, print) {
|
164
140
|
const node = path.getValue();
|
165
141
|
|
166
142
|
const [callNode, blockNode] = node.body;
|
167
143
|
const [callDoc, blockDoc] = path.map(print, "body");
|
168
144
|
|
169
|
-
// Very special handling here for sorbet type annotations. They look like Ruby
|
170
|
-
// code, but they're not actually Ruby code, so we're not going to mess with
|
171
|
-
// them at all.
|
172
|
-
if (isSorbetTypeAnnotation(node)) {
|
173
|
-
return opts.originalText.slice(opts.locStart(node), opts.locEnd(node));
|
174
|
-
}
|
175
|
-
|
176
145
|
// Don't bother trying to do any kind of fancy toProc transform if the option
|
177
146
|
// is disabled.
|
178
147
|
if (opts.rubyToProc) {
|
@@ -217,10 +186,14 @@ function printMethodAddBlock(path, opts, print) {
|
|
217
186
|
return concat([callDoc, blockDoc]);
|
218
187
|
}
|
219
188
|
|
189
|
+
function printCallContainer(path, opts, print) {
|
190
|
+
return path.call(print, "body", 0);
|
191
|
+
}
|
192
|
+
|
220
193
|
module.exports = {
|
221
194
|
call: printCall,
|
222
|
-
fcall:
|
195
|
+
fcall: printCallContainer,
|
223
196
|
method_add_arg: printMethodAddArg,
|
224
197
|
method_add_block: printMethodAddBlock,
|
225
|
-
vcall:
|
198
|
+
vcall: printCallContainer
|
226
199
|
};
|
@@ -0,0 +1,131 @@
|
|
1
|
+
const {
|
2
|
+
align,
|
3
|
+
concat,
|
4
|
+
group,
|
5
|
+
ifBreak,
|
6
|
+
indent,
|
7
|
+
join,
|
8
|
+
line,
|
9
|
+
softline
|
10
|
+
} = require("../../prettier");
|
11
|
+
const { makeCall } = require("../../utils");
|
12
|
+
|
13
|
+
function docLength(doc) {
|
14
|
+
if (doc.length) {
|
15
|
+
return doc.length;
|
16
|
+
}
|
17
|
+
|
18
|
+
if (doc.parts) {
|
19
|
+
return doc.parts.reduce((sum, child) => sum + docLength(child), 0);
|
20
|
+
}
|
21
|
+
|
22
|
+
if (doc.contents) {
|
23
|
+
return docLength(doc.contents);
|
24
|
+
}
|
25
|
+
|
26
|
+
return 0;
|
27
|
+
}
|
28
|
+
|
29
|
+
function hasDef(node) {
|
30
|
+
return (
|
31
|
+
node.body[1].type === "args_add_block" &&
|
32
|
+
node.body[1].body[0].type === "args" &&
|
33
|
+
node.body[1].body[0].body[0] &&
|
34
|
+
["def", "defs"].includes(node.body[1].body[0].body[0].type)
|
35
|
+
);
|
36
|
+
}
|
37
|
+
|
38
|
+
// Very special handling case for rspec matchers. In general with rspec matchers
|
39
|
+
// you expect to see something like:
|
40
|
+
//
|
41
|
+
// expect(foo).to receive(:bar).with(
|
42
|
+
// 'one',
|
43
|
+
// 'two',
|
44
|
+
// 'three',
|
45
|
+
// 'four',
|
46
|
+
// 'five'
|
47
|
+
// )
|
48
|
+
//
|
49
|
+
// In this case the arguments are aligned to the left side as opposed to being
|
50
|
+
// aligned with the `receive` call.
|
51
|
+
function skipArgsAlign(path) {
|
52
|
+
return ["to", "not_to"].includes(path.getValue().body[2].body);
|
53
|
+
}
|
54
|
+
|
55
|
+
// If there is a ternary argument to a command and it's going to get broken
|
56
|
+
// into multiple lines, then we're going to have to use parentheses around the
|
57
|
+
// command in order to make sure operator precedence doesn't get messed up.
|
58
|
+
function hasTernaryArg(node) {
|
59
|
+
return node.body[0].body.some((child) => child.type === "ifop");
|
60
|
+
}
|
61
|
+
|
62
|
+
function printCommand(path, opts, print) {
|
63
|
+
const node = path.getValue();
|
64
|
+
|
65
|
+
const command = path.call(print, "body", 0);
|
66
|
+
const joinedArgs = join(concat([",", line]), path.call(print, "body", 1));
|
67
|
+
|
68
|
+
const hasTernary = hasTernaryArg(node.body[1]);
|
69
|
+
let breakArgs;
|
70
|
+
|
71
|
+
if (hasTernary) {
|
72
|
+
breakArgs = indent(concat([softline, joinedArgs]));
|
73
|
+
} else if (hasDef(path.getValue())) {
|
74
|
+
breakArgs = joinedArgs;
|
75
|
+
} else {
|
76
|
+
breakArgs = align(command.length + 1, joinedArgs);
|
77
|
+
}
|
78
|
+
|
79
|
+
return group(
|
80
|
+
ifBreak(
|
81
|
+
concat([
|
82
|
+
command,
|
83
|
+
hasTernary ? "(" : " ",
|
84
|
+
breakArgs,
|
85
|
+
hasTernary ? concat([softline, ")"]) : ""
|
86
|
+
]),
|
87
|
+
concat([command, " ", joinedArgs])
|
88
|
+
)
|
89
|
+
);
|
90
|
+
}
|
91
|
+
|
92
|
+
function printCommandCall(path, opts, print) {
|
93
|
+
const node = path.getValue();
|
94
|
+
const parts = [
|
95
|
+
path.call(print, "body", 0),
|
96
|
+
makeCall(path, opts, print),
|
97
|
+
path.call(print, "body", 2)
|
98
|
+
];
|
99
|
+
|
100
|
+
if (!node.body[3]) {
|
101
|
+
return concat(parts);
|
102
|
+
}
|
103
|
+
|
104
|
+
const argDocs = join(concat([",", line]), path.call(print, "body", 3));
|
105
|
+
let breakDoc;
|
106
|
+
|
107
|
+
if (hasTernaryArg(node.body[3])) {
|
108
|
+
breakDoc = parts.concat(
|
109
|
+
"(",
|
110
|
+
indent(concat([softline, argDocs])),
|
111
|
+
softline,
|
112
|
+
")"
|
113
|
+
);
|
114
|
+
parts.push(" ");
|
115
|
+
} else if (skipArgsAlign(path)) {
|
116
|
+
parts.push(" ");
|
117
|
+
breakDoc = parts.concat(argDocs);
|
118
|
+
} else {
|
119
|
+
parts.push(" ");
|
120
|
+
breakDoc = parts.concat(align(docLength(concat(parts)), argDocs));
|
121
|
+
}
|
122
|
+
|
123
|
+
const joinedDoc = parts.concat(argDocs);
|
124
|
+
|
125
|
+
return group(ifBreak(concat(breakDoc), concat(joinedDoc)));
|
126
|
+
}
|
127
|
+
|
128
|
+
module.exports = {
|
129
|
+
command: printCommand,
|
130
|
+
command_call: printCommandCall
|
131
|
+
};
|