diff --git a/src/rules/hasMacroNameInMend.spec.ts b/src/rules/hasMacroNameInMend.spec.ts index f493b1c..e9a6bcb 100644 --- a/src/rules/hasMacroNameInMend.spec.ts +++ b/src/rules/hasMacroNameInMend.spec.ts @@ -28,7 +28,7 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement is missing macro name', + message: '%mend statement is missing macro name - somemacro', lineNumber: 4, startColumnNumber: 3, endColumnNumber: 9, @@ -83,7 +83,7 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement has mismatched macro name', + message: `%mend statement has mismatched macro name, it should be 'somemacro'`, lineNumber: 4, startColumnNumber: 9, endColumnNumber: 24, @@ -126,7 +126,7 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement is missing macro name', + message: '%mend statement is missing macro name - inner', lineNumber: 6, startColumnNumber: 5, endColumnNumber: 11, @@ -148,7 +148,7 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement is missing macro name', + message: '%mend statement is missing macro name - outer', lineNumber: 9, startColumnNumber: 3, endColumnNumber: 9, @@ -170,14 +170,14 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement is missing macro name', + message: '%mend statement is missing macro name - inner', lineNumber: 6, startColumnNumber: 5, endColumnNumber: 11, severity: Severity.Warning }, { - message: '%mend statement is missing macro name', + message: '%mend statement is missing macro name - outer', lineNumber: 9, startColumnNumber: 3, endColumnNumber: 9, @@ -235,7 +235,7 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement is missing macro name', + message: '%mend statement is missing macro name - examplemacro', lineNumber: 29, startColumnNumber: 5, endColumnNumber: 11, @@ -254,7 +254,7 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement has mismatched macro name', + message: `%mend statement has mismatched macro name, it should be 'somemacro'`, lineNumber: 6, startColumnNumber: 14, endColumnNumber: 29, @@ -271,7 +271,7 @@ describe('hasMacroNameInMend', () => { expect(hasMacroNameInMend.test(content)).toEqual([ { - message: '%mend statement is missing macro name', + message: '%mend statement is missing macro name - somemacro', lineNumber: 4, startColumnNumber: 5, endColumnNumber: 11, diff --git a/src/rules/hasMacroNameInMend.ts b/src/rules/hasMacroNameInMend.ts index 5a123a0..1a7c829 100644 --- a/src/rules/hasMacroNameInMend.ts +++ b/src/rules/hasMacroNameInMend.ts @@ -13,51 +13,64 @@ const message = '%mend statement has missing or incorrect macro name' const test = (value: string) => { const diagnostics: Diagnostic[] = [] - const statements: string[] = value ? value.split(';') : [] + const lines: string[] = value ? value.split('\n') : [] const declaredMacros: { name: string; lineNumber: number }[] = [] let isCommentStarted = false - statements.forEach((statement, index) => { - const { statement: trimmedStatement, commentStarted } = trimComments( - statement, + lines.forEach((line, index) => { + const { statement: trimmedLine, commentStarted } = trimComments( + line, isCommentStarted ) isCommentStarted = commentStarted + const statements: string[] = trimmedLine ? trimmedLine.split(';') : [] - if (trimmedStatement.startsWith('%macro ')) { - const macroName = trimmedStatement - .slice(7, trimmedStatement.length) - .trim() - .split('(')[0] - declaredMacros.push({ - name: macroName, - lineNumber: getLineNumber(statements, index + 1) - }) - } else if (trimmedStatement.startsWith('%mend')) { - const declaredMacro = declaredMacros.pop() - const macroName = trimmedStatement - .split(' ') - .filter((s: string) => !!s)[1] + statements.forEach((statement) => { + const { statement: trimmedStatement, commentStarted } = trimComments( + statement, + isCommentStarted + ) + isCommentStarted = commentStarted - if (!macroName) { - diagnostics.push({ - message: '%mend statement is missing macro name', - lineNumber: getLineNumber(statements, index + 1), - startColumnNumber: getColumnNumber(statement, '%mend'), - endColumnNumber: getColumnNumber(statement, '%mend') + 6, - severity: Severity.Warning - }) - } else if (macroName !== declaredMacro!.name) { - diagnostics.push({ - message: '%mend statement has mismatched macro name', - lineNumber: getLineNumber(statements, index + 1), - startColumnNumber: getColumnNumber(statement, macroName), - endColumnNumber: - getColumnNumber(statement, macroName) + macroName.length - 1, - severity: Severity.Warning + if (trimmedStatement.startsWith('%macro ')) { + const macroName = trimmedStatement + .slice(7, trimmedStatement.length) + .trim() + .split('(')[0] + declaredMacros.push({ + name: macroName, + lineNumber: getLineNumber(lines, index + 1) }) + } else if (trimmedStatement.startsWith('%mend')) { + const declaredMacro = declaredMacros.pop() + const macroName = trimmedStatement + .split(' ') + .filter((s: string) => !!s)[1] + + if (!macroName) { + diagnostics.push({ + message: `%mend statement is missing macro name - ${ + declaredMacro!.name + }`, + lineNumber: getLineNumber(lines, index + 1), + startColumnNumber: getColumnNumber(line, '%mend'), + endColumnNumber: getColumnNumber(line, '%mend') + 6, + severity: Severity.Warning + }) + } else if (macroName !== declaredMacro!.name) { + diagnostics.push({ + message: `%mend statement has mismatched macro name, it should be '${ + declaredMacro!.name + }'`, + lineNumber: getLineNumber(lines, index + 1), + startColumnNumber: getColumnNumber(line, macroName), + endColumnNumber: + getColumnNumber(line, macroName) + macroName.length - 1, + severity: Severity.Warning + }) + } } - } + }) }) declaredMacros.forEach((declaredMacro) => { diff --git a/src/rules/hasMacroParentheses.spec.ts b/src/rules/hasMacroParentheses.spec.ts index 49da46c..bf56b13 100644 --- a/src/rules/hasMacroParentheses.spec.ts +++ b/src/rules/hasMacroParentheses.spec.ts @@ -36,7 +36,7 @@ describe('hasMacroParentheses', () => { expect(hasMacroParentheses.test(content)).toEqual([ { - message: 'Macro definition missing name', + message: 'Macro definition contains space(s)', lineNumber: 2, startColumnNumber: 3, endColumnNumber: 12, @@ -53,10 +53,10 @@ describe('hasMacroParentheses', () => { expect(hasMacroParentheses.test(content)).toEqual([ { - message: 'Macro definition missing name', + message: 'Macro definition contains space(s)', lineNumber: 2, startColumnNumber: 3, - endColumnNumber: 10, + endColumnNumber: 9, severity: Severity.Warning } ]) diff --git a/src/rules/hasMacroParentheses.ts b/src/rules/hasMacroParentheses.ts index 6e9306b..6e67340 100644 --- a/src/rules/hasMacroParentheses.ts +++ b/src/rules/hasMacroParentheses.ts @@ -12,55 +12,64 @@ const message = 'Macro definition missing parentheses' const test = (value: string) => { const diagnostics: Diagnostic[] = [] - const statements: string[] = value ? value.split(';') : [] - + const lines: string[] = value ? value.split('\n') : [] let isCommentStarted = false - statements.forEach((statement, index) => { - const { statement: trimmedStatement, commentStarted } = trimComments( - statement, + lines.forEach((line, index) => { + const { statement: trimmedLine, commentStarted } = trimComments( + line, isCommentStarted ) isCommentStarted = commentStarted + const statements: string[] = trimmedLine ? trimmedLine.split(';') : [] - if (trimmedStatement.startsWith('%macro')) { - const macroNameDefinition = trimmedStatement - .slice(7, trimmedStatement.length) - .trim() + statements.forEach((statement) => { + const { statement: trimmedStatement, commentStarted } = trimComments( + statement, + isCommentStarted + ) + isCommentStarted = commentStarted - const macroNameDefinitionParts = macroNameDefinition.split('(') - const macroName = macroNameDefinitionParts[0] + if (trimmedStatement.startsWith('%macro')) { + const macroNameDefinition = trimmedStatement + .slice(7, trimmedStatement.length) + .trim() - if (!macroName) - diagnostics.push({ - message: 'Macro definition missing name', - lineNumber: getLineNumber(statements, index + 1), - startColumnNumber: getColumnNumber(statement, '%macro'), - endColumnNumber: statement.length, - severity: Severity.Warning - }) - else if (macroNameDefinitionParts.length === 1) - diagnostics.push({ - message, - lineNumber: getLineNumber(statements, index + 1), - startColumnNumber: getColumnNumber(statement, macroNameDefinition), - endColumnNumber: - getColumnNumber(statement, macroNameDefinition) + - macroNameDefinition.length - - 1, - severity: Severity.Warning - }) - else if (macroName !== macroName.trim()) - diagnostics.push({ - message: 'Macro definition contains space(s)', - lineNumber: getLineNumber(statements, index + 1), - startColumnNumber: getColumnNumber(statement, macroNameDefinition), - endColumnNumber: - getColumnNumber(statement, macroNameDefinition) + - macroNameDefinition.length - - 1, - severity: Severity.Warning - }) - } + const macroNameDefinitionParts = macroNameDefinition.split('(') + const macroName = macroNameDefinitionParts[0] + + if (!macroName) + diagnostics.push({ + message: 'Macro definition contains space(s)', + lineNumber: getLineNumber(lines, index + 1), + startColumnNumber: getColumnNumber(line, '%macro'), + endColumnNumber: + getColumnNumber(line, '%macro') + trimmedStatement.length, + severity: Severity.Warning + }) + else if (macroNameDefinitionParts.length === 1) + diagnostics.push({ + message, + lineNumber: getLineNumber(lines, index + 1), + startColumnNumber: getColumnNumber(line, macroNameDefinition), + endColumnNumber: + getColumnNumber(line, macroNameDefinition) + + macroNameDefinition.length - + 1, + severity: Severity.Warning + }) + else if (macroName !== macroName.trim()) + diagnostics.push({ + message: 'Macro definition contains space(s)', + lineNumber: getLineNumber(lines, index + 1), + startColumnNumber: getColumnNumber(line, macroNameDefinition), + endColumnNumber: + getColumnNumber(line, macroNameDefinition) + + macroNameDefinition.length - + 1, + severity: Severity.Warning + }) + } + }) }) return diagnostics } diff --git a/src/rules/noNestedMacros.ts b/src/rules/noNestedMacros.ts index 1acbd33..a8cec22 100644 --- a/src/rules/noNestedMacros.ts +++ b/src/rules/noNestedMacros.ts @@ -11,40 +11,48 @@ const description = 'Enfoces the absence of nested macro definitions.' const message = `Macro definition for '{macro}' present in macro '{parent}'` const test = (value: string) => { const diagnostics: Diagnostic[] = [] - - const statements: string[] = value ? value.split(';') : [] - const declaredMacros: string[] = [] + + const lines: string[] = value ? value.split('\n') : [] let isCommentStarted = false - statements.forEach((statement, index) => { - const { statement: trimmedStatement, commentStarted } = trimComments( - statement, + lines.forEach((line, index) => { + const { statement: trimmedLine, commentStarted } = trimComments( + line, isCommentStarted ) isCommentStarted = commentStarted + const statements: string[] = trimmedLine ? trimmedLine.split(';') : [] - if (trimmedStatement.startsWith('%macro ')) { - const macroName = trimmedStatement - .slice(7, trimmedStatement.length) - .trim() - .split('(')[0] - if (declaredMacros.length) { - const parentMacro = declaredMacros.slice(-1).pop() - diagnostics.push({ - message: message - .replace('{macro}', macroName) - .replace('{parent}', parentMacro!), - lineNumber: getLineNumber(statements, index + 1), - startColumnNumber: getColumnNumber(statement, '%macro'), - endColumnNumber: - getColumnNumber(statement, '%macro') + trimmedStatement.length - 1, - severity: Severity.Warning - }) + statements.forEach((statement) => { + const { statement: trimmedStatement, commentStarted } = trimComments( + statement, + isCommentStarted + ) + isCommentStarted = commentStarted + + if (trimmedStatement.startsWith('%macro ')) { + const macroName = trimmedStatement + .slice(7, trimmedStatement.length) + .trim() + .split('(')[0] + if (declaredMacros.length) { + const parentMacro = declaredMacros.slice(-1).pop() + diagnostics.push({ + message: message + .replace('{macro}', macroName) + .replace('{parent}', parentMacro!), + lineNumber: getLineNumber(lines, index + 1), + startColumnNumber: getColumnNumber(line, '%macro'), + endColumnNumber: + getColumnNumber(line, '%macro') + trimmedStatement.length - 1, + severity: Severity.Warning + }) + } + declaredMacros.push(macroName) + } else if (trimmedStatement.startsWith('%mend')) { + declaredMacros.pop() } - declaredMacros.push(macroName) - } else if (trimmedStatement.startsWith('%mend')) { - declaredMacros.pop() - } + }) }) return diagnostics } diff --git a/src/utils/getLineNumber.ts b/src/utils/getLineNumber.ts index ebfe055..7d988e7 100644 --- a/src/utils/getLineNumber.ts +++ b/src/utils/getLineNumber.ts @@ -1,5 +1,4 @@ -export const getLineNumber = (statements: string[], index: number): number => { - const combinedCode = statements.slice(0, index).join(';') - const lines = (combinedCode.match(/\n/g) || []).length + 1 - return lines +export const getLineNumber = (lines: string[], index: number): number => { + const combinedCode = lines.slice(0, index).join('\n') + return (combinedCode.match(/\n/g) || []).length + 1 }