Skip to content

Commit

Permalink
Fixed #41 - Global functions GetInterface() and `FindMemberFunction…
Browse files Browse the repository at this point in the history
…()` are not properly boxing parameters (#42)
  • Loading branch information
lvcabral authored Jan 18, 2024
1 parent 7cdd4a3 commit bcf6142
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 13 deletions.
8 changes: 7 additions & 1 deletion src/brsTypes/BrsInterface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ export class BrsInterface implements BrsValue {
readonly methodNames: Set<string>;

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 {
Expand Down
2 changes: 1 addition & 1 deletion src/brsTypes/components/RoInt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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],
});
}

Expand Down
29 changes: 18 additions & 11 deletions src/stdlib/GlobalUtilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -35,27 +37,32 @@ 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;
},
});

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;
},
});
4 changes: 4 additions & 0 deletions test/e2e/StdLib.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ describe("end to end standard libary", () => {
"<Interface: ifFloat>",
"<Interface: ifAssociativeArray>",
"<Interface: ifSGNodeDict>",
"<Interface: ifStringOps>",
"<Interface: ifStringOps>",
"<Interface: ifIntOps>",
"<Interface: ifToStr>",
]);
});
});
4 changes: 4 additions & 0 deletions test/e2e/resources/stdlib/global-utilities.brs
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit bcf6142

Please sign in to comment.