prettier 1.1.0 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -1
  3. data/CONTRIBUTING.md +2 -2
  4. data/README.md +16 -1
  5. data/lib/prettier.rb +2 -2
  6. data/package.json +2 -2
  7. data/rubocop.yml +26 -0
  8. data/src/{ruby.js → plugin.js} +2 -2
  9. data/src/prettier.js +1 -0
  10. data/src/{embed.js → ruby/embed.js} +6 -2
  11. data/src/{nodes.js → ruby/nodes.js} +0 -0
  12. data/src/{nodes → ruby/nodes}/alias.js +1 -1
  13. data/src/{nodes → ruby/nodes}/aref.js +8 -1
  14. data/src/{nodes → ruby/nodes}/args.js +2 -2
  15. data/src/{nodes → ruby/nodes}/arrays.js +2 -3
  16. data/src/{nodes → ruby/nodes}/assign.js +12 -4
  17. data/src/ruby/nodes/blocks.js +90 -0
  18. data/src/{nodes → ruby/nodes}/calls.js +18 -9
  19. data/src/ruby/nodes/case.js +65 -0
  20. data/src/{nodes → ruby/nodes}/class.js +1 -1
  21. data/src/ruby/nodes/commands.js +126 -0
  22. data/src/{nodes → ruby/nodes}/conditionals.js +3 -3
  23. data/src/{nodes → ruby/nodes}/constants.js +2 -2
  24. data/src/{nodes → ruby/nodes}/flow.js +2 -2
  25. data/src/{nodes → ruby/nodes}/hashes.js +32 -10
  26. data/src/{nodes → ruby/nodes}/heredocs.js +2 -2
  27. data/src/ruby/nodes/hooks.js +34 -0
  28. data/src/{nodes → ruby/nodes}/ints.js +0 -0
  29. data/src/{nodes → ruby/nodes}/lambdas.js +2 -2
  30. data/src/{nodes → ruby/nodes}/loops.js +10 -7
  31. data/src/{nodes → ruby/nodes}/massign.js +8 -1
  32. data/src/{nodes → ruby/nodes}/methods.js +32 -6
  33. data/src/{nodes → ruby/nodes}/operators.js +2 -2
  34. data/src/{nodes → ruby/nodes}/params.js +31 -16
  35. data/src/{nodes → ruby/nodes}/patterns.js +54 -15
  36. data/src/{nodes → ruby/nodes}/regexp.js +2 -2
  37. data/src/{nodes → ruby/nodes}/rescue.js +2 -2
  38. data/src/ruby/nodes/return.js +94 -0
  39. data/src/{nodes → ruby/nodes}/statements.js +6 -9
  40. data/src/{nodes → ruby/nodes}/strings.js +27 -36
  41. data/src/{nodes → ruby/nodes}/super.js +2 -2
  42. data/src/{nodes → ruby/nodes}/undef.js +1 -1
  43. data/src/{parser.js → ruby/parser.js} +4 -3
  44. data/src/{parser.rb → ruby/parser.rb} +498 -492
  45. data/src/{printer.js → ruby/printer.js} +33 -1
  46. data/src/{toProc.js → ruby/toProc.js} +4 -8
  47. data/src/utils.js +10 -93
  48. data/src/utils/containsAssignment.js +11 -0
  49. data/src/utils/getTrailingComma.js +5 -0
  50. data/src/utils/hasAncestor.js +17 -0
  51. data/src/utils/literal.js +7 -0
  52. data/src/utils/makeCall.js +14 -0
  53. data/src/utils/noIndent.js +10 -0
  54. data/src/utils/skipAssignIndent.js +10 -0
  55. metadata +49 -41
  56. data/src/nodes/blocks.js +0 -85
  57. data/src/nodes/case.js +0 -61
  58. data/src/nodes/commands.js +0 -91
  59. data/src/nodes/hooks.js +0 -44
  60. data/src/nodes/return.js +0 -72
@@ -1,61 +0,0 @@
1
- const {
2
- align,
3
- concat,
4
- fill,
5
- group,
6
- hardline,
7
- indent,
8
- line
9
- } = require("../prettier");
10
-
11
- module.exports = {
12
- case: (path, opts, print) => {
13
- const statement = ["case"];
14
-
15
- // You don't need to explicitly have something to test against in a case
16
- // statement (without it it effectively becomes an if/elsif chain).
17
- if (path.getValue().body[0]) {
18
- statement.push(" ", path.call(print, "body", 0));
19
- }
20
-
21
- return concat(
22
- statement.concat([hardline, path.call(print, "body", 1), hardline, "end"])
23
- );
24
- },
25
- when: (path, opts, print) => {
26
- const [_preds, _stmts, addition] = path.getValue().body;
27
-
28
- // The `fill` builder command expects an array of docs alternating with
29
- // line breaks. This is so it can loop through and determine where to break.
30
- const preds = fill(
31
- path.call(print, "body", 0).reduce((accum, pred, index) => {
32
- if (index === 0) {
33
- return [pred];
34
- }
35
-
36
- // Pull off the last element and make it concat with a comma so that
37
- // we can maintain alternating lines and docs.
38
- return accum
39
- .slice(0, -1)
40
- .concat([concat([accum[accum.length - 1], ","]), line, pred]);
41
- }, null)
42
- );
43
-
44
- const stmts = path.call(print, "body", 1);
45
- const parts = [concat(["when ", align("when ".length, preds)])];
46
-
47
- // It's possible in a when to just have empty void statements, in which case
48
- // we would skip adding the body.
49
- if (!stmts.parts.every((part) => !part)) {
50
- parts.push(indent(concat([hardline, stmts])));
51
- }
52
-
53
- // This is the next clause on the case statement, either another `when` or
54
- // an `else` clause.
55
- if (addition) {
56
- parts.push(hardline, path.call(print, "body", 2));
57
- }
58
-
59
- return group(concat(parts));
60
- }
61
- };
@@ -1,91 +0,0 @@
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");
12
-
13
- const hasDef = (node) =>
14
- node.body[1].type === "args_add_block" &&
15
- node.body[1].body[0].type === "args" &&
16
- node.body[1].body[0].body[0] &&
17
- ["def", "defs"].includes(node.body[1].body[0].body[0].type);
18
-
19
- // Very special handling case for rspec matchers. In general with rspec matchers
20
- // you expect to see something like:
21
- //
22
- // expect(foo).to receive(:bar).with(
23
- // 'one',
24
- // 'two',
25
- // 'three',
26
- // 'four',
27
- // 'five'
28
- // )
29
- //
30
- // In this case the arguments are aligned to the left side as opposed to being
31
- // aligned with the `receive` call.
32
- const skipArgsAlign = (path) =>
33
- ["to", "not_to"].includes(path.getValue().body[2].body);
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
-
41
- module.exports = {
42
- command: (path, opts, print) => {
43
- const command = path.call(print, "body", 0);
44
- const joinedArgs = join(concat([",", line]), path.call(print, "body", 1));
45
-
46
- const hasTernary = hasTernaryArg(path);
47
- let breakArgs;
48
-
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
- }
56
-
57
- return group(
58
- ifBreak(
59
- concat([
60
- command,
61
- hasTernary ? "(" : " ",
62
- breakArgs,
63
- hasTernary ? concat([softline, ")"]) : ""
64
- ]),
65
- concat([command, " ", joinedArgs])
66
- )
67
- );
68
- },
69
- command_call: (path, opts, print) => {
70
- const parts = [
71
- path.call(print, "body", 0),
72
- makeCall(path, opts, print),
73
- path.call(print, "body", 2)
74
- ];
75
-
76
- if (!path.getValue().body[3]) {
77
- return concat(parts);
78
- }
79
-
80
- parts.push(" ");
81
-
82
- const joinedArgs = join(concat([",", line]), path.call(print, "body", 3));
83
- const breakArgs = skipArgsAlign(path)
84
- ? joinedArgs
85
- : align(docLength(concat(parts)), joinedArgs);
86
-
87
- return group(
88
- ifBreak(concat(parts.concat(breakArgs)), concat(parts.concat(joinedArgs)))
89
- );
90
- }
91
- };
@@ -1,44 +0,0 @@
1
- const { concat, group, indent, line } = require("../prettier");
2
- const { isEmptyStmts } = require("../utils");
3
-
4
- // The `BEGIN` and `END` keywords are used to hook into the Ruby process. Any
5
- // `BEGIN` blocks are executed right when the process starts up, and the `END`
6
- // blocks are executed right before exiting.
7
- //
8
- // BEGIN {
9
- // # content goes here
10
- // }
11
- //
12
- // END {
13
- // # content goes here
14
- // }
15
- //
16
- // Interesting side note, you don't use `do...end` blocks with these hooks. Both
17
- // nodes contain one child which is a `stmts` node.
18
- function printHook(name) {
19
- return function printHookWithName(path, opts, print) {
20
- const stmtsNode = path.getValue().body[1];
21
- const printedStmts = path.call(print, "body", 1);
22
-
23
- const parts = [
24
- name,
25
- " ",
26
- path.call(print, "body", 0),
27
- indent(concat([line, printedStmts])),
28
- concat([line, "}"])
29
- ];
30
-
31
- // If there are no statements but there are comments, then we want to skip
32
- // printing the newline so that we don't end up with multiple spaces.
33
- if (isEmptyStmts(stmtsNode) && stmtsNode.comments) {
34
- parts[1] = indent(printedStmts);
35
- }
36
-
37
- return group(concat(parts));
38
- };
39
- }
40
-
41
- module.exports = {
42
- BEGIN: printHook("BEGIN"),
43
- END: printHook("END")
44
- };
@@ -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
- };