@@ -47,10 +47,8 @@ struct BridgeJSLink {
4747
4848 func link( ) throws -> ( outputJs: String , outputDts: String ) {
4949 var exportsLines : [ String ] = [ ]
50- var importedLines : [ String ] = [ ]
5150 var classLines : [ String ] = [ ]
5251 var dtsExportLines : [ String ] = [ ]
53- var dtsImportLines : [ String ] = [ ]
5452 var dtsClassLines : [ String ] = [ ]
5553
5654 if exportedSkeletons. contains ( where: { $0. classes. count > 0 } ) {
@@ -84,57 +82,18 @@ struct BridgeJSLink {
8482 }
8583 }
8684
85+ var importObjectBuilders : [ ImportObjectBuilder ] = [ ]
8786 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)
9488 for fileSkeleton in skeletonSet. children {
9589 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)
9991 }
10092 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)
13694 }
13795 }
96+ importObjectBuilders. append ( importObjectBuilder)
13897 }
13998
14099 let outputJs = """
@@ -175,7 +134,7 @@ struct BridgeJSLink {
175134 target.set(tmpRetBytes);
176135 tmpRetBytes = undefined;
177136 }
178- \( importedLines. map { $0. indent ( count: 12 ) } . joined ( separator: " \n " ) )
137+ \( importObjectBuilders . flatMap { $0 . importedLines } . map { $0. indent ( count: 12 ) } . joined ( separator: " \n " ) )
179138 },
180139 setInstance: (i) => {
181140 instance = i;
@@ -198,7 +157,7 @@ struct BridgeJSLink {
198157 dtsLines. append ( contentsOf: dtsExportLines. map { $0. indent ( count: 4 ) } )
199158 dtsLines. append ( " } " )
200159 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 ) } )
202161 dtsLines. append ( " } " )
203162 let outputDts = """
204163 // NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit,
@@ -437,6 +396,11 @@ struct BridgeJSLink {
437396 }
438397 }
439398
399+ func callConstructor( name: String ) {
400+ let call = " new options.imports. \( name) ( \( parameterForwardings. joined ( separator: " , " ) ) ) "
401+ bodyLines. append ( " let ret = \( call) ; " )
402+ }
403+
440404 func callMethod( name: String , returnType: BridgeType ) {
441405 let call = " swift.memory.getObject(self). \( name) ( \( parameterForwardings. joined ( separator: " , " ) ) ) "
442406 if returnType == . void {
@@ -475,7 +439,31 @@ struct BridgeJSLink {
475439 }
476440 }
477441
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 {
479467 let thunkBuilder = ImportedThunkBuilder ( )
480468 for param in function. parameters {
481469 thunkBuilder. liftParameter ( param: param)
@@ -486,11 +474,85 @@ struct BridgeJSLink {
486474 name: function. abiName ( context: nil ) ,
487475 returnExpr: returnExpr
488476 )
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+ ]
492481 )
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+ ] )
494556 }
495557
496558 func renderImportedProperty(
@@ -552,8 +614,8 @@ extension BridgeType {
552614 return " number "
553615 case . bool:
554616 return " boolean "
555- case . jsObject:
556- return " any "
617+ case . jsObject( let name ) :
618+ return name ?? " any "
557619 case . swiftHeapObject( let name) :
558620 return name
559621 }
0 commit comments