UNPKG

eslint-plugin-perfectionist

Version:

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

153 lines (152 loc) 4.99 kB
import { UnreachableCaseError } from '../../utils/unreachable-case-error.js' import { computeParentNodesWithTypes } from '../../utils/compute-parent-nodes-with-types.js' import { passesAllNamesMatchPatternFilter } from '../../utils/context-matching/passes-all-names-match-pattern-filter.js' import { passesAstSelectorFilter } from '../../utils/context-matching/passes-ast-selector-filter.js' import { objectParentTypes } from './types.js' import { computePropertyOrVariableDeclaratorName } from './compute-property-or-variable-declarator-name.js' import { passesCallingFunctionNamePatternFilter } from './passes-calling-function-name-pattern-filter.js' import { passesDeclarationMatchesPatternFilter } from './passes-declaration-matches-pattern-filter.js' import { passesDeclarationCommentMatchesFilter } from './passes-declaration-comment-matches-filter.js' import { AST_NODE_TYPES } from '@typescript-eslint/utils' /** * Computes the matched context options for a given object node. * * @param params - Parameters. * @param params.isDestructuredObject - Whether the object is destructured. * @param params.matchedAstSelectors - The matched AST selectors for an object * node. * @param params.sourceCode - The source code object. * @param params.nodeObject - The object node to evaluate. * @param params.context - The rule context. * @returns The matched context options or undefined if none match. */ function computeMatchedContextOptions({ isDestructuredObject, matchedAstSelectors, sourceCode, nodeObject, context, }) { let nodeNames = nodeObject.properties .filter( property => property.type !== AST_NODE_TYPES.SpreadElement && property.type !== AST_NODE_TYPES.RestElement, ) .map(property => computePropertyOrVariableDeclaratorName({ node: property, sourceCode, }), ) let parentNodes = computeParentNodesWithTypes({ allowedTypes: [...objectParentTypes], consecutiveOnly: false, node: nodeObject, maxParent: null, }) return context.options.find(options => isContextOptionMatching({ isDestructuredObject, matchedAstSelectors, parentNodes, sourceCode, nodeObject, nodeNames, options, }), ) } function isContextOptionMatching({ isDestructuredObject, matchedAstSelectors, parentNodes, sourceCode, nodeObject, nodeNames, options, }) { if (!options.useConfigurationIf) { return true } return ( passesAllNamesMatchPatternFilter({ allNamesMatchPattern: options.useConfigurationIf.allNamesMatchPattern, nodeNames, }) && passesObjectTypeFilter({ objectType: options.useConfigurationIf.objectType, isDestructuredObject, }) && passesCallingFunctionNamePatternFilter({ callingFunctionNamePattern: options.useConfigurationIf.callingFunctionNamePattern, parentNodes, sourceCode, }) && passesDeclarationMatchesPatternFilter({ declarationMatchesPattern: options.useConfigurationIf.declarationMatchesPattern, parentNodes, sourceCode, }) && passesHasNumericKeysOnlyFilter({ hasNumericKeysOnlyFilter: options.useConfigurationIf.hasNumericKeysOnly, object: nodeObject, }) && passesDeclarationCommentMatchesFilter({ declarationCommentMatchesPattern: options.useConfigurationIf.declarationCommentMatchesPattern, parentNodes, sourceCode, }) && passesAstSelectorFilter({ matchesAstSelector: options.useConfigurationIf.matchesAstSelector, matchedAstSelectors, }) ) } function passesHasNumericKeysOnlyFilter({ hasNumericKeysOnlyFilter, object }) { let hasOnlyNumericKeys = hasNumericKeysOnly() switch (hasNumericKeysOnlyFilter) { case void 0: return true case false: return !hasOnlyNumericKeys case true: return hasOnlyNumericKeys /* v8 ignore next 2 -- @preserve Exhaustive guard. */ default: throw new UnreachableCaseError(hasNumericKeysOnlyFilter) } function hasNumericKeysOnly() { switch (object.type) { case AST_NODE_TYPES.ObjectExpression: return object.properties.every( property => property.type === AST_NODE_TYPES.Property && property.key.type === AST_NODE_TYPES.Literal && typeof property.key.value === 'number', ) case AST_NODE_TYPES.ObjectPattern: return false /* v8 ignore next 2 */ default: throw new UnreachableCaseError(object) } } } function passesObjectTypeFilter({ isDestructuredObject, objectType }) { switch (objectType) { case 'non-destructured': return !isDestructuredObject case 'destructured': return isDestructuredObject case void 0: return true /* v8 ignore next 2 -- @preserve Exhaustive guard. */ default: throw new UnreachableCaseError(objectType) } } export { computeMatchedContextOptions }