From f0304f77ec1032187763bb360fbc2d69c27895b9 Mon Sep 17 00:00:00 2001 From: Mark Pearce Date: Fri, 13 Dec 2024 14:43:15 -0400 Subject: [PATCH] Ensures diagnostic on using parent function var in inner func (#1369) --- src/bscPlugin/validation/BrsFileValidator.ts | 4 ++ .../validation/ScopeValidator.spec.ts | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/bscPlugin/validation/BrsFileValidator.ts b/src/bscPlugin/validation/BrsFileValidator.ts index 81e0bd270..57059e2c3 100644 --- a/src/bscPlugin/validation/BrsFileValidator.ts +++ b/src/bscPlugin/validation/BrsFileValidator.ts @@ -167,6 +167,10 @@ export class BrsFileValidator { FunctionExpression: (node) => { const funcSymbolTable = node.getSymbolTable(); const isInlineFunc = !(isFunctionStatement(node.parent) || isMethodStatement(node.parent)); + if (isInlineFunc) { + // symbol table should not include any symbols from parent func + funcSymbolTable.pushParentProvider(() => node.findAncestor(isBody).getSymbolTable()); + } if (!funcSymbolTable?.hasSymbol('m', SymbolTypeFlag.runtime) || isInlineFunc) { if (!isTypecastStatement(node.body?.statements?.[0])) { funcSymbolTable?.addSymbol('m', { isInstance: true }, new AssociativeArrayType(), SymbolTypeFlag.runtime); diff --git a/src/bscPlugin/validation/ScopeValidator.spec.ts b/src/bscPlugin/validation/ScopeValidator.spec.ts index ad39d04fe..64c9a3399 100644 --- a/src/bscPlugin/validation/ScopeValidator.spec.ts +++ b/src/bscPlugin/validation/ScopeValidator.spec.ts @@ -1960,6 +1960,50 @@ describe('ScopeValidator', () => { program.validate(); expectZeroDiagnostics(program); }); + + it('has an diagnostic when using a variable defined in parent function', () => { + program.setFile('source/main.bs', ` + function parentFunction() + parentVar = "test" + + innerFunction = sub() + ' Attempting to use parentVar from the parent function scope + print parentVar ' This should trigger a diagnostic + otherFunc() ' this is fine + end sub + + innerFunction() + end function + + sub otherFunc() + print "hello" + end sub + `); + + program.validate(); + expectDiagnostics(program, [ + DiagnosticMessages.cannotFindName('parentVar') + ]); + }); + + it('has an diagnostic when using a param from parent function', () => { + program.setFile('source/main.bs', ` + function parentFunction(outerVal) + parentVar = "test" + + innerFunction = sub(inner) + print inner + outer + end sub + + innerFunction(2) + end function + `); + + program.validate(); + expectDiagnostics(program, [ + DiagnosticMessages.cannotFindName('outer') + ]); + }); }); describe('itemCannotBeUsedAsVariable', () => {