From f54168e72c6608445b27bf5f02cab794571280e6 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Fri, 21 Aug 2026 10:16:54 +0000 Subject: [PATCH 1/2] [SwiftExtract] Record the source file path on ExtractedFunc ExtractedNominalType already exposes sourceFilePath, but functions did not carry theirs, so a consumer that groups output by input file (e.g. BridgeJS's per-file imported-API skeletons) could not attribute global functions or accessors to a file. Thread the path through the visitor into every ExtractedFunc; synthesized declarations keep nil. --- Sources/SwiftExtract/ExtractedDecls.swift | 12 ++++++++++-- Sources/SwiftExtract/SwiftAnalysisVisitor.swift | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftExtract/ExtractedDecls.swift b/Sources/SwiftExtract/ExtractedDecls.swift index c0dac567e..752e60b53 100644 --- a/Sources/SwiftExtract/ExtractedDecls.swift +++ b/Sources/SwiftExtract/ExtractedDecls.swift @@ -309,6 +309,10 @@ public final class ExtractedFunc: ExtractedSwiftDecl, CustomStringConvertible { public let functionSignature: SwiftFunctionSignature + // The short path from module root to the file in which this declaration was originally declared. + // E.g. for `Sources/Example/My/Types.swift` it would be `My/Types.swift`. + public let sourceFilePath: String? + public var signatureString: String { self.swiftDecl.signatureString } @@ -390,12 +394,14 @@ public final class ExtractedFunc: ExtractedSwiftDecl, CustomStringConvertible { name: String, apiKind: SwiftAPIKind, functionSignature: SwiftFunctionSignature, + sourceFilePath: String? = nil, ) { self.module = module self.name = name self.swiftDecl = swiftDecl self.apiKind = apiKind self.functionSignature = functionSignature + self.sourceFilePath = sourceFilePath } public var description: String { @@ -418,7 +424,8 @@ public final class ExtractedFunc: ExtractedSwiftDecl, CustomStringConvertible { swiftDecl: swiftDecl, name: name, apiKind: apiKind, - functionSignature: functionSignature + functionSignature: functionSignature, + sourceFilePath: sourceFilePath ) } @@ -469,7 +476,8 @@ public final class ExtractedFunc: ExtractedSwiftDecl, CustomStringConvertible { swiftDecl: swiftDecl, name: name, apiKind: apiKind, - functionSignature: newSignature + functionSignature: newSignature, + sourceFilePath: sourceFilePath ) ) } diff --git a/Sources/SwiftExtract/SwiftAnalysisVisitor.swift b/Sources/SwiftExtract/SwiftAnalysisVisitor.swift index 0f08b43df..1939bf592 100644 --- a/Sources/SwiftExtract/SwiftAnalysisVisitor.swift +++ b/Sources/SwiftExtract/SwiftAnalysisVisitor.swift @@ -227,6 +227,7 @@ final class SwiftAnalysisVisitor { name: node.name.text.unescapedSwiftName, apiKind: apiKind, functionSignature: signature, + sourceFilePath: sourceFilePath, ) log.debug("Record extracted method \(node.qualifiedNameForDebug)") @@ -268,6 +269,7 @@ final class SwiftAnalysisVisitor { name: caseName, apiKind: .enumCase, functionSignature: signature, + sourceFilePath: sourceFilePath, ) let extractedCase = ExtractedEnumCase( @@ -318,6 +320,7 @@ final class SwiftAnalysisVisitor { in: typeContext, kind: .getter, name: varName, + sourceFilePath: sourceFilePath, ) } if supportedAccessors.contains(.set) { @@ -326,6 +329,7 @@ final class SwiftAnalysisVisitor { in: typeContext, kind: .setter, name: varName, + sourceFilePath: sourceFilePath, ) } } catch { @@ -375,6 +379,7 @@ final class SwiftAnalysisVisitor { name: "init", apiKind: .initializer, functionSignature: signature, + sourceFilePath: sourceFilePath, ) typeContext.initializers.append(extracted) @@ -403,6 +408,7 @@ final class SwiftAnalysisVisitor { in: typeContext, kind: .subscriptGetter, name: name, + sourceFilePath: sourceFilePath, ) } if accessors.contains(.set) { @@ -411,6 +417,7 @@ final class SwiftAnalysisVisitor { in: typeContext, kind: .subscriptSetter, name: name, + sourceFilePath: sourceFilePath, ) } } catch { @@ -452,6 +459,7 @@ final class SwiftAnalysisVisitor { in typeContext: ExtractedNominalType?, kind: SwiftAPIKind, name: String, + sourceFilePath: String, ) throws { let signature: SwiftFunctionSignature @@ -481,6 +489,7 @@ final class SwiftAnalysisVisitor { name: name, apiKind: kind, functionSignature: signature, + sourceFilePath: sourceFilePath, ) log.debug( From f5d4b8a9e11bd79ebc67834eb1b1ae6c8337a4e6 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 24 Aug 2026 14:37:37 +0900 Subject: [PATCH 2/2] Apply suggestions from code review --- Sources/SwiftExtract/ExtractedDecls.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftExtract/ExtractedDecls.swift b/Sources/SwiftExtract/ExtractedDecls.swift index 752e60b53..f6bf3788b 100644 --- a/Sources/SwiftExtract/ExtractedDecls.swift +++ b/Sources/SwiftExtract/ExtractedDecls.swift @@ -309,8 +309,8 @@ public final class ExtractedFunc: ExtractedSwiftDecl, CustomStringConvertible { public let functionSignature: SwiftFunctionSignature - // The short path from module root to the file in which this declaration was originally declared. - // E.g. for `Sources/Example/My/Types.swift` it would be `My/Types.swift`. + /// The short path from module root to the file in which this declaration was originally declared. + /// E.g. for `Sources/Example/My/Types.swift` it would be `My/Types.swift`. public let sourceFilePath: String? public var signatureString: String {