@@ -123,10 +123,13 @@ 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 | + |
129 | 130 | let name = node.name.text |
| 131 | + let namespace = extractNamespace(from: jsAttribute) |
| 132 | + |
130 | 133 | var parameters: [Parameter] = [] |
131 | 134 | for param in node.signature.parameterClause.parameters { |
132 | 135 | guard let type = self.parent.lookupType(for: param.type) else { |
@@ -165,7 +168,8 @@ class ExportSwift { |
165 | 168 | abiName: abiName, |
166 | 169 | parameters: parameters, |
167 | 170 | returnType: returnType, |
168 | | - effects: effects |
| 171 | + effects: effects, |
| 172 | + namespace: namespace |
169 | 173 | ) |
170 | 174 | } |
171 | 175 |
|
@@ -192,6 +196,17 @@ class ExportSwift { |
192 | 196 | } |
193 | 197 | return Effects(isAsync: isAsync, isThrows: isThrows) |
194 | 198 | } |
| 199 | + |
| 200 | + private func extractNamespace( |
| 201 | + from jsAttribute: AttributeSyntax |
| 202 | + ) -> [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 nil |
| 207 | + } |
| 208 | + return namespaceString.split(separator: ".").map(String.init) |
| 209 | + } |
195 | 210 |
|
196 | 211 | override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind { |
197 | 212 | guard node.attributes.hasJSAttribute() else { return .skipChildren } |
@@ -225,13 +240,17 @@ class ExportSwift { |
225 | 240 |
|
226 | 241 | override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind { |
227 | 242 | let name = node.name.text |
| 243 | + |
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 | + |
| 248 | + let namespace = extractNamespace(from: jsAttribute) |
231 | 249 | exportedClassByName[name] = ExportedClass( |
232 | 250 | name: name, |
233 | 251 | constructor: nil, |
234 | | - methods: [] |
| 252 | + methods: [], |
| 253 | + namespace: namespace |
235 | 254 | ) |
236 | 255 | exportedClassNames.append(name) |
237 | 256 | return .visitChildren |
@@ -635,9 +654,13 @@ class ExportSwift { |
635 | 654 |
|
636 | 655 | extension AttributeListSyntax { |
637 | 656 | fileprivate func hasJSAttribute() -> Bool { |
638 | | - return first(where: { |
| 657 | + firstJSAttribute != nil |
| 658 | + } |
| 659 | + |
| 660 | + fileprivate var firstJSAttribute: AttributeSyntax? { |
| 661 | + first(where: { |
639 | 662 | $0.as(AttributeSyntax.self)?.attributeName.trimmedDescription == "JS" |
640 | | - }) != nil |
| 663 | + })?.as(AttributeSyntax.self) |
641 | 664 | } |
642 | 665 | } |
643 | 666 |
|
|