From 6b9817607cd8b28a664ba4fceb09fb83507218c9 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 28 Dec 2023 11:19:22 +0000 Subject: [PATCH 01/11] Add new rule of LowercaseDirectives --- .../server/src/providers/linter/index.ts | 1 + language/linter.ts | 40 ++++++++++++++----- language/parserTypes.ts | 1 + package-lock.json | 4 +- schemas/rpglint.json | 5 +++ 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/extension/server/src/providers/linter/index.ts b/extension/server/src/providers/linter/index.ts index f400e8ac..0f5f94e6 100644 --- a/extension/server/src/providers/linter/index.ts +++ b/extension/server/src/providers/linter/index.ts @@ -314,6 +314,7 @@ export function getActions(document: TextDocument, errors: IssueRange[]) { case `SpecificCasing`: case `IncorrectVariableCase`: + case `LowercaseDirectives`: case `UppercaseDirectives`: if (error.newValue) { action = CodeAction.create(`Correct casing to '${error.newValue}'`, CodeActionKind.QuickFix); diff --git a/language/linter.ts b/language/linter.ts index 2e02eca0..23bea18b 100644 --- a/language/linter.ts +++ b/language/linter.ts @@ -26,6 +26,7 @@ const errorText = { 'StringLiteralDupe': `Same string literal used more than once. Consider using a constant instead.`, 'RequireBlankSpecial': `\`*BLANK\` should be used over empty string literals.`, 'CopybookDirective': `Directive does not match requirement.`, + 'LowercaseDirectives': `Directives must be in lowercase.`, 'UppercaseDirectives': `Directives must be in uppercase.`, 'NoSQLJoins': `SQL joins are not allowed. Consider creating a view instead.`, 'NoGlobalsInProcedures': `Global variables should not be referenced in procedures.`, @@ -203,15 +204,6 @@ export default class Linter { case `directive`: value = statement[0].value; - if (rules.UppercaseDirectives) { - if (value !== value.toUpperCase()) { - errors.push({ - offset: { position: statement[0].range.start, end: statement[0].range.end }, - type: `UppercaseDirectives`, - newValue: value.toUpperCase() - }); - } - } if (rules.CopybookDirective || rules.IncludeMustBeRelative) { if ([`/COPY`, `/INCLUDE`].includes(value.toUpperCase())) { @@ -291,8 +283,13 @@ export default class Linter { } if (rules.CopybookDirective) { - const correctDirective = `/${rules.CopybookDirective.toUpperCase()}`; - if (value.toUpperCase() !== correctDirective) { + let correctDirective = `/${rules.CopybookDirective.toUpperCase()}`; + let correctValue = value.toUpperCase(); + if (rules.LowercaseDirectives) { + correctDirective = correctDirective.toLowerCase(); + correctValue = value.toLowerCase(); + } + if (correctValue !== correctDirective) { errors.push({ offset: { position: statement[0].range.start, end: statement[0].range.end }, type: `CopybookDirective`, @@ -302,6 +299,27 @@ export default class Linter { } } } + + if (rules.LowercaseDirectives) { + if (value !== value.toLowerCase()) { + errors.push({ + offset: { position: statement[0].range.start, end: statement[0].range.end }, + type: `LowercaseDirectives`, + newValue: value.toLowerCase() + }); + } + } + + if (rules.UppercaseDirectives) { + if (value !== value.toUpperCase()) { + errors.push({ + offset: { position: statement[0].range.start, end: statement[0].range.end }, + type: `UppercaseDirectives`, + newValue: value.toUpperCase() + }); + } + } + break; case `declare`: diff --git a/language/parserTypes.ts b/language/parserTypes.ts index c4d4355a..2a4716fe 100644 --- a/language/parserTypes.ts +++ b/language/parserTypes.ts @@ -41,6 +41,7 @@ export interface Rules { literalMinimum?: number; RequireBlankSpecial?: boolean; CopybookDirective?: "copy"|"include"; + LowercaseDirectives?: boolean; UppercaseDirectives?: boolean; NoSQLJoins?: boolean; NoGlobalsInProcedures?: boolean; diff --git a/package-lock.json b/package-lock.json index 2e2c6570..e4a68173 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-rpgle", - "version": "0.20.2", + "version": "0.24.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "vscode-rpgle", - "version": "0.20.2", + "version": "0.24.0", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/schemas/rpglint.json b/schemas/rpglint.json index 9a452c0b..a9075dee 100644 --- a/schemas/rpglint.json +++ b/schemas/rpglint.json @@ -85,6 +85,11 @@ ], "description": "Force which directive which must be used to include other source. (Copy or Include)" }, + "LowercaseDirectives": { + "$id": "#/properties/LowercaseDirectives", + "type": "boolean", + "description": "Directives must be in lowercase." + }, "UppercaseDirectives": { "$id": "#/properties/UppercaseDirectives", "type": "boolean", From d186cbe10b7ac6ffa24d3481c699aa2e2863ede1 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 28 Dec 2023 11:19:50 +0000 Subject: [PATCH 02/11] Fix IncorrectVariableCase when definition exists in copybook --- extension/server/src/providers/linter/documentFormatting.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extension/server/src/providers/linter/documentFormatting.ts b/extension/server/src/providers/linter/documentFormatting.ts index 3a73d03b..e9e01a30 100644 --- a/extension/server/src/providers/linter/documentFormatting.ts +++ b/extension/server/src/providers/linter/documentFormatting.ts @@ -23,7 +23,8 @@ export default async function documentFormattingProvider(params: DocumentFormatt // Need to fetch the docs again incase comments were added // as part of RequiresProcedureDescription docs = await parser.getDocs(document.uri, document.getText(), { - ignoreCache: true + ignoreCache: true, + withIncludes: true }); // Next up, let's fix all the other things! From c7bfee50839f470beb24c1d0ccd5e27b9ebf2023 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 28 Dec 2023 11:19:58 +0000 Subject: [PATCH 03/11] Fix Quick Fix comment for RequireBlankSpecial --- extension/server/src/providers/linter/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/server/src/providers/linter/index.ts b/extension/server/src/providers/linter/index.ts index 0f5f94e6..ef45c728 100644 --- a/extension/server/src/providers/linter/index.ts +++ b/extension/server/src/providers/linter/index.ts @@ -343,7 +343,7 @@ export function getActions(document: TextDocument, errors: IssueRange[]) { case `RequireBlankSpecial`: if (error.newValue) { - action = CodeAction.create(`Convert constant name to uppercase`, CodeActionKind.QuickFix); + action = CodeAction.create(`Convert empty string literal to *BLANK`, CodeActionKind.QuickFix); action.edit = { changes: { [document.uri]: [ From 2433427909db441b10f2f513f1d67aecdd678b0e Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 28 Dec 2023 12:35:21 +0000 Subject: [PATCH 04/11] eslint quote fix --- tests/suite/linter.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/suite/linter.js b/tests/suite/linter.js index 4add3ec3..c3c1d4a7 100644 --- a/tests/suite/linter.js +++ b/tests/suite/linter.js @@ -1269,14 +1269,14 @@ exports.linter15 = async () => { assert.deepStrictEqual(errors[0], { offset: { position: 36, end: 38 }, - type: 'PrettyComments', - newValue: '// ' + type: `PrettyComments`, + newValue: `// ` }); assert.deepStrictEqual(errors[1], { offset: { position: 207, end: 209 }, - type: 'PrettyComments', - newValue: '// ' + type: `PrettyComments`, + newValue: `// ` }); }; From d6534edea7ee524350c2ca405bb6a73883213774 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 28 Dec 2023 12:40:59 +0000 Subject: [PATCH 05/11] add tests for IncorrectVariableCase, UppercaseDirectives and LowercaseDirectives --- tests/rpgle/copy3.rpgle | 3 ++ tests/suite/directives.js | 106 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 tests/rpgle/copy3.rpgle diff --git a/tests/rpgle/copy3.rpgle b/tests/rpgle/copy3.rpgle new file mode 100644 index 00000000..b07ca6c1 --- /dev/null +++ b/tests/rpgle/copy3.rpgle @@ -0,0 +1,3 @@ +**FREE + +Dcl-S CustomerName_t varchar(40) template; diff --git a/tests/suite/directives.js b/tests/suite/directives.js index ff5f91f3..cf55e6cf 100644 --- a/tests/suite/directives.js +++ b/tests/suite/directives.js @@ -463,5 +463,111 @@ module.exports = { const someDs = cache.find(`someDs`); assert.strictEqual(someDs.keyword[`BASED`], undefined); + }, + + variable_case1: async () => { + const lines = [ + `**FREE`, + `Ctl-Opt DftActGrp(*No);`, + `/copy './tests/rpgle/copy3.rpgle'`, + `Dcl-S MyCustomerName1 like(customername_t);`, + `Dcl-S MyCustomerName2 like(CustomerName_t);`, + `Dcl-S MyCustomerName3 like(CUSTOMERNAME_t);`, + `Dcl-S MyCustomerName4 like(CUSTOMERNAME_T);`, + `MyCustomerName1 = 'John Smith';`, + `dsply MyCustomerName1;`, + `Return;` + ].join(`\n`); + + const cache = await parser.getDocs(uri, lines, {withIncludes: true, ignoreCache: true}); + const { errors } = Linter.getErrors({ uri, content: lines }, { + IncorrectVariableCase: true + }, cache); + + assert.strictEqual(errors.length, 3, `Expect length of 3`); + + assert.deepStrictEqual(errors[0], { + offset: { position: 92, end: 106 }, + type: `IncorrectVariableCase`, + newValue: `CustomerName_t` + }); + + assert.deepStrictEqual(errors[1], { + offset: { position: 180, end: 194 }, + type: `IncorrectVariableCase`, + newValue: `CustomerName_t` + }); + + assert.deepStrictEqual(errors[2], { + offset: { position: 224, end: 238 }, + type: `IncorrectVariableCase`, + newValue: `CustomerName_t` + }); + }, + + uppercase1: async () => { + const lines = [ + `**FREE`, + `Ctl-Opt DftActGrp(*No);`, + `/copy './tests/rpgle/copy1.rpgle'`, + `/Copy './tests/rpgle/copy2.rpgle'`, + `/COPY './tests/rpgle/copy3.rpgle'`, + `Dcl-S MyCustomerName1 like(CustomerName_t);`, + `MyCustomerName1 = 'John Smith';`, + `dsply MyCustomerName1;`, + `Return;` + ].join(`\n`); + + const cache = await parser.getDocs(uri, lines, {withIncludes: true, ignoreCache: true}); + const { errors } = Linter.getErrors({ uri, content: lines }, { + UppercaseDirectives: true + }, cache); + + assert.strictEqual(errors.length, 2, `Expect length of 2`); + + assert.deepStrictEqual(errors[0], { + offset: { position: 31, end: 36 }, + type: `UppercaseDirectives`, + newValue: `/COPY` + }); + + assert.deepStrictEqual(errors[1], { + offset: { position: 65, end: 70 }, + type: `UppercaseDirectives`, + newValue: `/COPY` + }); + }, + + lowercase1: async () => { + const lines = [ + `**FREE`, + `Ctl-Opt DftActGrp(*No);`, + `/copy './tests/rpgle/copy1.rpgle'`, + `/Copy './tests/rpgle/copy2.rpgle'`, + `/COPY './tests/rpgle/copy3.rpgle'`, + `Dcl-S MyCustomerName1 like(CustomerName_t);`, + `MyCustomerName1 = 'John Smith';`, + `dsply MyCustomerName1;`, + `Return;` + ].join(`\n`); + + const cache = await parser.getDocs(uri, lines, {withIncludes: true, ignoreCache: true}); + const { errors } = Linter.getErrors({ uri, content: lines }, { + LowercaseDirectives: true + }, cache); + + assert.strictEqual(errors.length, 2, `Expect length of 2`); + + assert.deepStrictEqual(errors[0], { + offset: { position: 65, end: 70 }, + type: `LowercaseDirectives`, + newValue: `/copy` + }); + + assert.deepStrictEqual(errors[1], { + offset: { position: 99, end: 104 }, + type: `LowercaseDirectives`, + newValue: `/copy` + }); } } \ No newline at end of file From f46a13ed47fcf97d23fd6c8a4f9a152dce0068c6 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 28 Dec 2023 12:56:55 +0000 Subject: [PATCH 06/11] Added myself to contributors list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 25c5e0aa..9cf4d9d3 100644 --- a/README.md +++ b/README.md @@ -43,3 +43,4 @@ Thanks so much to everyone [who has contributed](https://github.com/codefori/vsc - [@p-behr](https://github.com/p-behr) - [@chrjorgensen](https://github.com/chrjorgensen) - [@sebjulliand](https://github.com/sebjulliand) +- [@richardm90](https://github.com/richardm90) \ No newline at end of file From ae54a5a518498ace4a0e2a55fca33232b7fef66a Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 18 Jan 2024 16:09:28 +0000 Subject: [PATCH 07/11] Reverse previous change, not necessary --- extension/server/src/providers/linter/documentFormatting.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/extension/server/src/providers/linter/documentFormatting.ts b/extension/server/src/providers/linter/documentFormatting.ts index e9e01a30..3a73d03b 100644 --- a/extension/server/src/providers/linter/documentFormatting.ts +++ b/extension/server/src/providers/linter/documentFormatting.ts @@ -23,8 +23,7 @@ export default async function documentFormattingProvider(params: DocumentFormatt // Need to fetch the docs again incase comments were added // as part of RequiresProcedureDescription docs = await parser.getDocs(document.uri, document.getText(), { - ignoreCache: true, - withIncludes: true + ignoreCache: true }); // Next up, let's fix all the other things! From 42b690e7efc1e45f7e0e0fae83714a71101a9479 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 18 Jan 2024 16:10:41 +0000 Subject: [PATCH 08/11] Change LowercaseDirectives to DirectiveCasing --- .../server/src/providers/linter/index.ts | 2 +- language/linter.ts | 19 ++++++--- language/parserTypes.ts | 2 +- schemas/rpglint.json | 12 ++++-- tests/suite/directives.js | 39 +++++++++++++++++-- 5 files changed, 60 insertions(+), 14 deletions(-) diff --git a/extension/server/src/providers/linter/index.ts b/extension/server/src/providers/linter/index.ts index ef45c728..87f8cd71 100644 --- a/extension/server/src/providers/linter/index.ts +++ b/extension/server/src/providers/linter/index.ts @@ -314,7 +314,7 @@ export function getActions(document: TextDocument, errors: IssueRange[]) { case `SpecificCasing`: case `IncorrectVariableCase`: - case `LowercaseDirectives`: + case `DirectiveCasing`: case `UppercaseDirectives`: if (error.newValue) { action = CodeAction.create(`Correct casing to '${error.newValue}'`, CodeActionKind.QuickFix); diff --git a/language/linter.ts b/language/linter.ts index 23bea18b..1044f789 100644 --- a/language/linter.ts +++ b/language/linter.ts @@ -26,7 +26,7 @@ const errorText = { 'StringLiteralDupe': `Same string literal used more than once. Consider using a constant instead.`, 'RequireBlankSpecial': `\`*BLANK\` should be used over empty string literals.`, 'CopybookDirective': `Directive does not match requirement.`, - 'LowercaseDirectives': `Directives must be in lowercase.`, + 'DirectiveCasing': `Does not match required case.`, 'UppercaseDirectives': `Directives must be in uppercase.`, 'NoSQLJoins': `SQL joins are not allowed. Consider creating a view instead.`, 'NoGlobalsInProcedures': `Global variables should not be referenced in procedures.`, @@ -285,7 +285,7 @@ export default class Linter { if (rules.CopybookDirective) { let correctDirective = `/${rules.CopybookDirective.toUpperCase()}`; let correctValue = value.toUpperCase(); - if (rules.LowercaseDirectives) { + if (rules.DirectiveCasing === `lower`) { correctDirective = correctDirective.toLowerCase(); correctValue = value.toLowerCase(); } @@ -300,16 +300,26 @@ export default class Linter { } } - if (rules.LowercaseDirectives) { + if (rules.DirectiveCasing === `lower`) { if (value !== value.toLowerCase()) { errors.push({ offset: { position: statement[0].range.start, end: statement[0].range.end }, - type: `LowercaseDirectives`, + type: `DirectiveCasing`, newValue: value.toLowerCase() }); } } + if (rules.DirectiveCasing === `upper`) { + if (value !== value.toUpperCase()) { + errors.push({ + offset: { position: statement[0].range.start, end: statement[0].range.end }, + type: `DirectiveCasing`, + newValue: value.toUpperCase() + }); + } + } + if (rules.UppercaseDirectives) { if (value !== value.toUpperCase()) { errors.push({ @@ -319,7 +329,6 @@ export default class Linter { }); } } - break; case `declare`: diff --git a/language/parserTypes.ts b/language/parserTypes.ts index 2a4716fe..29a69d03 100644 --- a/language/parserTypes.ts +++ b/language/parserTypes.ts @@ -41,7 +41,7 @@ export interface Rules { literalMinimum?: number; RequireBlankSpecial?: boolean; CopybookDirective?: "copy"|"include"; - LowercaseDirectives?: boolean; + DirectiveCasing?: "lower"|"upper"; UppercaseDirectives?: boolean; NoSQLJoins?: boolean; NoGlobalsInProcedures?: boolean; diff --git a/schemas/rpglint.json b/schemas/rpglint.json index a9075dee..5803c2a8 100644 --- a/schemas/rpglint.json +++ b/schemas/rpglint.json @@ -85,10 +85,14 @@ ], "description": "Force which directive which must be used to include other source. (Copy or Include)" }, - "LowercaseDirectives": { - "$id": "#/properties/LowercaseDirectives", - "type": "boolean", - "description": "Directives must be in lowercase." + "DirectiveCase": { + "$id": "#/properties/DirectiveCase", + "type": "string", + "enum": [ + "lower", + "upper" + ], + "description": "The expected casing of directives (lower or upper)." }, "UppercaseDirectives": { "$id": "#/properties/UppercaseDirectives", diff --git a/tests/suite/directives.js b/tests/suite/directives.js index cf55e6cf..6ece64e3 100644 --- a/tests/suite/directives.js +++ b/tests/suite/directives.js @@ -518,6 +518,39 @@ module.exports = { `Return;` ].join(`\n`); + const cache = await parser.getDocs(uri, lines, {withIncludes: true, ignoreCache: true}); + const { errors } = Linter.getErrors({ uri, content: lines }, { + DirectiveCasing: `upper` + }, cache); + + assert.strictEqual(errors.length, 2, `Expect length of 2`); + + assert.deepStrictEqual(errors[0], { + offset: { position: 31, end: 36 }, + type: `DirectiveCasing`, + newValue: `/COPY` + }); + + assert.deepStrictEqual(errors[1], { + offset: { position: 65, end: 70 }, + type: `DirectiveCasing`, + newValue: `/COPY` + }); + }, + + uppercase2: async () => { + const lines = [ + `**FREE`, + `Ctl-Opt DftActGrp(*No);`, + `/copy './tests/rpgle/copy1.rpgle'`, + `/Copy './tests/rpgle/copy2.rpgle'`, + `/COPY './tests/rpgle/copy3.rpgle'`, + `Dcl-S MyCustomerName1 like(CustomerName_t);`, + `MyCustomerName1 = 'John Smith';`, + `dsply MyCustomerName1;`, + `Return;` + ].join(`\n`); + const cache = await parser.getDocs(uri, lines, {withIncludes: true, ignoreCache: true}); const { errors } = Linter.getErrors({ uri, content: lines }, { UppercaseDirectives: true @@ -553,20 +586,20 @@ module.exports = { const cache = await parser.getDocs(uri, lines, {withIncludes: true, ignoreCache: true}); const { errors } = Linter.getErrors({ uri, content: lines }, { - LowercaseDirectives: true + DirectiveCasing: `lower` }, cache); assert.strictEqual(errors.length, 2, `Expect length of 2`); assert.deepStrictEqual(errors[0], { offset: { position: 65, end: 70 }, - type: `LowercaseDirectives`, + type: `DirectiveCasing`, newValue: `/copy` }); assert.deepStrictEqual(errors[1], { offset: { position: 99, end: 104 }, - type: `LowercaseDirectives`, + type: `DirectiveCasing`, newValue: `/copy` }); } From 16807babdfbc89bdddff4b612752dbe8b13ce1f8 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 18 Jan 2024 16:25:38 +0000 Subject: [PATCH 09/11] Flag UppercaseDirectives as deprecated --- schemas/rpglint.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/schemas/rpglint.json b/schemas/rpglint.json index 5803c2a8..79dccbfe 100644 --- a/schemas/rpglint.json +++ b/schemas/rpglint.json @@ -1,5 +1,5 @@ { - "$schema": "http://json-schema.org/draft-07/schema", + "$schema": "http://json-schema.org/draft-07/schema#", "$id": "https://github.com/halcyon-tech/vscode-ibmi", "type": "object", "description": "Available lint configuration for RPGLE", @@ -97,7 +97,8 @@ "UppercaseDirectives": { "$id": "#/properties/UppercaseDirectives", "type": "boolean", - "description": "Directives must be in uppercase." + "description": "Directives must be in uppercase.", + "deprecated": true }, "NoSQLJoins": { "$id": "#/properties/NoSQLJoins", From 0a40db81043b8c37ab7f2e9b9953a7ad92a1d69a Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 18 Jan 2024 16:43:10 +0000 Subject: [PATCH 10/11] Reinstate change, fixes problem in Format Document --- extension/server/src/providers/linter/documentFormatting.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extension/server/src/providers/linter/documentFormatting.ts b/extension/server/src/providers/linter/documentFormatting.ts index 3a73d03b..e9e01a30 100644 --- a/extension/server/src/providers/linter/documentFormatting.ts +++ b/extension/server/src/providers/linter/documentFormatting.ts @@ -23,7 +23,8 @@ export default async function documentFormattingProvider(params: DocumentFormatt // Need to fetch the docs again incase comments were added // as part of RequiresProcedureDescription docs = await parser.getDocs(document.uri, document.getText(), { - ignoreCache: true + ignoreCache: true, + withIncludes: true }); // Next up, let's fix all the other things! From 7ed6c660d23725d1b649fbb6caa44bca5b619031 Mon Sep 17 00:00:00 2001 From: Richard Moulton Date: Thu, 18 Jan 2024 17:13:04 +0000 Subject: [PATCH 11/11] Tweaked UppercaseDirectives error text to indicate the option is deprecated. --- language/linter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language/linter.ts b/language/linter.ts index 1044f789..6dc9acf4 100644 --- a/language/linter.ts +++ b/language/linter.ts @@ -27,7 +27,7 @@ const errorText = { 'RequireBlankSpecial': `\`*BLANK\` should be used over empty string literals.`, 'CopybookDirective': `Directive does not match requirement.`, 'DirectiveCasing': `Does not match required case.`, - 'UppercaseDirectives': `Directives must be in uppercase.`, + 'UppercaseDirectives': `Directives must be in uppercase. UppercaseDirectives option is deprecated, consider using DirectiveCasing.`, 'NoSQLJoins': `SQL joins are not allowed. Consider creating a view instead.`, 'NoGlobalsInProcedures': `Global variables should not be referenced in procedures.`, 'NoCTDATA': `\`CTDATA\` is not allowed.`,