Skip to content

Commit

Permalink
feat: mult-line macro declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
saadjutt01 committed May 21, 2021
1 parent 8bfb547 commit af2d2c1
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 87 deletions.
8 changes: 4 additions & 4 deletions src/format/formatText.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 <Your brief here>
<h4> SAS Macros </h4>
**/\n%macro test
**/\n%macro test;
%put 'hello';\n%mend test;`

const output = await formatText(text)
Expand All @@ -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 <Your brief here>\r\n <h4> SAS Macros </h4>\r\n**/\r\n%macro test\r\n %put 'hello';\r\n%mend test;`
const expectedOutput = `/**\r\n @file\r\n @brief <Your brief here>\r\n <h4> SAS Macros </h4>\r\n**/\r\n%macro test;\r\n %put 'hello';\r\n%mend test;`

const output = await formatText(text)

Expand Down
2 changes: 1 addition & 1 deletion src/rules/file/hasMacroNameInMend.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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([
{
Expand Down
16 changes: 11 additions & 5 deletions src/rules/file/hasMacroNameInMend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
Expand All @@ -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
Expand Down Expand Up @@ -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')
Expand All @@ -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
Expand Down
26 changes: 13 additions & 13 deletions src/rules/file/hasMacroParentheses.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()`

expect(hasMacroParentheses.test(content)).toEqual([
{
message: 'Macro definition contains space(s)',
lineNumber: 1,
startColumnNumber: 8,
endColumnNumber: 14,
severity: Severity.Warning
}
])
})
// 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
// }
// ])
// })
})
50 changes: 31 additions & 19 deletions src/rules/file/hasMacroParentheses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
// })
}
})

Expand Down
8 changes: 4 additions & 4 deletions src/rules/file/noNestedMacros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand Down
29 changes: 28 additions & 1 deletion src/rules/line/strictMacroDefinition.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand All @@ -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([
{
Expand All @@ -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([
Expand Down
26 changes: 24 additions & 2 deletions src/rules/line/strictMacroDefinition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
}
Expand Down
Loading

0 comments on commit af2d2c1

Please sign in to comment.