@@ -1856,6 +1856,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
18561856 private let inputFilePath : String
18571857 private var jsClassNames : Set < String >
18581858 private let parent : SwiftToSkeleton
1859+ private var staticMethodsByType : [ String : [ ImportedFunctionSkeleton ] ] = [ : ]
18591860
18601861 // MARK: - State Management
18611862
@@ -1876,6 +1877,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
18761877 let from : JSImportFrom ?
18771878 var constructor : ImportedConstructorSkeleton ?
18781879 var methods : [ ImportedFunctionSkeleton ]
1880+ var staticMethods : [ ImportedFunctionSkeleton ]
18791881 var getters : [ ImportedGetterSkeleton ]
18801882 var setters : [ ImportedSetterSkeleton ]
18811883 }
@@ -2094,6 +2096,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
20942096 from : nil ,
20952097 constructor : nil ,
20962098 methods : [ ] ,
2099+ staticMethods : [ ] ,
20972100 getters : [ ] ,
20982101 setters : [ ]
20992102 )
@@ -2107,25 +2110,29 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
21072110 from : from ,
21082111 constructor : nil ,
21092112 methods : [ ] ,
2113+ staticMethods : [ ] ,
21102114 getters : [ ] ,
21112115 setters : [ ]
21122116 )
21132117 }
21142118
21152119 private func exitJSClass ( ) {
21162120 if case . jsClassBody ( let typeName ) = state , let type = currentType , type . name == typeName {
2121+ let externalStaticMethods = staticMethodsByType [ type . name ] ?? [ ]
21172122 importedTypes . append (
21182123 ImportedTypeSkeleton (
21192124 name : type . name ,
21202125 jsName : type . jsName ,
21212126 from : type . from ,
21222127 constructor : type . constructor ,
21232128 methods : type . methods ,
2129+ staticMethods : type . staticMethods + externalStaticMethods ,
21242130 getters : type . getters ,
21252131 setters : type . setters ,
21262132 documentation : nil
21272133 )
21282134 )
2135+ staticMethodsByType [ type . name ] = nil
21292136 currentType = nil
21302137 }
21312138 stateStack . removeLast ( )
@@ -2217,8 +2224,14 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
22172224 ) -> Bool {
22182225 if let jsFunction = AttributeChecker . firstJSFunctionAttribute ( node . attributes ) {
22192226 if isStaticMember {
2220- parseFunction ( jsFunction , node , enclosingTypeName : typeName , isStaticMember : true ) . map {
2221- importedFunctions . append ( $0 )
2227+ parseFunction (
2228+ jsFunction ,
2229+ node ,
2230+ enclosingTypeName : typeName ,
2231+ isStaticMember : true ,
2232+ includeTypeNameForStatic : false
2233+ ) . map {
2234+ type . staticMethods . append ( $0 )
22222235 }
22232236 } else {
22242237 parseFunction ( jsFunction , node , enclosingTypeName : typeName , isStaticMember : false ) . map {
@@ -2319,9 +2332,34 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
23192332 for member in members {
23202333 if let function = member . decl . as ( FunctionDeclSyntax . self ) {
23212334 if let jsFunction = AttributeChecker . firstJSFunctionAttribute ( function . attributes ) ,
2322- let parsed = parseFunction ( jsFunction , function , enclosingTypeName : typeName , isStaticMember : true )
2335+ let parsed = parseFunction (
2336+ jsFunction ,
2337+ function ,
2338+ enclosingTypeName : typeName ,
2339+ isStaticMember : true ,
2340+ includeTypeNameForStatic : ! jsClassNames . contains ( typeName )
2341+ )
23232342 {
2324- importedFunctions . append ( parsed )
2343+ if jsClassNames . contains ( typeName ) {
2344+ if let index = importedTypes . firstIndex ( where : { $0 . name == typeName } ) {
2345+ let existing = importedTypes [ index ]
2346+ importedTypes [ index ] = ImportedTypeSkeleton (
2347+ name : existing . name ,
2348+ jsName : existing . jsName ,
2349+ from : existing . from ,
2350+ constructor : existing . constructor ,
2351+ methods : existing . methods ,
2352+ staticMethods : existing . staticMethods + [ parsed ] ,
2353+ getters : existing . getters ,
2354+ setters : existing . setters ,
2355+ documentation : existing . documentation
2356+ )
2357+ } else {
2358+ staticMethodsByType [ typeName , default : [ ] ] . append ( parsed )
2359+ }
2360+ } else {
2361+ importedFunctions . append ( parsed )
2362+ }
23252363 } else if AttributeChecker . hasJSSetterAttribute ( function . attributes ) {
23262364 errors . append (
23272365 DiagnosticError (
@@ -2366,7 +2404,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
23662404 _ jsFunction : AttributeSyntax ,
23672405 _ node : FunctionDeclSyntax ,
23682406 enclosingTypeName : String ? ,
2369- isStaticMember : Bool
2407+ isStaticMember : Bool ,
2408+ includeTypeNameForStatic : Bool = true
23702409 ) -> ImportedFunctionSkeleton ? {
23712410 guard validateEffects ( node . signature . effectSpecifiers , node : node , attributeName : " JSFunction " ) != nil
23722411 else {
@@ -2377,7 +2416,7 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor {
23772416 let jsName = AttributeChecker . extractJSName ( from : jsFunction )
23782417 let from = AttributeChecker . extractJSImportFrom ( from : jsFunction )
23792418 let name : String
2380- if isStaticMember , let enclosingTypeName {
2419+ if isStaticMember , includeTypeNameForStatic , let enclosingTypeName {
23812420 name = " \( enclosingTypeName ) _ \( baseName ) "
23822421 } else {
23832422 name = baseName
0 commit comments