From 7e36adfce67f5fe4735ab7a3aa57e9cd4cc95a5f Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 7 Nov 2024 09:52:40 -0500 Subject: [PATCH 1/6] expose all target files to SourceKit-LSP --- .../ClangModuleBuildDescription.swift | 10 ++++++ .../SwiftModuleBuildDescription.swift | 10 ++++++ .../SourceKitLSPAPI/BuildDescription.swift | 33 +++++++++++++++++++ .../PluginTargetBuildDescription.swift | 12 +++++++ 4 files changed, 65 insertions(+) diff --git a/Sources/Build/BuildDescription/ClangModuleBuildDescription.swift b/Sources/Build/BuildDescription/ClangModuleBuildDescription.swift index b149675ebe2..139bf38aa21 100644 --- a/Sources/Build/BuildDescription/ClangModuleBuildDescription.swift +++ b/Sources/Build/BuildDescription/ClangModuleBuildDescription.swift @@ -57,6 +57,16 @@ public final class ClangModuleBuildDescription { self.target.underlying.resources + self.pluginDerivedResources } + /// The list of files in the target that were marked as ignored. + public var ignored: [AbsolutePath] { + self.target.underlying.ignored + } + + /// The list of other kinds of files in the target. + public var others: [AbsolutePath] { + self.target.underlying.others + } + /// Path to the bundle generated for this module (if any). var bundlePath: AbsolutePath? { guard !self.resources.isEmpty else { diff --git a/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift b/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift index de958a7d370..cb2c5b7ca24 100644 --- a/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift +++ b/Sources/Build/BuildDescription/SwiftModuleBuildDescription.swift @@ -108,6 +108,16 @@ public final class SwiftModuleBuildDescription { self.target.underlying.resources + self.pluginDerivedResources } + /// The list of files in the target that were marked as ignored. + public var ignored: [AbsolutePath] { + self.target.underlying.ignored + } + + /// The list of other kinds of files in the target. + public var others: [AbsolutePath] { + self.target.underlying.others + } + /// The objects in this target, containing either machine code or bitcode /// depending on the build parameters used. public var objects: [AbsolutePath] { diff --git a/Sources/SourceKitLSPAPI/BuildDescription.swift b/Sources/SourceKitLSPAPI/BuildDescription.swift index 0c72f4eb57c..501d45257b6 100644 --- a/Sources/SourceKitLSPAPI/BuildDescription.swift +++ b/Sources/SourceKitLSPAPI/BuildDescription.swift @@ -37,6 +37,15 @@ public protocol BuildTarget { /// Header files in the target var headers: [URL] { get } + /// The resource files in the target. + var resources: [URL] { get } + + /// Files in the target that were marked as ignored. + var ignored: [URL] { get } + + /// Other kinds of files in the module. + var others: [URL] { get } + /// The name of the target. It should be possible to build a target by passing this name to `swift build --target` var name: String { get } @@ -72,6 +81,18 @@ private struct WrappedClangTargetBuildDescription: BuildTarget { return description.clangTarget.headers.map(\.asURL) } + var resources: [URL] { + return description.resources.map { URL(fileURLWithPath: $0.path.pathString) } + } + + var ignored: [URL] { + return description.ignored.map { URL(fileURLWithPath: $0.pathString)} + } + + var others: [URL] { + return description.others.map { URL(fileURLWithPath: $0.pathString)} + } + public var name: String { return description.clangTarget.name } @@ -113,6 +134,18 @@ private struct WrappedSwiftTargetBuildDescription: BuildTarget { var headers: [URL] { [] } + var resources: [URL] { + return description.resources.map { URL(fileURLWithPath: $0.path.pathString) } + } + + var ignored: [URL] { + return description.ignored.map { URL(fileURLWithPath: $0.pathString)} + } + + var others: [URL] { + return description.others.map { URL(fileURLWithPath: $0.pathString)} + } + func compileArguments(for fileURL: URL) throws -> [String] { // Note: we ignore the `fileURL` here as the expectation is that we get a command line for the entire target // in case of Swift. diff --git a/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift b/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift index 5e7809c366e..d1923cda578 100644 --- a/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift +++ b/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift @@ -41,6 +41,18 @@ struct PluginTargetBuildDescription: BuildTarget { var headers: [URL] { [] } + var resources: [URL] { + return target.underlying.resources.map { URL(fileURLWithPath: $0.path.pathString) } + } + + var ignored: [URL] { + return target.underlying.ignored.map { URL(fileURLWithPath: $0.pathString)} + } + + var others: [URL] { + return target.underlying.others.map { URL(fileURLWithPath: $0.pathString)} + } + var name: String { return target.name } From dcbdce65ae78e6fe500fe9695c2809a9c54a4206 Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 7 Nov 2024 10:37:31 -0500 Subject: [PATCH 2/6] update tests to check for other files --- .../SourceKitLSPAPITests/SourceKitLSPAPITests.swift | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift index 5f4f6ca5686..b5d187af97a 100644 --- a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift +++ b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift @@ -26,7 +26,9 @@ final class SourceKitLSPAPITests: XCTestCase { func testBasicSwiftPackage() async throws { let fs = InMemoryFileSystem(emptyFiles: "/Pkg/Sources/exe/main.swift", + "/Pkg/Sources/exe/exe.docc/GettingStarted.md", "/Pkg/Sources/lib/lib.swift", + "/Pkg/Sources/lib/lib.docc/GettingStarted.md", "/Pkg/Plugins/plugin/plugin.swift" ) @@ -71,6 +73,7 @@ final class SourceKitLSPAPITests: XCTestCase { "-emit-module", "-emit-module-path", "/path/to/build/\(plan.destinationBuildParameters.triple)/debug/exe.build/exe.swiftmodule" ], + otherFiles: 1, isPartOfRootPackage: true ) try description.checkArguments( @@ -82,6 +85,7 @@ final class SourceKitLSPAPITests: XCTestCase { "-emit-module", "-emit-module-path", "/path/to/build/\(plan.destinationBuildParameters.triple)/debug/Modules/lib.swiftmodule" ], + otherFiles: 1, isPartOfRootPackage: true ) try description.checkArguments( @@ -90,6 +94,7 @@ final class SourceKitLSPAPITests: XCTestCase { partialArguments: [ "-I", "/fake/manifestLib/path" ], + otherFiles: 0, isPartOfRootPackage: true, destination: .host ) @@ -238,18 +243,20 @@ extension SourceKitLSPAPI.BuildDescription { for targetName: String, graph: ModulesGraph, partialArguments: [String], + otherFiles: Int, isPartOfRootPackage: Bool, destination: BuildParameters.Destination = .target ) throws -> Bool { let target = try XCTUnwrap(graph.module(for: targetName)) let buildTarget = try XCTUnwrap(self.getBuildTarget(for: target, destination: destination)) - guard let file = buildTarget.sources.first else { - XCTFail("build target \(targetName) contains no files") + XCTAssertEqual(buildTarget.others.count, otherFiles, "build target \(targetName) contains an incorrect number of other files") + guard let source = buildTarget.sources.first else { + XCTFail("build target \(targetName) contains no source files") return false } - let arguments = try buildTarget.compileArguments(for: file) + let arguments = try buildTarget.compileArguments(for: source) let result = arguments.contains(partialArguments) XCTAssertTrue(result, "could not match \(partialArguments) to actual arguments \(arguments)") From 8f5a4d4859d78b1607814ec9a48e0577f665abff Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 7 Nov 2024 13:31:31 -0500 Subject: [PATCH 3/6] add tests for resources, ignored, and other files --- .../SourceKitLSPAPITests.swift | 42 +++++++++++++++---- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift index b5d187af97a..f65384c864e 100644 --- a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift +++ b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift @@ -26,10 +26,14 @@ final class SourceKitLSPAPITests: XCTestCase { func testBasicSwiftPackage() async throws { let fs = InMemoryFileSystem(emptyFiles: "/Pkg/Sources/exe/main.swift", + "/Pkg/Sources/exe/README.md", "/Pkg/Sources/exe/exe.docc/GettingStarted.md", + "/Pkg/Sources/exe/Resources/some_file.txt", "/Pkg/Sources/lib/lib.swift", + "/Pkg/Sources/lib/README.md", "/Pkg/Sources/lib/lib.docc/GettingStarted.md", - "/Pkg/Plugins/plugin/plugin.swift" + "/Pkg/Sources/lib/Resources/some_file.txt", + "/Pkg/Plugins/plugin/plugin.swift", ) let observability = ObservabilitySystem.makeForTesting() @@ -39,9 +43,19 @@ final class SourceKitLSPAPITests: XCTestCase { Manifest.createRootManifest( displayName: "Pkg", path: "/Pkg", + toolsVersion: .v5_10, targets: [ - TargetDescription(name: "exe", dependencies: ["lib"]), - TargetDescription(name: "lib", dependencies: []), + TargetDescription( + name: "exe", + dependencies: ["lib"], + resources: [.init(rule: .copy, path: "Resources/some_file.txt")], + type: .executable + ), + TargetDescription( + name: "lib", + dependencies: [], + resources: [.init(rule: .copy, path: "Resources/some_file.txt")] + ), TargetDescription(name: "plugin", type: .plugin, pluginCapability: .buildTool) ]), ], @@ -69,11 +83,14 @@ final class SourceKitLSPAPITests: XCTestCase { graph: graph, partialArguments: [ "-module-name", "exe", + "-package-name", "pkg", "-emit-dependencies", "-emit-module", - "-emit-module-path", "/path/to/build/\(plan.destinationBuildParameters.triple)/debug/exe.build/exe.swiftmodule" + "-emit-module-path", "/path/to/build/\(plan.destinationBuildParameters.triple)/debug/Modules/exe.swiftmodule" ], - otherFiles: 1, + resources: [.init(filePath: "/Pkg/Sources/exe/Resources/some_file.txt")], + ignoredFiles: [.init(filePath: "/Pkg/Sources/exe/exe.docc")], + otherFiles: [.init(filePath: "/Pkg/Sources/exe/README.md")], isPartOfRootPackage: true ) try description.checkArguments( @@ -81,11 +98,14 @@ final class SourceKitLSPAPITests: XCTestCase { graph: graph, partialArguments: [ "-module-name", "lib", + "-package-name", "pkg", "-emit-dependencies", "-emit-module", "-emit-module-path", "/path/to/build/\(plan.destinationBuildParameters.triple)/debug/Modules/lib.swiftmodule" ], - otherFiles: 1, + resources: [.init(filePath: "/Pkg/Sources/lib/Resources/some_file.txt")], + ignoredFiles: [.init(filePath: "/Pkg/Sources/lib/lib.docc")], + otherFiles: [.init(filePath: "/Pkg/Sources/lib/README.md")], isPartOfRootPackage: true ) try description.checkArguments( @@ -94,7 +114,6 @@ final class SourceKitLSPAPITests: XCTestCase { partialArguments: [ "-I", "/fake/manifestLib/path" ], - otherFiles: 0, isPartOfRootPackage: true, destination: .host ) @@ -243,14 +262,19 @@ extension SourceKitLSPAPI.BuildDescription { for targetName: String, graph: ModulesGraph, partialArguments: [String], - otherFiles: Int, + resources: [URL] = [], + ignoredFiles: [URL] = [], + otherFiles: [URL] = [], isPartOfRootPackage: Bool, destination: BuildParameters.Destination = .target ) throws -> Bool { let target = try XCTUnwrap(graph.module(for: targetName)) let buildTarget = try XCTUnwrap(self.getBuildTarget(for: target, destination: destination)) - XCTAssertEqual(buildTarget.others.count, otherFiles, "build target \(targetName) contains an incorrect number of other files") + XCTAssertEqual(buildTarget.resources, resources, "build target \(targetName) contains unexpected resource files") + XCTAssertEqual(buildTarget.ignored, ignoredFiles, "build target \(targetName) contains unexpected ignored files") + XCTAssertEqual(buildTarget.others, otherFiles, "build target \(targetName) contains unexpected other files") + guard let source = buildTarget.sources.first else { XCTFail("build target \(targetName) contains no source files") return false From 10638291d2c7798135fd20c87e5e71322e4ff2c8 Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 7 Nov 2024 13:33:27 -0500 Subject: [PATCH 4/6] fix formatting inconsistencies --- Sources/SourceKitLSPAPI/BuildDescription.swift | 6 +++--- Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/SourceKitLSPAPI/BuildDescription.swift b/Sources/SourceKitLSPAPI/BuildDescription.swift index 501d45257b6..4efc256b861 100644 --- a/Sources/SourceKitLSPAPI/BuildDescription.swift +++ b/Sources/SourceKitLSPAPI/BuildDescription.swift @@ -43,7 +43,7 @@ public protocol BuildTarget { /// Files in the target that were marked as ignored. var ignored: [URL] { get } - /// Other kinds of files in the module. + /// Other kinds of files in the target. var others: [URL] { get } /// The name of the target. It should be possible to build a target by passing this name to `swift build --target` @@ -86,11 +86,11 @@ private struct WrappedClangTargetBuildDescription: BuildTarget { } var ignored: [URL] { - return description.ignored.map { URL(fileURLWithPath: $0.pathString)} + return description.ignored.map { URL(fileURLWithPath: $0.pathString) } } var others: [URL] { - return description.others.map { URL(fileURLWithPath: $0.pathString)} + return description.others.map { URL(fileURLWithPath: $0.pathString) } } public var name: String { diff --git a/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift b/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift index d1923cda578..6a956ce005d 100644 --- a/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift +++ b/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift @@ -46,11 +46,11 @@ struct PluginTargetBuildDescription: BuildTarget { } var ignored: [URL] { - return target.underlying.ignored.map { URL(fileURLWithPath: $0.pathString)} + return target.underlying.ignored.map { URL(fileURLWithPath: $0.pathString) } } var others: [URL] { - return target.underlying.others.map { URL(fileURLWithPath: $0.pathString)} + return target.underlying.others.map { URL(fileURLWithPath: $0.pathString) } } var name: String { From fa16606833f2c897934ed5e730a0786ccc318f3f Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 7 Nov 2024 13:35:43 -0500 Subject: [PATCH 5/6] fix more formatting inconsistencies --- Sources/SourceKitLSPAPI/BuildDescription.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SourceKitLSPAPI/BuildDescription.swift b/Sources/SourceKitLSPAPI/BuildDescription.swift index 4efc256b861..5f516e31e9d 100644 --- a/Sources/SourceKitLSPAPI/BuildDescription.swift +++ b/Sources/SourceKitLSPAPI/BuildDescription.swift @@ -139,11 +139,11 @@ private struct WrappedSwiftTargetBuildDescription: BuildTarget { } var ignored: [URL] { - return description.ignored.map { URL(fileURLWithPath: $0.pathString)} + return description.ignored.map { URL(fileURLWithPath: $0.pathString) } } var others: [URL] { - return description.others.map { URL(fileURLWithPath: $0.pathString)} + return description.others.map { URL(fileURLWithPath: $0.pathString) } } func compileArguments(for fileURL: URL) throws -> [String] { From 03637520dcfc8d6dc3039f5172563fabee07abf1 Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 7 Nov 2024 16:07:47 -0500 Subject: [PATCH 6/6] remove extra comma to fix the CI error --- Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift index f65384c864e..20e6e1766ac 100644 --- a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift +++ b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift @@ -33,7 +33,7 @@ final class SourceKitLSPAPITests: XCTestCase { "/Pkg/Sources/lib/README.md", "/Pkg/Sources/lib/lib.docc/GettingStarted.md", "/Pkg/Sources/lib/Resources/some_file.txt", - "/Pkg/Plugins/plugin/plugin.swift", + "/Pkg/Plugins/plugin/plugin.swift" ) let observability = ObservabilitySystem.makeForTesting()