1
0
mirror of https://github.com/sasjs/lint.git synced 2025-12-10 17:34:36 +00:00

chore: Code Refactor

This commit is contained in:
Saad Jutt
2021-05-22 00:08:24 +05:00
parent 020a1e08d0
commit 0caf31b7ff
4 changed files with 140 additions and 124 deletions

View File

@@ -1,8 +1,6 @@
import { Diagnostic } from '../../types/Diagnostic'
import { LintConfig } from '../../types'
import { Diagnostic, LintConfig, Macro, Severity } from '../../types'
import { FileLintRule } from '../../types/LintRule'
import { LintRuleType } from '../../types/LintRuleType'
import { Severity } from '../../types/Severity'
import { parseMacros } from '../../utils/parseMacros'
const name = 'strictMacroDefinition'
@@ -24,120 +22,136 @@ const validOptions = [
'STORE'
]
const processParams = (
content: string,
macro: Macro,
diagnostics: Diagnostic[]
): string => {
const declaration = macro.declaration
const regExpParams = new RegExp(/(?<=\().*(?=\))/)
const regExpParamsResult = regExpParams.exec(declaration)
let _declaration = declaration
if (regExpParamsResult) {
const paramsPresent = regExpParamsResult[0]
const params = paramsPresent.trim().split(',')
params.forEach((param) => {
const trimedParam = param.split('=')[0].trim()
let paramLineNumber: number = 1,
paramStartIndex: number = 1,
paramEndIndex: number = content.length
if (
macro.declarationLines.findIndex(
(dl) => dl.indexOf(trimedParam) !== -1
) === -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 declarationLineIndex = macro.declarationLines.findIndex(
(dl) => !!regEx.exec(dl)
)
if (declarationLineIndex !== -1) {
const declarationLine = macro.declarationLines[declarationLineIndex]
const partFound = regEx.exec(declarationLine)![0]
paramLineNumber = macro.startLineNumbers[declarationLineIndex]
paramStartIndex = declarationLine.indexOf(partFound)
paramEndIndex =
declarationLine.indexOf(partFound) + partFound.length
break
}
}
} else {
const declarationLineIndex = macro.declarationLines.findIndex(
(dl) => dl.indexOf(trimedParam) !== -1
)
const declarationLine = macro.declarationLines[declarationLineIndex]
paramLineNumber = macro.startLineNumbers[declarationLineIndex]
paramStartIndex = declarationLine.indexOf(trimedParam)
paramEndIndex =
declarationLine.indexOf(trimedParam) + trimedParam.length
}
if (trimedParam.includes(' ')) {
diagnostics.push({
message: `Param '${trimedParam}' cannot have space`,
lineNumber: paramLineNumber,
startColumnNumber: paramStartIndex + 1,
endColumnNumber: paramEndIndex,
severity: Severity.Warning
})
}
})
_declaration = declaration.split(`(${paramsPresent})`)[1]
}
return _declaration
}
const processOptions = (
_declaration: string,
macro: Macro,
diagnostics: Diagnostic[]
): void => {
let optionsPresent = _declaration.split('/')?.[1]?.trim()
if (optionsPresent) {
const regex = new RegExp(/="(.*?)"/, 'g')
let result = regex.exec(optionsPresent)
// removing Option's `="..."` part, e.g. des="..."
while (result) {
optionsPresent =
optionsPresent.slice(0, result.index) +
optionsPresent.slice(result.index + result[0].length)
result = regex.exec(optionsPresent)
}
optionsPresent
.split(' ')
?.filter((o) => !!o)
.forEach((option) => {
const trimmedOption = option.trim()
if (!validOptions.includes(trimmedOption.toUpperCase())) {
const declarationLineIndex = macro.declarationLines.findIndex(
(dl) => dl.indexOf(trimmedOption) !== -1
)
const declarationLine = macro.declarationLines[declarationLineIndex]
diagnostics.push({
message: `Option '${trimmedOption}' is not valid`,
lineNumber: macro.startLineNumbers[declarationLineIndex],
startColumnNumber: declarationLine.indexOf(trimmedOption) + 1,
endColumnNumber:
declarationLine.indexOf(trimmedOption) + trimmedOption.length,
severity: Severity.Warning
})
}
})
}
}
const test = (value: string, config?: LintConfig) => {
const diagnostics: Diagnostic[] = []
const macros = parseMacros(value, config)
macros.forEach((macro) => {
const declaration = macro.declaration
const _declaration = processParams(value, macro, diagnostics)
const regExpParams = new RegExp(/(?<=\().*(?=\))/)
const regExpParamsResult = regExpParams.exec(declaration)
let _declaration = declaration
if (regExpParamsResult) {
const paramsPresent = regExpParamsResult[0]
const paramsTrimmed = paramsPresent.trim()
const params = paramsTrimmed.split(',')
params.forEach((param) => {
const trimedParam = param.split('=')[0].trim()
let paramLineNumber: number = 1,
paramStartIndex: number = 1,
paramEndIndex: number = value.length
if (
macro.declarationLines.findIndex(
(dl) => dl.indexOf(trimedParam) !== -1
) === -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 declarationLineIndex = macro.declarationLines.findIndex(
(dl) => !!regEx.exec(dl)
)
if (declarationLineIndex !== -1) {
const declarationLine =
macro.declarationLines[declarationLineIndex]
const partFound = regEx.exec(declarationLine)![0]
paramLineNumber = macro.startLineNumbers[declarationLineIndex]
paramStartIndex = declarationLine.indexOf(partFound)
paramEndIndex =
declarationLine.indexOf(partFound) + partFound.length
break
}
}
} else {
const declarationLineIndex = macro.declarationLines.findIndex(
(dl) => dl.indexOf(trimedParam) !== -1
)
const declarationLine = macro.declarationLines[declarationLineIndex]
paramLineNumber = macro.startLineNumbers[declarationLineIndex]
paramStartIndex = declarationLine.indexOf(trimedParam)
paramEndIndex =
declarationLine.indexOf(trimedParam) + trimedParam.length
}
if (trimedParam.includes(' ')) {
diagnostics.push({
message: `Param '${trimedParam}' cannot have space`,
lineNumber: paramLineNumber,
startColumnNumber: paramStartIndex + 1,
endColumnNumber: paramEndIndex,
severity: Severity.Warning
})
}
})
_declaration = declaration.split(`(${paramsPresent})`)[1]
}
let optionsPresent = _declaration.split('/')?.[1]?.trim()
if (optionsPresent) {
const regex = new RegExp(/="(.*?)"/, 'g')
let result = regex.exec(optionsPresent)
while (result) {
optionsPresent =
optionsPresent.slice(0, result.index) +
optionsPresent.slice(result.index + result[0].length)
result = regex.exec(optionsPresent)
}
optionsPresent
.split(' ')
?.filter((o) => !!o)
.forEach((option) => {
const trimmedOption = option.trim()
if (!validOptions.includes(trimmedOption.toUpperCase())) {
const declarationLineIndex = macro.declarationLines.findIndex(
(dl) => dl.indexOf(trimmedOption) !== -1
)
const declarationLine = macro.declarationLines[declarationLineIndex]
diagnostics.push({
message: `Option '${trimmedOption}' is not valid`,
lineNumber: macro.startLineNumbers[declarationLineIndex],
startColumnNumber: declarationLine.indexOf(trimmedOption) + 1,
endColumnNumber:
declarationLine.indexOf(trimmedOption) + trimmedOption.length,
severity: Severity.Warning
})
}
})
}
processOptions(_declaration, macro, diagnostics)
})
return diagnostics

12
src/types/Macro.ts Normal file
View File

@@ -0,0 +1,12 @@
export interface Macro {
name: string
startLineNumbers: number[]
endLineNumber: number | null
declarationLines: string[]
terminationLine: string
declaration: string
termination: string
parentMacro: string
hasMacroNameInMend: boolean
mismatchedMendMacroName: string
}

View File

@@ -4,3 +4,4 @@ export * from './LintConfig'
export * from './LintRule'
export * from './LintRuleType'
export * from './Severity'
export * from './Macro'

View File

@@ -1,20 +1,7 @@
import { LintConfig } from '../types/LintConfig'
import { LintConfig, Macro } from '../types'
import { LineEndings } from '../types/LineEndings'
import { trimComments } from './trimComments'
interface Macro {
name: string
startLineNumbers: number[]
endLineNumber: number | null
declarationLines: string[]
terminationLine: string
declaration: string
termination: string
parentMacro: string
hasMacroNameInMend: boolean
mismatchedMendMacroName: string
}
export const parseMacros = (text: string, config?: LintConfig): Macro[] => {
const lineEnding = config?.lineEndings === LineEndings.CRLF ? '\r\n' : '\n'
const lines: string[] = text ? text.split(lineEnding) : []
@@ -39,6 +26,8 @@ export const parseMacros = (text: string, config?: LintConfig): Macro[] => {
const statements: string[] = trimmedLine.split(';')
if (isReadingMacroDefinition) {
// checking if code is split into statements based on `;` is a part of HTML Encoded Character
// if it happened, merges two statements into one
statements.forEach((statement, statementIndex) => {
if (/&[^\s]{1,5}$/.test(statement)) {
const next = statements[statementIndex]