prettier 2.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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);