@@ -424,7 +424,15 @@ public struct BridgeJSLink {
424424 private func genericWrapperHelperDeclarations( ) -> [ String ] {
425425 let i32 = JSGlueVariableScope . reservedI32Stack
426426 let codecs = JSGlueVariableScope . reservedCodecs
427+ let codecsById = JSGlueVariableScope . reservedCodecsById
427428 return [
429+ " function __bjs_resolveGenericType(token) { " ,
430+ " const codec = \( codecs) [token]; " ,
431+ " if (!codec) { throw new Error( \" BridgeJS: no generic codec registered for type ' \" + token + \" ' \" ); } " ,
432+ " let id = \( codecsById) .indexOf(codec); " ,
433+ " if (id === -1) { id = \( codecsById) .push(codec) - 1; } " ,
434+ " return id; " ,
435+ " } " ,
428436 " function __bjs_lowerArrayGeneric(value, codec) { " ,
429437 " for (let i = 0; i < value.length; i++) { codec.lower(value[i]); } " ,
430438 " \( i32) .push(value.length); " ,
@@ -475,23 +483,7 @@ public struct BridgeJSLink {
475483 allClasses: [ ExportedClass ] ,
476484 allEnums: [ ExportedEnum ]
477485 ) -> [ ( token: String , type: BridgeType ) ] {
478- var entries : [ ( token: String , type: BridgeType ) ] = [
479- ( " Bool " , . bool) ,
480- ( " Int " , . integer( . int) ) ,
481- ( " Int8 " , . integer( . int8) ) ,
482- ( " UInt8 " , . integer( . uint8) ) ,
483- ( " Int16 " , . integer( . int16) ) ,
484- ( " UInt16 " , . integer( . uint16) ) ,
485- ( " Int32 " , . integer( . int32) ) ,
486- ( " UInt32 " , . integer( . uint32) ) ,
487- ( " UInt " , . integer( . uint) ) ,
488- ( " Int64 " , . integer( . int64) ) ,
489- ( " UInt64 " , . integer( . uint64) ) ,
490- ( " Float " , . float) ,
491- ( " Double " , . double) ,
492- ( " String " , . string) ,
493- ( " JSValue " , . jsValue) ,
494- ]
486+ var entries = BridgeType . genericBridgeablePrimitives
495487 for structDef in allStructs {
496488 entries. append ( ( structDef. abiName, . swiftStruct( structDef. abiName) ) )
497489 }
@@ -550,57 +542,39 @@ public struct BridgeJSLink {
550542 printer. write ( " }; " )
551543 printer. write ( " bjs[ \" swift_js_resolve_type_id \" ] = function(ptr, len) { " )
552544 printer. indent {
553- printer. write ( " const name = \( decodeString) (ptr, len); " )
554- printer. write ( " const codec = \( JSGlueVariableScope . reservedCodecs) [name]; " )
555- printer. write ( " if (!codec) { " )
556- printer. indent {
557- printer. write (
558- " throw new Error( \" BridgeJS: no generic codec registered for type ' \" + name + \" ' \" ); "
559- )
560- }
561- printer. write ( " } " )
562- printer. write ( " let id = \( JSGlueVariableScope . reservedCodecsById) .indexOf(codec); " )
563- printer. write ( " if (id === -1) { " )
564- printer. indent {
565- printer. write ( " id = \( JSGlueVariableScope . reservedCodecsById) .push(codec) - 1; " )
566- }
567- printer. write ( " } " )
568- printer. write ( " return id; " )
545+ printer. write ( " return __bjs_resolveGenericType( \( decodeString) (ptr, len)); " )
569546 }
570547 printer. write ( " } " )
571548 }
572549
573550 private func generateBridgeTypeTokens( ) -> ( js: [ String ] , dts: [ String ] ) {
574- let primitives : [ ( token: String , tsType: String ) ] = [
575- ( " Bool " , BridgeType . bool. tsType) ,
576- ( " Int " , BridgeType . integer ( . int) . tsType) ,
577- ( " Int8 " , BridgeType . integer ( . int8) . tsType) ,
578- ( " UInt8 " , BridgeType . integer ( . uint8) . tsType) ,
579- ( " Int16 " , BridgeType . integer ( . int16) . tsType) ,
580- ( " UInt16 " , BridgeType . integer ( . uint16) . tsType) ,
581- ( " Int32 " , BridgeType . integer ( . int32) . tsType) ,
582- ( " UInt32 " , BridgeType . integer ( . uint32) . tsType) ,
583- ( " UInt " , BridgeType . integer ( . uint) . tsType) ,
584- ( " Int64 " , BridgeType . integer ( . int64) . tsType) ,
585- ( " UInt64 " , BridgeType . integer ( . uint64) . tsType) ,
586- ( " Float " , BridgeType . float. tsType) ,
587- ( " Double " , BridgeType . double. tsType) ,
588- ( " String " , BridgeType . string. tsType) ,
589- ( " JSValue " , BridgeType . jsValue. tsType) ,
590- ]
551+ let primitives : [ ( token: String , tsType: String ) ] = BridgeType . genericBridgeablePrimitives. map {
552+ ( token: $0. token, tsType: $0. type. tsType)
553+ }
554+ func tsQualifiedName( name: String , namespace: [ String ] ? ) -> String {
555+ ( ( namespace ?? [ ] ) + [ name] ) . joined ( separator: " . " )
556+ }
591557 let structs = skeletons. compactMap { $0. exported? . structs } . flatMap { $0 }
592558 let classes = skeletons. compactMap { $0. exported? . classes } . flatMap { $0 }
593559 let enums = skeletons. compactMap { $0. exported? . enums } . flatMap { $0 }
594560 var tokens : [ ( token: String , tsType: String ) ] = primitives
595561 for structDef in structs {
596- tokens. append ( ( token: structDef. abiName, tsType: structDef. name) )
562+ tokens. append (
563+ (
564+ token: structDef. abiName,
565+ tsType: tsQualifiedName ( name: structDef. name, namespace: structDef. namespace)
566+ )
567+ )
597568 }
598569 for klass in classes where klass. isFinal == true {
599- tokens. append ( ( token: klass. abiName, tsType: klass. name) )
570+ tokens. append (
571+ ( token: klass. abiName, tsType: tsQualifiedName ( name: klass. name, namespace: klass. namespace) )
572+ )
600573 }
601574 for enumDef in enums {
602- guard let bridgeType = genericEnumBridgeType ( enumDef) else { continue }
603- tokens. append ( ( token: enumDef. abiName, tsType: bridgeType. tsType) )
575+ guard genericEnumBridgeType ( enumDef) != nil else { continue }
576+ let enumTypeName = enumDef. emitStyle == . tsEnum ? enumDef. tsFullPath : " \( enumDef. tsFullPath) Tag "
577+ tokens. append ( ( token: enumDef. abiName, tsType: enumTypeName) )
604578 }
605579
606580 let jsEntries = tokens. map { " \( $0. token) : \" \( $0. token) \" " }
@@ -2132,22 +2106,22 @@ extension BridgeJSLink {
21322106 }
21332107
21342108 static func genericCodecLowerStatement( type: BridgeType , codec: String , value: String ) -> String ? {
2135- switch type {
2136- case . generic : return " \( codec ) .lower( \( value ) ); "
2137- case . array ( . generic ) : return " __bjs_lowerArrayGeneric( \( value ) , \( codec ) ); "
2138- case . nullable ( . generic , _ ) : return " __bjs_lowerOptionalGeneric (\( value) , \( codec) ); "
2139- case . dictionary ( . generic ) : return " __bjs_lowerDictGeneric (\( value) , \( codec) ); "
2140- default : return nil
2109+ guard let wrapper = type. genericWrapper else { return nil }
2110+ switch wrapper . kind {
2111+ case . bare : return " \( codec ) .lower( \( value ) ); "
2112+ case . array : return " __bjs_lowerArrayGeneric (\( value) , \( codec) ); "
2113+ case . optional : return " __bjs_lowerOptionalGeneric (\( value) , \( codec) ); "
2114+ case . dictionary : return " __bjs_lowerDictGeneric( \( value ) , \( codec ) ); "
21412115 }
21422116 }
21432117
21442118 static func genericCodecLiftExpression( type: BridgeType , codec: String ) -> String ? {
2145- switch type {
2146- case . generic : return " \( codec ) .lift() "
2147- case . array ( . generic ) : return " __bjs_liftArrayGeneric( \( codec) ) "
2148- case . nullable ( . generic , _ ) : return " __bjs_liftOptionalGeneric (\( codec) ) "
2149- case . dictionary ( . generic ) : return " __bjs_liftDictGeneric (\( codec) ) "
2150- default : return nil
2119+ guard let wrapper = type. genericWrapper else { return nil }
2120+ switch wrapper . kind {
2121+ case . bare : return " \( codec) .lift( )"
2122+ case . array : return " __bjs_liftArrayGeneric (\( codec) ) "
2123+ case . optional : return " __bjs_liftOptionalGeneric (\( codec) ) "
2124+ case . dictionary : return " __bjs_liftDictGeneric( \( codec ) ) "
21512125 }
21522126 }
21532127
@@ -2168,7 +2142,10 @@ extension BridgeJSLink {
21682142 let genericNames = function. genericParameters ?? [ ]
21692143
21702144 func genericNameOf( _ param: Parameter ) -> String {
2171- param. type. referencedGenericName ?? genericNames [ 0 ]
2145+ guard let name = param. type. referencedGenericName else {
2146+ preconditionFailure ( " Generic value parameter ' \( param. name) ' has no referenced generic name " )
2147+ }
2148+ return name
21722149 }
21732150
21742151 let genericValueParameters = function. parameters. filter { $0. type. usesBareGeneric }
@@ -2188,9 +2165,20 @@ extension BridgeJSLink {
21882165 }
21892166 let concreteForwardings = thunkBuilder. parameterForwardings
21902167
2191- func tokenName( _ genericName: String ) -> String { " type \( genericName) " }
2192- func codecVariable( _ genericName: String ) -> String { " codec \( genericName) " }
2193- func typeIdVariable( _ genericName: String ) -> String { " \( genericName. lowercased ( ) ) TypeId " }
2168+ let nameScope = JSGlueVariableScope ( intrinsicRegistry: intrinsicRegistry)
2169+ for parameter in function. parameters {
2170+ _ = nameScope. variable ( parameter. name)
2171+ }
2172+ let tokenNames = Dictionary ( uniqueKeysWithValues: genericNames. map { ( $0, nameScope. variable ( " type \( $0) " ) ) } )
2173+ let codecNames = Dictionary ( uniqueKeysWithValues: genericNames. map { ( $0, nameScope. variable ( " codec \( $0) " ) ) } )
2174+ let typeIdNames = Dictionary (
2175+ uniqueKeysWithValues: genericNames. map { ( $0, nameScope. variable ( " \( $0. lowercased ( ) ) TypeId " ) ) }
2176+ )
2177+ func tokenName( _ genericName: String ) -> String { tokenNames [ genericName] ?? " type \( genericName) " }
2178+ func codecVariable( _ genericName: String ) -> String { codecNames [ genericName] ?? " codec \( genericName) " }
2179+ func typeIdVariable( _ genericName: String ) -> String {
2180+ typeIdNames [ genericName] ?? " \( genericName. lowercased ( ) ) TypeId "
2181+ }
21942182
21952183 let returnGenericName = function. returnType. referencedGenericName
21962184
@@ -2200,16 +2188,10 @@ extension BridgeJSLink {
22002188 printer. indent {
22012189 for genericName in genericNames {
22022190 printer. write (
2203- " const \( codecVariable ( genericName) ) = \( JSGlueVariableScope . reservedCodecs) [ \( tokenName ( genericName) ) ]; "
2204- )
2205- printer. write (
2206- " if (! \( codecVariable ( genericName) ) ) { throw new Error( \" BridgeJS: no generic codec registered for type ' \" + \( tokenName ( genericName) ) + \" ' \" ); } "
2207- )
2208- printer. write (
2209- " let \( typeIdVariable ( genericName) ) = \( JSGlueVariableScope . reservedCodecsById) .indexOf( \( codecVariable ( genericName) ) ); "
2191+ " const \( typeIdVariable ( genericName) ) = __bjs_resolveGenericType( \( tokenName ( genericName) ) ); "
22102192 )
22112193 printer. write (
2212- " if ( \( typeIdVariable ( genericName) ) === -1) { \( typeIdVariable ( genericName ) ) = \( JSGlueVariableScope . reservedCodecsById) .push( \( codecVariable ( genericName) ) ) - 1; } "
2194+ " const \( codecVariable ( genericName) ) = \( JSGlueVariableScope . reservedCodecsById) [ \( typeIdVariable ( genericName) ) ]; "
22132195 )
22142196 }
22152197 printer. write ( contentsOf: thunkBuilder. body)
@@ -2652,6 +2634,7 @@ extension BridgeJSLink {
26522634 var parameterForwardings : [ String ] = [ ]
26532635 var returnExpr : String ?
26542636 var genericCodecVariables : [ String : String ] = [ : ]
2637+ var genericTypeIdParameters : [ String : String ] = [ : ]
26552638 let printContext : IntrinsicJSFragment . PrintCodeContext
26562639
26572640 init (
@@ -2679,10 +2662,11 @@ extension BridgeJSLink {
26792662
26802663 func declareGenericCodecs( genericParameters: [ String ] ) {
26812664 for genericParam in genericParameters {
2682- let typeIdParam = " \( genericParam. lowercased ( ) ) TypeId "
2665+ let typeIdParam = scope . variable ( " \( genericParam. lowercased ( ) ) TypeId " )
26832666 let codecVar = scope. variable ( " codec \( genericParam) " )
26842667 body. write ( " const \( codecVar) = \( JSGlueVariableScope . reservedCodecsById) [ \( typeIdParam) ]; " )
26852668 genericCodecVariables [ genericParam] = codecVar
2669+ genericTypeIdParameters [ genericParam] = typeIdParam
26862670 }
26872671 }
26882672
@@ -3729,7 +3713,7 @@ extension BridgeJSLink {
37293713 try thunkBuilder. liftParameter ( param: param)
37303714 }
37313715 for genericParam in genericParameters {
3732- thunkBuilder. parameterNames. append ( " \( genericParam . lowercased ( ) ) TypeId " )
3716+ thunkBuilder. parameterNames. append ( thunkBuilder . genericTypeIdParameters [ genericParam ] ?? genericParam )
37333717 }
37343718 let jsName = function. jsName ?? function. name
37353719 let importRootExpr = function. from == . global ? " globalThis " : " imports "
0 commit comments