@@ -47,10 +47,8 @@ struct BridgeJSLink {
47
47
48
48
func link( ) throws -> ( outputJs: String , outputDts: String ) {
49
49
var exportsLines : [ String ] = [ ]
50
- var importedLines : [ String ] = [ ]
51
50
var classLines : [ String ] = [ ]
52
51
var dtsExportLines : [ String ] = [ ]
53
- var dtsImportLines : [ String ] = [ ]
54
52
var dtsClassLines : [ String ] = [ ]
55
53
56
54
if exportedSkeletons. contains ( where: { $0. classes. count > 0 } ) {
@@ -84,57 +82,18 @@ struct BridgeJSLink {
84
82
}
85
83
}
86
84
85
+ var importObjectBuilders : [ ImportObjectBuilder ] = [ ]
87
86
for skeletonSet in importedSkeletons {
88
- importedLines. append ( " const \( skeletonSet. moduleName) = importObject[ \" \( skeletonSet. moduleName) \" ] = {}; " )
89
- func assignToImportObject( name: String , function: [ String ] ) {
90
- var js = function
91
- js [ 0 ] = " \( skeletonSet. moduleName) [ \" \( name) \" ] = " + js[ 0 ]
92
- importedLines. append ( contentsOf: js)
93
- }
87
+ let importObjectBuilder = ImportObjectBuilder ( moduleName: skeletonSet. moduleName)
94
88
for fileSkeleton in skeletonSet. children {
95
89
for function in fileSkeleton. functions {
96
- let ( js, dts) = try renderImportedFunction ( function: function)
97
- assignToImportObject ( name: function. abiName ( context: nil ) , function: js)
98
- dtsImportLines. append ( contentsOf: dts)
90
+ try renderImportedFunction ( importObjectBuilder: importObjectBuilder, function: function)
99
91
}
100
92
for type in fileSkeleton. types {
101
- for property in type. properties {
102
- let getterAbiName = property. getterAbiName ( context: type)
103
- let ( js, dts) = try renderImportedProperty (
104
- property: property,
105
- abiName: getterAbiName,
106
- emitCall: { thunkBuilder in
107
- thunkBuilder. callPropertyGetter ( name: property. name, returnType: property. type)
108
- return try thunkBuilder. lowerReturnValue ( returnType: property. type)
109
- }
110
- )
111
- assignToImportObject ( name: getterAbiName, function: js)
112
- dtsImportLines. append ( contentsOf: dts)
113
-
114
- if !property. isReadonly {
115
- let setterAbiName = property. setterAbiName ( context: type)
116
- let ( js, dts) = try renderImportedProperty (
117
- property: property,
118
- abiName: setterAbiName,
119
- emitCall: { thunkBuilder in
120
- thunkBuilder. liftParameter (
121
- param: Parameter ( label: nil , name: " newValue " , type: property. type)
122
- )
123
- thunkBuilder. callPropertySetter ( name: property. name, returnType: property. type)
124
- return nil
125
- }
126
- )
127
- assignToImportObject ( name: setterAbiName, function: js)
128
- dtsImportLines. append ( contentsOf: dts)
129
- }
130
- }
131
- for method in type. methods {
132
- let ( js, dts) = try renderImportedMethod ( context: type, method: method)
133
- assignToImportObject ( name: method. abiName ( context: type) , function: js)
134
- dtsImportLines. append ( contentsOf: dts)
135
- }
93
+ try renderImportedType ( importObjectBuilder: importObjectBuilder, type: type)
136
94
}
137
95
}
96
+ importObjectBuilders. append ( importObjectBuilder)
138
97
}
139
98
140
99
let outputJs = """
@@ -175,7 +134,7 @@ struct BridgeJSLink {
175
134
target.set(tmpRetBytes);
176
135
tmpRetBytes = undefined;
177
136
}
178
- \( importedLines. map { $0. indent ( count: 12 ) } . joined ( separator: " \n " ) )
137
+ \( importObjectBuilders . flatMap { $0 . importedLines } . map { $0. indent ( count: 12 ) } . joined ( separator: " \n " ) )
179
138
},
180
139
setInstance: (i) => {
181
140
instance = i;
@@ -198,7 +157,7 @@ struct BridgeJSLink {
198
157
dtsLines. append ( contentsOf: dtsExportLines. map { $0. indent ( count: 4 ) } )
199
158
dtsLines. append ( " } " )
200
159
dtsLines. append ( " export type Imports = { " )
201
- dtsLines. append ( contentsOf: dtsImportLines. map { $0. indent ( count: 4 ) } )
160
+ dtsLines. append ( contentsOf: importObjectBuilders . flatMap { $0 . dtsImportLines } . map { $0. indent ( count: 4 ) } )
202
161
dtsLines. append ( " } " )
203
162
let outputDts = """
204
163
// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
@@ -437,6 +396,11 @@ struct BridgeJSLink {
437
396
}
438
397
}
439
398
399
+ func callConstructor( name: String ) {
400
+ let call = " new options.imports. \( name) ( \( parameterForwardings. joined ( separator: " , " ) ) ) "
401
+ bodyLines. append ( " let ret = \( call) ; " )
402
+ }
403
+
440
404
func callMethod( name: String , returnType: BridgeType ) {
441
405
let call = " swift.memory.getObject(self). \( name) ( \( parameterForwardings. joined ( separator: " , " ) ) ) "
442
406
if returnType == . void {
@@ -475,7 +439,31 @@ struct BridgeJSLink {
475
439
}
476
440
}
477
441
478
- func renderImportedFunction( function: ImportedFunctionSkeleton ) throws -> ( js: [ String ] , dts: [ String ] ) {
442
+ class ImportObjectBuilder {
443
+ var moduleName : String
444
+ var importedLines : [ String ] = [ ]
445
+ var dtsImportLines : [ String ] = [ ]
446
+
447
+ init ( moduleName: String ) {
448
+ self . moduleName = moduleName
449
+ importedLines. append ( " const \( moduleName) = importObject[ \" \( moduleName) \" ] = {}; " )
450
+ }
451
+
452
+ func assignToImportObject( name: String , function: [ String ] ) {
453
+ var js = function
454
+ js [ 0 ] = " \( moduleName) [ \" \( name) \" ] = " + js[ 0 ]
455
+ importedLines. append ( contentsOf: js)
456
+ }
457
+
458
+ func appendDts( _ lines: [ String ] ) {
459
+ dtsImportLines. append ( contentsOf: lines)
460
+ }
461
+ }
462
+
463
+ func renderImportedFunction(
464
+ importObjectBuilder: ImportObjectBuilder ,
465
+ function: ImportedFunctionSkeleton
466
+ ) throws {
479
467
let thunkBuilder = ImportedThunkBuilder ( )
480
468
for param in function. parameters {
481
469
thunkBuilder. liftParameter ( param: param)
@@ -486,11 +474,85 @@ struct BridgeJSLink {
486
474
name: function. abiName ( context: nil ) ,
487
475
returnExpr: returnExpr
488
476
)
489
- var dtsLines : [ String ] = [ ]
490
- dtsLines. append (
491
- " \( function. name) \( renderTSSignature ( parameters: function. parameters, returnType: function. returnType) ) ; "
477
+ importObjectBuilder. appendDts (
478
+ [
479
+ " \( function. name) \( renderTSSignature ( parameters: function. parameters, returnType: function. returnType) ) ; "
480
+ ]
492
481
)
493
- return ( funcLines, dtsLines)
482
+ importObjectBuilder. assignToImportObject ( name: function. abiName ( context: nil ) , function: funcLines)
483
+ }
484
+
485
+ func renderImportedType(
486
+ importObjectBuilder: ImportObjectBuilder ,
487
+ type: ImportedTypeSkeleton
488
+ ) throws {
489
+ if let constructor = type. constructor {
490
+ try renderImportedConstructor (
491
+ importObjectBuilder: importObjectBuilder,
492
+ type: type,
493
+ constructor: constructor
494
+ )
495
+ }
496
+ for property in type. properties {
497
+ let getterAbiName = property. getterAbiName ( context: type)
498
+ let ( js, dts) = try renderImportedProperty (
499
+ property: property,
500
+ abiName: getterAbiName,
501
+ emitCall: { thunkBuilder in
502
+ thunkBuilder. callPropertyGetter ( name: property. name, returnType: property. type)
503
+ return try thunkBuilder. lowerReturnValue ( returnType: property. type)
504
+ }
505
+ )
506
+ importObjectBuilder. assignToImportObject ( name: getterAbiName, function: js)
507
+ importObjectBuilder. appendDts ( dts)
508
+
509
+ if !property. isReadonly {
510
+ let setterAbiName = property. setterAbiName ( context: type)
511
+ let ( js, dts) = try renderImportedProperty (
512
+ property: property,
513
+ abiName: setterAbiName,
514
+ emitCall: { thunkBuilder in
515
+ thunkBuilder. liftParameter (
516
+ param: Parameter ( label: nil , name: " newValue " , type: property. type)
517
+ )
518
+ thunkBuilder. callPropertySetter ( name: property. name, returnType: property. type)
519
+ return nil
520
+ }
521
+ )
522
+ importObjectBuilder. assignToImportObject ( name: setterAbiName, function: js)
523
+ importObjectBuilder. appendDts ( dts)
524
+ }
525
+ }
526
+ for method in type. methods {
527
+ let ( js, dts) = try renderImportedMethod ( context: type, method: method)
528
+ importObjectBuilder. assignToImportObject ( name: method. abiName ( context: type) , function: js)
529
+ importObjectBuilder. appendDts ( dts)
530
+ }
531
+ }
532
+
533
+ func renderImportedConstructor(
534
+ importObjectBuilder: ImportObjectBuilder ,
535
+ type: ImportedTypeSkeleton ,
536
+ constructor: ImportedConstructorSkeleton
537
+ ) throws {
538
+ let thunkBuilder = ImportedThunkBuilder ( )
539
+ for param in constructor. parameters {
540
+ thunkBuilder. liftParameter ( param: param)
541
+ }
542
+ let returnType = BridgeType . jsObject ( type. name)
543
+ thunkBuilder. callConstructor ( name: type. name)
544
+ let returnExpr = try thunkBuilder. lowerReturnValue ( returnType: returnType)
545
+ let abiName = constructor. abiName ( context: type)
546
+ let funcLines = thunkBuilder. renderFunction (
547
+ name: abiName,
548
+ returnExpr: returnExpr
549
+ )
550
+ importObjectBuilder. assignToImportObject ( name: abiName, function: funcLines)
551
+ importObjectBuilder. appendDts ( [
552
+ " \( type. name) : { " ,
553
+ " new \( renderTSSignature ( parameters: constructor. parameters, returnType: returnType) ) ; " . indent ( count: 4 ) ,
554
+ " } " ,
555
+ ] )
494
556
}
495
557
496
558
func renderImportedProperty(
@@ -552,8 +614,8 @@ extension BridgeType {
552
614
return " number "
553
615
case . bool:
554
616
return " boolean "
555
- case . jsObject:
556
- return " any "
617
+ case . jsObject( let name ) :
618
+ return name ?? " any "
557
619
case . swiftHeapObject( let name) :
558
620
return name
559
621
}
0 commit comments