@@ -137,14 +137,36 @@ struct IntrinsicJSFragment: Sendable {
137137 /// The printer to print the main fragment code.
138138 var printer : CodeFragmentPrinter
139139 /// Whether the fragment has direct access to the SwiftHeapObject classes.
140- /// If false, the fragment needs to use `_exports["<class name>"] ` to access the class.
140+ /// If false, the fragment needs to use `_exports` to access the class.
141141 var hasDirectAccessToSwiftClass : Bool = true
142+ /// Maps class names to their namespace path components for resolving `_exports` access.
143+ var classNamespaces : [ String : [ String ] ] = [ : ]
142144
143145 func with < T > ( _ keyPath : WritableKeyPath < PrintCodeContext , T > , _ value : T ) -> PrintCodeContext {
144146 var new = self
145147 new [ keyPath : keyPath ] = value
146148 return new
147149 }
150+
151+ private func unqualifiedClassName ( for qualifiedName : String ) -> String {
152+ qualifiedName . split ( separator : " . " ) . last . map ( String . init ) ?? qualifiedName
153+ }
154+
155+ private func exportsAccess ( forClass name : String ) -> String {
156+ if let namespace = classNamespaces [ name ] , ! namespace . isEmpty {
157+ let path = namespace . map { " . \( $0 ) " } . joined ( )
158+ return " _exports \( path ) . \( name ) "
159+ }
160+ return " _exports[' \( name ) '] "
161+ }
162+
163+ func classReference ( forQualifiedName qualifiedName : String ) -> String {
164+ if hasDirectAccessToSwiftClass {
165+ return unqualifiedClassName ( for : qualifiedName )
166+ }
167+ let unqualified = unqualifiedClassName ( for : qualifiedName )
168+ return exportsAccess ( forClass : unqualified )
169+ }
148170 }
149171
150172 /// A function that prints the fragment code.
@@ -555,8 +577,9 @@ struct IntrinsicJSFragment: Sendable {
555577 return IntrinsicJSFragment (
556578 parameters : [ " value " ] ,
557579 printCode : { arguments , context in
580+ let classRef = context . classReference ( forQualifiedName : name )
558581 return [
559- " \( context . hasDirectAccessToSwiftClass ? name : " _exports[' \( name ) '] " ) .__construct( \( arguments [ 0 ] ) ) "
582+ " \( classRef ) .__construct( \( arguments [ 0 ] ) ) "
560583 ]
561584 }
562585 )
@@ -565,7 +588,8 @@ struct IntrinsicJSFragment: Sendable {
565588 return IntrinsicJSFragment (
566589 parameters : [ " pointer " ] ,
567590 printCode : { arguments , context in
568- return [ " _exports[' \( name ) '].__construct( \( arguments [ 0 ] ) ) " ]
591+ let classRef = context . classReference ( forQualifiedName : name )
592+ return [ " \( classRef ) .__construct( \( arguments [ 0 ] ) ) " ]
569593 }
570594 )
571595 }
@@ -874,10 +898,8 @@ struct IntrinsicJSFragment: Sendable {
874898 printer . write (
875899 " \( JSGlueVariableScope . reservedStorageToReturnOptionalHeapObject ) = undefined; "
876900 )
877- let constructExpr =
878- context . hasDirectAccessToSwiftClass
879- ? " \( className ) .__construct( \( pointerVar ) ) "
880- : " _exports[' \( className ) '].__construct( \( pointerVar ) ) "
901+ let classRef = context . classReference ( forQualifiedName : className )
902+ let constructExpr = " \( classRef ) .__construct( \( pointerVar ) ) "
881903 printer . write (
882904 " const \( resultVar ) = \( pointerVar ) === null ? \( absenceLiteral ) : \( constructExpr ) ; "
883905 )
@@ -2075,8 +2097,9 @@ struct IntrinsicJSFragment: Sendable {
20752097 let ( scope , printer ) = ( context . scope , context . printer )
20762098 let ptrVar = scope . variable ( " ptr " )
20772099 let objVar = scope . variable ( " obj " )
2100+ let classRef = context . classReference ( forQualifiedName : className )
20782101 printer . write ( " const \( ptrVar ) = \( scope . popPointer ( ) ) ; " )
2079- printer . write ( " const \( objVar ) = _exports[' \( className ) '] .__construct(\( ptrVar ) ); " )
2102+ printer . write ( " const \( objVar ) = \( classRef ) .__construct( \( ptrVar ) ); " )
20802103 return [ objVar ]
20812104 }
20822105 )
0 commit comments