astro-ghostcms/.pnpm-store/v3/files/73/06dfc2b9fc3ae4de8e7abb2faf2...

167 lines
4.9 KiB
Plaintext
Raw Normal View History

2024-02-14 14:10:47 +00:00
'use strict';
const acorn = require('acorn');
function _stripLiteralAcorn(code, options) {
const FILL = options?.fillChar ?? " ";
const FILL_COMMENT = " ";
let result = "";
const filter = options?.filter ?? (() => true);
function fillupTo(index) {
if (index > result.length)
result += code.slice(result.length, index).replace(/[^\n]/g, FILL_COMMENT);
}
const tokens = [];
const pasers = acorn.tokenizer(code, {
ecmaVersion: "latest",
sourceType: "module",
allowHashBang: true,
allowAwaitOutsideFunction: true,
allowImportExportEverywhere: true
});
const iter = pasers[Symbol.iterator]();
let error;
try {
while (true) {
const { done, value: token } = iter.next();
if (done)
break;
tokens.push(token);
fillupTo(token.start);
if (token.type.label === "string") {
const body = code.slice(token.start + 1, token.end - 1);
if (filter(body)) {
result += code[token.start] + FILL.repeat(token.end - token.start - 2) + code[token.end - 1];
continue;
}
} else if (token.type.label === "template") {
const body = code.slice(token.start, token.end);
if (filter(body)) {
result += FILL.repeat(token.end - token.start);
continue;
}
} else if (token.type.label === "regexp") {
const body = code.slice(token.start, token.end);
if (filter(body)) {
result += body.replace(/\/(.*)\/(\w?)$/g, (_, $1, $2) => `/${FILL.repeat($1.length)}/${$2}`);
continue;
}
}
result += code.slice(token.start, token.end);
}
fillupTo(code.length);
} catch (e) {
error = e;
}
return {
error,
result,
tokens
};
}
function stripLiteralAcorn(code, options) {
const result = _stripLiteralAcorn(code, options);
if (result.error)
throw result.error;
return result.result;
}
function createIsLiteralPositionAcorn(code) {
const positionList = [];
const tokens = acorn.tokenizer(code, {
ecmaVersion: "latest",
sourceType: "module",
allowHashBang: true,
allowAwaitOutsideFunction: true,
allowImportExportEverywhere: true,
onComment(_isBlock, _text, start, end) {
positionList.push(start);
positionList.push(end);
}
});
const inter = tokens[Symbol.iterator]();
while (true) {
const { done, value: token } = inter.next();
if (done)
break;
if (token.type.label === "string") {
positionList.push(token.start + 1);
positionList.push(token.end - 1);
} else if (token.type.label === "template") {
positionList.push(token.start);
positionList.push(token.end);
}
}
return (position) => {
const i = binarySearch(positionList, (v) => position < v);
return (i - 1) % 2 === 0;
};
}
function binarySearch(array, pred) {
let low = -1;
let high = array.length;
while (1 + low < high) {
const mid = low + (high - low >> 1);
if (pred(array[mid]))
high = mid;
else
low = mid;
}
return high;
}
const multilineCommentsRE = /\/\*([^*\/])*?\*\//gms;
const singlelineCommentsRE = /(?:^|\n|\r)\s*\/\/.*(?:\r|\n|$)/gm;
const templateLiteralRE = /\$\{(\s*(?:|{.*}|(?!\$\{).|\n|\r)*?\s*)\}/g;
const quotesRE = [
/(["'`])((?:\\\1|(?!\1)|.|\r)*?)\1/gm,
/([`])((?:\\\1|(?!\1)|.|\n|\r)*?)\1/gm
// multi-line strings (i.e. template literals only)
];
function stripLiteralRegex(code, options) {
const FILL_COMMENT = " ";
const FILL = options?.fillChar ?? " ";
const filter = options?.filter ?? (() => true);
code = code.replace(multilineCommentsRE, (s) => filter(s) ? FILL_COMMENT.repeat(s.length) : s).replace(singlelineCommentsRE, (s) => filter(s) ? FILL_COMMENT.repeat(s.length) : s);
let expanded = code;
for (let i = 0; i < 16; i++) {
const before = expanded;
expanded = expanded.replace(templateLiteralRE, "` $1`");
if (expanded === before)
break;
}
quotesRE.forEach((re) => {
expanded = expanded.replace(re, (s, quote, body, index) => {
if (!filter(s.slice(1, -1)))
return s;
code = code.slice(0, index + 1) + FILL.repeat(s.length - 2) + code.slice(index + s.length - 1);
return quote + FILL.repeat(s.length - 2) + quote;
});
});
return code;
}
function stripLiteral(code, options) {
return stripLiteralDetailed(code, options).result;
}
function stripLiteralDetailed(code, options) {
const acorn = _stripLiteralAcorn(code, options);
if (!acorn.error) {
return {
mode: "acorn",
result: acorn.result,
acorn
};
}
return {
mode: "regex",
result: stripLiteralRegex(acorn.result + code.slice(acorn.result.length), options),
acorn
};
}
exports.createIsLiteralPositionAcorn = createIsLiteralPositionAcorn;
exports.stripLiteral = stripLiteral;
exports.stripLiteralAcorn = stripLiteralAcorn;
exports.stripLiteralDetailed = stripLiteralDetailed;
exports.stripLiteralRegex = stripLiteralRegex;