@@ -30,8 +30,6 @@ import ToolchainRegistry
3030import XCTest
3131#endif
3232
33- private struct SwiftSyntaxCShimsModulemapNotFoundError : Error { }
34-
3533package class SwiftPMTestProject : MultiFileTestProject {
3634 enum Error : Swift . Error {
3735 /// The `swift` executable could not be found.
@@ -85,9 +83,36 @@ package class SwiftPMTestProject: MultiFileTestProject {
8583 . first { FileManager . default. fileExists ( at: $0) }
8684
8785 guard let swiftSyntaxCShimsModulemap else {
86+ struct SwiftSyntaxCShimsModulemapNotFoundError : Swift . Error { }
8887 throw SwiftSyntaxCShimsModulemapNotFoundError ( )
8988 }
9089
90+ // Only link against object files that are listed in the `Objects.LinkFileList`. Otherwise we can get a situation
91+ // where a `.swift` file is removed from swift-syntax, its `.o` file is still in the build directory because the
92+ // build folder wasn't cleaned and thus we would link against the stale `.o` file.
93+ let linkFileListURL =
94+ productsDirectory
95+ . appendingPathComponent ( " SourceKitLSPPackageTests.product " )
96+ . appendingPathComponent ( " Objects.LinkFileList " )
97+ let linkFileListContents = try ? String ( contentsOf: linkFileListURL, encoding: . utf8)
98+ guard let linkFileListContents else {
99+ struct LinkFileListNotFoundError : Swift . Error {
100+ let url : URL
101+ }
102+ throw LinkFileListNotFoundError ( url: linkFileListURL)
103+ }
104+ let linkFileList =
105+ linkFileListContents
106+ . split ( separator: " \n " )
107+ . map {
108+ // Files are wrapped in single quotes if the path contains spaces. Drop the quotes.
109+ if $0. hasPrefix ( " ' " ) && $0. hasSuffix ( " ' " ) {
110+ return String ( $0. dropFirst ( ) . dropLast ( ) )
111+ } else {
112+ return String ( $0)
113+ }
114+ }
115+
91116 let swiftSyntaxModulesToLink = [
92117 " SwiftBasicFormat " ,
93118 " SwiftCompilerPlugin " ,
@@ -108,7 +133,7 @@ package class SwiftPMTestProject: MultiFileTestProject {
108133 let dir = productsDirectory. appendingPathComponent ( " \( moduleName) .build " )
109134 let enumerator = FileManager . default. enumerator ( at: dir, includingPropertiesForKeys: nil )
110135 while let file = enumerator? . nextObject ( ) as? URL {
111- if file . pathExtension == " o " {
136+ if linkFileList . contains ( try file . filePath ) {
112137 objectFiles. append ( try file. filePath)
113138 }
114139 }
0 commit comments