UNPKG

eslint-plugin-mocha

Version:

Eslint rules for mocha.

85 lines 3.84 kB
import { flatMapWithArgs, mapWithArgs } from "../list.js"; import { getUniqueBaseNames } from "../mocha/path.js"; import { isRecord } from "../record.js"; import { isConstantPath } from "./member-expression.js"; import { getParentNode } from "./node-types.js"; import { findParentNodeAndPathForIdentifier } from "./resolved-reference.js"; function isLiteralWithValue(node, expectedValue) { return node.type === 'Literal' && (expectedValue === null || node.value === expectedValue); } function getFirstChildScope(scope) { return scope?.childScopes[0]; } function isImportSpecifierNode(node) { return isRecord(node) && node.type === 'ImportSpecifier' && isRecord(node.imported) && typeof node.imported.name === 'string'; } function isExclusiveNamedImportBindingWithMatchingSource(variable, expectedSource) { const importDef = variable.defs[0]; const importNode = importDef?.node; return (importDef?.type === 'ImportBinding' && isImportSpecifierNode(importNode) && isLiteralWithValue(importDef.parent.source, expectedSource)); } function getAllNamedImportBindingVariables(moduleScope, expectedSource) { return moduleScope.variables.filter(function (variable) { return isExclusiveNamedImportBindingWithMatchingSource(variable, expectedSource); }); } function isNonAssignmentReference(reference) { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- bad eslint core typings const node = reference.identifier; const parent = getParentNode(node); return parent.type !== 'AssignmentExpression' || !Object.is(parent.left, node); } function isBindingConstant(variable) { return variable.references.every(isNonAssignmentReference); } function replaceFirstSegment(path, replacement) { if (isConstantPath(path)) { const [firstSegment, ...remainingPath] = path; if (firstSegment === undefined) { return [replacement]; } const suffix = firstSegment.endsWith('()') ? '()' : ''; return [`${replacement}${suffix}`, ...remainingPath]; } return path; } function resolveImportPathWithOriginalName(reference, sourceCode, originalName) { // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- bad eslint core typings const { node, path } = findParentNodeAndPathForIdentifier(sourceCode, reference.identifier); return { node, path, resolvedPath: replaceFirstSegment(path, originalName) }; } function resolveReferencesForNamedImport(variable, sourceCode, identifierNames) { const originalName = variable.defs[0].node.imported.name; if (identifierNames.includes(originalName)) { return mapWithArgs(variable.references, resolveImportPathWithOriginalName, sourceCode, originalName); } return []; } function processNamedImports(sourceCode, moduleScope, identifierNames, importSource) { const namedImportVariables = getAllNamedImportBindingVariables(moduleScope, importSource); const constantNamedImports = namedImportVariables.filter(isBindingConstant); return flatMapWithArgs(constantNamedImports, resolveReferencesForNamedImport, sourceCode, identifierNames); } export function findImportReferencesByName(context, nameDetailsList, importSource) { const { sourceCode } = context; const { globalScope } = sourceCode.scopeManager; const maybeModuleScope = getFirstChildScope(globalScope); if (maybeModuleScope?.type !== 'module') { return []; } const identifierNames = getUniqueBaseNames(nameDetailsList); const moduleScope = maybeModuleScope; const namedImportReferences = processNamedImports(sourceCode, moduleScope, identifierNames, importSource); return namedImportReferences; } //# sourceMappingURL=find-import-references.js.map