diff --git a/.vscode/launch.json b/.vscode/launch.json index dd6fe634..ff1fc1ca 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -39,7 +39,7 @@ "type": "npm", "script": "compile:tests" }, - "args": ["issue_239"], + "args": [], "env": { "INCLUDE_DIR": "${workspaceFolder}" } diff --git a/language/linter.ts b/language/linter.ts index a3b049d8..c22d7bf1 100644 --- a/language/linter.ts +++ b/language/linter.ts @@ -828,9 +828,12 @@ export default class Linter { const definedProcedure = globalProcs.find(proc => proc.name.toUpperCase() === upperName); if (definedProcedure) { let requiresBlock = false; - // Don't require parms for procedures found in Ctl-Opt - if (statement[0].value.toUpperCase() === `CTL-OPT` || statement[0].type === `directive`) { + // Don't require parms for procedures found in Ctl-Opt or directives + if (isDeclare || isDirective) { // do nothing + } else if (statement[i-2] && statement[i-2].type === `builtin` && statement[i-2].value?.toUpperCase() === `%PADDR`) { + // Do nothing because you can pass a function to PADDR as a reference + } else if (statement.length <= i + 1) { requiresBlock = true; } else if (statement[i + 1].type !== `openbracket`) { diff --git a/tests/suite/linter.js b/tests/suite/linter.js index 243282cb..7e8d0f72 100644 --- a/tests/suite/linter.js +++ b/tests/suite/linter.js @@ -3301,4 +3301,55 @@ exports.issue_251 = async () => { assert.strictEqual(errors.length, 1); assert.strictEqual(errors[0].type, `ForceOptionalParens`); assert.strictEqual(lines.substring(errors[0].offset.position, errors[0].offset.end), `iCost >= 10000`); +} + +exports.paddr_issue_250 = async () => { + const lines = [ + `**FREE`, + `ctl-opt dftactgrp(*NO);`, + `dcl-s callback pointer(*PROC);`, + `callback = %paddr('SOMEOTHERFUNCTION');`, + ``, + `.///`, + `// The following line will incorrectly be flagged in error.`, + `///`, + `callback = %paddr(someFunction);`, + ``, + ``, + `*inLR = *ON;`, + `return;`, + `dcl-proc someFunction;`, + ` dcl-pi *N int(10);`, + ` value1 char(10) const;`, + ` value2 char(10) const;`, + ` end-pi;`, + ` if value1 < value2;`, + ` return -1;`, + ` endif;`, + ` if value1 > value2;`, + ` return 1;`, + ` endif;`, + ` return 0;`, + `end-proc;`, + `dcl-proc someOtherFunction;`, + ` dcl-pi *N int(10);`, + ` value1 int(10) const;`, + ` value2 int(10) const;`, + ` end-pi;`, + ` if value1 < value2;`, + ` return -1;`, + ` endif;`, + ` if value1 > value2;`, + ` return 1;`, + ` endif;`, + ` return 0;`, + `end-proc;`, + ].join(`\n`); + + const cache = await parser.getDocs(uri, lines, {ignoreCache: true, withIncludes: true}); + const { errors } = Linter.getErrors({ uri, content: lines }, { + RequiresParameter: true + }, cache); + + assert.strictEqual(errors.length, 0); } \ No newline at end of file