prettier 1.6.1 → 2.0.0.pre.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +348 -293
  3. data/CONTRIBUTING.md +6 -9
  4. data/LICENSE +1 -1
  5. data/README.md +11 -12
  6. data/dist/haml/embed.js +53 -0
  7. data/dist/haml/parser.js +31 -0
  8. data/{src → dist}/haml/parser.rb +0 -0
  9. data/dist/haml/printer.js +336 -0
  10. data/dist/parser/getInfo.js +17 -0
  11. data/{src → dist}/parser/netcat.js +1 -0
  12. data/dist/parser/parseSync.js +179 -0
  13. data/dist/parser/server.rb +141 -0
  14. data/dist/plugin.js +143 -0
  15. data/dist/prettier.js +15 -0
  16. data/dist/rbs/parser.js +34 -0
  17. data/{src → dist}/rbs/parser.rb +0 -0
  18. data/dist/rbs/printer.js +517 -0
  19. data/dist/ruby/embed.js +110 -0
  20. data/dist/ruby/nodes/alias.js +59 -0
  21. data/{src → dist}/ruby/nodes/aref.js +26 -35
  22. data/dist/ruby/nodes/args.js +165 -0
  23. data/dist/ruby/nodes/arrays.js +126 -0
  24. data/dist/ruby/nodes/assign.js +41 -0
  25. data/dist/ruby/nodes/blocks.js +87 -0
  26. data/dist/ruby/nodes/calls.js +260 -0
  27. data/dist/ruby/nodes/case.js +50 -0
  28. data/dist/ruby/nodes/class.js +54 -0
  29. data/dist/ruby/nodes/commands.js +124 -0
  30. data/dist/ruby/nodes/conditionals.js +242 -0
  31. data/dist/ruby/nodes/constants.js +38 -0
  32. data/dist/ruby/nodes/flow.js +66 -0
  33. data/dist/ruby/nodes/hashes.js +130 -0
  34. data/dist/ruby/nodes/heredocs.js +30 -0
  35. data/dist/ruby/nodes/hooks.js +35 -0
  36. data/dist/ruby/nodes/ints.js +27 -0
  37. data/dist/ruby/nodes/lambdas.js +69 -0
  38. data/dist/ruby/nodes/loops.js +73 -0
  39. data/dist/ruby/nodes/massign.js +73 -0
  40. data/dist/ruby/nodes/methods.js +70 -0
  41. data/dist/ruby/nodes/operators.js +70 -0
  42. data/dist/ruby/nodes/params.js +89 -0
  43. data/dist/ruby/nodes/patterns.js +109 -0
  44. data/dist/ruby/nodes/regexp.js +45 -0
  45. data/dist/ruby/nodes/rescue.js +85 -0
  46. data/dist/ruby/nodes/return.js +75 -0
  47. data/dist/ruby/nodes/statements.js +111 -0
  48. data/dist/ruby/nodes/strings.js +218 -0
  49. data/dist/ruby/nodes/super.js +30 -0
  50. data/dist/ruby/nodes/undef.js +26 -0
  51. data/dist/ruby/nodes.js +151 -0
  52. data/dist/ruby/parser.js +34 -0
  53. data/{src → dist}/ruby/parser.rb +1195 -254
  54. data/dist/ruby/printer.js +129 -0
  55. data/dist/ruby/toProc.js +93 -0
  56. data/dist/types/haml.js +4 -0
  57. data/dist/types/plugin.js +3 -0
  58. data/dist/types/rbs.js +4 -0
  59. data/dist/types/ruby.js +4 -0
  60. data/dist/types/utils.js +2 -0
  61. data/dist/types.js +30 -0
  62. data/dist/utils/containsAssignment.js +15 -0
  63. data/dist/utils/getTrailingComma.js +6 -0
  64. data/dist/utils/hasAncestor.js +15 -0
  65. data/{src → dist}/utils/inlineEnsureParens.js +16 -17
  66. data/dist/utils/isEmptyBodyStmt.js +10 -0
  67. data/dist/utils/isEmptyStmts.js +10 -0
  68. data/dist/utils/literal.js +8 -0
  69. data/dist/utils/literallineWithoutBreakParent.js +8 -0
  70. data/dist/utils/makeCall.js +13 -0
  71. data/dist/utils/noIndent.js +11 -0
  72. data/dist/utils/printEmptyCollection.js +44 -0
  73. data/dist/utils/skipAssignIndent.js +15 -0
  74. data/dist/utils.js +30 -0
  75. data/exe/rbprettier +1 -2
  76. data/lib/prettier.rb +36 -5
  77. data/node_modules/prettier/bin-prettier.js +313 -190
  78. data/node_modules/prettier/doc.js +191 -323
  79. data/node_modules/prettier/index.js +2753 -3677
  80. data/node_modules/prettier/package.json +1 -1
  81. data/node_modules/prettier/parser-angular.js +13 -14
  82. data/node_modules/prettier/parser-babel.js +7 -7
  83. data/node_modules/prettier/parser-espree.js +7 -7
  84. data/node_modules/prettier/parser-flow.js +7 -7
  85. data/node_modules/prettier/parser-glimmer.js +1 -1
  86. data/node_modules/prettier/parser-graphql.js +1 -1
  87. data/node_modules/prettier/parser-html.js +17 -17
  88. data/node_modules/prettier/parser-markdown.js +9 -9
  89. data/node_modules/prettier/parser-meriyah.js +7 -7
  90. data/node_modules/prettier/parser-postcss.js +2 -2
  91. data/node_modules/prettier/parser-typescript.js +7 -7
  92. data/node_modules/prettier/parser-yaml.js +2 -2
  93. data/node_modules/prettier/third-party.js +143 -78
  94. data/package.json +26 -18
  95. metadata +74 -67
  96. data/src/haml/embed.js +0 -87
  97. data/src/haml/parser.js +0 -23
  98. data/src/haml/printer.js +0 -438
  99. data/src/parser/parseSync.js +0 -172
  100. data/src/parser/server.rb +0 -66
  101. data/src/plugin.js +0 -148
  102. data/src/prettier.js +0 -16
  103. data/src/rbs/parser.js +0 -37
  104. data/src/rbs/printer.js +0 -643
  105. data/src/ruby/embed.js +0 -142
  106. data/src/ruby/nodes/alias.js +0 -73
  107. data/src/ruby/nodes/args.js +0 -222
  108. data/src/ruby/nodes/arrays.js +0 -162
  109. data/src/ruby/nodes/assign.js +0 -47
  110. data/src/ruby/nodes/blocks.js +0 -90
  111. data/src/ruby/nodes/calls.js +0 -246
  112. data/src/ruby/nodes/case.js +0 -65
  113. data/src/ruby/nodes/class.js +0 -64
  114. data/src/ruby/nodes/commands.js +0 -131
  115. data/src/ruby/nodes/conditionals.js +0 -282
  116. data/src/ruby/nodes/constants.js +0 -43
  117. data/src/ruby/nodes/flow.js +0 -74
  118. data/src/ruby/nodes/hashes.js +0 -155
  119. data/src/ruby/nodes/heredocs.js +0 -36
  120. data/src/ruby/nodes/hooks.js +0 -34
  121. data/src/ruby/nodes/ints.js +0 -31
  122. data/src/ruby/nodes/lambdas.js +0 -76
  123. data/src/ruby/nodes/loops.js +0 -98
  124. data/src/ruby/nodes/massign.js +0 -98
  125. data/src/ruby/nodes/methods.js +0 -74
  126. data/src/ruby/nodes/operators.js +0 -83
  127. data/src/ruby/nodes/params.js +0 -106
  128. data/src/ruby/nodes/patterns.js +0 -157
  129. data/src/ruby/nodes/regexp.js +0 -56
  130. data/src/ruby/nodes/rescue.js +0 -101
  131. data/src/ruby/nodes/return.js +0 -94
  132. data/src/ruby/nodes/statements.js +0 -142
  133. data/src/ruby/nodes/strings.js +0 -272
  134. data/src/ruby/nodes/super.js +0 -35
  135. data/src/ruby/nodes/undef.js +0 -42
  136. data/src/ruby/nodes.js +0 -34
  137. data/src/ruby/parser.js +0 -37
  138. data/src/ruby/printer.js +0 -147
  139. data/src/ruby/toProc.js +0 -105
  140. data/src/utils/containsAssignment.js +0 -11
  141. data/src/utils/getTrailingComma.js +0 -5
  142. data/src/utils/hasAncestor.js +0 -17
  143. data/src/utils/isEmptyBodyStmt.js +0 -7
  144. data/src/utils/isEmptyStmts.js +0 -11
  145. data/src/utils/literal.js +0 -7
  146. data/src/utils/literallineWithoutBreakParent.js +0 -7
  147. data/src/utils/makeCall.js +0 -14
  148. data/src/utils/noIndent.js +0 -10
  149. data/src/utils/printEmptyCollection.js +0 -49
  150. data/src/utils/skipAssignIndent.js +0 -17
  151. data/src/utils.js +0 -13
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const prettier_1 = __importDefault(require("../prettier"));
7
+ const embed_1 = __importDefault(require("./embed"));
8
+ const nodes_1 = __importDefault(require("./nodes"));
9
+ const { trim } = prettier_1.default;
10
+ const noComments = [
11
+ "args",
12
+ "args_add_block",
13
+ "args_add_star",
14
+ "mlhs",
15
+ "mlhs_add_post",
16
+ "mlhs_add_star",
17
+ "mlhs_paren"
18
+ ];
19
+ const printer = {
20
+ // Certain nodes are used more for organizational purposed than for actually
21
+ // displaying content, so we tell prettier that we don't want comments
22
+ // attached to them.
23
+ canAttachComment(node) {
24
+ return !noComments.includes(node.type);
25
+ },
26
+ embed: embed_1.default,
27
+ // This function tells prettier how to recurse down our AST so that it can
28
+ // find where it needs to attach the comments. The types on this are a little
29
+ // abysmal, but we're going to leave it as is to get this out.
30
+ getCommentChildNodes(node) {
31
+ switch (node.type) {
32
+ case "heredoc":
33
+ return [node.beging];
34
+ case "aryptn":
35
+ return [node.body[0]]
36
+ .concat(node.body[1])
37
+ .concat(node.body[2])
38
+ .concat(node.body[3]);
39
+ case "hshptn": {
40
+ const pairs = node.body[1];
41
+ const values = pairs.reduce((left, right) => left.concat(right), []);
42
+ return [node.body[0]].concat(values).concat(node.body[2]);
43
+ }
44
+ case "params": {
45
+ const [reqs, optls, rest, post, kwargs, kwargRest, block] = node.body;
46
+ let parts = reqs || [];
47
+ (optls || []).forEach((optl) => {
48
+ parts = parts.concat(optl);
49
+ });
50
+ if (rest) {
51
+ parts.push(rest);
52
+ }
53
+ parts = parts.concat(post || []);
54
+ (kwargs || []).forEach((kwarg) => {
55
+ if (kwarg[1]) {
56
+ parts = parts.concat(kwarg);
57
+ }
58
+ else {
59
+ parts.push(kwarg[0]);
60
+ }
61
+ });
62
+ if (kwargRest && kwargRest !== "nil") {
63
+ parts.push(kwargRest);
64
+ }
65
+ if (block) {
66
+ parts.push(block);
67
+ }
68
+ return parts;
69
+ }
70
+ case "brace_block":
71
+ return [node.body[0], node.body[1], node.beging];
72
+ case "do_block":
73
+ return [node.body[0], node.body[1], node.beging];
74
+ case "paren":
75
+ return [node.lparen, node.body[0]];
76
+ default: {
77
+ if (Array.isArray(node.body)) {
78
+ return node.body.filter((child) => child && typeof child === "object");
79
+ }
80
+ return [];
81
+ }
82
+ }
83
+ },
84
+ // This is an escape-hatch to ignore nodes in the tree. If you have a comment
85
+ // that includes this pattern, then the entire node will be ignored and just
86
+ // the original source will be printed out.
87
+ hasPrettierIgnore(path) {
88
+ const node = path.getValue();
89
+ return ((node.comments &&
90
+ node.comments.some((comment) => comment.value.includes("prettier-ignore"))) ||
91
+ false);
92
+ },
93
+ // To be honest I'm not 100% sure this function is actually necessary, but it
94
+ // *feels* like a block comment equivalent in JavaScript so I'm going to leave
95
+ // it in place for now.
96
+ isBlockComment(comment) {
97
+ return comment.type === "@embdoc";
98
+ },
99
+ // This function handles adding the format pragma to a source string. This is
100
+ // an optional workflow for incremental adoption.
101
+ insertPragma(text) {
102
+ const boundary = text.startsWith("#") ? "\n" : "\n\n";
103
+ return `# @format${boundary}${text}`;
104
+ },
105
+ // This is the generic node print function, used to convert any node in the
106
+ // AST into its equivalent Doc representation.
107
+ print(path, opts, print) {
108
+ const node = path.getValue();
109
+ const printer = nodes_1.default[node.type];
110
+ if (printer) {
111
+ return printer(path, opts, print);
112
+ }
113
+ if (node.type[0] === "@") {
114
+ return node.body;
115
+ }
116
+ throw new Error(`Unsupported node encountered: ${node.type}`);
117
+ },
118
+ // This is the generic print function for any comment in the AST. It handles
119
+ // both regular comments that begin with a # and embdoc comments, which are
120
+ // surrounded by =begin..=end.
121
+ printComment(path) {
122
+ const comment = path.getValue();
123
+ if (comment.type === "@comment") {
124
+ return `#${comment.value}`;
125
+ }
126
+ return [trim, comment.value];
127
+ }
128
+ };
129
+ exports.default = printer;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function isCall(node) {
4
+ // Older versions of Ruby didn't have a @period ripper event, so we need to
5
+ // explicitly cast to any here.
6
+ if (node === "::" || node === ".") {
7
+ return true;
8
+ }
9
+ return node.type === "@period";
10
+ }
11
+ // If you have a simple block that only calls a method on the single required
12
+ // parameter that is passed to it, then you can replace that block with the
13
+ // simpler `Symbol#to_proc`. Meaning, it would go from:
14
+ //
15
+ // [1, 2, 3].map { |i| i.to_s }
16
+ //
17
+ // to:
18
+ //
19
+ // [1, 2, 3].map(&:to_s)
20
+ //
21
+ // This works with `do` blocks as well.
22
+ function toProc(path, node) {
23
+ const [variables, blockContents] = node.body;
24
+ // Ensure that there are variables being passed to this block.
25
+ const params = variables && variables.body[0];
26
+ if (!params) {
27
+ return null;
28
+ }
29
+ // Ensure there is one and only one parameter, and that it is required.
30
+ const reqParams = params.body[0];
31
+ const otherParams = params.body.slice(1);
32
+ if (!Array.isArray(reqParams) ||
33
+ reqParams.length !== 1 ||
34
+ otherParams.some(Boolean)) {
35
+ return null;
36
+ }
37
+ let statements;
38
+ if (blockContents.type === "bodystmt") {
39
+ // We’re in a `do` block
40
+ const blockStatements = blockContents.body[0];
41
+ const rescueElseEnsure = blockContents.body.slice(1);
42
+ // You can’t use the to_proc shortcut if you’re rescuing
43
+ if (rescueElseEnsure.some(Boolean)) {
44
+ return null;
45
+ }
46
+ statements = blockStatements;
47
+ }
48
+ else {
49
+ // We’re in a brace block
50
+ statements = blockContents;
51
+ }
52
+ // Ensure the block contains only one statement
53
+ if (statements.body.length !== 1) {
54
+ return null;
55
+ }
56
+ // Ensure that statement is a call and that it has no comments attached
57
+ const [statement] = statements.body;
58
+ if (statement.type !== "call" || statement.comments) {
59
+ return null;
60
+ }
61
+ // Ensure the call is a method of the block argument
62
+ const [varRef, call, method] = statement.body;
63
+ if (varRef.type !== "var_ref" ||
64
+ varRef.body[0].body !== reqParams[0].body ||
65
+ !isCall(call) ||
66
+ method === "call" ||
67
+ method.type !== "@ident") {
68
+ return null;
69
+ }
70
+ // Ensure that we're not inside of a hash that is being passed to a key that
71
+ // corresponds to `:if` or `:unless` to avoid problems with callbacks with
72
+ // Rails. For more context, see:
73
+ // https://github.com/prettier/plugin-ruby/issues/449
74
+ let assocNode = null;
75
+ if (path.getValue().type === "method_add_block") {
76
+ assocNode = path.getParentNode();
77
+ }
78
+ else {
79
+ assocNode = path.getParentNode(2);
80
+ }
81
+ if (assocNode && assocNode.type === "assoc_new") {
82
+ const [key] = assocNode.body;
83
+ if (key.type === "@label" && ["if:", "unless:"].includes(key.body)) {
84
+ return null;
85
+ }
86
+ if (key.type === "symbol_literal" &&
87
+ ["if", "unless"].includes(key.body[0].body)) {
88
+ return null;
89
+ }
90
+ }
91
+ return `&:${method.body}`;
92
+ }
93
+ exports.default = toProc;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ // This file contains all of the types that represent objects being returned
3
+ // from the HAML parser.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ ;
data/dist/types/rbs.js ADDED
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ // This file contains all of the types that represent objects being returned
3
+ // from the RBS parser.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ // This file contains all of the types that represent objects being returned
3
+ // from our ripper-based parser.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
data/dist/types.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.Ruby = exports.RBS = exports.Plugin = exports.HAML = void 0;
26
+ exports.HAML = __importStar(require("./types/haml"));
27
+ exports.Plugin = __importStar(require("./types/plugin"));
28
+ exports.RBS = __importStar(require("./types/rbs"));
29
+ exports.Ruby = __importStar(require("./types/ruby"));
30
+ __exportStar(require("./types/utils"), exports);
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // If the node is a type of assignment or if the node is a paren and nested
4
+ // inside that paren is a node that is a type of assignment.
5
+ function containsAssignment(node) {
6
+ if (!node) {
7
+ return false;
8
+ }
9
+ if (["assign", "massign", "opassign"].includes(node.type)) {
10
+ return true;
11
+ }
12
+ const anyNode = node;
13
+ return Array.isArray(anyNode.body) && anyNode.body.some(containsAssignment);
14
+ }
15
+ exports.default = containsAssignment;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function getTrailingComma(opts) {
4
+ return ["all", "es5"].includes(opts.trailingComma);
5
+ }
6
+ exports.default = getTrailingComma;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function hasAncestor(path, types) {
4
+ let parent = 0;
5
+ let parentNode = path.getParentNode();
6
+ while (parentNode) {
7
+ if (types.includes(parentNode.type)) {
8
+ return true;
9
+ }
10
+ parent += 1;
11
+ parentNode = path.getParentNode(parent);
12
+ }
13
+ return false;
14
+ }
15
+ exports.default = hasAncestor;
@@ -1,13 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
1
3
  const needsParens = [
2
- "args",
3
- "assign",
4
- "assoc_new",
5
- "binary",
6
- "call",
7
- "massign",
8
- "opassign"
4
+ "args",
5
+ "assign",
6
+ "assoc_new",
7
+ "binary",
8
+ "call",
9
+ "massign",
10
+ "opassign"
9
11
  ];
10
-
11
12
  // If you have a modifier statement (for instance an inline if statement or an
12
13
  // inline while loop) there are times when you need to wrap the entire statement
13
14
  // in parentheses. This occurs when you have something like:
@@ -39,12 +40,10 @@ const needsParens = [
39
40
  //
40
41
  // This approach maintains the nice conciseness of the inline version, while
41
42
  // keeping the correct semantic meaning.
42
- const inlineEnsureParens = (path, parts) => {
43
- if (needsParens.includes(path.getParentNode().type)) {
44
- return ["("].concat(parts, ")");
45
- }
46
-
47
- return parts;
48
- };
49
-
50
- module.exports = inlineEnsureParens;
43
+ function inlineEnsureParens(path, parts) {
44
+ if (needsParens.includes(path.getParentNode().type)) {
45
+ return ["(", ...parts, ")"];
46
+ }
47
+ return parts;
48
+ }
49
+ exports.default = inlineEnsureParens;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const isEmptyStmts_1 = __importDefault(require("./isEmptyStmts"));
7
+ function isEmptyBodyStmt(node) {
8
+ return (0, isEmptyStmts_1.default)(node.body[0]) && !node.body.slice(1).some(Boolean);
9
+ }
10
+ exports.default = isEmptyBodyStmt;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function isEmptyStmts(node) {
4
+ return (node &&
5
+ node.type === "stmts" &&
6
+ node.body.length === 1 &&
7
+ node.body[0].type === "void_stmt" &&
8
+ !node.body[0].comments);
9
+ }
10
+ exports.default = isEmptyStmts;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function literal(value) {
4
+ return function printLiteral() {
5
+ return value;
6
+ };
7
+ }
8
+ exports.default = literal;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const literallineWithoutBreakParent = {
4
+ type: "line",
5
+ hard: true,
6
+ literal: true
7
+ };
8
+ exports.default = literallineWithoutBreakParent;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const makeCall = (path, opts, print) => {
4
+ const operation = path.getValue().body[1];
5
+ // Ignoring the next block for coverage information because it's only relevant
6
+ // in Ruby 2.5 and below.
7
+ /* istanbul ignore next */
8
+ if ([".", "&."].includes(operation)) {
9
+ return operation;
10
+ }
11
+ return operation === "::" ? "." : path.call(print, "body", 1);
12
+ };
13
+ exports.default = makeCall;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const noIndent = [
4
+ "array",
5
+ "hash",
6
+ "heredoc",
7
+ "if",
8
+ "unless",
9
+ "xstring_literal"
10
+ ];
11
+ exports.default = noIndent;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const prettier_1 = __importDefault(require("../prettier"));
7
+ const { group, hardline, indent, join, line } = prettier_1.default;
8
+ function containedWithin(node) {
9
+ return function containedWithinNode(comment) {
10
+ return comment.sc >= node.sc && comment.ec <= node.ec;
11
+ };
12
+ }
13
+ // Empty collections are array or hash literals that do not contain any
14
+ // contents. They can, however, have comments inside the body. You can solve
15
+ // this by having a child node inside the array that gets the comments attached
16
+ // to it, but that requires modifying the parser. Instead, we can just manually
17
+ // print out the non-leading comments here.
18
+ function printEmptyCollection(path, opts, startToken, endToken) {
19
+ const node = path.getValue();
20
+ const containedWithinNode = containedWithin(node);
21
+ // If there are no comments or only leading comments, then we can just print
22
+ // out the start and end token and be done, as there are no comments inside
23
+ // the body of this node.
24
+ if (!node.comments || !node.comments.some(containedWithinNode)) {
25
+ return `${startToken}${endToken}`;
26
+ }
27
+ const comments = [];
28
+ const nodePath = path;
29
+ // For each comment, go through its path and print it out manually.
30
+ nodePath.each((commentPath) => {
31
+ const comment = commentPath.getValue();
32
+ if (containedWithinNode(comment)) {
33
+ comment.printed = true;
34
+ comments.push(opts.printer.printComment(commentPath, opts));
35
+ }
36
+ }, "comments");
37
+ return group([
38
+ startToken,
39
+ indent([hardline, join(hardline, comments)]),
40
+ line,
41
+ endToken
42
+ ]);
43
+ }
44
+ exports.default = printEmptyCollection;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const skippable = [
4
+ "array",
5
+ "dyna_symbol",
6
+ "hash",
7
+ "heredoc",
8
+ "lambda",
9
+ "regexp_literal"
10
+ ];
11
+ function skipAssignIndent(node) {
12
+ return (skippable.includes(node.type) ||
13
+ (node.type === "call" && skipAssignIndent(node.body[0])));
14
+ }
15
+ exports.default = skipAssignIndent;
data/dist/utils.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.skipAssignIndent = exports.printEmptyCollection = exports.noIndent = exports.makeCall = exports.literallineWithoutBreakParent = exports.literal = exports.inlineEnsureParens = exports.hasAncestor = exports.isEmptyStmts = exports.isEmptyBodyStmt = exports.getTrailingComma = exports.containsAssignment = void 0;
7
+ var containsAssignment_1 = require("./utils/containsAssignment");
8
+ Object.defineProperty(exports, "containsAssignment", { enumerable: true, get: function () { return __importDefault(containsAssignment_1).default; } });
9
+ var getTrailingComma_1 = require("./utils/getTrailingComma");
10
+ Object.defineProperty(exports, "getTrailingComma", { enumerable: true, get: function () { return __importDefault(getTrailingComma_1).default; } });
11
+ var isEmptyBodyStmt_1 = require("./utils/isEmptyBodyStmt");
12
+ Object.defineProperty(exports, "isEmptyBodyStmt", { enumerable: true, get: function () { return __importDefault(isEmptyBodyStmt_1).default; } });
13
+ var isEmptyStmts_1 = require("./utils/isEmptyStmts");
14
+ Object.defineProperty(exports, "isEmptyStmts", { enumerable: true, get: function () { return __importDefault(isEmptyStmts_1).default; } });
15
+ var hasAncestor_1 = require("./utils/hasAncestor");
16
+ Object.defineProperty(exports, "hasAncestor", { enumerable: true, get: function () { return __importDefault(hasAncestor_1).default; } });
17
+ var inlineEnsureParens_1 = require("./utils/inlineEnsureParens");
18
+ Object.defineProperty(exports, "inlineEnsureParens", { enumerable: true, get: function () { return __importDefault(inlineEnsureParens_1).default; } });
19
+ var literal_1 = require("./utils/literal");
20
+ Object.defineProperty(exports, "literal", { enumerable: true, get: function () { return __importDefault(literal_1).default; } });
21
+ var literallineWithoutBreakParent_1 = require("./utils/literallineWithoutBreakParent");
22
+ Object.defineProperty(exports, "literallineWithoutBreakParent", { enumerable: true, get: function () { return __importDefault(literallineWithoutBreakParent_1).default; } });
23
+ var makeCall_1 = require("./utils/makeCall");
24
+ Object.defineProperty(exports, "makeCall", { enumerable: true, get: function () { return __importDefault(makeCall_1).default; } });
25
+ var noIndent_1 = require("./utils/noIndent");
26
+ Object.defineProperty(exports, "noIndent", { enumerable: true, get: function () { return __importDefault(noIndent_1).default; } });
27
+ var printEmptyCollection_1 = require("./utils/printEmptyCollection");
28
+ Object.defineProperty(exports, "printEmptyCollection", { enumerable: true, get: function () { return __importDefault(printEmptyCollection_1).default; } });
29
+ var skipAssignIndent_1 = require("./utils/skipAssignIndent");
30
+ Object.defineProperty(exports, "skipAssignIndent", { enumerable: true, get: function () { return __importDefault(skipAssignIndent_1).default; } });
data/exe/rbprettier CHANGED
@@ -4,5 +4,4 @@
4
4
  $:.unshift(File.expand_path(File.join('..', 'lib'), __dir__))
5
5
  require 'prettier'
6
6
 
7
- Prettier.run(ARGV)
8
- exit($?.exitstatus) if $?.exited?
7
+ exit(Prettier.run(ARGV))
data/lib/prettier.rb CHANGED
@@ -1,18 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json' unless defined?(JSON)
4
+ require 'open3'
4
5
 
5
6
  module Prettier
6
7
  PLUGIN = -File.expand_path('..', __dir__)
7
8
  BINARY = -File.join(PLUGIN, 'node_modules', 'prettier', 'bin-prettier.js')
8
9
  VERSION = -JSON.parse(File.read(File.join(PLUGIN, 'package.json')))['version']
9
10
 
10
- class << self
11
- def run(args)
12
- quoted = args.map { |arg| arg.start_with?('-') ? arg : "\"#{arg}\"" }
13
- command = "node #{BINARY} --plugin \"#{PLUGIN}\" #{quoted.join(' ')}"
11
+ def self.run(args)
12
+ quoted = args.map { |arg| arg.start_with?('-') ? arg : "\"#{arg}\"" }
13
+ command = "node #{BINARY} --plugin \"#{PLUGIN}\" #{quoted.join(' ')}"
14
14
 
15
- system({ 'RBPRETTIER' => '1' }, command)
15
+ stdout, stderr, status = Open3.capture3({ 'RBPRETTIER' => '1' }, command)
16
+ STDOUT.puts(stdout)
17
+
18
+ # If we completed successfully, then just exit out.
19
+ exitstatus = status.exitstatus
20
+ return exitstatus if exitstatus == 0
21
+
22
+ if stderr.match?(%r{Cannot find module '/.+?/bin-prettier.js'})
23
+ # If we're missing bin-prettier.js, then it's possible the user installed
24
+ # the gem through git, which wouldn't have installed the requisite
25
+ # JavaScript files.
26
+ STDERR.puts(<<~MSG)
27
+ Could not find the JavaScript files necessary to run prettier.
28
+
29
+ If you installed this dependency through git instead of from rubygems,
30
+ it does not install the necessary files by default. To fix this you can
31
+ either install them yourself by cd-ing into the directory where this gem
32
+ is located (#{File.expand_path('..', __dir__)}) and running:
33
+
34
+ `yarn && yarn prepublishOnly`
35
+ or
36
+ `npm install && npm run prepublishOnly`
37
+ or
38
+ you can change the source in your Gemfile to point directly to rubygems.
39
+ MSG
40
+ else
41
+ # Otherwise, just print out the same error that prettier emitted, as it's
42
+ # unknown to us.
43
+ STDERR.puts(stderr)
16
44
  end
45
+
46
+ # Make sure we still exit with the same status code the prettier emitted.
47
+ exitstatus
17
48
  end
18
49
  end