diff --git a/BuildSupport/SwiftSyntax/CMakeLists.txt b/BuildSupport/SwiftSyntax/CMakeLists.txt index 09f4cd51d2c..e1d9decb5f3 100644 --- a/BuildSupport/SwiftSyntax/CMakeLists.txt +++ b/BuildSupport/SwiftSyntax/CMakeLists.txt @@ -1,14 +1,16 @@ include(FetchContent) -set(BUILD_SHARED_LIBS OFF) - -if(DEFINED SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE) - file(TO_CMAKE_PATH "${SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE}" swift_syntax_path) - FetchContent_Declare(SwiftSyntax - SOURCE_DIR "${swift_syntax_path}") -else() - FetchContent_Declare(SwiftSyntax - GIT_REPOSITORY https://github.com/apple/swift-syntax - GIT_TAG main) +find_package(SwiftSyntax CONFIG GLOBAL) +if(NOT SwiftSyntax_FOUND) + set(SWIFT_SYNTAX_INSTALL_TARGETS YES) + if(DEFINED SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE) + file(TO_CMAKE_PATH "${SWIFTPM_PATH_TO_SWIFT_SYNTAX_SOURCE}" swift_syntax_path) + FetchContent_Declare(SwiftSyntax + SOURCE_DIR "${swift_syntax_path}") + else() + FetchContent_Declare(SwiftSyntax + GIT_REPOSITORY https://github.com/apple/swift-syntax + GIT_TAG main) + endif() + FetchContent_MakeAvailable(SwiftSyntax) endif() -FetchContent_MakeAvailable(SwiftSyntax) diff --git a/Sources/PackageModelSyntax/CMakeLists.txt b/Sources/PackageModelSyntax/CMakeLists.txt index 556fd0c619b..cfab869efc1 100644 --- a/Sources/PackageModelSyntax/CMakeLists.txt +++ b/Sources/PackageModelSyntax/CMakeLists.txt @@ -24,12 +24,12 @@ target_link_libraries(PackageModelSyntax PUBLIC PackageLoading PackageModel - SwiftBasicFormat - SwiftDiagnostics - SwiftIDEUtils - SwiftParser - SwiftSyntax - SwiftSyntaxBuilder + SwiftSyntax::SwiftBasicFormat + SwiftSyntax::SwiftDiagnostics + SwiftSyntax::SwiftIDEUtils + SwiftSyntax::SwiftParser + SwiftSyntax::SwiftSyntax + SwiftSyntax::SwiftSyntaxBuilder ) # NOTE(compnerd) workaround for CMake not setting up include flags yet @@ -41,17 +41,3 @@ install(TARGETS PackageModelSyntax LIBRARY DESTINATION lib RUNTIME DESTINATION bin) set_property(GLOBAL APPEND PROPERTY SwiftPM_EXPORTS PackageModelSyntax) - -set(SWIFT_SYNTAX_MODULES - SwiftBasicFormat - SwiftParser - SwiftParserDiagnostics - SwiftDiagnostics - SwiftSyntax - SwiftSyntaxBuilder - SwiftIDEUtils -) -export(TARGETS ${SWIFT_SYNTAX_MODULES} - NAMESPACE SPMSwiftSyntax:: - FILE ${CMAKE_BINARY_DIR}/cmake/modules/SwiftSyntaxConfig.cmake - EXPORT_LINK_INTERFACE_LIBRARIES) \ No newline at end of file diff --git a/Sources/SourceKitLSPAPI/BuildDescription.swift b/Sources/SourceKitLSPAPI/BuildDescription.swift index d9287580bae..6e6f71f58b0 100644 --- a/Sources/SourceKitLSPAPI/BuildDescription.swift +++ b/Sources/SourceKitLSPAPI/BuildDescription.swift @@ -22,21 +22,33 @@ import class Build.BuildPlan import class Build.ClangTargetBuildDescription import class Build.SwiftTargetBuildDescription import struct PackageGraph.ResolvedTarget +import struct PackageGraph.ModulesGraph public protocol BuildTarget { var sources: [URL] { get } + /// Whether the target is part of the root package that the user opened or if it's part of a package dependency. + var isPartOfRootPackage: Bool { get } + func compileArguments(for fileURL: URL) throws -> [String] - } +} + +private struct WrappedClangTargetBuildDescription: BuildTarget { + private let description: ClangTargetBuildDescription + let isPartOfRootPackage: Bool + + init(description: ClangTargetBuildDescription, isPartOfRootPackage: Bool) { + self.description = description + self.isPartOfRootPackage = isPartOfRootPackage + } -extension ClangTargetBuildDescription: BuildTarget { public var sources: [URL] { - return (try? compilePaths().map { URL(fileURLWithPath: $0.source.pathString) }) ?? [] + return (try? description.compilePaths().map { URL(fileURLWithPath: $0.source.pathString) }) ?? [] } public func compileArguments(for fileURL: URL) throws -> [String] { let filePath = try resolveSymlinks(try AbsolutePath(validating: fileURL.path)) - let commandLine = try self.emitCommandLine(for: filePath) + let commandLine = try description.emitCommandLine(for: filePath) // First element on the command line is the compiler itself, not an argument. return Array(commandLine.dropFirst()) } @@ -44,9 +56,11 @@ extension ClangTargetBuildDescription: BuildTarget { private struct WrappedSwiftTargetBuildDescription: BuildTarget { private let description: SwiftTargetBuildDescription + let isPartOfRootPackage: Bool - init(description: SwiftTargetBuildDescription) { + init(description: SwiftTargetBuildDescription, isPartOfRootPackage: Bool) { self.description = description + self.isPartOfRootPackage = isPartOfRootPackage } var sources: [URL] { @@ -71,17 +85,27 @@ public struct BuildDescription { } // FIXME: should not use `ResolvedTarget` in the public interface - public func getBuildTarget(for target: ResolvedTarget) -> BuildTarget? { + public func getBuildTarget(for target: ResolvedTarget, in modulesGraph: ModulesGraph) -> BuildTarget? { if let description = buildPlan.targetMap[target.id] { switch description { case .clang(let description): - return description + return WrappedClangTargetBuildDescription( + description: description, + isPartOfRootPackage: modulesGraph.rootPackages.map(\.id).contains(description.package.id) + ) case .swift(let description): - return WrappedSwiftTargetBuildDescription(description: description) + return WrappedSwiftTargetBuildDescription( + description: description, + isPartOfRootPackage: modulesGraph.rootPackages.map(\.id).contains(description.package.id) + ) } } else { if target.type == .plugin, let package = self.buildPlan.graph.package(for: target) { - return PluginTargetBuildDescription(target: target, toolsVersion: package.manifest.toolsVersion) + return PluginTargetBuildDescription( + target: target, + toolsVersion: package.manifest.toolsVersion, + isPartOfRootPackage: modulesGraph.rootPackages.map(\.id).contains(package.id) + ) } return nil } diff --git a/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift b/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift index 8524908f5c1..56338493269 100644 --- a/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift +++ b/Sources/SourceKitLSPAPI/PluginTargetBuildDescription.swift @@ -21,11 +21,13 @@ private import class PackageModel.UserToolchain struct PluginTargetBuildDescription: BuildTarget { private let target: ResolvedTarget private let toolsVersion: ToolsVersion + let isPartOfRootPackage: Bool - init(target: ResolvedTarget, toolsVersion: ToolsVersion) { + init(target: ResolvedTarget, toolsVersion: ToolsVersion, isPartOfRootPackage: Bool) { assert(target.type == .plugin) self.target = target self.toolsVersion = toolsVersion + self.isPartOfRootPackage = isPartOfRootPackage } var sources: [URL] { diff --git a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift index 127710d0785..29691c493d9 100644 --- a/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift +++ b/Tests/SourceKitLSPAPITests/SourceKitLSPAPITests.swift @@ -51,15 +51,15 @@ class SourceKitLSPAPITests: XCTestCase { ) let description = BuildDescription(buildPlan: plan) - try description.checkArguments(for: "exe", graph: graph, partialArguments: ["-module-name", "exe", "-emit-dependencies", "-emit-module", "-emit-module-path", "/path/to/build/debug/exe.build/exe.swiftmodule"]) - try description.checkArguments(for: "lib", graph: graph, partialArguments: ["-module-name", "lib", "-emit-dependencies", "-emit-module", "-emit-module-path", "/path/to/build/debug/Modules/lib.swiftmodule"]) + try description.checkArguments(for: "exe", graph: graph, partialArguments: ["-module-name", "exe", "-emit-dependencies", "-emit-module", "-emit-module-path", "/path/to/build/debug/exe.build/exe.swiftmodule"], isPartOfRootPackage: true) + try description.checkArguments(for: "lib", graph: graph, partialArguments: ["-module-name", "lib", "-emit-dependencies", "-emit-module", "-emit-module-path", "/path/to/build/debug/Modules/lib.swiftmodule"], isPartOfRootPackage: true) } } extension SourceKitLSPAPI.BuildDescription { - @discardableResult func checkArguments(for targetName: String, graph: ModulesGraph, partialArguments: [String]) throws -> Bool { + @discardableResult func checkArguments(for targetName: String, graph: ModulesGraph, partialArguments: [String], isPartOfRootPackage: Bool) throws -> Bool { let target = try XCTUnwrap(graph.allTargets.first(where: { $0.name == targetName })) - let buildTarget = try XCTUnwrap(self.getBuildTarget(for: target)) + let buildTarget = try XCTUnwrap(self.getBuildTarget(for: target, in: graph)) guard let file = buildTarget.sources.first else { XCTFail("build target \(targetName) contains no files") @@ -70,6 +70,7 @@ extension SourceKitLSPAPI.BuildDescription { let result = arguments.contains(partialArguments) XCTAssertTrue(result, "could not match \(partialArguments) to actual arguments \(arguments)") + XCTAssertEqual(buildTarget.isPartOfRootPackage, isPartOfRootPackage) return result } }