@@ -123,10 +123,12 @@ class ExportSwift {
123
123
}
124
124
125
125
private func visitFunction( node: FunctionDeclSyntax ) -> ExportedFunction ? {
126
- guard node. attributes. hasJSAttribute ( ) else {
126
+ guard let jsAttribute = node. attributes. firstJSAttribute else {
127
127
return nil
128
128
}
129
- let name = node. name. text
129
+
130
+ let ( baseName, namespace) = extractNameAndNamespace ( from: node, jsAttribute: jsAttribute)
131
+
130
132
var parameters : [ Parameter ] = [ ]
131
133
for param in node. signature. parameterClause. parameters {
132
134
guard let type = self . parent. lookupType ( for: param. type) else {
@@ -151,21 +153,22 @@ class ExportSwift {
151
153
let abiName : String
152
154
switch state {
153
155
case . topLevel:
154
- abiName = " bjs_ \( name ) "
156
+ abiName = " bjs_ \( baseName ) "
155
157
case . classBody( let className) :
156
- abiName = " bjs_ \( className) _ \( name ) "
158
+ abiName = " bjs_ \( className) _ \( baseName ) "
157
159
}
158
160
159
161
guard let effects = collectEffects ( signature: node. signature) else {
160
162
return nil
161
163
}
162
164
163
165
return ExportedFunction (
164
- name: name ,
166
+ name: baseName ,
165
167
abiName: abiName,
166
168
parameters: parameters,
167
169
returnType: returnType,
168
- effects: effects
170
+ effects: effects,
171
+ namespace: namespace
169
172
)
170
173
}
171
174
@@ -192,6 +195,19 @@ class ExportSwift {
192
195
}
193
196
return Effects ( isAsync: isAsync, isThrows: isThrows)
194
197
}
198
+
199
+ private func extractNameAndNamespace(
200
+ from node: FunctionDeclSyntax ,
201
+ jsAttribute: AttributeSyntax
202
+ ) -> ( name: String , namespace: [ String ] ? ) {
203
+ guard let arguments = jsAttribute. arguments? . as ( LabeledExprListSyntax . self) ,
204
+ let firstArg = arguments. first? . expression. as ( StringLiteralExprSyntax . self) ,
205
+ let namespaceString = firstArg. segments. first? . as ( StringSegmentSyntax . self) ? . content. text else {
206
+ return ( node. name. text, nil )
207
+ }
208
+ let namespaces = namespaceString. split ( separator: " . " ) . map ( String . init)
209
+ return ( node. name. text, namespaces)
210
+ }
195
211
196
212
override func visit( _ node: InitializerDeclSyntax ) -> SyntaxVisitorContinueKind {
197
213
guard node. attributes. hasJSAttribute ( ) else { return . skipChildren }
@@ -227,11 +243,13 @@ class ExportSwift {
227
243
let name = node. name. text
228
244
stateStack. push ( state: . classBody( name: name) )
229
245
230
- guard node. attributes. hasJSAttribute ( ) else { return . skipChildren }
246
+ guard let jsAttribute = node. attributes. firstJSAttribute else { return . skipChildren }
247
+
231
248
exportedClassByName [ name] = ExportedClass (
232
249
name: name,
233
250
constructor: nil ,
234
- methods: [ ]
251
+ methods: [ ] ,
252
+ namespace: nil
235
253
)
236
254
exportedClassNames. append ( name)
237
255
return . visitChildren
@@ -635,9 +653,13 @@ class ExportSwift {
635
653
636
654
extension AttributeListSyntax {
637
655
fileprivate func hasJSAttribute( ) -> Bool {
638
- return first ( where: {
656
+ firstJSAttribute != nil
657
+ }
658
+
659
+ fileprivate var firstJSAttribute : AttributeSyntax ? {
660
+ first ( where: {
639
661
$0. as ( AttributeSyntax . self) ? . attributeName. trimmedDescription == " JS "
640
- } ) != nil
662
+ } ) ? . as ( AttributeSyntax . self )
641
663
}
642
664
}
643
665
0 commit comments