Skip to content

Commit

Permalink
[tsgen] Use optional params for trailing std::optional arguments. (#2…
Browse files Browse the repository at this point in the history
…1786)

This replaces `_0: Foo | undefined` with `_0?: Foo` for any optional
arguments at the end of function, which allows for more idiomatic TS.

Fixes #21776
  • Loading branch information
brendandahl committed Apr 19, 2024
1 parent 1ca2f31 commit a41843e
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 7 deletions.
20 changes: 17 additions & 3 deletions src/embind/embind_gen.js
Expand Up @@ -55,11 +55,25 @@ var LibraryEmbind = {

printSignature(nameMap, out) {
out.push('(');

const argOut = [];
for (const arg of this.argumentTypes) {
argOut.push(`${arg.name}: ${nameMap(arg.type)}`);
// Work backwards on the arguments, so optional types can be replaced
// with TS optional params until we see the first non-optional argument.
let seenNonOptional = false;
for (let i = this.argumentTypes.length - 1; i >= 0; i--) {
const arg = this.argumentTypes[i];
let argType;
let argName;
if (arg.type instanceof OptionalType && !seenNonOptional) {
argType = nameMap(arg.type.type);
argName = arg.name + '?';
} else {
seenNonOptional = true;
argType = nameMap(arg.type);
argName = arg.name;
}
argOut.unshift(`${argName}: ${argType}`);
}

out.push(argOut.join(', '));
out.push(`): ${nameMap(this.returnType, true)}`);
}
Expand Down
5 changes: 5 additions & 0 deletions test/other/embind_tsgen.cpp
Expand Up @@ -102,6 +102,10 @@ std::optional<int> optional_test(std::optional<Foo> arg) {
return {};
}

std::optional<int> optional_and_nonoptional_test(std::optional<Foo> arg1, int arg2) {
return {};
}

class BaseClass {
public:
virtual ~BaseClass() = default;
Expand Down Expand Up @@ -174,6 +178,7 @@ EMSCRIPTEN_BINDINGS(Test) {
register_optional<int>();
register_optional<Foo>();
function("optional_test", &optional_test);
function("optional_and_nonoptional_test", &optional_and_nonoptional_test);

function("string_test", &string_test);
function("wstring_test", &wstring_test);
Expand Down
3 changes: 2 additions & 1 deletion test/other/embind_tsgen.d.ts
Expand Up @@ -114,8 +114,9 @@ interface EmbindModule {
DerivedClass: {};
a_bool: boolean;
an_int: number;
optional_test(_0: Foo | undefined): number | undefined;
optional_test(_0?: Foo): number | undefined;
global_fn(_0: number, _1: number): number;
optional_and_nonoptional_test(_0: Foo | undefined, _1: number): number | undefined;
smart_ptr_function(_0: ClassWithSmartPtrConstructor): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor): number;
function_with_callback_param(_0: (message: string) => void): number;
Expand Down
3 changes: 2 additions & 1 deletion test/other/embind_tsgen_ignore_1.d.ts
Expand Up @@ -123,8 +123,9 @@ interface EmbindModule {
DerivedClass: {};
a_bool: boolean;
an_int: number;
optional_test(_0: Foo | undefined): number | undefined;
optional_test(_0?: Foo): number | undefined;
global_fn(_0: number, _1: number): number;
optional_and_nonoptional_test(_0: Foo | undefined, _1: number): number | undefined;
smart_ptr_function(_0: ClassWithSmartPtrConstructor): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor): number;
function_with_callback_param(_0: (message: string) => void): number;
Expand Down
3 changes: 2 additions & 1 deletion test/other/embind_tsgen_ignore_2.d.ts
Expand Up @@ -101,8 +101,9 @@ interface EmbindModule {
DerivedClass: {};
a_bool: boolean;
an_int: number;
optional_test(_0: Foo | undefined): number | undefined;
optional_test(_0?: Foo): number | undefined;
global_fn(_0: number, _1: number): number;
optional_and_nonoptional_test(_0: Foo | undefined, _1: number): number | undefined;
smart_ptr_function(_0: ClassWithSmartPtrConstructor): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor): number;
function_with_callback_param(_0: (message: string) => void): number;
Expand Down
3 changes: 2 additions & 1 deletion test/other/embind_tsgen_ignore_3.d.ts
Expand Up @@ -114,8 +114,9 @@ interface EmbindModule {
DerivedClass: {};
a_bool: boolean;
an_int: number;
optional_test(_0: Foo | undefined): number | undefined;
optional_test(_0?: Foo): number | undefined;
global_fn(_0: number, _1: number): number;
optional_and_nonoptional_test(_0: Foo | undefined, _1: number): number | undefined;
smart_ptr_function(_0: ClassWithSmartPtrConstructor): number;
smart_ptr_function_with_params(foo: ClassWithSmartPtrConstructor): number;
function_with_callback_param(_0: (message: string) => void): number;
Expand Down

0 comments on commit a41843e

Please sign in to comment.