prettier 1.6.1 → 2.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +316 -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 +128 -0
  13. data/dist/parser/server.rb +140 -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 +68 -0
  26. data/dist/ruby/nodes/calls.js +220 -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 +82 -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 +1215 -252
  54. data/dist/ruby/printer.js +125 -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/node_modules/prettier/bin-prettier.js +313 -190
  76. data/node_modules/prettier/doc.js +191 -323
  77. data/node_modules/prettier/index.js +2753 -3677
  78. data/node_modules/prettier/package.json +1 -1
  79. data/node_modules/prettier/parser-angular.js +13 -14
  80. data/node_modules/prettier/parser-babel.js +7 -7
  81. data/node_modules/prettier/parser-espree.js +7 -7
  82. data/node_modules/prettier/parser-flow.js +7 -7
  83. data/node_modules/prettier/parser-glimmer.js +1 -1
  84. data/node_modules/prettier/parser-graphql.js +1 -1
  85. data/node_modules/prettier/parser-html.js +17 -17
  86. data/node_modules/prettier/parser-markdown.js +9 -9
  87. data/node_modules/prettier/parser-meriyah.js +7 -7
  88. data/node_modules/prettier/parser-postcss.js +2 -2
  89. data/node_modules/prettier/parser-typescript.js +7 -7
  90. data/node_modules/prettier/parser-yaml.js +2 -2
  91. data/node_modules/prettier/third-party.js +143 -78
  92. data/package.json +26 -18
  93. metadata +74 -67
  94. data/src/haml/embed.js +0 -87
  95. data/src/haml/parser.js +0 -23
  96. data/src/haml/printer.js +0 -438
  97. data/src/parser/parseSync.js +0 -172
  98. data/src/parser/server.rb +0 -66
  99. data/src/plugin.js +0 -148
  100. data/src/prettier.js +0 -16
  101. data/src/rbs/parser.js +0 -37
  102. data/src/rbs/printer.js +0 -643
  103. data/src/ruby/embed.js +0 -142
  104. data/src/ruby/nodes/alias.js +0 -73
  105. data/src/ruby/nodes/args.js +0 -222
  106. data/src/ruby/nodes/arrays.js +0 -162
  107. data/src/ruby/nodes/assign.js +0 -47
  108. data/src/ruby/nodes/blocks.js +0 -90
  109. data/src/ruby/nodes/calls.js +0 -246
  110. data/src/ruby/nodes/case.js +0 -65
  111. data/src/ruby/nodes/class.js +0 -64
  112. data/src/ruby/nodes/commands.js +0 -131
  113. data/src/ruby/nodes/conditionals.js +0 -282
  114. data/src/ruby/nodes/constants.js +0 -43
  115. data/src/ruby/nodes/flow.js +0 -74
  116. data/src/ruby/nodes/hashes.js +0 -155
  117. data/src/ruby/nodes/heredocs.js +0 -36
  118. data/src/ruby/nodes/hooks.js +0 -34
  119. data/src/ruby/nodes/ints.js +0 -31
  120. data/src/ruby/nodes/lambdas.js +0 -76
  121. data/src/ruby/nodes/loops.js +0 -98
  122. data/src/ruby/nodes/massign.js +0 -98
  123. data/src/ruby/nodes/methods.js +0 -74
  124. data/src/ruby/nodes/operators.js +0 -83
  125. data/src/ruby/nodes/params.js +0 -106
  126. data/src/ruby/nodes/patterns.js +0 -157
  127. data/src/ruby/nodes/regexp.js +0 -56
  128. data/src/ruby/nodes/rescue.js +0 -101
  129. data/src/ruby/nodes/return.js +0 -94
  130. data/src/ruby/nodes/statements.js +0 -142
  131. data/src/ruby/nodes/strings.js +0 -272
  132. data/src/ruby/nodes/super.js +0 -35
  133. data/src/ruby/nodes/undef.js +0 -42
  134. data/src/ruby/nodes.js +0 -34
  135. data/src/ruby/parser.js +0 -37
  136. data/src/ruby/printer.js +0 -147
  137. data/src/ruby/toProc.js +0 -105
  138. data/src/utils/containsAssignment.js +0 -11
  139. data/src/utils/getTrailingComma.js +0 -5
  140. data/src/utils/hasAncestor.js +0 -17
  141. data/src/utils/isEmptyBodyStmt.js +0 -7
  142. data/src/utils/isEmptyStmts.js +0 -11
  143. data/src/utils/literal.js +0 -7
  144. data/src/utils/literallineWithoutBreakParent.js +0 -7
  145. data/src/utils/makeCall.js +0 -14
  146. data/src/utils/noIndent.js +0 -10
  147. data/src/utils/printEmptyCollection.js +0 -49
  148. data/src/utils/skipAssignIndent.js +0 -17
  149. data/src/utils.js +0 -13
data/src/ruby/embed.js DELETED
@@ -1,142 +0,0 @@
1
- const {
2
- concat,
3
- group,
4
- indent,
5
- lineSuffix,
6
- mapDoc,
7
- markAsRoot,
8
- stripTrailingHardline
9
- } = require("../prettier");
10
-
11
- const { literallineWithoutBreakParent } = require("../utils");
12
-
13
- const parsers = {
14
- css: "css",
15
- javascript: "babel",
16
- js: "babel",
17
- less: "less",
18
- markdown: "markdown",
19
- ruby: "ruby",
20
- scss: "scss"
21
- };
22
-
23
- // This function is in here because it handles embedded parser values. I don't
24
- // have a test that exercises it because I'm not sure for which parser it is
25
- // necessary, but since it's in prettier core I'm keeping it here.
26
- /* istanbul ignore next */
27
- function replaceNewlines(doc) {
28
- return mapDoc(doc, (currentDoc) =>
29
- typeof currentDoc === "string" && currentDoc.includes("\n")
30
- ? concat(
31
- currentDoc
32
- .split(/(\n)/g)
33
- .map((v, i) => (i % 2 === 0 ? v : literallineWithoutBreakParent))
34
- )
35
- : currentDoc
36
- );
37
- }
38
-
39
- // Returns a number that represents the minimum amount of leading whitespace
40
- // that is present on every line in the given string. So for example if you have
41
- // the following heredoc:
42
- //
43
- // <<~HERE
44
- // my
45
- // content
46
- // here
47
- // HERE
48
- //
49
- // then the return value of this function would be 2. If you indented every line
50
- // of the inner content 2 more spaces then this function would return 4.
51
- function getCommonLeadingWhitespace(content) {
52
- const pattern = /^\s+/;
53
-
54
- return content
55
- .split("\n")
56
- .slice(0, -1)
57
- .reduce((minimum, line) => {
58
- const matched = pattern.exec(line);
59
- const length = matched ? matched[0].length : 0;
60
-
61
- return minimum === null ? length : Math.min(minimum, length);
62
- }, null);
63
- }
64
-
65
- // Returns a new string with the common whitespace stripped out. Effectively it
66
- // emulates what a squiggly heredoc does in Ruby.
67
- function stripCommonLeadingWhitespace(content) {
68
- const lines = content.split("\n");
69
- const minimum = getCommonLeadingWhitespace(content);
70
-
71
- return lines.map((line) => line.slice(minimum)).join("\n");
72
- }
73
-
74
- function embed(path, print, textToDoc, _opts) {
75
- const node = path.getValue();
76
-
77
- // Currently we only support embedded formatting on heredoc nodes
78
- if (node.type !== "heredoc") {
79
- return null;
80
- }
81
-
82
- // First, ensure that we don't have any interpolation
83
- const { beging, body, ending } = node;
84
- const isSquiggly = beging.body[2] === "~";
85
-
86
- if (body.some((part) => part.type !== "@tstring_content")) {
87
- return null;
88
- }
89
-
90
- // Next, find the parser associated with this heredoc (if there is one). For
91
- // example, if you use <<~CSS, we'd hook it up to the css parser.
92
- const parser = parsers[beging.body.slice(3).toLowerCase()];
93
- if (!parser) {
94
- return null;
95
- }
96
-
97
- // Get the content as if it were a source string.
98
- let content = body.map((part) => part.body).join("");
99
-
100
- // If we're using a squiggly heredoc, then we're going to manually strip off
101
- // the leading whitespace of each line up to the minimum leading whitespace so
102
- // that the embedded parser can handle that for us.
103
- if (isSquiggly) {
104
- content = stripCommonLeadingWhitespace(content);
105
- }
106
-
107
- // Pass that content into the embedded parser. Get back the doc node.
108
- const formatted = concat([
109
- literallineWithoutBreakParent,
110
- replaceNewlines(stripTrailingHardline(textToDoc(content, { parser })))
111
- ]);
112
-
113
- // If we're using a squiggly heredoc, then we can properly handle indentation
114
- // ourselves.
115
- if (isSquiggly) {
116
- return concat([
117
- path.call(print, "beging"),
118
- lineSuffix(
119
- group(
120
- concat([
121
- indent(markAsRoot(formatted)),
122
- literallineWithoutBreakParent,
123
- ending.trim()
124
- ])
125
- )
126
- )
127
- ]);
128
- }
129
-
130
- // Otherwise, we need to just assume it's formatted correctly and return the
131
- // content as it is.
132
- return markAsRoot(
133
- concat([
134
- path.call(print, "beging"),
135
- lineSuffix(
136
- group(concat([formatted, literallineWithoutBreakParent, ending.trim()]))
137
- )
138
- ])
139
- );
140
- }
141
-
142
- module.exports = embed;
@@ -1,73 +0,0 @@
1
- const {
2
- addTrailingComment,
3
- align,
4
- concat,
5
- group,
6
- hardline,
7
- line
8
- } = require("../../prettier");
9
-
10
- // In general, return the printed doc of the argument at the provided index.
11
- // Special handling is given for symbol literals that are not bare words, as we
12
- // convert those into bare words by just pulling out the ident node.
13
- function printAliasArgument(path, print, argIndex) {
14
- const node = path.getValue().body[argIndex];
15
-
16
- if (node.type === "symbol_literal") {
17
- // If we're going to descend into the symbol literal to grab out the ident
18
- // node, then we need to make sure we copy over any comments as well,
19
- // otherwise we could accidentally skip printing them.
20
- if (node.comments) {
21
- node.comments.forEach((comment) => {
22
- addTrailingComment(node.body[0], comment);
23
- });
24
- }
25
-
26
- return path.call(print, "body", argIndex, "body", 0);
27
- }
28
-
29
- return path.call(print, "body", argIndex);
30
- }
31
-
32
- // The `alias` keyword is used to make a method respond to another name as well
33
- // as the current one. For example, to get the method `foo` to also respond to
34
- // `bar`, you would:
35
- //
36
- // alias bar foo
37
- //
38
- // Now, in the current context you can call `bar` and it will execute the `foo`
39
- // method.
40
- //
41
- // When you're aliasing two methods, you can either provide bare words (like the
42
- // example above) or you can provide symbols (note that this includes dynamic
43
- // symbols like :"foo-#{bar}-baz"). In general, to be consistent with the ruby
44
- // style guide, we prefer bare words:
45
- //
46
- // https://github.com/rubocop-hq/ruby-style-guide#alias-method-lexically
47
- //
48
- // The `alias` node contains two children. The left and right align with the
49
- // arguments passed to the keyword. So, for the above example the left would be
50
- // the symbol literal `bar` and the right could be the symbol literal `foo`.
51
- function printAlias(path, opts, print) {
52
- const keyword = "alias ";
53
-
54
- const rightSide = concat([
55
- // If the left child has any comments, then we need to explicitly break this
56
- // into two lines
57
- path.getValue().body[0].comments ? hardline : line,
58
- printAliasArgument(path, print, 1)
59
- ]);
60
-
61
- return group(
62
- concat([
63
- keyword,
64
- printAliasArgument(path, print, 0),
65
- group(align(keyword.length, rightSide))
66
- ])
67
- );
68
- }
69
-
70
- module.exports = {
71
- alias: printAlias,
72
- var_alias: printAlias
73
- };
@@ -1,222 +0,0 @@
1
- const {
2
- concat,
3
- group,
4
- ifBreak,
5
- indent,
6
- join,
7
- line,
8
- softline
9
- } = require("../../prettier");
10
- const { getTrailingComma } = require("../../utils");
11
- const toProc = require("../toProc");
12
-
13
- const noTrailingComma = ["command", "command_call"];
14
-
15
- function getArgParenTrailingComma(node) {
16
- // If we have a block, then we don't want to add a trailing comma.
17
- if (node.type === "args_add_block" && node.body[1]) {
18
- return "";
19
- }
20
-
21
- // If we only have one argument and that first argument necessitates that we
22
- // skip putting a comma (because it would interfere with parsing the argument)
23
- // then we don't want to add a trailing comma.
24
- if (node.body.length === 1 && noTrailingComma.includes(node.body[0].type)) {
25
- return "";
26
- }
27
-
28
- return ifBreak(",", "");
29
- }
30
-
31
- function printArgParen(path, opts, print) {
32
- const argsNode = path.getValue().body[0];
33
-
34
- if (argsNode === null) {
35
- return "";
36
- }
37
-
38
- // Here we can skip the entire rest of the method by just checking if it's
39
- // an args_forward node, as we're guaranteed that there are no other arg
40
- // nodes.
41
- if (argsNode.type === "args_forward") {
42
- return group(
43
- concat([
44
- "(",
45
- indent(concat([softline, path.call(print, "body", 0)])),
46
- softline,
47
- ")"
48
- ])
49
- );
50
- }
51
-
52
- // Now here we return a doc that represents the whole grouped expression,
53
- // including the surrouding parentheses.
54
- return group(
55
- concat([
56
- "(",
57
- indent(
58
- concat([
59
- softline,
60
- join(concat([",", line]), path.call(print, "body", 0)),
61
- getTrailingComma(opts) ? getArgParenTrailingComma(argsNode) : ""
62
- ])
63
- ),
64
- softline,
65
- ")"
66
- ])
67
- );
68
- }
69
-
70
- function printArgs(path, { rubyToProc }, print) {
71
- const args = path.map(print, "body");
72
-
73
- // Don't bother trying to do any kind of fancy toProc transform if the
74
- // option is disabled.
75
- if (rubyToProc) {
76
- let blockNode = null;
77
-
78
- // Look up the chain to see if these arguments are contained within a
79
- // method_add_block node, and if they are that that node has a block
80
- // associated with it. If it does, we're going to attempt to transform it
81
- // into the to_proc shorthand and add it to the list of arguments.
82
- [1, 2, 3].find((parent) => {
83
- const parentNode = path.getParentNode(parent);
84
- blockNode =
85
- parentNode &&
86
- parentNode.type === "method_add_block" &&
87
- parentNode.body[1];
88
-
89
- return blockNode;
90
- });
91
-
92
- const proc = blockNode && toProc(path, blockNode);
93
-
94
- // If we have a successful to_proc transformation, but we're part of an
95
- // aref node, that means it's something to the effect of
96
- //
97
- // foo[:bar].each(&:to_s)
98
- //
99
- // In this case we need to just return regular arguments, otherwise we
100
- // would end up putting &:to_s inside the brackets accidentally.
101
- if (proc && path.getParentNode(1).type !== "aref") {
102
- args.push(proc);
103
- }
104
- }
105
-
106
- return args;
107
- }
108
-
109
- function printArgsAddBlock(path, opts, print) {
110
- const node = path.getValue();
111
- const blockNode = node.body[1];
112
-
113
- const parts = path.call(print, "body", 0);
114
-
115
- if (blockNode) {
116
- let blockDoc = path.call(print, "body", 1);
117
-
118
- if (!(blockNode.comments || []).some(({ leading }) => leading)) {
119
- // If we don't have any leading comments, we can just prepend the
120
- // operator.
121
- blockDoc = concat(["&", blockDoc]);
122
- } else if (Array.isArray(blockDoc[0])) {
123
- // If we have a method call like:
124
- //
125
- // foo(
126
- // # comment
127
- // &block
128
- // )
129
- //
130
- // then we need to make sure we don't accidentally prepend the operator
131
- // before the comment.
132
- //
133
- // In prettier >= 2.3.0, the comments are printed as an array before the
134
- // content. I don't love this kind of reflection, but it's the simplest
135
- // way at the moment to get this right.
136
- blockDoc = blockDoc[0].concat(
137
- concat(["&", blockDoc[1]]),
138
- blockDoc.slice(2)
139
- );
140
- } else {
141
- // In prettier < 2.3.0, the comments are printed as part of a concat, so
142
- // we can reflect on how many leading comments there are to determine
143
- // which doc node we should modify.
144
- const index = blockNode.comments.filter(({ leading }) => leading).length;
145
- blockDoc.parts[index] = concat(["&", blockDoc.parts[index]]);
146
- }
147
-
148
- parts.push(blockDoc);
149
- }
150
-
151
- return parts;
152
- }
153
-
154
- function printArgsAddStar(path, opts, print) {
155
- let docs = [];
156
-
157
- path.each((argPath, argIndex) => {
158
- const doc = print(argPath);
159
-
160
- // If it's the first child, then it's an array of args, so we're going to
161
- // concat that onto the existing docs if there are any.
162
- if (argIndex === 0) {
163
- if (doc.length > 0) {
164
- docs = docs.concat(doc);
165
- }
166
- return;
167
- }
168
-
169
- // If it's after the splat, then it's an individual arg, so we're just going
170
- // to push it onto the array.
171
- if (argIndex !== 1) {
172
- docs.push(doc);
173
- return;
174
- }
175
-
176
- // If we don't have any leading comments, we can just prepend the operator.
177
- const argsNode = argPath.getValue();
178
- if (!(argsNode.comments || []).some(({ leading }) => leading)) {
179
- docs.push(concat(["*", doc]));
180
- return;
181
- }
182
-
183
- // If we have an array like:
184
- //
185
- // [
186
- // # comment
187
- // *values
188
- // ]
189
- //
190
- // then we need to make sure we don't accidentally prepend the operator
191
- // before the comment(s).
192
- //
193
- // In prettier >= 2.3.0, the comments are printed as an array before the
194
- // content. I don't love this kind of reflection, but it's the simplest way
195
- // at the moment to get this right.
196
- if (Array.isArray(doc[0])) {
197
- docs.push(doc[0].concat(concat(["*", doc[1]]), doc.slice(2)));
198
- return;
199
- }
200
-
201
- // In prettier < 2.3.0, the comments are printed as part of a concat, so
202
- // we can reflect on how many leading comments there are to determine which
203
- // doc node we should modify.
204
- const index = argsNode.comments.filter(({ leading }) => leading).length;
205
- doc.parts[index] = concat(["*", doc.parts[index]]);
206
- docs = docs.concat(doc);
207
- }, "body");
208
-
209
- return docs;
210
- }
211
-
212
- function printBlockArg(path, opts, print) {
213
- return concat(["&", path.call(print, "body", 0)]);
214
- }
215
-
216
- module.exports = {
217
- arg_paren: printArgParen,
218
- args: printArgs,
219
- args_add_block: printArgsAddBlock,
220
- args_add_star: printArgsAddStar,
221
- blockarg: printBlockArg
222
- };
@@ -1,162 +0,0 @@
1
- const {
2
- concat,
3
- group,
4
- ifBreak,
5
- indent,
6
- join,
7
- line,
8
- softline
9
- } = require("../../prettier");
10
- const { getTrailingComma, printEmptyCollection } = require("../../utils");
11
-
12
- // Checks that every argument within this args node is a string_literal node
13
- // that has no spaces or interpolations. This means we're dealing with an array
14
- // that looks something like:
15
- //
16
- // ['a', 'b', 'c']
17
- //
18
- function isStringArray(args) {
19
- return (
20
- args.body.length > 1 &&
21
- args.body.every((arg) => {
22
- // We want to verify that every node inside of this array is a string
23
- // literal. We also want to make sure none of them have comments attached.
24
- if (arg.type !== "string_literal" || arg.comments) {
25
- return false;
26
- }
27
-
28
- // If the string has multiple parts (meaning plain string content but also
29
- // interpolated content) then we know it's not a simple string.
30
- if (arg.body.length !== 1) {
31
- return false;
32
- }
33
-
34
- const part = arg.body[0];
35
-
36
- // If the only part of this string is not @tstring_content then it's
37
- // interpolated, so again we can return false.
38
- if (part.type !== "@tstring_content") {
39
- return false;
40
- }
41
-
42
- // Finally, verify that the string doesn't contain a space, an escape
43
- // character, or brackets so that we know it can be put into a string
44
- // literal array.
45
- return !/[\s\\[\]]/.test(part.body);
46
- })
47
- );
48
- }
49
-
50
- // Checks that every argument within this args node is a symbol_literal node (as
51
- // opposed to a dyna_symbol) so it has no interpolation. This means we're
52
- // dealing with an array that looks something like:
53
- //
54
- // [:a, :b, :c]
55
- //
56
- function isSymbolArray(args) {
57
- return (
58
- args.body.length > 1 &&
59
- args.body.every((arg) => arg.type === "symbol_literal" && !arg.comments)
60
- );
61
- }
62
-
63
- // Prints out a word that is a part of a special array literal that accepts
64
- // interpolation. The body is an array of either plain strings or interpolated
65
- // expressions.
66
- function printArrayLiteralWord(path, opts, print) {
67
- return concat(path.map(print, "body"));
68
- }
69
-
70
- // Prints out a special array literal. Accepts the parts of the array literal as
71
- // an argument, where the first element of the parts array is a string that
72
- // contains the special start.
73
- function printArrayLiteral(start, parts) {
74
- return group(
75
- concat([
76
- start,
77
- "[",
78
- indent(concat([softline, join(line, parts)])),
79
- concat([softline, "]"])
80
- ])
81
- );
82
- }
83
-
84
- const arrayLiteralStarts = {
85
- qsymbols: "%i",
86
- qwords: "%w",
87
- symbols: "%I",
88
- words: "%W"
89
- };
90
-
91
- // An array node is any literal array in Ruby. This includes all of the special
92
- // array literals as well as regular arrays. If it is a special array literal
93
- // then it will have one child that represents the special array, otherwise it
94
- // will have one child that contains all of the elements of the array.
95
- function printArray(path, opts, print) {
96
- const array = path.getValue();
97
- const args = array.body[0];
98
-
99
- // If there is no inner arguments node, then we're dealing with an empty
100
- // array, so we can go ahead and return.
101
- if (args === null) {
102
- return printEmptyCollection(path, opts, "[", "]");
103
- }
104
-
105
- if (opts.rubyArrayLiteral) {
106
- // If we have an array that contains only simple string literals with no
107
- // spaces or interpolation, then we're going to print a %w array.
108
- if (isStringArray(args)) {
109
- const printString = (stringPath) => stringPath.call(print, "body", 0);
110
- const parts = path.map(printString, "body", 0, "body");
111
-
112
- return printArrayLiteral("%w", parts);
113
- }
114
-
115
- // If we have an array that contains only simple symbol literals with no
116
- // interpolation, then we're going to print a %i array.
117
- if (isSymbolArray(args)) {
118
- const printSymbol = (symbolPath) => symbolPath.call(print, "body", 0);
119
- const parts = path.map(printSymbol, "body", 0, "body");
120
-
121
- return printArrayLiteral("%i", parts);
122
- }
123
- }
124
-
125
- // If we don't have a regular args node at this point then we have a special
126
- // array literal. In that case we're going to print out the body (which will
127
- // return to us an array with the first one being the start of the array) and
128
- // send that over to the printArrayLiteral function.
129
- if (!["args", "args_add_star"].includes(args.type)) {
130
- return path.call(
131
- (arrayPath) =>
132
- printArrayLiteral(
133
- arrayLiteralStarts[arrayPath.getValue().type],
134
- arrayPath.map(print, "body")
135
- ),
136
- "body",
137
- 0
138
- );
139
- }
140
-
141
- // Here we have a normal array of any type of object with no special literal
142
- // types or anything.
143
- return group(
144
- concat([
145
- "[",
146
- indent(
147
- concat([
148
- softline,
149
- join(concat([",", line]), path.call(print, "body", 0)),
150
- getTrailingComma(opts) ? ifBreak(",", "") : ""
151
- ])
152
- ),
153
- softline,
154
- "]"
155
- ])
156
- );
157
- }
158
-
159
- module.exports = {
160
- array: printArray,
161
- word: printArrayLiteralWord
162
- };
@@ -1,47 +0,0 @@
1
- const { concat, group, indent, join, line } = require("../../prettier");
2
- const { skipAssignIndent } = require("../../utils");
3
-
4
- function printAssign(path, opts, print) {
5
- const [_targetNode, valueNode] = path.getValue().body;
6
- const [targetDoc, valueDoc] = path.map(print, "body");
7
-
8
- let rightSideDoc = valueDoc;
9
-
10
- // If the right side of this assignment is a multiple assignment, then we need
11
- // to join it together with commas.
12
- if (["mrhs_add_star", "mrhs_new_from_args"].includes(valueNode.type)) {
13
- rightSideDoc = group(join(concat([",", line]), valueDoc));
14
- }
15
-
16
- if (skipAssignIndent(valueNode)) {
17
- return group(concat([targetDoc, " = ", rightSideDoc]));
18
- }
19
-
20
- return group(concat([targetDoc, " =", indent(concat([line, rightSideDoc]))]));
21
- }
22
-
23
- function printOpAssign(path, opts, print) {
24
- return group(
25
- concat([
26
- path.call(print, "body", 0),
27
- " ",
28
- path.call(print, "body", 1),
29
- indent(concat([line, path.call(print, "body", 2)]))
30
- ])
31
- );
32
- }
33
-
34
- function printVarField(path, opts, print) {
35
- return path.getValue().body ? path.call(print, "body", 0) : "";
36
- }
37
-
38
- function printVarRef(path, opts, print) {
39
- return path.call(print, "body", 0);
40
- }
41
-
42
- module.exports = {
43
- assign: printAssign,
44
- opassign: printOpAssign,
45
- var_field: printVarField,
46
- var_ref: printVarRef
47
- };