From 85b2c65b58625034c1457958ee738264b8f177b7 Mon Sep 17 00:00:00 2001 From: Liam Barry Allan Date: Tue, 20 Sep 2022 21:36:54 -0400 Subject: [PATCH] No longer check strings inside of SQL statements (#124) Signed-off-by: Liam Barry Allan --- src/language/linter.js | 10 +++++--- tests/suite/linter.js | 57 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/language/linter.js b/src/language/linter.js index 5770dbe2..0597c259 100644 --- a/src/language/linter.js +++ b/src/language/linter.js @@ -240,6 +240,7 @@ module.exports = class Linter { const statement = Statement.parseStatement(currentStatement); let value; + let isEmbeddedSQL = false; if (statement.length >= 1) { if (statement[0].type === `directive` && statement[0].value.toUpperCase() === `/EOF`) { @@ -681,6 +682,7 @@ module.exports = class Linter { } break; case `EXEC`: + isEmbeddedSQL = true; if (rules.NoSELECTAll) { if (currentStatementUpper.includes(`SELECT *`)) { errors.push({ @@ -756,7 +758,7 @@ module.exports = class Linter { let part; if (statement.length > 0 && [`declare`, `end`].includes(statement[0].type) === false) { - const isSQL = (statement[0].type === `word` && statement[0].value.toUpperCase() === `EXEC`); + // const isSQL = (statement[0].type === `word` && statement[0].value.toUpperCase() === `EXEC`); for (let i = 0; i < statement.length; i++) { part = statement[i]; @@ -833,7 +835,7 @@ module.exports = class Linter { // Check the casing of the reference matches the definition const definedName = definedNames.find(defName => defName.toUpperCase() === upperName); if (definedName && definedName !== part.value) { - if (isSQL === false || (isSQL && statement[i-1] && statement[i-1].type === `seperator`)) { + if (isEmbeddedSQL === false || (isEmbeddedSQL && statement[i-1] && statement[i-1].type === `seperator`)) { errors.push({ range: new vscode.Range( statementStart, @@ -938,7 +940,7 @@ module.exports = class Linter { break; case `string`: - if (part.value.substring(1, part.value.length-1).trim() === `` && rules.RequireBlankSpecial) { + if (part.value.substring(1, part.value.length-1).trim() === `` && rules.RequireBlankSpecial && !isEmbeddedSQL) { errors.push({ range: new vscode.Range( statementStart, @@ -949,7 +951,7 @@ module.exports = class Linter { newValue: `*BLANK` }); - } else if (rules.StringLiteralDupe) { + } else if (rules.StringLiteralDupe && !isEmbeddedSQL) { let foundBefore = stringLiterals.find(literal => literal.value === part.value); // If it does not exist on our list, we can add it diff --git a/tests/suite/linter.js b/tests/suite/linter.js index 3359f79e..c214f52f 100644 --- a/tests/suite/linter.js +++ b/tests/suite/linter.js @@ -2676,4 +2676,59 @@ exports.linter40 = async () => { }, cache); assert.strictEqual(errors.length, 0); -}; \ No newline at end of file +}; + +exports.linter4 = async () => { + const lines = [ + `**FREE`, + ``, + `Ctl-Opt DFTACTGRP(*No);`, + ``, + `Dsply 'aaa';`, + `DSPLY '';`, + `Dsply 'aaa';`, + ``, + `EXEC SQL`, + ` Select nullif('aaa', '') from sysibm/sysdummy1;`, + `Return;` + ].join(`\n`); + + const parser = new Parser(); + const cache = await parser.getDocs(uri, lines); + const { errors } = Linter.getErrors({uri, content: lines}, { + RequireBlankSpecial: true, + StringLiteralDupe: true + }, cache); + + assert.strictEqual(errors.length, 3); + + assert.deepStrictEqual(errors[0], { + range: new vscode.Range(5, 0, 5, 8), + offset: { + position: 6, + length: 8 + }, + type: `RequireBlankSpecial`, + newValue: `*BLANK` + }); + + assert.deepStrictEqual(errors[1], { + range: new vscode.Range(4, 0, 4, 11), + offset: { + position: 6, + length: 11 + }, + type: `StringLiteralDupe`, + newValue: undefined + }); + + assert.deepStrictEqual(errors[2], { + range: new vscode.Range(6, 0, 6, 11), + offset: { + position: 6, + length: 11 + }, + type: `StringLiteralDupe`, + newValue: undefined + }); +} \ No newline at end of file