UNPKG

@sasjs/lint

Version:

Linting and formatting for SAS code

132 lines 6.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseMacros = void 0; const LineEndings_1 = require("../types/LineEndings"); const trimComments_1 = require("./trimComments"); const parseMacros = (text, config) => { const lineEnding = (config === null || config === void 0 ? void 0 : config.lineEndings) === LineEndings_1.LineEndings.CRLF ? '\r\n' : '\n'; const lines = text ? text.split(lineEnding) : []; const macros = []; let isCommentStarted = false; let macroStack = []; let isReadingMacroDefinition = false; let isStatementContinues = true; let tempMacroDeclaration = ''; let tempMacroDeclarationLines = []; let tempStartLineNumbers = []; lines.forEach((line, lineIndex) => { const { statement: trimmedLine, commentStarted } = (0, trimComments_1.trimComments)(line, isCommentStarted); isCommentStarted = commentStarted; isStatementContinues = !trimmedLine.endsWith(';'); const statements = trimmedLine.split(';'); if (isReadingMacroDefinition) { // checking if code is split into statements based on `;` is a part of HTML Encoded Character // if it happened, merges two statements into one statements.forEach((statement, statementIndex) => { if (/&[^\s]{1,5}$/.test(statement)) { const next = statements[statementIndex]; const updatedStatement = `${statement};${statements[statementIndex + 1]}`; statements.splice(statementIndex, 1, updatedStatement); statements.splice(statementIndex + 1, 1); } }); } statements.forEach((statement, statementIndex) => { const { statement: trimmedStatement, commentStarted } = (0, trimComments_1.trimComments)(statement, isCommentStarted); isCommentStarted = commentStarted; if (isReadingMacroDefinition) { tempMacroDeclaration = tempMacroDeclaration + (trimmedStatement ? ' ' + trimmedStatement : ''); tempMacroDeclarationLines.push(line); tempStartLineNumbers.push(lineIndex + 1); if (!Object.is(statements.length - 1, statementIndex)) { isReadingMacroDefinition = false; const name = tempMacroDeclaration .slice(7, tempMacroDeclaration.length) .trim() .split('/')[0] .split('(')[0] .trim(); macroStack.push({ name, startLineNumbers: tempStartLineNumbers, endLineNumber: null, parentMacro: macroStack.length ? macroStack[macroStack.length - 1].name : '', hasMacroNameInMend: false, mismatchedMendMacroName: '', declarationLines: tempMacroDeclarationLines, terminationLine: '', declaration: tempMacroDeclaration, termination: '' }); } } if (trimmedStatement.startsWith('%macro')) { const startLineNumber = lineIndex + 1; if (isStatementContinues && Object.is(statements.length - 1, statementIndex)) { tempMacroDeclaration = trimmedStatement; tempMacroDeclarationLines = [line]; tempStartLineNumbers = [startLineNumber]; isReadingMacroDefinition = true; return; } const name = trimmedStatement .slice(7, trimmedStatement.length) .trim() .split('/')[0] .split('(')[0] .trim(); macroStack.push({ name, startLineNumbers: [startLineNumber], endLineNumber: null, parentMacro: macroStack.length ? macroStack[macroStack.length - 1].name : '', hasMacroNameInMend: false, mismatchedMendMacroName: '', declarationLines: [line], terminationLine: '', declaration: trimmedStatement, termination: '' }); } else if (trimmedStatement.startsWith('%mend')) { if (macroStack.length) { const macro = macroStack.pop(); const mendMacroName = trimmedStatement.split(' ').filter((s) => !!s)[1] || ''; macro.endLineNumber = lineIndex + 1; macro.hasMacroNameInMend = mendMacroName === macro.name; macro.mismatchedMendMacroName = macro.hasMacroNameInMend ? '' : mendMacroName; macro.terminationLine = line; macro.termination = trimmedStatement; macros.push(macro); } else { macros.push({ name: '', startLineNumbers: [], endLineNumber: lineIndex + 1, parentMacro: '', hasMacroNameInMend: false, mismatchedMendMacroName: '', declarationLines: [], terminationLine: line, declaration: '', termination: trimmedStatement }); } } }); }); macros.push(...macroStack); return macros; }; exports.parseMacros = parseMacros; //# sourceMappingURL=parseMacros.js.map