Skip to content

Commit

Permalink
Allow calling JS functions with up to 7 arguments in Embedded Swift
Browse files Browse the repository at this point in the history
  • Loading branch information
ole committed Jan 15, 2025
1 parent 4afe045 commit dccced1
Show file tree
Hide file tree
Showing 3 changed files with 315 additions and 14 deletions.
178 changes: 169 additions & 9 deletions Sources/JavaScriptKit/FundamentalObjects/JSFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,14 @@ public class JSFunction: JSObject {
}

#if hasFeature(Embedded)
// NOTE: once embedded supports variadic generics, we can remove these overloads
// Overloads of `callAsFunction(ConvertibleToJSValue...) -> JSValue`
// for 0 through 7 arguments for Embedded Swift.
//
// These are required because the `ConvertibleToJSValue...` version is not
// available in Embedded Swift due to lack of support for existentials.
//
// Once Embedded Swift supports parameter packs/variadic generics, we can
// replace all variants with a single method each that takes a generic pack.
public extension JSFunction {

@discardableResult
Expand All @@ -178,15 +185,74 @@ public extension JSFunction {
}

@discardableResult
func callAsFunction(this: JSObject, _ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue) -> JSValue {
func callAsFunction(
this: JSObject,
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue], this: this).jsValue
}

@discardableResult
func callAsFunction(this: JSObject, _ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue, _ arg2: some ConvertibleToJSValue) -> JSValue {
func callAsFunction(
this: JSObject,
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue], this: this).jsValue
}

@discardableResult
func callAsFunction(
this: JSObject,
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue], this: this).jsValue
}

@discardableResult
func callAsFunction(
this: JSObject,
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue], this: this).jsValue
}

@discardableResult
func callAsFunction(
this: JSObject,
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue,
_ arg5: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue, arg5.jsValue], this: this).jsValue
}

@discardableResult
func callAsFunction(
this: JSObject,
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue,
_ arg5: some ConvertibleToJSValue,
_ arg6: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue, arg5.jsValue, arg6.jsValue], this: this).jsValue
}

@discardableResult
func callAsFunction(this: JSObject, arguments: [JSValue]) -> JSValue {
invokeNonThrowingJSFunction(arguments: arguments, this: this).jsValue
Expand All @@ -203,15 +269,68 @@ public extension JSFunction {
}

@discardableResult
func callAsFunction(_ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue) -> JSValue {
func callAsFunction(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue]).jsValue
}

@discardableResult
func callAsFunction(_ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue, _ arg2: some ConvertibleToJSValue) -> JSValue {
func callAsFunction(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue]).jsValue
}

@discardableResult
func callAsFunction(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue]).jsValue
}

@discardableResult
func callAsFunction(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue]).jsValue
}

@discardableResult
func callAsFunction(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue,
_ arg5: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue, arg5.jsValue]).jsValue
}

@discardableResult
func callAsFunction(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue,
_ arg5: some ConvertibleToJSValue,
_ arg6: some ConvertibleToJSValue
) -> JSValue {
invokeNonThrowingJSFunction(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue, arg5.jsValue, arg6.jsValue]).jsValue
}

func new() -> JSObject {
new(arguments: [])
}
Expand All @@ -220,19 +339,60 @@ public extension JSFunction {
new(arguments: [arg0.jsValue])
}

func new(_ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue) -> JSObject {
func new(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue
) -> JSObject {
new(arguments: [arg0.jsValue, arg1.jsValue])
}

func new(_ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue, _ arg2: some ConvertibleToJSValue) -> JSObject {
func new(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue
) -> JSObject {
new(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue])
}

func new(_ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue, _ arg2: some ConvertibleToJSValue, _ arg3: some ConvertibleToJSValue) -> JSObject {
func new(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue
) -> JSObject {
new(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue])
}

func new(_ arg0: some ConvertibleToJSValue, _ arg1: some ConvertibleToJSValue, _ arg2: some ConvertibleToJSValue, _ arg3: some ConvertibleToJSValue, _ arg4: some ConvertibleToJSValue, _ arg5: some ConvertibleToJSValue, _ arg6: some ConvertibleToJSValue) -> JSObject {
func new(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue
) -> JSObject {
new(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue])
}

func new(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue,
_ arg5: some ConvertibleToJSValue
) -> JSObject {
new(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue, arg5.jsValue])
}

func new(
_ arg0: some ConvertibleToJSValue,
_ arg1: some ConvertibleToJSValue,
_ arg2: some ConvertibleToJSValue,
_ arg3: some ConvertibleToJSValue,
_ arg4: some ConvertibleToJSValue,
_ arg5: some ConvertibleToJSValue,
_ arg6: some ConvertibleToJSValue
) -> JSObject {
new(arguments: [arg0.jsValue, arg1.jsValue, arg2.jsValue, arg3.jsValue, arg4.jsValue, arg5.jsValue, arg6.jsValue])
}
}
Expand Down
79 changes: 77 additions & 2 deletions Sources/JavaScriptKit/FundamentalObjects/JSObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,14 @@ public class JSThrowingObject {


#if hasFeature(Embedded)
// NOTE: once embedded supports variadic generics, we can remove these overloads
// Overloads of `JSObject.subscript(_ name: String) -> ((ConvertibleToJSValue...) -> JSValue)?`
// for 0 through 7 arguments for Embedded Swift.
//
// These are required because the `ConvertibleToJSValue...` subscript is not
// available in Embedded Swift due to lack of support for existentials.
//
// NOTE: Once Embedded Swift supports parameter packs/variadic generics, we can
// replace all of these with a single method that takes a generic pack.
public extension JSObject {
@_disfavoredOverload
subscript(dynamicMember name: String) -> (() -> JSValue)? {
Expand All @@ -315,10 +322,78 @@ public extension JSObject {
}

@_disfavoredOverload
subscript<A0: ConvertibleToJSValue, A1: ConvertibleToJSValue>(dynamicMember name: String) -> ((A0, A1) -> JSValue)? {
subscript<
A0: ConvertibleToJSValue,
A1: ConvertibleToJSValue
>(dynamicMember name: String) -> ((A0, A1) -> JSValue)? {
self[name].function.map { function in
{ function(this: self, $0, $1) }
}
}

@_disfavoredOverload
subscript<
A0: ConvertibleToJSValue,
A1: ConvertibleToJSValue,
A2: ConvertibleToJSValue
>(dynamicMember name: String) -> ((A0, A1, A2) -> JSValue)? {
self[name].function.map { function in
{ function(this: self, $0, $1, $2) }
}
}

@_disfavoredOverload
subscript<
A0: ConvertibleToJSValue,
A1: ConvertibleToJSValue,
A2: ConvertibleToJSValue,
A3: ConvertibleToJSValue
>(dynamicMember name: String) -> ((A0, A1, A2, A3) -> JSValue)? {
self[name].function.map { function in
{ function(this: self, $0, $1, $2, $3) }
}
}

@_disfavoredOverload
subscript<
A0: ConvertibleToJSValue,
A1: ConvertibleToJSValue,
A2: ConvertibleToJSValue,
A3: ConvertibleToJSValue,
A4: ConvertibleToJSValue
>(dynamicMember name: String) -> ((A0, A1, A2, A3, A4) -> JSValue)? {
self[name].function.map { function in
{ function(this: self, $0, $1, $2, $3, $4) }
}
}

@_disfavoredOverload
subscript<
A0: ConvertibleToJSValue,
A1: ConvertibleToJSValue,
A2: ConvertibleToJSValue,
A3: ConvertibleToJSValue,
A4: ConvertibleToJSValue,
A5: ConvertibleToJSValue
>(dynamicMember name: String) -> ((A0, A1, A2, A3, A4, A5) -> JSValue)? {
self[name].function.map { function in
{ function(this: self, $0, $1, $2, $3, $4, $5) }
}
}

@_disfavoredOverload
subscript<
A0: ConvertibleToJSValue,
A1: ConvertibleToJSValue,
A2: ConvertibleToJSValue,
A3: ConvertibleToJSValue,
A4: ConvertibleToJSValue,
A5: ConvertibleToJSValue,
A6: ConvertibleToJSValue
>(dynamicMember name: String) -> ((A0, A1, A2, A3, A4, A5, A6) -> JSValue)? {
self[name].function.map { function in
{ function(this: self, $0, $1, $2, $3, $4, $5, $6) }
}
}
}
#endif
Loading

0 comments on commit dccced1

Please sign in to comment.