shared/analyzers/check.analyzer.ts
shared/analyzers/check.analyzer.ts is a file in GovLab Extension Host. 44 lines of code and 15 definitions.
import type { ReadDeclaration } from "../../types/check.types.ts";
import ts from "typescript";
export const DECLARING_CALLEE = "defineCheck";
type Field = keyof ReadDeclaration;
const stringsOf = function stringsOf(node: ts.Expression): readonly string[] | null {
if (!ts.isArrayLiteralExpression(node)) {
return null;
}
const values = node.elements.flatMap((element) => (ts.isStringLiteral(element) ? [element.text] : []));
return values.length === node.elements.length ? values : null;
};
const fieldOf = function fieldOf(object: ts.ObjectLiteralExpression, field: Field): readonly string[] | null {
const property = object.properties.find(
(member) => ts.isPropertyAssignment(member) && ts.isIdentifier(member.name) && member.name.text === field,
);
return property !== undefined && ts.isPropertyAssignment(property) ? stringsOf(property.initializer) : null;
};
const declarationOf = function declarationOf(node: ts.CallExpression): ReadDeclaration | null {
const [argument] = node.arguments;
if (argument === undefined || !ts.isObjectLiteralExpression(argument)) {
return null;
}
const detects = fieldOf(argument, "detects");
const enforces = fieldOf(argument, "enforces");
return detects === null || enforces === null ? null : { detects, enforces };
};
const isDeclaringCall = function isDeclaringCall(node: ts.Node): node is ts.CallExpression {
return ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === DECLARING_CALLEE;
};
export const declarationsIn = function declarationsIn(
fileName: string,
text: string,
): readonly (ReadDeclaration | null)[] {
const source = ts.createSourceFile(fileName, text, ts.ScriptTarget.Latest, false, ts.ScriptKind.TS);
const found: (ReadDeclaration | null)[] = [];
const visit = (node: ts.Node): void => {
if (isDeclaringCall(node)) {
found.push(declarationOf(node));
}
ts.forEachChild(node, visit);
};
visit(source);
return found;
};