mirror of
https://github.com/apple/sourcekit-lsp.git
synced 2026-03-02 18:23:24 +01:00
Support building SourceKit-LSP without a dependency on SwiftPM
This commit is contained in:
@@ -80,10 +80,12 @@ var targets: [Target] = [
|
||||
"SwiftExtensions",
|
||||
"ToolchainRegistry",
|
||||
"TSCExtensions",
|
||||
.product(name: "SwiftPM-auto", package: "swift-package-manager"),
|
||||
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
|
||||
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
|
||||
],
|
||||
]
|
||||
+ swiftPMDependency([
|
||||
.product(name: "SwiftPM-auto", package: "swift-package-manager"),
|
||||
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
|
||||
]),
|
||||
exclude: ["CMakeLists.txt"],
|
||||
swiftSettings: globalSwiftSettings
|
||||
),
|
||||
@@ -387,8 +389,10 @@ var targets: [Target] = [
|
||||
.product(name: "IndexStoreDB", package: "indexstore-db"),
|
||||
.product(name: "Crypto", package: "swift-crypto"),
|
||||
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
|
||||
.product(name: "SwiftPM-auto", package: "swift-package-manager"),
|
||||
]
|
||||
+ swiftPMDependency([
|
||||
.product(name: "SwiftPM-auto", package: "swift-package-manager")
|
||||
])
|
||||
+ swiftSyntaxDependencies([
|
||||
"SwiftBasicFormat", "SwiftDiagnostics", "SwiftIDEUtils", "SwiftParser", "SwiftParserDiagnostics",
|
||||
"SwiftRefactor", "SwiftSyntax",
|
||||
@@ -449,8 +453,6 @@ var targets: [Target] = [
|
||||
"SKUtilities",
|
||||
"SwiftExtensions",
|
||||
"TSCExtensions",
|
||||
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
|
||||
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
|
||||
],
|
||||
exclude: ["CMakeLists.txt"],
|
||||
swiftSettings: globalSwiftSettings
|
||||
@@ -461,8 +463,6 @@ var targets: [Target] = [
|
||||
dependencies: [
|
||||
"SKTestSupport",
|
||||
"ToolchainRegistry",
|
||||
.product(name: "SwiftPMDataModel-auto", package: "swift-package-manager"),
|
||||
.product(name: "SwiftToolsSupport-auto", package: "swift-tools-support-core"),
|
||||
],
|
||||
swiftSettings: globalSwiftSettings
|
||||
),
|
||||
@@ -524,6 +524,13 @@ func swiftSyntaxDependencies(_ names: [String]) -> [Target.Dependency] {
|
||||
}
|
||||
}
|
||||
|
||||
func swiftPMDependency<T>(_ values: [T]) -> [T] {
|
||||
if noSwiftPMDependency {
|
||||
return []
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// MARK: - Parse build arguments
|
||||
|
||||
func hasEnvironmentVariable(_ name: String) -> Bool {
|
||||
@@ -558,6 +565,9 @@ var buildDynamicSwiftSyntaxLibrary: Bool { hasEnvironmentVariable("SWIFTSYNTAX_B
|
||||
/// the `swift test` invocation so that all pre-built modules can be found.
|
||||
var buildOnlyTests: Bool { hasEnvironmentVariable("SOURCEKIT_LSP_BUILD_ONLY_TESTS") }
|
||||
|
||||
/// Build SourceKit-LSP without a dependency on SwiftPM, ie. without support for SwiftPM projects.
|
||||
var noSwiftPMDependency: Bool { hasEnvironmentVariable("SOURCEKIT_LSP_NO_SWIFTPM_DEPENDENCY") }
|
||||
|
||||
// MARK: - Dependencies
|
||||
|
||||
// When building with the swift build-script, use local dependencies whose contents are controlled
|
||||
@@ -570,18 +580,16 @@ var dependencies: [Package.Dependency] {
|
||||
} else if useLocalDependencies {
|
||||
return [
|
||||
.package(path: "../indexstore-db"),
|
||||
.package(name: "swift-package-manager", path: "../swiftpm"),
|
||||
.package(path: "../swift-tools-support-core"),
|
||||
.package(path: "../swift-argument-parser"),
|
||||
.package(path: "../swift-syntax"),
|
||||
.package(path: "../swift-crypto"),
|
||||
]
|
||||
] + swiftPMDependency([.package(name: "swift-package-manager", path: "../swiftpm")])
|
||||
} else {
|
||||
let relatedDependenciesBranch = "main"
|
||||
|
||||
return [
|
||||
.package(url: "https://github.com/swiftlang/indexstore-db.git", branch: relatedDependenciesBranch),
|
||||
.package(url: "https://github.com/swiftlang/swift-package-manager.git", branch: relatedDependenciesBranch),
|
||||
.package(url: "https://github.com/apple/swift-tools-support-core.git", branch: relatedDependenciesBranch),
|
||||
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.4.0"),
|
||||
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: relatedDependenciesBranch),
|
||||
@@ -589,6 +597,9 @@ var dependencies: [Package.Dependency] {
|
||||
// Not a build dependency. Used so the "Format Source Code" command plugin can be used to format sourcekit-lsp
|
||||
.package(url: "https://github.com/swiftlang/swift-format.git", branch: relatedDependenciesBranch),
|
||||
]
|
||||
+ swiftPMDependency([
|
||||
.package(url: "https://github.com/swiftlang/swift-package-manager.git", branch: relatedDependenciesBranch)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -210,6 +210,7 @@ private extension BuildSystemSpec {
|
||||
)
|
||||
}
|
||||
case .swiftPM:
|
||||
#if canImport(PackageModel)
|
||||
return await Self.createBuiltInBuildSystemAdapter(
|
||||
projectRoot: projectRoot,
|
||||
messagesToSourceKitLSPHandler: messagesToSourceKitLSPHandler,
|
||||
@@ -223,6 +224,9 @@ private extension BuildSystemSpec {
|
||||
testHooks: testHooks.swiftPMTestHooks
|
||||
)
|
||||
}
|
||||
#else
|
||||
return nil
|
||||
#endif
|
||||
case .testBuildSystem:
|
||||
return await Self.createBuiltInBuildSystemAdapter(
|
||||
projectRoot: projectRoot,
|
||||
|
||||
@@ -16,6 +16,19 @@ package import LanguageServerProtocol
|
||||
import LanguageServerProtocol
|
||||
#endif
|
||||
|
||||
package struct SwiftPMTestHooks: Sendable {
|
||||
package var reloadPackageDidStart: (@Sendable () async -> Void)?
|
||||
package var reloadPackageDidFinish: (@Sendable () async -> Void)?
|
||||
|
||||
package init(
|
||||
reloadPackageDidStart: (@Sendable () async -> Void)? = nil,
|
||||
reloadPackageDidFinish: (@Sendable () async -> Void)? = nil
|
||||
) {
|
||||
self.reloadPackageDidStart = reloadPackageDidStart
|
||||
self.reloadPackageDidFinish = reloadPackageDidFinish
|
||||
}
|
||||
}
|
||||
|
||||
package struct BuildSystemTestHooks: Sendable {
|
||||
package var swiftPMTestHooks: SwiftPMTestHooks
|
||||
|
||||
|
||||
@@ -10,20 +10,92 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Foundation
|
||||
import LanguageServerProtocol
|
||||
import SKLogging
|
||||
|
||||
#if compiler(>=6)
|
||||
package import BuildServerProtocol
|
||||
import LanguageServerProtocol
|
||||
import SKLogging
|
||||
#else
|
||||
import BuildServerProtocol
|
||||
import LanguageServerProtocol
|
||||
import SKLogging
|
||||
#endif
|
||||
|
||||
extension BuildTargetIdentifier {
|
||||
package static let dummy: BuildTargetIdentifier = BuildTargetIdentifier(uri: try! URI(string: "dummy://dummy"))
|
||||
}
|
||||
|
||||
package enum BuildDestinationIdentifier {
|
||||
case host
|
||||
case target
|
||||
|
||||
/// A string that can be used to identify the build triple in a `BuildTargetIdentifier`.
|
||||
///
|
||||
/// `BuildSystemManager.canonicalBuildTargetIdentifier` picks the canonical target based on alphabetical
|
||||
/// ordering. We rely on the string "destination" being ordered before "tools" so that we prefer a
|
||||
/// `destination` (or "target") target over a `tools` (or "host") target.
|
||||
var id: String {
|
||||
switch self {
|
||||
case .host:
|
||||
return "tools"
|
||||
case .target:
|
||||
return "destination"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension BuildTargetIdentifier {
|
||||
/// - Important: *For testing only*
|
||||
package init(target: String, destination: BuildDestinationIdentifier) throws {
|
||||
var components = URLComponents()
|
||||
components.scheme = "swiftpm"
|
||||
components.host = "target"
|
||||
components.queryItems = [
|
||||
URLQueryItem(name: "target", value: target),
|
||||
URLQueryItem(name: "destination", value: destination.id),
|
||||
]
|
||||
|
||||
struct FailedToConvertSwiftBuildTargetToUrlError: Swift.Error, CustomStringConvertible {
|
||||
var target: String
|
||||
var destination: String
|
||||
|
||||
var description: String {
|
||||
return "Failed to generate URL for target: \(target), destination: \(destination)"
|
||||
}
|
||||
}
|
||||
|
||||
guard let url = components.url else {
|
||||
throw FailedToConvertSwiftBuildTargetToUrlError(target: target, destination: destination.id)
|
||||
}
|
||||
|
||||
self.init(uri: URI(url))
|
||||
}
|
||||
|
||||
fileprivate static let forPackageManifest = BuildTargetIdentifier(uri: try! URI(string: "swiftpm://package-manifest"))
|
||||
|
||||
fileprivate var targetProperties: (target: String, runDestination: String) {
|
||||
get throws {
|
||||
struct InvalidTargetIdentifierError: Swift.Error, CustomStringConvertible {
|
||||
var target: BuildTargetIdentifier
|
||||
|
||||
var description: String {
|
||||
return "Invalid target identifier \(target)"
|
||||
}
|
||||
}
|
||||
guard let components = URLComponents(url: self.uri.arbitrarySchemeURL, resolvingAgainstBaseURL: false) else {
|
||||
throw InvalidTargetIdentifierError(target: self)
|
||||
}
|
||||
let target = components.queryItems?.last(where: { $0.name == "target" })?.value
|
||||
let runDestination = components.queryItems?.last(where: { $0.name == "destination" })?.value
|
||||
|
||||
guard let target, let runDestination else {
|
||||
throw InvalidTargetIdentifierError(target: self)
|
||||
}
|
||||
|
||||
return (target, runDestination)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if compiler(>=6)
|
||||
extension BuildTargetIdentifier: CustomLogStringConvertible {
|
||||
package var description: String {
|
||||
|
||||
@@ -59,9 +59,13 @@ package func determineBuildSystem(
|
||||
return BuildSystemSpec(kind: .compilationDatabase, projectRoot: projectRoot)
|
||||
}
|
||||
case .swiftPM:
|
||||
#if canImport(PackageModel)
|
||||
if let projectRoot = SwiftPMBuildSystem.projectRoot(for: workspaceFolderUrl, options: options) {
|
||||
return BuildSystemSpec(kind: .swiftPM, projectRoot: projectRoot)
|
||||
}
|
||||
#else
|
||||
return nil
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,53 +10,41 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if compiler(>=6)
|
||||
#if canImport(PackageModel)
|
||||
import Basics
|
||||
@preconcurrency import Build
|
||||
package import BuildServerProtocol
|
||||
import Dispatch
|
||||
package import Foundation
|
||||
package import LanguageServerProtocol
|
||||
import LanguageServerProtocolExtensions
|
||||
@preconcurrency import PackageGraph
|
||||
import PackageLoading
|
||||
import PackageModel
|
||||
import SKLogging
|
||||
package import SKOptions
|
||||
@preconcurrency package import SPMBuildCore
|
||||
import SourceControl
|
||||
package import SourceKitLSPAPI
|
||||
import SwiftExtensions
|
||||
package import ToolchainRegistry
|
||||
import TSCExtensions
|
||||
@preconcurrency import Workspace
|
||||
|
||||
import struct TSCBasic.AbsolutePath
|
||||
import class TSCBasic.Process
|
||||
|
||||
#if compiler(>=6)
|
||||
package import BuildServerProtocol
|
||||
package import BuildSystemIntegration
|
||||
package import Foundation
|
||||
package import LanguageServerProtocol
|
||||
package import SKOptions
|
||||
package import SourceKitLSPAPI
|
||||
package import ToolchainRegistry
|
||||
package import class ToolchainRegistry.Toolchain
|
||||
#else
|
||||
import Basics
|
||||
@preconcurrency import Build
|
||||
import BuildServerProtocol
|
||||
import Dispatch
|
||||
import BuildSystemIntegration
|
||||
import Foundation
|
||||
import LanguageServerProtocol
|
||||
import LanguageServerProtocolExtensions
|
||||
@preconcurrency import PackageGraph
|
||||
import PackageLoading
|
||||
import PackageModel
|
||||
import SKLogging
|
||||
import SKOptions
|
||||
@preconcurrency import SPMBuildCore
|
||||
import SourceControl
|
||||
import SourceKitLSPAPI
|
||||
import SwiftExtensions
|
||||
import ToolchainRegistry
|
||||
import TSCExtensions
|
||||
@preconcurrency import Workspace
|
||||
|
||||
import struct TSCBasic.AbsolutePath
|
||||
import class TSCBasic.Process
|
||||
import class ToolchainRegistry.Toolchain
|
||||
#endif
|
||||
|
||||
@@ -78,51 +66,18 @@ fileprivate extension Basics.Diagnostic.Severity {
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate extension BuildDestination {
|
||||
/// A string that can be used to identify the build triple in a `BuildTargetIdentifier`.
|
||||
///
|
||||
/// `BuildSystemManager.canonicalBuildTargetIdentifier` picks the canonical target based on alphabetical
|
||||
/// ordering. We rely on the string "destination" being ordered before "tools" so that we prefer a
|
||||
/// `destination` (or "target") target over a `tools` (or "host") target.
|
||||
var id: String {
|
||||
switch self {
|
||||
case .host:
|
||||
return "tools"
|
||||
case .target:
|
||||
return "destination"
|
||||
extension BuildDestinationIdentifier {
|
||||
init(_ destination: BuildDestination) {
|
||||
switch destination {
|
||||
case .target: self = .target
|
||||
case .host: self = .host
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension BuildTargetIdentifier {
|
||||
fileprivate init(_ buildTarget: any SwiftBuildTarget) throws {
|
||||
try self.init(target: buildTarget.name, destination: buildTarget.destination)
|
||||
}
|
||||
|
||||
/// - Important: *For testing only*
|
||||
package init(target: String, destination: BuildDestination) throws {
|
||||
var components = URLComponents()
|
||||
components.scheme = "swiftpm"
|
||||
components.host = "target"
|
||||
components.queryItems = [
|
||||
URLQueryItem(name: "target", value: target),
|
||||
URLQueryItem(name: "destination", value: destination.id),
|
||||
]
|
||||
|
||||
struct FailedToConvertSwiftBuildTargetToUrlError: Swift.Error, CustomStringConvertible {
|
||||
var target: String
|
||||
var destination: String
|
||||
|
||||
var description: String {
|
||||
return "Failed to generate URL for target: \(target), destination: \(destination)"
|
||||
}
|
||||
}
|
||||
|
||||
guard let url = components.url else {
|
||||
throw FailedToConvertSwiftBuildTargetToUrlError(target: target, destination: destination.id)
|
||||
}
|
||||
|
||||
self.init(uri: URI(url))
|
||||
try self.init(target: buildTarget.name, destination: BuildDestinationIdentifier(buildTarget.destination))
|
||||
}
|
||||
|
||||
fileprivate static let forPackageManifest = BuildTargetIdentifier(uri: try! URI(string: "swiftpm://package-manifest"))
|
||||
@@ -159,19 +114,6 @@ fileprivate extension TSCBasic.AbsolutePath {
|
||||
|
||||
fileprivate let preparationTaskID: AtomicUInt32 = AtomicUInt32(initialValue: 0)
|
||||
|
||||
package struct SwiftPMTestHooks: Sendable {
|
||||
package var reloadPackageDidStart: (@Sendable () async -> Void)?
|
||||
package var reloadPackageDidFinish: (@Sendable () async -> Void)?
|
||||
|
||||
package init(
|
||||
reloadPackageDidStart: (@Sendable () async -> Void)? = nil,
|
||||
reloadPackageDidFinish: (@Sendable () async -> Void)? = nil
|
||||
) {
|
||||
self.reloadPackageDidStart = reloadPackageDidStart
|
||||
self.reloadPackageDidFinish = reloadPackageDidFinish
|
||||
}
|
||||
}
|
||||
|
||||
/// Swift Package Manager build system and workspace support.
|
||||
///
|
||||
/// This class implements the `BuiltInBuildSystem` interface to provide the build settings for a Swift
|
||||
@@ -793,3 +735,5 @@ fileprivate extension URL {
|
||||
(try? resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if canImport(PackageModel)
|
||||
|
||||
import Foundation
|
||||
import LanguageServerProtocol
|
||||
import PackageModel
|
||||
@@ -298,3 +300,5 @@ fileprivate extension FunctionCallExprSyntax {
|
||||
return memberAccess.declName.baseName.text
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -14,15 +14,20 @@ import SwiftRefactor
|
||||
|
||||
/// List of all of the syntactic code action providers, which can be used
|
||||
/// to produce code actions using only the swift-syntax tree of a file.
|
||||
let allSyntaxCodeActions: [SyntaxCodeActionProvider.Type] = [
|
||||
AddDocumentation.self,
|
||||
AddSeparatorsToIntegerLiteral.self,
|
||||
ConvertIntegerLiteral.self,
|
||||
ConvertJSONToCodableStruct.self,
|
||||
ConvertStringConcatenationToStringInterpolation.self,
|
||||
FormatRawStringLiteral.self,
|
||||
MigrateToNewIfLetSyntax.self,
|
||||
OpaqueParameterToGeneric.self,
|
||||
PackageManifestEdits.self,
|
||||
RemoveSeparatorsFromIntegerLiteral.self,
|
||||
]
|
||||
let allSyntaxCodeActions: [SyntaxCodeActionProvider.Type] = {
|
||||
var result: [SyntaxCodeActionProvider.Type] = [
|
||||
AddDocumentation.self,
|
||||
AddSeparatorsToIntegerLiteral.self,
|
||||
ConvertIntegerLiteral.self,
|
||||
ConvertJSONToCodableStruct.self,
|
||||
ConvertStringConcatenationToStringInterpolation.self,
|
||||
FormatRawStringLiteral.self,
|
||||
MigrateToNewIfLetSyntax.self,
|
||||
OpaqueParameterToGeneric.self,
|
||||
RemoveSeparatorsFromIntegerLiteral.self,
|
||||
]
|
||||
#if canImport(PackageModel)
|
||||
result.append(PackageManifestEdits.self)
|
||||
#endif
|
||||
return result
|
||||
}()
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
import Build
|
||||
#if canImport(PackageModel)
|
||||
import BuildServerProtocol
|
||||
@_spi(Testing) import BuildSystemIntegration
|
||||
import LanguageServerProtocol
|
||||
@@ -19,6 +19,7 @@ import PackageModel
|
||||
import SKOptions
|
||||
import SKTestSupport
|
||||
import SourceKitLSP
|
||||
@preconcurrency import SPMBuildCore
|
||||
import SwiftExtensions
|
||||
import TSCBasic
|
||||
import TSCExtensions
|
||||
@@ -27,11 +28,6 @@ import XCTest
|
||||
|
||||
import struct Basics.AbsolutePath
|
||||
import struct Basics.Triple
|
||||
import struct PackageModel.BuildFlags
|
||||
|
||||
#if canImport(SPMBuildCore)
|
||||
@preconcurrency import SPMBuildCore
|
||||
#endif
|
||||
|
||||
private var hostTriple: Triple {
|
||||
get async throws {
|
||||
@@ -1243,3 +1239,4 @@ fileprivate extension URL {
|
||||
return result
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,9 +15,55 @@ import BuildSystemIntegration
|
||||
import LanguageServerProtocol
|
||||
import SKLogging
|
||||
import SemanticIndex
|
||||
import SourceKitLSPAPI
|
||||
import XCTest
|
||||
|
||||
enum BuildDestination {
|
||||
case host
|
||||
case target
|
||||
|
||||
/// A string that can be used to identify the build triple in a `BuildTargetIdentifier`.
|
||||
///
|
||||
/// `BuildSystemManager.canonicalBuildTargetIdentifier` picks the canonical target based on alphabetical
|
||||
/// ordering. We rely on the string "destination" being ordered before "tools" so that we prefer a
|
||||
/// `destination` (or "target") target over a `tools` (or "host") target.
|
||||
var id: String {
|
||||
switch self {
|
||||
case .host:
|
||||
return "tools"
|
||||
case .target:
|
||||
return "destination"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension BuildTargetIdentifier {
|
||||
/// - Important: *For testing only*
|
||||
init(target: String, destination: BuildDestination) throws {
|
||||
var components = URLComponents()
|
||||
components.scheme = "swiftpm"
|
||||
components.host = "target"
|
||||
components.queryItems = [
|
||||
URLQueryItem(name: "target", value: target),
|
||||
URLQueryItem(name: "destination", value: destination.id),
|
||||
]
|
||||
|
||||
struct FailedToConvertSwiftBuildTargetToUrlError: Swift.Error, CustomStringConvertible {
|
||||
var target: String
|
||||
var destination: String
|
||||
|
||||
var description: String {
|
||||
return "Failed to generate URL for target: \(target), destination: \(destination)"
|
||||
}
|
||||
}
|
||||
|
||||
guard let url = components.url else {
|
||||
throw FailedToConvertSwiftBuildTargetToUrlError(target: target, destination: destination.id)
|
||||
}
|
||||
|
||||
self.init(uri: URI(url))
|
||||
}
|
||||
}
|
||||
|
||||
struct ExpectedPreparation {
|
||||
let target: BuildTargetIdentifier
|
||||
|
||||
|
||||
Reference in New Issue
Block a user