@@ -1266,10 +1266,54 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
12661266 returnType: returnType,
12671267 effects: effects,
12681268 namespace: finalNamespace,
1269- staticContext: staticContext
1269+ staticContext: staticContext,
1270+ documentation: extractDocumentation ( from: node)
12701271 )
12711272 }
12721273
1274+ /// Returns the doc comment (`///` or `/** */`) attached to a declaration, with
1275+ /// markers stripped and DocC field lists (`- Parameters:`, `- Returns:`) preserved.
1276+ private func extractDocumentation( from node: some SyntaxProtocol ) -> String ? {
1277+ var run : [ String ] = [ ]
1278+ for piece in node. leadingTrivia {
1279+ switch piece {
1280+ case . docLineComment( let text) :
1281+ var line = Substring ( text)
1282+ if line. hasPrefix ( " /// " ) { line = line. dropFirst ( 3 ) }
1283+ if line. first == " " { line = line. dropFirst ( ) }
1284+ run. append ( String ( line) )
1285+ case . docBlockComment( let text) :
1286+ run. append ( contentsOf: stripBlockComment ( text) )
1287+ case . newlines( let count) , . carriageReturns( let count) , . carriageReturnLineFeeds( let count) :
1288+ if count >= 2 { run. removeAll ( ) }
1289+ case . lineComment, . blockComment:
1290+ run. removeAll ( )
1291+ default :
1292+ continue
1293+ }
1294+ }
1295+ let joined = run. joined ( separator: " \n " )
1296+ return joined. trimmingCharacters ( in: . whitespacesAndNewlines) . isEmpty ? nil : joined
1297+ }
1298+
1299+ private func stripBlockComment( _ text: String ) -> [ String ] {
1300+ var body = Substring ( text)
1301+ if body. hasPrefix ( " /**") { body = body.dropFirst(3) }
1302+ if body.hasSuffix("*/" ) { body = body. dropLast ( 2 ) }
1303+ var lines = body. split ( separator: " \n " , omittingEmptySubsequences: false ) . map { raw -> String in
1304+ var line = raw [ ... ]
1305+ while let first = line. first, first == " " || first == " \t " { line = line. dropFirst ( ) }
1306+ if line. first == " * " {
1307+ line = line. dropFirst ( )
1308+ if line. first == " " { line = line. dropFirst ( ) }
1309+ }
1310+ return String ( line)
1311+ }
1312+ while lines. first? . trimmingCharacters ( in: . whitespaces) . isEmpty == true { lines. removeFirst ( ) }
1313+ while lines. last? . trimmingCharacters ( in: . whitespaces) . isEmpty == true { lines. removeLast ( ) }
1314+ return lines
1315+ }
1316+
12731317 private func collectEffects( signature: FunctionSignatureSyntax , isStatic: Bool = false ) -> Effects ? {
12741318 let isAsync = signature. effectSpecifiers? . asyncSpecifier != nil
12751319 var isThrows = false
@@ -1360,7 +1404,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
13601404 let constructor = ExportedConstructor (
13611405 abiName: " bjs_ \( classAbiName) _init " ,
13621406 parameters: parameters,
1363- effects: effects
1407+ effects: effects,
1408+ documentation: extractDocumentation ( from: node)
13641409 )
13651410 exportedClassByName [ classKey] ? . constructor = constructor
13661411
@@ -1383,7 +1428,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
13831428 let constructor = ExportedConstructor (
13841429 abiName: " bjs_ \( structAbiName) _init " ,
13851430 parameters: parameters,
1386- effects: effects
1431+ effects: effects,
1432+ documentation: extractDocumentation ( from: node)
13871433 )
13881434 exportedStructByName [ structKey] ? . constructor = constructor
13891435
@@ -1490,7 +1536,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
14901536 isReadonly: isReadonly,
14911537 isStatic: isStatic,
14921538 namespace: finalNamespace,
1493- staticContext: staticContext
1539+ staticContext: staticContext,
1540+ documentation: extractDocumentation ( from: node)
14941541 )
14951542
14961543 if case . enumBody( _, let key) = state {
@@ -1537,7 +1584,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
15371584 methods: [ ] ,
15381585 properties: [ ] ,
15391586 namespace: effectiveNamespace,
1540- identityMode: classIdentityMode
1587+ identityMode: classIdentityMode,
1588+ documentation: extractDocumentation ( from: node)
15411589 )
15421590 let uniqueKey = makeKey ( name: name, namespace: effectiveNamespace)
15431591
@@ -1657,7 +1705,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
16571705 namespace: effectiveNamespace,
16581706 emitStyle: emitStyle,
16591707 staticMethods: [ ] ,
1660- staticProperties: [ ]
1708+ staticProperties: [ ] ,
1709+ documentation: extractDocumentation ( from: node)
16611710 )
16621711
16631712 let enumUniqueKey = makeKey ( name: name, namespace: effectiveNamespace)
@@ -1774,7 +1823,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
17741823 name: name,
17751824 methods: [ ] ,
17761825 properties: [ ] ,
1777- namespace: effectiveNamespace
1826+ namespace: effectiveNamespace,
1827+ documentation: extractDocumentation ( from: node)
17781828 )
17791829
17801830 stateStack. push ( state: . protocolBody( name: name, key: protocolUniqueKey) )
@@ -1798,7 +1848,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
17981848 name: name,
17991849 methods: methods,
18001850 properties: exportedProtocolByName [ protocolUniqueKey] ? . properties ?? [ ] ,
1801- namespace: effectiveNamespace
1851+ namespace: effectiveNamespace,
1852+ documentation: extractDocumentation ( from: node)
18021853 )
18031854
18041855 exportedProtocolByName [ protocolUniqueKey] = exportedProtocol
@@ -1874,7 +1925,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
18741925 isReadonly: true ,
18751926 isStatic: false ,
18761927 namespace: effectiveNamespace,
1877- staticContext: nil
1928+ staticContext: nil ,
1929+ documentation: extractDocumentation ( from: varDecl)
18781930 )
18791931 properties. append ( property)
18801932 }
@@ -1888,7 +1940,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
18881940 explicitAccessControl: explicitAccessControl,
18891941 properties: properties,
18901942 methods: [ ] ,
1891- namespace: effectiveNamespace
1943+ namespace: effectiveNamespace,
1944+ documentation: extractDocumentation ( from: node)
18921945 )
18931946
18941947 exportedStructByName [ structUniqueKey] = exportedStruct
@@ -1981,7 +2034,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
19812034 returnType: returnType,
19822035 effects: effects,
19832036 namespace: namespace,
1984- staticContext: nil
2037+ staticContext: nil ,
2038+ documentation: extractDocumentation ( from: node)
19852039 )
19862040 }
19872041
@@ -2022,7 +2076,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
20222076 let exportedProperty = ExportedProtocolProperty (
20232077 name: propertyName,
20242078 type: propertyType,
2025- isReadonly: isReadonly
2079+ isReadonly: isReadonly,
2080+ documentation: extractDocumentation ( from: node)
20262081 )
20272082
20282083 if var currentProtocol = exportedProtocolByName [ protocolKey] {
@@ -2033,7 +2088,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor {
20332088 name: currentProtocol. name,
20342089 methods: currentProtocol. methods,
20352090 properties: properties,
2036- namespace: currentProtocol. namespace
2091+ namespace: currentProtocol. namespace,
2092+ documentation: currentProtocol. documentation
20372093 )
20382094 exportedProtocolByName [ protocolKey] = currentProtocol
20392095 }
0 commit comments