-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: new rule added 'strictMacroDefinition'
- Loading branch information
1 parent
e5780cd
commit dcfeb7a
Showing
7 changed files
with
190 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { LintConfig, Severity } from '../../types' | ||
import { strictMacroDefinition } from './strictMacroDefinition' | ||
|
||
describe('strictMacroDefinition', () => { | ||
it('should return an empty array when the line has correct macro definition syntax', () => { | ||
const line = '%macro somemacro;' | ||
expect(strictMacroDefinition.test(line, 1)).toEqual([]) | ||
|
||
const line2 = '%macro somemacro();' | ||
expect(strictMacroDefinition.test(line2, 1)).toEqual([]) | ||
|
||
const line3 = '%macro somemacro(var1);' | ||
expect(strictMacroDefinition.test(line3, 1)).toEqual([]) | ||
|
||
const line4 = '%macro somemacro/minoperator;' | ||
expect(strictMacroDefinition.test(line4, 1)).toEqual([]) | ||
|
||
const line5 = '%macro somemacro /minoperator;' | ||
expect(strictMacroDefinition.test(line5, 1)).toEqual([]) | ||
|
||
const line6 = '%macro somemacro(var1, var2)/minoperator;' | ||
expect(strictMacroDefinition.test(line6, 1)).toEqual([]) | ||
|
||
const line7 = | ||
' /* Some Comment */ %macro somemacro(var1, var2) /minoperator ; /* Some Comment */' | ||
expect(strictMacroDefinition.test(line7, 1)).toEqual([]) | ||
}) | ||
|
||
it('should return an array with a single diagnostic when Macro definition has space in param', () => { | ||
const line = '%macro somemacro(va r1);' | ||
expect(strictMacroDefinition.test(line, 1)).toEqual([ | ||
{ | ||
message: `Param 'va r1' cannot have space`, | ||
lineNumber: 1, | ||
startColumnNumber: 18, | ||
endColumnNumber: 22, | ||
severity: Severity.Warning | ||
} | ||
]) | ||
}) | ||
|
||
it('should return an array with a two diagnostics when Macro definition has space in param', () => { | ||
const line = '%macro somemacro(var1, var 2, v ar3, var4);' | ||
expect(strictMacroDefinition.test(line, 1)).toEqual([ | ||
{ | ||
message: `Param 'var 2' cannot have space`, | ||
lineNumber: 1, | ||
startColumnNumber: 24, | ||
endColumnNumber: 28, | ||
severity: Severity.Warning | ||
}, | ||
{ | ||
message: `Param 'v ar3' cannot have space`, | ||
lineNumber: 1, | ||
startColumnNumber: 31, | ||
endColumnNumber: 35, | ||
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([ | ||
{ | ||
message: `Option 'minXoperator' is not valid`, | ||
lineNumber: 1, | ||
startColumnNumber: 30, | ||
endColumnNumber: 41, | ||
severity: Severity.Warning | ||
} | ||
]) | ||
}) | ||
|
||
it('should return an array with a two diagnostics when Macro definition has invalid options', () => { | ||
const line = | ||
'%macro somemacro(var1, var2)/ store invalidoption secure ;' | ||
expect(strictMacroDefinition.test(line, 1)).toEqual([ | ||
{ | ||
message: `Option 'invalidoption' is not valid`, | ||
lineNumber: 1, | ||
startColumnNumber: 39, | ||
endColumnNumber: 51, | ||
severity: Severity.Warning | ||
} | ||
]) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { Diagnostic } from '../../types/Diagnostic' | ||
import { LintConfig } from '../../types' | ||
import { LineLintRule } from '../../types/LintRule' | ||
import { LintRuleType } from '../../types/LintRuleType' | ||
import { Severity } from '../../types/Severity' | ||
import { parseMacros } from '../../utils/parseMacros' | ||
|
||
const name = 'strictMacroDefinition' | ||
const description = 'Enforce strictly rules of macro definition syntax.' | ||
const message = 'Incorrent Macro Definition Syntax' | ||
|
||
const validOptions = [ | ||
'CMD', | ||
'DES', | ||
'MINDELIMITER', | ||
'MINOPERATOR', | ||
'NOMINOPERATOR', | ||
'PARMBUFF', | ||
'SECURE', | ||
'NOSECURE', | ||
'STMT', | ||
'SOURCE', | ||
'SRC', | ||
'STORE' | ||
] | ||
|
||
const test = (value: string, lineNumber: number) => { | ||
const diagnostics: Diagnostic[] = [] | ||
|
||
const macros = parseMacros(value) | ||
const declaration = macros[0]?.declaration | ||
if (!declaration) return [] | ||
|
||
const regExpParams = new RegExp(/\((.*?)\)/) | ||
const regExpParamsResult = regExpParams.exec(declaration) | ||
|
||
let _declaration = declaration | ||
if (regExpParamsResult) { | ||
const paramsPresent = regExpParamsResult[1] | ||
|
||
const paramsTrimmed = paramsPresent.trim() | ||
const params = paramsTrimmed.split(',') | ||
params.forEach((param) => { | ||
const trimedParam = param.split('=')[0].trim() | ||
if (trimedParam.includes(' ')) { | ||
diagnostics.push({ | ||
message: `Param '${trimedParam}' cannot have space`, | ||
lineNumber, | ||
startColumnNumber: value.indexOf(trimedParam) + 1, | ||
endColumnNumber: value.indexOf(trimedParam) + trimedParam.length, | ||
severity: Severity.Warning | ||
}) | ||
} | ||
}) | ||
|
||
_declaration = declaration.split(`(${paramsPresent})`)[1] | ||
} | ||
|
||
const optionsPresent = _declaration.split('/')?.[1]?.trim().split(' ') | ||
|
||
optionsPresent | ||
?.filter((o) => !!o) | ||
.forEach((option) => { | ||
const trimmedOption = option.trim() | ||
if (!validOptions.includes(trimmedOption.toUpperCase())) { | ||
diagnostics.push({ | ||
message: `Option '${trimmedOption}' is not valid`, | ||
lineNumber, | ||
startColumnNumber: value.indexOf(trimmedOption) + 1, | ||
endColumnNumber: value.indexOf(trimmedOption) + trimmedOption.length, | ||
severity: Severity.Warning | ||
}) | ||
} | ||
}) | ||
|
||
return diagnostics | ||
} | ||
|
||
/** | ||
* Lint rule that checks if a line has followed syntax for macro definition | ||
*/ | ||
export const strictMacroDefinition: LineLintRule = { | ||
type: LintRuleType.Line, | ||
name, | ||
description, | ||
message, | ||
test | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters