From 870120bc13909a3681e0f0a2351806849476342f Mon Sep 17 00:00:00 2001 From: undergroundwires Date: Sun, 12 May 2024 12:32:42 +0200 Subject: [PATCH] Add specific empty function name compiler error This commit adds checks to rjeect functions with empty or whitespace names. The compiler throws a specific errror when it encounters a function data object lacking a proper name. This provides early detection and clear feedback on invalid function definitions, helping in faster debugging and ensuring script integrity in the compilation process. The enhancement aims to provide early detection and clear feedback on invalid function definitions, aiding in faster debugging and ensuring script integrity in the compilation process. when it encounters a function data object lacking a proper name. It covers scenarios where the function name might be an empty string, undefined, or solely consist of whitespace. --- .../Function/SharedFunctionsParser.ts | 11 ++++++++++ .../Function/SharedFunctionsParser.spec.ts | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts b/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts index 60f8d425..9cdb4173 100644 --- a/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts +++ b/src/application/Parser/Script/Compiler/Function/SharedFunctionsParser.ts @@ -98,6 +98,7 @@ function hasCall(data: FunctionData): data is CallFunctionData { } function ensureValidFunctions(functions: readonly FunctionData[]) { + ensureNoUnnamedFunctions(functions); ensureNoDuplicatesInFunctionNames(functions); ensureEitherCallOrCodeIsDefined(functions); ensureNoDuplicateCode(functions); @@ -108,6 +109,16 @@ function printList(list: readonly string[]): string { return `"${list.join('","')}"`; } +function ensureNoUnnamedFunctions(functions: readonly FunctionData[]) { + const functionsWithoutNames = functions.filter( + (func) => !func.name || func.name.trim().length === 0, + ); + if (functionsWithoutNames.length) { + const invalidFunctions = functionsWithoutNames.map((f) => JSON.stringify(f)); + throw new Error(`Some function(s) have no names:\n${invalidFunctions.join('\n')}`); + } +} + function ensureEitherCallOrCodeIsDefined(holders: readonly FunctionData[]) { // Ensure functions do not define both call and code const withBothCallAndCode = holders.filter((holder) => hasCode(holder) && hasCall(holder)); diff --git a/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts b/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts index 47616539..29426618 100644 --- a/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts +++ b/tests/unit/application/Parser/Script/Compiler/Function/SharedFunctionsParser.spec.ts @@ -26,6 +26,27 @@ describe('SharedFunctionsParser', () => { }); describe('parseFunctions', () => { describe('validates functions', () => { + it('throws when functions have no names', () => { + // arrange + const invalidFunctions = [ + createFunctionDataWithCode() + .withCode('test function 1') + .withName(' '), // Whitespace, + createFunctionDataWithCode() + .withCode('test function 2') + .withName(undefined as unknown as string), // Undefined + createFunctionDataWithCode() + .withCode('test function 3') + .withName(''), // Empty + ]; + const expectedError = `Some function(s) have no names:\n${invalidFunctions.map((f) => JSON.stringify(f)).join('\n')}`; + // act + const act = () => new ParseFunctionsCallerWithDefaults() + .withFunctions(invalidFunctions) + .parseFunctions(); + // assert + expect(act).to.throw(expectedError); + }); it('throws when functions have same names', () => { // arrange const name = 'same-func-name';