prettier 1.0.1 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +65 -1
- data/CONTRIBUTING.md +2 -2
- data/README.md +6 -1
- data/lib/prettier.rb +2 -2
- data/node_modules/prettier/index.js +54 -54
- data/package.json +4 -2
- data/src/{ruby.js → plugin.js} +2 -2
- data/src/{embed.js → ruby/embed.js} +2 -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 +12 -4
- data/src/{nodes → ruby/nodes}/blocks.js +3 -3
- data/src/{nodes → ruby/nodes}/calls.js +54 -11
- data/src/ruby/nodes/case.js +65 -0
- data/src/{nodes → ruby/nodes}/class.js +1 -1
- data/src/ruby/nodes/commands.js +126 -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/{nodes → ruby/nodes}/hooks.js +2 -2
- data/src/{nodes → ruby/nodes}/ints.js +0 -0
- data/src/{nodes → ruby/nodes}/lambdas.js +2 -2
- data/src/ruby/nodes/loops.js +104 -0
- data/src/{nodes → ruby/nodes}/massign.js +8 -1
- data/src/{nodes → ruby/nodes}/methods.js +34 -6
- data/src/{nodes → ruby/nodes}/operators.js +2 -2
- data/src/{nodes → ruby/nodes}/params.js +9 -2
- data/src/{nodes → ruby/nodes}/patterns.js +45 -10
- data/src/ruby/nodes/regexp.js +56 -0
- data/src/{nodes → ruby/nodes}/rescue.js +2 -2
- data/src/ruby/nodes/return.js +98 -0
- data/src/{nodes → ruby/nodes}/statements.js +1 -1
- data/src/{nodes → ruby/nodes}/strings.js +1 -1
- data/src/{nodes → ruby/nodes}/super.js +2 -2
- data/src/{nodes → ruby/nodes}/undef.js +1 -1
- data/src/{parser.js → ruby/parser.js} +2 -2
- data/src/{parser.rb → ruby/parser.rb} +323 -317
- data/src/{printer.js → ruby/printer.js} +46 -1
- data/src/{toProc.js → ruby/toProc.js} +0 -0
- 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 +11 -0
- data/src/utils/noIndent.js +10 -0
- data/src/utils/skipAssignIndent.js +10 -0
- metadata +48 -41
- data/src/nodes/case.js +0 -61
- data/src/nodes/commands.js +0 -91
- data/src/nodes/loops.js +0 -101
- data/src/nodes/regexp.js +0 -49
- data/src/nodes/return.js +0 -72
data/src/nodes/loops.js
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
const {
|
2
|
-
align,
|
3
|
-
breakParent,
|
4
|
-
concat,
|
5
|
-
group,
|
6
|
-
hardline,
|
7
|
-
ifBreak,
|
8
|
-
indent,
|
9
|
-
softline
|
10
|
-
} = require("../prettier");
|
11
|
-
|
12
|
-
const { containsAssignment } = require("../utils");
|
13
|
-
const inlineEnsureParens = require("../utils/inlineEnsureParens");
|
14
|
-
|
15
|
-
const printLoop = (keyword, modifier) => (path, { rubyModifier }, print) => {
|
16
|
-
const [_predicate, stmts] = path.getValue().body;
|
17
|
-
|
18
|
-
// If the only statement inside this while loop is a void statement, then we
|
19
|
-
// can shorten to just displaying the predicate and then a semicolon.
|
20
|
-
if (
|
21
|
-
stmts.body.length === 1 &&
|
22
|
-
stmts.body[0].type === "void_stmt" &&
|
23
|
-
!stmts.body[0].comments
|
24
|
-
) {
|
25
|
-
return group(
|
26
|
-
concat([
|
27
|
-
keyword,
|
28
|
-
" ",
|
29
|
-
path.call(print, "body", 0),
|
30
|
-
ifBreak(softline, "; "),
|
31
|
-
"end"
|
32
|
-
])
|
33
|
-
);
|
34
|
-
}
|
35
|
-
|
36
|
-
const inlineLoop = concat(
|
37
|
-
inlineEnsureParens(path, [
|
38
|
-
path.call(print, "body", 1),
|
39
|
-
` ${keyword} `,
|
40
|
-
path.call(print, "body", 0)
|
41
|
-
])
|
42
|
-
);
|
43
|
-
|
44
|
-
// If we're in the modifier form and we're modifying a `begin`, then this is a
|
45
|
-
// special case where we need to explicitly use the modifier form because
|
46
|
-
// otherwise the semantic meaning changes. This looks like:
|
47
|
-
//
|
48
|
-
// begin
|
49
|
-
// foo
|
50
|
-
// end while bar
|
51
|
-
//
|
52
|
-
// The above is effectively a `do...while` loop (which we don't have in ruby).
|
53
|
-
if (modifier && path.getValue().body[1].type === "begin") {
|
54
|
-
return inlineLoop;
|
55
|
-
}
|
56
|
-
|
57
|
-
const blockLoop = concat([
|
58
|
-
concat([
|
59
|
-
`${keyword} `,
|
60
|
-
align(keyword.length + 1, path.call(print, "body", 0))
|
61
|
-
]),
|
62
|
-
indent(concat([softline, path.call(print, "body", 1)])),
|
63
|
-
concat([softline, "end"])
|
64
|
-
]);
|
65
|
-
|
66
|
-
// If we're disallowing inline loops or if the predicate of the loop contains
|
67
|
-
// an assignment (in which case we can't know for certain that that
|
68
|
-
// assignment doesn't impact the statements inside the loop) then we can't
|
69
|
-
// use the modifier form and we must use the block form.
|
70
|
-
if (!rubyModifier || containsAssignment(path.getValue().body[0])) {
|
71
|
-
return concat([breakParent, blockLoop]);
|
72
|
-
}
|
73
|
-
|
74
|
-
return group(ifBreak(blockLoop, inlineLoop));
|
75
|
-
};
|
76
|
-
|
77
|
-
// Technically this is incorrect. A `for` loop actually introduces and modifies
|
78
|
-
// a local variable that then remains in the outer scope. Additionally, if the
|
79
|
-
// `each` method was somehow missing from the enumerable (it's possible...),
|
80
|
-
// then this transformation would fail. However - I've never actually seen a
|
81
|
-
// `for` loop used in production. If someone actually calls me on it, I'll fix
|
82
|
-
// this, but for now I'm leaving it.
|
83
|
-
const printFor = (path, opts, print) =>
|
84
|
-
group(
|
85
|
-
concat([
|
86
|
-
path.call(print, "body", 1),
|
87
|
-
".each do |",
|
88
|
-
path.call(print, "body", 0),
|
89
|
-
"|",
|
90
|
-
indent(concat([hardline, path.call(print, "body", 2)])),
|
91
|
-
concat([hardline, "end"])
|
92
|
-
])
|
93
|
-
);
|
94
|
-
|
95
|
-
module.exports = {
|
96
|
-
while: printLoop("while", false),
|
97
|
-
while_mod: printLoop("while", true),
|
98
|
-
until: printLoop("until", false),
|
99
|
-
until_mod: printLoop("until", true),
|
100
|
-
for: printFor
|
101
|
-
};
|
data/src/nodes/regexp.js
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
const { concat } = require("../prettier");
|
2
|
-
const { hasAncestor } = require("../utils");
|
3
|
-
|
4
|
-
function isStringContent(node) {
|
5
|
-
return node.type === "@tstring_content";
|
6
|
-
}
|
7
|
-
|
8
|
-
function shouldUseBraces(path) {
|
9
|
-
const node = path.getValue();
|
10
|
-
const first = node.body[0];
|
11
|
-
|
12
|
-
// If the first part of this regex is plain string content and we have a
|
13
|
-
// space or an =, then we want to use braces because otherwise we could end up
|
14
|
-
// with an ambiguous operator, e.g. foo / bar/ or foo /=bar/
|
15
|
-
if (
|
16
|
-
first &&
|
17
|
-
isStringContent(first) &&
|
18
|
-
[" ", "="].includes(first.body[0]) &&
|
19
|
-
hasAncestor(path, ["command", "command_call"])
|
20
|
-
) {
|
21
|
-
return true;
|
22
|
-
}
|
23
|
-
|
24
|
-
return node.body.some(
|
25
|
-
(child) => isStringContent(child) && child.body.includes("/")
|
26
|
-
);
|
27
|
-
}
|
28
|
-
|
29
|
-
// This function is responsible for printing out regexp_literal nodes. They can
|
30
|
-
// either use the special %r literal syntax or they can use forward slashes. At
|
31
|
-
// the end of either of those they can have modifiers like m or x that have
|
32
|
-
// special meaning for the regex engine.
|
33
|
-
//
|
34
|
-
// We favor the use of forward slashes unless the regex contains a forward slash
|
35
|
-
// itself. In that case we switch over to using %r with braces.
|
36
|
-
function printRegexpLiteral(path, opts, print) {
|
37
|
-
const node = path.getValue();
|
38
|
-
const useBraces = shouldUseBraces(path);
|
39
|
-
|
40
|
-
const parts = [useBraces ? "%r{" : "/"]
|
41
|
-
.concat(path.map(print, "body"))
|
42
|
-
.concat([useBraces ? "}" : "/", node.ending.slice(1)]);
|
43
|
-
|
44
|
-
return concat(parts);
|
45
|
-
}
|
46
|
-
|
47
|
-
module.exports = {
|
48
|
-
regexp_literal: printRegexpLiteral
|
49
|
-
};
|
data/src/nodes/return.js
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
const {
|
2
|
-
concat,
|
3
|
-
group,
|
4
|
-
ifBreak,
|
5
|
-
indent,
|
6
|
-
line,
|
7
|
-
join,
|
8
|
-
softline
|
9
|
-
} = require("../prettier");
|
10
|
-
const { literal } = require("../utils");
|
11
|
-
|
12
|
-
// You can't skip the parentheses if you have the `and` or `or` operator,
|
13
|
-
// because they have low enough operator precedence that you need to explicitly
|
14
|
-
// keep them in there.
|
15
|
-
const canSkipParens = (args) => {
|
16
|
-
const statement = args.body[0].body[0].body[0];
|
17
|
-
return (
|
18
|
-
statement.type !== "binary" || !["and", "or"].includes(statement.body[1])
|
19
|
-
);
|
20
|
-
};
|
21
|
-
|
22
|
-
const printReturn = (path, opts, print) => {
|
23
|
-
let args = path.getValue().body[0].body[0];
|
24
|
-
let steps = ["body", 0, "body", 0];
|
25
|
-
|
26
|
-
if (!args) {
|
27
|
-
return "return";
|
28
|
-
}
|
29
|
-
|
30
|
-
// If the body of the return contains parens, then just skip directly to the
|
31
|
-
// content of the parens so that we can skip printing parens if we don't
|
32
|
-
// want them.
|
33
|
-
if (args.body[0] && args.body[0].type === "paren" && canSkipParens(args)) {
|
34
|
-
args = args.body[0].body[0];
|
35
|
-
steps = steps.concat("body", 0, "body", 0);
|
36
|
-
}
|
37
|
-
|
38
|
-
// If we're returning an array literal that isn't a special array, single
|
39
|
-
// element array, or an empty array, then we want to grab the arguments so
|
40
|
-
// that we can print them out as if they were normal return arguments.
|
41
|
-
if (
|
42
|
-
args.body[0] &&
|
43
|
-
args.body[0].type === "array" &&
|
44
|
-
args.body[0].body[0] &&
|
45
|
-
args.body[0].body[0].body.length > 1 &&
|
46
|
-
["args", "args_add_star"].includes(args.body[0].body[0].type)
|
47
|
-
) {
|
48
|
-
steps = steps.concat("body", 0, "body", 0);
|
49
|
-
}
|
50
|
-
|
51
|
-
// Now that we've established which actual node is the arguments to return,
|
52
|
-
// we grab it out of the path by diving down the steps that we've set up.
|
53
|
-
const parts = path.call.apply(path, [print].concat(steps));
|
54
|
-
|
55
|
-
// If we got the value straight out of the parens, then `parts` would only
|
56
|
-
// be a singular doc as opposed to an array.
|
57
|
-
const value = Array.isArray(parts) ? join(concat([",", line]), parts) : parts;
|
58
|
-
|
59
|
-
return group(
|
60
|
-
concat([
|
61
|
-
"return",
|
62
|
-
ifBreak(parts.length > 1 ? " [" : "(", " "),
|
63
|
-
indent(concat([softline, value])),
|
64
|
-
concat([softline, ifBreak(parts.length > 1 ? "]" : ")", "")])
|
65
|
-
])
|
66
|
-
);
|
67
|
-
};
|
68
|
-
|
69
|
-
module.exports = {
|
70
|
-
return: printReturn,
|
71
|
-
return0: literal("return")
|
72
|
-
};
|