UNPKG

prettierx

Version:

prettierX - a less opinionated fork of the Prettier code formatter

195 lines (167 loc) 5.55 kB
"use strict"; const { printDanglingComments } = require("../../main/comments"); const { builders: { line, softline, hardline, group, indent, ifBreak, fill }, } = require("../../document"); const { getLast, hasNewline } = require("../../common/util"); const { shouldPrintComma, hasComment, CommentCheckFlags, isNextLineEmpty, isNumericLiteral, isSignedNumericLiteral, } = require("../utils"); const { locStart } = require("../loc"); const { printOptionalToken, printTypeAnnotation } = require("./misc"); /** @typedef {import("../../document").Doc} Doc */ function printArray(path, options, print) { const node = path.getValue(); /** @type{Doc[]} */ const parts = []; const openBracket = node.type === "TupleExpression" ? "#[" : "["; const closeBracket = "]"; if (node.elements.length === 0) { if (!hasComment(node, CommentCheckFlags.Dangling)) { parts.push(openBracket, closeBracket); } else { parts.push( group([ openBracket, printDanglingComments(path, options), softline, closeBracket, ]) ); } } else { const lastElem = getLast(node.elements); const canHaveTrailingComma = !(lastElem && lastElem.type === "RestElement"); // JavaScript allows you to have empty elements in an array which // changes its length based on the number of commas. The algorithm // is that if the last argument is null, we need to force insert // a comma to ensure JavaScript recognizes it. // [,].length === 1 // [1,].length === 1 // [1,,].length === 2 // // Note that getLast returns null if the array is empty, but // we already check for an empty array just above so we are safe const needsForcedTrailingComma = lastElem === null; const groupId = Symbol("array"); const shouldBreak = !options.__inJestEach && node.elements.length > 1 && node.elements.every((element, i, elements) => { const elementType = element && element.type; if ( elementType !== "ArrayExpression" && elementType !== "ObjectExpression" ) { return false; } const nextElement = elements[i + 1]; if (nextElement && elementType !== nextElement.type) { return false; } const itemsKey = elementType === "ArrayExpression" ? "elements" : "properties"; return element[itemsKey] && element[itemsKey].length > 1; }); const shouldUseConciseFormatting = isConciselyPrintedArray(node, options); const trailingComma = !canHaveTrailingComma ? "" : needsForcedTrailingComma ? "," : !shouldPrintComma(options) ? "" : shouldUseConciseFormatting ? ifBreak(",", "", { groupId }) : ifBreak(","); // [prettierx] --array-bracket-spacing option support (...) parts.push( group( // [prettierx] --array-bracket-spacing option support (...) [ openBracket, // [prettierx] --array-bracket-spacing option support (...) indent([ // [prettierx] --array-bracket-spacing option support (...) options.arrayBracketSpacing ? line : softline, shouldUseConciseFormatting ? printArrayItemsConcisely(path, options, print, trailingComma) : [ printArrayItems(path, options, "elements", print), trailingComma, ], printDanglingComments(path, options, /* sameIndent */ true), ]), // [prettierx] --array-bracket-spacing option support (...) options.arrayBracketSpacing ? line : softline, closeBracket, ], { shouldBreak, id: groupId } ) ); } parts.push( printOptionalToken(path), printTypeAnnotation(path, options, print) ); return parts; } function isConciselyPrintedArray(node, options) { return ( node.elements.length > 1 && node.elements.every( (element) => element && (isNumericLiteral(element) || (isSignedNumericLiteral(element) && !hasComment(element.argument))) && !hasComment( element, CommentCheckFlags.Trailing | CommentCheckFlags.Line, (comment) => !hasNewline(options.originalText, locStart(comment), { backwards: true, }) ) ) ); } function printArrayItems(path, options, printPath, print) { const printedElements = []; let separatorParts = []; path.each((childPath) => { printedElements.push(separatorParts, group(print())); separatorParts = [",", line]; if ( childPath.getValue() && isNextLineEmpty(childPath.getValue(), options) ) { separatorParts.push(softline); } }, printPath); return printedElements; } function printArrayItemsConcisely(path, options, print, trailingComma) { const parts = []; path.each((childPath, i, elements) => { const isLast = i === elements.length - 1; parts.push([print(), isLast ? trailingComma : ","]); if (!isLast) { parts.push( isNextLineEmpty(childPath.getValue(), options) ? [hardline, hardline] : hasComment( elements[i + 1], CommentCheckFlags.Leading | CommentCheckFlags.Line ) ? hardline : line ); } }, "elements"); return fill(parts); } module.exports = { printArray, printArrayItems, isConciselyPrintedArray };