core/converters/literal.converter.ts
core/converters/literal.converter.ts is a file in Bane's Lab Site. 88 lines of code and 21 definitions.
import {
CALL_OPEN,
EXTENSION_SEPARATOR,
LOCAL_RULE_PREFIX,
NON_PATH_CHARS,
PATH_SEPARATOR,
RULE_FILE_SUFFIX,
SLOT_CALLEES,
SLOT_QUOTES,
} from "#configuration/constants/anatomy.constants";
import type { CodeTarget, ReferenceLookups, TemplateParts } from "#types/code.types";
import { foldedOf, templatePartsOf } from "#core/converters/template.converter";
import { CONFIG_TAB } from "#core/ids/anatomy.ids";
import type { DefinitionIndex } from "#types/definition.types";
import { treeOf } from "#core/converters/folder.converter";
const isPathShaped = function isPathShaped(text: string): boolean {
for (let at = 0; at < text.length; at += 1) {
if (NON_PATH_CHARS.includes(text.charAt(at))) {
return false;
}
}
return text.includes(PATH_SEPARATOR) || text.includes(EXTENSION_SEPARATOR);
};
const exactTarget = function exactTarget(index: DefinitionIndex, text: string, path: string): CodeTarget | null {
const specified = index.resolveSpecifier(text, path);
const file = specified ?? (isPathShaped(text) ? index.resolveOwnPath(text, path) : null);
if (file !== null) {
return { kind: "file", path: file };
}
const folder = isPathShaped(text) ? index.resolveFolder(text, path) : null;
return folder === null ? null : { kind: "folder", path: folder };
};
const openTarget = function openTarget(index: DefinitionIndex, parts: TemplateParts, path: string): CodeTarget | null {
const literals = parts.literals.filter((literal) => literal.length > 0);
if (!isPathShaped(literals.join(""))) {
return null;
}
const matches = index.filesMatching(literals, path);
const [only] = matches;
if (matches.length === 1 && only !== undefined) {
return { kind: "file", path: only };
}
return matches.length > 1
? { kind: "candidates", locations: matches.map((file) => ({ file, line: null, name: file })) }
: null;
};
const isSlotArgument = function isSlotArgument(source: string, text: string): boolean {
return SLOT_CALLEES.some((callee) =>
SLOT_QUOTES.some((mark) => source.includes(callee + CALL_OPEN + mark + text + mark)),
);
};
const slotTarget = function slotTarget(
index: DefinitionIndex,
lookups: ReferenceLookups,
site: { readonly path: string; readonly source: string; readonly text: string },
): CodeTarget | null {
const declared = isSlotArgument(site.source, site.text) ? lookups.slotDeclaration(site.path) : null;
const declaration = declared === null ? null : index.resolveOwnPath(declared, site.path);
return declaration === null ? null : { kind: "file", path: declaration };
};
const ruleTarget = function ruleTarget(index: DefinitionIndex, text: string): CodeTarget | null {
const id = text.startsWith(LOCAL_RULE_PREFIX) ? text.slice(LOCAL_RULE_PREFIX.length) : "";
const file = id.length === 0 ? null : index.resolvePath(id + RULE_FILE_SUFFIX);
return file === null ? null : { kind: "file", path: file };
};
const catalogTarget = function catalogTarget(lookups: ReferenceLookups, text: string, path: string): CodeTarget | null {
const ref = treeOf(path) === CONFIG_TAB ? lookups.ruleRecord(text) : null;
return ref === null ? null : { kind: "record", ref };
};
export const literalTarget = function literalTarget(
index: DefinitionIndex,
lookups: ReferenceLookups,
text: string,
path: string,
source: string,
): CodeTarget | null {
const parts = templatePartsOf(text);
if (parts === null) {
return (
exactTarget(index, text, path) ??
slotTarget(index, lookups, { path, source, text }) ??
ruleTarget(index, text) ??
catalogTarget(lookups, text, path)
);
}
const folded = foldedOf(parts, source);
return folded === null ? openTarget(index, parts, path) : exactTarget(index, folded, path);
};