From af2d2c12c19bae9f18cbd477889f7b7aa7f2e37c Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Fri, 21 May 2021 05:10:34 +0500 Subject: [PATCH] feat: mult-line macro declarations --- src/format/formatText.spec.ts | 8 +- src/rules/file/hasMacroNameInMend.spec.ts | 2 +- src/rules/file/hasMacroNameInMend.ts | 16 +- src/rules/file/hasMacroParentheses.spec.ts | 24 +-- src/rules/file/hasMacroParentheses.ts | 50 +++--- src/rules/file/noNestedMacros.ts | 8 +- src/rules/line/strictMacroDefinition.spec.ts | 29 +++- src/rules/line/strictMacroDefinition.ts | 26 +++- src/utils/parseMacros.spec.ts | 154 ++++++++++++++++--- src/utils/parseMacros.ts | 78 ++++++++-- src/utils/trimComments.spec.ts | 2 +- src/utils/trimComments.ts | 14 +- 12 files changed, 325 insertions(+), 86 deletions(-) diff --git a/src/format/formatText.spec.ts b/src/format/formatText.spec.ts index 35f2a53..2cccf0d 100644 --- a/src/format/formatText.spec.ts +++ b/src/format/formatText.spec.ts @@ -12,14 +12,14 @@ describe('formatText', () => { new LintConfig(getLintConfigModule.DefaultLintConfiguration) ) ) - const text = `%macro test + const text = `%macro test; %put 'hello';\r\n%mend; ` const expectedOutput = `/** @file @brief

SAS Macros

-**/\n%macro test +**/\n%macro test; %put 'hello';\n%mend test;` const output = await formatText(text) @@ -38,9 +38,9 @@ describe('formatText', () => { }) ) ) - const text = `%macro test\n %put 'hello';\r\n%mend; ` + const text = `%macro test;\n %put 'hello';\r\n%mend; ` - const expectedOutput = `/**\r\n @file\r\n @brief \r\n

SAS Macros

\r\n**/\r\n%macro test\r\n %put 'hello';\r\n%mend test;` + const expectedOutput = `/**\r\n @file\r\n @brief \r\n

SAS Macros

\r\n**/\r\n%macro test;\r\n %put 'hello';\r\n%mend test;` const output = await formatText(text) diff --git a/src/rules/file/hasMacroNameInMend.spec.ts b/src/rules/file/hasMacroNameInMend.spec.ts index 5693a2e..8acf000 100644 --- a/src/rules/file/hasMacroNameInMend.spec.ts +++ b/src/rules/file/hasMacroNameInMend.spec.ts @@ -56,7 +56,7 @@ describe('hasMacroNameInMend - test', () => { it('should return an array with a diagnostic for each macro missing an %mend statement', () => { const content = `%macro somemacro; %put &sysmacroname; - %macro othermacro` + %macro othermacro;` expect(hasMacroNameInMend.test(content)).toEqual([ { diff --git a/src/rules/file/hasMacroNameInMend.ts b/src/rules/file/hasMacroNameInMend.ts index cab7ac1..0a37100 100644 --- a/src/rules/file/hasMacroNameInMend.ts +++ b/src/rules/file/hasMacroNameInMend.ts @@ -17,7 +17,7 @@ const test = (value: string, config?: LintConfig) => { const macros = parseMacros(value, config) const diagnostics: Diagnostic[] = [] macros.forEach((macro) => { - if (macro.startLineNumber === null && macro.endLineNumber !== null) { + if (macro.startLineNumbers.length === 0 && macro.endLineNumber !== null) { const endLine = lines[macro.endLineNumber - 1] diagnostics.push({ message: `%mend statement is redundant`, @@ -27,10 +27,13 @@ const test = (value: string, config?: LintConfig) => { getColumnNumber(endLine, '%mend') + macro.termination.length, severity: Severity.Warning }) - } else if (macro.endLineNumber === null && macro.startLineNumber !== null) { + } else if ( + macro.endLineNumber === null && + macro.startLineNumbers.length !== 0 + ) { diagnostics.push({ message: `Missing %mend statement for macro - ${macro.name}`, - lineNumber: macro.startLineNumber, + lineNumber: macro.startLineNumbers![0], startColumnNumber: 1, endColumnNumber: 1, severity: Severity.Warning @@ -73,7 +76,7 @@ const fix = (value: string, config?: LintConfig): string => { const macros = parseMacros(value, config) macros.forEach((macro) => { - if (macro.startLineNumber === null && macro.endLineNumber !== null) { + if (macro.startLineNumbers.length === 0 && macro.endLineNumber !== null) { // %mend statement is redundant const endLine = lines[macro.endLineNumber - 1] const startColumnNumber = getColumnNumber(endLine, '%mend') @@ -83,7 +86,10 @@ const fix = (value: string, config?: LintConfig): string => { const beforeStatement = endLine.slice(0, startColumnNumber - 1) const afterStatement = endLine.slice(endColumnNumber) lines[macro.endLineNumber - 1] = beforeStatement + afterStatement - } else if (macro.endLineNumber === null && macro.startLineNumber !== null) { + } else if ( + macro.endLineNumber === null && + macro.startLineNumbers.length !== 0 + ) { // missing %mend statement } else if (macro.mismatchedMendMacroName) { // mismatched macro name diff --git a/src/rules/file/hasMacroParentheses.spec.ts b/src/rules/file/hasMacroParentheses.spec.ts index 1fa58bc..3ace5ce 100644 --- a/src/rules/file/hasMacroParentheses.spec.ts +++ b/src/rules/file/hasMacroParentheses.spec.ts @@ -140,17 +140,17 @@ describe('hasMacroParentheses', () => { }) }) - it('should return an array with a single diagnostic when a macro definition contains a space', () => { - const content = `%macro test ()` + // it('should return an array with a single diagnostic when a macro definition contains a space', () => { + // const content = `%macro test ()` - expect(hasMacroParentheses.test(content)).toEqual([ - { - message: 'Macro definition contains space(s)', - lineNumber: 1, - startColumnNumber: 8, - endColumnNumber: 14, - severity: Severity.Warning - } - ]) - }) + // expect(hasMacroParentheses.test(content)).toEqual([ + // { + // message: 'Macro definition contains space(s)', + // lineNumber: 1, + // startColumnNumber: 8, + // endColumnNumber: 14, + // severity: Severity.Warning + // } + // ]) + // }) }) diff --git a/src/rules/file/hasMacroParentheses.ts b/src/rules/file/hasMacroParentheses.ts index 7975cba..13d15e5 100644 --- a/src/rules/file/hasMacroParentheses.ts +++ b/src/rules/file/hasMacroParentheses.ts @@ -16,36 +16,48 @@ const test = (value: string, config?: LintConfig) => { if (!macro.name) { diagnostics.push({ message: 'Macro definition missing name', - lineNumber: macro.startLineNumber!, - startColumnNumber: getColumnNumber(macro.declarationLine, '%macro'), + lineNumber: macro.startLineNumbers![0], + startColumnNumber: getColumnNumber( + macro.declarationLines![0], + '%macro' + ), endColumnNumber: - getColumnNumber(macro.declarationLine, '%macro') + + getColumnNumber(macro.declarationLines![0], '%macro') + macro.declaration.length, severity: Severity.Warning }) - } else if (!macro.declarationLine.includes('(')) { + } else if (!macro.declarationLines.find((dl) => dl.includes('('))) { + const macroNameLineIndex = macro.declarationLines.findIndex((dl) => + dl.includes(macro.name) + ) diagnostics.push({ message, - lineNumber: macro.startLineNumber!, - startColumnNumber: getColumnNumber(macro.declarationLine, macro.name), + lineNumber: macro.startLineNumbers![macroNameLineIndex], + startColumnNumber: getColumnNumber( + macro.declarationLines[macroNameLineIndex], + macro.name + ), endColumnNumber: - getColumnNumber(macro.declarationLine, macro.name) + + getColumnNumber( + macro.declarationLines[macroNameLineIndex], + macro.name + ) + macro.name.length - 1, severity: Severity.Warning }) - } else if (macro.name !== macro.name.trim()) { - diagnostics.push({ - message: 'Macro definition contains space(s)', - lineNumber: macro.startLineNumber!, - startColumnNumber: getColumnNumber(macro.declarationLine, macro.name), - endColumnNumber: - getColumnNumber(macro.declarationLine, macro.name) + - macro.name.length - - 1 + - `()`.length, - severity: Severity.Warning - }) + // } else if (macro.name !== macro.name.trim()) { + // diagnostics.push({ + // message: 'Macro definition contains space(s)', + // lineNumber: macro.startLineNumber!, + // startColumnNumber: getColumnNumber(macro.declarationLine, macro.name), + // endColumnNumber: + // getColumnNumber(macro.declarationLine, macro.name) + + // macro.name.length - + // 1 + + // `()`.length, + // severity: Severity.Warning + // }) } }) diff --git a/src/rules/file/noNestedMacros.ts b/src/rules/file/noNestedMacros.ts index 338ae15..b255545 100644 --- a/src/rules/file/noNestedMacros.ts +++ b/src/rules/file/noNestedMacros.ts @@ -22,17 +22,17 @@ const test = (value: string, config?: LintConfig) => { message: message .replace('{macro}', macro.name) .replace('{parent}', macro.parentMacro), - lineNumber: macro.startLineNumber as number, + lineNumber: macro.startLineNumbers![0] as number, startColumnNumber: getColumnNumber( - lines[(macro.startLineNumber as number) - 1], + lines[(macro.startLineNumbers![0] as number) - 1], '%macro' ), endColumnNumber: getColumnNumber( - lines[(macro.startLineNumber as number) - 1], + lines[(macro.startLineNumbers![0] as number) - 1], '%macro' ) + - lines[(macro.startLineNumber as number) - 1].trim().length - + lines[(macro.startLineNumbers![0] as number) - 1].trim().length - 1, severity: Severity.Warning }) diff --git a/src/rules/line/strictMacroDefinition.spec.ts b/src/rules/line/strictMacroDefinition.spec.ts index 63b0a4e..750084d 100644 --- a/src/rules/line/strictMacroDefinition.spec.ts +++ b/src/rules/line/strictMacroDefinition.spec.ts @@ -24,6 +24,19 @@ describe('strictMacroDefinition', () => { const line7 = ' /* Some Comment */ %macro somemacro(var1, var2) /minoperator ; /* Some Comment */' expect(strictMacroDefinition.test(line7, 1)).toEqual([]) + + const line8 = + '%macro macroName( arr, arr/* / store source */3 ) /* / store source */;/* / store source */' + expect(strictMacroDefinition.test(line8, 1)).toEqual([]) + + const line9 = '%macro macroName(var1, var2=with space, var3=);' + expect(strictMacroDefinition.test(line9, 1)).toEqual([]) + + const line10 = '%macro macroName()/ /* some comment */ store source;' + expect(strictMacroDefinition.test(line10, 1)).toEqual([]) + + const line11 = '`%macro macroName() /* / store source */;' + expect(strictMacroDefinition.test(line11, 1)).toEqual([]) }) it('should return an array with a single diagnostic when Macro definition has space in param', () => { @@ -39,7 +52,7 @@ describe('strictMacroDefinition', () => { ]) }) - it('should return an array with a two diagnostics when Macro definition has space in param', () => { + it('should return an array with a two diagnostics when Macro definition has space in params', () => { const line = '%macro somemacro(var1, var 2, v ar3, var4);' expect(strictMacroDefinition.test(line, 1)).toEqual([ { @@ -59,6 +72,20 @@ describe('strictMacroDefinition', () => { ]) }) + it('should return an array with a two diagnostics when Macro definition has space in params - special case', () => { + const line = + '%macro macroName( arr, ar r/* / store source */ 3 ) /* / store source */;/* / store source */' + expect(strictMacroDefinition.test(line, 1)).toEqual([ + { + message: `Param 'ar r 3' cannot have space`, + lineNumber: 1, + startColumnNumber: 24, + endColumnNumber: 49, + severity: Severity.Warning + } + ]) + }) + it('should return an array with a single diagnostic when Macro definition has invalid option', () => { const line = '%macro somemacro(var1, var2)/minXoperator;' expect(strictMacroDefinition.test(line, 1)).toEqual([ diff --git a/src/rules/line/strictMacroDefinition.ts b/src/rules/line/strictMacroDefinition.ts index 9adc3cf..246ba7f 100644 --- a/src/rules/line/strictMacroDefinition.ts +++ b/src/rules/line/strictMacroDefinition.ts @@ -42,12 +42,34 @@ const test = (value: string, lineNumber: number) => { const params = paramsTrimmed.split(',') params.forEach((param) => { const trimedParam = param.split('=')[0].trim() + + let paramStartIndex: number = 1, + paramEndIndex: number = value.length + + if (value.indexOf(trimedParam) === -1) { + const comment = '/\\*(.*?)\\*/' + for (let i = 1; i < trimedParam.length; i++) { + const paramWithComment = + trimedParam.slice(0, i) + comment + trimedParam.slice(i) + const regEx = new RegExp(paramWithComment) + const result = regEx.exec(value) + if (result) { + paramStartIndex = value.indexOf(result[0]) + paramEndIndex = value.indexOf(result[0]) + result[0].length + break + } + } + } else { + paramStartIndex = value.indexOf(trimedParam) + paramEndIndex = value.indexOf(trimedParam) + trimedParam.length + } + if (trimedParam.includes(' ')) { diagnostics.push({ message: `Param '${trimedParam}' cannot have space`, lineNumber, - startColumnNumber: value.indexOf(trimedParam) + 1, - endColumnNumber: value.indexOf(trimedParam) + trimedParam.length, + startColumnNumber: paramStartIndex + 1, + endColumnNumber: paramEndIndex, severity: Severity.Warning }) } diff --git a/src/utils/parseMacros.spec.ts b/src/utils/parseMacros.spec.ts index a238ff0..e8f25ce 100644 --- a/src/utils/parseMacros.spec.ts +++ b/src/utils/parseMacros.spec.ts @@ -3,7 +3,7 @@ import { parseMacros } from './parseMacros' describe('parseMacros', () => { it('should return an array with a single macro', () => { - const text = `%macro test; + const text = ` %macro test; %put 'hello'; %mend` @@ -12,11 +12,11 @@ describe('parseMacros', () => { expect(macros.length).toEqual(1) expect(macros).toContainEqual({ name: 'test', - declarationLine: '%macro test;', + declarationLines: [' %macro test;'], terminationLine: '%mend', declaration: '%macro test', termination: '%mend', - startLineNumber: 1, + startLineNumbers: [1], endLineNumber: 3, parentMacro: '', hasMacroNameInMend: false, @@ -34,11 +34,11 @@ describe('parseMacros', () => { expect(macros.length).toEqual(1) expect(macros).toContainEqual({ name: 'test', - declarationLine: '%macro test(var,sum);', + declarationLines: ['%macro test(var,sum);'], terminationLine: '%mend', declaration: '%macro test(var,sum)', termination: '%mend', - startLineNumber: 1, + startLineNumbers: [1], endLineNumber: 3, parentMacro: '', hasMacroNameInMend: false, @@ -56,11 +56,11 @@ describe('parseMacros', () => { expect(macros.length).toEqual(1) expect(macros).toContainEqual({ name: 'test', - declarationLine: '%macro test/parmbuff;', + declarationLines: ['%macro test/parmbuff;'], terminationLine: '%mend', declaration: '%macro test/parmbuff', termination: '%mend', - startLineNumber: 1, + startLineNumbers: [1], endLineNumber: 3, parentMacro: '', hasMacroNameInMend: false, @@ -79,11 +79,15 @@ describe('parseMacros', () => { expect(macros.length).toEqual(1) expect(macros).toContainEqual({ name: 'foobar', - declarationLine: '/* commentary */ %macro foobar(arg) /store source', + declarationLines: [ + '/* commentary */ %macro foobar(arg) /store source', + ' des="This macro does not do much";' + ], terminationLine: '%mend', - declaration: '%macro foobar(arg) /store source', + declaration: + '%macro foobar(arg) /store source des="This macro does not do much"', termination: '%mend', - startLineNumber: 1, + startLineNumbers: [1, 2], endLineNumber: 4, parentMacro: '', hasMacroNameInMend: false, @@ -104,11 +108,11 @@ describe('parseMacros', () => { expect(macros.length).toEqual(2) expect(macros).toContainEqual({ name: 'foo', - declarationLine: '%macro foo;', + declarationLines: ['%macro foo;'], terminationLine: '%mend;', declaration: '%macro foo', termination: '%mend', - startLineNumber: 1, + startLineNumbers: [1], endLineNumber: 3, parentMacro: '', hasMacroNameInMend: false, @@ -116,11 +120,11 @@ describe('parseMacros', () => { }) expect(macros).toContainEqual({ name: 'bar', - declarationLine: '%macro bar();', + declarationLines: ['%macro bar();'], terminationLine: '%mend bar;', declaration: '%macro bar()', termination: '%mend bar', - startLineNumber: 4, + startLineNumbers: [4], endLineNumber: 6, parentMacro: '', hasMacroNameInMend: true, @@ -129,9 +133,9 @@ describe('parseMacros', () => { }) it('should detect nested macro definitions', () => { - const text = `%macro test() + const text = `%macro test(); %put 'hello'; - %macro test2 + %macro test2; %put 'world; %mend %mend test` @@ -141,11 +145,11 @@ describe('parseMacros', () => { expect(macros.length).toEqual(2) expect(macros).toContainEqual({ name: 'test', - declarationLine: '%macro test()', + declarationLines: ['%macro test();'], terminationLine: '%mend test', declaration: '%macro test()', termination: '%mend test', - startLineNumber: 1, + startLineNumbers: [1], endLineNumber: 6, parentMacro: '', hasMacroNameInMend: true, @@ -153,15 +157,125 @@ describe('parseMacros', () => { }) expect(macros).toContainEqual({ name: 'test2', - declarationLine: ' %macro test2', + declarationLines: [' %macro test2;'], terminationLine: ' %mend', declaration: '%macro test2', termination: '%mend', - startLineNumber: 3, + startLineNumbers: [3], endLineNumber: 5, parentMacro: 'test', hasMacroNameInMend: false, mismatchedMendMacroName: '' }) }) + + describe(`multi-line macro declarations`, () => { + it('should return an array with a single macro', () => { + const text = `%macro + test; + %put 'hello'; +%mend` + + const macros = parseMacros(text, new LintConfig()) + + expect(macros.length).toEqual(1) + expect(macros).toContainEqual({ + name: 'test', + declarationLines: ['%macro ', ' test;'], + terminationLine: '%mend', + declaration: '%macro test', + termination: '%mend', + startLineNumbers: [1, 2], + endLineNumber: 4, + parentMacro: '', + hasMacroNameInMend: false, + mismatchedMendMacroName: '' + }) + }) + + it('should return an array with a single macro having parameters', () => { + const text = `%macro + test( + var, + sum);%put 'hello'; +%mend` + + const macros = parseMacros(text, new LintConfig()) + + expect(macros.length).toEqual(1) + expect(macros).toContainEqual({ + name: 'test', + declarationLines: [ + '%macro ', + ` test(`, + ` var,`, + ` sum);%put 'hello';` + ], + terminationLine: '%mend', + declaration: '%macro test( var, sum)', + termination: '%mend', + startLineNumbers: [1, 2, 3, 4], + endLineNumber: 5, + parentMacro: '', + hasMacroNameInMend: false, + mismatchedMendMacroName: '' + }) + }) + + it('should return an array with a single macro having PARMBUFF option', () => { + const text = `%macro test + /parmbuff; + %put 'hello'; +%mend` + + const macros = parseMacros(text, new LintConfig()) + + expect(macros.length).toEqual(1) + expect(macros).toContainEqual({ + name: 'test', + declarationLines: ['%macro test', ' /parmbuff;'], + terminationLine: '%mend', + declaration: '%macro test /parmbuff', + termination: '%mend', + startLineNumbers: [1, 2], + endLineNumber: 4, + parentMacro: '', + hasMacroNameInMend: false, + mismatchedMendMacroName: '' + }) + }) + + it('should return an array with a single macro having paramerter & SOURCE option', () => { + const text = `/* commentary */ %macro foobar/* commentary */(arg) + /* commentary */ + /store + /* commentary */source + des="This macro does not do much"; + %put 'hello'; +%mend` + + const macros = parseMacros(text, new LintConfig()) + + expect(macros.length).toEqual(1) + expect(macros).toContainEqual({ + name: 'foobar', + declarationLines: [ + '/* commentary */ %macro foobar/* commentary */(arg) ', + ' /* commentary */', + ' /store', + ' /* commentary */source', + ' des="This macro does not do much";' + ], + terminationLine: '%mend', + declaration: + '%macro foobar(arg) /store source des="This macro does not do much"', + termination: '%mend', + startLineNumbers: [1, 2, 3, 4, 5], + endLineNumber: 7, + parentMacro: '', + hasMacroNameInMend: false, + mismatchedMendMacroName: '' + }) + }) + }) }) diff --git a/src/utils/parseMacros.ts b/src/utils/parseMacros.ts index 89728ba..591dc50 100644 --- a/src/utils/parseMacros.ts +++ b/src/utils/parseMacros.ts @@ -4,9 +4,9 @@ import { trimComments } from './trimComments' interface Macro { name: string - startLineNumber: number | null + startLineNumbers: number[] endLineNumber: number | null - declarationLine: string + declarationLines: string[] terminationLine: string declaration: string termination: string @@ -22,38 +22,92 @@ export const parseMacros = (text: string, config?: LintConfig): Macro[] => { let isCommentStarted = false let macroStack: Macro[] = [] - lines.forEach((line, index) => { + let isReadingMacroDefinition = false + let isStatementContinues = true + let tempMacroDeclaration = '' + let tempMacroDeclarationLines: string[] = [] + let tempStartLineNumbers: number[] = [] + lines.forEach((line, lineIndex) => { const { statement: trimmedLine, commentStarted } = trimComments( line, isCommentStarted ) isCommentStarted = commentStarted - const statements: string[] = trimmedLine ? trimmedLine.split(';') : [] - statements.forEach((statement) => { + isStatementContinues = !trimmedLine.endsWith(';') + + const statements: string[] = trimmedLine.split(';') + + statements.forEach((statement, statementIndex) => { const { statement: trimmedStatement, commentStarted } = 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 = index + 1 + 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, - startLineNumber, + startLineNumbers: [startLineNumber], endLineNumber: null, parentMacro: macroStack.length ? macroStack[macroStack.length - 1].name : '', hasMacroNameInMend: false, mismatchedMendMacroName: '', - declarationLine: line, + declarationLines: [line], terminationLine: '', declaration: trimmedStatement, termination: '' @@ -63,7 +117,7 @@ export const parseMacros = (text: string, config?: LintConfig): Macro[] => { const macro = macroStack.pop() as Macro const mendMacroName = trimmedStatement.split(' ').filter((s: string) => !!s)[1] || '' - macro.endLineNumber = index + 1 + macro.endLineNumber = lineIndex + 1 macro.hasMacroNameInMend = mendMacroName === macro.name macro.mismatchedMendMacroName = macro.hasMacroNameInMend ? '' @@ -74,12 +128,12 @@ export const parseMacros = (text: string, config?: LintConfig): Macro[] => { } else { macros.push({ name: '', - startLineNumber: null, - endLineNumber: index + 1, + startLineNumbers: [], + endLineNumber: lineIndex + 1, parentMacro: '', hasMacroNameInMend: false, mismatchedMendMacroName: '', - declarationLine: '', + declarationLines: [], terminationLine: line, declaration: '', termination: trimmedStatement diff --git a/src/utils/trimComments.spec.ts b/src/utils/trimComments.spec.ts index 712b770..1a1b169 100644 --- a/src/utils/trimComments.spec.ts +++ b/src/utils/trimComments.spec.ts @@ -13,7 +13,7 @@ describe('trimComments', () => { /* some comment */ CODE_Keyword1 /* some comment */ CODE_Keyword2/* some comment */;/* some comment */ /* some comment */`) ).toEqual({ - statement: 'CODE_Keyword1 CODE_Keyword2;', + statement: 'CODE_Keyword1 CODE_Keyword2;', commentStarted: false }) }) diff --git a/src/utils/trimComments.ts b/src/utils/trimComments.ts index a6b5d2a..6660435 100644 --- a/src/utils/trimComments.ts +++ b/src/utils/trimComments.ts @@ -1,8 +1,9 @@ export const trimComments = ( statement: string, - commentStarted: boolean = false + commentStarted: boolean = false, + trimEnd: boolean = false ): { statement: string; commentStarted: boolean } => { - let trimmed = (statement || '').trim() + let trimmed = trimEnd ? (statement || '').trimEnd() : (statement || '').trim() if (commentStarted || trimmed.startsWith('/*')) { const parts = trimmed.split('*/') @@ -20,13 +21,16 @@ export const trimComments = ( } else if (trimmed.includes('/*')) { const statementBeforeCommentStarts = trimmed.slice(0, trimmed.indexOf('/*')) const remainingStatement = trimmed.slice( - trimmed.indexOf('/*'), + trimmed.indexOf('*/') + 2, trimmed.length ) - const result = trimComments(remainingStatement, false) + const result = trimComments(remainingStatement, false, true) + const completeStatement = statementBeforeCommentStarts + result.statement return { - statement: statementBeforeCommentStarts + result.statement, + statement: trimEnd + ? completeStatement.trimEnd() + : completeStatement.trim(), commentStarted: result.commentStarted } }