From bcf6142a64ddc7e79582a0e15a27ca2a6876dc90 Mon Sep 17 00:00:00 2001 From: Marcelo Lv Cabral Date: Thu, 18 Jan 2024 12:14:57 -0700 Subject: [PATCH] Fixed #41 - Global functions `GetInterface()` and `FindMemberFunction()` are not properly boxing parameters (#42) --- src/brsTypes/BrsInterface.ts | 8 ++++- src/brsTypes/components/RoInt.ts | 2 +- src/stdlib/GlobalUtilities.ts | 29 ++++++++++++------- test/e2e/StdLib.test.js | 4 +++ .../e2e/resources/stdlib/global-utilities.brs | 4 +++ 5 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/brsTypes/BrsInterface.ts b/src/brsTypes/BrsInterface.ts index 1655afb7b..9d04608e0 100644 --- a/src/brsTypes/BrsInterface.ts +++ b/src/brsTypes/BrsInterface.ts @@ -11,7 +11,13 @@ export class BrsInterface implements BrsValue { readonly methodNames: Set; constructor(readonly name: string, methods: Callable[]) { - this.methodNames = new Set(methods.filter((m) => m.name).map((m) => m.name!)); + this.methodNames = new Set( + methods.filter((m) => m.name?.toLowerCase()).map((m) => m.name?.toLowerCase()!) + ); + } + + hasMethod(method: string): boolean { + return this.methodNames.has(method.toLowerCase()); } toString(): string { diff --git a/src/brsTypes/components/RoInt.ts b/src/brsTypes/components/RoInt.ts index e683c2665..7064ef870 100644 --- a/src/brsTypes/components/RoInt.ts +++ b/src/brsTypes/components/RoInt.ts @@ -20,10 +20,10 @@ export class roInt extends BrsComponent implements BrsValue, Unboxable { this.intrinsic = initialValue; this.registerMethods({ ifInt: [this.getInt, this.setInt], - ifToStr: [this.toStr], // Per https://developer.roku.com/docs/references/brightscript/interfaces/ifintops.md, // ifIntOps _also_ implements toStr() ifIntOps: [this.toStr], + ifToStr: [this.toStr], }); } diff --git a/src/stdlib/GlobalUtilities.ts b/src/stdlib/GlobalUtilities.ts index 36baee8c1..6981025b8 100644 --- a/src/stdlib/GlobalUtilities.ts +++ b/src/stdlib/GlobalUtilities.ts @@ -8,7 +8,9 @@ import { RoAssociativeArray, BrsInterface, } from "../brsTypes"; +import { isBoxable } from "../brsTypes/Boxing"; import { BrsComponent } from "../brsTypes/components/BrsComponent"; +import { Interpreter } from "../interpreter"; let warningShown = false; @@ -35,8 +37,12 @@ export const GetInterface = new Callable("GetInterface", { ], returns: ValueKind.Interface, }, - impl: (interpreter, object: BrsComponent, ifname: BrsString): BrsInterface | BrsInvalid => { - return object.interfaces.get(ifname.value.toLowerCase()) || BrsInvalid.Instance; + impl: (_: Interpreter, object: BrsType, ifname: BrsString): BrsInterface | BrsInvalid => { + const boxedObj = isBoxable(object) ? object.box() : object; + if (boxedObj instanceof BrsComponent) { + return boxedObj.interfaces.get(ifname.value.toLowerCase()) || BrsInvalid.Instance; + } + return BrsInvalid.Instance; }, }); @@ -44,18 +50,19 @@ export const FindMemberFunction = new Callable("FindMemberFunction", { signature: { args: [ new StdlibArgument("object", ValueKind.Object), - new StdlibArgument("funname", ValueKind.String), + new StdlibArgument("funName", ValueKind.String), ], returns: ValueKind.Interface, }, - impl: (interpreter, object: BrsComponent, funName: BrsString): BrsInterface | BrsInvalid => { - let iface: BrsType = BrsInvalid.Instance; - object.interfaces.forEach((interfaceName) => { - if (interfaceName.methodNames.has(funName.value.toLowerCase())) { - iface = interfaceName; + impl: (_: Interpreter, object: BrsType, funName: BrsString): BrsInterface | BrsInvalid => { + const boxedObj = isBoxable(object) ? object.box() : object; + if (boxedObj instanceof BrsComponent) { + for (let [_, iface] of boxedObj.interfaces) { + if (iface.hasMethod(funName.value)) { + return iface; + } } - }); - - return iface; + } + return BrsInvalid.Instance; }, }); diff --git a/test/e2e/StdLib.test.js b/test/e2e/StdLib.test.js index cff130ce1..4d0644642 100644 --- a/test/e2e/StdLib.test.js +++ b/test/e2e/StdLib.test.js @@ -130,6 +130,10 @@ describe("end to end standard libary", () => { "", "", "", + "", + "", + "", + "", ]); }); }); diff --git a/test/e2e/resources/stdlib/global-utilities.brs b/test/e2e/resources/stdlib/global-utilities.brs index bcfde2ba1..37d8bb407 100644 --- a/test/e2e/resources/stdlib/global-utilities.brs +++ b/test/e2e/resources/stdlib/global-utilities.brs @@ -3,4 +3,8 @@ sub main() print getInterface(1.123, "ifFloat") print findMemberFunction({}, "count") print findMemberFunction(node, "findNode") + print FindMemberFunction("", "left") + print GetInterface("", "ifStringOps") + print FindMemberFunction(1, "tostr") + print GetInterface(1, "iftostr") end sub