prettier-plugin-multiline-arrays-2 1.0.0 → 5.0.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 (62) hide show
  1. package/README.md +5 -19
  2. package/dist/augments/array.d.ts +8 -2
  3. package/dist/augments/array.js +11 -5
  4. package/dist/augments/doc.d.ts +2 -2
  5. package/dist/augments/doc.js +12 -9
  6. package/dist/augments/string.js +1 -1
  7. package/dist/index.d.ts +1 -1
  8. package/dist/index.js +42 -20
  9. package/dist/options.d.ts +6 -9
  10. package/dist/options.js +20 -25
  11. package/dist/plugin-marker.js +1 -1
  12. package/dist/preprocessing.d.ts +1 -1
  13. package/dist/preprocessing.js +60 -30
  14. package/dist/printer/child-docs.d.ts +9 -7
  15. package/dist/printer/child-docs.js +89 -63
  16. package/dist/printer/comment-triggers.d.ts +5 -7
  17. package/dist/printer/comment-triggers.js +104 -134
  18. package/dist/printer/comments.d.ts +1 -1
  19. package/dist/printer/comments.js +15 -16
  20. package/dist/printer/insert-new-lines.d.ts +10 -6
  21. package/dist/printer/insert-new-lines.js +260 -277
  22. package/dist/printer/leading-new-line.d.ts +2 -2
  23. package/dist/printer/leading-new-line.js +2 -1
  24. package/dist/printer/multiline-array-printer.js +4 -2
  25. package/dist/printer/original-printer.js +6 -4
  26. package/dist/printer/supported-node-types.d.ts +1 -1
  27. package/dist/printer/supported-node-types.js +6 -5
  28. package/dist/printer/trailing-comma.d.ts +1 -1
  29. package/dist/printer/trailing-comma.js +1 -1
  30. package/package.json +56 -29
  31. package/dist/augments/array.test.d.ts +0 -1
  32. package/dist/augments/array.test.js +0 -34
  33. package/dist/options.test.d.ts +0 -1
  34. package/dist/options.test.js +0 -48
  35. package/dist/printer/insert-new-lines.test.d.ts +0 -1
  36. package/dist/printer/insert-new-lines.test.js +0 -36
  37. package/dist/readme-examples/formatted-with-comments.example.d.ts +0 -3
  38. package/dist/readme-examples/formatted-with-comments.example.js +0 -16
  39. package/dist/readme-examples/formatted.example.d.ts +0 -2
  40. package/dist/readme-examples/formatted.example.js +0 -12
  41. package/dist/readme-examples/not-formatted.example.d.ts +0 -2
  42. package/dist/readme-examples/not-formatted.example.js +0 -6
  43. package/dist/readme-examples/prettier-options.example.d.ts +0 -4
  44. package/dist/readme-examples/prettier-options.example.js +0 -5
  45. package/dist/test/babel-ts.test.d.ts +0 -1
  46. package/dist/test/babel-ts.test.js +0 -10
  47. package/dist/test/javascript.test.d.ts +0 -1
  48. package/dist/test/javascript.test.js +0 -702
  49. package/dist/test/json.test.d.ts +0 -1
  50. package/dist/test/json.test.js +0 -403
  51. package/dist/test/json5.test.d.ts +0 -1
  52. package/dist/test/json5.test.js +0 -210
  53. package/dist/test/prettier-config.d.ts +0 -2
  54. package/dist/test/prettier-config.js +0 -12
  55. package/dist/test/prettier-versions.mock.script.d.ts +0 -1
  56. package/dist/test/prettier-versions.mock.script.js +0 -123
  57. package/dist/test/run-tests.mock.d.ts +0 -17
  58. package/dist/test/run-tests.mock.js +0 -95
  59. package/dist/test/typescript-tests.mock.d.ts +0 -2
  60. package/dist/test/typescript-tests.mock.js +0 -1575
  61. package/dist/test/typescript.test.d.ts +0 -1
  62. package/dist/test/typescript.test.js +0 -10
@@ -1,7 +1,7 @@
1
1
  import { getObjectTypedKeys, stringify, } from "@augment-vir/common";
2
- import { doc } from "prettier";
2
+ import * as prettier from "prettier";
3
+ import { arrayFirst, arrayIncludes, arrayJoin, assertDefined, isEmpty, objectHasIn, safeCastTo, stringSplit, } from "ts-extras";
3
4
  import { isDocCommand } from "../augments/doc.js";
4
- import {} from "../options.js";
5
5
  import { walkDoc } from "./child-docs.js";
6
6
  import { getCommentTriggers, parseNextLineCounts, } from "./comment-triggers.js";
7
7
  import { containsLeadingNewline } from "./leading-new-line.js";
@@ -19,14 +19,14 @@ const found = 'Found "[" but:';
19
19
  function isMatchingNestingSyntaxClose({ maybeClose, openingSyntax, }) {
20
20
  const closingSyntax = matchingNestingSyntaxClose[openingSyntax];
21
21
  const firstCharacter = maybeClose.trimStart()[0];
22
- return !!firstCharacter && closingSyntax === firstCharacter;
22
+ return Boolean(firstCharacter) && closingSyntax === firstCharacter;
23
23
  }
24
24
  function extractIndentDoc({ maybeIndentDoc, }) {
25
25
  if (isDocCommand(maybeIndentDoc) && maybeIndentDoc.type === "indent") {
26
26
  return maybeIndentDoc;
27
27
  }
28
- else if (Array.isArray(maybeIndentDoc)) {
29
- const firstDoc = maybeIndentDoc[0];
28
+ if (Array.isArray(maybeIndentDoc)) {
29
+ const firstDoc = arrayFirst(maybeIndentDoc);
30
30
  if (isDocCommand(firstDoc) && firstDoc.type === "indent") {
31
31
  return firstDoc;
32
32
  }
@@ -46,19 +46,12 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
46
46
  startDoc: inputDoc,
47
47
  debug,
48
48
  callback: (currentDoc, parentDocs, childIndex) => {
49
- const currentParent = parentDocs[0];
49
+ const currentParent = arrayFirst(parentDocs);
50
50
  const parentDoc = currentParent?.parent;
51
51
  if (typeof currentDoc === "string" && currentDoc.trim() === "[") {
52
52
  if (hasProcessedOwnArray) {
53
53
  return true;
54
54
  }
55
- const undoMutations = [];
56
- let finalLineBreakExists = false;
57
- function undoAllMutations() {
58
- undoMutations.toReversed().forEach((undoMutation) => {
59
- undoMutation();
60
- });
61
- }
62
55
  if (!Array.isArray(parentDoc)) {
63
56
  if (debug) {
64
57
  console.error({
@@ -86,6 +79,12 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
86
79
  */
87
80
  return true;
88
81
  }
82
+ const undoMutations = [];
83
+ function undoAllMutations() {
84
+ for (const undoMutation of undoMutations.toReversed()) {
85
+ undoMutation();
86
+ }
87
+ }
89
88
  const maybeBreak = parentDoc[childIndex + 2];
90
89
  if (isDocCommand(maybeBreak) &&
91
90
  maybeBreak.type === "if-break") {
@@ -95,9 +94,7 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
95
94
  parentDoc[childIndex + 2] = maybeBreak.breakContents;
96
95
  }
97
96
  const indentIndex = childIndex + 1;
98
- const maybeBracketSibling = parentDoc[indentIndex] === ""
99
- ? parentDoc[indentIndex + 1]
100
- : parentDoc[indentIndex];
97
+ const maybeBracketSibling = parentDoc[indentIndex + (parentDoc[indentIndex] === "" ? 1 : 0)];
101
98
  const bracketSibling = extractIndentDoc({
102
99
  maybeIndentDoc: maybeBracketSibling,
103
100
  });
@@ -109,9 +106,12 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
109
106
  if (maybeBracketSibling === "]") {
110
107
  return false;
111
108
  }
112
- else if (!bracketSibling) {
109
+ if (!bracketSibling) {
113
110
  throw new Error(`${found} its sibling was not an indent Doc.: ${stringify(maybeBracketSibling)}`);
114
111
  }
112
+ const finalLineBreak = {
113
+ exists: false,
114
+ };
115
115
  const indentContents = bracketSibling.contents;
116
116
  if (debug) {
117
117
  console.info({
@@ -121,13 +121,13 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
121
121
  if (!Array.isArray(indentContents)) {
122
122
  throw new TypeError(`${found} indent didn't have array contents.`);
123
123
  }
124
- else if (indentContents.length < 2) {
124
+ if (indentContents.length < 2) {
125
125
  if (debug) {
126
126
  console.error(stringify(indentContents));
127
127
  }
128
128
  throw new Error(`${found} indent contents did not have at least 2 children`);
129
129
  }
130
- const startingLine = indentContents[0];
130
+ const startingLine = arrayFirst(indentContents);
131
131
  if (debug) {
132
132
  console.info({
133
133
  firstIndentContentsChild: startingLine,
@@ -139,9 +139,7 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
139
139
  undoAllMutations();
140
140
  return false;
141
141
  }
142
- else {
143
- throw new TypeError(`${found} first indent child was not a line.`);
144
- }
142
+ throw new TypeError(`${found} first indent child was not a line.`);
145
143
  }
146
144
  indentContents[0] = "";
147
145
  undoMutations.push(() => {
@@ -151,7 +149,9 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
151
149
  if (debug) {
152
150
  console.info({
153
151
  secondIndentContentsChild: indentedContent,
154
- itsFirstChild: indentedContent[0],
152
+ itsFirstChild: Array.isArray(indentedContent)
153
+ ? arrayFirst(indentedContent)
154
+ : undefined,
155
155
  });
156
156
  }
157
157
  if (!indentedContent) {
@@ -161,264 +161,249 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
161
161
  });
162
162
  throw new Error(`${found} second indent child is not a fill.`);
163
163
  }
164
- else if (!Array.isArray(indentedContent) &&
165
- !(isDocCommand(indentedContent) &&
166
- indentedContent.type === "fill")) {
164
+ if (!Array.isArray(indentedContent) &&
165
+ (!isDocCommand(indentedContent) ||
166
+ indentedContent.type !== "fill")) {
167
167
  console.error("second indent child (indentCode) is not a fill doc or an array:", {
168
168
  indentContents,
169
169
  indentCode: indentedContent,
170
170
  });
171
171
  throw new Error(`${found} second indent child is not a fill doc or an array.`);
172
172
  }
173
- else if (Array.isArray(indentedContent)
174
- ? indentedContent.length === 0
175
- : indentedContent.parts.length === 0) {
173
+ if (isEmpty(Array.isArray(indentedContent)
174
+ ? indentedContent
175
+ : indentedContent.parts)) {
176
176
  throw new Error(`${found} indentedContent has no length.`);
177
177
  }
178
- // lineIndex is 0 indexed
178
+ // LineIndex is 0 indexed
179
179
  let lineIndex = 0;
180
- // columnCount is 1 indexed
180
+ // ColumnCount is 1 indexed
181
181
  let columnCount = 1;
182
182
  if (debug) {
183
183
  console.info(">>>>>>>>>>>>>> Walking children for commas");
184
184
  }
185
185
  let arrayChildCount = 0;
186
- let forceFinalLineBreakExists = false;
187
- if (!finalLineBreakExists) {
188
- walkDoc({
189
- startDoc: indentedContent,
190
- debug,
191
- callback: (currentDoc, commaParents, commaChildIndex) => {
192
- finalLineBreakExists = false;
193
- const innerCurrentParent = commaParents[0];
194
- const innerCurrentParentDoc = innerCurrentParent?.parent;
195
- if (isDocCommand(currentDoc) &&
196
- currentDoc.type === "if-break" &&
197
- currentDoc.breakContents === ",") {
186
+ walkDoc({
187
+ startDoc: indentedContent,
188
+ debug,
189
+ callback: (commaDoc, commaParents, commaChildIndex) => {
190
+ const innerCurrentParent = arrayFirst(commaParents);
191
+ const innerCurrentParentDoc = innerCurrentParent?.parent;
192
+ if (isDocCommand(commaDoc) &&
193
+ commaDoc.type === "if-break" &&
194
+ commaDoc.breakContents === ",") {
195
+ /**
196
+ * Only treat a trailing-comma if-break (whose
197
+ * `breakContents` is `,`) as the array's final
198
+ * line-break marker. Other if-break commands, like
199
+ * the leading pipe Prettier emits when a union type
200
+ * wraps, appear inside element docs and must not be
201
+ * forced open, otherwise the inner union breaks
202
+ * unnecessarily.
203
+ */
204
+ if (debug) {
205
+ console.info("found final line break inside of if-break");
206
+ }
207
+ finalLineBreak.exists = true;
208
+ if (!innerCurrentParentDoc) {
209
+ throw new Error("Found if-break without a parent");
210
+ }
211
+ if (!Array.isArray(innerCurrentParentDoc)) {
212
+ throw new TypeError("if-break parent is not an array");
213
+ }
214
+ assertDefined(commaChildIndex);
215
+ innerCurrentParentDoc[commaChildIndex] =
216
+ commaDoc.breakContents;
217
+ innerCurrentParentDoc.splice(commaChildIndex + 1, 0, prettier.doc.builders.breakParent);
218
+ undoMutations.push(() => {
219
+ innerCurrentParentDoc.splice(commaChildIndex + 1, 1);
220
+ innerCurrentParentDoc[commaChildIndex] =
221
+ commaDoc;
222
+ });
223
+ }
224
+ else if (typeof commaDoc === "string") {
225
+ if (!innerCurrentParentDoc) {
226
+ console.error({
227
+ innerParentDoc: innerCurrentParentDoc,
228
+ });
229
+ throw new Error("Found string but innerParentDoc is not defined.");
230
+ }
231
+ if (commaDoc === "<" &&
232
+ Array.isArray(innerCurrentParentDoc) &&
233
+ commaChildIndex != undefined &&
234
+ arrayIncludes(innerCurrentParentDoc.slice(commaChildIndex + 1), ">")) {
198
235
  /**
199
- * Only treat a trailing-comma if-break (whose
200
- * `breakContents` is `,`) as the array's final
201
- * line-break marker. Other if-break commands —
202
- * like the leading `| ` Prettier emits when a
203
- * union type wraps appear inside element docs
204
- * (e.g. `[A | B | C]`) and must not be forced
205
- * open, otherwise the inner union breaks
206
- * unnecessarily.
236
+ * A paired `<...>` in the same Doc array is a
237
+ * generic type-argument group (e.g.
238
+ * `Omit<MyType, 'field'>`). Skip walking its
239
+ * siblings so commas inside the generic aren't
240
+ * mistaken for array-element separators. A lone
241
+ * `<` or `>` without a match in the same array
242
+ * is a comparison operator and handled by the
243
+ * default walk.
207
244
  */
208
- if (debug) {
209
- console.info("found final line break inside of if-break");
210
- }
211
- finalLineBreakExists = true;
212
- if (!innerCurrentParentDoc) {
213
- throw new Error("Found if-break without a parent");
214
- }
215
- else if (!Array.isArray(innerCurrentParentDoc)) {
216
- throw new TypeError("if-break parent is not an array");
245
+ return false;
246
+ }
247
+ if (commaDoc &&
248
+ nestingSyntaxOpen.includes(commaDoc)) {
249
+ if (!Array.isArray(innerCurrentParentDoc)) {
250
+ throw new TypeError("Found opening syntax but parent is not an array.");
217
251
  }
218
- else if (commaChildIndex == undefined) {
219
- throw new Error("if-break child index is undefined");
252
+ const closingIndex = innerCurrentParentDoc.findIndex((sibling) => typeof sibling === "string" &&
253
+ sibling &&
254
+ isMatchingNestingSyntaxClose({
255
+ maybeClose: sibling,
256
+ openingSyntax: commaDoc,
257
+ }));
258
+ if (closingIndex === -1) {
259
+ throw new Error(`Could not find closing match for ${commaDoc}`);
220
260
  }
221
- innerCurrentParentDoc[commaChildIndex] =
222
- currentDoc.breakContents;
223
- innerCurrentParentDoc.splice(commaChildIndex + 1, 0, doc.builders.breakParent);
224
- undoMutations.push(() => {
225
- innerCurrentParentDoc.splice(commaChildIndex + 1, 1);
226
- innerCurrentParentDoc[commaChildIndex] =
227
- currentDoc;
228
- });
261
+ return false;
262
+ }
263
+ if (commaDoc &&
264
+ nestingSyntaxClose.includes(commaDoc)) {
265
+ throw new Error("Found closing syntax which shouldn't be walked");
229
266
  }
230
- else if (typeof currentDoc === "string") {
231
- if (!innerCurrentParentDoc) {
267
+ if (commaDoc === ",") {
268
+ if (debug) {
269
+ console.info({
270
+ foundCommaIn: innerCurrentParentDoc,
271
+ });
272
+ }
273
+ if (!Array.isArray(innerCurrentParentDoc)) {
232
274
  console.error({
233
275
  innerParentDoc: innerCurrentParentDoc,
234
276
  });
235
- throw new Error("Found string but innerParentDoc is not defined.");
236
- }
237
- else if (currentDoc === "<" &&
238
- Array.isArray(innerCurrentParentDoc) &&
239
- commaChildIndex != undefined &&
240
- innerCurrentParentDoc
241
- .slice(commaChildIndex + 1)
242
- .includes(">")) {
243
- /**
244
- * A paired `<...>` in the same Doc array is
245
- * a generic type-argument group (e.g.
246
- * `Omit<MyType, 'field'>`). Skip walking
247
- * its siblings so commas inside the generic
248
- * aren't mistaken for array-element
249
- * separators. A lone `<` or `>` without a
250
- * match in the same array is a comparison
251
- * operator and handled by the default
252
- * walk.
253
- */
254
- return false;
277
+ throw new Error("Found comma but innerParentDoc is not an array.");
255
278
  }
256
- else if (currentDoc &&
257
- nestingSyntaxOpen.includes(currentDoc)) {
258
- if (!Array.isArray(innerCurrentParentDoc)) {
259
- throw new TypeError("Found opening syntax but parent is not an array.");
260
- }
261
- const closingIndex = innerCurrentParentDoc.findIndex((sibling) => typeof sibling === "string" &&
262
- sibling &&
263
- isMatchingNestingSyntaxClose({
264
- maybeClose: sibling,
265
- openingSyntax: currentDoc,
266
- }));
267
- if (closingIndex < 0) {
268
- throw new Error(`Could not find closing match for ${currentDoc}`);
279
+ assertDefined(commaChildIndex);
280
+ let siblingIndex = commaChildIndex + 1;
281
+ let parentToMutate = innerCurrentParentDoc;
282
+ if (commaChildIndex ===
283
+ innerCurrentParentDoc.length - 1) {
284
+ const commaGrandParent = commaParents[1];
285
+ assertDefined(commaGrandParent);
286
+ assertDefined(commaGrandParent.childIndexInThisParent);
287
+ if (!Array.isArray(commaGrandParent.parent)) {
288
+ throw new TypeError("Comma group grandparent is not an array.");
269
289
  }
270
- return false;
290
+ siblingIndex =
291
+ commaGrandParent.childIndexInThisParent +
292
+ 1;
293
+ parentToMutate = commaGrandParent.parent;
294
+ }
295
+ if (debug) {
296
+ console.info({
297
+ commaParentDoc: innerCurrentParentDoc,
298
+ parentToMutate,
299
+ siblingIndex,
300
+ });
271
301
  }
272
- else if (currentDoc &&
273
- nestingSyntaxClose.includes(currentDoc)) {
274
- throw new Error("Found closing syntax which shouldn't be walked");
302
+ let maybeCommaSibling = parentToMutate[siblingIndex];
303
+ if (debug) {
304
+ console.info(`Trying to find comma sibling at index ${siblingIndex}`, stringify({
305
+ parentToMutate,
306
+ maybeCommaSibling,
307
+ }));
308
+ }
309
+ function isCommaSibling(maybe) {
310
+ const firstMaybe = Array.isArray(maybe)
311
+ ? arrayFirst(maybe)
312
+ : undefined;
313
+ return ((isDocCommand(maybe) &&
314
+ maybe.type === "line") ||
315
+ (Array.isArray(maybe) &&
316
+ isDocCommand(firstMaybe) &&
317
+ firstMaybe.type === "line"));
275
318
  }
276
- else if (currentDoc === ",") {
319
+ while (!isCommaSibling(maybeCommaSibling) &&
320
+ siblingIndex < parentToMutate.length) {
321
+ siblingIndex += 1;
322
+ maybeCommaSibling =
323
+ parentToMutate[siblingIndex];
277
324
  if (debug) {
278
- console.info({
279
- foundCommaIn: innerCurrentParentDoc,
280
- });
281
- }
282
- if (!Array.isArray(innerCurrentParentDoc)) {
283
- console.error({
284
- innerParentDoc: innerCurrentParentDoc,
285
- });
286
- throw new Error("Found comma but innerParentDoc is not an array.");
287
- }
288
- else if (commaChildIndex == undefined) {
289
- throw new Error("Found comma but childIndex is undefined.");
290
- }
291
- let siblingIndex = commaChildIndex + 1;
292
- let parentToMutate = innerCurrentParentDoc;
293
- if (commaChildIndex ===
294
- innerCurrentParentDoc.length - 1) {
295
- const commaGrandParent = commaParents[1];
296
- if (commaGrandParent == undefined) {
297
- throw new Error("Could not find grandparent of comma group.");
298
- }
299
- else if (commaGrandParent.childIndexInThisParent ==
300
- undefined) {
301
- throw new Error("Could not find index of comma group parent");
302
- }
303
- else if (!Array.isArray(commaGrandParent.parent)) {
304
- throw new TypeError("Comma group grandparent is not an array.");
305
- }
306
- siblingIndex =
307
- commaGrandParent.childIndexInThisParent +
308
- 1;
309
- parentToMutate =
310
- commaGrandParent.parent;
325
+ console.info(`Trying to find comma sibling at index ${siblingIndex}`, parentToMutate, maybeCommaSibling);
311
326
  }
327
+ }
328
+ if (debug) {
329
+ console.info(`Found comma sibling at index ${siblingIndex}`, parentToMutate, maybeCommaSibling);
330
+ }
331
+ if (!isCommaSibling(maybeCommaSibling)) {
332
+ throw new Error(`Found comma but its following sibling is not a line: ${stringify(maybeCommaSibling)}`);
333
+ }
334
+ const commaSibling = maybeCommaSibling;
335
+ const currentLineCountIndex = lineIndex % lineCounts.length;
336
+ const currentLineCount = lineCounts.length > 0
337
+ ? lineCounts[currentLineCountIndex]
338
+ : undefined;
339
+ const hasCurrentLineCount = currentLineCount != undefined &&
340
+ currentLineCount !== 0;
341
+ arrayChildCount += 1;
342
+ if ((hasCurrentLineCount &&
343
+ columnCount === currentLineCount) ||
344
+ !hasCurrentLineCount) {
345
+ // If we're on the last element of the line then increment to the next line
346
+ lineIndex += 1;
347
+ columnCount = 1;
348
+ /**
349
+ * Don't use doc.builders.hardline here. It
350
+ * causes "invalid size error" which I don't
351
+ * understand and which has no other useful
352
+ * information or stack trace.
353
+ */
312
354
  if (debug) {
313
355
  console.info({
314
- commaParentDoc: innerCurrentParentDoc,
315
- parentToMutate,
316
- siblingIndex,
356
+ breakingAfter: parentToMutate[siblingIndex - 1],
317
357
  });
318
358
  }
319
- let maybeCommaSibling = parentToMutate[siblingIndex];
320
- if (debug) {
321
- console.info(`Trying to find comma sibling at index ${siblingIndex}`, stringify({
322
- parentToMutate,
323
- maybeCommaSibling,
324
- }));
325
- }
326
- function isCommaSibling(maybe) {
327
- return ((isDocCommand(maybe) &&
328
- maybe.type === "line") ||
329
- (Array.isArray(maybe) &&
330
- isDocCommand(maybe[0]) &&
331
- maybe[0].type === "line"));
332
- }
333
- while (!isCommaSibling(maybeCommaSibling) &&
334
- siblingIndex < parentToMutate.length) {
335
- siblingIndex++;
336
- maybeCommaSibling =
337
- parentToMutate[siblingIndex];
338
- if (debug) {
339
- console.info(`Trying to find comma sibling at index ${siblingIndex}`, parentToMutate, maybeCommaSibling);
340
- }
341
- }
342
- if (debug) {
343
- console.info(`Found comma sibling at index ${siblingIndex}`, parentToMutate, maybeCommaSibling);
344
- }
345
- if (!isCommaSibling(maybeCommaSibling)) {
346
- throw new Error(`Found comma but its following sibling is not a line: ${stringify(maybeCommaSibling)}`);
347
- }
348
- const commaSibling = maybeCommaSibling;
349
- const currentLineCountIndex = lineIndex % lineCounts.length;
350
- const currentLineCount = lineCounts.length
351
- ? lineCounts[currentLineCountIndex]
352
- : undefined;
353
- arrayChildCount++;
354
- if ((currentLineCount &&
355
- columnCount === currentLineCount) ||
356
- !currentLineCount) {
357
- // if we're on the last element of the line then increment to the next line
358
- lineIndex++;
359
- columnCount = 1;
360
- /**
361
- * Don't use doc.builders.hardline here.
362
- * It causes "invalid size error" which
363
- * I don't understand and which has no
364
- * other useful information or stack
365
- * trace.
366
- */
367
- if (debug) {
368
- console.info({
369
- breakingAfter: parentToMutate[siblingIndex - 1],
370
- });
371
- }
372
- parentToMutate[siblingIndex] =
373
- doc.builders.hardlineWithoutBreakParent;
374
- }
375
- else {
376
- parentToMutate[siblingIndex] = " ";
377
- columnCount++;
378
- }
379
- undoMutations.push(() => {
380
- parentToMutate[siblingIndex] =
381
- commaSibling;
382
- });
359
+ parentToMutate[siblingIndex] =
360
+ prettier.doc.builders.hardlineWithoutBreakParent;
361
+ }
362
+ else {
363
+ parentToMutate[siblingIndex] = " ";
364
+ columnCount += 1;
383
365
  }
366
+ undoMutations.push(() => {
367
+ parentToMutate[siblingIndex] = commaSibling;
368
+ });
369
+ }
370
+ }
371
+ else if (Array.isArray(currentDoc)) {
372
+ const firstPart = safeCastTo(arrayFirst(currentDoc));
373
+ const secondPart = safeCastTo(currentDoc[1]);
374
+ if (debug) {
375
+ console.info("got concat child doc");
376
+ console.info(currentDoc, {
377
+ firstPart,
378
+ secondPart,
379
+ });
380
+ console.info(isDocCommand(firstPart), isDocCommand(secondPart), isDocCommand(firstPart) &&
381
+ firstPart.type === "line", isDocCommand(firstPart) &&
382
+ objectHasIn(firstPart, "hard") &&
383
+ firstPart.hard === true, isDocCommand(secondPart) &&
384
+ secondPart.type === "break-parent");
384
385
  }
385
- else if (Array.isArray(currentDoc)) {
386
- const firstPart = currentDoc[0];
387
- const secondPart = currentDoc[1];
386
+ if (isDocCommand(firstPart) &&
387
+ isDocCommand(secondPart) &&
388
+ firstPart.type === "line" &&
389
+ firstPart.hard &&
390
+ secondPart.type === "break-parent") {
388
391
  if (debug) {
389
- console.info("got concat child doc");
390
- console.info(currentDoc, {
391
- firstPart,
392
- secondPart,
393
- });
394
- console.info(isDocCommand(firstPart), isDocCommand(secondPart), firstPart?.type === "line", firstPart?.hard, secondPart?.type ===
395
- "break-parent");
396
- }
397
- if (isDocCommand(firstPart) &&
398
- isDocCommand(secondPart) &&
399
- firstPart.type === "line" &&
400
- firstPart.hard &&
401
- secondPart.type === "break-parent") {
402
- if (debug) {
403
- console.info("concat child was indeed a line break");
404
- }
405
- forceFinalLineBreakExists = true;
406
- return false;
407
- }
408
- else if (debug) {
409
- console.info("concat child doc was not a line break");
392
+ console.info("concat child was indeed a line break");
410
393
  }
394
+ finalLineBreak.exists = true;
395
+ return false;
411
396
  }
412
- return true;
413
- },
414
- });
415
- }
416
- if (forceFinalLineBreakExists) {
417
- finalLineBreakExists = true;
418
- }
419
- if (!finalLineBreakExists) {
397
+ if (debug) {
398
+ console.info("concat child doc was not a line break");
399
+ }
400
+ }
401
+ return true;
402
+ },
403
+ });
404
+ if (!finalLineBreak.exists) {
420
405
  if (debug) {
421
- console.info(`Parsed all array children but finalBreakHappened = ${finalLineBreakExists}`);
406
+ console.info(`Parsed all array children but finalBreakHappened = ${String(finalLineBreak.exists)}`);
422
407
  }
423
408
  const closingBracketIndex = parentDoc.indexOf("]");
424
409
  const preBracketChild = parentDoc[closingBracketIndex - 1];
@@ -429,27 +414,27 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
429
414
  parentDoc.splice(closingBracketIndex - 1, 0, preBracketChild);
430
415
  });
431
416
  }
432
- parentDoc.splice(closingBracketIndex - 1, 0, doc.builders.hardlineWithoutBreakParent);
417
+ parentDoc.splice(closingBracketIndex - 1, 0, prettier.doc.builders.hardlineWithoutBreakParent);
433
418
  undoMutations.push(() => {
434
419
  parentDoc.splice(closingBracketIndex - 1, 1);
435
420
  });
436
421
  }
437
422
  if (Array.isArray(indentedContent)) {
438
423
  const oldIndentContentChild = indentContents[1];
439
- indentContents.splice(1, 1, doc.builders.group([
440
- doc.builders.hardlineWithoutBreakParent,
424
+ assertDefined(oldIndentContentChild);
425
+ indentContents[1] = prettier.doc.builders.group([
426
+ prettier.doc.builders.hardlineWithoutBreakParent,
441
427
  ...indentedContent,
442
- ]));
428
+ ]);
443
429
  undoMutations.push(() => {
444
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
445
430
  indentContents[1] = oldIndentContentChild;
446
431
  });
447
432
  }
448
433
  else {
449
434
  const oldParts = indentedContent.parts;
450
435
  indentedContent.parts = [
451
- doc.builders.group([
452
- doc.builders.hardlineWithoutBreakParent,
436
+ prettier.doc.builders.group([
437
+ prettier.doc.builders.hardlineWithoutBreakParent,
453
438
  ...indentedContent.parts,
454
439
  ]),
455
440
  ];
@@ -458,15 +443,15 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
458
443
  });
459
444
  }
460
445
  if (arrayChildCount < wrapThreshold &&
461
- !lineCounts.length &&
446
+ isEmpty(lineCounts) &&
462
447
  !manualWrap) {
463
448
  undoAllMutations();
464
449
  }
465
450
  hasProcessedOwnArray = true;
466
- // don't walk any deeper
451
+ // Don't walk any deeper
467
452
  return false;
468
453
  }
469
- else if (debug) {
454
+ if (debug) {
470
455
  console.info({
471
456
  ignoring: currentDoc,
472
457
  });
@@ -477,28 +462,28 @@ export function insertLinesIntoArray({ inputDoc, manualWrap, lineCounts, wrapThr
477
462
  if (debug) {
478
463
  console.info("final doc:", stringify(inputDoc));
479
464
  }
480
- // return what is input because we perform mutations on it
465
+ // Return what is input because we perform mutations on it
481
466
  return inputDoc;
482
467
  }
483
468
  function getLatestSetValue(currentLine, triggers) {
484
- const relevantSetLineCountsKey = getObjectTypedKeys(triggers)
485
- .sort()
486
- .reduce((closestKey, currentKey) => {
487
- if (Number(currentKey) < currentLine) {
488
- const currentData = triggers[currentKey];
489
- if (currentData && currentData.lineEnd > currentLine) {
490
- return currentKey;
491
- }
469
+ let relevantSetLineCountsKey = "";
470
+ const sortedTriggerKeys = getObjectTypedKeys(triggers).toSorted((firstKey, secondKey) => Number(firstKey) - Number(secondKey));
471
+ for (const currentKey of sortedTriggerKeys) {
472
+ if (Number(currentKey) >= currentLine) {
473
+ continue;
492
474
  }
493
- return closestKey;
494
- }, "");
495
- const relevantSetLineCount = triggers[relevantSetLineCountsKey]?.data;
496
- return relevantSetLineCount;
475
+ const currentData = safeCastTo(triggers[currentKey]);
476
+ if (currentData && currentData.lineEnd > currentLine) {
477
+ relevantSetLineCountsKey = currentKey;
478
+ }
479
+ }
480
+ const relevantTrigger = safeCastTo(triggers[relevantSetLineCountsKey]);
481
+ return relevantTrigger?.data;
497
482
  }
498
483
  export function printWithMultilineArrays({ originalFormattedOutput, path, inputOptions, debug, }) {
499
- const rootNode = path.stack[0];
484
+ const rootNode = arrayFirst(path.stack);
500
485
  if (!rootNode) {
501
- throw new Error(`Could not find valid root node in ${path.stack.map((entry) => entry.type).join(",")}`);
486
+ throw new Error(`Could not find valid root node in ${arrayJoin(path.stack.map((entry) => entry.type), ",")}`);
502
487
  }
503
488
  const node = path.getNode();
504
489
  if (debug) {
@@ -506,12 +491,12 @@ export function printWithMultilineArrays({ originalFormattedOutput, path, inputO
506
491
  }
507
492
  if (node && isArrayLikeNode(node)) {
508
493
  if (!node.loc) {
509
- throw new Error(`Could not find location of node ${node.type}`);
494
+ throw new Error(`Could not find location of node ${String(node.type)}`);
510
495
  }
511
496
  const currentLineNumber = node.loc.start.line;
512
497
  const commentTriggers = getCommentTriggers(rootNode, debug);
513
498
  const originalText = inputOptions.originalText;
514
- const splitOriginalText = originalText.split("\n");
499
+ const splitOriginalText = stringSplit(originalText, "\n");
515
500
  /**
516
501
  * ArrayPattern nodes in Babel-TS include their `typeAnnotation` in the
517
502
  * node's `loc`, so the node's end location can be well past the array's
@@ -519,7 +504,7 @@ export function printWithMultilineArrays({ originalFormattedOutput, path, inputO
519
504
  * end so trailing-comma / leading-newline detection only inspects text
520
505
  * inside the actual array brackets.
521
506
  */
522
- const typeAnnotationStart = node.typeAnnotation?.loc?.start;
507
+ const typeAnnotationStart = safeCastTo(node).typeAnnotation?.loc?.start;
523
508
  const arrayLoc = typeAnnotationStart
524
509
  ? {
525
510
  start: node.loc.start,
@@ -554,7 +539,7 @@ export function printWithMultilineArrays({ originalFormattedOutput, path, inputO
554
539
  : inputOptions.multilineArraysWrapThreshold);
555
540
  const includesCommentTrigger = (commentTriggers.nextWrapThresholds[currentLineNumber] ??
556
541
  relevantSetWrapCommentThreshold) != undefined ||
557
- !!lineCounts.length;
542
+ lineCounts.length > 0;
558
543
  if (debug) {
559
544
  console.info(`======= Starting call to ${insertLinesIntoArray.name}: =======`);
560
545
  console.info({
@@ -564,17 +549,15 @@ export function printWithMultilineArrays({ originalFormattedOutput, path, inputO
564
549
  },
565
550
  });
566
551
  }
567
- const manualWrap = includesCommentTrigger
568
- ? false
569
- : includesTrailingComma || includesLeadingNewline;
570
- const newDoc = insertLinesIntoArray({
552
+ const manualWrap = !includesCommentTrigger &&
553
+ (includesTrailingComma || includesLeadingNewline);
554
+ return insertLinesIntoArray({
571
555
  inputDoc: originalFormattedOutput,
572
556
  manualWrap,
573
557
  lineCounts,
574
558
  wrapThreshold,
575
559
  debug,
576
560
  });
577
- return newDoc;
578
561
  }
579
562
  return originalFormattedOutput;
580
563
  }