From 4a6b4a725920c16c1bc69335944e70d9a5f8f389 Mon Sep 17 00:00:00 2001 From: Bronley Plumb Date: Mon, 8 Jul 2024 13:49:04 -0400 Subject: [PATCH] Fix some potential after-dispose crashes --- src/Program.spec.ts | 9 +++++++++ src/Scope.ts | 6 +++--- src/bscPlugin/validation/ScopeValidator.ts | 2 +- src/lsp/ProjectManager.ts | 2 -- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Program.spec.ts b/src/Program.spec.ts index a568e879b..2c4d0b04a 100644 --- a/src/Program.spec.ts +++ b/src/Program.spec.ts @@ -44,6 +44,15 @@ describe('Program', () => { program.dispose(); }); + it('does not throw exception after calling validate() after dispose()', () => { + program.setFile('source/themes/alpha.bs', ` + sub main() + end sub + `); + program.dispose(); + program.validate(); + }); + it('Does not crash for file not referenced by any other scope', async () => { program.setFile('tests/testFile.spec.bs', ` function main(args as object) as object diff --git a/src/Scope.ts b/src/Scope.ts index 82ec7b86e..476348372 100644 --- a/src/Scope.ts +++ b/src/Scope.ts @@ -562,7 +562,7 @@ export class Scope { //get callables from own files this.enumerateOwnFiles((file) => { - for (let callable of file.callables) { + for (let callable of file?.callables ?? []) { result.push({ callable: callable, scope: this @@ -843,7 +843,7 @@ export class Scope { * Find various function collisions */ private diagnosticDetectFunctionCollisions(file: BscFile) { - for (let func of file.callables) { + for (let func of file?.callables ?? []) { const funcName = func.getName(ParseMode.BrighterScript); const lowerFuncName = funcName?.toLowerCase(); if (lowerFuncName) { @@ -932,7 +932,7 @@ export class Scope { */ private diagnosticDetectFunctionCallsWithWrongParamCount(file: BscFile, callableContainersByLowerName: CallableContainerMap) { //validate all function calls - for (let expCall of file.functionCalls) { + for (let expCall of file?.functionCalls ?? []) { let callableContainersWithThisName = callableContainersByLowerName.get(expCall.name.toLowerCase()); //use the first item from callablesByLowerName, because if there are more, that's a separate error diff --git a/src/bscPlugin/validation/ScopeValidator.ts b/src/bscPlugin/validation/ScopeValidator.ts index 900263cff..a2d924225 100644 --- a/src/bscPlugin/validation/ScopeValidator.ts +++ b/src/bscPlugin/validation/ScopeValidator.ts @@ -269,7 +269,7 @@ export class ScopeValidator { protected validateCreateObjectCalls(file: BrsFile) { const diagnostics: BsDiagnostic[] = []; - for (const call of file.functionCalls) { + for (const call of file?.functionCalls ?? []) { //skip non CreateObject function calls if (call.name?.toLowerCase() !== 'createobject' || !isLiteralExpression(call?.args[0]?.expression)) { continue; diff --git a/src/lsp/ProjectManager.ts b/src/lsp/ProjectManager.ts index 1d771f6bd..79129d3e6 100644 --- a/src/lsp/ProjectManager.ts +++ b/src/lsp/ProjectManager.ts @@ -72,8 +72,6 @@ export class ProjectManager { */ @TrackBusyStatus private async flushDocumentChanges(event: FlushEvent) { - this.logger.log('flushDocumentChanges', event.actions.map(x => x.srcPath)); - //ensure that we're fully initialized before proceeding await this.onInitialized();