eslint-plugin-perfectionist
Version:
ESLint plugin for sorting various data such as objects, imports, types, enums, JSX props, etc.
137 lines (136 loc) • 4.63 kB
JavaScript
import { validateNewlinesAndPartitionConfiguration } from '../../utils/validate-newlines-and-partition-configuration.js'
import { defaultComparatorByOptionsComputer } from '../../utils/compare/default-comparator-by-options-computer.js'
import { buildOptionsByGroupIndexComputer } from '../../utils/build-options-by-group-index-computer.js'
import { validateCustomSortConfiguration } from '../../utils/validate-custom-sort-configuration.js'
import { validateGroupsConfiguration } from '../../utils/validate-groups-configuration.js'
import { generatePredefinedGroups } from '../../utils/generate-predefined-groups.js'
import { getEslintDisabledLines } from '../../utils/get-eslint-disabled-lines.js'
import { doesCustomGroupMatch } from '../../utils/does-custom-group-match.js'
import { isNodeEslintDisabled } from '../../utils/is-node-eslint-disabled.js'
import { sortNodesByGroups } from '../../utils/sort-nodes-by-groups.js'
import { reportAllErrors } from '../../utils/report-all-errors.js'
import { shouldPartition } from '../../utils/should-partition.js'
import { computeGroup } from '../../utils/compute-group.js'
import { rangeToDiff } from '../../utils/range-to-diff.js'
import { getSettings } from '../../utils/get-settings.js'
import { isSortable } from '../../utils/is-sortable.js'
import { complete } from '../../utils/complete.js'
import { allSelectors } from './types.js'
import { computeNodeName } from './compute-node-name.js'
import { computeMatchedContextOptions } from './compute-matched-context-options.js'
import { computeArrayElements } from './compute-array-elements.js'
import { AST_NODE_TYPES } from '@typescript-eslint/utils'
function sortArray({
cachedGroupsByModifiersAndSelectors,
mustHaveMatchedContextOptions,
availableMessageIds,
matchedAstSelectors,
defaultOptions,
context,
node,
}) {
let elements = computeArrayElements(node)
if (!elements) {
return
}
if (!isSortable(elements)) {
return
}
let { sourceCode, id } = context
let settings = getSettings(context.settings)
let matchedContextOptions = computeMatchedContextOptions({
matchedAstSelectors,
elements,
context,
})
if (mustHaveMatchedContextOptions && !matchedContextOptions) {
return
}
let options = complete(matchedContextOptions, settings, defaultOptions)
validateCustomSortConfiguration(options)
validateGroupsConfiguration({
selectors: allSelectors,
modifiers: [],
options,
})
validateNewlinesAndPartitionConfiguration(options)
let eslintDisabledLines = getEslintDisabledLines({
ruleName: id,
sourceCode,
})
let optionsByGroupIndexComputer = buildOptionsByGroupIndexComputer(options)
let formattedMembers = elements.reduce(
(accumulator, element) => {
if (element === null) {
return accumulator
}
if (element.type === AST_NODE_TYPES.SpreadElement) {
accumulator.push([])
return accumulator
}
let name = computeNodeName({
node: element,
sourceCode,
})
let selector = 'literal'
let group = computeGroup({
customGroupMatcher: customGroup =>
doesCustomGroupMatch({
selectors: [selector],
elementName: name,
modifiers: [],
customGroup,
}),
predefinedGroups: generatePredefinedGroups({
cache: cachedGroupsByModifiersAndSelectors,
selectors: [selector],
modifiers: [],
}),
options,
})
let sortingNode = {
isEslintDisabled: isNodeEslintDisabled(element, eslintDisabledLines),
size: rangeToDiff(element, sourceCode),
node: element,
group,
name,
}
let lastSortingNode = accumulator.at(-1)?.at(-1)
if (
shouldPartition({
lastSortingNode,
sortingNode,
sourceCode,
options,
})
) {
accumulator.push([])
}
accumulator.at(-1).push({
...sortingNode,
partitionId: accumulator.length,
})
return accumulator
},
[[]],
)
function sortNodesExcludingEslintDisabled(ignoreEslintDisabledNodes) {
return formattedMembers.flatMap(nodes =>
sortNodesByGroups({
comparatorByOptionsComputer: defaultComparatorByOptionsComputer,
optionsByGroupIndexComputer,
ignoreEslintDisabledNodes,
groups: options.groups,
nodes,
}),
)
}
reportAllErrors({
sortNodesExcludingEslintDisabled,
availableMessageIds,
options,
context,
nodes: formattedMembers.flat(),
})
}
export { sortArray }