UNPKG

eslint-plugin-perfectionist

Version:

ESLint plugin for sorting various data such as objects, imports, types, enums, JSX props, etc.

136 lines (135 loc) 4.55 kB
import { populateSortingNodeGroupsWithDependencies } from '../../utils/populate-sorting-node-groups-with-dependencies.js' import { computeOrderedValue } from '../../utils/compare/compute-ordered-value.js' import { isNodeDependentOnOtherNode } from '../../utils/is-node-dependent-on-other-node.js' import { sortNodesByDependencies } from '../../utils/sort-nodes-by-dependencies.js' import { buildSortingNodeByNodeMap } from '../../utils/build-sorting-node-by-node-map.js' import { computeDependenciesBySortingNode } from './compute-dependencies-by-sorting-node.js' import { computeDependencies } from './compute-dependencies.js' /** * Builds a comparator function for sorting module nodes based on their usage. * * @param params - The parameters object. * @param params.ignoreEslintDisabledNodes - Whether to ignore ESLint disabled * nodes. * @param params.sortingNodes - The module sorting nodes. * @param params.useExperimentalDependencyDetection - Whether to use * experimental dependency detection. * @param params.sourceCode - The source code object. * @param params.options - The sorting options. * @returns A comparator function for sorting module nodes by usage. */ function buildUsageComparator({ useExperimentalDependencyDetection, ignoreEslintDisabledNodes, sortingNodes, sourceCode, options, }) { let { updatedSortingNodeByNode, orderByUnsortedNode, orderBySortedNode } = buildOrderByNodeMaps({ useExperimentalDependencyDetection, ignoreEslintDisabledNodes, sortingNodes, sourceCode, }) return (a, b) => { let nodeA = a.node let nodeB = b.node let sortedOrderA = orderBySortedNode.get(nodeA) let unsortedOrderA = orderByUnsortedNode.get(nodeA) let sortedOrderB = orderBySortedNode.get(nodeB) let unsortedOrderB = orderByUnsortedNode.get(nodeB) let sortedOrderedValue = computeOrderedValue( sortedOrderA - sortedOrderB, options.order, ) if ( sortedOrderedValue !== computeOrderedValue(unsortedOrderA - unsortedOrderB, options.order) ) { return sortedOrderedValue } let aWithUpdatedDependencies = updatedSortingNodeByNode.get(nodeA) let bWithUpdatedDependencies = updatedSortingNodeByNode.get(nodeB) if ( isNodeDependentOnOtherNode( aWithUpdatedDependencies, bWithUpdatedDependencies, ) || isNodeDependentOnOtherNode( bWithUpdatedDependencies, aWithUpdatedDependencies, ) ) { return sortedOrderedValue } return 0 } } function buildOrderByNodeMaps({ useExperimentalDependencyDetection, ignoreEslintDisabledNodes, sortingNodes, sourceCode, }) { let sortingNodesWithUpdatedDependencies if (useExperimentalDependencyDetection) { let dependenciesBySortingNode = computeDependenciesBySortingNode({ dependencyDetection: 'soft', sortingNodes, sourceCode, }) sortingNodesWithUpdatedDependencies = populateSortingNodeGroupsWithDependencies({ sortingNodeGroups: [sortingNodes], dependenciesBySortingNode, })[0] } else { sortingNodesWithUpdatedDependencies = sortingNodes.map( computeSortingNodeWithUpdatedDependencies, ) } let sortedSortingNodes = sortNodesByDependencies( sortingNodesWithUpdatedDependencies, { ignoreEslintDisabledNodes }, ) return { updatedSortingNodeByNode: buildSortingNodeByNodeMap( sortingNodesWithUpdatedDependencies, ), orderBySortedNode: buildOrderByNodeMap(sortedSortingNodes), orderByUnsortedNode: buildOrderByNodeMap(sortingNodes), } /** * Computes a sorting node with updated dependencies. * * @deprecated - To remove when experimental dependency detection is the only * option. * @param params - The parameters object. * @returns The sorting node populated with updated dependencies. */ function computeSortingNodeWithUpdatedDependencies({ isEslintDisabled, dependencyNames, node, }) { let dependencies = computeDependencies(node, { type: 'soft' }) let dependencyNamesSet = new Set(dependencyNames) return { dependencies: dependencies.filter( dependency => !dependencyNamesSet.has(dependency), ), isEslintDisabled, dependencyNames, node, } } } function buildOrderByNodeMap(sortingNodes) { let returnValue = /* @__PURE__ */ new Map() for (let [i, { node }] of sortingNodes.entries()) { returnValue.set(node, i) } return returnValue } export { buildUsageComparator }