From 443bdc0a506b6cbab4c90e003c8d6a1dffc46a98 Mon Sep 17 00:00:00 2001 From: Saad Jutt Date: Tue, 6 Apr 2021 14:34:51 +0500 Subject: [PATCH] fix(hasMacroNameInMend): added support for comments having code in it --- src/rules/hasMacroNameInMend.spec.ts | 42 ++++++++++++++++++++++++++++ src/rules/hasMacroNameInMend.ts | 29 +++++++++++++++---- 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/src/rules/hasMacroNameInMend.spec.ts b/src/rules/hasMacroNameInMend.spec.ts index 28a15d9..6ea35ca 100644 --- a/src/rules/hasMacroNameInMend.spec.ts +++ b/src/rules/hasMacroNameInMend.spec.ts @@ -164,6 +164,48 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([]) }) + it('should return an array with a single diagnostic when %mend has correct macro name having code in comments', () => { + const content = `/** + @file examplemacro.sas + @brief an example of a macro to be used in a service + @details This macro is great. Yadda yadda yadda. Usage: + + * code formatting applies when indented by 4 spaces; code formatting applies when indented by 4 spaces; code formatting applies when indented by 4 spaces; code formatting applies when indented by 4 spaces; code formatting applies when indented by 4 spaces; + + some code + %macro examplemacro123(); + + %examplemacro() + +

SAS Macros

+ @li doesnothing.sas + + @author Allan Bowe + **/ + + %macro examplemacro(); + + proc sql; + create table areas + as select area + + from sashelp.springs; + + %doesnothing(); + + %mend;` + + expect(hasMacroNameInMend.test(content)).toEqual([ + { + message: '%mend missing macro name', + lineNumber: 29, + startColumnNumber: 5, + endColumnNumber: 11, + severity: Severity.Warning + } + ]) + }) + it('should return an array with a single diagnostic when %mend has incorrect macro name', () => { const content = ` %macro somemacro; diff --git a/src/rules/hasMacroNameInMend.ts b/src/rules/hasMacroNameInMend.ts index fb0dcbe..338bf5a 100644 --- a/src/rules/hasMacroNameInMend.ts +++ b/src/rules/hasMacroNameInMend.ts @@ -12,8 +12,14 @@ const test = (value: string) => { const statements: string[] = value ? value.split(';') : [] const stack: string[] = [] + let trimmedStatement = '', + commentStarted = false statements.forEach((statement, index) => { - const trimmedStatement = trimComments(statement).trim() + ;({ statement: trimmedStatement, commentStarted } = trimComments( + statement, + commentStarted + )) + if (trimmedStatement.startsWith('%macro ')) { const macroName = trimmedStatement .split(' ') @@ -58,13 +64,24 @@ const test = (value: string) => { return diagnostics } -const trimComments = (statement: string): string => { +const trimComments = ( + statement: string, + commentStarted: boolean = false +): { statement: string; commentStarted: boolean } => { let trimmed = statement.trim() - if (trimmed.startsWith('/*')) - trimmed = (trimmed.split('*/').pop() as string).trim() - - return trimmed + if (commentStarted || trimmed.startsWith('/*')) { + const parts = trimmed.split('*/') + if (parts.length > 1) { + return { + statement: (parts.pop() as string).trim(), + commentStarted: false + } + } else { + return { statement: '', commentStarted: true } + } + } + return { statement: trimmed, commentStarted: false } } const getLineNumber = (statements: string[], index: number): number => {