import * as logger from "../../lib/logger.js";
import * as regex from "../regex.js";
const MultiClassError = new Error();
function remapScopeNames(mode, regexes, { key }) {
let offset = 0;
const scopeNames = mode[key];
const emit = {};
const positions = {};
for (let i = 1; i <= regexes.length; i++) {
positions[i + offset] = scopeNames[i];
emit[i + offset] = true;
offset += regex.countMatchGroups(regexes[i - 1]);
}
mode[key] = positions;
mode[key]._emit = emit;
mode[key]._multi = true;
}
function beginMultiClass(mode) {
if (!Array.isArray(mode.begin)) return;
if (mode.skip || mode.excludeBegin || mode.returnBegin) {
logger.error("skip, excludeBegin, returnBegin not compatible with beginScope: {}");
throw MultiClassError;
}
if (typeof mode.beginScope !== "object" || mode.beginScope === null) {
logger.error("beginScope must be object");
throw MultiClassError;
}
remapScopeNames(mode, mode.begin, { key: "beginScope" });
mode.begin = regex._rewriteBackreferences(mode.begin, { joinWith: "" });
}
function endMultiClass(mode) {
if (!Array.isArray(mode.end)) return;
if (mode.skip || mode.excludeEnd || mode.returnEnd) {
logger.error("skip, excludeEnd, returnEnd not compatible with endScope: {}");
throw MultiClassError;
}
if (typeof mode.endScope !== "object" || mode.endScope === null) {
logger.error("endScope must be object");
throw MultiClassError;
}
remapScopeNames(mode, mode.end, { key: "endScope" });
mode.end = regex._rewriteBackreferences(mode.end, { joinWith: "" });
}
function scopeSugar(mode) {
if (mode.scope && typeof mode.scope === "object" && mode.scope !== null) {
mode.beginScope = mode.scope;
delete mode.scope;
}
}
export function MultiClass(mode) {
scopeSugar(mode);
if (typeof mode.beginScope === "string") {
mode.beginScope = { _wrap: mode.beginScope };
}
if (typeof mode.endScope === "string") {
mode.endScope = { _wrap: mode.endScope };
}
beginMultiClass(mode);
endMultiClass(mode);
}