shared/resolvers/scope.resolver.ts
shared/resolvers/scope.resolver.ts is a file in GovLab Extension Host. 47 lines of code and 11 definitions.
import type { Rule, Scope } from "eslint";
import type { WriteNode } from "../../types/generator.types.ts";
const isWriteNode = function isWriteNode(value: unknown): value is WriteNode {
return value !== null && typeof value === "object" && "type" in value;
};
export const asWriteNode = function asWriteNode(value: unknown): WriteNode | null {
return isWriteNode(value) ? value : null;
};
export const findVariable = function findVariable(
context: Rule.RuleContext,
node: Rule.Node,
name: string,
): Scope.Variable | null {
let scope: Scope.Scope | null = context.sourceCode.getScope(node);
while (scope !== null) {
const variable = scope.variables.find((entry) => entry.name === name);
if (variable) {
return variable;
}
scope = scope.upper;
}
return null;
};
const declaratorInit = function declaratorInit(variable: Scope.Variable): WriteNode | null {
for (const def of variable.defs) {
const declarator = asWriteNode(def.node);
if (declarator?.type === "VariableDeclarator") {
return declarator.init ?? null;
}
}
return null;
};
const lastWrittenValue = function lastWrittenValue(variable: Scope.Variable): WriteNode | null {
const written = variable.references.flatMap((reference) => {
const value = asWriteNode(reference.writeExpr);
return value === null ? [] : [value];
});
return written.at(-1) ?? null;
};
export const variableInit = function variableInit(
context: Rule.RuleContext,
node: Rule.Node,
name: string,
): WriteNode | null {
const variable = findVariable(context, node, name);
return variable === null ? null : (lastWrittenValue(variable) ?? declaratorInit(variable));
};