eslint-plugin-mocha
Version:
Eslint rules for mocha.
94 lines • 4.49 kB
JavaScript
import { findVariable } from '@eslint-community/eslint-utils';
import { flatMapWithArgs, mapWithArgs } from "../list.js";
import { extractMemberExpressionPath, getIdentifierName, isConstantPath } from "./member-expression.js";
import { isAssignmentProperty, isIdentifierPattern, isObjectPattern, isVariableDeclarator } from "./node-types.js";
import { findParentNodeAndPathForIdentifier } from "./resolved-reference.js";
import { asRuleNode } from "./rule-node.js";
function isConstVariableDeclarationParent(parent) {
return parent?.type === 'VariableDeclaration' && parent.kind === 'const';
}
function isAliasConstAssignment(node) {
return isVariableDeclarator(node) && isConstVariableDeclarationParent(node.parent);
}
function extractIdentifiersFromObjectPattern(node, currentPath) {
return node.properties.flatMap(function (property) {
if (!isAssignmentProperty(property)) {
return [];
}
if (property.value.type === 'Identifier') {
return [{ identifier: property.value, path: [...currentPath, getIdentifierName(property.key)] }];
}
if (property.value.type === 'ObjectPattern') {
return extractIdentifiersFromObjectPattern(property.value, [
...currentPath,
getIdentifierName(property.key)
]);
}
return [];
});
}
function getDeclaredIdentifiers(sourceCode, node) {
const path = extractMemberExpressionPath(sourceCode, asRuleNode(node.init));
if (isIdentifierPattern(node.id)) {
return [{ identifier: node.id, leftHandSidePath: [], rightHandSidePath: path }];
}
if (isObjectPattern(node.id)) {
const allPatternIdentifiers = extractIdentifiersFromObjectPattern(node.id, []);
return allPatternIdentifiers.map(function (patternIdentifiers) {
return {
identifier: patternIdentifiers.identifier,
leftHandSidePath: patternIdentifiers.path,
rightHandSidePath: path
};
});
}
return [];
}
function extendPath(parentReference, originalPath, identifierPath) {
const extendedPath = [...parentReference.resolvedPath, ...originalPath, ...identifierPath.slice(1)];
const [callAlias] = identifierPath;
if (identifierPath.length === 1 && String(callAlias).endsWith('()')) {
const lastIndex = extendedPath.length - 1;
const lastElement = extendedPath[lastIndex];
if (typeof lastElement === 'string') {
extendedPath[lastIndex] = `${lastElement}()`;
}
}
return extendedPath;
}
function aliasReferenceToResolvedReference(reference, sourceCode, parentReference, originalPath) {
const { node, path } = findParentNodeAndPathForIdentifier(sourceCode, asRuleNode(reference.identifier));
return { node, path, resolvedPath: extendPath(parentReference, originalPath, path) };
}
function isNonInitReference(reference) {
return reference.init !== true;
}
function getNonInitAliasReferences(variable) {
return variable.references.filter(isNonInitReference);
}
function resolveAliasReferencesRecursively(reference, sourceCode) {
const { node } = reference;
const result = [reference];
function resolveAliasedReferencesForIdentifier(identifierPath, identifierName) {
const aliasedVariable = findVariable(sourceCode.getScope(reference.node), identifierName);
if (aliasedVariable === null) {
return [];
}
const aliasedResolvedReferences = mapWithArgs(getNonInitAliasReferences(aliasedVariable), aliasReferenceToResolvedReference, sourceCode, reference, identifierPath);
return flatMapWithArgs(aliasedResolvedReferences, resolveAliasReferencesRecursively, sourceCode);
}
if (isAliasConstAssignment(node)) {
const declaratedIdentifiers = getDeclaredIdentifiers(sourceCode, node);
for (const { identifier, leftHandSidePath: identifierPath } of declaratedIdentifiers) {
result.push(...resolveAliasedReferencesForIdentifier(identifierPath, identifier.name));
}
}
return result;
}
function hasConstantResolvedPath(resolvedReference) {
return isConstantPath(resolvedReference.resolvedPath);
}
export function resolveAliasedReferences(sourceCode, originalResolvedReferences) {
return flatMapWithArgs(originalResolvedReferences, resolveAliasReferencesRecursively, sourceCode).filter(hasConstantResolvedPath);
}
//# sourceMappingURL=alias-references.js.map