prettier 2.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -6
  3. data/README.md +17 -16
  4. data/exe/rbprettier +2 -2
  5. data/lib/prettier/rake/task.rb +5 -5
  6. data/lib/prettier.rb +12 -11
  7. data/node_modules/prettier/bin-prettier.js +48 -18924
  8. data/node_modules/prettier/cli.js +12335 -0
  9. data/node_modules/prettier/doc.js +1306 -4755
  10. data/node_modules/prettier/index.js +37468 -57614
  11. data/node_modules/prettier/package.json +3 -2
  12. data/node_modules/prettier/parser-angular.js +2 -66
  13. data/node_modules/prettier/parser-babel.js +27 -22
  14. data/node_modules/prettier/parser-espree.js +26 -22
  15. data/node_modules/prettier/parser-flow.js +26 -22
  16. data/node_modules/prettier/parser-glimmer.js +27 -1
  17. data/node_modules/prettier/parser-graphql.js +15 -1
  18. data/node_modules/prettier/parser-html.js +21 -117
  19. data/node_modules/prettier/parser-markdown.js +61 -19
  20. data/node_modules/prettier/parser-meriyah.js +19 -22
  21. data/node_modules/prettier/parser-postcss.js +76 -22
  22. data/node_modules/prettier/parser-typescript.js +280 -22
  23. data/node_modules/prettier/parser-yaml.js +150 -15
  24. data/node_modules/prettier/third-party.js +8660 -11030
  25. data/package.json +11 -25
  26. data/rubocop.yml +6 -6
  27. data/src/getInfo.js +23 -0
  28. data/{dist/parser → src}/netcat.js +0 -1
  29. data/src/parseSync.js +216 -0
  30. data/src/plugin.js +170 -0
  31. data/{dist/parser → src}/server.rb +50 -27
  32. metadata +95 -75
  33. data/bin/console +0 -7
  34. data/dist/haml/embed.js +0 -53
  35. data/dist/haml/parser.js +0 -31
  36. data/dist/haml/parser.rb +0 -143
  37. data/dist/haml/printer.js +0 -336
  38. data/dist/parser/getInfo.js +0 -17
  39. data/dist/parser/parseSync.js +0 -179
  40. data/dist/plugin.js +0 -143
  41. data/dist/prettier.js +0 -15
  42. data/dist/rbs/parser.js +0 -34
  43. data/dist/rbs/parser.rb +0 -98
  44. data/dist/rbs/printer.js +0 -517
  45. data/dist/ruby/embed.js +0 -110
  46. data/dist/ruby/nodes/alias.js +0 -59
  47. data/dist/ruby/nodes/aref.js +0 -53
  48. data/dist/ruby/nodes/args.js +0 -165
  49. data/dist/ruby/nodes/arrays.js +0 -126
  50. data/dist/ruby/nodes/assign.js +0 -41
  51. data/dist/ruby/nodes/blocks.js +0 -87
  52. data/dist/ruby/nodes/calls.js +0 -260
  53. data/dist/ruby/nodes/case.js +0 -50
  54. data/dist/ruby/nodes/class.js +0 -54
  55. data/dist/ruby/nodes/commands.js +0 -124
  56. data/dist/ruby/nodes/conditionals.js +0 -242
  57. data/dist/ruby/nodes/constants.js +0 -38
  58. data/dist/ruby/nodes/flow.js +0 -66
  59. data/dist/ruby/nodes/hashes.js +0 -130
  60. data/dist/ruby/nodes/heredocs.js +0 -30
  61. data/dist/ruby/nodes/hooks.js +0 -35
  62. data/dist/ruby/nodes/ints.js +0 -27
  63. data/dist/ruby/nodes/lambdas.js +0 -69
  64. data/dist/ruby/nodes/loops.js +0 -73
  65. data/dist/ruby/nodes/massign.js +0 -73
  66. data/dist/ruby/nodes/methods.js +0 -70
  67. data/dist/ruby/nodes/operators.js +0 -70
  68. data/dist/ruby/nodes/params.js +0 -89
  69. data/dist/ruby/nodes/patterns.js +0 -122
  70. data/dist/ruby/nodes/regexp.js +0 -45
  71. data/dist/ruby/nodes/rescue.js +0 -85
  72. data/dist/ruby/nodes/return.js +0 -75
  73. data/dist/ruby/nodes/statements.js +0 -111
  74. data/dist/ruby/nodes/strings.js +0 -218
  75. data/dist/ruby/nodes/super.js +0 -30
  76. data/dist/ruby/nodes/undef.js +0 -26
  77. data/dist/ruby/nodes.js +0 -151
  78. data/dist/ruby/parser.js +0 -34
  79. data/dist/ruby/parser.rb +0 -3636
  80. data/dist/ruby/printer.js +0 -129
  81. data/dist/ruby/toProc.js +0 -93
  82. data/dist/types/haml.js +0 -4
  83. data/dist/types/plugin.js +0 -3
  84. data/dist/types/rbs.js +0 -4
  85. data/dist/types/ruby.js +0 -4
  86. data/dist/types/utils.js +0 -2
  87. data/dist/types.js +0 -30
  88. data/dist/utils/containsAssignment.js +0 -15
  89. data/dist/utils/getTrailingComma.js +0 -6
  90. data/dist/utils/hasAncestor.js +0 -15
  91. data/dist/utils/inlineEnsureParens.js +0 -49
  92. data/dist/utils/isEmptyBodyStmt.js +0 -10
  93. data/dist/utils/isEmptyStmts.js +0 -10
  94. data/dist/utils/literal.js +0 -8
  95. data/dist/utils/literallineWithoutBreakParent.js +0 -8
  96. data/dist/utils/makeCall.js +0 -13
  97. data/dist/utils/noIndent.js +0 -11
  98. data/dist/utils/printEmptyCollection.js +0 -44
  99. data/dist/utils/skipAssignIndent.js +0 -15
  100. data/dist/utils.js +0 -30
data/dist/ruby/embed.js DELETED
@@ -1,110 +0,0 @@
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 utils_1 = require("../utils");
8
- const { group, indent, dedent, lineSuffix, mapDoc, markAsRoot, stripTrailingHardline } = prettier_1.default;
9
- const parsers = {
10
- css: "css",
11
- javascript: "babel",
12
- js: "babel",
13
- less: "less",
14
- markdown: "markdown",
15
- ruby: "ruby",
16
- scss: "scss"
17
- };
18
- // This function is in here because it handles embedded parser values. I don't
19
- // have a test that exercises it because I'm not sure for which parser it is
20
- // necessary, but since it's in prettier core I'm keeping it here.
21
- /* istanbul ignore next */
22
- function replaceNewlines(doc) {
23
- return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" && currentDoc.includes("\n")
24
- ? currentDoc
25
- .split(/(\n)/g)
26
- .map((v, i) => (i % 2 === 0 ? v : utils_1.literallineWithoutBreakParent))
27
- : currentDoc);
28
- }
29
- // Returns a number that represents the minimum amount of leading whitespace
30
- // that is present on every line in the given string. So for example if you have
31
- // the following heredoc:
32
- //
33
- // <<~HERE
34
- // my
35
- // content
36
- // here
37
- // HERE
38
- //
39
- // then the return value of this function would be 2. If you indented every line
40
- // of the inner content 2 more spaces then this function would return 4.
41
- function getCommonLeadingWhitespace(content) {
42
- const pattern = /^\s+/;
43
- return content
44
- .split("\n")
45
- .slice(0, -1)
46
- .filter((line) => line.trim().length > 0)
47
- .reduce((minimum, line) => {
48
- const matched = pattern.exec(line);
49
- const length = matched ? matched[0].length : 0;
50
- return minimum === null ? length : Math.min(minimum, length);
51
- }, content.length);
52
- }
53
- // Returns a new string with the common whitespace stripped out. Effectively it
54
- // emulates what a squiggly heredoc does in Ruby.
55
- function stripCommonLeadingWhitespace(content) {
56
- const lines = content.split("\n");
57
- const minimum = getCommonLeadingWhitespace(content);
58
- return lines.map((line) => line.slice(minimum)).join("\n");
59
- }
60
- const embed = (path, print, textToDoc) => {
61
- const node = path.getValue();
62
- // Currently we only support embedded formatting on heredoc nodes
63
- if (node.type !== "heredoc") {
64
- return null;
65
- }
66
- // First, ensure that we don't have any interpolation
67
- const { beging, body, ending } = node;
68
- const isSquiggly = beging.body[2] === "~";
69
- if (body.some((part) => part.type !== "@tstring_content")) {
70
- return null;
71
- }
72
- // Next, find the parser associated with this heredoc (if there is one). For
73
- // example, if you use <<~CSS, we'd hook it up to the css parser.
74
- const parser = parsers[beging.body.slice(3).toLowerCase()];
75
- if (!parser) {
76
- return null;
77
- }
78
- // Get the content as if it were a source string.
79
- let content = body.map((part) => part.body).join("");
80
- // If we're using a squiggly heredoc, then we're going to manually strip off
81
- // the leading whitespace of each line up to the minimum leading whitespace so
82
- // that the embedded parser can handle that for us.
83
- if (isSquiggly) {
84
- content = stripCommonLeadingWhitespace(content);
85
- }
86
- // Pass that content into the embedded parser. Get back the doc node.
87
- const formatted = [
88
- utils_1.literallineWithoutBreakParent,
89
- replaceNewlines(stripTrailingHardline(textToDoc(content, { parser })))
90
- ];
91
- // If we're using a squiggly heredoc, then we can properly handle indentation
92
- // ourselves.
93
- if (isSquiggly) {
94
- return [
95
- path.call(print, "beging"),
96
- lineSuffix(dedent([
97
- indent(markAsRoot(formatted)),
98
- { type: "line", hard: true },
99
- ending.trim()
100
- ]))
101
- ];
102
- }
103
- // Otherwise, we need to just assume it's formatted correctly and return the
104
- // content as it is.
105
- return markAsRoot([
106
- path.call(print, "beging"),
107
- lineSuffix(group([formatted, utils_1.literallineWithoutBreakParent, ending.trim()]))
108
- ]);
109
- };
110
- exports.default = embed;
@@ -1,59 +0,0 @@
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.printAlias = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const { addTrailingComment, align, group, hardline, line } = prettier_1.default;
9
- // The `alias` keyword is used to make a method respond to another name as well
10
- // as the current one. For example, to get the method `foo` to also respond to
11
- // `bar`, you would:
12
- //
13
- // alias bar foo
14
- //
15
- // Now, in the current context you can call `bar` and it will execute the `foo`
16
- // method.
17
- //
18
- // When you're aliasing two methods, you can either provide bare words (like the
19
- // example above) or you can provide symbols (note that this includes dynamic
20
- // symbols like :"foo-#{bar}-baz"). In general, to be consistent with the ruby
21
- // style guide, we prefer bare words:
22
- //
23
- // https://github.com/rubocop-hq/ruby-style-guide#alias-method-lexically
24
- //
25
- // The `alias` node contains two children. The left and right align with the
26
- // arguments passed to the keyword. So, for the above example the left would be
27
- // the symbol literal `bar` and the right could be the symbol literal `foo`.
28
- const printAlias = (path, opts, print) => {
29
- const keyword = "alias ";
30
- // In general, return the printed doc of the argument at the provided index.
31
- // Special handling is given for symbol literals that are not bare words, as
32
- // we convert those into bare words by just pulling out the ident node.
33
- const printAliasArg = (argPath) => {
34
- const argNode = argPath.getValue();
35
- if (argNode.type === "symbol_literal") {
36
- // If we're going to descend into the symbol literal to grab out the ident
37
- // node, then we need to make sure we copy over any comments as well,
38
- // otherwise we could accidentally skip printing them.
39
- if (argNode.comments) {
40
- argNode.comments.forEach((comment) => {
41
- addTrailingComment(argNode.body[0], comment);
42
- });
43
- }
44
- return argPath.call(print, "body", 0);
45
- }
46
- return print(argPath);
47
- };
48
- return group([
49
- keyword,
50
- path.call(printAliasArg, "body", 0),
51
- group(align(keyword.length, [
52
- // If the left child has any comments, then we need to explicitly break
53
- // this into two lines
54
- path.getValue().body[0].comments ? hardline : line,
55
- path.call(printAliasArg, "body", 1)
56
- ]))
57
- ]);
58
- };
59
- exports.printAlias = printAlias;
@@ -1,53 +0,0 @@
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.printArefField = exports.printAref = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const { group, indent, join, line, softline } = prettier_1.default;
9
- // `aref` nodes are when you're pulling a value out of a collection at a
10
- // specific index. Put another way, it's any time you're calling the method
11
- // `#[]`.
12
- //
13
- // The nodes usually contains two children, details below in the
14
- // `printArefField` function. In some cases, you don't necessarily have the
15
- // second child node, because you can call procs with a pretty esoteric syntax.
16
- // In the following example, you wouldn't have a second child, and `"foo"` would
17
- // be the first child.
18
- //
19
- // foo[]
20
- //
21
- const printAref = (path, opts, print) => {
22
- const indexNode = path.getValue().body[1];
23
- if (!indexNode) {
24
- return [path.call(print, "body", 0), "[]"];
25
- }
26
- return (0, exports.printArefField)(path, opts, print);
27
- };
28
- exports.printAref = printAref;
29
- // `aref_field` nodes are for assigning values into collections at specific
30
- // indices. Put another way, it's any time you're calling the method `#[]=`.
31
- // The `aref_field` node itself is just the left side of the assignment, and
32
- // they're always wrapped in `assign` nodes.
33
- //
34
- // The nodes always contain two children, the name of the array (usually a
35
- // `vcall` node and the index (usually an `args_add_block` node). The
36
- // `args_add_block` is one of a couple nodes that has special handling where its
37
- // printed form is actually an array to make joining easier.
38
- //
39
- // So in the following example, `"foo"` is the array and `["bar"]` is the index.
40
- //
41
- // foo[bar] = baz
42
- //
43
- const printArefField = (path, opts, print) => {
44
- const [printedArray, printedIndex] = path.map(print, "body");
45
- return group([
46
- printedArray,
47
- "[",
48
- indent([softline, join([",", line], printedIndex)]),
49
- softline,
50
- "]"
51
- ]);
52
- };
53
- exports.printArefField = printArefField;
@@ -1,165 +0,0 @@
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.printBlockArg = exports.printArgsAddStar = exports.printArgsAddBlock = exports.printArgs = exports.printArgParen = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const toProc_1 = __importDefault(require("../toProc"));
10
- const { group, ifBreak, indent, join, line, softline } = prettier_1.default;
11
- const noTrailingComma = ["command", "command_call"];
12
- function getArgParenTrailingComma(node) {
13
- // If we have a block, then we don't want to add a trailing comma.
14
- if (node.type === "args_add_block" && node.body[1]) {
15
- return "";
16
- }
17
- // If we only have one argument and that first argument necessitates that we
18
- // skip putting a comma (because it would interfere with parsing the argument)
19
- // then we don't want to add a trailing comma.
20
- if (node.body.length === 1 && noTrailingComma.includes(node.body[0].type)) {
21
- return "";
22
- }
23
- return ifBreak(",", "");
24
- }
25
- const printArgParen = (path, opts, print) => {
26
- const argsNode = path.getValue().body[0];
27
- if (argsNode === null) {
28
- return "";
29
- }
30
- // Here we can skip the entire rest of the method by just checking if it's
31
- // an args_forward node, as we're guaranteed that there are no other arg
32
- // nodes.
33
- if (argsNode.type === "args_forward") {
34
- return group([
35
- "(",
36
- indent([softline, path.call(print, "body", 0)]),
37
- softline,
38
- ")"
39
- ]);
40
- }
41
- // Now here we return a doc that represents the whole grouped expression,
42
- // including the surrouding parentheses.
43
- return group([
44
- "(",
45
- indent([
46
- softline,
47
- join([",", line], path.call(print, "body", 0)),
48
- (0, utils_1.getTrailingComma)(opts) ? getArgParenTrailingComma(argsNode) : ""
49
- ]),
50
- softline,
51
- ")"
52
- ]);
53
- };
54
- exports.printArgParen = printArgParen;
55
- const printArgs = (path, { rubyToProc }, print) => {
56
- const args = path.map(print, "body");
57
- // Don't bother trying to do any kind of fancy toProc transform if the
58
- // option is disabled.
59
- if (rubyToProc) {
60
- let blockNode = null;
61
- // Look up the chain to see if these arguments are contained within a
62
- // method_add_block node, and if they are that that node has a block
63
- // associated with it. If it does, we're going to attempt to transform it
64
- // into the to_proc shorthand and add it to the list of arguments.
65
- [1, 2, 3].find((parent) => {
66
- const parentNode = path.getParentNode(parent);
67
- blockNode =
68
- parentNode &&
69
- parentNode.type === "method_add_block" &&
70
- parentNode.body[1];
71
- return blockNode;
72
- });
73
- const proc = blockNode && (0, toProc_1.default)(path, blockNode);
74
- // If we have a successful to_proc transformation, but we're part of an
75
- // aref node, that means it's something to the effect of
76
- //
77
- // foo[:bar].each(&:to_s)
78
- //
79
- // In this case we need to just return regular arguments, otherwise we
80
- // would end up putting &:to_s inside the brackets accidentally.
81
- if (proc && path.getParentNode(1).type !== "aref") {
82
- args.push(proc);
83
- }
84
- }
85
- return args;
86
- };
87
- exports.printArgs = printArgs;
88
- const printArgsAddBlock = (path, opts, print) => {
89
- const node = path.getValue();
90
- const blockNode = node.body[1];
91
- const parts = path.call(print, "body", 0);
92
- if (blockNode) {
93
- let blockDoc = path.call(print, "body", 1);
94
- if (!(blockNode.comments || []).some(({ leading }) => leading)) {
95
- // If we don't have any leading comments, we can just prepend the
96
- // operator.
97
- blockDoc = ["&", blockDoc];
98
- }
99
- else {
100
- // If we have a method call like:
101
- //
102
- // foo(
103
- // # comment
104
- // &block
105
- // )
106
- //
107
- // then we need to make sure we don't accidentally prepend the operator
108
- // before the comment.
109
- //
110
- // In prettier >= 2.3.0, the comments are printed as an array before the
111
- // content. I don't love this kind of reflection, but it's the simplest
112
- // way at the moment to get this right.
113
- blockDoc = blockDoc[0].concat(["&", blockDoc[1]], blockDoc.slice(2));
114
- }
115
- parts.push(blockDoc);
116
- }
117
- return parts;
118
- };
119
- exports.printArgsAddBlock = printArgsAddBlock;
120
- const printArgsAddStar = (path, opts, print) => {
121
- let docs = [];
122
- path.each((argPath, argIndex) => {
123
- const doc = print(argPath);
124
- // If it's the first child, then it's an array of args, so we're going to
125
- // concat that onto the existing docs if there are any.
126
- if (argIndex === 0) {
127
- if (doc.length > 0) {
128
- docs = docs.concat(doc);
129
- }
130
- return;
131
- }
132
- // If it's after the splat, then it's an individual arg, so we're just going
133
- // to push it onto the array.
134
- if (argIndex !== 1) {
135
- docs.push(doc);
136
- return;
137
- }
138
- // If we don't have any leading comments, we can just prepend the operator.
139
- const argsNode = argPath.getValue();
140
- if (!(argsNode.comments || []).some(({ leading }) => leading)) {
141
- docs.push(["*", doc]);
142
- return;
143
- }
144
- // If we have an array like:
145
- //
146
- // [
147
- // # comment
148
- // *values
149
- // ]
150
- //
151
- // then we need to make sure we don't accidentally prepend the operator
152
- // before the comment(s).
153
- //
154
- // In prettier >= 2.3.0, the comments are printed as an array before the
155
- // content. I don't love this kind of reflection, but it's the simplest way
156
- // at the moment to get this right.
157
- docs.push(doc[0].concat(["*", doc[1]], doc.slice(2)));
158
- }, "body");
159
- return docs;
160
- };
161
- exports.printArgsAddStar = printArgsAddStar;
162
- const printBlockArg = (path, opts, print) => {
163
- return ["&", path.call(print, "body", 0)];
164
- };
165
- exports.printBlockArg = printBlockArg;
@@ -1,126 +0,0 @@
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.printArray = exports.printWord = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { group, ifBreak, indent, join, line, softline } = prettier_1.default;
10
- // Checks that every argument within this args node is a string_literal node
11
- // that has no spaces or interpolations. This means we're dealing with an array
12
- // that looks something like:
13
- //
14
- // ['a', 'b', 'c']
15
- //
16
- function isStringArray(args) {
17
- return (args.body.length > 1 &&
18
- args.body.every((arg) => {
19
- // We want to verify that every node inside of this array is a string
20
- // literal. We also want to make sure none of them have comments attached.
21
- if (arg.type !== "string_literal" || arg.comments) {
22
- return false;
23
- }
24
- // If the string has multiple parts (meaning plain string content but also
25
- // interpolated content) then we know it's not a simple string.
26
- if (arg.body.length !== 1) {
27
- return false;
28
- }
29
- const part = arg.body[0];
30
- // If the only part of this string is not @tstring_content then it's
31
- // interpolated, so again we can return false.
32
- if (part.type !== "@tstring_content") {
33
- return false;
34
- }
35
- // Finally, verify that the string doesn't contain a space, an escape
36
- // character, or brackets so that we know it can be put into a string
37
- // literal array.
38
- return !/[\s\\[\]]/.test(part.body);
39
- }));
40
- }
41
- // Checks that every argument within this args node is a symbol_literal node (as
42
- // opposed to a dyna_symbol) so it has no interpolation. This means we're
43
- // dealing with an array that looks something like:
44
- //
45
- // [:a, :b, :c]
46
- //
47
- function isSymbolArray(args) {
48
- return (args.body.length > 1 &&
49
- args.body.every((arg) => arg.type === "symbol_literal" && !arg.comments));
50
- }
51
- // Prints out a word that is a part of a special array literal that accepts
52
- // interpolation. The body is an array of either plain strings or interpolated
53
- // expressions.
54
- const printWord = (path, opts, print) => {
55
- return path.map(print, "body");
56
- };
57
- exports.printWord = printWord;
58
- // Prints out a special array literal. Accepts the parts of the array literal as
59
- // an argument, where the first element of the parts array is a string that
60
- // contains the special start.
61
- function printArrayLiteral(start, parts) {
62
- return group([
63
- start,
64
- "[",
65
- indent([softline, join(line, parts)]),
66
- softline,
67
- "]"
68
- ]);
69
- }
70
- const arrayLiteralStarts = {
71
- qsymbols: "%i",
72
- qwords: "%w",
73
- symbols: "%I",
74
- words: "%W"
75
- };
76
- // An array node is any literal array in Ruby. This includes all of the special
77
- // array literals as well as regular arrays. If it is a special array literal
78
- // then it will have one child that represents the special array, otherwise it
79
- // will have one child that contains all of the elements of the array.
80
- const printArray = (path, opts, print) => {
81
- const array = path.getValue();
82
- const args = array.body[0];
83
- // If there is no inner arguments node, then we're dealing with an empty
84
- // array, so we can go ahead and return.
85
- if (args === null) {
86
- return (0, utils_1.printEmptyCollection)(path, opts, "[", "]");
87
- }
88
- // If we don't have a regular args node at this point then we have a special
89
- // array literal. In that case we're going to print out the body (which will
90
- // return to us an array with the first one being the start of the array) and
91
- // send that over to the printArrayLiteral function.
92
- if (args.type !== "args" && args.type !== "args_add_star") {
93
- return path.call((arrayPath) => printArrayLiteral(arrayLiteralStarts[args.type], arrayPath.map(print, "body")), "body", 0);
94
- }
95
- if (opts.rubyArrayLiteral) {
96
- // If we have an array that contains only simple string literals with no
97
- // spaces or interpolation, then we're going to print a %w array.
98
- if (isStringArray(args)) {
99
- const printString = (stringPath) => stringPath.call(print, "body", 0);
100
- const nodePath = path;
101
- const parts = nodePath.map(printString, "body", 0, "body");
102
- return printArrayLiteral("%w", parts);
103
- }
104
- // If we have an array that contains only simple symbol literals with no
105
- // interpolation, then we're going to print a %i array.
106
- if (isSymbolArray(args)) {
107
- const printSymbol = (symbolPath) => symbolPath.call(print, "body", 0);
108
- const nodePath = path;
109
- const parts = nodePath.map(printSymbol, "body", 0, "body");
110
- return printArrayLiteral("%i", parts);
111
- }
112
- }
113
- // Here we have a normal array of any type of object with no special literal
114
- // types or anything.
115
- return group([
116
- "[",
117
- indent([
118
- softline,
119
- join([",", line], path.call(print, "body", 0)),
120
- (0, utils_1.getTrailingComma)(opts) ? ifBreak(",", "") : ""
121
- ]),
122
- softline,
123
- "]"
124
- ]);
125
- };
126
- exports.printArray = printArray;
@@ -1,41 +0,0 @@
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.printVarRef = exports.printVarField = exports.printOpAssign = exports.printAssign = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { group, indent, join, line } = prettier_1.default;
10
- const printAssign = (path, opts, print) => {
11
- const [, valueNode] = path.getValue().body;
12
- const [targetDoc, valueDoc] = path.map(print, "body");
13
- let rightSideDoc = valueDoc;
14
- // If the right side of this assignment is a multiple assignment, then we need
15
- // to join it together with commas.
16
- if (["mrhs_add_star", "mrhs_new_from_args"].includes(valueNode.type)) {
17
- rightSideDoc = group(join([",", line], valueDoc));
18
- }
19
- if ((0, utils_1.skipAssignIndent)(valueNode)) {
20
- return group([targetDoc, " = ", rightSideDoc]);
21
- }
22
- return group([targetDoc, " =", indent([line, rightSideDoc])]);
23
- };
24
- exports.printAssign = printAssign;
25
- const printOpAssign = (path, opts, print) => {
26
- return group([
27
- path.call(print, "body", 0),
28
- " ",
29
- path.call(print, "body", 1),
30
- indent([line, path.call(print, "body", 2)])
31
- ]);
32
- };
33
- exports.printOpAssign = printOpAssign;
34
- const printVarField = (path, opts, print) => {
35
- return path.getValue().body ? path.call(print, "body", 0) : "";
36
- };
37
- exports.printVarField = printVarField;
38
- const printVarRef = (path, opts, print) => {
39
- return path.call(print, "body", 0);
40
- };
41
- exports.printVarRef = printVarRef;
@@ -1,87 +0,0 @@
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.printDoBlock = exports.printBraceBlock = exports.printBlockVar = void 0;
7
- const prettier_1 = __importDefault(require("../../prettier"));
8
- const utils_1 = require("../../utils");
9
- const { breakParent, group, ifBreak, indent, join, removeLines, softline } = prettier_1.default;
10
- const printBlockVar = (path, opts, print) => {
11
- const parts = ["|", removeLines(path.call(print, "body", 0))];
12
- // The second part of this node is a list of optional block-local variables
13
- if (path.getValue().body[1]) {
14
- parts.push("; ", join(", ", path.map(print, "body", 1)));
15
- }
16
- parts.push("| ");
17
- return parts;
18
- };
19
- exports.printBlockVar = printBlockVar;
20
- // You have to go through the main print function if you could potentially have
21
- // comments attached. So we're doing this weird reflection on the printed docs
22
- // to retroactively change the printed keyword depending on if we're using
23
- // braces or not. Ideally we wouldn't do this, we would instead do this
24
- // reflection in the child printer, but this keeps the logic to just this file
25
- // and contains it, so keeping it here for now.
26
- function printBlockBeging(path, print, useBraces) {
27
- let docs = print(path);
28
- const doc = useBraces ? "{" : "do";
29
- if (Array.isArray(docs)) {
30
- docs[1] = doc;
31
- }
32
- else {
33
- docs = doc;
34
- }
35
- return docs;
36
- }
37
- function printBlock(braces) {
38
- return function printBlockWithBraces(path, opts, print) {
39
- const [variables, statements] = path.getValue().body;
40
- const stmts = statements.type === "stmts" ? statements.body : statements.body[0].body;
41
- let doBlockBody = "";
42
- if (stmts.length !== 1 ||
43
- stmts[0].type !== "void_stmt" ||
44
- stmts[0].comments) {
45
- doBlockBody = indent([softline, path.call(print, "body", 1)]);
46
- }
47
- // If this block is nested underneath a command or command_call node, then
48
- // we can't use `do...end` because that will get associated with the parent
49
- // node as opposed to the current node (because of the difference in
50
- // operator precedence). Instead, we still use a multi-line format but
51
- // switch to using braces instead.
52
- const useBraces = braces && (0, utils_1.hasAncestor)(path, ["command", "command_call"]);
53
- const doBlock = [
54
- " ",
55
- path.call((begingPath) => printBlockBeging(begingPath, print, useBraces), "beging"),
56
- variables ? [" ", path.call(print, "body", 0)] : "",
57
- doBlockBody,
58
- [softline, useBraces ? "}" : "end"]
59
- ];
60
- // We can hit this next pattern if within the block the only statement is a
61
- // comment.
62
- if (stmts.length === 1 &&
63
- stmts[0].type === "void_stmt" &&
64
- stmts[0].comments) {
65
- return [breakParent, doBlock];
66
- }
67
- const blockReceiver = path.getParentNode().body[0];
68
- // If the parent node is a command node, then there are no parentheses
69
- // around the arguments to that command, so we need to break the block
70
- if (["command", "command_call"].includes(blockReceiver.type)) {
71
- return [breakParent, doBlock];
72
- }
73
- const hasBody = stmts.some(({ type }) => type !== "void_stmt");
74
- const braceBlock = [
75
- " ",
76
- path.call((begingPath) => printBlockBeging(begingPath, print, true), "beging"),
77
- hasBody || variables ? " " : "",
78
- variables ? path.call(print, "body", 0) : "",
79
- path.call(print, "body", 1),
80
- hasBody ? " " : "",
81
- "}"
82
- ];
83
- return group(ifBreak(doBlock, braceBlock));
84
- };
85
- }
86
- exports.printBraceBlock = printBlock(true);
87
- exports.printDoBlock = printBlock(false);