parse-statements
Version:
Fast and easy parser of statements in source code in any language ✂️
66 lines (65 loc) • 2.5 kB
JavaScript
/**
* Get internal prepared options from public options.
*/
export const getPreparedOptions = ({ comments = [], onError, regexpFlags = 'gmu', statements = [], }) => {
const commentsKeys = [];
const firstTokens = [];
const firstTokensAfterComments = [];
let keyIndex = 1;
const openTokens = [];
const preparedComments = { __proto__: null };
const preparedStatements = { __proto__: null };
const statementsKeys = [];
for (const { onError, onParse, tokens: [open, close], } of comments) {
const closeRegExp = createRegExp(regexpFlags, ['', close]);
const key = `parseStatementsPackageComment${keyIndex++}`;
commentsKeys.push(key);
openTokens.push([key, open]);
preparedComments[key] = { closeRegExp, onError, onParse };
}
for (const { canIncludeComments, onError, onParse, tokens: [firstToken, ...restTokens], shouldSearchBeforeComments, } of statements) {
const statementKey = `parseStatementsPackageStatement${keyIndex++}`;
const tokens = [];
(shouldSearchBeforeComments ? firstTokens : firstTokensAfterComments).push([
statementKey,
firstToken,
]);
statementsKeys.push(statementKey);
for (const nextToken of restTokens) {
const nextTokenKey = `parseStatementsPackageStatementPart${keyIndex++}`;
const regexpTokens = [[nextTokenKey, nextToken]];
if (canIncludeComments) {
regexpTokens[shouldSearchBeforeComments ? 'push' : 'unshift'](...openTokens);
}
const nextTokenRegExp = createRegExp(regexpFlags, ...regexpTokens);
tokens.push({ nextTokenKey, nextTokenRegExp });
}
preparedStatements[statementKey] = { onError, onParse, tokens };
}
const nextStatementRegExp = createRegExp(regexpFlags, ...firstTokens, ...openTokens, ...firstTokensAfterComments);
return {
commentsKeys,
nextStatementRegExp,
onError,
preparedComments,
preparedStatements,
statementsKeys,
};
};
/**
* Creates regexp by tokens.
*/
const createRegExp = (flags, ...tokens) => {
if (!tokens[0]) {
return emptyRegExp;
}
let source = tokens[0][1];
if (tokens[0][0] !== '') {
source = tokens.map(([key, token]) => `(?<${key}>${token})`).join('|');
}
return new RegExp(source, flags);
};
/**
* Empty regexp that match only the empty string.
*/
const emptyRegExp = /^$/g;