Skip to content

Commit 9d830e2

Browse files
authored
embind: Support overloaded constructors for TS generation. (#20714)
This also removes the default constructor which was producing an inaccurate TS definition for classes, since a class binding that doesn't have `constructor<>()` won't have a JS constructor. Thanks to @walkingeyerobot for finding this solution.
1 parent cd5f6ed commit 9d830e2

File tree

3 files changed

+36
-15
lines changed

3 files changed

+36
-15
lines changed

src/embind/embind_ts.js

+16-11
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,7 @@ var LibraryEmbind = {
6868
this.methods = [];
6969
this.staticMethods = [];
7070
this.staticProperties = [];
71-
this.constructors = [
72-
new FunctionDefinition('default', this, [])
73-
];
71+
this.constructors = [];
7472
this.base = base;
7573
this.properties = [];
7674
}
@@ -96,18 +94,25 @@ var LibraryEmbind = {
9694
}
9795

9896
printModuleEntry(nameMap, out) {
99-
out.push(` ${this.name}: {new`);
100-
// TODO Handle constructor overloading
101-
const constructor = this.constructors[this.constructors.length > 1 ? 1 : 0];
102-
constructor.printSignature(nameMap, out);
97+
out.push(` ${this.name}: {`);
98+
const entries = [];
99+
for(const construct of this.constructors) {
100+
const entry = [];
101+
entry.push('new');
102+
construct.printSignature(nameMap, entry);
103+
entries.push(entry.join(''));
104+
}
103105
for (const method of this.staticMethods) {
104-
out.push('; ');
105-
method.printFunction(nameMap, out);
106+
const entry = [];
107+
method.printFunction(nameMap, entry);
108+
entries.push(entry.join(''));
106109
}
107110
for (const prop of this.staticProperties) {
108-
out.push('; ');
109-
prop.print(nameMap, out);
111+
const entry = [];
112+
prop.print(nameMap, entry);
113+
entries.push(entry.join(''));
110114
}
115+
out.push(entries.join('; '));
111116
out.push('};\n');
112117
}
113118
},

test/other/embind_tsgen.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ class ClassWithConstructor {
6363
int fn(int x) { return 0; }
6464
};
6565

66+
class ClassWithTwoConstructors {
67+
public:
68+
ClassWithTwoConstructors() {}
69+
ClassWithTwoConstructors(int) {}
70+
};
71+
6672
class ClassWithSmartPtrConstructor {
6773
public:
6874
ClassWithSmartPtrConstructor(int, const ValArr&) {}
@@ -154,6 +160,11 @@ EMSCRIPTEN_BINDINGS(Test) {
154160
.constructor<int, const ValArr&>()
155161
.function("fn", &ClassWithConstructor::fn);
156162

163+
// The last defined constructor should be used in the definition.
164+
class_<ClassWithTwoConstructors>("ClassWithTwoConstructors")
165+
.constructor<>()
166+
.constructor<int>();
167+
157168
class_<ClassWithSmartPtrConstructor>("ClassWithSmartPtrConstructor")
158169
.smart_ptr_constructor(
159170
"ClassWithSmartPtrConstructor",

test/other/embind_tsgen.d.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ export interface ClassWithConstructor {
4848
delete(): void;
4949
}
5050

51+
export interface ClassWithTwoConstructors {
52+
delete(): void;
53+
}
54+
5155
export interface ClassWithSmartPtrConstructor {
5256
fn(_0: number): number;
5357
delete(): void;
@@ -66,7 +70,7 @@ export interface DerivedClass extends BaseClass {
6670
export type ValArr = [ number, number, number ];
6771

6872
export interface MainModule {
69-
Test: {new(): Test; staticFunction(_0: number): number; staticFunctionWithParam(x: number): number; staticProperty: number};
73+
Test: {staticFunction(_0: number): number; staticFunctionWithParam(x: number): number; staticProperty: number};
7074
class_returning_fn(): Test;
7175
class_unique_ptr_returning_fn(): Test;
7276
a_class_instance: Test;
@@ -75,11 +79,12 @@ export interface MainModule {
7579
EmptyEnum: {};
7680
enum_returning_fn(): Bar;
7781
IntVec: {new(): IntVec};
78-
Foo: {new(): Foo};
82+
Foo: {};
7983
ClassWithConstructor: {new(_0: number, _1: ValArr): ClassWithConstructor};
84+
ClassWithTwoConstructors: {new(): ClassWithTwoConstructors; new(_0: number): ClassWithTwoConstructors};
8085
ClassWithSmartPtrConstructor: {new(_0: number, _1: ValArr): ClassWithSmartPtrConstructor};
81-
BaseClass: {new(): BaseClass};
82-
DerivedClass: {new(): DerivedClass};
86+
BaseClass: {};
87+
DerivedClass: {};
8388
a_bool: boolean;
8489
an_int: number;
8590
global_fn(_0: number, _1: number): number;

0 commit comments

Comments
 (0)