@@ -832,6 +832,8 @@ struct StackCodegen {
832832 return liftNullableExpression ( wrappedType : wrappedType , kind : kind )
833833 case . array ( let elementType ) :
834834 return liftArrayExpression ( elementType : elementType )
835+ case . dictionary ( let valueType ) :
836+ return liftDictionaryExpression ( valueType : valueType )
835837 case . closure :
836838 return " JSObject.bridgeJSLiftParameter() "
837839 case . void , . namespaceEnum :
@@ -849,7 +851,7 @@ struct StackCodegen {
849851 return liftArrayExpressionInline ( elementType : elementType )
850852 case . swiftProtocol ( let protocolName ) :
851853 return " [Any \( raw : protocolName ) ].bridgeJSLiftParameter() "
852- case . nullable , . array , . closure :
854+ case . nullable , . array , . closure , . dictionary :
853855 return liftArrayExpressionInline ( elementType : elementType )
854856 case . void , . namespaceEnum :
855857 fatalError ( " Invalid array element type: \( elementType ) " )
@@ -873,6 +875,51 @@ struct StackCodegen {
873875 """
874876 }
875877
878+ func liftDictionaryExpression ( valueType : BridgeType ) -> ExprSyntax {
879+ switch valueType {
880+ case . int , . uint , . float , . double , . string , . bool , . jsValue ,
881+ . jsObject ( nil ) , . swiftStruct , . caseEnum , . swiftHeapObject ,
882+ . unsafePointer , . rawValueEnum , . associatedValueEnum :
883+ return " [String: \( raw : valueType . swiftType ) ].bridgeJSLiftParameter() "
884+ case . jsObject ( let className ? ) :
885+ return """
886+ {
887+ let __dict = [String: JSObject].bridgeJSLiftParameter()
888+ return __dict.mapValues { \( raw : className ) (unsafelyWrapping: $0) }
889+ }()
890+ """
891+ case . swiftProtocol ( let protocolName ) :
892+ return """
893+ {
894+ let __dict = [String: JSObject].bridgeJSLiftParameter()
895+ return __dict.mapValues { $0 as! Any \( raw : protocolName ) }
896+ }()
897+ """
898+ case . nullable , . array , . dictionary , . closure :
899+ return liftDictionaryExpressionInline ( valueType : valueType )
900+ case . void , . namespaceEnum :
901+ fatalError ( " Invalid dictionary value type: \( valueType ) " )
902+ }
903+ }
904+
905+ private func liftDictionaryExpressionInline ( valueType : BridgeType ) -> ExprSyntax {
906+ let valueLift = liftExpression ( for : valueType )
907+ let swiftTypeName = valueType . swiftType
908+ return """
909+ {
910+ let __count = Int(_swift_js_pop_i32())
911+ var __result: [String: \( raw : swiftTypeName ) ] = [:]
912+ __result.reserveCapacity(__count)
913+ for _ in 0..<__count {
914+ let __value = \( valueLift )
915+ let __key = String.bridgeJSLiftParameter()
916+ __result[__key] = __value
917+ }
918+ return __result
919+ }()
920+ """
921+ }
922+
876923 private func liftNullableExpression ( wrappedType : BridgeType , kind : JSOptionalKind ) -> ExprSyntax {
877924 let typeName = kind == . null ? " Optional " : " JSUndefinedOr "
878925 switch wrappedType {
@@ -897,6 +944,23 @@ struct StackCodegen {
897944 }
898945 }()
899946 """
947+ case . dictionary ( let valueType ) :
948+ let dictionaryLift = liftDictionaryExpression ( valueType : valueType )
949+ let swiftTypeName = valueType . swiftType
950+ let absentExpr =
951+ kind == . null
952+ ? " \( typeName ) <[String: \( swiftTypeName ) ]>.none "
953+ : " \( typeName ) <[String: \( swiftTypeName ) ]>.undefinedValue "
954+ return """
955+ {
956+ let __isSome = _swift_js_pop_i32()
957+ if __isSome == 0 {
958+ return \( raw : absentExpr )
959+ } else {
960+ return \( dictionaryLift )
961+ }
962+ }()
963+ """
900964 case . nullable , . void , . namespaceEnum , . closure , . unsafePointer , . swiftProtocol :
901965 fatalError ( " Invalid nullable wrapped type: \( wrappedType ) " )
902966 }
@@ -935,6 +999,8 @@ struct StackCodegen {
935999 return [ ]
9361000 case . array ( let elementType ) :
9371001 return lowerArrayStatements ( elementType : elementType , accessor : accessor , varPrefix : varPrefix )
1002+ case . dictionary ( let valueType ) :
1003+ return lowerDictionaryStatements ( valueType : valueType , accessor : accessor , varPrefix : varPrefix )
9381004 }
9391005 }
9401006
@@ -952,7 +1018,7 @@ struct StackCodegen {
9521018 return [ " \( raw : accessor ) .map { $0.jsObject }.bridgeJSLowerReturn() " ]
9531019 case . swiftProtocol ( let protocolName ) :
9541020 return [ " \( raw : accessor ) .map { $0 as! Any \( raw : protocolName ) }.bridgeJSLowerReturn() " ]
955- case . nullable , . array , . closure :
1021+ case . nullable , . array , . closure , . dictionary :
9561022 return lowerArrayStatementsInline (
9571023 elementType : elementType ,
9581024 accessor : accessor ,
@@ -986,6 +1052,65 @@ struct StackCodegen {
9861052 return statements
9871053 }
9881054
1055+ private func lowerDictionaryStatements (
1056+ valueType : BridgeType ,
1057+ accessor : String ,
1058+ varPrefix : String
1059+ ) -> [ CodeBlockItemSyntax ] {
1060+ switch valueType {
1061+ case . int , . uint , . float , . double , . string , . bool , . jsValue ,
1062+ . jsObject ( nil ) , . swiftStruct , . caseEnum , . swiftHeapObject ,
1063+ . unsafePointer , . rawValueEnum , . associatedValueEnum :
1064+ return [ " \( raw : accessor ) .bridgeJSLowerReturn() " ]
1065+ case . jsObject ( _? ) :
1066+ return [ " \( raw : accessor ) .mapValues { $0.jsObject }.bridgeJSLowerReturn() " ]
1067+ case . swiftProtocol ( let protocolName ) :
1068+ return [ " \( raw : accessor ) .mapValues { $0 as! Any \( raw : protocolName ) }.bridgeJSLowerReturn() " ]
1069+ case . nullable , . array , . dictionary , . closure :
1070+ return lowerDictionaryStatementsInline (
1071+ valueType : valueType ,
1072+ accessor : accessor ,
1073+ varPrefix : varPrefix
1074+ )
1075+ case . void , . namespaceEnum :
1076+ fatalError ( " Invalid dictionary value type: \( valueType ) " )
1077+ }
1078+ }
1079+
1080+ private func lowerDictionaryStatementsInline (
1081+ valueType : BridgeType ,
1082+ accessor : String ,
1083+ varPrefix : String
1084+ ) -> [ CodeBlockItemSyntax ] {
1085+ var statements : [ CodeBlockItemSyntax ] = [ ]
1086+ let pairVarName = " __bjs_kv_ \( varPrefix ) "
1087+ statements . append ( " for \( raw : pairVarName ) in \( raw : accessor ) { " )
1088+ statements . append ( " let __bjs_key_ \( raw : varPrefix ) = \( raw : pairVarName ) .key " )
1089+ statements . append ( " let __bjs_value_ \( raw : varPrefix ) = \( raw : pairVarName ) .value " )
1090+
1091+ let keyStatements = lowerStatements (
1092+ for : . string ,
1093+ accessor : " __bjs_key_ \( varPrefix ) " ,
1094+ varPrefix : " \( varPrefix ) _key "
1095+ )
1096+ for stmt in keyStatements {
1097+ statements . append ( stmt )
1098+ }
1099+
1100+ let valueStatements = lowerStatements (
1101+ for : valueType ,
1102+ accessor : " __bjs_value_ \( varPrefix ) " ,
1103+ varPrefix : " \( varPrefix ) _value "
1104+ )
1105+ for stmt in valueStatements {
1106+ statements . append ( stmt )
1107+ }
1108+
1109+ statements . append ( " } " )
1110+ statements . append ( " _swift_js_push_i32(Int32( \( raw : accessor ) .count)) " )
1111+ return statements
1112+ }
1113+
9891114 private func lowerOptionalStatements (
9901115 wrappedType : BridgeType ,
9911116 accessor : String ,
@@ -1033,6 +1158,8 @@ struct StackCodegen {
10331158 return [ " \( raw : unwrappedVar ) .jsObject.bridgeJSLowerStackReturn() " ]
10341159 case . array ( let elementType ) :
10351160 return lowerArrayStatements ( elementType : elementType , accessor : unwrappedVar , varPrefix : varPrefix )
1161+ case . dictionary ( let valueType ) :
1162+ return lowerDictionaryStatements ( valueType : valueType , accessor : unwrappedVar , varPrefix : varPrefix )
10361163 default :
10371164 return [ " preconditionFailure( \" BridgeJS: unsupported optional wrapped type \" ) " ]
10381165 }
@@ -1616,6 +1743,7 @@ extension BridgeType {
16161743 case . nullable ( let wrappedType , let kind ) :
16171744 return kind == . null ? " Optional< \( wrappedType . swiftType ) > " : " JSUndefinedOr< \( wrappedType . swiftType ) > "
16181745 case . array ( let elementType ) : return " [ \( elementType . swiftType ) ] "
1746+ case . dictionary ( let valueType ) : return " [String: \( valueType . swiftType ) ] "
16191747 case . caseEnum ( let name ) : return name
16201748 case . rawValueEnum ( let name , _) : return name
16211749 case . associatedValueEnum ( let name ) : return name
@@ -1675,7 +1803,7 @@ extension BridgeType {
16751803 throw BridgeJSCoreError ( " Namespace enums are not supported to pass as parameters " )
16761804 case . closure :
16771805 return LiftingIntrinsicInfo ( parameters : [ ( " callbackId " , . i32 ) ] )
1678- case . array :
1806+ case . array , . dictionary :
16791807 return LiftingIntrinsicInfo ( parameters : [ ] )
16801808 }
16811809 }
@@ -1726,7 +1854,7 @@ extension BridgeType {
17261854 throw BridgeJSCoreError ( " Namespace enums are not supported to pass as parameters " )
17271855 case . closure :
17281856 return . swiftHeapObject
1729- case . array :
1857+ case . array , . dictionary :
17301858 return . array
17311859 }
17321860 }
0 commit comments