import { getNodeRange } from './get-node-range.js' /** * Generates fixes for reordering nodes to their sorted positions. * * Creates text replacement fixes that swap node positions to achieve the * desired sort order. The function handles several important edge cases: * * - Preserves leading comments and documentation * - Maintains file-level block comments for the first node * - Adds safety semicolons when needed to prevent ASI issues * - Respects partition boundaries defined by comments. * * The function iterates through each node position and replaces the original * node text with the text from the node that should be in that position * according to the sorted order. * * @example * * ```ts * // Original order: * const b = 2 * const a = 1 * * // After applying order fixes: * const a = 1 * const b = 2 * ``` * * @example * * ```ts * // Safety semicolon example * // Original: * const b = 2 * const a = 1 // 'a' will move to first position * * // After fix (semicolon added to prevent ASI issues): * const a = 1 * const b = 2 * ``` * * @param params - Parameters for generating order fixes. * @returns Array of ESLint fix operations to reorder nodes. */ function makeOrderFixes({ ignoreFirstNodeHighestBlockComment, sortedNodes, sourceCode, options, fixer, nodes, }) { let fixes = [] for (let max = nodes.length, i = 0; i < max; i++) { let sortingNode = nodes.at(i) let sortedSortingNode = sortedNodes.at(i) let { node } = sortingNode let { addSafetySemicolonWhenInline, node: sortedNode } = sortedSortingNode let isNodeFirstNode = node === nodes.at(0).node let isSortedNodeFirstNode = sortedNode === nodes.at(0).node if (node === sortedNode) { continue } let sortedNodeCode = sourceCode.text.slice( ...getNodeRange({ ignoreHighestBlockComment: ignoreFirstNodeHighestBlockComment && isSortedNodeFirstNode, node: sortedNode, sourceCode, options, }), ) let sortedNodeText = sourceCode.getText(sortedNode) let nextToken = sourceCode .getTokensAfter(node, { includeComments: false, count: 1, }) .at(0) let sortedNextNodeEndsWithSafeCharacter = sortedNodeText.endsWith(';') || sortedNodeText.endsWith(',') let isNextTokenOnSameLineAsNode = nextToken?.loc.start.line === node.loc.end.line let isNextTokenSafeCharacter = nextToken?.value === ';' || nextToken?.value === ',' if ( addSafetySemicolonWhenInline && isNextTokenOnSameLineAsNode && !sortedNextNodeEndsWithSafeCharacter && !isNextTokenSafeCharacter ) { sortedNodeCode += ';' } fixes.push( fixer.replaceTextRange( getNodeRange({ ignoreHighestBlockComment: ignoreFirstNodeHighestBlockComment && isNodeFirstNode, sourceCode, options, node, }), sortedNodeCode, ), ) } return fixes } export { makeOrderFixes }